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