/* * 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.compilers.common; import org.jikesrvm.VM; import org.jikesrvm.adaptive.measurements.VM_RuntimeMeasurements; import org.jikesrvm.classloader.VM_Method; import org.jikesrvm.classloader.VM_NormalMethod; /** * This class enables an external driver to block recompile all * methods that have been dynamically compiled since the VM began * execution. This support can be used to eliminate the effects * of early vs. late compilation by removing all dynamic linking * and "bad" class hierarchy based optimizations. * <p> */ public final class VM_RecompilationManager { private static final boolean DEBUG = false; /** * Use the runtime compiler to forcibly recompile all dynamically * loaded methods */ public static void recompileAllDynamicallyLoadedMethods(boolean report, boolean forSubArch) { int numMethods = VM_CompiledMethods.numCompiledMethods(); // To avoid the assertion for unused cmids VM_CompiledMethod[] compiledMethods = VM_CompiledMethods.getCompiledMethods(); for (int cmid = 1; cmid < numMethods; cmid++) { VM_CompiledMethod cpMeth = compiledMethods[cmid]; if (cpMeth == null) { if (DEBUG) { VM.sysWrite("Not recompiling method ID ", cmid, " because it has no compiledMethod\n"); } } else { VM_Method meth = cpMeth.getMethod(); if (DEBUG) { VM.sysWrite("numMethods: " + numMethods + ", Inspecting cpMethod " + cpMeth + ", method: " + cpMeth.getMethod() + "(" + cmid + ")\n"); } if (cpMeth.getCompilerType() == VM_CompiledMethod.TRAP) { if (DEBUG) { VM.sysWrite("Not recompiling compiled method " + cpMeth + "(" + cmid + ") because it a TRAP, i.e. has no source code\n"); } } else { if (meth.getDeclaringClass().isResolved(forSubArch)) { if (meth.getDeclaringClass().isInBootImage()) { if (DEBUG) { VM.sysWrite("Not recompiling bootimage method " + meth + "(" + cmid + ")\n"); } } else { if (meth.isAbstract()) { if (DEBUG) VM.sysWrite("Not recompiling abstract method " + meth + "(" + cmid + ")\n"); } else if (meth.isNative()) { if (DEBUG) VM.sysWrite("Not recompiling native method " + meth + "(" + cmid + ")\n"); } else { if (DEBUG || report) VM.sysWrite("Recompiling " + meth + "(" + cmid + ") "); recompile((VM_NormalMethod) meth, forSubArch); if (DEBUG || report) VM.sysWrite("...done\n"); } } } else { if (DEBUG) VM.sysWrite("Class not resolved" + meth + "(" + cmid + ")\n"); } } } } if (VM.BuildForAdaptiveSystem) { // clear profiling counter if (DEBUG || report) { VM.sysWrite("Reseting profiling information\n"); } VM_RuntimeMeasurements.resetReportableObjects(); } } /** * recompile and replace the argument method by invoking the runtime compiler */ public static void recompile(VM_NormalMethod meth, boolean forSubArch) { try { VM_CompiledMethod cm = VM_RuntimeCompiler.compile(meth, forSubArch); meth.replaceCompiledMethod(cm, forSubArch); } catch (Throwable e) { VM.sysWrite("Failure while recompiling \"" + meth + "\" : " + e + "\n"); } } }