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.adaptive.controller.ControllerInputEvent;
017    import org.jikesrvm.adaptive.controller.ControllerMemory;
018    import org.jikesrvm.adaptive.controller.ControllerPlan;
019    import org.jikesrvm.adaptive.util.AOSLogging;
020    import org.jikesrvm.classloader.NormalMethod;
021    import org.jikesrvm.compilers.common.CompiledMethod;
022    import org.jikesrvm.compilers.common.CompiledMethods;
023    import org.jikesrvm.compilers.common.RuntimeCompiler;
024    import org.jikesrvm.compilers.opt.OptOptions;
025    import org.jikesrvm.compilers.opt.driver.CompilationPlan;
026    import org.jikesrvm.compilers.opt.driver.OptimizationPlanElement;
027    import org.jikesrvm.scheduler.RVMThread;
028    import org.vmmagic.unboxed.Offset;
029    
030    /**
031     * Event generated by a thread aware of on-stack-replacement request.
032     * The event is feed to the controller with suspended thread, and hot
033     * method id. Since it does not need to go through analytic model, it does
034     * not extend the HotMethodEvent.
035     */
036    public final class OnStackReplacementEvent implements ControllerInputEvent {
037    
038      /** the suspended thread. */
039      public RVMThread suspendedThread;
040    
041      /** remember where it comes from */
042      public int whereFrom;
043    
044      /** the compiled method id */
045      public int CMID;
046    
047      /** the threadSwithFrom fp offset */
048      public Offset tsFromFPoff;
049    
050      /** the osr method's fp offset */
051      public Offset ypTakenFPoff;
052    
053      /**
054       * This function will generate a controller plan and
055       * inserted in the recompilation queue.
056       */
057      @Override
058      public void process() {
059    
060        CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(CMID);
061    
062        NormalMethod todoMethod = (NormalMethod) compiledMethod.getMethod();
063    
064        double priority;
065        OptOptions options;
066        OptimizationPlanElement[] optimizationPlan;
067    
068        ControllerPlan oldPlan = ControllerMemory.findLatestPlan(todoMethod);
069    
070        if (oldPlan != null) {
071          CompilationPlan oldCompPlan = oldPlan.getCompPlan();
072          priority = oldPlan.getPriority();
073          options = oldCompPlan.options;
074          optimizationPlan = oldCompPlan.optimizationPlan;
075        } else {
076          priority = 5.0;
077          options = (OptOptions) RuntimeCompiler.options;
078          optimizationPlan = (OptimizationPlanElement[]) RuntimeCompiler.optimizationPlan;
079        }
080    
081        CompilationPlan compPlan = new CompilationPlan(todoMethod, optimizationPlan, null, options);
082    
083        OnStackReplacementPlan plan =
084            new OnStackReplacementPlan(this.suspendedThread,
085                                           compPlan,
086                                           this.CMID,
087                                           this.whereFrom,
088                                           this.tsFromFPoff,
089                                           this.ypTakenFPoff,
090                                           priority);
091    
092        Controller.compilationQueue.insert(priority, plan);
093    
094        AOSLogging.logger.logOsrEvent("OSR inserts compilation plan successfully!");
095    
096        // do not hold the reference anymore.
097        suspendedThread = null;
098        CMID = 0;
099      }
100    }