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    }