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      /**
044       * A reg value could be
045       * <ul>
046       *   <li>an integer constant (ICONST),
047       *   <li>a physical register (PHYREG), or
048       *   <li>a spill on the stack (SPILL).
049       * </ul>
050       * <p>
051       * The  valueType is one of them, combined with the typeCode, one should be
052       * able to recover the value of a variable.
053       */
054      public byte valueType;
055    
056      /**
057       * The meaning of value field depends on valueType:
058       * <ul>
059       *   <li>for ICONST, ACONST and LCONST, it is the value of the constant,
060       *   <li>for PHYREG, it is the register number,
061       *   <li>for SPILL, it is the spill location.
062       * </ul>
063       */
064      public Word value;
065    
066      /**
067       * A LONG variable takes two symbolic registers, we need to know another
068       * half part.
069       */
070      public LocalRegPair _otherHalf;
071    
072      /* The LiveAnalysis phase builds the linked list of tuples, and
073       * the long type variables will get another half register
074       * ( split in BURS ).
075       * After register allocation, we should not use <code>operand</code>
076       * anymore. The physical register number, spilled location, or
077       * constant value is represented by (valueType, value)
078       */
079      public LocalRegPair(boolean kind, int num, byte type, Operand op) {
080        this.kind = kind;
081        this.num = num;
082        this.typeCode = type;
083        this.operand = op;
084      }
085    
086      public LocalRegPair copy() {
087        return new LocalRegPair(kind, num, typeCode, operand);
088      }
089    
090      /**
091       * converts tuple to string as
092       * ( L/S num, type, valueType, value, operand )
093       */
094      @Override
095      public String toString() {
096        StringBuilder buf = new StringBuilder("(");
097    
098        buf.append(kind == LOCAL ? 'L' : 'S');
099        buf.append(num).append(" , ");
100    
101        char tcode = (char) typeCode;
102    
103        buf.append(tcode).append(" , ");
104        buf.append(valueType).append(" , ");
105        buf.append("0x").append(Long.toHexString(value.toLong())).append(" , ");
106        buf.append(operand).append(")");
107    
108        // for long type, append another half
109        if (VM.BuildFor32Addr && (tcode == LongTypeCode)) {
110          buf.append("(").append(_otherHalf.valueType).append(" , ");
111          buf.append("0x").append(Integer.toHexString(_otherHalf.value.toInt())).append(")");
112        }
113        return buf.toString();
114      }
115    }
116