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