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.osr;
014    
015    import java.util.Enumeration;
016    
017    import org.jikesrvm.compilers.opt.OptOptions;
018    import org.jikesrvm.compilers.opt.driver.CompilerPhase;
019    import org.jikesrvm.compilers.opt.driver.OptConstants;
020    import org.jikesrvm.compilers.opt.inlining.InlineSequence;
021    import org.jikesrvm.compilers.opt.ir.IR;
022    import org.jikesrvm.compilers.opt.ir.Instruction;
023    
024    /**
025     * OSR_AdjustBCIndex is an optimizing phase performed on HIR.
026     * It adjust the byte code index of instructions from specialized
027     * byte code to its original byte code.
028     */
029    public class AdjustBCIndexes extends CompilerPhase {
030    
031      @Override
032      public final boolean shouldPerform(OptOptions options) {
033        return true;
034      }
035    
036      /**
037       * Return this instance of this phase. This phase contains no
038       * per-compilation instance fields.
039       * @param ir not used
040       * @return this
041       */
042      @Override
043      public CompilerPhase newExecution(IR ir) {
044        return this;
045      }
046    
047      @Override
048      public final String getName() { return "AdjustBytecodeIndexes"; }
049    
050      @Override
051      public final void perform(IR ir) {
052        if (!ir.method.isForOsrSpecialization()) return;
053        int offset = ir.method.getOsrPrologueLength();
054    
055        for (Enumeration<Instruction> ie = ir.forwardInstrEnumerator(); ie.hasMoreElements();) {
056          Instruction s = ie.nextElement();
057    
058          if ((s.position != null) && (s.position.method != ir.method)) {
059            // also adjust InlineSequence of the direct callee
060            InlineSequence caller = s.position.caller;
061            if ((caller != null) && (caller.method == ir.method)) {
062              // adjust the call site's bcIndex
063              s.position.bcIndex -= offset;
064            }
065            continue;
066          }
067    
068          if (s.bcIndex >= offset) {
069            s.bcIndex -= offset;
070          } else if (s.bcIndex >= 0) {
071            s.bcIndex = OptConstants.OSR_PROLOGUE;
072          }
073        }
074      }
075    }