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