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 */
013 package org.jikesrvm.adaptive.recompilation;
014
015 import org.jikesrvm.VM;
016 import org.jikesrvm.adaptive.controller.Controller;
017 import org.jikesrvm.adaptive.controller.ControllerPlan;
018 import org.jikesrvm.adaptive.controller.RecompilationStrategy;
019 import org.jikesrvm.adaptive.recompilation.instrumentation.AOSInstrumentationPlan;
020 import org.jikesrvm.classloader.NormalMethod;
021 import org.jikesrvm.compilers.baseline.BaselineCompiler;
022 import org.jikesrvm.compilers.common.CompiledMethod;
023 import org.jikesrvm.compilers.common.CompiledMethods;
024 import org.jikesrvm.compilers.opt.OptOptions;
025 import org.jikesrvm.compilers.opt.driver.CompilationPlan;
026 import org.jikesrvm.compilers.opt.driver.OptimizationPlanElement;
027 import org.jikesrvm.compilers.opt.driver.OptimizationPlanner;
028 import 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 */
037 public 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 static synchronized void counterTripped(int id) {
066 counts[id] = 0x7fffffff; // set counter to max int to avoid lots of redundant calls.
067 if (processed[id]) return;
068 processed[id] = true;
069 CompiledMethod cm = CompiledMethods.getCompiledMethod(id);
070 if (cm == null) return;
071 if (VM.VerifyAssertions) VM._assert(cm.getCompilerType() == CompiledMethod.BASELINE);
072 NormalMethod m = (NormalMethod) cm.getMethod();
073 CompilationPlan compPlan = new CompilationPlan(m, _optPlan, null, _options);
074 ControllerPlan cp =
075 new ControllerPlan(compPlan, Controller.controllerClock, id, 2.0, 2.0, 2.0); // 2.0 is a bogus number....
076 cp.execute();
077 }
078
079 /**
080 * Create the compilation plan according to the default set
081 * of <optimization plan, options> pairs
082 */
083 public static CompilationPlan createCompilationPlan(NormalMethod method) {
084 return new CompilationPlan(method, _optPlan, null, _options);
085 }
086
087 public static CompilationPlan createCompilationPlan(NormalMethod method, AOSInstrumentationPlan instPlan) {
088 return new CompilationPlan(method, _optPlan, instPlan, _options);
089 }
090
091 /**
092 * Initialize the recompilation strategy.
093 *
094 * Note: This uses the command line options to set up the
095 * optimization plans, so this must be run after the command line
096 * options are available.
097 */
098 public static void init() {
099 createOptimizationPlan();
100 BaselineCompiler.options.INVOCATION_COUNTERS = true;
101 }
102
103 private static OptimizationPlanElement[] _optPlan;
104 private static OptOptions _options;
105
106 /**
107 * Create the default set of <optimization plan, options> pairs
108 * Process optimizing compiler command line options.
109 */
110 static void createOptimizationPlan() {
111 _options = new OptOptions();
112
113 int optLevel = Controller.options.INVOCATION_COUNT_OPT_LEVEL;
114 String[] optCompilerOptions = Controller.getOptCompilerOptions();
115 _options.setOptLevel(optLevel);
116 RecompilationStrategy.processCommandLineOptions(_options, optLevel, optLevel, optCompilerOptions);
117 _optPlan = OptimizationPlanner.createOptimizationPlan(_options);
118 }
119
120 }