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.classloader.ClassLoaderConstants.LongTypeCode;
016import static org.jikesrvm.osr.OSRConstants.LOCAL;
017
018import org.jikesrvm.VM;
019import org.jikesrvm.compilers.opt.ir.operand.Operand;
020import org.vmmagic.unboxed.Word;
021
022/**
023 * An LocalRegPair keeps the type information and location of
024 * a local variable/stack slot from byte code to machine code.
025 */
026public class LocalRegPair {
027
028  /** is it a local or stack? */
029  public final boolean kind;
030
031  /** what's the number of local of stack */
032  public int num;
033
034  /** what's the type code? ('I', 'J', 'D', etc) */
035  public final byte typeCode;
036
037  /**
038   * What's the register operand, from which we can get the symbolic register.
039   * The operand could be symbolic register, or constants, we need to take
040   * it out later.
041   */
042  public final Operand operand;
043
044  /* rest part only available after the OSR maps were updated */
045
046  /**
047   * A reg value could be
048   * <ul>
049   *   <li>an integer constant (ICONST),
050   *   <li>a physical register (PHYREG), or
051   *   <li>a spill on the stack (SPILL).
052   * </ul>
053   * <p>
054   * The  valueType is one of them, combined with the typeCode, one should be
055   * able to recover the value of a variable.
056   */
057  public byte valueType;
058
059  /**
060   * The meaning of value field depends on valueType:
061   * <ul>
062   *   <li>for ICONST, ACONST and LCONST, it is the value of the constant,
063   *   <li>for PHYREG, it is the register number,
064   *   <li>for SPILL, it is the spill location.
065   * </ul>
066   */
067  public Word value;
068
069  /**
070   * A LONG variable takes two symbolic registers, we need to know another
071   * half part.
072   */
073  public LocalRegPair _otherHalf;
074
075  /* The LiveAnalysis phase builds the linked list of tuples, and
076   * the long type variables will get another half register
077   * ( split in BURS ).
078   * After register allocation, we should not use <code>operand</code>
079   * anymore. The physical register number, spilled location, or
080   * constant value is represented by (valueType, value)
081   */
082  public LocalRegPair(boolean kind, int num, byte type, Operand op) {
083    this.kind = kind;
084    this.num = num;
085    this.typeCode = type;
086    this.operand = op;
087  }
088
089  public LocalRegPair copy() {
090    return new LocalRegPair(kind, num, typeCode, operand);
091  }
092
093  /**
094   * converts tuple to string as
095   * ( L/S num, type, valueType, value, operand )
096   */
097  @Override
098  public String toString() {
099    StringBuilder buf = new StringBuilder("(");
100
101    buf.append(kind == LOCAL ? 'L' : 'S');
102    buf.append(num).append(" , ");
103
104    char tcode = (char) typeCode;
105
106    buf.append(tcode).append(" , ");
107    buf.append(valueType).append(" , ");
108    buf.append("0x").append(Long.toHexString(value.toLong())).append(" , ");
109    buf.append(operand).append(")");
110
111    // for long type, append another half
112    if (VM.BuildFor32Addr && (tcode == LongTypeCode)) {
113      buf.append("(").append(_otherHalf.valueType).append(" , ");
114      buf.append("0x").append(Integer.toHexString(_otherHalf.value.toInt())).append(")");
115    }
116    return buf.toString();
117  }
118}
119