comparison agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java @ 1602:136b78722a08

6939203: JSR 292 needs method handle constants Summary: Add new CP types CONSTANT_MethodHandle, CONSTANT_MethodType; extend 'ldc' bytecode. Reviewed-by: twisti, never
author jrose
date Wed, 09 Jun 2010 18:50:45 -0700
parents c18cbe5936b8
children 3b2dea75431e
comparison
equal deleted inserted replaced
1585:49fac4acd688 1602:136b78722a08
23 */ 23 */
24 24
25 package sun.jvm.hotspot.interpreter; 25 package sun.jvm.hotspot.interpreter;
26 26
27 import sun.jvm.hotspot.oops.*; 27 import sun.jvm.hotspot.oops.*;
28 import sun.jvm.hotspot.runtime.*;
28 import sun.jvm.hotspot.utilities.*; 29 import sun.jvm.hotspot.utilities.*;
29 30
30 public class BytecodeLoadConstant extends BytecodeWithCPIndex { 31 public class BytecodeLoadConstant extends BytecodeWithCPIndex {
31 BytecodeLoadConstant(Method method, int bci) { 32 BytecodeLoadConstant(Method method, int bci) {
32 super(method, bci); 33 super(method, bci);
33 } 34 }
34 35
36 public boolean hasCacheIndex() {
37 // normal ldc uses CP index, but fast_aldc uses swapped CP cache index
38 return javaCode() != code();
39 }
40
35 public int index() { 41 public int index() {
36 return javaCode() == Bytecodes._ldc ? 42 int i = javaCode() == Bytecodes._ldc ?
37 (int) (0xFF & javaByteAt(1)) 43 (int) (0xFF & javaByteAt(1))
38 : (int) (0xFFFF & javaShortAt(1)); 44 : (int) (0xFFFF & javaShortAt(1));
45 if (hasCacheIndex()) {
46 return (0xFFFF & VM.getVM().getBytes().swapShort((short) i));
47 } else {
48 return i;
49 }
50 }
51
52 public int poolIndex() {
53 int i = index();
54 if (hasCacheIndex()) {
55 ConstantPoolCache cpCache = method().getConstants().getCache();
56 return cpCache.getEntryAt(i).getConstantPoolIndex();
57 } else {
58 return i;
59 }
60 }
61
62 public int cacheIndex() {
63 if (hasCacheIndex()) {
64 return index();
65 } else {
66 return -1; // no cache index
67 }
68 }
69
70 private Oop getCachedConstant() {
71 int i = cacheIndex();
72 if (i >= 0) {
73 ConstantPoolCache cpCache = method().getConstants().getCache();
74 return cpCache.getEntryAt(i).getF1();
75 }
76 return null;
39 } 77 }
40 78
41 public void verify() { 79 public void verify() {
42 if (Assert.ASSERTS_ENABLED) { 80 if (Assert.ASSERTS_ENABLED) {
43 Assert.that(isValid(), "check load constant"); 81 Assert.that(isValid(), "check load constant");
56 return (ctag.isDouble() || ctag.isLong()) ? true: false; 94 return (ctag.isDouble() || ctag.isLong()) ? true: false;
57 } else { 95 } else {
58 // has to be int or float or String or Klass 96 // has to be int or float or String or Klass
59 return (ctag.isUnresolvedString() || ctag.isString() 97 return (ctag.isUnresolvedString() || ctag.isString()
60 || ctag.isUnresolvedKlass() || ctag.isKlass() 98 || ctag.isUnresolvedKlass() || ctag.isKlass()
99 || ctag.isMethodHandle() || ctag.isMethodType()
61 || ctag.isInt() || ctag.isFloat())? true: false; 100 || ctag.isInt() || ctag.isFloat())? true: false;
62 } 101 }
63 } 102 }
64 103
65 public boolean isKlassConstant() { 104 public boolean isKlassConstant() {
110 return new BytecodeLoadConstant(bcs.method(), bcs.bci()); 149 return new BytecodeLoadConstant(bcs.method(), bcs.bci());
111 } 150 }
112 151
113 public String getConstantValue() { 152 public String getConstantValue() {
114 ConstantPool cpool = method().getConstants(); 153 ConstantPool cpool = method().getConstants();
115 int cpIndex = index(); 154 int cpIndex = poolIndex();
116 ConstantTag ctag = cpool.getTagAt(cpIndex); 155 ConstantTag ctag = cpool.getTagAt(cpIndex);
117 if (ctag.isInt()) { 156 if (ctag.isInt()) {
118 return "<int " + Integer.toString(cpool.getIntAt(cpIndex)) +">"; 157 return "<int " + Integer.toString(cpool.getIntAt(cpIndex)) +">";
119 } else if (ctag.isLong()) { 158 } else if (ctag.isLong()) {
120 return "<long " + Long.toString(cpool.getLongAt(cpIndex)) + "L>"; 159 return "<long " + Long.toString(cpool.getLongAt(cpIndex)) + "L>";
147 Symbol sym = (Symbol) obj; 186 Symbol sym = (Symbol) obj;
148 return "<Class " + sym.asString() + ">"; 187 return "<Class " + sym.asString() + ">";
149 } else { 188 } else {
150 throw new RuntimeException("should not reach here"); 189 throw new RuntimeException("should not reach here");
151 } 190 }
191 } else if (ctag.isMethodHandle() || ctag.isMethodType()) {
192 Oop x = getCachedConstant();
193 int refidx = cpool.getMethodHandleIndexAt(cpIndex);
194 int refkind = cpool.getMethodHandleRefKindAt(cpIndex);
195 return "<MethodHandle kind=" + Integer.toString(refkind) +
196 " ref=" + Integer.toString(refidx)
197 + (x == null ? "" : " @" + x.getHandle()) + ">";
198 } else if (ctag.isMethodType()) {
199 Oop x = getCachedConstant();
200 int refidx = cpool.getMethodTypeIndexAt(cpIndex);
201 return "<MethodType " + cpool.getSymbolAt(refidx).asString()
202 + (x == null ? "" : " @" + x.getHandle()) + ">";
152 } else { 203 } else {
153 if (Assert.ASSERTS_ENABLED) { 204 if (Assert.ASSERTS_ENABLED) {
154 Assert.that(false, "invalid load constant type"); 205 Assert.that(false, "invalid load constant type");
155 } 206 }
156 return null; 207 return null;
160 public String toString() { 211 public String toString() {
161 StringBuffer buf = new StringBuffer(); 212 StringBuffer buf = new StringBuffer();
162 buf.append(getJavaBytecodeName()); 213 buf.append(getJavaBytecodeName());
163 buf.append(spaces); 214 buf.append(spaces);
164 buf.append('#'); 215 buf.append('#');
165 buf.append(Integer.toString(index())); 216 buf.append(Integer.toString(poolIndex()));
217 if (hasCacheIndex()) {
218 buf.append('(');
219 buf.append(Integer.toString(cacheIndex()));
220 buf.append(')');
221 }
166 buf.append(spaces); 222 buf.append(spaces);
167 buf.append(getConstantValue()); 223 buf.append(getConstantValue());
168 if (code() != javaCode()) { 224 if (code() != javaCode()) {
169 buf.append(spaces); 225 buf.append(spaces);
170 buf.append('['); 226 buf.append('[');