Пример #1
0
  /* Compiles the method with the baseline compiler.
   * 1. generate  prologue (PSEUDO_bytecode) from the state.
   * 2. make up new byte code with prologue.
   * 3. set method's bytecode to the specilizaed byte code.
   * 4. call BaselineCompilerImpl.compile,
   *    the 'compile' method is customized to process pseudo instructions,
   *    and it will reset the byte code to the original one, and adjust
   *    the map from bytecode to the generated machine code. then the
   *    reference map can be generated corrected relying on the original
   *    bytecode.
   * NOTE: this is different from optCompile which resets the
   *    bytecode after compilation. I believe this minimizes the
   *    work to change both compilers.
   */
  public static CompiledMethod baselineCompile(ExecutionState state) {
    NormalMethod method = state.getMethod();

    if (VM.TraceOnStackReplacement) {
      VM.sysWriteln("BASE : starts compiling " + method);
    }

    /* generate prologue bytes */
    byte[] prologue = state.generatePrologue();

    if (VM.TraceOnStackReplacement) {
      VM.sysWriteln("prologue length " + prologue.length);
    }

    // the compiler will call setForOsrSpecialization after generating the reference map
    /* set a flag for specialization, compiler will see it, and
     * know how to do it properly.
     */
    method.setForOsrSpecialization(prologue, state.getMaxStackHeight());

    /* for baseline compilation, we do not adjust the exception table and line table
     * because the compiler will generate maps after compilation.
     * Any necessary adjustment should be made during the compilation
     */
    CompiledMethod newCompiledMethod = BaselineCompilerImpl.compile(method);

    // compiled method was already set by BaselineCompilerImpl.compile
    // the call here does nothing
    //    method.finalizeOsrSpecialization();

    // mark the method is a specialized one
    newCompiledMethod.setSpecialForOSR();

    if (VM.TraceOnStackReplacement) {
      //        ((BaselineCompiledMethod)newCompiledMethod).printCodeMapEntries();
      VM.sysWriteln(
          "BASE : done, CMID 0x"
              + Integer.toHexString(newCompiledMethod.getId())
              + "("
              + newCompiledMethod.getId()
              + ") JTOC offset "
              + VM.addressAsHexString(newCompiledMethod.getOsrJTOCoffset().toWord().toAddress()));
    }

    return newCompiledMethod;
  }
Пример #2
0
  /**
   * 1. generate prologue PSEUDO_bytecode from the state. 2. make new bytecodes with prologue. 3.
   * set method's bytecode to specialized one. 4. adjust exception map, line number map. 5. compile
   * the method. 6. restore bytecode, exception, linenumber map to the original one.
   */
  public static CompiledMethod optCompile(ExecutionState state) {

    NormalMethod method = state.getMethod();
    if (VM.TraceOnStackReplacement) {
      VM.sysWriteln("OPT : starts compiling " + method);
    }

    ControllerPlan latestPlan = ControllerMemory.findLatestPlan(method);

    OptOptions _options = null;
    if (latestPlan != null) {
      _options = latestPlan.getCompPlan().options.dup();
    } else {
      // no previous compilation plan, a long run loop promoted from baseline.
      // this only happens when testing, not in real code
      _options = new OptOptions();
      _options.setOptLevel(0);
    }
    // disable OSR points in specialized method
    _options.OSR_GUARDED_INLINING = false;

    CompilationPlan compPlan =
        new CompilationPlan(
            method, (OptimizationPlanElement[]) RuntimeCompiler.optimizationPlan, null, _options);

    // it is also necessary to recompile the current method
    // without OSR.

    /* generate prologue bytes */
    byte[] prologue = state.generatePrologue();
    int prosize = prologue.length;

    method.setForOsrSpecialization(prologue, state.getMaxStackHeight());

    int[] oldStartPCs = null;
    int[] oldEndPCs = null;
    int[] oldHandlerPCs = null;

    /* adjust exception table. */
    {
      // if (VM.TraceOnStackReplacement) { VM.sysWrite("OPT adjust exception table.\n"); }

      ExceptionHandlerMap exceptionHandlerMap = method.getExceptionHandlerMap();

      if (exceptionHandlerMap != null) {

        oldStartPCs = exceptionHandlerMap.getStartPC();
        oldEndPCs = exceptionHandlerMap.getEndPC();
        oldHandlerPCs = exceptionHandlerMap.getHandlerPC();

        int n = oldStartPCs.length;

        int[] newStartPCs = new int[n];
        System.arraycopy(oldStartPCs, 0, newStartPCs, 0, n);
        exceptionHandlerMap.setStartPC(newStartPCs);

        int[] newEndPCs = new int[n];
        System.arraycopy(oldEndPCs, 0, newEndPCs, 0, n);
        exceptionHandlerMap.setEndPC(newEndPCs);

        int[] newHandlerPCs = new int[n];
        System.arraycopy(oldHandlerPCs, 0, newHandlerPCs, 0, n);
        exceptionHandlerMap.setHandlerPC(newHandlerPCs);

        for (int i = 0; i < n; i++) {
          newStartPCs[i] += prosize;
          newEndPCs[i] += prosize;
          newHandlerPCs[i] += prosize;
        }
      }
    }

    CompiledMethod newCompiledMethod =
        RuntimeCompiler.recompileWithOptOnStackSpecialization(compPlan);

    // restore original bytecode, exception table, and line number table
    method.finalizeOsrSpecialization();

    {
      ExceptionHandlerMap exceptionHandlerMap = method.getExceptionHandlerMap();

      if (exceptionHandlerMap != null) {
        exceptionHandlerMap.setStartPC(oldStartPCs);
        exceptionHandlerMap.setEndPC(oldEndPCs);
        exceptionHandlerMap.setHandlerPC(oldHandlerPCs);
      }
    }

    // compilation failed because compilation is in progress,
    // reverse back to the baseline
    if (newCompiledMethod == null) {
      if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("OPT : fialed, because compilation in progress, " + "fall back to baseline");
      }
      return baselineCompile(state);
    }

    // mark the method is a specialized one
    newCompiledMethod.setSpecialForOSR();

    if (VM.TraceOnStackReplacement) VM.sysWriteln("OPT : done\n");

    return newCompiledMethod;
  }