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 {@literal <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.<p> 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 }