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 */
013package org.jikesrvm.compilers.common;
014
015import org.jikesrvm.VM;
016import org.jikesrvm.classloader.NativeMethod;
017import org.jikesrvm.classloader.NormalMethod;
018import org.jikesrvm.classloader.TypeReference;
019import org.jikesrvm.compilers.baseline.BaselineBootImageCompiler;
020import org.jikesrvm.runtime.Callbacks;
021
022/**
023 * Abstract superclass to interface bootimage compiler to the rest of the VM.
024 * Individual compilers provide concrete implementations, one of which is
025 * instantiated by BootImageCompiler.init.
026 */
027public abstract class BootImageCompiler {
028
029  protected static final BootImageCompiler baseCompiler;
030  protected static final BootImageCompiler optCompiler;
031  protected static final BootImageCompiler compiler;
032
033  static {
034    baseCompiler = new BaselineBootImageCompiler();
035    optCompiler = VM.BuildForAdaptiveSystem ? new org.jikesrvm.compilers.opt.driver.OptimizingBootImageCompiler() : null;
036    compiler = VM.BuildWithBaseBootImageCompiler ? baseCompiler : optCompiler;
037  }
038
039  /**
040   * Initialize boot image compiler.
041   * @param args command line arguments to the bootimage compiler
042   */
043  protected abstract void initCompiler(String[] args);
044
045  /**
046   * Compiles a method with bytecodes.
047   * @param method the method to compile
048   * @param params the specialized types of the method's parameters.
049   *  This will be {@code null} if the types from the method's signature are used.
050   * @return the compiled method
051   */
052  protected abstract CompiledMethod compileMethod(NormalMethod method, TypeReference[] params);
053
054  /**
055   * Initialize boot image compiler.
056   * @param args command line arguments to the bootimage compiler
057   */
058  public static void init(String[] args) {
059    try {
060      compiler.initCompiler(args);
061      if (VM.BuildForAdaptiveSystem && VM.BuildWithBaseBootImageCompiler) {
062        // We have to use the opt compiler to compile the org.jikesrvm.compiler.opt.OptSaveVolatile class,
063        // so if we're building a baseline compiled configuration that includes AOS, we also need to init
064        // the optimizing bootimage compiler so it can be invoked to compile this class.
065        optCompiler.initCompiler(args);
066      }
067    } catch (Throwable e) {
068      while (e != null) {
069        e.printStackTrace();
070        e = e.getCause();
071      }
072    }
073  }
074
075  public static CompiledMethod compile(NormalMethod method, TypeReference[] params) {
076    try {
077      if (VM.BuildForAdaptiveSystem && VM.BuildWithBaseBootImageCompiler && method.getDeclaringClass().hasSaveVolatileAnnotation()) {
078        // Force opt compilation of SaveVolatile methods.
079        return optCompiler.compileMethod(method, params);
080      } else {
081        return compiler.compileMethod(method, params);
082      }
083    } catch (Exception e) {
084      throw new Error("Exception during compilation of " + method, e);
085    }
086  }
087
088  public static CompiledMethod compile(NormalMethod method) {
089    return compile(method, null);
090  }
091
092  /**
093   * Compile a native method.
094   * @param method the method to compile
095   * @return the compiled method
096   */
097  public static CompiledMethod compile(NativeMethod method) {
098    Callbacks.notifyMethodCompile(method, CompiledMethod.JNI);
099
100    if (VM.BuildForIA32) {
101      return org.jikesrvm.jni.ia32.JNICompiler.compile(method);
102    } else {
103      if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC);
104      return org.jikesrvm.jni.ppc.JNICompiler.compile(method);
105    }
106  }
107}