/* * 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; import org.jikesrvm.VM; import org.jikesrvm.VM_Constants; import org.jikesrvm.ArchitectureSpecific.OSR_BaselineExecStateExtractor; import org.jikesrvm.ArchitectureSpecific.OSR_CodeInstaller; import org.jikesrvm.ArchitectureSpecific.OSR_OptExecStateExtractor; import org.jikesrvm.adaptive.controller.VM_Controller; import org.jikesrvm.adaptive.controller.VM_ControllerPlan; import org.jikesrvm.adaptive.util.VM_AOSLogging; import org.jikesrvm.compilers.common.VM_CompiledMethod; import org.jikesrvm.compilers.common.VM_CompiledMethods; import org.jikesrvm.compilers.opt.OPT_CompilationPlan; import org.jikesrvm.osr.OSR_ExecStateExtractor; import org.jikesrvm.osr.OSR_ExecutionState; import org.jikesrvm.osr.OSR_Profiler; import org.jikesrvm.osr.OSR_SpecialCompiler; import org.jikesrvm.scheduler.VM_Thread; import org.vmmagic.unboxed.Offset; /** * A OSR_ControllerOnStackReplacementPlan is scheduled by VM_ControllerThread, * and executed by the VM_RecompilationThread. * * It has the suspended thread whose activation being replaced, * and a compilation plan. * * The execution of this plan compiles the method, installs the new * code, and reschedule the thread. */ public class OSR_OnStackReplacementPlan implements VM_Constants { private final int CMID; private final Offset tsFromFPoff; private final Offset ypTakenFPoff; /* Status is write-only at the moment, but I suspect it comes in * handy for debugging -- RJG */ @SuppressWarnings("unused") private byte status; private final VM_Thread suspendedThread; private final OPT_CompilationPlan compPlan; private int timeInitiated = 0; private int timeCompleted = 0; public OSR_OnStackReplacementPlan(VM_Thread thread, OPT_CompilationPlan cp, int cmid, int source, Offset tsoff, Offset ypoff, double priority) { this.suspendedThread = thread; this.compPlan = cp; this.CMID = cmid; this.tsFromFPoff = tsoff; this.ypTakenFPoff = ypoff; this.status = VM_ControllerPlan.UNINITIALIZED; } public int getTimeInitiated() { return timeInitiated; } public void setTimeInitiated(int t) { timeInitiated = t; } public int getTimeCompleted() { return timeCompleted; } public void setTimeCompleted(int t) { timeCompleted = t; } public void setStatus(byte newStatus) { status = newStatus; } public void execute() { // 1. extract stack state // 2. recompile the specialized method // 3. install the code // 4. reschedule the thread to new code. VM_AOSLogging.logOsrEvent("OSR compiling " + compPlan.method); setTimeInitiated(VM_Controller.controllerClock); { OSR_ExecStateExtractor extractor = null; VM_CompiledMethod cm = VM_CompiledMethods.getCompiledMethod(this.CMID); boolean invalidate = true; if (cm.getCompilerType() == VM_CompiledMethod.BASELINE) { extractor = new OSR_BaselineExecStateExtractor(); // don't need to invalidate when transitioning from baseline invalidate = false; } else if (cm.getCompilerType() == VM_CompiledMethod.OPT) { extractor = new OSR_OptExecStateExtractor(); } else { if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); return; } //////// // states is a list of state: callee -> caller -> caller OSR_ExecutionState state = extractor.extractState(suspendedThread, this.tsFromFPoff, this.ypTakenFPoff, CMID); if (invalidate) { VM_AOSLogging.debug("Invalidate cmid " + CMID); OSR_Profiler.notifyInvalidation(state); } // compile from callee to caller VM_CompiledMethod newCM = OSR_SpecialCompiler.recompileState(state, invalidate); setTimeCompleted(VM_Controller.controllerClock); if (newCM == null) { setStatus(VM_ControllerPlan.ABORTED_COMPILATION_ERROR); VM_AOSLogging.logOsrEvent("OSR compilation failed!"); } else { setStatus(VM_ControllerPlan.COMPLETED); // now let OSR_CodeInstaller generate a code stub, // and OSR_PostThreadSwitch will install the stub to run. OSR_CodeInstaller.install(state, newCM); VM_AOSLogging.logOsrEvent("OSR compilation succeeded! " + compPlan.method); } } suspendedThread.osrResume(); } }