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