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