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; 014 015 import org.jikesrvm.VM; 016 import org.jikesrvm.Constants; 017 import org.jikesrvm.ArchitectureSpecificOpt.BaselineExecutionStateExtractor; 018 import org.jikesrvm.ArchitectureSpecificOpt.CodeInstaller; 019 import org.jikesrvm.ArchitectureSpecificOpt.OptExecutionStateExtractor; 020 import org.jikesrvm.adaptive.controller.Controller; 021 import org.jikesrvm.adaptive.controller.ControllerPlan; 022 import org.jikesrvm.adaptive.util.AOSLogging; 023 import org.jikesrvm.compilers.common.CompiledMethod; 024 import org.jikesrvm.compilers.common.CompiledMethods; 025 import org.jikesrvm.compilers.opt.driver.CompilationPlan; 026 import org.jikesrvm.osr.ExecutionStateExtractor; 027 import org.jikesrvm.osr.ExecutionState; 028 import org.jikesrvm.osr.OSRProfiler; 029 import org.jikesrvm.osr.SpecialCompiler; 030 import org.jikesrvm.scheduler.RVMThread; 031 import org.vmmagic.unboxed.Offset; 032 033 /** 034 * A OSR_ControllerOnStackReplacementPlan is scheduled by ControllerThread, 035 * and executed by the RecompilationThread.<p> 036 * 037 * It has the suspended thread whose activation being replaced, 038 * and a compilation plan.<p> 039 * 040 * The execution of this plan compiles the method, installs the new 041 * code, and reschedule the thread. 042 */ 043 public class OnStackReplacementPlan implements Constants { 044 private final int CMID; 045 private final Offset tsFromFPoff; 046 private final Offset ypTakenFPoff; 047 048 /** 049 * Status is write-only at the moment, but I suspect it comes in 050 * handy for debugging -- RJG 051 */ 052 @SuppressWarnings("unused") 053 private byte status; 054 055 private final RVMThread suspendedThread; 056 private final CompilationPlan compPlan; 057 058 private int timeInitiated = 0; 059 private int timeCompleted = 0; 060 061 public OnStackReplacementPlan(RVMThread thread, CompilationPlan cp, int cmid, int source, Offset tsoff, 062 Offset ypoff, double priority) { 063 this.suspendedThread = thread; 064 this.compPlan = cp; 065 this.CMID = cmid; 066 this.tsFromFPoff = tsoff; 067 this.ypTakenFPoff = ypoff; 068 this.status = ControllerPlan.UNINITIALIZED; 069 } 070 071 public int getTimeInitiated() { return timeInitiated; } 072 073 public void setTimeInitiated(int t) { timeInitiated = t; } 074 075 public int getTimeCompleted() { return timeCompleted; } 076 077 public void setTimeCompleted(int t) { timeCompleted = t; } 078 079 public void setStatus(byte newStatus) { 080 status = newStatus; 081 } 082 083 public void execute() { 084 // 1. extract stack state 085 // 2. recompile the specialized method 086 // 3. install the code 087 // 4. reschedule the thread to new code. 088 089 AOSLogging.logger.logOsrEvent("OSR compiling " + compPlan.method); 090 091 setTimeInitiated(Controller.controllerClock); 092 093 { 094 ExecutionStateExtractor extractor = null; 095 096 CompiledMethod cm = CompiledMethods.getCompiledMethod(this.CMID); 097 098 boolean invalidate = true; 099 if (cm.getCompilerType() == CompiledMethod.BASELINE) { 100 extractor = new BaselineExecutionStateExtractor(); 101 // don't need to invalidate when transitioning from baseline 102 invalidate = false; 103 } else if (cm.getCompilerType() == CompiledMethod.OPT) { 104 extractor = new OptExecutionStateExtractor(); 105 } else { 106 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 107 return; 108 } 109 110 //////// 111 // states is a list of state: callee -> caller -> caller 112 ExecutionState state = extractor.extractState(suspendedThread, this.tsFromFPoff, this.ypTakenFPoff, CMID); 113 114 if (invalidate) { 115 AOSLogging.logger.debug("Invalidate cmid " + CMID); 116 OSRProfiler.notifyInvalidation(state); 117 } 118 119 // compile from callee to caller 120 CompiledMethod newCM = SpecialCompiler.recompileState(state, invalidate); 121 122 setTimeCompleted(Controller.controllerClock); 123 124 if (newCM == null) { 125 setStatus(ControllerPlan.ABORTED_COMPILATION_ERROR); 126 AOSLogging.logger.logOsrEvent("OSR compilation failed!"); 127 } else { 128 setStatus(ControllerPlan.COMPLETED); 129 // now let CodeInstaller generate a code stub, 130 // and PostThreadSwitch will install the stub to run. 131 CodeInstaller.install(state, newCM); 132 AOSLogging.logger.logOsrEvent("OSR compilation succeeded! " + compPlan.method); 133 } 134 } 135 136 suspendedThread.monitor().lockNoHandshake(); 137 suspendedThread.osr_done=true; 138 suspendedThread.monitor().broadcast(); 139 suspendedThread.monitor().unlock(); 140 } 141 }