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.opt.specialization;
014    
015    import org.jikesrvm.classloader.NormalMethod;
016    import org.jikesrvm.compilers.common.CompiledMethod;
017    import org.jikesrvm.compilers.opt.OptOptions;
018    import org.jikesrvm.compilers.opt.driver.CompilationPlan;
019    import org.jikesrvm.compilers.opt.driver.OptimizationPlanElement;
020    import org.jikesrvm.compilers.opt.driver.OptimizationPlanner;
021    import org.jikesrvm.compilers.opt.driver.OptimizingCompiler;
022    
023    /**
024     * This class represents a specialization context meaning
025     * "the invokee is thread local".
026     * We use this context to remove unnecessary synchronizations.
027     */
028    public final class InvokeeThreadLocalContext implements SpecializationContext {
029    
030      public InvokeeThreadLocalContext() {
031      }
032    
033      /**
034       * Find or create a specialized method in this context.
035       * @param source
036       */
037      public SpecializedMethod findOrCreateSpecializedVersion(NormalMethod source) {
038        // first check if the specialization database contains
039        // a specialized version from this context.
040        java.util.Iterator<SpecializedMethod> versions = SpecializationDatabase.getSpecialVersions(source);
041        if (versions != null) {
042          while (versions.hasNext()) {
043            SpecializedMethod spMethod = versions.next();
044            SpecializationContext context = spMethod.getSpecializationContext();
045            if (context == this) {
046              return spMethod;
047            }
048          }
049        }
050        // none found. create one.
051        SpecializedMethod spMethod = createSpecializedMethod(source);
052        // register it in the database.
053        SpecializationDatabase.registerSpecialVersion(spMethod);
054        // return it.
055        return spMethod;
056      }
057    
058      /**
059       * Create specialized method in this context.
060       * @param method
061       */
062      private SpecializedMethod createSpecializedMethod(NormalMethod method) {
063        return (new SpecializedMethod(method, this));
064      }
065    
066      /**
067       * Generate code to specialize a method in this context. Namely, invoke
068       * the opt compiler with the INVOKEE_THREAD_LOCAL option.
069       * @param source
070       */
071      public CompiledMethod specialCompile(NormalMethod source) {
072        CompilationPlan plan = new CompilationPlan(source, optimizationPlan, null, options);
073        return OptimizingCompiler.compile(plan);
074      }
075    
076      /**
077       * The default optimization options, with the INVOKEE_THREAD_LOCAL flag
078       * set true.
079       */
080      private static OptOptions options;
081      /**
082       * The default optimization plan.
083       */
084      private static OptimizationPlanElement[] optimizationPlan;
085    
086      /**
087       * Initialize static members.
088       */
089      public static void init() {
090        options = new OptOptions();
091        optimizationPlan = OptimizationPlanner.createOptimizationPlan(options);
092        // all objects in the specialized method will be thread local
093        options.ESCAPE_INVOKEE_THREAD_LOCAL = true;
094      }
095    }
096