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