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