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.adaptive.controller.Controller;
016 import org.jikesrvm.classloader.RVMMethod;
017 import org.jikesrvm.compilers.common.CompiledMethod;
018 import org.jikesrvm.compilers.common.CompiledMethods;
019 import org.jikesrvm.scheduler.RVMThread;
020 import org.vmmagic.pragma.NoInline;
021 import org.vmmagic.pragma.Unpreemptible;
022 import org.vmmagic.unboxed.Offset;
023
024 /**
025 * Trigger an OSR from a running thread.
026 */
027 public class OnStackReplacementTrigger {
028
029 /**
030 * Trigger an OSR from a running thread.
031 */
032 @NoInline
033 @Unpreemptible
034 public static void trigger(int ypTakenInCMID, Offset tsFromFPoff, Offset ypTakenFPoff, int whereFrom) {
035
036 RVMThread thread = RVMThread.getCurrentThread();
037 CompiledMethod ypTakenInCM = CompiledMethods.getCompiledMethod(ypTakenInCMID);
038 RVMMethod ypTakenInMethod = ypTakenInCM.getMethod();
039 boolean isInBootImage = ypTakenInMethod.getDeclaringClass().isInBootImage();
040
041 if (isInBootImage) return;
042 OnStackReplacementEvent event = (OnStackReplacementEvent) thread.onStackReplacementEvent;
043 event.suspendedThread = thread;
044 event.whereFrom = whereFrom;
045 event.CMID = ypTakenInCMID;
046 event.tsFromFPoff = tsFromFPoff;
047 event.ypTakenFPoff = ypTakenFPoff;
048
049 thread.monitor().lockNoHandshake();
050 thread.requesting_osr = true;
051 thread.monitor().unlock();
052
053 Controller.osrOrganizer.activate();
054 // PNT: Assumes that OSR doesn't need access to our context regs
055 thread.monitor().lockNoHandshake();
056 while (!thread.osr_done) {
057 thread.monitor().waitWithHandshake();
058 }
059 thread.osr_done=false;
060 thread.monitor().unlock();
061 }
062 }