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.compilers.common; 014 015 import org.jikesrvm.VM; 016 import org.jikesrvm.adaptive.measurements.RuntimeMeasurements; 017 import org.jikesrvm.classloader.RVMMethod; 018 import org.jikesrvm.classloader.NormalMethod; 019 020 /** 021 * This class enables an external driver to block recompile all 022 * methods that have been dynamically compiled since the VM began 023 * execution. This support can be used to eliminate the effects 024 * of early vs. late compilation by removing all dynamic linking 025 * and "bad" class hierarchy based optimizations. 026 */ 027 public final class RecompilationManager { 028 029 private static final boolean DEBUG = false; 030 031 /** 032 * Use the runtime compiler to forcibly recompile all dynamically 033 * loaded methods 034 */ 035 public static void recompileAllDynamicallyLoadedMethods(boolean report) { 036 int numMethods = CompiledMethods.numCompiledMethods(); 037 for (int cmid = 1; cmid < numMethods; cmid++) { 038 // To avoid the assertion for unused cmids 039 CompiledMethod cpMeth = CompiledMethods.getCompiledMethodUnchecked(cmid); 040 if (cpMeth == null) { 041 if (DEBUG) { 042 VM.sysWrite("Not recompiling method ID ", cmid, " because it has no compiledMethod\n"); 043 } 044 } else { 045 RVMMethod meth = cpMeth.getMethod(); 046 if (DEBUG) { 047 VM.sysWrite("numMethods: " + 048 numMethods + 049 ", Inspecting cpMethod " + 050 cpMeth + 051 ", method: " + 052 cpMeth.getMethod() + 053 "(" + 054 cmid + 055 ")\n"); 056 } 057 if (cpMeth.getCompilerType() == CompiledMethod.TRAP) { 058 if (DEBUG) { 059 VM.sysWrite("Not recompiling compiled method " + 060 cpMeth + 061 "(" + 062 cmid + 063 ") because it a TRAP, i.e. has no source code\n"); 064 } 065 } else { 066 if (meth.getDeclaringClass().isResolved()) { 067 if (meth.getDeclaringClass().isInBootImage()) { 068 if (DEBUG) { 069 VM.sysWrite("Not recompiling bootimage method " + meth + "(" + cmid + ")\n"); 070 } 071 } else { 072 if (meth.isAbstract()) { 073 if (DEBUG) VM.sysWrite("Not recompiling abstract method " + meth + "(" + cmid + ")\n"); 074 } else if (meth.isNative()) { 075 if (DEBUG) VM.sysWrite("Not recompiling native method " + meth + "(" + cmid + ")\n"); 076 } else { 077 if (DEBUG || report) VM.sysWrite("Recompiling " + meth + "(" + cmid + ") "); 078 recompile((NormalMethod) meth); 079 if (DEBUG || report) VM.sysWrite("...done\n"); 080 } 081 } 082 } else { 083 if (DEBUG) VM.sysWrite("Class not resolved" + meth + "(" + cmid + ")\n"); 084 } 085 } 086 } 087 } 088 089 if (VM.BuildForAdaptiveSystem) { 090 // clear profiling counter 091 if (DEBUG || report) { VM.sysWrite("Reseting profiling information\n"); } 092 RuntimeMeasurements.resetReportableObjects(); 093 } 094 } 095 096 /** 097 * recompile and replace the argument method by invoking the runtime compiler 098 */ 099 public static void recompile(NormalMethod meth) { 100 try { 101 CompiledMethod cm = RuntimeCompiler.compile(meth); 102 meth.replaceCompiledMethod(cm); 103 } catch (Throwable e) { 104 VM.sysWrite("Failure while recompiling \"" + meth + "\" : " + e + "\n"); 105 } 106 } 107 } 108