/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Common Public License (CPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/cpl1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.adaptive.recompilation; import org.jikesrvm.VM; import org.jikesrvm.adaptive.controller.VM_Controller; import org.jikesrvm.adaptive.controller.VM_ControllerPlan; import org.jikesrvm.adaptive.controller.VM_RecompilationStrategy; import org.jikesrvm.adaptive.recompilation.instrumentation.VM_AOSInstrumentationPlan; import org.jikesrvm.classloader.VM_NormalMethod; import org.jikesrvm.compilers.baseline.VM_BaselineCompiler; import org.jikesrvm.compilers.common.VM_CompiledMethod; import org.jikesrvm.compilers.common.VM_CompiledMethods; import org.jikesrvm.compilers.opt.OPT_CompilationPlan; import org.jikesrvm.compilers.opt.OPT_OptimizationPlanElement; import org.jikesrvm.compilers.opt.OPT_OptimizationPlanner; import org.jikesrvm.compilers.opt.OPT_Options; import org.jikesrvm.runtime.VM_Magic; /** * Runtime system support for using invocation counters in baseline * compiled code to select methods for optimizing recompilation * by the adaptive system. Bypasses the normal controller logic: * If an invocation counter trips, then the method is enqueued for * recompilation at a default optimization level. */ public final class VM_InvocationCounts { private static int[] counts; private static boolean[] processed; public static synchronized void allocateCounter(int id) { if (counts == null) { counts = new int[id + 500]; processed = new boolean[counts.length]; } if (id >= counts.length) { int newSize = counts.length * 2; if (newSize <= id) newSize = id + 500; int[] tmp = new int[newSize]; System.arraycopy(counts, 0, tmp, 0, counts.length); boolean[] tmp2 = new boolean[newSize]; System.arraycopy(processed, 0, tmp2, 0, processed.length); VM_Magic.sync(); counts = tmp; processed = tmp2; } counts[id] = VM_Controller.options.INVOCATION_COUNT_THRESHOLD; } /** * Called from baseline compiled code when a method's invocation counter * becomes negative and thus must be handled */ static synchronized void counterTripped(int id) { counts[id] = 0x7fffffff; // set counter to max int to avoid lots of redundant calls. if (processed[id]) return; processed[id] = true; VM_CompiledMethod cm = VM_CompiledMethods.getCompiledMethod(id); if (cm == null) return; if (VM.VerifyAssertions) VM._assert(cm.getCompilerType() == VM_CompiledMethod.BASELINE); VM_NormalMethod m = (VM_NormalMethod) cm.getMethod(); OPT_CompilationPlan compPlan = new OPT_CompilationPlan(m, _optPlan, null, _options); VM_ControllerPlan cp = new VM_ControllerPlan(compPlan, VM_Controller.controllerClock, id, 2.0, 2.0, 2.0); // 2.0 is a bogus number.... cp.execute(); } /** * Create the compilation plan according to the default set * of <optimization plan, options> pairs */ public static OPT_CompilationPlan createCompilationPlan(VM_NormalMethod method) { return new OPT_CompilationPlan(method, _optPlan, null, _options); } public static OPT_CompilationPlan createCompilationPlan(VM_NormalMethod method, VM_AOSInstrumentationPlan instPlan) { return new OPT_CompilationPlan(method, _optPlan, instPlan, _options); } /** * Initialize the recompilation strategy. * * Note: This uses the command line options to set up the * optimization plans, so this must be run after the command line * options are available. */ public static void init() { createOptimizationPlan(); VM_BaselineCompiler.options.INVOCATION_COUNTERS = true; } private static OPT_OptimizationPlanElement[] _optPlan; private static OPT_Options _options; /** * Create the default set of <optimization plan, options> pairs * Process optimizing compiler command line options. */ static void createOptimizationPlan() { _options = new OPT_Options(); int optLevel = VM_Controller.options.INVOCATION_COUNT_OPT_LEVEL; String[] optCompilerOptions = VM_Controller.getOptCompilerOptions(); _options.setOptLevel(optLevel); VM_RecompilationStrategy.processCommandLineOptions(_options, optLevel, optLevel, optCompilerOptions); _optPlan = OPT_OptimizationPlanner.createOptimizationPlan(_options); } }