/**
   * Initialize boot image compiler.
   *
   * @param args command line arguments to the bootimage compiler
   */
  protected void initCompiler(String[] args) {
    try {
      BaselineCompiler.initOptions();
      VM.sysWrite("BootImageCompiler: init (opt compiler)\n");

      // Writing a boot image is a little bit special.  We're not really
      // concerned about compile time, but we do care a lot about the quality
      // and stability of the generated code.  Set the options accordingly.
      OptimizingCompiler.setBootOptions(masterOptions);

      // Allow further customization by the user.
      for (int i = 0, n = args.length; i < n; i++) {
        String arg = args[i];
        if (!masterOptions.processAsOption("-X:bc:", arg)) {
          if (arg.startsWith("exclude=")) {
            excludePattern = arg.substring(8);
          } else {
            VM.sysWrite("BootImageCompiler: Unrecognized argument " + arg + "; ignoring\n");
          }
        }
      }
      EdgeCounts.loadCountsFromFileIfAvailable(masterOptions.PROFILE_EDGE_COUNT_INPUT_FILE);
      OptimizingCompiler.init(masterOptions);
    } catch (OptimizingCompilerException e) {
      String msg = "BootImageCompiler: Compiler failed during initialization: " + e + "\n";
      if (e.isFatal) {
        // An unexpected error when building the opt boot image should be fatal
        e.printStackTrace();
        System.exit(VM.EXIT_STATUS_OPT_COMPILER_FAILED);
      } else {
        VM.sysWrite(msg);
      }
    }
  }
 /**
  * Compile a method with bytecodes.
  *
  * @param method the method to compile
  * @return the compiled method
  */
 protected CompiledMethod compileMethod(NormalMethod method, TypeReference[] params) {
   if (method.hasNoOptCompileAnnotation()) {
     return baselineCompile(method);
   } else {
     CompiledMethod cm = null;
     OptimizingCompilerException escape = new OptimizingCompilerException(false);
     try {
       Callbacks.notifyMethodCompile(method, CompiledMethod.OPT);
       boolean include = match(method);
       if (!include) {
         throw escape;
       }
       int freeOptimizationPlan = getFreeOptimizationPlan();
       OptimizationPlanElement[] optimizationPlan = optimizationPlans.get(freeOptimizationPlan);
       CompilationPlan cp =
           new CompilationPlan(
               method, params, optimizationPlan, null, options.get(freeOptimizationPlan));
       cm = OptimizingCompiler.compile(cp);
       if (VM.BuildForAdaptiveSystem) {
         /* We can't accurately measure compilation time on Host JVM, so just approximate with DNA */
         int compilerId = CompilerDNA.getCompilerConstant(cp.options.getOptLevel());
         cm.setCompilationTime((float) CompilerDNA.estimateCompileTime(compilerId, method));
       }
       releaseOptimizationPlan(freeOptimizationPlan);
       return cm;
     } catch (OptimizingCompilerException e) {
       if (e.isFatal) {
         // An unexpected error when building the opt boot image should be fatal
         VM.sysWriteln("Error compiling method: " + method);
         e.printStackTrace();
         System.exit(VM.EXIT_STATUS_OPT_COMPILER_FAILED);
       } else {
         boolean printMsg = true;
         if (e instanceof MagicNotImplementedException) {
           printMsg = !((MagicNotImplementedException) e).isExpected;
         }
         if (e == escape) {
           printMsg = false;
         }
         if (printMsg) {
           if (e.toString().indexOf("method excluded") >= 0) {
             String msg = "BootImageCompiler: " + method + " excluded from opt-compilation\n";
             VM.sysWrite(msg);
           } else {
             String msg =
                 "BootImageCompiler: can't optimize \"" + method + "\" (error was: " + e + ")\n";
             VM.sysWrite(msg);
           }
         }
       }
       return baselineCompile(method);
     }
   }
 }