001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.jikesrvm.adaptive.recompilation; 014 015import org.jikesrvm.VM; 016import org.jikesrvm.adaptive.controller.Controller; 017import org.jikesrvm.adaptive.controller.ControllerPlan; 018import org.jikesrvm.adaptive.controller.RecompilationStrategy; 019import org.jikesrvm.adaptive.recompilation.instrumentation.AOSInstrumentationPlan; 020import org.jikesrvm.classloader.NormalMethod; 021import org.jikesrvm.compilers.baseline.BaselineCompiler; 022import org.jikesrvm.compilers.common.CompiledMethod; 023import org.jikesrvm.compilers.common.CompiledMethods; 024import org.jikesrvm.compilers.opt.OptOptions; 025import org.jikesrvm.compilers.opt.driver.CompilationPlan; 026import org.jikesrvm.compilers.opt.driver.OptimizationPlanElement; 027import org.jikesrvm.compilers.opt.driver.OptimizationPlanner; 028import org.jikesrvm.runtime.Magic; 029 030/** 031 * Runtime system support for using invocation counters in baseline 032 * compiled code to select methods for optimizing recompilation 033 * by the adaptive system. Bypasses the normal controller logic: 034 * If an invocation counter trips, then the method is enqueued for 035 * recompilation at a default optimization level. 036 */ 037public final class InvocationCounts { 038 039 private static int[] counts; 040 private static boolean[] processed; 041 042 public static synchronized void allocateCounter(int id) { 043 if (counts == null) { 044 counts = new int[id + 500]; 045 processed = new boolean[counts.length]; 046 } 047 if (id >= counts.length) { 048 int newSize = counts.length * 2; 049 if (newSize <= id) newSize = id + 500; 050 int[] tmp = new int[newSize]; 051 System.arraycopy(counts, 0, tmp, 0, counts.length); 052 boolean[] tmp2 = new boolean[newSize]; 053 System.arraycopy(processed, 0, tmp2, 0, processed.length); 054 Magic.sync(); 055 counts = tmp; 056 processed = tmp2; 057 } 058 counts[id] = Controller.options.INVOCATION_COUNT_THRESHOLD; 059 } 060 061 /** 062 * Called from baseline compiled code when a method's invocation counter 063 * becomes negative and thus must be handled 064 * 065 * @param id the compiled method id 066 */ 067 static synchronized void counterTripped(int id) { 068 counts[id] = 0x7fffffff; // set counter to max int to avoid lots of redundant calls. 069 if (processed[id]) return; 070 processed[id] = true; 071 CompiledMethod cm = CompiledMethods.getCompiledMethod(id); 072 if (cm == null) return; 073 if (VM.VerifyAssertions) VM._assert(cm.getCompilerType() == CompiledMethod.BASELINE); 074 NormalMethod m = (NormalMethod) cm.getMethod(); 075 CompilationPlan compPlan = new CompilationPlan(m, _optPlan, null, _options); 076 ControllerPlan cp = 077 new ControllerPlan(compPlan, Controller.controllerClock, id, 2.0, 2.0, 2.0); // 2.0 is a bogus number.... 078 cp.execute(); 079 } 080 081 public static CompilationPlan createCompilationPlan(NormalMethod method) { 082 return new CompilationPlan(method, _optPlan, null, _options); 083 } 084 085 public static CompilationPlan createCompilationPlan(NormalMethod method, AOSInstrumentationPlan instPlan) { 086 return new CompilationPlan(method, _optPlan, instPlan, _options); 087 } 088 089 /** 090 * Initialize the recompilation strategy.<p> 091 * 092 * Note: This uses the command line options to set up the 093 * optimization plans, so this must be run after the command line 094 * options are available. 095 */ 096 public static void init() { 097 createOptimizationPlan(); 098 BaselineCompiler.options.INVOCATION_COUNTERS = true; 099 } 100 101 private static OptimizationPlanElement[] _optPlan; 102 private static OptOptions _options; 103 104 /** 105 * Create the default set of <optimization plan, options> pairs 106 * Process optimizing compiler command line options. 107 */ 108 static void createOptimizationPlan() { 109 _options = new OptOptions(); 110 111 int optLevel = Controller.options.INVOCATION_COUNT_OPT_LEVEL; 112 String[] optCompilerOptions = Controller.getOptCompilerOptions(); 113 _options.setOptLevel(optLevel); 114 RecompilationStrategy.processCommandLineOptions(_options, optLevel, optLevel, optCompilerOptions); 115 _optPlan = OptimizationPlanner.createOptimizationPlan(_options); 116 } 117 118}