gt:     return planWithStatus(m, ControllerPlan.OSR_BASE_2_OPT);
context: /*
   *  This file is part of the Jikes RVM project (http://jikesrvm.org).
   *
   *  This file is licensed to You under the Eclipse Public License (EPL);
   *  You may not use this file except in compliance with the License. You
   *  may obtain a copy of the License at
   *
   *      http://www.opensource.org/licenses/eclipse-1.0.php
   *
   *  See the COPYRIGHT.txt file distributed with this work for information
   *  regarding copyright ownership.
   */
  package org.jikesrvm.adaptive.controller;
  
  import java.io.PrintStream;
  import java.util.LinkedList;
  import org.jikesrvm.VM;
  import org.jikesrvm.Constants;
  import org.jikesrvm.classloader.RVMMethod;
  import org.jikesrvm.compilers.common.CompiledMethod;
  import org.jikesrvm.compilers.common.CompiledMethods;
  import org.jikesrvm.util.ImmutableEntryHashMapRVM;
  
  /**
   *  This class records decisions taken by the controller.  It will remember
   *  controller plans, which contain compilation plans and other goodies,
   *  and allows searching for previous decisions
   */
  public final class ControllerMemory implements Constants {
  
    /**
     *  This is a hashtable of controller plans indexed by RVMMethod.
     *  Each method can have a list of such plans associated with.
     */
    private static final ImmutableEntryHashMapRVM<RVMMethod, LinkedList<ControllerPlan>> table =
        new ImmutableEntryHashMapRVM<RVMMethod, LinkedList<ControllerPlan>>();
  
    /**
     * Number of times controller is awoken and did nothing.
     */
    private static int didNothing = 0;
  
    /**
     * Number of times controller is awoken
     */
    private static int awoken = 0;
  
    // counters for chosen opt levels
    private static int numMethodsConsidered = 0;
    private static int numMethodsScheduledForRecomp = 0;
    private static int numBase = 0;
    private static int numOpt0 = 0;
    private static int numOpt1 = 0;
    private static int numOpt2 = 0;
    private static int numOpt3 = 0;
    private static int numOpt4 = 0;
  
    public static int getNumAwoken() { return awoken; }
  
    public static int getNumDidNothing() { return didNothing; }
  
    public static int getNumMethodsConsidered() { return numMethodsConsidered; }
  
    public static int getNumMethodsScheduledForRecomp() { return numMethodsScheduledForRecomp; }
  
    public static int getNumBase() { return numBase; }
  
    public static int getNumOpt0() { return numOpt0; }
  
    public static int getNumOpt1() { return numOpt1; }
  
    public static int getNumOpt2() { return numOpt2; }
  
    public static int getNumOpt3() { return numOpt3; }
  
    static int getNumOpt4() { return numOpt4; }
  
    static void incrementNumAwoken() { awoken++; }
  
    static void incrementNumDidNothing() { didNothing++; }
  
    static void incrementNumMethodsConsidered() { numMethodsConsidered++; }
  
    static void incrementNumMethodsScheduledForRecomp() { numMethodsScheduledForRecomp++; }
  
    public static void incrementNumBase() { numBase++; }
  
    static void incrementNumOpt0() { numOpt0++; }
  
    static void incrementNumOpt1() { numOpt1++; }
  
    static void incrementNumOpt2() { numOpt2++; }
  
    static void incrementNumOpt3() { numOpt3++; }
  
    static void incrementNumOpt4() { numOpt4++; }
  
    /**
     *  Inserts a controller plan keyed on the underlying method
     *
     *  @param plan the controller plan to insert
     */
    static synchronized void insert(ControllerPlan plan) {
  
      numMethodsScheduledForRecomp++;
      int optLevel = plan.getCompPlan().options.getOptLevel();
      switch (optLevel) {
        case 0:
          numOpt0++;
          break;
        case 1:
          numOpt1++;
          break;
        case 2:
          numOpt2++;
          break;
        case 3:
          numOpt3++;
          break;
        case 4:
          numOpt4++;
          break;
        default:
          if (VM.VerifyAssertions) VM._assert(NOT_REACHED, "Unknown Opt Level");
      }
  
      // first check to see if there is a plan list for this method
      LinkedList<ControllerPlan> planList = findPlan(plan.getCompPlan().method);
  
      if (planList == null) {
        // create a plan list, with the single element being this plan
        planList = new LinkedList<ControllerPlan>();
  
        // no synch needed here because the planList is not in the table yet
        planList.addLast(plan);
  
        // insert in the hashtable using the method as the hash value
        table.put(plan.getCompPlan().method, planList);
      } else {
        // add the current plan to the end of the list
        synchronized (planList) {
          planList.addLast(plan);
        }
      }
  
      // tell the plan what list it is on
      plan.setPlanList(planList);
    }
  
    /**
     * Looks for a controller plan for the passed method
     *
     * @param method   The method to look for
     * @return the list of controller plans for this method if one exists,
     *         otherwise, {@code null}
     */
    private static synchronized LinkedList<ControllerPlan> findPlan(RVMMethod method) {
      return table.get(method);
    }
  
    /**
     *  Find the plan for the compiled method that is passed
     *  @param cmpMethod the compiled method of interest
     *  @return the matching plan or {@code null} if none exists.
     */
    public static synchronized ControllerPlan findMatchingPlan(CompiledMethod cmpMethod) {
      RVMMethod method = cmpMethod.getMethod();
  
      LinkedList<ControllerPlan> planList = findPlan(method);
      if (planList == null) {
        return null;
      } else {
        // iterate over the planList until we get to this item
        synchronized (planList) {
          for (ControllerPlan plan : planList) {
            // exit when we find ourselves
            if (plan.getCMID() == cmpMethod.getId()) {
              return plan;
            }
          } // more to process
        }
        return null;
      }
    }
  
    /**
     *  Determine if the passed method should be considered as a candidate
     *  for _initial_ AOS recompilation.
     *  A method should not be reconsider for initial AOS recompilation if
     *  a plan already exists for the method whose status is {@link ControllerPlan#IN_PROGRESS},
     *  {@link ControllerPlan#COMPLETED}, {@link ControllerPlan#OUTDATED},
     *  or {@link ControllerPlan#ABORTED_COMPILATION_ERROR} because of compilation error.
     *
     *  @param method the method of interest
     *  @return whether the method should be considered or not
     */
    static synchronized boolean shouldConsiderForInitialRecompilation(RVMMethod method) {
      LinkedList<ControllerPlan> planList = findPlan(method);
      if (planList == null) {
        return true;
      } else {
        // iterate over the planList until we find a plan whose status is
        // inprogress, completed,
        synchronized (planList) {
          for (ControllerPlan curPlan : planList) {
            // exit when we find ourselves
            byte status = curPlan.getStatus();
            if (status == ControllerPlan.COMPLETED ||
                status == ControllerPlan.IN_PROGRESS ||
                status == ControllerPlan.ABORTED_COMPILATION_ERROR ||
                status == ControllerPlan.OUTDATED) {
              return false;
            }
          }
        }
        return true;  // we didn't find any, so return true
      }
    }
  
    /**
     * Return {@code true} if there is a plan with the given status for the given method
     *
     * @param method the method of interest
     * @param status the status of interest
     * @return whether or not there is plan with that status for the method
     */
    static synchronized boolean planWithStatus(RVMMethod method, byte status) {
      LinkedList<ControllerPlan> planList = findPlan(method);
      if (planList != null) {
        // iterate over the planList until we find a plan with status 'status'
        synchronized (planList) {
          for (ControllerPlan curPlan : planList) {
            if (curPlan.getStatus() == status) {
              return true;
            }
          }
        }
      }
      return false;
    }
  
    /**
     * Return {@code true} iff there is a plan to transition from Base to Opt for a
     * given CMID.
     */
    public static synchronized boolean requestedOSR(int cmid) {
      CompiledMethod cm = CompiledMethods.getCompiledMethod(cmid);
  
      // make sure that the cm in question is baseline-compiled
      if (cm.getCompilerType() != CompiledMethod.BASELINE) return false;
  
      // OK; now check for an OSR plan
      RVMMethod m = cm.getMethod();
      if (m == null) return false;
  