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