Mon, 28 Jun 2010 12:03:05 -0400
Merge
src/share/vm/runtime/arguments.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeDisassembler.java Thu Jun 24 15:38:42 2010 -0700 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeDisassembler.java Mon Jun 28 12:03:05 2010 -0400 1.3 @@ -72,6 +72,7 @@ 1.4 addBytecodeClass(Bytecodes._invokestatic, BytecodeInvoke.class); 1.5 addBytecodeClass(Bytecodes._invokespecial, BytecodeInvoke.class); 1.6 addBytecodeClass(Bytecodes._invokeinterface, BytecodeInvoke.class); 1.7 + addBytecodeClass(Bytecodes._invokedynamic, BytecodeInvoke.class); 1.8 addBytecodeClass(Bytecodes._jsr, BytecodeJsr.class); 1.9 addBytecodeClass(Bytecodes._jsr_w, BytecodeJsrW.class); 1.10 addBytecodeClass(Bytecodes._iload, BytecodeLoad.class);
2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeInvoke.java Thu Jun 24 15:38:42 2010 -0700 2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeInvoke.java Mon Jun 28 12:03:05 2010 -0400 2.3 @@ -54,15 +54,31 @@ 2.4 // returns the name of the invoked method 2.5 public Symbol name() { 2.6 ConstantPool cp = method().getConstants(); 2.7 + if (isInvokedynamic()) { 2.8 + int[] nt = cp.getNameAndTypeAt(indexForFieldOrMethod()); 2.9 + return cp.getSymbolAt(nt[0]); 2.10 + } 2.11 return cp.getNameRefAt(index()); 2.12 } 2.13 2.14 // returns the signature of the invoked method 2.15 public Symbol signature() { 2.16 ConstantPool cp = method().getConstants(); 2.17 + if (isInvokedynamic()) { 2.18 + int[] nt = cp.getNameAndTypeAt(indexForFieldOrMethod()); 2.19 + return cp.getSymbolAt(nt[1]); 2.20 + } 2.21 return cp.getSignatureRefAt(index()); 2.22 } 2.23 2.24 + public int getSecondaryIndex() { 2.25 + if (isInvokedynamic()) { 2.26 + // change byte-ordering of 4-byte integer 2.27 + return VM.getVM().getBytes().swapInt(javaSignedWordAt(1)); 2.28 + } 2.29 + return super.getSecondaryIndex(); // throw an error 2.30 + } 2.31 + 2.32 public Method getInvokedMethod() { 2.33 return method().getConstants().getMethodRefAt(index()); 2.34 } 2.35 @@ -87,6 +103,7 @@ 2.36 public boolean isInvokevirtual() { return adjustedInvokeCode() == Bytecodes._invokevirtual; } 2.37 public boolean isInvokestatic() { return adjustedInvokeCode() == Bytecodes._invokestatic; } 2.38 public boolean isInvokespecial() { return adjustedInvokeCode() == Bytecodes._invokespecial; } 2.39 + public boolean isInvokedynamic() { return adjustedInvokeCode() == Bytecodes._invokedynamic; } 2.40 2.41 public boolean isValid() { return isInvokeinterface() || 2.42 isInvokevirtual() || 2.43 @@ -104,6 +121,11 @@ 2.44 buf.append(spaces); 2.45 buf.append('#'); 2.46 buf.append(Integer.toString(indexForFieldOrMethod())); 2.47 + if (isInvokedynamic()) { 2.48 + buf.append('('); 2.49 + buf.append(Integer.toString(getSecondaryIndex())); 2.50 + buf.append(')'); 2.51 + } 2.52 buf.append(" [Method "); 2.53 StringBuffer sigBuf = new StringBuffer(); 2.54 new SignatureConverter(signature(), sigBuf).iterateReturntype();
3.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java Thu Jun 24 15:38:42 2010 -0700 3.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java Mon Jun 28 12:03:05 2010 -0400 3.3 @@ -25,6 +25,7 @@ 3.4 package sun.jvm.hotspot.interpreter; 3.5 3.6 import sun.jvm.hotspot.oops.*; 3.7 +import sun.jvm.hotspot.runtime.*; 3.8 import sun.jvm.hotspot.utilities.*; 3.9 3.10 public class BytecodeLoadConstant extends BytecodeWithCPIndex { 3.11 @@ -32,10 +33,47 @@ 3.12 super(method, bci); 3.13 } 3.14 3.15 + public boolean hasCacheIndex() { 3.16 + // normal ldc uses CP index, but fast_aldc uses swapped CP cache index 3.17 + return javaCode() != code(); 3.18 + } 3.19 + 3.20 public int index() { 3.21 - return javaCode() == Bytecodes._ldc ? 3.22 + int i = javaCode() == Bytecodes._ldc ? 3.23 (int) (0xFF & javaByteAt(1)) 3.24 : (int) (0xFFFF & javaShortAt(1)); 3.25 + if (hasCacheIndex()) { 3.26 + return (0xFFFF & VM.getVM().getBytes().swapShort((short) i)); 3.27 + } else { 3.28 + return i; 3.29 + } 3.30 + } 3.31 + 3.32 + public int poolIndex() { 3.33 + int i = index(); 3.34 + if (hasCacheIndex()) { 3.35 + ConstantPoolCache cpCache = method().getConstants().getCache(); 3.36 + return cpCache.getEntryAt(i).getConstantPoolIndex(); 3.37 + } else { 3.38 + return i; 3.39 + } 3.40 + } 3.41 + 3.42 + public int cacheIndex() { 3.43 + if (hasCacheIndex()) { 3.44 + return index(); 3.45 + } else { 3.46 + return -1; // no cache index 3.47 + } 3.48 + } 3.49 + 3.50 + private Oop getCachedConstant() { 3.51 + int i = cacheIndex(); 3.52 + if (i >= 0) { 3.53 + ConstantPoolCache cpCache = method().getConstants().getCache(); 3.54 + return cpCache.getEntryAt(i).getF1(); 3.55 + } 3.56 + return null; 3.57 } 3.58 3.59 public void verify() { 3.60 @@ -58,6 +96,7 @@ 3.61 // has to be int or float or String or Klass 3.62 return (ctag.isUnresolvedString() || ctag.isString() 3.63 || ctag.isUnresolvedKlass() || ctag.isKlass() 3.64 + || ctag.isMethodHandle() || ctag.isMethodType() 3.65 || ctag.isInt() || ctag.isFloat())? true: false; 3.66 } 3.67 } 3.68 @@ -112,7 +151,7 @@ 3.69 3.70 public String getConstantValue() { 3.71 ConstantPool cpool = method().getConstants(); 3.72 - int cpIndex = index(); 3.73 + int cpIndex = poolIndex(); 3.74 ConstantTag ctag = cpool.getTagAt(cpIndex); 3.75 if (ctag.isInt()) { 3.76 return "<int " + Integer.toString(cpool.getIntAt(cpIndex)) +">"; 3.77 @@ -149,6 +188,18 @@ 3.78 } else { 3.79 throw new RuntimeException("should not reach here"); 3.80 } 3.81 + } else if (ctag.isMethodHandle() || ctag.isMethodType()) { 3.82 + Oop x = getCachedConstant(); 3.83 + int refidx = cpool.getMethodHandleIndexAt(cpIndex); 3.84 + int refkind = cpool.getMethodHandleRefKindAt(cpIndex); 3.85 + return "<MethodHandle kind=" + Integer.toString(refkind) + 3.86 + " ref=" + Integer.toString(refidx) 3.87 + + (x == null ? "" : " @" + x.getHandle()) + ">"; 3.88 + } else if (ctag.isMethodType()) { 3.89 + Oop x = getCachedConstant(); 3.90 + int refidx = cpool.getMethodTypeIndexAt(cpIndex); 3.91 + return "<MethodType " + cpool.getSymbolAt(refidx).asString() 3.92 + + (x == null ? "" : " @" + x.getHandle()) + ">"; 3.93 } else { 3.94 if (Assert.ASSERTS_ENABLED) { 3.95 Assert.that(false, "invalid load constant type"); 3.96 @@ -162,7 +213,12 @@ 3.97 buf.append(getJavaBytecodeName()); 3.98 buf.append(spaces); 3.99 buf.append('#'); 3.100 - buf.append(Integer.toString(index())); 3.101 + buf.append(Integer.toString(poolIndex())); 3.102 + if (hasCacheIndex()) { 3.103 + buf.append('('); 3.104 + buf.append(Integer.toString(cacheIndex())); 3.105 + buf.append(')'); 3.106 + } 3.107 buf.append(spaces); 3.108 buf.append(getConstantValue()); 3.109 if (code() != javaCode()) {
4.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithCPIndex.java Thu Jun 24 15:38:42 2010 -0700 4.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithCPIndex.java Mon Jun 28 12:03:05 2010 -0400 4.3 @@ -37,12 +37,19 @@ 4.4 // the constant pool index for this bytecode 4.5 public int index() { return 0xFFFF & javaShortAt(1); } 4.6 4.7 + public int getSecondaryIndex() { 4.8 + throw new IllegalArgumentException("must be invokedynamic"); 4.9 + } 4.10 + 4.11 protected int indexForFieldOrMethod() { 4.12 ConstantPoolCache cpCache = method().getConstants().getCache(); 4.13 // get ConstantPool index from ConstantPoolCacheIndex at given bci 4.14 int cpCacheIndex = index(); 4.15 if (cpCache == null) { 4.16 return cpCacheIndex; 4.17 + } else if (code() == Bytecodes._invokedynamic) { 4.18 + int secondaryIndex = getSecondaryIndex(); 4.19 + return cpCache.getMainEntryAt(secondaryIndex).getConstantPoolIndex(); 4.20 } else { 4.21 // change byte-ordering and go via cache 4.22 return cpCache.getEntryAt((int) (0xFFFF & VM.getVM().getBytes().swapShort((short) cpCacheIndex))).getConstantPoolIndex();
5.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java Thu Jun 24 15:38:42 2010 -0700 5.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java Mon Jun 28 12:03:05 2010 -0400 5.3 @@ -222,7 +222,7 @@ 5.4 public static final int _invokespecial = 183; // 0xb7 5.5 public static final int _invokestatic = 184; // 0xb8 5.6 public static final int _invokeinterface = 185; // 0xb9 5.7 - public static final int _xxxunusedxxx = 186; // 0xba 5.8 + public static final int _invokedynamic = 186; // 0xba 5.9 public static final int _new = 187; // 0xbb 5.10 public static final int _newarray = 188; // 0xbc 5.11 public static final int _anewarray = 189; // 0xbd 5.12 @@ -269,9 +269,12 @@ 5.13 public static final int _fast_invokevfinal = 226; 5.14 public static final int _fast_linearswitch = 227; 5.15 public static final int _fast_binaryswitch = 228; 5.16 - public static final int _shouldnotreachhere = 229; // For debugging 5.17 + public static final int _fast_aldc = 229; 5.18 + public static final int _fast_aldc_w = 230; 5.19 + public static final int _return_register_finalizer = 231; 5.20 + public static final int _shouldnotreachhere = 232; // For debugging 5.21 5.22 - public static final int number_of_codes = 230; 5.23 + public static final int number_of_codes = 233; 5.24 5.25 public static int specialLengthAt(Method method, int bci) { 5.26 int code = codeAt(method, bci); 5.27 @@ -458,9 +461,9 @@ 5.28 def(_dconst_1 , "dconst_1" , "b" , null , BasicType.getTDouble() , 2, false); 5.29 def(_bipush , "bipush" , "bc" , null , BasicType.getTInt() , 1, false); 5.30 def(_sipush , "sipush" , "bcc" , null , BasicType.getTInt() , 1, false); 5.31 - def(_ldc , "ldc" , "bi" , null , BasicType.getTIllegal(), 1, true ); 5.32 - def(_ldc_w , "ldc_w" , "bii" , null , BasicType.getTIllegal(), 1, true ); 5.33 - def(_ldc2_w , "ldc2_w" , "bii" , null , BasicType.getTIllegal(), 2, true ); 5.34 + def(_ldc , "ldc" , "bk" , null , BasicType.getTIllegal(), 1, true ); 5.35 + def(_ldc_w , "ldc_w" , "bkk" , null , BasicType.getTIllegal(), 1, true ); 5.36 + def(_ldc2_w , "ldc2_w" , "bkk" , null , BasicType.getTIllegal(), 2, true ); 5.37 def(_iload , "iload" , "bi" , "wbii" , BasicType.getTInt() , 1, false); 5.38 def(_lload , "lload" , "bi" , "wbii" , BasicType.getTLong() , 2, false); 5.39 def(_fload , "fload" , "bi" , "wbii" , BasicType.getTFloat() , 1, false); 5.40 @@ -618,26 +621,26 @@ 5.41 def(_dreturn , "dreturn" , "b" , null , BasicType.getTDouble() , -2, true ); 5.42 def(_areturn , "areturn" , "b" , null , BasicType.getTObject() , -1, true ); 5.43 def(_return , "return" , "b" , null , BasicType.getTVoid() , 0, true ); 5.44 - def(_getstatic , "getstatic" , "bjj" , null , BasicType.getTIllegal(), 1, true ); 5.45 - def(_putstatic , "putstatic" , "bjj" , null , BasicType.getTIllegal(), -1, true ); 5.46 - def(_getfield , "getfield" , "bjj" , null , BasicType.getTIllegal(), 0, true ); 5.47 - def(_putfield , "putfield" , "bjj" , null , BasicType.getTIllegal(), -2, true ); 5.48 - def(_invokevirtual , "invokevirtual" , "bjj" , null , BasicType.getTIllegal(), -1, true ); 5.49 - def(_invokespecial , "invokespecial" , "bjj" , null , BasicType.getTIllegal(), -1, true ); 5.50 - def(_invokestatic , "invokestatic" , "bjj" , null , BasicType.getTIllegal(), 0, true ); 5.51 - def(_invokeinterface , "invokeinterface" , "bjj__", null , BasicType.getTIllegal(), -1, true ); 5.52 - def(_xxxunusedxxx , "xxxunusedxxx" , null , null , BasicType.getTVoid() , 0, false); 5.53 - def(_new , "new" , "bii" , null , BasicType.getTObject() , 1, true ); 5.54 + def(_getstatic , "getstatic" , "bJJ" , null , BasicType.getTIllegal(), 1, true ); 5.55 + def(_putstatic , "putstatic" , "bJJ" , null , BasicType.getTIllegal(), -1, true ); 5.56 + def(_getfield , "getfield" , "bJJ" , null , BasicType.getTIllegal(), 0, true ); 5.57 + def(_putfield , "putfield" , "bJJ" , null , BasicType.getTIllegal(), -2, true ); 5.58 + def(_invokevirtual , "invokevirtual" , "bJJ" , null , BasicType.getTIllegal(), -1, true ); 5.59 + def(_invokespecial , "invokespecial" , "bJJ" , null , BasicType.getTIllegal(), -1, true ); 5.60 + def(_invokestatic , "invokestatic" , "bJJ" , null , BasicType.getTIllegal(), 0, true ); 5.61 + def(_invokeinterface , "invokeinterface" , "bJJ__", null , BasicType.getTIllegal(), -1, true ); 5.62 + def(_invokedynamic , "invokedynamic" , "bJJJJ", null , BasicType.getTIllegal(), -1, true ); 5.63 + def(_new , "new" , "bkk" , null , BasicType.getTObject() , 1, true ); 5.64 def(_newarray , "newarray" , "bc" , null , BasicType.getTObject() , 0, true ); 5.65 - def(_anewarray , "anewarray" , "bii" , null , BasicType.getTObject() , 0, true ); 5.66 + def(_anewarray , "anewarray" , "bkk" , null , BasicType.getTObject() , 0, true ); 5.67 def(_arraylength , "arraylength" , "b" , null , BasicType.getTVoid() , 0, true ); 5.68 def(_athrow , "athrow" , "b" , null , BasicType.getTVoid() , -1, true ); 5.69 - def(_checkcast , "checkcast" , "bii" , null , BasicType.getTObject() , 0, true ); 5.70 - def(_instanceof , "instanceof" , "bii" , null , BasicType.getTInt() , 0, true ); 5.71 + def(_checkcast , "checkcast" , "bkk" , null , BasicType.getTObject() , 0, true ); 5.72 + def(_instanceof , "instanceof" , "bkk" , null , BasicType.getTInt() , 0, true ); 5.73 def(_monitorenter , "monitorenter" , "b" , null , BasicType.getTVoid() , -1, true ); 5.74 def(_monitorexit , "monitorexit" , "b" , null , BasicType.getTVoid() , -1, true ); 5.75 def(_wide , "wide" , "" , null , BasicType.getTVoid() , 0, false); 5.76 - def(_multianewarray , "multianewarray" , "biic" , null , BasicType.getTObject() , 1, true ); 5.77 + def(_multianewarray , "multianewarray" , "bkkc" , null , BasicType.getTObject() , 1, true ); 5.78 def(_ifnull , "ifnull" , "boo" , null , BasicType.getTVoid() , -1, false); 5.79 def(_ifnonnull , "ifnonnull" , "boo" , null , BasicType.getTVoid() , -1, false); 5.80 def(_goto_w , "goto_w" , "boooo", null , BasicType.getTVoid() , 0, false); 5.81 @@ -646,38 +649,44 @@ 5.82 5.83 // JVM bytecodes 5.84 // bytecode bytecode name format wide f. result tp stk traps std code 5.85 - def(_fast_agetfield , "fast_agetfield" , "bjj" , null , BasicType.getTObject() , 0, true , _getfield ); 5.86 - def(_fast_bgetfield , "fast_bgetfield" , "bjj" , null , BasicType.getTInt() , 0, true , _getfield ); 5.87 - def(_fast_cgetfield , "fast_cgetfield" , "bjj" , null , BasicType.getTChar() , 0, true , _getfield ); 5.88 - def(_fast_dgetfield , "fast_dgetfield" , "bjj" , null , BasicType.getTDouble() , 0, true , _getfield ); 5.89 - def(_fast_fgetfield , "fast_fgetfield" , "bjj" , null , BasicType.getTFloat() , 0, true , _getfield ); 5.90 - def(_fast_igetfield , "fast_igetfield" , "bjj" , null , BasicType.getTInt() , 0, true , _getfield ); 5.91 - def(_fast_lgetfield , "fast_lgetfield" , "bjj" , null , BasicType.getTLong() , 0, true , _getfield ); 5.92 - def(_fast_sgetfield , "fast_sgetfield" , "bjj" , null , BasicType.getTShort() , 0, true , _getfield ); 5.93 + def(_fast_agetfield , "fast_agetfield" , "bJJ" , null , BasicType.getTObject() , 0, true , _getfield ); 5.94 + def(_fast_bgetfield , "fast_bgetfield" , "bJJ" , null , BasicType.getTInt() , 0, true , _getfield ); 5.95 + def(_fast_cgetfield , "fast_cgetfield" , "bJJ" , null , BasicType.getTChar() , 0, true , _getfield ); 5.96 + def(_fast_dgetfield , "fast_dgetfield" , "bJJ" , null , BasicType.getTDouble() , 0, true , _getfield ); 5.97 + def(_fast_fgetfield , "fast_fgetfield" , "bJJ" , null , BasicType.getTFloat() , 0, true , _getfield ); 5.98 + def(_fast_igetfield , "fast_igetfield" , "bJJ" , null , BasicType.getTInt() , 0, true , _getfield ); 5.99 + def(_fast_lgetfield , "fast_lgetfield" , "bJJ" , null , BasicType.getTLong() , 0, true , _getfield ); 5.100 + def(_fast_sgetfield , "fast_sgetfield" , "bJJ" , null , BasicType.getTShort() , 0, true , _getfield ); 5.101 5.102 - def(_fast_aputfield , "fast_aputfield" , "bjj" , null , BasicType.getTObject() , 0, true , _putfield ); 5.103 - def(_fast_bputfield , "fast_bputfield" , "bjj" , null , BasicType.getTInt() , 0, true , _putfield ); 5.104 - def(_fast_cputfield , "fast_cputfield" , "bjj" , null , BasicType.getTChar() , 0, true , _putfield ); 5.105 - def(_fast_dputfield , "fast_dputfield" , "bjj" , null , BasicType.getTDouble() , 0, true , _putfield ); 5.106 - def(_fast_fputfield , "fast_fputfield" , "bjj" , null , BasicType.getTFloat() , 0, true , _putfield ); 5.107 - def(_fast_iputfield , "fast_iputfield" , "bjj" , null , BasicType.getTInt() , 0, true , _putfield ); 5.108 - def(_fast_lputfield , "fast_lputfield" , "bjj" , null , BasicType.getTLong() , 0, true , _putfield ); 5.109 - def(_fast_sputfield , "fast_sputfield" , "bjj" , null , BasicType.getTShort() , 0, true , _putfield ); 5.110 + def(_fast_aputfield , "fast_aputfield" , "bJJ" , null , BasicType.getTObject() , 0, true , _putfield ); 5.111 + def(_fast_bputfield , "fast_bputfield" , "bJJ" , null , BasicType.getTInt() , 0, true , _putfield ); 5.112 + def(_fast_cputfield , "fast_cputfield" , "bJJ" , null , BasicType.getTChar() , 0, true , _putfield ); 5.113 + def(_fast_dputfield , "fast_dputfield" , "bJJ" , null , BasicType.getTDouble() , 0, true , _putfield ); 5.114 + def(_fast_fputfield , "fast_fputfield" , "bJJ" , null , BasicType.getTFloat() , 0, true , _putfield ); 5.115 + def(_fast_iputfield , "fast_iputfield" , "bJJ" , null , BasicType.getTInt() , 0, true , _putfield ); 5.116 + def(_fast_lputfield , "fast_lputfield" , "bJJ" , null , BasicType.getTLong() , 0, true , _putfield ); 5.117 + def(_fast_sputfield , "fast_sputfield" , "bJJ" , null , BasicType.getTShort() , 0, true , _putfield ); 5.118 5.119 def(_fast_aload_0 , "fast_aload_0" , "b" , null , BasicType.getTObject() , 1, true , _aload_0 ); 5.120 - def(_fast_iaccess_0 , "fast_iaccess_0" , "b_jj" , null , BasicType.getTInt() , 1, true , _aload_0 ); 5.121 - def(_fast_aaccess_0 , "fast_aaccess_0" , "b_jj" , null , BasicType.getTObject() , 1, true , _aload_0 ); 5.122 - def(_fast_faccess_0 , "fast_faccess_0" , "b_jj" , null , BasicType.getTObject() , 1, true , _aload_0 ); 5.123 + def(_fast_iaccess_0 , "fast_iaccess_0" , "b_JJ" , null , BasicType.getTInt() , 1, true , _aload_0 ); 5.124 + def(_fast_aaccess_0 , "fast_aaccess_0" , "b_JJ" , null , BasicType.getTObject() , 1, true , _aload_0 ); 5.125 + def(_fast_faccess_0 , "fast_faccess_0" , "b_JJ" , null , BasicType.getTObject() , 1, true , _aload_0 ); 5.126 5.127 def(_fast_iload , "fast_iload" , "bi" , null , BasicType.getTInt() , 1, false, _iload); 5.128 def(_fast_iload2 , "fast_iload2" , "bi_i" , null , BasicType.getTInt() , 2, false, _iload); 5.129 def(_fast_icaload , "fast_icaload" , "bi_" , null , BasicType.getTInt() , 0, false, _iload); 5.130 5.131 // Faster method invocation. 5.132 - def(_fast_invokevfinal , "fast_invokevfinal" , "bjj" , null , BasicType.getTIllegal(), -1, true, _invokevirtual); 5.133 + def(_fast_invokevfinal , "fast_invokevfinal" , "bJJ" , null , BasicType.getTIllegal(), -1, true, _invokevirtual); 5.134 5.135 def(_fast_linearswitch , "fast_linearswitch" , "" , null , BasicType.getTVoid() , -1, false, _lookupswitch ); 5.136 def(_fast_binaryswitch , "fast_binaryswitch" , "" , null , BasicType.getTVoid() , -1, false, _lookupswitch ); 5.137 + 5.138 + def(_return_register_finalizer, "return_register_finalizer", "b" , null , BasicType.getTVoid() , 0, true, _return ); 5.139 + 5.140 + def(_fast_aldc , "fast_aldc" , "bj" , null , BasicType.getTObject(), 1, true, _ldc ); 5.141 + def(_fast_aldc_w , "fast_aldc_w" , "bJJ" , null , BasicType.getTObject(), 1, true, _ldc_w ); 5.142 + 5.143 def(_shouldnotreachhere , "_shouldnotreachhere" , "b" , null , BasicType.getTVoid() , 0, false); 5.144 5.145 if (Assert.ASSERTS_ENABLED) {
6.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Thu Jun 24 15:38:42 2010 -0700 6.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Mon Jun 28 12:03:05 2010 -0400 6.3 @@ -152,7 +152,7 @@ 6.4 return res; 6.5 } 6.6 6.7 - public int getNameAndTypeAt(int which) { 6.8 + public int[] getNameAndTypeAt(int which) { 6.9 if (Assert.ASSERTS_ENABLED) { 6.10 Assert.that(getTagAt(which).isNameAndType(), "Corrupted constant pool"); 6.11 } 6.12 @@ -160,18 +160,16 @@ 6.13 if (DEBUG) { 6.14 System.err.println("ConstantPool.getNameAndTypeAt(" + which + "): result = " + i); 6.15 } 6.16 - return i; 6.17 + return new int[] { extractLowShortFromInt(i), extractHighShortFromInt(i) }; 6.18 } 6.19 6.20 public Symbol getNameRefAt(int which) { 6.21 - int refIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which)); 6.22 - int nameIndex = extractLowShortFromInt(refIndex); 6.23 + int nameIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[0]; 6.24 return getSymbolAt(nameIndex); 6.25 } 6.26 6.27 public Symbol getSignatureRefAt(int which) { 6.28 - int refIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which)); 6.29 - int sigIndex = extractHighShortFromInt(refIndex); 6.30 + int sigIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[1]; 6.31 return getSymbolAt(sigIndex); 6.32 } 6.33 6.34 @@ -220,11 +218,11 @@ 6.35 6.36 /** Lookup for entries consisting of (name_index, signature_index) */ 6.37 public int getNameRefIndexAt(int index) { 6.38 - int refIndex = getNameAndTypeAt(index); 6.39 + int[] refIndex = getNameAndTypeAt(index); 6.40 if (DEBUG) { 6.41 - System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): refIndex = " + refIndex); 6.42 + System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): refIndex = " + refIndex[0]+"/"+refIndex[1]); 6.43 } 6.44 - int i = extractLowShortFromInt(refIndex); 6.45 + int i = refIndex[0]; 6.46 if (DEBUG) { 6.47 System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): result = " + i); 6.48 } 6.49 @@ -233,17 +231,53 @@ 6.50 6.51 /** Lookup for entries consisting of (name_index, signature_index) */ 6.52 public int getSignatureRefIndexAt(int index) { 6.53 - int refIndex = getNameAndTypeAt(index); 6.54 + int[] refIndex = getNameAndTypeAt(index); 6.55 if (DEBUG) { 6.56 - System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): refIndex = " + refIndex); 6.57 + System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): refIndex = " + refIndex[0]+"/"+refIndex[1]); 6.58 } 6.59 - int i = extractHighShortFromInt(refIndex); 6.60 + int i = refIndex[1]; 6.61 if (DEBUG) { 6.62 System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): result = " + i); 6.63 } 6.64 return i; 6.65 } 6.66 6.67 + /** Lookup for MethodHandle entries. */ 6.68 + public int getMethodHandleIndexAt(int i) { 6.69 + if (Assert.ASSERTS_ENABLED) { 6.70 + Assert.that(getTagAt(i).isMethodHandle(), "Corrupted constant pool"); 6.71 + } 6.72 + int res = extractHighShortFromInt(getIntAt(i)); 6.73 + if (DEBUG) { 6.74 + System.err.println("ConstantPool.getMethodHandleIndexAt(" + i + "): result = " + res); 6.75 + } 6.76 + return res; 6.77 + } 6.78 + 6.79 + /** Lookup for MethodHandle entries. */ 6.80 + public int getMethodHandleRefKindAt(int i) { 6.81 + if (Assert.ASSERTS_ENABLED) { 6.82 + Assert.that(getTagAt(i).isMethodHandle(), "Corrupted constant pool"); 6.83 + } 6.84 + int res = extractLowShortFromInt(getIntAt(i)); 6.85 + if (DEBUG) { 6.86 + System.err.println("ConstantPool.getMethodHandleRefKindAt(" + i + "): result = " + res); 6.87 + } 6.88 + return res; 6.89 + } 6.90 + 6.91 + /** Lookup for MethodType entries. */ 6.92 + public int getMethodTypeIndexAt(int i) { 6.93 + if (Assert.ASSERTS_ENABLED) { 6.94 + Assert.that(getTagAt(i).isMethodType(), "Corrupted constant pool"); 6.95 + } 6.96 + int res = getIntAt(i); 6.97 + if (DEBUG) { 6.98 + System.err.println("ConstantPool.getMethodHandleTypeAt(" + i + "): result = " + res); 6.99 + } 6.100 + return res; 6.101 + } 6.102 + 6.103 final private static String[] nameForTag = new String[] { 6.104 }; 6.105 6.106 @@ -261,6 +295,8 @@ 6.107 case JVM_CONSTANT_Methodref: return "JVM_CONSTANT_Methodref"; 6.108 case JVM_CONSTANT_InterfaceMethodref: return "JVM_CONSTANT_InterfaceMethodref"; 6.109 case JVM_CONSTANT_NameAndType: return "JVM_CONSTANT_NameAndType"; 6.110 + case JVM_CONSTANT_MethodHandle: return "JVM_CONSTANT_MethodHandle"; 6.111 + case JVM_CONSTANT_MethodType: return "JVM_CONSTANT_MethodType"; 6.112 case JVM_CONSTANT_Invalid: return "JVM_CONSTANT_Invalid"; 6.113 case JVM_CONSTANT_UnresolvedClass: return "JVM_CONSTANT_UnresolvedClass"; 6.114 case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError"; 6.115 @@ -317,6 +353,8 @@ 6.116 case JVM_CONSTANT_Methodref: 6.117 case JVM_CONSTANT_InterfaceMethodref: 6.118 case JVM_CONSTANT_NameAndType: 6.119 + case JVM_CONSTANT_MethodHandle: 6.120 + case JVM_CONSTANT_MethodType: 6.121 visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); 6.122 break; 6.123 } 6.124 @@ -467,6 +505,18 @@ 6.125 + ", type = " + signatureIndex); 6.126 break; 6.127 } 6.128 + 6.129 + case JVM_CONSTANT_MethodHandle: { 6.130 + dos.writeByte(cpConstType); 6.131 + int value = getIntAt(ci); 6.132 + short nameIndex = (short) extractLowShortFromInt(value); 6.133 + short signatureIndex = (short) extractHighShortFromInt(value); 6.134 + dos.writeShort(nameIndex); 6.135 + dos.writeShort(signatureIndex); 6.136 + if (DEBUG) debugMessage("CP[" + ci + "] = N&T name = " + nameIndex 6.137 + + ", type = " + signatureIndex); 6.138 + break; 6.139 + } 6.140 default: 6.141 throw new InternalError("unknown tag: " + cpConstType); 6.142 } // switch 6.143 @@ -488,10 +538,12 @@ 6.144 // 6.145 6.146 private static int extractHighShortFromInt(int val) { 6.147 + // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. 6.148 return (val >> 16) & 0xFFFF; 6.149 } 6.150 6.151 private static int extractLowShortFromInt(int val) { 6.152 + // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. 6.153 return val & 0xFFFF; 6.154 } 6.155 }
7.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java Thu Jun 24 15:38:42 2010 -0700 7.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java Mon Jun 28 12:03:05 2010 -0400 7.3 @@ -78,6 +78,31 @@ 7.4 return new ConstantPoolCacheEntry(this, i); 7.5 } 7.6 7.7 + public static boolean isSecondaryIndex(int i) { return (i < 0); } 7.8 + public static int decodeSecondaryIndex(int i) { return isSecondaryIndex(i) ? ~i : i; } 7.9 + public static int encodeSecondaryIndex(int i) { return !isSecondaryIndex(i) ? ~i : i; } 7.10 + 7.11 + // secondary entries hold invokedynamic call site bindings 7.12 + public ConstantPoolCacheEntry getSecondaryEntryAt(int i) { 7.13 + ConstantPoolCacheEntry e = new ConstantPoolCacheEntry(this, decodeSecondaryIndex(i)); 7.14 + if (Assert.ASSERTS_ENABLED) { 7.15 + Assert.that(e.isSecondaryEntry(), "must be a secondary entry"); 7.16 + } 7.17 + return e; 7.18 + } 7.19 + 7.20 + public ConstantPoolCacheEntry getMainEntryAt(int i) { 7.21 + if (isSecondaryIndex(i)) { 7.22 + // run through an extra level of indirection: 7.23 + i = getSecondaryEntryAt(i).getMainEntryIndex(); 7.24 + } 7.25 + ConstantPoolCacheEntry e = new ConstantPoolCacheEntry(this, i); 7.26 + if (Assert.ASSERTS_ENABLED) { 7.27 + Assert.that(!e.isSecondaryEntry(), "must not be a secondary entry"); 7.28 + } 7.29 + return e; 7.30 + } 7.31 + 7.32 public int getIntAt(int entry, int fld) { 7.33 //alignObjectSize ? 7.34 long offset = baseOffset + /*alignObjectSize*/entry * elementSize + fld* getHeap().getIntSize();
8.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCacheEntry.java Thu Jun 24 15:38:42 2010 -0700 8.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCacheEntry.java Mon Jun 28 12:03:05 2010 -0400 8.3 @@ -28,6 +28,7 @@ 8.4 import sun.jvm.hotspot.debugger.*; 8.5 import sun.jvm.hotspot.runtime.*; 8.6 import sun.jvm.hotspot.types.*; 8.7 +import sun.jvm.hotspot.utilities.*; 8.8 8.9 public class ConstantPoolCacheEntry { 8.10 private static long size; 8.11 @@ -67,9 +68,23 @@ 8.12 } 8.13 8.14 public int getConstantPoolIndex() { 8.15 + if (Assert.ASSERTS_ENABLED) { 8.16 + Assert.that(!isSecondaryEntry(), "must not be a secondary CP entry"); 8.17 + } 8.18 return (int) (getIndices() & 0xFFFF); 8.19 } 8.20 8.21 + public boolean isSecondaryEntry() { 8.22 + return (getIndices() & 0xFFFF) == 0; 8.23 + } 8.24 + 8.25 + public int getMainEntryIndex() { 8.26 + if (Assert.ASSERTS_ENABLED) { 8.27 + Assert.that(isSecondaryEntry(), "must be a secondary CP entry"); 8.28 + } 8.29 + return (int) (getIndices() >>> 16); 8.30 + } 8.31 + 8.32 private long getIndices() { 8.33 return cp.getHandle().getCIntegerAt(indices.getOffset() + offset, indices.getSize(), indices.isUnsigned()); 8.34 }
9.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java Thu Jun 24 15:38:42 2010 -0700 9.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java Mon Jun 28 12:03:05 2010 -0400 9.3 @@ -566,6 +566,7 @@ 9.4 case Bytecodes._invokespecial: 9.5 case Bytecodes._invokestatic: 9.6 case Bytecodes._invokeinterface: 9.7 + case Bytecodes._invokedynamic: 9.8 // FIXME: print signature of referenced method (need more 9.9 // accessors in ConstantPool and ConstantPoolCache) 9.10 int idx = currentBC.getIndexBig(); 9.11 @@ -605,6 +606,7 @@ 9.12 case Bytecodes._invokespecial: 9.13 case Bytecodes._invokestatic: 9.14 case Bytecodes._invokeinterface: 9.15 + case Bytecodes._invokedynamic: 9.16 // FIXME: print signature of referenced method (need more 9.17 // accessors in ConstantPool and ConstantPoolCache) 9.18 int idx = currentBC.getIndexBig(); 9.19 @@ -1134,6 +1136,7 @@ 9.20 case Bytecodes._invokespecial: 9.21 case Bytecodes._invokestatic: 9.22 case Bytecodes._invokeinterface: 9.23 + case Bytecodes._invokedynamic: 9.24 _itr_send = itr; 9.25 _report_result_for_send = true; 9.26 break; 9.27 @@ -1379,6 +1382,7 @@ 9.28 case Bytecodes._invokevirtual: 9.29 case Bytecodes._invokespecial: doMethod(false, false, itr.getIndexBig(), itr.bci()); break; 9.30 case Bytecodes._invokestatic: doMethod(true, false, itr.getIndexBig(), itr.bci()); break; 9.31 + case Bytecodes._invokedynamic: doMethod(false, true, itr.getIndexBig(), itr.bci()); break; 9.32 case Bytecodes._invokeinterface: doMethod(false, true, itr.getIndexBig(), itr.bci()); break; 9.33 case Bytecodes._newarray: 9.34 case Bytecodes._anewarray: ppNewRef(vCTS, itr.bci()); break; 9.35 @@ -1725,7 +1729,7 @@ 9.36 void doMethod (boolean is_static, boolean is_interface, int idx, int bci) { 9.37 // Dig up signature for field in constant pool 9.38 ConstantPool cp = _method.getConstants(); 9.39 - int nameAndTypeIdx = cp.getNameAndTypeRefIndexAt(idx); 9.40 + int nameAndTypeIdx = cp.getTagAt(idx).isNameAndType() ? idx : cp.getNameAndTypeRefIndexAt(idx); 9.41 int signatureIdx = cp.getSignatureRefIndexAt(nameAndTypeIdx); 9.42 Symbol signature = cp.getSymbolAt(signatureIdx); 9.43
10.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Thu Jun 24 15:38:42 2010 -0700 10.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Mon Jun 28 12:03:05 2010 -0400 10.3 @@ -40,6 +40,19 @@ 10.4 public static final int JVM_CONSTANT_Methodref = 10; 10.5 public static final int JVM_CONSTANT_InterfaceMethodref = 11; 10.6 public static final int JVM_CONSTANT_NameAndType = 12; 10.7 + public static final int JVM_CONSTANT_MethodHandle = 15; 10.8 + public static final int JVM_CONSTANT_MethodType = 16; 10.9 + 10.10 + // JVM_CONSTANT_MethodHandle subtypes 10.11 + public static final int JVM_REF_getField = 1; 10.12 + public static final int JVM_REF_getStatic = 2; 10.13 + public static final int JVM_REF_putField = 3; 10.14 + public static final int JVM_REF_putStatic = 4; 10.15 + public static final int JVM_REF_invokeVirtual = 5; 10.16 + public static final int JVM_REF_invokeStatic = 6; 10.17 + public static final int JVM_REF_invokeSpecial = 7; 10.18 + public static final int JVM_REF_newInvokeSpecial = 8; 10.19 + public static final int JVM_REF_invokeInterface = 9; 10.20 10.21 // HotSpot specific constant pool constant types. 10.22
11.1 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java Thu Jun 24 15:38:42 2010 -0700 11.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java Mon Jun 28 12:03:05 2010 -0400 11.3 @@ -54,14 +54,34 @@ 11.4 11.5 } 11.6 11.7 - protected short getConstantPoolIndex(int bci) { 11.8 + protected short getConstantPoolIndex(int rawcode, int bci) { 11.9 // get ConstantPool index from ConstantPoolCacheIndex at given bci 11.10 - short cpCacheIndex = method.getBytecodeShortArg(bci); 11.11 + String fmt = Bytecodes.format(rawcode); 11.12 + int cpCacheIndex; 11.13 + switch (fmt.length()) { 11.14 + case 2: cpCacheIndex = method.getBytecodeByteArg(bci); break; 11.15 + case 3: cpCacheIndex = method.getBytecodeShortArg(bci); break; 11.16 + case 5: 11.17 + if (fmt.indexOf("__") >= 0) 11.18 + cpCacheIndex = method.getBytecodeShortArg(bci); 11.19 + else 11.20 + cpCacheIndex = method.getBytecodeIntArg(bci); 11.21 + break; 11.22 + default: throw new IllegalArgumentException(); 11.23 + } 11.24 if (cpCache == null) { 11.25 - return cpCacheIndex; 11.26 + return (short) cpCacheIndex; 11.27 + } else if (fmt.indexOf("JJJJ") >= 0) { 11.28 + // change byte-ordering and go via secondary cache entry 11.29 + return (short) cpCache.getMainEntryAt(bytes.swapInt(cpCacheIndex)).getConstantPoolIndex(); 11.30 + } else if (fmt.indexOf("JJ") >= 0) { 11.31 + // change byte-ordering and go via cache 11.32 + return (short) cpCache.getEntryAt((int) (0xFFFF & bytes.swapShort((short)cpCacheIndex))).getConstantPoolIndex(); 11.33 + } else if (fmt.indexOf("j") >= 0) { 11.34 + // go via cache 11.35 + return (short) cpCache.getEntryAt((int) (0xFF & cpCacheIndex)).getConstantPoolIndex(); 11.36 } else { 11.37 - // change byte-ordering and go via cache 11.38 - return (short) cpCache.getEntryAt((int) (0xFFFF & bytes.swapShort(cpCacheIndex))).getConstantPoolIndex(); 11.39 + return (short) cpCacheIndex; 11.40 } 11.41 } 11.42 11.43 @@ -100,10 +120,31 @@ 11.44 case Bytecodes._invokespecial: 11.45 case Bytecodes._invokestatic: 11.46 case Bytecodes._invokeinterface: { 11.47 - cpoolIndex = getConstantPoolIndex(bci + 1); 11.48 + cpoolIndex = getConstantPoolIndex(hotspotcode, bci + 1); 11.49 writeShort(code, bci + 1, cpoolIndex); 11.50 break; 11.51 } 11.52 + 11.53 + case Bytecodes._invokedynamic: 11.54 + cpoolIndex = getConstantPoolIndex(hotspotcode, bci + 1); 11.55 + writeShort(code, bci + 1, cpoolIndex); 11.56 + writeShort(code, bci + 3, (short)0); // clear out trailing bytes 11.57 + break; 11.58 + 11.59 + case Bytecodes._ldc_w: 11.60 + if (hotspotcode != bytecode) { 11.61 + // fast_aldc_w puts constant in CP cache 11.62 + cpoolIndex = getConstantPoolIndex(hotspotcode, bci + 1); 11.63 + writeShort(code, bci + 1, cpoolIndex); 11.64 + } 11.65 + break; 11.66 + case Bytecodes._ldc: 11.67 + if (hotspotcode != bytecode) { 11.68 + // fast_aldc puts constant in CP cache 11.69 + cpoolIndex = getConstantPoolIndex(hotspotcode, bci + 1); 11.70 + code[bci + 1] = (byte)(cpoolIndex); 11.71 + } 11.72 + break; 11.73 } 11.74 11.75 len = Bytecodes.lengthFor(bytecode);
12.1 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Thu Jun 24 15:38:42 2010 -0700 12.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Mon Jun 28 12:03:05 2010 -0400 12.3 @@ -61,10 +61,12 @@ 12.4 protected short _signatureIndex; 12.5 12.6 protected static int extractHighShortFromInt(int val) { 12.7 + // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. 12.8 return (val >> 16) & 0xFFFF; 12.9 } 12.10 12.11 protected static int extractLowShortFromInt(int val) { 12.12 + // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. 12.13 return val & 0xFFFF; 12.14 } 12.15 12.16 @@ -297,6 +299,28 @@ 12.17 + ", type = " + signatureIndex); 12.18 break; 12.19 } 12.20 + 12.21 + case JVM_CONSTANT_MethodHandle: { 12.22 + dos.writeByte(cpConstType); 12.23 + int value = cpool.getIntAt(ci); 12.24 + short refIndex = (short) extractHighShortFromInt(value); 12.25 + byte refKind = (byte) extractLowShortFromInt(value); 12.26 + dos.writeByte(refKind); 12.27 + dos.writeShort(refIndex); 12.28 + if (DEBUG) debugMessage("CP[" + ci + "] = MH index = " + refIndex 12.29 + + ", kind = " + refKind); 12.30 + break; 12.31 + } 12.32 + 12.33 + case JVM_CONSTANT_MethodType: { 12.34 + dos.writeByte(cpConstType); 12.35 + int value = cpool.getIntAt(ci); 12.36 + short refIndex = (short) value; 12.37 + dos.writeShort(refIndex); 12.38 + if (DEBUG) debugMessage("CP[" + ci + "] = MT index = " + refIndex); 12.39 + break; 12.40 + } 12.41 + 12.42 default: 12.43 throw new InternalError("Unknown tag: " + cpConstType); 12.44 } // switch
13.1 --- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Thu Jun 24 15:38:42 2010 -0700 13.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Mon Jun 28 12:03:05 2010 -0400 13.3 @@ -572,6 +572,16 @@ 13.4 buf.cell(Integer.toString(cpool.getIntAt(index))); 13.5 break; 13.6 13.7 + case JVM_CONSTANT_MethodHandle: 13.8 + buf.cell("JVM_CONSTANT_MethodHandle"); 13.9 + buf.cell(genLowHighShort(cpool.getIntAt(index))); 13.10 + break; 13.11 + 13.12 + case JVM_CONSTANT_MethodType: 13.13 + buf.cell("JVM_CONSTANT_MethodType"); 13.14 + buf.cell(Integer.toString(cpool.getIntAt(index))); 13.15 + break; 13.16 + 13.17 default: 13.18 throw new InternalError("unknown tag: " + ctag); 13.19 }
14.1 --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Thu Jun 24 15:38:42 2010 -0700 14.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Mon Jun 28 12:03:05 2010 -0400 14.3 @@ -38,12 +38,26 @@ 14.4 private static int JVM_CONSTANT_Methodref = 10; 14.5 private static int JVM_CONSTANT_InterfaceMethodref = 11; 14.6 private static int JVM_CONSTANT_NameAndType = 12; 14.7 + private static int JVM_CONSTANT_MethodHandle = 15; // JSR 292 14.8 + private static int JVM_CONSTANT_MethodType = 16; // JSR 292 14.9 private static int JVM_CONSTANT_Invalid = 0; // For bad value initialization 14.10 private static int JVM_CONSTANT_UnresolvedClass = 100; // Temporary tag until actual use 14.11 private static int JVM_CONSTANT_ClassIndex = 101; // Temporary tag while constructing constant pool 14.12 private static int JVM_CONSTANT_UnresolvedString = 102; // Temporary tag until actual use 14.13 private static int JVM_CONSTANT_StringIndex = 103; // Temporary tag while constructing constant pool 14.14 private static int JVM_CONSTANT_UnresolvedClassInError = 104; // Resolution failed 14.15 + private static int JVM_CONSTANT_Object = 105; // Required for BoundMethodHandle arguments. 14.16 + 14.17 + // JVM_CONSTANT_MethodHandle subtypes //FIXME: connect these to data structure 14.18 + private static int JVM_REF_getField = 1; 14.19 + private static int JVM_REF_getStatic = 2; 14.20 + private static int JVM_REF_putField = 3; 14.21 + private static int JVM_REF_putStatic = 4; 14.22 + private static int JVM_REF_invokeVirtual = 5; 14.23 + private static int JVM_REF_invokeStatic = 6; 14.24 + private static int JVM_REF_invokeSpecial = 7; 14.25 + private static int JVM_REF_newInvokeSpecial = 8; 14.26 + private static int JVM_REF_invokeInterface = 9; 14.27 14.28 private byte tag; 14.29 14.30 @@ -62,6 +76,8 @@ 14.31 public boolean isDouble() { return tag == JVM_CONSTANT_Double; } 14.32 public boolean isNameAndType() { return tag == JVM_CONSTANT_NameAndType; } 14.33 public boolean isUtf8() { return tag == JVM_CONSTANT_Utf8; } 14.34 + public boolean isMethodHandle() { return tag == JVM_CONSTANT_MethodHandle; } 14.35 + public boolean isMethodType() { return tag == JVM_CONSTANT_MethodType; } 14.36 14.37 public boolean isInvalid() { return tag == JVM_CONSTANT_Invalid; } 14.38 14.39 @@ -73,6 +89,8 @@ 14.40 public boolean isUnresolvedString() { return tag == JVM_CONSTANT_UnresolvedString; } 14.41 public boolean isStringIndex() { return tag == JVM_CONSTANT_StringIndex; } 14.42 14.43 + public boolean isObject() { return tag == JVM_CONSTANT_Object; } 14.44 + 14.45 public boolean isKlassReference() { return isKlassIndex() || isUnresolvedKlass(); } 14.46 public boolean isFieldOrMethod() { return isField() || isMethod() || isInterfaceMethod(); } 14.47 public boolean isSymbol() { return isUtf8(); }
15.1 --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Thu Jun 24 15:38:42 2010 -0700 15.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Mon Jun 28 12:03:05 2010 -0400 15.3 @@ -825,6 +825,8 @@ 15.4 } 15.5 writeln(""); 15.6 disAsm.decode(new sapkg.interpreter.BytecodeVisitor() { 15.7 + prologue: function(method) { }, 15.8 + epilogue: function() { }, 15.9 visit: function(bytecode) { 15.10 if (hasLines) { 15.11 var line = method.getLineNumberFromBCI(bci);
16.1 --- a/make/linux/makefiles/adlc.make Thu Jun 24 15:38:42 2010 -0700 16.2 +++ b/make/linux/makefiles/adlc.make Mon Jun 28 12:03:05 2010 -0400 16.3 @@ -138,7 +138,11 @@ 16.4 16.5 # Normally, debugging is done directly on the ad_<arch>*.cpp files. 16.6 # But -g will put #line directives in those files pointing back to <arch>.ad. 16.7 +# Some builds of gcc 3.2 have a bug that gets tickled by the extra #line directives 16.8 +# so skip it for 3.2 and ealier. 16.9 +ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0" 16.10 ADLCFLAGS += -g 16.11 +endif 16.12 16.13 ifdef LP64 16.14 ADLCFLAGS += -D_LP64
17.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Jun 24 15:38:42 2010 -0700 17.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Mon Jun 28 12:03:05 2010 -0400 17.3 @@ -318,6 +318,31 @@ 17.4 __ bind(exit); 17.5 } 17.6 17.7 +// Fast path for caching oop constants. 17.8 +// %%% We should use this to handle Class and String constants also. 17.9 +// %%% It will simplify the ldc/primitive path considerably. 17.10 +void TemplateTable::fast_aldc(bool wide) { 17.11 + transition(vtos, atos); 17.12 + 17.13 + if (!EnableMethodHandles) { 17.14 + // We should not encounter this bytecode if !EnableMethodHandles. 17.15 + // The verifier will stop it. However, if we get past the verifier, 17.16 + // this will stop the thread in a reasonable way, without crashing the JVM. 17.17 + __ call_VM(noreg, CAST_FROM_FN_PTR(address, 17.18 + InterpreterRuntime::throw_IncompatibleClassChangeError)); 17.19 + // the call_VM checks for exception, so we should never return here. 17.20 + __ should_not_reach_here(); 17.21 + return; 17.22 + } 17.23 + 17.24 + Register Rcache = G3_scratch; 17.25 + Register Rscratch = G4_scratch; 17.26 + 17.27 + resolve_cache_and_index(f1_oop, Otos_i, Rcache, Rscratch, wide ? sizeof(u2) : sizeof(u1)); 17.28 + 17.29 + __ verify_oop(Otos_i); 17.30 +} 17.31 + 17.32 void TemplateTable::ldc2_w() { 17.33 transition(vtos, vtos); 17.34 Label retry, resolved, Long, exit; 17.35 @@ -1994,6 +2019,8 @@ 17.36 case Bytecodes::_invokestatic : // fall through 17.37 case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break; 17.38 case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break; 17.39 + case Bytecodes::_fast_aldc : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); break; 17.40 + case Bytecodes::_fast_aldc_w : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); break; 17.41 default : ShouldNotReachHere(); break; 17.42 } 17.43 // first time invocation - must resolve first
18.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Jun 24 15:38:42 2010 -0700 18.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Mon Jun 28 12:03:05 2010 -0400 18.3 @@ -375,6 +375,32 @@ 18.4 __ bind(Done); 18.5 } 18.6 18.7 +// Fast path for caching oop constants. 18.8 +// %%% We should use this to handle Class and String constants also. 18.9 +// %%% It will simplify the ldc/primitive path considerably. 18.10 +void TemplateTable::fast_aldc(bool wide) { 18.11 + transition(vtos, atos); 18.12 + 18.13 + if (!EnableMethodHandles) { 18.14 + // We should not encounter this bytecode if !EnableMethodHandles. 18.15 + // The verifier will stop it. However, if we get past the verifier, 18.16 + // this will stop the thread in a reasonable way, without crashing the JVM. 18.17 + __ call_VM(noreg, CAST_FROM_FN_PTR(address, 18.18 + InterpreterRuntime::throw_IncompatibleClassChangeError)); 18.19 + // the call_VM checks for exception, so we should never return here. 18.20 + __ should_not_reach_here(); 18.21 + return; 18.22 + } 18.23 + 18.24 + const Register cache = rcx; 18.25 + const Register index = rdx; 18.26 + 18.27 + resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1)); 18.28 + if (VerifyOops) { 18.29 + __ verify_oop(rax); 18.30 + } 18.31 +} 18.32 + 18.33 void TemplateTable::ldc2_w() { 18.34 transition(vtos, vtos); 18.35 Label Long, Done; 18.36 @@ -2055,6 +2081,8 @@ 18.37 case Bytecodes::_invokestatic : // fall through 18.38 case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break; 18.39 case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break; 18.40 + case Bytecodes::_fast_aldc : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); break; 18.41 + case Bytecodes::_fast_aldc_w : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); break; 18.42 default : ShouldNotReachHere(); break; 18.43 } 18.44 __ movl(temp, (int)bytecode());
19.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Jun 24 15:38:42 2010 -0700 19.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Mon Jun 28 12:03:05 2010 -0400 19.3 @@ -389,6 +389,32 @@ 19.4 __ bind(Done); 19.5 } 19.6 19.7 +// Fast path for caching oop constants. 19.8 +// %%% We should use this to handle Class and String constants also. 19.9 +// %%% It will simplify the ldc/primitive path considerably. 19.10 +void TemplateTable::fast_aldc(bool wide) { 19.11 + transition(vtos, atos); 19.12 + 19.13 + if (!EnableMethodHandles) { 19.14 + // We should not encounter this bytecode if !EnableMethodHandles. 19.15 + // The verifier will stop it. However, if we get past the verifier, 19.16 + // this will stop the thread in a reasonable way, without crashing the JVM. 19.17 + __ call_VM(noreg, CAST_FROM_FN_PTR(address, 19.18 + InterpreterRuntime::throw_IncompatibleClassChangeError)); 19.19 + // the call_VM checks for exception, so we should never return here. 19.20 + __ should_not_reach_here(); 19.21 + return; 19.22 + } 19.23 + 19.24 + const Register cache = rcx; 19.25 + const Register index = rdx; 19.26 + 19.27 + resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1)); 19.28 + if (VerifyOops) { 19.29 + __ verify_oop(rax); 19.30 + } 19.31 +} 19.32 + 19.33 void TemplateTable::ldc2_w() { 19.34 transition(vtos, vtos); 19.35 Label Long, Done; 19.36 @@ -2063,6 +2089,12 @@ 19.37 case Bytecodes::_invokedynamic: 19.38 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); 19.39 break; 19.40 + case Bytecodes::_fast_aldc: 19.41 + entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); 19.42 + break; 19.43 + case Bytecodes::_fast_aldc_w: 19.44 + entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); 19.45 + break; 19.46 default: 19.47 ShouldNotReachHere(); 19.48 break;
20.1 --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Jun 24 15:38:42 2010 -0700 20.2 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Mon Jun 28 12:03:05 2010 -0400 20.3 @@ -820,7 +820,7 @@ 20.4 bool is_top_frame) { 20.5 assert(popframe_extra_args == 0, "what to do?"); 20.6 assert(!is_top_frame || (!callee_locals && !callee_param_count), 20.7 - "top frame should have no caller") 20.8 + "top frame should have no caller"); 20.9 20.10 // This code must exactly match what InterpreterFrame::build 20.11 // does (the full InterpreterFrame::build, that is, not the
21.1 --- a/src/os_cpu/linux_x86/vm/copy_linux_x86.inline.hpp Thu Jun 24 15:38:42 2010 -0700 21.2 +++ b/src/os_cpu/linux_x86/vm/copy_linux_x86.inline.hpp Mon Jun 28 12:03:05 2010 -0400 21.3 @@ -26,7 +26,7 @@ 21.4 #ifdef AMD64 21.5 (void)memmove(to, from, count * HeapWordSize); 21.6 #else 21.7 - // Same as pd_aligned_conjoint_words, except includes a zero-count check. 21.8 + // Includes a zero-count check. 21.9 intx temp; 21.10 __asm__ volatile(" testl %6,%6 ;" 21.11 " jz 7f ;" 21.12 @@ -84,7 +84,7 @@ 21.13 break; 21.14 } 21.15 #else 21.16 - // Same as pd_aligned_disjoint_words, except includes a zero-count check. 21.17 + // Includes a zero-count check. 21.18 intx temp; 21.19 __asm__ volatile(" testl %6,%6 ;" 21.20 " jz 3f ;" 21.21 @@ -130,75 +130,18 @@ 21.22 } 21.23 21.24 static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) { 21.25 -#ifdef AMD64 21.26 - (void)memmove(to, from, count * HeapWordSize); 21.27 -#else 21.28 - // Same as pd_conjoint_words, except no zero-count check. 21.29 - intx temp; 21.30 - __asm__ volatile(" cmpl %4,%5 ;" 21.31 - " leal -4(%4,%6,4),%3;" 21.32 - " jbe 1f ;" 21.33 - " cmpl %7,%5 ;" 21.34 - " jbe 4f ;" 21.35 - "1: cmpl $32,%6 ;" 21.36 - " ja 3f ;" 21.37 - " subl %4,%1 ;" 21.38 - "2: movl (%4),%3 ;" 21.39 - " movl %7,(%5,%4,1) ;" 21.40 - " addl $4,%0 ;" 21.41 - " subl $1,%2 ;" 21.42 - " jnz 2b ;" 21.43 - " jmp 7f ;" 21.44 - "3: rep; smovl ;" 21.45 - " jmp 7f ;" 21.46 - "4: cmpl $32,%2 ;" 21.47 - " movl %7,%0 ;" 21.48 - " leal -4(%5,%6,4),%1;" 21.49 - " ja 6f ;" 21.50 - " subl %4,%1 ;" 21.51 - "5: movl (%4),%3 ;" 21.52 - " movl %7,(%5,%4,1) ;" 21.53 - " subl $4,%0 ;" 21.54 - " subl $1,%2 ;" 21.55 - " jnz 5b ;" 21.56 - " jmp 7f ;" 21.57 - "6: std ;" 21.58 - " rep; smovl ;" 21.59 - " cld ;" 21.60 - "7: nop " 21.61 - : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) 21.62 - : "0" (from), "1" (to), "2" (count), "3" (temp) 21.63 - : "memory", "flags"); 21.64 -#endif // AMD64 21.65 + pd_conjoint_words(from, to, count); 21.66 } 21.67 21.68 static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) { 21.69 -#ifdef AMD64 21.70 pd_disjoint_words(from, to, count); 21.71 -#else 21.72 - // Same as pd_disjoint_words, except no zero-count check. 21.73 - intx temp; 21.74 - __asm__ volatile(" cmpl $32,%6 ;" 21.75 - " ja 2f ;" 21.76 - " subl %4,%1 ;" 21.77 - "1: movl (%4),%3 ;" 21.78 - " movl %7,(%5,%4,1);" 21.79 - " addl $4,%0 ;" 21.80 - " subl $1,%2 ;" 21.81 - " jnz 1b ;" 21.82 - " jmp 3f ;" 21.83 - "2: rep; smovl ;" 21.84 - "3: nop " 21.85 - : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) 21.86 - : "0" (from), "1" (to), "2" (count), "3" (temp) 21.87 - : "memory", "cc"); 21.88 -#endif // AMD64 21.89 } 21.90 21.91 static void pd_conjoint_bytes(void* from, void* to, size_t count) { 21.92 #ifdef AMD64 21.93 (void)memmove(to, from, count); 21.94 #else 21.95 + // Includes a zero-count check. 21.96 intx temp; 21.97 __asm__ volatile(" testl %6,%6 ;" 21.98 " jz 13f ;"
22.1 --- a/src/os_cpu/linux_x86/vm/linux_x86_32.s Thu Jun 24 15:38:42 2010 -0700 22.2 +++ b/src/os_cpu/linux_x86/vm/linux_x86_32.s Mon Jun 28 12:03:05 2010 -0400 22.3 @@ -121,10 +121,10 @@ 22.4 jnz 3b 22.5 addl %esi,%edi 22.6 4: movl %eax,%ecx # byte count less prefix 22.7 - andl $3,%ecx # suffix byte count 22.8 +5: andl $3,%ecx # suffix byte count 22.9 jz 7f # no suffix 22.10 # copy suffix 22.11 -5: xorl %eax,%eax 22.12 + xorl %eax,%eax 22.13 6: movb (%esi,%eax,1),%dl 22.14 movb %dl,(%edi,%eax,1) 22.15 addl $1,%eax 22.16 @@ -159,10 +159,10 @@ 22.17 # copy dwords, aligned or not 22.18 3: rep; smovl 22.19 4: movl %eax,%ecx # byte count 22.20 - andl $3,%ecx # suffix byte count 22.21 +5: andl $3,%ecx # suffix byte count 22.22 jz 7f # no suffix 22.23 # copy suffix 22.24 -5: subl %esi,%edi 22.25 + subl %esi,%edi 22.26 addl $3,%esi 22.27 6: movb (%esi),%dl 22.28 movb %dl,(%edi,%esi,1) 22.29 @@ -214,10 +214,10 @@ 22.30 # copy aligned dwords 22.31 3: rep; smovl 22.32 4: movl %eax,%ecx 22.33 - andl $3,%ecx 22.34 +5: andl $3,%ecx 22.35 jz 7f 22.36 # copy suffix 22.37 -5: xorl %eax,%eax 22.38 + xorl %eax,%eax 22.39 6: movb (%esi,%eax,1),%dl 22.40 movb %dl,(%edi,%eax,1) 22.41 addl $1,%eax 22.42 @@ -250,9 +250,9 @@ 22.43 jnz 3b 22.44 addl %esi,%edi 22.45 4: movl %eax,%ecx 22.46 - andl $3,%ecx 22.47 +5: andl $3,%ecx 22.48 jz 7f 22.49 -5: subl %esi,%edi 22.50 + subl %esi,%edi 22.51 addl $3,%esi 22.52 6: movb (%esi),%dl 22.53 movb %dl,(%edi,%esi,1) 22.54 @@ -287,11 +287,12 @@ 22.55 andl $3,%eax # either 0 or 2 22.56 jz 1f # no prefix 22.57 # copy prefix 22.58 + subl $1,%ecx 22.59 + jl 5f # zero count 22.60 movw (%esi),%dx 22.61 movw %dx,(%edi) 22.62 addl %eax,%esi # %eax == 2 22.63 addl %eax,%edi 22.64 - subl $1,%ecx 22.65 1: movl %ecx,%eax # word count less prefix 22.66 sarl %ecx # dword count 22.67 jz 4f # no dwords to move 22.68 @@ -454,12 +455,13 @@ 22.69 ret 22.70 .=.+10 22.71 2: subl %esi,%edi 22.72 + jmp 4f 22.73 .p2align 4,,15 22.74 3: movl (%esi),%edx 22.75 movl %edx,(%edi,%esi,1) 22.76 addl $4,%esi 22.77 - subl $1,%ecx 22.78 - jnz 3b 22.79 +4: subl $1,%ecx 22.80 + jge 3b 22.81 popl %edi 22.82 popl %esi 22.83 ret 22.84 @@ -467,19 +469,20 @@ 22.85 std 22.86 leal -4(%edi,%ecx,4),%edi # to + count*4 - 4 22.87 cmpl $32,%ecx 22.88 - ja 3f # > 32 dwords 22.89 + ja 4f # > 32 dwords 22.90 subl %eax,%edi # eax == from + count*4 - 4 22.91 + jmp 3f 22.92 .p2align 4,,15 22.93 2: movl (%eax),%edx 22.94 movl %edx,(%edi,%eax,1) 22.95 subl $4,%eax 22.96 - subl $1,%ecx 22.97 - jnz 2b 22.98 +3: subl $1,%ecx 22.99 + jge 2b 22.100 cld 22.101 popl %edi 22.102 popl %esi 22.103 ret 22.104 -3: movl %eax,%esi # from + count*4 - 4 22.105 +4: movl %eax,%esi # from + count*4 - 4 22.106 rep; smovl 22.107 cld 22.108 popl %edi
23.1 --- a/src/os_cpu/solaris_x86/vm/solaris_x86_32.s Thu Jun 24 15:38:42 2010 -0700 23.2 +++ b/src/os_cpu/solaris_x86/vm/solaris_x86_32.s Mon Jun 28 12:03:05 2010 -0400 23.3 @@ -154,10 +154,10 @@ 23.4 jnz 3b 23.5 addl %esi,%edi 23.6 4: movl %eax,%ecx / byte count less prefix 23.7 - andl $3,%ecx / suffix byte count 23.8 +5: andl $3,%ecx / suffix byte count 23.9 jz 7f / no suffix 23.10 / copy suffix 23.11 -5: xorl %eax,%eax 23.12 + xorl %eax,%eax 23.13 6: movb (%esi,%eax,1),%dl 23.14 movb %dl,(%edi,%eax,1) 23.15 addl $1,%eax 23.16 @@ -192,10 +192,10 @@ 23.17 / copy dwords, aligned or not 23.18 3: rep; smovl 23.19 4: movl %eax,%ecx / byte count 23.20 - andl $3,%ecx / suffix byte count 23.21 +5: andl $3,%ecx / suffix byte count 23.22 jz 7f / no suffix 23.23 / copy suffix 23.24 -5: subl %esi,%edi 23.25 + subl %esi,%edi 23.26 addl $3,%esi 23.27 6: movb (%esi),%dl 23.28 movb %dl,(%edi,%esi,1) 23.29 @@ -246,10 +246,10 @@ 23.30 / copy aligned dwords 23.31 3: rep; smovl 23.32 4: movl %eax,%ecx 23.33 - andl $3,%ecx 23.34 +5: andl $3,%ecx 23.35 jz 7f 23.36 / copy suffix 23.37 -5: xorl %eax,%eax 23.38 + xorl %eax,%eax 23.39 6: movb (%esi,%eax,1),%dl 23.40 movb %dl,(%edi,%eax,1) 23.41 addl $1,%eax 23.42 @@ -282,9 +282,9 @@ 23.43 jnz 3b 23.44 addl %esi,%edi 23.45 4: movl %eax,%ecx 23.46 - andl $3,%ecx 23.47 +5: andl $3,%ecx 23.48 jz 7f 23.49 -5: subl %esi,%edi 23.50 + subl %esi,%edi 23.51 addl $3,%esi 23.52 6: movb (%esi),%dl 23.53 movb %dl,(%edi,%esi,1) 23.54 @@ -318,11 +318,12 @@ 23.55 andl $3,%eax / either 0 or 2 23.56 jz 1f / no prefix 23.57 / copy prefix 23.58 + subl $1,%ecx 23.59 + jl 5f / zero count 23.60 movw (%esi),%dx 23.61 movw %dx,(%edi) 23.62 addl %eax,%esi / %eax == 2 23.63 addl %eax,%edi 23.64 - subl $1,%ecx 23.65 1: movl %ecx,%eax / word count less prefix 23.66 sarl %ecx / dword count 23.67 jz 4f / no dwords to move 23.68 @@ -482,12 +483,13 @@ 23.69 ret 23.70 .=.+10 23.71 2: subl %esi,%edi 23.72 + jmp 4f 23.73 .align 16 23.74 3: movl (%esi),%edx 23.75 movl %edx,(%edi,%esi,1) 23.76 addl $4,%esi 23.77 - subl $1,%ecx 23.78 - jnz 3b 23.79 +4: subl $1,%ecx 23.80 + jge 3b 23.81 popl %edi 23.82 popl %esi 23.83 ret 23.84 @@ -495,19 +497,20 @@ 23.85 std 23.86 leal -4(%edi,%ecx,4),%edi / to + count*4 - 4 23.87 cmpl $32,%ecx 23.88 - ja 3f / > 32 dwords 23.89 + ja 4f / > 32 dwords 23.90 subl %eax,%edi / eax == from + count*4 - 4 23.91 + jmp 3f 23.92 .align 16 23.93 2: movl (%eax),%edx 23.94 movl %edx,(%edi,%eax,1) 23.95 subl $4,%eax 23.96 - subl $1,%ecx 23.97 - jnz 2b 23.98 +3: subl $1,%ecx 23.99 + jge 2b 23.100 cld 23.101 popl %edi 23.102 popl %esi 23.103 ret 23.104 -3: movl %eax,%esi / from + count*4 - 4 23.105 +4: movl %eax,%esi / from + count*4 - 4 23.106 rep; smovl 23.107 cld 23.108 popl %edi
24.1 --- a/src/share/vm/asm/codeBuffer.cpp Thu Jun 24 15:38:42 2010 -0700 24.2 +++ b/src/share/vm/asm/codeBuffer.cpp Mon Jun 28 12:03:05 2010 -0400 24.3 @@ -404,7 +404,7 @@ 24.4 locs_start = REALLOC_RESOURCE_ARRAY(relocInfo, _locs_start, old_capacity, new_capacity); 24.5 } else { 24.6 locs_start = NEW_RESOURCE_ARRAY(relocInfo, new_capacity); 24.7 - Copy::conjoint_bytes(_locs_start, locs_start, old_capacity * sizeof(relocInfo)); 24.8 + Copy::conjoint_jbytes(_locs_start, locs_start, old_capacity * sizeof(relocInfo)); 24.9 _locs_own = true; 24.10 } 24.11 _locs_start = locs_start; 24.12 @@ -581,7 +581,7 @@ 24.13 (HeapWord*)(buf+buf_offset), 24.14 (lsize + HeapWordSize-1) / HeapWordSize); 24.15 } else { 24.16 - Copy::conjoint_bytes(lstart, buf+buf_offset, lsize); 24.17 + Copy::conjoint_jbytes(lstart, buf+buf_offset, lsize); 24.18 } 24.19 } 24.20 buf_offset += lsize;
25.1 --- a/src/share/vm/c1/c1_Compilation.cpp Thu Jun 24 15:38:42 2010 -0700 25.2 +++ b/src/share/vm/c1/c1_Compilation.cpp Mon Jun 28 12:03:05 2010 -0400 25.3 @@ -242,10 +242,10 @@ 25.4 code->insts()->initialize_shared_locs((relocInfo*)locs_buffer, 25.5 locs_buffer_size / sizeof(relocInfo)); 25.6 code->initialize_consts_size(Compilation::desired_max_constant_size()); 25.7 - // Call stubs + deopt/exception handler 25.8 + // Call stubs + two deopt handlers (regular and MH) + exception handler 25.9 code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) + 25.10 LIR_Assembler::exception_handler_size + 25.11 - LIR_Assembler::deopt_handler_size); 25.12 + 2 * LIR_Assembler::deopt_handler_size); 25.13 } 25.14 25.15
26.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Jun 24 15:38:42 2010 -0700 26.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Mon Jun 28 12:03:05 2010 -0400 26.3 @@ -878,15 +878,12 @@ 26.4 case T_OBJECT : 26.5 { 26.6 ciObject* obj = con.as_object(); 26.7 - if (obj->is_klass()) { 26.8 - ciKlass* klass = obj->as_klass(); 26.9 - if (!klass->is_loaded() || PatchALot) { 26.10 - patch_state = state()->copy(); 26.11 - t = new ObjectConstant(obj); 26.12 - } else { 26.13 - t = new InstanceConstant(klass->java_mirror()); 26.14 - } 26.15 + if (!obj->is_loaded() 26.16 + || (PatchALot && obj->klass() != ciEnv::current()->String_klass())) { 26.17 + patch_state = state()->copy(); 26.18 + t = new ObjectConstant(obj); 26.19 } else { 26.20 + assert(!obj->is_klass(), "must be java_mirror of klass"); 26.21 t = new InstanceConstant(obj->as_instance()); 26.22 } 26.23 break;
27.1 --- a/src/share/vm/c1/c1_Runtime1.cpp Thu Jun 24 15:38:42 2010 -0700 27.2 +++ b/src/share/vm/c1/c1_Runtime1.cpp Mon Jun 28 12:03:05 2010 -0400 27.3 @@ -601,7 +601,7 @@ 27.4 27.5 27.6 static klassOop resolve_field_return_klass(methodHandle caller, int bci, TRAPS) { 27.7 - Bytecode_field* field_access = Bytecode_field_at(caller(), caller->bcp_from(bci)); 27.8 + Bytecode_field* field_access = Bytecode_field_at(caller, bci); 27.9 // This can be static or non-static field access 27.10 Bytecodes::Code code = field_access->code(); 27.11 27.12 @@ -721,7 +721,7 @@ 27.13 Handle load_klass(THREAD, NULL); // oop needed by load_klass_patching code 27.14 if (stub_id == Runtime1::access_field_patching_id) { 27.15 27.16 - Bytecode_field* field_access = Bytecode_field_at(caller_method(), caller_method->bcp_from(bci)); 27.17 + Bytecode_field* field_access = Bytecode_field_at(caller_method, bci); 27.18 FieldAccessInfo result; // initialize class if needed 27.19 Bytecodes::Code code = field_access->code(); 27.20 constantPoolHandle constants(THREAD, caller_method->constants()); 27.21 @@ -781,11 +781,9 @@ 27.22 case Bytecodes::_ldc: 27.23 case Bytecodes::_ldc_w: 27.24 { 27.25 - Bytecode_loadconstant* cc = Bytecode_loadconstant_at(caller_method(), 27.26 - caller_method->bcp_from(bci)); 27.27 - klassOop resolved = caller_method->constants()->klass_at(cc->index(), CHECK); 27.28 - // ldc wants the java mirror. 27.29 - k = resolved->klass_part()->java_mirror(); 27.30 + Bytecode_loadconstant* cc = Bytecode_loadconstant_at(caller_method, bci); 27.31 + k = cc->resolve_constant(CHECK); 27.32 + assert(k != NULL && !k->is_klass(), "must be class mirror or other Java constant"); 27.33 } 27.34 break; 27.35 default: Unimplemented(); 27.36 @@ -816,6 +814,15 @@ 27.37 // Return to the now deoptimized frame. 27.38 } 27.39 27.40 + // If we are patching in a non-perm oop, make sure the nmethod 27.41 + // is on the right list. 27.42 + if (ScavengeRootsInCode && load_klass.not_null() && load_klass->is_scavengable()) { 27.43 + MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag); 27.44 + nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); 27.45 + guarantee(nm != NULL, "only nmethods can contain non-perm oops"); 27.46 + if (!nm->on_scavenge_root_list()) 27.47 + CodeCache::add_scavenge_root_nmethod(nm); 27.48 + } 27.49 27.50 // Now copy code back 27.51 27.52 @@ -1115,7 +1122,7 @@ 27.53 if (length == 0) return; 27.54 // Not guaranteed to be word atomic, but that doesn't matter 27.55 // for anything but an oop array, which is covered by oop_arraycopy. 27.56 - Copy::conjoint_bytes(src, dst, length); 27.57 + Copy::conjoint_jbytes(src, dst, length); 27.58 JRT_END 27.59 27.60 JRT_LEAF(void, Runtime1::oop_arraycopy(HeapWord* src, HeapWord* dst, int num))
28.1 --- a/src/share/vm/ci/ciCPCache.cpp Thu Jun 24 15:38:42 2010 -0700 28.2 +++ b/src/share/vm/ci/ciCPCache.cpp Mon Jun 28 12:03:05 2010 -0400 28.3 @@ -44,13 +44,23 @@ 28.4 // ciCPCache::is_f1_null_at 28.5 bool ciCPCache::is_f1_null_at(int index) { 28.6 VM_ENTRY_MARK; 28.7 - constantPoolCacheOop cpcache = (constantPoolCacheOop) get_oop(); 28.8 - oop f1 = cpcache->secondary_entry_at(index)->f1(); 28.9 + oop f1 = entry_at(index)->f1(); 28.10 return (f1 == NULL); 28.11 } 28.12 28.13 28.14 // ------------------------------------------------------------------ 28.15 +// ciCPCache::get_pool_index 28.16 +int ciCPCache::get_pool_index(int index) { 28.17 + VM_ENTRY_MARK; 28.18 + ConstantPoolCacheEntry* e = entry_at(index); 28.19 + if (e->is_secondary_entry()) 28.20 + e = entry_at(e->main_entry_index()); 28.21 + return e->constant_pool_index(); 28.22 +} 28.23 + 28.24 + 28.25 +// ------------------------------------------------------------------ 28.26 // ciCPCache::print 28.27 // 28.28 // Print debugging information about the cache.
29.1 --- a/src/share/vm/ci/ciCPCache.hpp Thu Jun 24 15:38:42 2010 -0700 29.2 +++ b/src/share/vm/ci/ciCPCache.hpp Mon Jun 28 12:03:05 2010 -0400 29.3 @@ -29,6 +29,18 @@ 29.4 // Note: This class is called ciCPCache as ciConstantPoolCache is used 29.5 // for something different. 29.6 class ciCPCache : public ciObject { 29.7 +private: 29.8 + constantPoolCacheOop get_cpCacheOop() { // must be called inside a VM_ENTRY_MARK 29.9 + return (constantPoolCacheOop) get_oop(); 29.10 + } 29.11 + 29.12 + ConstantPoolCacheEntry* entry_at(int i) { 29.13 + int raw_index = i; 29.14 + if (constantPoolCacheOopDesc::is_secondary_index(i)) 29.15 + raw_index = constantPoolCacheOopDesc::decode_secondary_index(i); 29.16 + return get_cpCacheOop()->entry_at(raw_index); 29.17 + } 29.18 + 29.19 public: 29.20 ciCPCache(constantPoolCacheHandle cpcache) : ciObject(cpcache) {} 29.21 29.22 @@ -41,5 +53,7 @@ 29.23 29.24 bool is_f1_null_at(int index); 29.25 29.26 + int get_pool_index(int index); 29.27 + 29.28 void print(); 29.29 };
30.1 --- a/src/share/vm/ci/ciClassList.hpp Thu Jun 24 15:38:42 2010 -0700 30.2 +++ b/src/share/vm/ci/ciClassList.hpp Mon Jun 28 12:03:05 2010 -0400 30.3 @@ -85,6 +85,7 @@ 30.4 friend class ciConstantPoolCache; \ 30.5 friend class ciField; \ 30.6 friend class ciConstant; \ 30.7 +friend class ciCPCache; \ 30.8 friend class ciFlags; \ 30.9 friend class ciExceptionHandler; \ 30.10 friend class ciCallProfile; \
31.1 --- a/src/share/vm/ci/ciEnv.cpp Thu Jun 24 15:38:42 2010 -0700 31.2 +++ b/src/share/vm/ci/ciEnv.cpp Mon Jun 28 12:03:05 2010 -0400 31.3 @@ -511,9 +511,22 @@ 31.4 // 31.5 // Implementation of get_constant_by_index(). 31.6 ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool, 31.7 - int index, 31.8 + int pool_index, int cache_index, 31.9 ciInstanceKlass* accessor) { 31.10 + bool ignore_will_link; 31.11 EXCEPTION_CONTEXT; 31.12 + int index = pool_index; 31.13 + if (cache_index >= 0) { 31.14 + assert(index < 0, "only one kind of index at a time"); 31.15 + ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index); 31.16 + index = cpc_entry->constant_pool_index(); 31.17 + oop obj = cpc_entry->f1(); 31.18 + if (obj != NULL) { 31.19 + assert(obj->is_instance(), "must be an instance"); 31.20 + ciObject* ciobj = get_object(obj); 31.21 + return ciConstant(T_OBJECT, ciobj); 31.22 + } 31.23 + } 31.24 constantTag tag = cpool->tag_at(index); 31.25 if (tag.is_int()) { 31.26 return ciConstant(T_INT, (jint)cpool->int_at(index)); 31.27 @@ -540,8 +553,7 @@ 31.28 return ciConstant(T_OBJECT, constant); 31.29 } else if (tag.is_klass() || tag.is_unresolved_klass()) { 31.30 // 4881222: allow ldc to take a class type 31.31 - bool ignore; 31.32 - ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore, accessor); 31.33 + ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore_will_link, accessor); 31.34 if (HAS_PENDING_EXCEPTION) { 31.35 CLEAR_PENDING_EXCEPTION; 31.36 record_out_of_memory_failure(); 31.37 @@ -549,12 +561,26 @@ 31.38 } 31.39 assert (klass->is_instance_klass() || klass->is_array_klass(), 31.40 "must be an instance or array klass "); 31.41 - return ciConstant(T_OBJECT, klass); 31.42 + return ciConstant(T_OBJECT, klass->java_mirror()); 31.43 } else if (tag.is_object()) { 31.44 oop obj = cpool->object_at(index); 31.45 assert(obj->is_instance(), "must be an instance"); 31.46 ciObject* ciobj = get_object(obj); 31.47 return ciConstant(T_OBJECT, ciobj); 31.48 + } else if (tag.is_method_type()) { 31.49 + // must execute Java code to link this CP entry into cache[i].f1 31.50 + ciSymbol* signature = get_object(cpool->method_type_signature_at(index))->as_symbol(); 31.51 + ciObject* ciobj = get_unloaded_method_type_constant(signature); 31.52 + return ciConstant(T_OBJECT, ciobj); 31.53 + } else if (tag.is_method_handle()) { 31.54 + // must execute Java code to link this CP entry into cache[i].f1 31.55 + int ref_kind = cpool->method_handle_ref_kind_at(index); 31.56 + int callee_index = cpool->method_handle_klass_index_at(index); 31.57 + ciKlass* callee = get_klass_by_index_impl(cpool, callee_index, ignore_will_link, accessor); 31.58 + ciSymbol* name = get_object(cpool->method_handle_name_ref_at(index))->as_symbol(); 31.59 + ciSymbol* signature = get_object(cpool->method_handle_signature_ref_at(index))->as_symbol(); 31.60 + ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind); 31.61 + return ciConstant(T_OBJECT, ciobj); 31.62 } else { 31.63 ShouldNotReachHere(); 31.64 return ciConstant(); 31.65 @@ -562,61 +588,15 @@ 31.66 } 31.67 31.68 // ------------------------------------------------------------------ 31.69 -// ciEnv::is_unresolved_string_impl 31.70 -// 31.71 -// Implementation of is_unresolved_string(). 31.72 -bool ciEnv::is_unresolved_string_impl(instanceKlass* accessor, int index) const { 31.73 - EXCEPTION_CONTEXT; 31.74 - assert(accessor->is_linked(), "must be linked before accessing constant pool"); 31.75 - constantPoolOop cpool = accessor->constants(); 31.76 - constantTag tag = cpool->tag_at(index); 31.77 - return tag.is_unresolved_string(); 31.78 -} 31.79 - 31.80 -// ------------------------------------------------------------------ 31.81 -// ciEnv::is_unresolved_klass_impl 31.82 -// 31.83 -// Implementation of is_unresolved_klass(). 31.84 -bool ciEnv::is_unresolved_klass_impl(instanceKlass* accessor, int index) const { 31.85 - EXCEPTION_CONTEXT; 31.86 - assert(accessor->is_linked(), "must be linked before accessing constant pool"); 31.87 - constantPoolOop cpool = accessor->constants(); 31.88 - constantTag tag = cpool->tag_at(index); 31.89 - return tag.is_unresolved_klass(); 31.90 -} 31.91 - 31.92 -// ------------------------------------------------------------------ 31.93 // ciEnv::get_constant_by_index 31.94 // 31.95 // Pull a constant out of the constant pool. How appropriate. 31.96 // 31.97 // Implementation note: this query is currently in no way cached. 31.98 ciConstant ciEnv::get_constant_by_index(constantPoolHandle cpool, 31.99 - int index, 31.100 + int pool_index, int cache_index, 31.101 ciInstanceKlass* accessor) { 31.102 - GUARDED_VM_ENTRY(return get_constant_by_index_impl(cpool, index, accessor);) 31.103 -} 31.104 - 31.105 -// ------------------------------------------------------------------ 31.106 -// ciEnv::is_unresolved_string 31.107 -// 31.108 -// Check constant pool 31.109 -// 31.110 -// Implementation note: this query is currently in no way cached. 31.111 -bool ciEnv::is_unresolved_string(ciInstanceKlass* accessor, 31.112 - int index) const { 31.113 - GUARDED_VM_ENTRY(return is_unresolved_string_impl(accessor->get_instanceKlass(), index); ) 31.114 -} 31.115 - 31.116 -// ------------------------------------------------------------------ 31.117 -// ciEnv::is_unresolved_klass 31.118 -// 31.119 -// Check constant pool 31.120 -// 31.121 -// Implementation note: this query is currently in no way cached. 31.122 -bool ciEnv::is_unresolved_klass(ciInstanceKlass* accessor, 31.123 - int index) const { 31.124 - GUARDED_VM_ENTRY(return is_unresolved_klass_impl(accessor->get_instanceKlass(), index); ) 31.125 + GUARDED_VM_ENTRY(return get_constant_by_index_impl(cpool, pool_index, cache_index, accessor);) 31.126 } 31.127 31.128 // ------------------------------------------------------------------
32.1 --- a/src/share/vm/ci/ciEnv.hpp Thu Jun 24 15:38:42 2010 -0700 32.2 +++ b/src/share/vm/ci/ciEnv.hpp Mon Jun 28 12:03:05 2010 -0400 32.3 @@ -116,12 +116,8 @@ 32.4 bool& is_accessible, 32.5 ciInstanceKlass* loading_klass); 32.6 ciConstant get_constant_by_index(constantPoolHandle cpool, 32.7 - int constant_index, 32.8 + int pool_index, int cache_index, 32.9 ciInstanceKlass* accessor); 32.10 - bool is_unresolved_string(ciInstanceKlass* loading_klass, 32.11 - int constant_index) const; 32.12 - bool is_unresolved_klass(ciInstanceKlass* loading_klass, 32.13 - int constant_index) const; 32.14 ciField* get_field_by_index(ciInstanceKlass* loading_klass, 32.15 int field_index); 32.16 ciMethod* get_method_by_index(constantPoolHandle cpool, 32.17 @@ -137,12 +133,8 @@ 32.18 bool& is_accessible, 32.19 ciInstanceKlass* loading_klass); 32.20 ciConstant get_constant_by_index_impl(constantPoolHandle cpool, 32.21 - int constant_index, 32.22 + int pool_index, int cache_index, 32.23 ciInstanceKlass* loading_klass); 32.24 - bool is_unresolved_string_impl (instanceKlass* loading_klass, 32.25 - int constant_index) const; 32.26 - bool is_unresolved_klass_impl (instanceKlass* loading_klass, 32.27 - int constant_index) const; 32.28 ciField* get_field_by_index_impl(ciInstanceKlass* loading_klass, 32.29 int field_index); 32.30 ciMethod* get_method_by_index_impl(constantPoolHandle cpool, 32.31 @@ -190,6 +182,25 @@ 32.32 return _factory->get_unloaded_klass(accessing_klass, name, true); 32.33 } 32.34 32.35 + // Get a ciKlass representing an unloaded klass mirror. 32.36 + // Result is not necessarily unique, but will be unloaded. 32.37 + ciInstance* get_unloaded_klass_mirror(ciKlass* type) { 32.38 + return _factory->get_unloaded_klass_mirror(type); 32.39 + } 32.40 + 32.41 + // Get a ciInstance representing an unresolved method handle constant. 32.42 + ciInstance* get_unloaded_method_handle_constant(ciKlass* holder, 32.43 + ciSymbol* name, 32.44 + ciSymbol* signature, 32.45 + int ref_kind) { 32.46 + return _factory->get_unloaded_method_handle_constant(holder, name, signature, ref_kind); 32.47 + } 32.48 + 32.49 + // Get a ciInstance representing an unresolved method type constant. 32.50 + ciInstance* get_unloaded_method_type_constant(ciSymbol* signature) { 32.51 + return _factory->get_unloaded_method_type_constant(signature); 32.52 + } 32.53 + 32.54 // See if we already have an unloaded klass for the given name 32.55 // or return NULL if not. 32.56 ciKlass *check_get_unloaded_klass(ciKlass* accessing_klass, ciSymbol* name) {
33.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp Thu Jun 24 15:38:42 2010 -0700 33.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Mon Jun 28 12:03:05 2010 -0400 33.3 @@ -323,8 +323,8 @@ 33.4 // ciInstanceKlass::java_mirror 33.5 // 33.6 // Get the instance of java.lang.Class corresponding to this klass. 33.7 +// Cache it on this->_java_mirror. 33.8 ciInstance* ciInstanceKlass::java_mirror() { 33.9 - assert(is_loaded(), "must be loaded"); 33.10 if (_java_mirror == NULL) { 33.11 _java_mirror = ciKlass::java_mirror(); 33.12 }
34.1 --- a/src/share/vm/ci/ciKlass.cpp Thu Jun 24 15:38:42 2010 -0700 34.2 +++ b/src/share/vm/ci/ciKlass.cpp Mon Jun 28 12:03:05 2010 -0400 34.3 @@ -192,8 +192,14 @@ 34.4 34.5 // ------------------------------------------------------------------ 34.6 // ciKlass::java_mirror 34.7 +// 34.8 +// Get the instance of java.lang.Class corresponding to this klass. 34.9 +// If it is an unloaded instance or array klass, return an unloaded 34.10 +// mirror object of type Class. 34.11 ciInstance* ciKlass::java_mirror() { 34.12 GUARDED_VM_ENTRY( 34.13 + if (!is_loaded()) 34.14 + return ciEnv::current()->get_unloaded_klass_mirror(this); 34.15 oop java_mirror = get_Klass()->java_mirror(); 34.16 return CURRENT_ENV->get_object(java_mirror)->as_instance(); 34.17 )
35.1 --- a/src/share/vm/ci/ciObjectFactory.cpp Thu Jun 24 15:38:42 2010 -0700 35.2 +++ b/src/share/vm/ci/ciObjectFactory.cpp Mon Jun 28 12:03:05 2010 -0400 35.3 @@ -70,6 +70,7 @@ 35.4 35.5 _unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL); 35.6 _unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL); 35.7 + _unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL); 35.8 _return_addresses = 35.9 new (arena) GrowableArray<ciReturnAddress*>(arena, 8, 0, NULL); 35.10 } 35.11 @@ -443,6 +444,74 @@ 35.12 return new_klass; 35.13 } 35.14 35.15 + 35.16 +//------------------------------------------------------------------ 35.17 +// ciObjectFactory::get_unloaded_instance 35.18 +// 35.19 +// Get a ciInstance representing an as-yet undetermined instance of a given class. 35.20 +// 35.21 +ciInstance* ciObjectFactory::get_unloaded_instance(ciInstanceKlass* instance_klass) { 35.22 + for (int i=0; i<_unloaded_instances->length(); i++) { 35.23 + ciInstance* entry = _unloaded_instances->at(i); 35.24 + if (entry->klass()->equals(instance_klass)) { 35.25 + // We've found a match. 35.26 + return entry; 35.27 + } 35.28 + } 35.29 + 35.30 + // This is a new unloaded instance. Create it and stick it in 35.31 + // the cache. 35.32 + ciInstance* new_instance = new (arena()) ciInstance(instance_klass); 35.33 + 35.34 + init_ident_of(new_instance); 35.35 + _unloaded_instances->append(new_instance); 35.36 + 35.37 + // make sure it looks the way we want: 35.38 + assert(!new_instance->is_loaded(), ""); 35.39 + assert(new_instance->klass() == instance_klass, ""); 35.40 + 35.41 + return new_instance; 35.42 +} 35.43 + 35.44 + 35.45 +//------------------------------------------------------------------ 35.46 +// ciObjectFactory::get_unloaded_klass_mirror 35.47 +// 35.48 +// Get a ciInstance representing an unresolved klass mirror. 35.49 +// 35.50 +// Currently, this ignores the parameters and returns a unique unloaded instance. 35.51 +ciInstance* ciObjectFactory::get_unloaded_klass_mirror(ciKlass* type) { 35.52 + assert(ciEnv::_Class_klass != NULL, ""); 35.53 + return get_unloaded_instance(ciEnv::_Class_klass->as_instance_klass()); 35.54 +} 35.55 + 35.56 +//------------------------------------------------------------------ 35.57 +// ciObjectFactory::get_unloaded_method_handle_constant 35.58 +// 35.59 +// Get a ciInstance representing an unresolved method handle constant. 35.60 +// 35.61 +// Currently, this ignores the parameters and returns a unique unloaded instance. 35.62 +ciInstance* ciObjectFactory::get_unloaded_method_handle_constant(ciKlass* holder, 35.63 + ciSymbol* name, 35.64 + ciSymbol* signature, 35.65 + int ref_kind) { 35.66 + if (ciEnv::_MethodHandle_klass == NULL) return NULL; 35.67 + return get_unloaded_instance(ciEnv::_MethodHandle_klass->as_instance_klass()); 35.68 +} 35.69 + 35.70 +//------------------------------------------------------------------ 35.71 +// ciObjectFactory::get_unloaded_method_type_constant 35.72 +// 35.73 +// Get a ciInstance representing an unresolved method type constant. 35.74 +// 35.75 +// Currently, this ignores the parameters and returns a unique unloaded instance. 35.76 +ciInstance* ciObjectFactory::get_unloaded_method_type_constant(ciSymbol* signature) { 35.77 + if (ciEnv::_MethodType_klass == NULL) return NULL; 35.78 + return get_unloaded_instance(ciEnv::_MethodType_klass->as_instance_klass()); 35.79 +} 35.80 + 35.81 + 35.82 + 35.83 //------------------------------------------------------------------ 35.84 // ciObjectFactory::get_empty_methodData 35.85 // 35.86 @@ -637,7 +706,8 @@ 35.87 // 35.88 // Print debugging information about the object factory 35.89 void ciObjectFactory::print() { 35.90 - tty->print("<ciObjectFactory oops=%d unloaded_methods=%d unloaded_klasses=%d>", 35.91 + tty->print("<ciObjectFactory oops=%d unloaded_methods=%d unloaded_instances=%d unloaded_klasses=%d>", 35.92 _ci_objects->length(), _unloaded_methods->length(), 35.93 + _unloaded_instances->length(), 35.94 _unloaded_klasses->length()); 35.95 }
36.1 --- a/src/share/vm/ci/ciObjectFactory.hpp Thu Jun 24 15:38:42 2010 -0700 36.2 +++ b/src/share/vm/ci/ciObjectFactory.hpp Mon Jun 28 12:03:05 2010 -0400 36.3 @@ -39,6 +39,7 @@ 36.4 GrowableArray<ciObject*>* _ci_objects; 36.5 GrowableArray<ciMethod*>* _unloaded_methods; 36.6 GrowableArray<ciKlass*>* _unloaded_klasses; 36.7 + GrowableArray<ciInstance*>* _unloaded_instances; 36.8 GrowableArray<ciReturnAddress*>* _return_addresses; 36.9 int _next_ident; 36.10 36.11 @@ -73,6 +74,8 @@ 36.12 36.13 void print_contents_impl(); 36.14 36.15 + ciInstance* get_unloaded_instance(ciInstanceKlass* klass); 36.16 + 36.17 public: 36.18 static bool is_initialized() { return _initialized; } 36.19 36.20 @@ -98,6 +101,18 @@ 36.21 ciSymbol* name, 36.22 bool create_if_not_found); 36.23 36.24 + // Get a ciInstance representing an unresolved klass mirror. 36.25 + ciInstance* get_unloaded_klass_mirror(ciKlass* type); 36.26 + 36.27 + // Get a ciInstance representing an unresolved method handle constant. 36.28 + ciInstance* get_unloaded_method_handle_constant(ciKlass* holder, 36.29 + ciSymbol* name, 36.30 + ciSymbol* signature, 36.31 + int ref_kind); 36.32 + 36.33 + // Get a ciInstance representing an unresolved method type constant. 36.34 + ciInstance* get_unloaded_method_type_constant(ciSymbol* signature); 36.35 + 36.36 36.37 // Get the ciMethodData representing the methodData for a method 36.38 // with none.
37.1 --- a/src/share/vm/ci/ciStreams.cpp Thu Jun 24 15:38:42 2010 -0700 37.2 +++ b/src/share/vm/ci/ciStreams.cpp Mon Jun 28 12:03:05 2010 -0400 37.3 @@ -186,12 +186,13 @@ 37.4 } 37.5 37.6 // ------------------------------------------------------------------ 37.7 -// ciBytecodeStream::get_constant_index 37.8 +// ciBytecodeStream::get_constant_raw_index 37.9 // 37.10 // If this bytecode is one of the ldc variants, get the index of the 37.11 // referenced constant. 37.12 -int ciBytecodeStream::get_constant_index() const { 37.13 - switch(cur_bc()) { 37.14 +int ciBytecodeStream::get_constant_raw_index() const { 37.15 + // work-alike for Bytecode_loadconstant::raw_index() 37.16 + switch (cur_bc()) { 37.17 case Bytecodes::_ldc: 37.18 return get_index_u1(); 37.19 case Bytecodes::_ldc_w: 37.20 @@ -202,25 +203,52 @@ 37.21 return 0; 37.22 } 37.23 } 37.24 + 37.25 +// ------------------------------------------------------------------ 37.26 +// ciBytecodeStream::get_constant_pool_index 37.27 +// Decode any CP cache index into a regular pool index. 37.28 +int ciBytecodeStream::get_constant_pool_index() const { 37.29 + // work-alike for Bytecode_loadconstant::pool_index() 37.30 + int index = get_constant_raw_index(); 37.31 + if (has_cache_index()) { 37.32 + return get_cpcache()->get_pool_index(index); 37.33 + } 37.34 + return index; 37.35 +} 37.36 + 37.37 +// ------------------------------------------------------------------ 37.38 +// ciBytecodeStream::get_constant_cache_index 37.39 +// Return the CP cache index, or -1 if there isn't any. 37.40 +int ciBytecodeStream::get_constant_cache_index() const { 37.41 + // work-alike for Bytecode_loadconstant::cache_index() 37.42 + return has_cache_index() ? get_constant_raw_index() : -1; 37.43 +} 37.44 + 37.45 // ------------------------------------------------------------------ 37.46 // ciBytecodeStream::get_constant 37.47 // 37.48 // If this bytecode is one of the ldc variants, get the referenced 37.49 // constant. 37.50 ciConstant ciBytecodeStream::get_constant() { 37.51 + int pool_index = get_constant_raw_index(); 37.52 + int cache_index = -1; 37.53 + if (has_cache_index()) { 37.54 + cache_index = pool_index; 37.55 + pool_index = -1; 37.56 + } 37.57 VM_ENTRY_MARK; 37.58 constantPoolHandle cpool(_method->get_methodOop()->constants()); 37.59 - return CURRENT_ENV->get_constant_by_index(cpool, get_constant_index(), _holder); 37.60 + return CURRENT_ENV->get_constant_by_index(cpool, pool_index, cache_index, _holder); 37.61 } 37.62 37.63 // ------------------------------------------------------------------ 37.64 -bool ciBytecodeStream::is_unresolved_string() const { 37.65 - return CURRENT_ENV->is_unresolved_string(_holder, get_constant_index()); 37.66 -} 37.67 - 37.68 -// ------------------------------------------------------------------ 37.69 -bool ciBytecodeStream::is_unresolved_klass() const { 37.70 - return CURRENT_ENV->is_unresolved_klass(_holder, get_klass_index()); 37.71 +// ciBytecodeStream::get_constant_pool_tag 37.72 +// 37.73 +// If this bytecode is one of the ldc variants, get the referenced 37.74 +// constant. 37.75 +constantTag ciBytecodeStream::get_constant_pool_tag(int index) const { 37.76 + VM_ENTRY_MARK; 37.77 + return _method->get_methodOop()->constants()->tag_at(index); 37.78 } 37.79 37.80 // ------------------------------------------------------------------ 37.81 @@ -378,13 +406,16 @@ 37.82 37.83 // ------------------------------------------------------------------ 37.84 // ciBytecodeStream::get_cpcache 37.85 -ciCPCache* ciBytecodeStream::get_cpcache() { 37.86 - VM_ENTRY_MARK; 37.87 - // Get the constant pool. 37.88 - constantPoolOop cpool = _holder->get_instanceKlass()->constants(); 37.89 - constantPoolCacheOop cpcache = cpool->cache(); 37.90 +ciCPCache* ciBytecodeStream::get_cpcache() const { 37.91 + if (_cpcache == NULL) { 37.92 + VM_ENTRY_MARK; 37.93 + // Get the constant pool. 37.94 + constantPoolOop cpool = _holder->get_instanceKlass()->constants(); 37.95 + constantPoolCacheOop cpcache = cpool->cache(); 37.96 37.97 - return CURRENT_ENV->get_object(cpcache)->as_cpcache(); 37.98 + *(ciCPCache**)&_cpcache = CURRENT_ENV->get_object(cpcache)->as_cpcache(); 37.99 + } 37.100 + return _cpcache; 37.101 } 37.102 37.103 // ------------------------------------------------------------------
38.1 --- a/src/share/vm/ci/ciStreams.hpp Thu Jun 24 15:38:42 2010 -0700 38.2 +++ b/src/share/vm/ci/ciStreams.hpp Mon Jun 28 12:03:05 2010 -0400 38.3 @@ -46,6 +46,7 @@ 38.4 38.5 ciMethod* _method; // the method 38.6 ciInstanceKlass* _holder; 38.7 + ciCPCache* _cpcache; 38.8 address _bc_start; // Start of current bytecode for table 38.9 address _was_wide; // Address past last wide bytecode 38.10 jint* _table_base; // Aligned start of last table or switch 38.11 @@ -58,7 +59,9 @@ 38.12 38.13 void reset( address base, unsigned int size ) { 38.14 _bc_start =_was_wide = 0; 38.15 - _start = _pc = base; _end = base + size; } 38.16 + _start = _pc = base; _end = base + size; 38.17 + _cpcache = NULL; 38.18 + } 38.19 38.20 void assert_wide(bool require_wide) const { 38.21 if (require_wide) 38.22 @@ -136,15 +139,20 @@ 38.23 bool is_wide() const { return ( _pc == _was_wide ); } 38.24 38.25 // Does this instruction contain an index which refes into the CP cache? 38.26 - bool uses_cp_cache() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); } 38.27 + bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); } 38.28 38.29 int get_index_u1() const { 38.30 return bytecode()->get_index_u1(cur_bc_raw()); 38.31 } 38.32 38.33 + int get_index_u1_cpcache() const { 38.34 + return bytecode()->get_index_u1_cpcache(cur_bc_raw()); 38.35 + } 38.36 + 38.37 // Get a byte index following this bytecode. 38.38 // If prefixed with a wide bytecode, get a wide index. 38.39 int get_index() const { 38.40 + assert(!has_cache_index(), "else use cpcache variant"); 38.41 return (_pc == _was_wide) // was widened? 38.42 ? get_index_u2(true) // yes, return wide index 38.43 : get_index_u1(); // no, return narrow index 38.44 @@ -207,7 +215,9 @@ 38.45 return cur_bci() + get_int_table(index); } 38.46 38.47 // --- Constant pool access --- 38.48 - int get_constant_index() const; 38.49 + int get_constant_raw_index() const; 38.50 + int get_constant_pool_index() const; 38.51 + int get_constant_cache_index() const; 38.52 int get_field_index(); 38.53 int get_method_index(); 38.54 38.55 @@ -217,12 +227,17 @@ 38.56 int get_klass_index() const; 38.57 38.58 // If this bytecode is one of the ldc variants, get the referenced 38.59 - // constant 38.60 + // constant. Do not attempt to resolve it, since that would require 38.61 + // execution of Java code. If it is not resolved, return an unloaded 38.62 + // object (ciConstant.as_object()->is_loaded() == false). 38.63 ciConstant get_constant(); 38.64 - // True if the ldc variant points to an unresolved string 38.65 - bool is_unresolved_string() const; 38.66 - // True if the ldc variant points to an unresolved klass 38.67 - bool is_unresolved_klass() const; 38.68 + constantTag get_constant_pool_tag(int index) const; 38.69 + 38.70 + // True if the klass-using bytecode points to an unresolved klass 38.71 + bool is_unresolved_klass() const { 38.72 + constantTag tag = get_constant_pool_tag(get_klass_index()); 38.73 + return tag.is_unresolved_klass(); 38.74 + } 38.75 38.76 // If this bytecode is one of get_field, get_static, put_field, 38.77 // or put_static, get the referenced field. 38.78 @@ -238,7 +253,7 @@ 38.79 int get_method_holder_index(); 38.80 int get_method_signature_index(); 38.81 38.82 - ciCPCache* get_cpcache(); 38.83 + ciCPCache* get_cpcache() const; 38.84 ciCallSite* get_call_site(); 38.85 }; 38.86
39.1 --- a/src/share/vm/ci/ciTypeFlow.cpp Thu Jun 24 15:38:42 2010 -0700 39.2 +++ b/src/share/vm/ci/ciTypeFlow.cpp Mon Jun 28 12:03:05 2010 -0400 39.3 @@ -712,10 +712,8 @@ 39.4 ciObject* obj = con.as_object(); 39.5 if (obj->is_null_object()) { 39.6 push_null(); 39.7 - } else if (obj->is_klass()) { 39.8 - // The type of ldc <class> is java.lang.Class 39.9 - push_object(outer()->env()->Class_klass()); 39.10 } else { 39.11 + assert(!obj->is_klass(), "must be java_mirror of klass"); 39.12 push_object(obj->klass()); 39.13 } 39.14 } else {
40.1 --- a/src/share/vm/classfile/classFileParser.cpp Thu Jun 24 15:38:42 2010 -0700 40.2 +++ b/src/share/vm/classfile/classFileParser.cpp Mon Jun 28 12:03:05 2010 -0400 40.3 @@ -117,6 +117,29 @@ 40.4 cp->string_index_at_put(index, string_index); 40.5 } 40.6 break; 40.7 + case JVM_CONSTANT_MethodHandle : 40.8 + case JVM_CONSTANT_MethodType : 40.9 + if (!EnableMethodHandles || 40.10 + _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { 40.11 + classfile_parse_error( 40.12 + (!EnableInvokeDynamic ? 40.13 + "This JVM does not support constant tag %u in class file %s" : 40.14 + "Class file version does not support constant tag %u in class file %s"), 40.15 + tag, CHECK); 40.16 + } 40.17 + if (tag == JVM_CONSTANT_MethodHandle) { 40.18 + cfs->guarantee_more(4, CHECK); // ref_kind, method_index, tag/access_flags 40.19 + u1 ref_kind = cfs->get_u1_fast(); 40.20 + u2 method_index = cfs->get_u2_fast(); 40.21 + cp->method_handle_index_at_put(index, ref_kind, method_index); 40.22 + } else if (tag == JVM_CONSTANT_MethodType) { 40.23 + cfs->guarantee_more(3, CHECK); // signature_index, tag/access_flags 40.24 + u2 signature_index = cfs->get_u2_fast(); 40.25 + cp->method_type_index_at_put(index, signature_index); 40.26 + } else { 40.27 + ShouldNotReachHere(); 40.28 + } 40.29 + break; 40.30 case JVM_CONSTANT_Integer : 40.31 { 40.32 cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags 40.33 @@ -337,6 +360,60 @@ 40.34 cp->unresolved_string_at_put(index, sym); 40.35 } 40.36 break; 40.37 + case JVM_CONSTANT_MethodHandle : 40.38 + { 40.39 + int ref_index = cp->method_handle_index_at(index); 40.40 + check_property( 40.41 + valid_cp_range(ref_index, length) && 40.42 + EnableMethodHandles, 40.43 + "Invalid constant pool index %u in class file %s", 40.44 + ref_index, CHECK_(nullHandle)); 40.45 + constantTag tag = cp->tag_at(ref_index); 40.46 + int ref_kind = cp->method_handle_ref_kind_at(index); 40.47 + switch (ref_kind) { 40.48 + case JVM_REF_getField: 40.49 + case JVM_REF_getStatic: 40.50 + case JVM_REF_putField: 40.51 + case JVM_REF_putStatic: 40.52 + check_property( 40.53 + tag.is_field(), 40.54 + "Invalid constant pool index %u in class file %s (not a field)", 40.55 + ref_index, CHECK_(nullHandle)); 40.56 + break; 40.57 + case JVM_REF_invokeVirtual: 40.58 + case JVM_REF_invokeStatic: 40.59 + case JVM_REF_invokeSpecial: 40.60 + case JVM_REF_newInvokeSpecial: 40.61 + check_property( 40.62 + tag.is_method(), 40.63 + "Invalid constant pool index %u in class file %s (not a method)", 40.64 + ref_index, CHECK_(nullHandle)); 40.65 + break; 40.66 + case JVM_REF_invokeInterface: 40.67 + check_property( 40.68 + tag.is_interface_method(), 40.69 + "Invalid constant pool index %u in class file %s (not an interface method)", 40.70 + ref_index, CHECK_(nullHandle)); 40.71 + break; 40.72 + default: 40.73 + classfile_parse_error( 40.74 + "Bad method handle kind at constant pool index %u in class file %s", 40.75 + index, CHECK_(nullHandle)); 40.76 + } 40.77 + // Keep the ref_index unchanged. It will be indirected at link-time. 40.78 + } 40.79 + break; 40.80 + case JVM_CONSTANT_MethodType : 40.81 + { 40.82 + int ref_index = cp->method_type_index_at(index); 40.83 + check_property( 40.84 + valid_cp_range(ref_index, length) && 40.85 + cp->tag_at(ref_index).is_utf8() && 40.86 + EnableMethodHandles, 40.87 + "Invalid constant pool index %u in class file %s", 40.88 + ref_index, CHECK_(nullHandle)); 40.89 + } 40.90 + break; 40.91 default: 40.92 fatal(err_msg("bad constant pool tag value %u", 40.93 cp->tag_at(index).value())); 40.94 @@ -452,6 +529,43 @@ 40.95 } 40.96 break; 40.97 } 40.98 + case JVM_CONSTANT_MethodHandle: { 40.99 + int ref_index = cp->method_handle_index_at(index); 40.100 + int ref_kind = cp->method_handle_ref_kind_at(index); 40.101 + switch (ref_kind) { 40.102 + case JVM_REF_invokeVirtual: 40.103 + case JVM_REF_invokeStatic: 40.104 + case JVM_REF_invokeSpecial: 40.105 + case JVM_REF_newInvokeSpecial: 40.106 + { 40.107 + int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index); 40.108 + int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); 40.109 + symbolHandle name(THREAD, cp->symbol_at(name_ref_index)); 40.110 + if (ref_kind == JVM_REF_newInvokeSpecial) { 40.111 + if (name() != vmSymbols::object_initializer_name()) { 40.112 + classfile_parse_error( 40.113 + "Bad constructor name at constant pool index %u in class file %s", 40.114 + name_ref_index, CHECK_(nullHandle)); 40.115 + } 40.116 + } else { 40.117 + if (name() == vmSymbols::object_initializer_name()) { 40.118 + classfile_parse_error( 40.119 + "Bad method name at constant pool index %u in class file %s", 40.120 + name_ref_index, CHECK_(nullHandle)); 40.121 + } 40.122 + } 40.123 + } 40.124 + break; 40.125 + // Other ref_kinds are already fully checked in previous pass. 40.126 + } 40.127 + break; 40.128 + } 40.129 + case JVM_CONSTANT_MethodType: { 40.130 + symbolHandle no_name = vmSymbolHandles::type_name(); // place holder 40.131 + symbolHandle signature(THREAD, cp->method_type_signature_at(index)); 40.132 + verify_legal_method_signature(no_name, signature, CHECK_(nullHandle)); 40.133 + break; 40.134 + } 40.135 } // end of switch 40.136 } // end of for 40.137 40.138 @@ -467,7 +581,7 @@ 40.139 case JVM_CONSTANT_UnresolvedClass : 40.140 // Patching a class means pre-resolving it. 40.141 // The name in the constant pool is ignored. 40.142 - if (patch->klass() == SystemDictionary::Class_klass()) { // %%% java_lang_Class::is_instance 40.143 + if (java_lang_Class::is_instance(patch())) { 40.144 guarantee_property(!java_lang_Class::is_primitive(patch()), 40.145 "Illegal class patch at %d in class file %s", 40.146 index, CHECK);
41.1 --- a/src/share/vm/classfile/systemDictionary.cpp Thu Jun 24 15:38:42 2010 -0700 41.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Mon Jun 28 12:03:05 2010 -0400 41.3 @@ -2454,6 +2454,48 @@ 41.4 return Handle(THREAD, (oop) result.get_jobject()); 41.5 } 41.6 41.7 +// Ask Java code to find or construct a method handle constant. 41.8 +Handle SystemDictionary::link_method_handle_constant(KlassHandle caller, 41.9 + int ref_kind, //e.g., JVM_REF_invokeVirtual 41.10 + KlassHandle callee, 41.11 + symbolHandle name_sym, 41.12 + symbolHandle signature, 41.13 + TRAPS) { 41.14 + Handle empty; 41.15 + Handle name = java_lang_String::create_from_symbol(name_sym(), CHECK_(empty)); 41.16 + Handle type; 41.17 + if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') { 41.18 + bool ignore_is_on_bcp = false; 41.19 + type = find_method_handle_type(signature, caller, ignore_is_on_bcp, CHECK_(empty)); 41.20 + } else { 41.21 + SignatureStream ss(signature(), false); 41.22 + if (!ss.is_done()) { 41.23 + oop mirror = ss.as_java_mirror(caller->class_loader(), caller->protection_domain(), 41.24 + SignatureStream::NCDFError, CHECK_(empty)); 41.25 + type = Handle(THREAD, mirror); 41.26 + ss.next(); 41.27 + if (!ss.is_done()) type = Handle(); // error! 41.28 + } 41.29 + } 41.30 + if (type.is_null()) { 41.31 + THROW_MSG_(vmSymbols::java_lang_LinkageError(), "bad signature", empty); 41.32 + } 41.33 + 41.34 + // call sun.dyn.MethodHandleNatives::linkMethodHandleConstant(Class caller, int refKind, Class callee, String name, Object type) -> MethodHandle 41.35 + JavaCallArguments args; 41.36 + args.push_oop(caller->java_mirror()); // the referring class 41.37 + args.push_int(ref_kind); 41.38 + args.push_oop(callee->java_mirror()); // the target class 41.39 + args.push_oop(name()); 41.40 + args.push_oop(type()); 41.41 + JavaValue result(T_OBJECT); 41.42 + JavaCalls::call_static(&result, 41.43 + SystemDictionary::MethodHandleNatives_klass(), 41.44 + vmSymbols::linkMethodHandleConstant_name(), 41.45 + vmSymbols::linkMethodHandleConstant_signature(), 41.46 + &args, CHECK_(empty)); 41.47 + return Handle(THREAD, (oop) result.get_jobject()); 41.48 +} 41.49 41.50 // Ask Java code to find or construct a java.dyn.CallSite for the given 41.51 // name and signature, as interpreted relative to the given class loader.
42.1 --- a/src/share/vm/classfile/systemDictionary.hpp Thu Jun 24 15:38:42 2010 -0700 42.2 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Jun 28 12:03:05 2010 -0400 42.3 @@ -473,6 +473,13 @@ 42.4 KlassHandle accessing_klass, 42.5 bool& return_bcp_flag, 42.6 TRAPS); 42.7 + // ask Java to compute a java.dyn.MethodHandle object for a given CP entry 42.8 + static Handle link_method_handle_constant(KlassHandle caller, 42.9 + int ref_kind, //e.g., JVM_REF_invokeVirtual 42.10 + KlassHandle callee, 42.11 + symbolHandle name, 42.12 + symbolHandle signature, 42.13 + TRAPS); 42.14 // ask Java to create a dynamic call site, while linking an invokedynamic op 42.15 static Handle make_dynamic_call_site(Handle bootstrap_method, 42.16 // Callee information:
43.1 --- a/src/share/vm/classfile/verifier.cpp Thu Jun 24 15:38:42 2010 -0700 43.2 +++ b/src/share/vm/classfile/verifier.cpp Mon Jun 28 12:03:05 2010 -0400 43.3 @@ -1598,7 +1598,10 @@ 43.4 if (opcode == Bytecodes::_ldc || opcode == Bytecodes::_ldc_w) { 43.5 if (!tag.is_unresolved_string() && !tag.is_unresolved_klass()) { 43.6 types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float) 43.7 - | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class); 43.8 + | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class) 43.9 + | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType); 43.10 + // Note: The class file parser already verified the legality of 43.11 + // MethodHandle and MethodType constants. 43.12 verify_cp_type(index, cp, types, CHECK_VERIFY(this)); 43.13 } 43.14 } else { 43.15 @@ -1632,6 +1635,14 @@ 43.16 current_frame->push_stack_2( 43.17 VerificationType::long_type(), 43.18 VerificationType::long2_type(), CHECK_VERIFY(this)); 43.19 + } else if (tag.is_method_handle()) { 43.20 + current_frame->push_stack( 43.21 + VerificationType::reference_type( 43.22 + vmSymbols::java_dyn_MethodHandle()), CHECK_VERIFY(this)); 43.23 + } else if (tag.is_method_type()) { 43.24 + current_frame->push_stack( 43.25 + VerificationType::reference_type( 43.26 + vmSymbols::java_dyn_MethodType()), CHECK_VERIFY(this)); 43.27 } else { 43.28 verify_error(bci, "Invalid index in ldc"); 43.29 return; 43.30 @@ -1920,9 +1931,12 @@ 43.31 // Get referenced class type 43.32 VerificationType ref_class_type; 43.33 if (opcode == Bytecodes::_invokedynamic) { 43.34 - if (!EnableInvokeDynamic) { 43.35 + if (!EnableInvokeDynamic || 43.36 + _klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { 43.37 class_format_error( 43.38 - "invokedynamic instructions not enabled on this JVM", 43.39 + (!EnableInvokeDynamic ? 43.40 + "invokedynamic instructions not enabled in this JVM" : 43.41 + "invokedynamic instructions not supported by this class file version"), 43.42 _klass->external_name()); 43.43 return; 43.44 }
44.1 --- a/src/share/vm/classfile/verifier.hpp Thu Jun 24 15:38:42 2010 -0700 44.2 +++ b/src/share/vm/classfile/verifier.hpp Mon Jun 28 12:03:05 2010 -0400 44.3 @@ -25,7 +25,10 @@ 44.4 // The verifier class 44.5 class Verifier : AllStatic { 44.6 public: 44.7 - enum { STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50 }; 44.8 + enum { 44.9 + STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50, 44.10 + INVOKEDYNAMIC_MAJOR_VERSION = 51 44.11 + }; 44.12 typedef enum { ThrowException, NoException } Mode; 44.13 44.14 /**
45.1 --- a/src/share/vm/classfile/vmSymbols.hpp Thu Jun 24 15:38:42 2010 -0700 45.2 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Jun 28 12:03:05 2010 -0400 45.3 @@ -246,6 +246,8 @@ 45.4 /* internal up-calls made only by the JVM, via class sun.dyn.MethodHandleNatives: */ \ 45.5 template(findMethodHandleType_name, "findMethodHandleType") \ 45.6 template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/dyn/MethodType;") \ 45.7 + template(linkMethodHandleConstant_name, "linkMethodHandleConstant") \ 45.8 + template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/dyn/MethodHandle;") \ 45.9 template(makeDynamicCallSite_name, "makeDynamicCallSite") \ 45.10 template(makeDynamicCallSite_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") \ 45.11 NOT_LP64( do_alias(machine_word_signature, int_signature) ) \
46.1 --- a/src/share/vm/code/nmethod.cpp Thu Jun 24 15:38:42 2010 -0700 46.2 +++ b/src/share/vm/code/nmethod.cpp Mon Jun 28 12:03:05 2010 -0400 46.3 @@ -584,6 +584,7 @@ 46.4 _oops_do_mark_link = NULL; 46.5 _method = method; 46.6 _entry_bci = InvocationEntryBci; 46.7 + _jmethod_id = NULL; 46.8 _osr_link = NULL; 46.9 _scavenge_root_link = NULL; 46.10 _scavenge_root_state = 0; 46.11 @@ -677,6 +678,7 @@ 46.12 _oops_do_mark_link = NULL; 46.13 _method = method; 46.14 _entry_bci = InvocationEntryBci; 46.15 + _jmethod_id = NULL; 46.16 _osr_link = NULL; 46.17 _scavenge_root_link = NULL; 46.18 _scavenge_root_state = 0; 46.19 @@ -784,6 +786,7 @@ 46.20 NOT_PRODUCT(_has_debug_info = false); 46.21 _oops_do_mark_link = NULL; 46.22 _method = method; 46.23 + _jmethod_id = NULL; 46.24 _compile_id = compile_id; 46.25 _comp_level = comp_level; 46.26 _entry_bci = entry_bci; 46.27 @@ -1488,11 +1491,25 @@ 46.28 moop->signature()->utf8_length(), 46.29 code_begin(), code_size()); 46.30 46.31 + if (JvmtiExport::should_post_compiled_method_load() || 46.32 + JvmtiExport::should_post_compiled_method_unload()) { 46.33 + get_and_cache_jmethod_id(); 46.34 + } 46.35 + 46.36 if (JvmtiExport::should_post_compiled_method_load()) { 46.37 JvmtiExport::post_compiled_method_load(this); 46.38 } 46.39 } 46.40 46.41 +jmethodID nmethod::get_and_cache_jmethod_id() { 46.42 + if (_jmethod_id == NULL) { 46.43 + // Cache the jmethod_id since it can no longer be looked up once the 46.44 + // method itself has been marked for unloading. 46.45 + _jmethod_id = method()->jmethod_id(); 46.46 + } 46.47 + return _jmethod_id; 46.48 +} 46.49 + 46.50 void nmethod::post_compiled_method_unload() { 46.51 if (unload_reported()) { 46.52 // During unloading we transition to unloaded and then to zombie 46.53 @@ -1504,12 +1521,17 @@ 46.54 DTRACE_METHOD_UNLOAD_PROBE(method()); 46.55 46.56 // If a JVMTI agent has enabled the CompiledMethodUnload event then 46.57 - // post the event. Sometime later this nmethod will be made a zombie by 46.58 - // the sweeper but the methodOop will not be valid at that point. 46.59 - if (JvmtiExport::should_post_compiled_method_unload()) { 46.60 + // post the event. Sometime later this nmethod will be made a zombie 46.61 + // by the sweeper but the methodOop will not be valid at that point. 46.62 + // If the _jmethod_id is null then no load event was ever requested 46.63 + // so don't bother posting the unload. The main reason for this is 46.64 + // that the jmethodID is a weak reference to the methodOop so if 46.65 + // it's being unloaded there's no way to look it up since the weak 46.66 + // ref will have been cleared. 46.67 + if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) { 46.68 assert(!unload_reported(), "already unloaded"); 46.69 HandleMark hm; 46.70 - JvmtiExport::post_compiled_method_unload(method()->jmethod_id(), code_begin()); 46.71 + JvmtiExport::post_compiled_method_unload(_jmethod_id, code_begin()); 46.72 } 46.73 46.74 // The JVMTI CompiledMethodUnload event can be enabled or disabled at 46.75 @@ -2659,13 +2681,10 @@ 46.76 case Bytecodes::_getstatic: 46.77 case Bytecodes::_putstatic: 46.78 { 46.79 - methodHandle sdm = sd->method(); 46.80 - Bytecode_field* field = Bytecode_field_at(sdm(), sdm->bcp_from(sd->bci())); 46.81 - constantPoolOop sdmc = sdm->constants(); 46.82 - symbolOop name = sdmc->name_ref_at(field->index()); 46.83 + Bytecode_field* field = Bytecode_field_at(sd->method(), sd->bci()); 46.84 st->print(" "); 46.85 - if (name != NULL) 46.86 - name->print_symbol_on(st); 46.87 + if (field->name() != NULL) 46.88 + field->name()->print_symbol_on(st); 46.89 else 46.90 st->print("<UNKNOWN>"); 46.91 }
47.1 --- a/src/share/vm/code/nmethod.hpp Thu Jun 24 15:38:42 2010 -0700 47.2 +++ b/src/share/vm/code/nmethod.hpp Mon Jun 28 12:03:05 2010 -0400 47.3 @@ -135,6 +135,7 @@ 47.4 47.5 methodOop _method; 47.6 int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method 47.7 + jmethodID _jmethod_id; // Cache of method()->jmethod_id() 47.8 47.9 // To support simple linked-list chaining of nmethods: 47.10 nmethod* _osr_link; // from instanceKlass::osr_nmethods_head 47.11 @@ -599,6 +600,7 @@ 47.12 47.13 // jvmti support: 47.14 void post_compiled_method_load_event(); 47.15 + jmethodID get_and_cache_jmethod_id(); 47.16 47.17 // verify operations 47.18 void verify();
48.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Jun 24 15:38:42 2010 -0700 48.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Jun 28 12:03:05 2010 -0400 48.3 @@ -3972,6 +3972,10 @@ 48.4 48.5 void work(int i) { 48.6 if (i >= _n_workers) return; // no work needed this round 48.7 + 48.8 + double start_time_ms = os::elapsedTime() * 1000.0; 48.9 + _g1h->g1_policy()->record_gc_worker_start_time(i, start_time_ms); 48.10 + 48.11 ResourceMark rm; 48.12 HandleMark hm; 48.13 48.14 @@ -4019,7 +4023,7 @@ 48.15 double elapsed_ms = (os::elapsedTime()-start)*1000.0; 48.16 double term_ms = pss.term_time()*1000.0; 48.17 _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms); 48.18 - _g1h->g1_policy()->record_termination_time(i, term_ms); 48.19 + _g1h->g1_policy()->record_termination(i, term_ms, pss.term_attempts()); 48.20 } 48.21 _g1h->g1_policy()->record_thread_age_table(pss.age_table()); 48.22 _g1h->update_surviving_young_words(pss.surviving_young_words()+1); 48.23 @@ -4043,7 +4047,8 @@ 48.24 double term = pss.term_time(); 48.25 gclog_or_tty->print(" Elapsed: %7.2f ms.\n" 48.26 " Strong roots: %7.2f ms (%6.2f%%)\n" 48.27 - " Termination: %7.2f ms (%6.2f%%) (in %d entries)\n", 48.28 + " Termination: %7.2f ms (%6.2f%%) " 48.29 + "(in "SIZE_FORMAT" entries)\n", 48.30 elapsed * 1000.0, 48.31 strong_roots * 1000.0, (strong_roots*100.0/elapsed), 48.32 term * 1000.0, (term*100.0/elapsed), 48.33 @@ -4059,6 +4064,8 @@ 48.34 48.35 assert(pss.refs_to_scan() == 0, "Task queue should be empty"); 48.36 assert(pss.overflowed_refs_to_scan() == 0, "Overflow queue should be empty"); 48.37 + double end_time_ms = os::elapsedTime() * 1000.0; 48.38 + _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms); 48.39 } 48.40 }; 48.41
49.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Jun 24 15:38:42 2010 -0700 49.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Jun 28 12:03:05 2010 -0400 49.3 @@ -1549,7 +1549,7 @@ 49.4 int _hash_seed; 49.5 int _queue_num; 49.6 49.7 - int _term_attempts; 49.8 + size_t _term_attempts; 49.9 #if G1_DETAILED_STATS 49.10 int _pushes, _pops, _steals, _steal_attempts; 49.11 int _overflow_pushes; 49.12 @@ -1727,8 +1727,8 @@ 49.13 int* hash_seed() { return &_hash_seed; } 49.14 int queue_num() { return _queue_num; } 49.15 49.16 - int term_attempts() { return _term_attempts; } 49.17 - void note_term_attempt() { _term_attempts++; } 49.18 + size_t term_attempts() { return _term_attempts; } 49.19 + void note_term_attempt() { _term_attempts++; } 49.20 49.21 #if G1_DETAILED_STATS 49.22 int pushes() { return _pushes; }
50.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Jun 24 15:38:42 2010 -0700 50.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Mon Jun 28 12:03:05 2010 -0400 50.3 @@ -231,20 +231,21 @@ 50.4 _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime()); 50.5 _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0; 50.6 50.7 + _par_last_gc_worker_start_times_ms = new double[_parallel_gc_threads]; 50.8 _par_last_ext_root_scan_times_ms = new double[_parallel_gc_threads]; 50.9 _par_last_mark_stack_scan_times_ms = new double[_parallel_gc_threads]; 50.10 50.11 - _par_last_update_rs_start_times_ms = new double[_parallel_gc_threads]; 50.12 _par_last_update_rs_times_ms = new double[_parallel_gc_threads]; 50.13 _par_last_update_rs_processed_buffers = new double[_parallel_gc_threads]; 50.14 50.15 - _par_last_scan_rs_start_times_ms = new double[_parallel_gc_threads]; 50.16 _par_last_scan_rs_times_ms = new double[_parallel_gc_threads]; 50.17 _par_last_scan_new_refs_times_ms = new double[_parallel_gc_threads]; 50.18 50.19 _par_last_obj_copy_times_ms = new double[_parallel_gc_threads]; 50.20 50.21 _par_last_termination_times_ms = new double[_parallel_gc_threads]; 50.22 + _par_last_termination_attempts = new double[_parallel_gc_threads]; 50.23 + _par_last_gc_worker_end_times_ms = new double[_parallel_gc_threads]; 50.24 50.25 // start conservatively 50.26 _expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis; 50.27 @@ -274,10 +275,64 @@ 50.28 50.29 // </NEW PREDICTION> 50.30 50.31 + // Below, we might need to calculate the pause time target based on 50.32 + // the pause interval. When we do so we are going to give G1 maximum 50.33 + // flexibility and allow it to do pauses when it needs to. So, we'll 50.34 + // arrange that the pause interval to be pause time target + 1 to 50.35 + // ensure that a) the pause time target is maximized with respect to 50.36 + // the pause interval and b) we maintain the invariant that pause 50.37 + // time target < pause interval. If the user does not want this 50.38 + // maximum flexibility, they will have to set the pause interval 50.39 + // explicitly. 50.40 + 50.41 + // First make sure that, if either parameter is set, its value is 50.42 + // reasonable. 50.43 + if (!FLAG_IS_DEFAULT(MaxGCPauseMillis)) { 50.44 + if (MaxGCPauseMillis < 1) { 50.45 + vm_exit_during_initialization("MaxGCPauseMillis should be " 50.46 + "greater than 0"); 50.47 + } 50.48 + } 50.49 + if (!FLAG_IS_DEFAULT(GCPauseIntervalMillis)) { 50.50 + if (GCPauseIntervalMillis < 1) { 50.51 + vm_exit_during_initialization("GCPauseIntervalMillis should be " 50.52 + "greater than 0"); 50.53 + } 50.54 + } 50.55 + 50.56 + // Then, if the pause time target parameter was not set, set it to 50.57 + // the default value. 50.58 + if (FLAG_IS_DEFAULT(MaxGCPauseMillis)) { 50.59 + if (FLAG_IS_DEFAULT(GCPauseIntervalMillis)) { 50.60 + // The default pause time target in G1 is 200ms 50.61 + FLAG_SET_DEFAULT(MaxGCPauseMillis, 200); 50.62 + } else { 50.63 + // We do not allow the pause interval to be set without the 50.64 + // pause time target 50.65 + vm_exit_during_initialization("GCPauseIntervalMillis cannot be set " 50.66 + "without setting MaxGCPauseMillis"); 50.67 + } 50.68 + } 50.69 + 50.70 + // Then, if the interval parameter was not set, set it according to 50.71 + // the pause time target (this will also deal with the case when the 50.72 + // pause time target is the default value). 50.73 + if (FLAG_IS_DEFAULT(GCPauseIntervalMillis)) { 50.74 + FLAG_SET_DEFAULT(GCPauseIntervalMillis, MaxGCPauseMillis + 1); 50.75 + } 50.76 + 50.77 + // Finally, make sure that the two parameters are consistent. 50.78 + if (MaxGCPauseMillis >= GCPauseIntervalMillis) { 50.79 + char buffer[256]; 50.80 + jio_snprintf(buffer, 256, 50.81 + "MaxGCPauseMillis (%u) should be less than " 50.82 + "GCPauseIntervalMillis (%u)", 50.83 + MaxGCPauseMillis, GCPauseIntervalMillis); 50.84 + vm_exit_during_initialization(buffer); 50.85 + } 50.86 + 50.87 + double max_gc_time = (double) MaxGCPauseMillis / 1000.0; 50.88 double time_slice = (double) GCPauseIntervalMillis / 1000.0; 50.89 - double max_gc_time = (double) MaxGCPauseMillis / 1000.0; 50.90 - guarantee(max_gc_time < time_slice, 50.91 - "Max GC time should not be greater than the time slice"); 50.92 _mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time); 50.93 _sigma = (double) G1ConfidencePercent / 100.0; 50.94 50.95 @@ -782,16 +837,17 @@ 50.96 // if they are not set properly 50.97 50.98 for (int i = 0; i < _parallel_gc_threads; ++i) { 50.99 - _par_last_ext_root_scan_times_ms[i] = -666.0; 50.100 - _par_last_mark_stack_scan_times_ms[i] = -666.0; 50.101 - _par_last_update_rs_start_times_ms[i] = -666.0; 50.102 - _par_last_update_rs_times_ms[i] = -666.0; 50.103 - _par_last_update_rs_processed_buffers[i] = -666.0; 50.104 - _par_last_scan_rs_start_times_ms[i] = -666.0; 50.105 - _par_last_scan_rs_times_ms[i] = -666.0; 50.106 - _par_last_scan_new_refs_times_ms[i] = -666.0; 50.107 - _par_last_obj_copy_times_ms[i] = -666.0; 50.108 - _par_last_termination_times_ms[i] = -666.0; 50.109 + _par_last_gc_worker_start_times_ms[i] = -1234.0; 50.110 + _par_last_ext_root_scan_times_ms[i] = -1234.0; 50.111 + _par_last_mark_stack_scan_times_ms[i] = -1234.0; 50.112 + _par_last_update_rs_times_ms[i] = -1234.0; 50.113 + _par_last_update_rs_processed_buffers[i] = -1234.0; 50.114 + _par_last_scan_rs_times_ms[i] = -1234.0; 50.115 + _par_last_scan_new_refs_times_ms[i] = -1234.0; 50.116 + _par_last_obj_copy_times_ms[i] = -1234.0; 50.117 + _par_last_termination_times_ms[i] = -1234.0; 50.118 + _par_last_termination_attempts[i] = -1234.0; 50.119 + _par_last_gc_worker_end_times_ms[i] = -1234.0; 50.120 } 50.121 #endif 50.122 50.123 @@ -942,9 +998,9 @@ 50.124 return sum; 50.125 } 50.126 50.127 -void G1CollectorPolicy::print_par_stats (int level, 50.128 - const char* str, 50.129 - double* data, 50.130 +void G1CollectorPolicy::print_par_stats(int level, 50.131 + const char* str, 50.132 + double* data, 50.133 bool summary) { 50.134 double min = data[0], max = data[0]; 50.135 double total = 0.0; 50.136 @@ -973,10 +1029,10 @@ 50.137 gclog_or_tty->print_cr("]"); 50.138 } 50.139 50.140 -void G1CollectorPolicy::print_par_buffers (int level, 50.141 - const char* str, 50.142 - double* data, 50.143 - bool summary) { 50.144 +void G1CollectorPolicy::print_par_sizes(int level, 50.145 + const char* str, 50.146 + double* data, 50.147 + bool summary) { 50.148 double min = data[0], max = data[0]; 50.149 double total = 0.0; 50.150 int j; 50.151 @@ -1321,15 +1377,22 @@ 50.152 } 50.153 if (parallel) { 50.154 print_stats(1, "Parallel Time", _cur_collection_par_time_ms); 50.155 - print_par_stats(2, "Update RS (Start)", _par_last_update_rs_start_times_ms, false); 50.156 + print_par_stats(2, "GC Worker Start Time", 50.157 + _par_last_gc_worker_start_times_ms, false); 50.158 print_par_stats(2, "Update RS", _par_last_update_rs_times_ms); 50.159 - print_par_buffers(3, "Processed Buffers", 50.160 - _par_last_update_rs_processed_buffers, true); 50.161 - print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms); 50.162 - print_par_stats(2, "Mark Stack Scanning", _par_last_mark_stack_scan_times_ms); 50.163 + print_par_sizes(3, "Processed Buffers", 50.164 + _par_last_update_rs_processed_buffers, true); 50.165 + print_par_stats(2, "Ext Root Scanning", 50.166 + _par_last_ext_root_scan_times_ms); 50.167 + print_par_stats(2, "Mark Stack Scanning", 50.168 + _par_last_mark_stack_scan_times_ms); 50.169 print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms); 50.170 print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms); 50.171 print_par_stats(2, "Termination", _par_last_termination_times_ms); 50.172 + print_par_sizes(3, "Termination Attempts", 50.173 + _par_last_termination_attempts, true); 50.174 + print_par_stats(2, "GC Worker End Time", 50.175 + _par_last_gc_worker_end_times_ms, false); 50.176 print_stats(2, "Other", parallel_other_time); 50.177 print_stats(1, "Clear CT", _cur_clear_ct_time_ms); 50.178 } else {
51.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu Jun 24 15:38:42 2010 -0700 51.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Mon Jun 28 12:03:05 2010 -0400 51.3 @@ -171,16 +171,17 @@ 51.4 double* _cur_aux_times_ms; 51.5 bool* _cur_aux_times_set; 51.6 51.7 + double* _par_last_gc_worker_start_times_ms; 51.8 double* _par_last_ext_root_scan_times_ms; 51.9 double* _par_last_mark_stack_scan_times_ms; 51.10 - double* _par_last_update_rs_start_times_ms; 51.11 double* _par_last_update_rs_times_ms; 51.12 double* _par_last_update_rs_processed_buffers; 51.13 - double* _par_last_scan_rs_start_times_ms; 51.14 double* _par_last_scan_rs_times_ms; 51.15 double* _par_last_scan_new_refs_times_ms; 51.16 double* _par_last_obj_copy_times_ms; 51.17 double* _par_last_termination_times_ms; 51.18 + double* _par_last_termination_attempts; 51.19 + double* _par_last_gc_worker_end_times_ms; 51.20 51.21 // indicates that we are in young GC mode 51.22 bool _in_young_gc_mode; 51.23 @@ -559,13 +560,14 @@ 51.24 } 51.25 51.26 protected: 51.27 - void print_stats (int level, const char* str, double value); 51.28 - void print_stats (int level, const char* str, int value); 51.29 - void print_par_stats (int level, const char* str, double* data) { 51.30 + void print_stats(int level, const char* str, double value); 51.31 + void print_stats(int level, const char* str, int value); 51.32 + 51.33 + void print_par_stats(int level, const char* str, double* data) { 51.34 print_par_stats(level, str, data, true); 51.35 } 51.36 - void print_par_stats (int level, const char* str, double* data, bool summary); 51.37 - void print_par_buffers (int level, const char* str, double* data, bool summary); 51.38 + void print_par_stats(int level, const char* str, double* data, bool summary); 51.39 + void print_par_sizes(int level, const char* str, double* data, bool summary); 51.40 51.41 void check_other_times(int level, 51.42 NumberSeq* other_times_ms, 51.43 @@ -891,6 +893,10 @@ 51.44 virtual void record_full_collection_start(); 51.45 virtual void record_full_collection_end(); 51.46 51.47 + void record_gc_worker_start_time(int worker_i, double ms) { 51.48 + _par_last_gc_worker_start_times_ms[worker_i] = ms; 51.49 + } 51.50 + 51.51 void record_ext_root_scan_time(int worker_i, double ms) { 51.52 _par_last_ext_root_scan_times_ms[worker_i] = ms; 51.53 } 51.54 @@ -912,10 +918,6 @@ 51.55 _all_mod_union_times_ms->add(ms); 51.56 } 51.57 51.58 - void record_update_rs_start_time(int thread, double ms) { 51.59 - _par_last_update_rs_start_times_ms[thread] = ms; 51.60 - } 51.61 - 51.62 void record_update_rs_time(int thread, double ms) { 51.63 _par_last_update_rs_times_ms[thread] = ms; 51.64 } 51.65 @@ -925,10 +927,6 @@ 51.66 _par_last_update_rs_processed_buffers[thread] = processed_buffers; 51.67 } 51.68 51.69 - void record_scan_rs_start_time(int thread, double ms) { 51.70 - _par_last_scan_rs_start_times_ms[thread] = ms; 51.71 - } 51.72 - 51.73 void record_scan_rs_time(int thread, double ms) { 51.74 _par_last_scan_rs_times_ms[thread] = ms; 51.75 } 51.76 @@ -953,16 +951,13 @@ 51.77 _par_last_obj_copy_times_ms[thread] += ms; 51.78 } 51.79 51.80 - void record_obj_copy_time(double ms) { 51.81 - record_obj_copy_time(0, ms); 51.82 + void record_termination(int thread, double ms, size_t attempts) { 51.83 + _par_last_termination_times_ms[thread] = ms; 51.84 + _par_last_termination_attempts[thread] = (double) attempts; 51.85 } 51.86 51.87 - void record_termination_time(int thread, double ms) { 51.88 - _par_last_termination_times_ms[thread] = ms; 51.89 - } 51.90 - 51.91 - void record_termination_time(double ms) { 51.92 - record_termination_time(0, ms); 51.93 + void record_gc_worker_end_time(int worker_i, double ms) { 51.94 + _par_last_gc_worker_end_times_ms[worker_i] = ms; 51.95 } 51.96 51.97 void record_pause_time_ms(double ms) {
52.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Jun 24 15:38:42 2010 -0700 52.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp Mon Jun 28 12:03:05 2010 -0400 52.3 @@ -303,7 +303,6 @@ 52.4 assert( _cards_scanned != NULL, "invariant" ); 52.5 _cards_scanned[worker_i] = scanRScl.cards_done(); 52.6 52.7 - _g1p->record_scan_rs_start_time(worker_i, rs_time_start * 1000.0); 52.8 _g1p->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0); 52.9 } 52.10 52.11 @@ -311,8 +310,6 @@ 52.12 ConcurrentG1Refine* cg1r = _g1->concurrent_g1_refine(); 52.13 52.14 double start = os::elapsedTime(); 52.15 - _g1p->record_update_rs_start_time(worker_i, start * 1000.0); 52.16 - 52.17 // Apply the appropriate closure to all remaining log entries. 52.18 _g1->iterate_dirty_card_closure(false, worker_i); 52.19 // Now there should be no dirty cards. 52.20 @@ -471,7 +468,6 @@ 52.21 updateRS(worker_i); 52.22 scanNewRefsRS(oc, worker_i); 52.23 } else { 52.24 - _g1p->record_update_rs_start_time(worker_i, os::elapsedTime() * 1000.0); 52.25 _g1p->record_update_rs_processed_buffers(worker_i, 0.0); 52.26 _g1p->record_update_rs_time(worker_i, 0.0); 52.27 _g1p->record_scan_new_refs_time(worker_i, 0.0); 52.28 @@ -479,7 +475,6 @@ 52.29 if (G1UseParallelRSetScanning || (worker_i == 0)) { 52.30 scanRS(oc, worker_i); 52.31 } else { 52.32 - _g1p->record_scan_rs_start_time(worker_i, os::elapsedTime() * 1000.0); 52.33 _g1p->record_scan_rs_time(worker_i, 0.0); 52.34 } 52.35 } else {
53.1 --- a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp Thu Jun 24 15:38:42 2010 -0700 53.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp Mon Jun 28 12:03:05 2010 -0400 53.3 @@ -1,5 +1,5 @@ 53.4 /* 53.5 - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. 53.6 + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 53.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 53.8 * 53.9 * This code is free software; you can redistribute it and/or modify it 53.10 @@ -566,14 +566,14 @@ 53.11 #endif 53.12 53.13 // Commit new or uncommit old pages, if necessary. 53.14 - resize_commit_uncommit(changed_region, new_region); 53.15 + if (resize_commit_uncommit(changed_region, new_region)) { 53.16 + // Set the new start of the committed region 53.17 + resize_update_committed_table(changed_region, new_region); 53.18 + } 53.19 53.20 // Update card table entries 53.21 resize_update_card_table_entries(changed_region, new_region); 53.22 53.23 - // Set the new start of the committed region 53.24 - resize_update_committed_table(changed_region, new_region); 53.25 - 53.26 // Update the covered region 53.27 resize_update_covered_table(changed_region, new_region); 53.28 53.29 @@ -604,8 +604,9 @@ 53.30 debug_only(verify_guard();) 53.31 } 53.32 53.33 -void CardTableExtension::resize_commit_uncommit(int changed_region, 53.34 +bool CardTableExtension::resize_commit_uncommit(int changed_region, 53.35 MemRegion new_region) { 53.36 + bool result = false; 53.37 // Commit new or uncommit old pages, if necessary. 53.38 MemRegion cur_committed = _committed[changed_region]; 53.39 assert(_covered[changed_region].end() == new_region.end(), 53.40 @@ -675,20 +676,31 @@ 53.41 "card table expansion"); 53.42 } 53.43 } 53.44 + result = true; 53.45 } else if (new_start_aligned > cur_committed.start()) { 53.46 // Shrink the committed region 53.47 +#if 0 // uncommitting space is currently unsafe because of the interactions 53.48 + // of growing and shrinking regions. One region A can uncommit space 53.49 + // that it owns but which is being used by another region B (maybe). 53.50 + // Region B has not committed the space because it was already 53.51 + // committed by region A. 53.52 MemRegion uncommit_region = committed_unique_to_self(changed_region, 53.53 MemRegion(cur_committed.start(), new_start_aligned)); 53.54 if (!uncommit_region.is_empty()) { 53.55 if (!os::uncommit_memory((char*)uncommit_region.start(), 53.56 uncommit_region.byte_size())) { 53.57 - vm_exit_out_of_memory(uncommit_region.byte_size(), 53.58 - "card table contraction"); 53.59 + // If the uncommit fails, ignore it. Let the 53.60 + // committed table resizing go even though the committed 53.61 + // table will over state the committed space. 53.62 } 53.63 } 53.64 +#else 53.65 + assert(!result, "Should be false with current workaround"); 53.66 +#endif 53.67 } 53.68 assert(_committed[changed_region].end() == cur_committed.end(), 53.69 "end should not change"); 53.70 + return result; 53.71 } 53.72 53.73 void CardTableExtension::resize_update_committed_table(int changed_region,
54.1 --- a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Thu Jun 24 15:38:42 2010 -0700 54.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Mon Jun 28 12:03:05 2010 -0400 54.3 @@ -1,5 +1,5 @@ 54.4 /* 54.5 - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. 54.6 + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 54.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 54.8 * 54.9 * This code is free software; you can redistribute it and/or modify it 54.10 @@ -30,7 +30,9 @@ 54.11 class CardTableExtension : public CardTableModRefBS { 54.12 private: 54.13 // Support methods for resizing the card table. 54.14 - void resize_commit_uncommit(int changed_region, MemRegion new_region); 54.15 + // resize_commit_uncommit() returns true if the pages were committed or 54.16 + // uncommitted 54.17 + bool resize_commit_uncommit(int changed_region, MemRegion new_region); 54.18 void resize_update_card_table_entries(int changed_region, 54.19 MemRegion new_region); 54.20 void resize_update_committed_table(int changed_region, MemRegion new_region);
55.1 --- a/src/share/vm/includeDB_core Thu Jun 24 15:38:42 2010 -0700 55.2 +++ b/src/share/vm/includeDB_core Mon Jun 28 12:03:05 2010 -0400 55.3 @@ -545,6 +545,7 @@ 55.4 55.5 ciCPCache.hpp ciClassList.hpp 55.6 ciCPCache.hpp ciObject.hpp 55.7 +ciCPCache.hpp cpCacheOop.hpp 55.8 55.9 ciEnv.cpp allocation.inline.hpp 55.10 ciEnv.cpp ciConstant.hpp 55.11 @@ -823,6 +824,7 @@ 55.12 55.13 ciStreams.cpp ciCallSite.hpp 55.14 ciStreams.cpp ciConstant.hpp 55.15 +ciStreams.cpp ciCPCache.hpp 55.16 ciStreams.cpp ciField.hpp 55.17 ciStreams.cpp ciStreams.hpp 55.18 ciStreams.cpp ciUtilities.hpp
56.1 --- a/src/share/vm/interpreter/bytecode.cpp Thu Jun 24 15:38:42 2010 -0700 56.2 +++ b/src/share/vm/interpreter/bytecode.cpp Mon Jun 28 12:03:05 2010 -0400 56.3 @@ -136,25 +136,24 @@ 56.4 // Implementation of Bytecode_invoke 56.5 56.6 void Bytecode_invoke::verify() const { 56.7 - Bytecodes::Code bc = adjusted_invoke_code(); 56.8 assert(is_valid(), "check invoke"); 56.9 assert(method()->constants()->cache() != NULL, "do not call this from verifier or rewriter"); 56.10 } 56.11 56.12 56.13 -symbolOop Bytecode_invoke::signature() const { 56.14 +symbolOop Bytecode_member_ref::signature() const { 56.15 constantPoolOop constants = method()->constants(); 56.16 return constants->signature_ref_at(index()); 56.17 } 56.18 56.19 56.20 -symbolOop Bytecode_invoke::name() const { 56.21 +symbolOop Bytecode_member_ref::name() const { 56.22 constantPoolOop constants = method()->constants(); 56.23 return constants->name_ref_at(index()); 56.24 } 56.25 56.26 56.27 -BasicType Bytecode_invoke::result_type(Thread *thread) const { 56.28 +BasicType Bytecode_member_ref::result_type(Thread *thread) const { 56.29 symbolHandle sh(thread, signature()); 56.30 ResultTypeFinder rts(sh); 56.31 rts.iterate(); 56.32 @@ -167,9 +166,9 @@ 56.33 KlassHandle resolved_klass; 56.34 constantPoolHandle constants(THREAD, _method->constants()); 56.35 56.36 - if (adjusted_invoke_code() == Bytecodes::_invokedynamic) { 56.37 + if (java_code() == Bytecodes::_invokedynamic) { 56.38 LinkResolver::resolve_dynamic_method(m, resolved_klass, constants, index(), CHECK_(methodHandle())); 56.39 - } else if (adjusted_invoke_code() != Bytecodes::_invokeinterface) { 56.40 + } else if (java_code() != Bytecodes::_invokeinterface) { 56.41 LinkResolver::resolve_method(m, resolved_klass, constants, index(), CHECK_(methodHandle())); 56.42 } else { 56.43 LinkResolver::resolve_interface_method(m, resolved_klass, constants, index(), CHECK_(methodHandle())); 56.44 @@ -178,51 +177,68 @@ 56.45 } 56.46 56.47 56.48 -int Bytecode_invoke::index() const { 56.49 +int Bytecode_member_ref::index() const { 56.50 // Note: Rewriter::rewrite changes the Java_u2 of an invokedynamic to a native_u4, 56.51 // at the same time it allocates per-call-site CP cache entries. 56.52 - Bytecodes::Code stdc = Bytecodes::java_code(code()); 56.53 - Bytecode* invoke = Bytecode_at(bcp()); 56.54 - if (invoke->has_index_u4(stdc)) 56.55 - return invoke->get_index_u4(stdc); 56.56 + Bytecodes::Code rawc = code(); 56.57 + Bytecode* invoke = bytecode(); 56.58 + if (invoke->has_index_u4(rawc)) 56.59 + return invoke->get_index_u4(rawc); 56.60 else 56.61 - return invoke->get_index_u2_cpcache(stdc); 56.62 + return invoke->get_index_u2_cpcache(rawc); 56.63 } 56.64 56.65 +int Bytecode_member_ref::pool_index() const { 56.66 + int index = this->index(); 56.67 + DEBUG_ONLY({ 56.68 + if (!bytecode()->has_index_u4(code())) 56.69 + index -= constantPoolOopDesc::CPCACHE_INDEX_TAG; 56.70 + }); 56.71 + return _method->constants()->cache()->entry_at(index)->constant_pool_index(); 56.72 +} 56.73 56.74 // Implementation of Bytecode_field 56.75 56.76 void Bytecode_field::verify() const { 56.77 - Bytecodes::Code stdc = Bytecodes::java_code(code()); 56.78 - assert(stdc == Bytecodes::_putstatic || stdc == Bytecodes::_getstatic || 56.79 - stdc == Bytecodes::_putfield || stdc == Bytecodes::_getfield, "check field"); 56.80 + assert(is_valid(), "check field"); 56.81 } 56.82 56.83 56.84 -bool Bytecode_field::is_static() const { 56.85 - Bytecodes::Code stdc = Bytecodes::java_code(code()); 56.86 - return stdc == Bytecodes::_putstatic || stdc == Bytecodes::_getstatic; 56.87 +// Implementation of Bytecode_loadconstant 56.88 + 56.89 +int Bytecode_loadconstant::raw_index() const { 56.90 + Bytecode* bcp = bytecode(); 56.91 + Bytecodes::Code rawc = bcp->code(); 56.92 + assert(rawc != Bytecodes::_wide, "verifier prevents this"); 56.93 + if (Bytecodes::java_code(rawc) == Bytecodes::_ldc) 56.94 + return bcp->get_index_u1(rawc); 56.95 + else 56.96 + return bcp->get_index_u2(rawc, false); 56.97 } 56.98 56.99 - 56.100 -int Bytecode_field::index() const { 56.101 - Bytecode* invoke = Bytecode_at(bcp()); 56.102 - return invoke->get_index_u2_cpcache(Bytecodes::_getfield); 56.103 +int Bytecode_loadconstant::pool_index() const { 56.104 + int index = raw_index(); 56.105 + if (has_cache_index()) { 56.106 + return _method->constants()->cache()->entry_at(index)->constant_pool_index(); 56.107 + } 56.108 + return index; 56.109 } 56.110 56.111 +BasicType Bytecode_loadconstant::result_type() const { 56.112 + int index = pool_index(); 56.113 + constantTag tag = _method->constants()->tag_at(index); 56.114 + return tag.basic_type(); 56.115 +} 56.116 56.117 -// Implementation of Bytecodes loac constant 56.118 - 56.119 -int Bytecode_loadconstant::index() const { 56.120 - Bytecodes::Code stdc = Bytecodes::java_code(code()); 56.121 - if (stdc != Bytecodes::_wide) { 56.122 - if (Bytecodes::java_code(stdc) == Bytecodes::_ldc) 56.123 - return get_index_u1(stdc); 56.124 - else 56.125 - return get_index_u2(stdc, false); 56.126 +oop Bytecode_loadconstant::resolve_constant(TRAPS) const { 56.127 + assert(_method.not_null(), "must supply method to resolve constant"); 56.128 + int index = raw_index(); 56.129 + constantPoolOop constants = _method->constants(); 56.130 + if (has_cache_index()) { 56.131 + return constants->resolve_cached_constant_at(index, THREAD); 56.132 + } else { 56.133 + return constants->resolve_constant_at(index, THREAD); 56.134 } 56.135 - stdc = Bytecodes::code_at(addr_at(1)); 56.136 - return get_index_u2(stdc, true); 56.137 } 56.138 56.139 //------------------------------------------------------------------------------
57.1 --- a/src/share/vm/interpreter/bytecode.hpp Thu Jun 24 15:38:42 2010 -0700 57.2 +++ b/src/share/vm/interpreter/bytecode.hpp Mon Jun 28 12:03:05 2010 -0400 57.3 @@ -76,9 +76,13 @@ 57.4 return Bytes::get_native_u2(p); 57.5 else return Bytes::get_Java_u2(p); 57.6 } 57.7 + int get_index_u1_cpcache(Bytecodes::Code bc) const { 57.8 + assert_same_format_as(bc); assert_index_size(1, bc); 57.9 + return *(jubyte*)addr_at(1) + constantPoolOopDesc::CPCACHE_INDEX_TAG; 57.10 + } 57.11 int get_index_u2_cpcache(Bytecodes::Code bc) const { 57.12 assert_same_format_as(bc); assert_index_size(2, bc); assert_native_index(bc); 57.13 - return Bytes::get_native_u2(addr_at(1)) DEBUG_ONLY(+ constantPoolOopDesc::CPCACHE_INDEX_TAG); 57.14 + return Bytes::get_native_u2(addr_at(1)) + constantPoolOopDesc::CPCACHE_INDEX_TAG; 57.15 } 57.16 int get_index_u4(Bytecodes::Code bc) const { 57.17 assert_same_format_as(bc); assert_index_size(4, bc); 57.18 @@ -152,7 +156,7 @@ 57.19 57.20 inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) { 57.21 Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp; 57.22 - debug_only(b->verify()); 57.23 + DEBUG_ONLY(b->verify()); 57.24 return b; 57.25 } 57.26 57.27 @@ -174,44 +178,56 @@ 57.28 57.29 inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) { 57.30 Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp; 57.31 - debug_only(b->verify()); 57.32 + DEBUG_ONLY(b->verify()); 57.33 return b; 57.34 } 57.35 57.36 57.37 -// Abstraction for invoke_{virtual, static, interface, special} 57.38 +// Common code for decoding invokes and field references. 57.39 57.40 -class Bytecode_invoke: public ResourceObj { 57.41 +class Bytecode_member_ref: public ResourceObj { 57.42 protected: 57.43 methodHandle _method; // method containing the bytecode 57.44 int _bci; // position of the bytecode 57.45 57.46 - Bytecode_invoke(methodHandle method, int bci) : _method(method), _bci(bci) {} 57.47 + Bytecode_member_ref(methodHandle method, int bci) : _method(method), _bci(bci) {} 57.48 + 57.49 + public: 57.50 + // Attributes 57.51 + methodHandle method() const { return _method; } 57.52 + int bci() const { return _bci; } 57.53 + address bcp() const { return _method->bcp_from(bci()); } 57.54 + Bytecode* bytecode() const { return Bytecode_at(bcp()); } 57.55 + 57.56 + int index() const; // cache index (loaded from instruction) 57.57 + int pool_index() const; // constant pool index 57.58 + symbolOop name() const; // returns the name of the method or field 57.59 + symbolOop signature() const; // returns the signature of the method or field 57.60 + 57.61 + BasicType result_type(Thread* thread) const; // returns the result type of the getfield or invoke 57.62 + 57.63 + Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); } 57.64 + Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } 57.65 +}; 57.66 + 57.67 +// Abstraction for invoke_{virtual, static, interface, special} 57.68 + 57.69 +class Bytecode_invoke: public Bytecode_member_ref { 57.70 + protected: 57.71 + Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {} 57.72 57.73 public: 57.74 void verify() const; 57.75 57.76 // Attributes 57.77 - methodHandle method() const { return _method; } 57.78 - int bci() const { return _bci; } 57.79 - address bcp() const { return _method->bcp_from(bci()); } 57.80 - 57.81 - int index() const; // the constant pool index for the invoke 57.82 - symbolOop name() const; // returns the name of the invoked method 57.83 - symbolOop signature() const; // returns the signature of the invoked method 57.84 - BasicType result_type(Thread *thread) const; // returns the result type of the invoke 57.85 - 57.86 - Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); } 57.87 - Bytecodes::Code adjusted_invoke_code() const { return Bytecodes::java_code(code()); } 57.88 - 57.89 methodHandle static_target(TRAPS); // "specified" method (from constant pool) 57.90 57.91 // Testers 57.92 - bool is_invokeinterface() const { return adjusted_invoke_code() == Bytecodes::_invokeinterface; } 57.93 - bool is_invokevirtual() const { return adjusted_invoke_code() == Bytecodes::_invokevirtual; } 57.94 - bool is_invokestatic() const { return adjusted_invoke_code() == Bytecodes::_invokestatic; } 57.95 - bool is_invokespecial() const { return adjusted_invoke_code() == Bytecodes::_invokespecial; } 57.96 - bool is_invokedynamic() const { return adjusted_invoke_code() == Bytecodes::_invokedynamic; } 57.97 + bool is_invokeinterface() const { return java_code() == Bytecodes::_invokeinterface; } 57.98 + bool is_invokevirtual() const { return java_code() == Bytecodes::_invokevirtual; } 57.99 + bool is_invokestatic() const { return java_code() == Bytecodes::_invokestatic; } 57.100 + bool is_invokespecial() const { return java_code() == Bytecodes::_invokespecial; } 57.101 + bool is_invokedynamic() const { return java_code() == Bytecodes::_invokedynamic; } 57.102 57.103 bool has_receiver() const { return !is_invokestatic() && !is_invokedynamic(); } 57.104 57.105 @@ -230,7 +246,7 @@ 57.106 57.107 inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) { 57.108 Bytecode_invoke* b = new Bytecode_invoke(method, bci); 57.109 - debug_only(b->verify()); 57.110 + DEBUG_ONLY(b->verify()); 57.111 return b; 57.112 } 57.113 57.114 @@ -240,21 +256,34 @@ 57.115 } 57.116 57.117 57.118 -// Abstraction for all field accesses (put/get field/static_ 57.119 -class Bytecode_field: public Bytecode { 57.120 -public: 57.121 +// Abstraction for all field accesses (put/get field/static) 57.122 +class Bytecode_field: public Bytecode_member_ref { 57.123 + protected: 57.124 + Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {} 57.125 + 57.126 + public: 57.127 + // Testers 57.128 + bool is_getfield() const { return java_code() == Bytecodes::_getfield; } 57.129 + bool is_putfield() const { return java_code() == Bytecodes::_putfield; } 57.130 + bool is_getstatic() const { return java_code() == Bytecodes::_getstatic; } 57.131 + bool is_putstatic() const { return java_code() == Bytecodes::_putstatic; } 57.132 + 57.133 + bool is_getter() const { return is_getfield() || is_getstatic(); } 57.134 + bool is_static() const { return is_getstatic() || is_putstatic(); } 57.135 + 57.136 + bool is_valid() const { return is_getfield() || 57.137 + is_putfield() || 57.138 + is_getstatic() || 57.139 + is_putstatic(); } 57.140 void verify() const; 57.141 57.142 - int index() const; 57.143 - bool is_static() const; 57.144 - 57.145 // Creation 57.146 - inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp); 57.147 + inline friend Bytecode_field* Bytecode_field_at(methodHandle method, int bci); 57.148 }; 57.149 57.150 -inline Bytecode_field* Bytecode_field_at(const methodOop method, address bcp) { 57.151 - Bytecode_field* b = (Bytecode_field*)bcp; 57.152 - debug_only(b->verify()); 57.153 +inline Bytecode_field* Bytecode_field_at(methodHandle method, int bci) { 57.154 + Bytecode_field* b = new Bytecode_field(method, bci); 57.155 + DEBUG_ONLY(b->verify()); 57.156 return b; 57.157 } 57.158 57.159 @@ -274,7 +303,7 @@ 57.160 57.161 inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) { 57.162 Bytecode_checkcast* b = (Bytecode_checkcast*)bcp; 57.163 - debug_only(b->verify()); 57.164 + DEBUG_ONLY(b->verify()); 57.165 return b; 57.166 } 57.167 57.168 @@ -294,7 +323,7 @@ 57.169 57.170 inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) { 57.171 Bytecode_instanceof* b = (Bytecode_instanceof*)bcp; 57.172 - debug_only(b->verify()); 57.173 + DEBUG_ONLY(b->verify()); 57.174 return b; 57.175 } 57.176 57.177 @@ -312,7 +341,7 @@ 57.178 57.179 inline Bytecode_new* Bytecode_new_at(address bcp) { 57.180 Bytecode_new* b = (Bytecode_new*)bcp; 57.181 - debug_only(b->verify()); 57.182 + DEBUG_ONLY(b->verify()); 57.183 return b; 57.184 } 57.185 57.186 @@ -330,7 +359,7 @@ 57.187 57.188 inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) { 57.189 Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp; 57.190 - debug_only(b->verify()); 57.191 + DEBUG_ONLY(b->verify()); 57.192 return b; 57.193 } 57.194 57.195 @@ -348,29 +377,57 @@ 57.196 57.197 inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) { 57.198 Bytecode_anewarray* b = (Bytecode_anewarray*)bcp; 57.199 - debug_only(b->verify()); 57.200 + DEBUG_ONLY(b->verify()); 57.201 return b; 57.202 } 57.203 57.204 57.205 // Abstraction for ldc, ldc_w and ldc2_w 57.206 57.207 -class Bytecode_loadconstant: public Bytecode { 57.208 +class Bytecode_loadconstant: public ResourceObj { 57.209 + private: 57.210 + int _bci; 57.211 + methodHandle _method; 57.212 + 57.213 + Bytecodes::Code code() const { return bytecode()->code(); } 57.214 + 57.215 + int raw_index() const; 57.216 + 57.217 + Bytecode_loadconstant(methodHandle method, int bci) : _method(method), _bci(bci) {} 57.218 + 57.219 public: 57.220 + // Attributes 57.221 + methodHandle method() const { return _method; } 57.222 + int bci() const { return _bci; } 57.223 + address bcp() const { return _method->bcp_from(bci()); } 57.224 + Bytecode* bytecode() const { return Bytecode_at(bcp()); } 57.225 + 57.226 void verify() const { 57.227 + assert(_method.not_null(), "must supply method"); 57.228 Bytecodes::Code stdc = Bytecodes::java_code(code()); 57.229 assert(stdc == Bytecodes::_ldc || 57.230 stdc == Bytecodes::_ldc_w || 57.231 stdc == Bytecodes::_ldc2_w, "load constant"); 57.232 } 57.233 57.234 - int index() const; 57.235 + // Only non-standard bytecodes (fast_aldc) have CP cache indexes. 57.236 + bool has_cache_index() const { return code() >= Bytecodes::number_of_java_codes; } 57.237 57.238 - inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp); 57.239 + int pool_index() const; // index into constant pool 57.240 + int cache_index() const { // index into CP cache (or -1 if none) 57.241 + return has_cache_index() ? raw_index() : -1; 57.242 + } 57.243 + 57.244 + BasicType result_type() const; // returns the result type of the ldc 57.245 + 57.246 + oop resolve_constant(TRAPS) const; 57.247 + 57.248 + // Creation 57.249 + inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci); 57.250 }; 57.251 57.252 -inline Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp) { 57.253 - Bytecode_loadconstant* b = (Bytecode_loadconstant*)bcp; 57.254 - debug_only(b->verify()); 57.255 +inline Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci) { 57.256 + Bytecode_loadconstant* b = new Bytecode_loadconstant(method, bci); 57.257 + DEBUG_ONLY(b->verify()); 57.258 return b; 57.259 }
58.1 --- a/src/share/vm/interpreter/bytecodeTracer.cpp Thu Jun 24 15:38:42 2010 -0700 58.2 +++ b/src/share/vm/interpreter/bytecodeTracer.cpp Mon Jun 28 12:03:05 2010 -0400 58.3 @@ -49,6 +49,7 @@ 58.4 58.5 int get_index_u1() { return *(address)_next_pc++; } 58.6 int get_index_u2() { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; } 58.7 + int get_index_u1_cpcache() { return get_index_u1() + constantPoolOopDesc::CPCACHE_INDEX_TAG; } 58.8 int get_index_u2_cpcache() { int i=Bytes::get_native_u2(_next_pc); _next_pc+=2; return i + constantPoolOopDesc::CPCACHE_INDEX_TAG; } 58.9 int get_index_u4() { int i=Bytes::get_native_u4(_next_pc); _next_pc+=4; return i; } 58.10 int get_index_special() { return (is_wide()) ? get_index_u2() : get_index_u1(); } 58.11 @@ -60,6 +61,7 @@ 58.12 bool check_index(int i, int& cp_index, outputStream* st = tty); 58.13 void print_constant(int i, outputStream* st = tty); 58.14 void print_field_or_method(int i, outputStream* st = tty); 58.15 + void print_field_or_method(int orig_i, int i, outputStream* st = tty); 58.16 void print_attributes(int bci, outputStream* st = tty); 58.17 void bytecode_epilog(int bci, outputStream* st = tty); 58.18 58.19 @@ -177,18 +179,29 @@ 58.20 _closure->trace(method, bcp, st); 58.21 } 58.22 58.23 +void print_symbol(symbolOop sym, outputStream* st) { 58.24 + char buf[40]; 58.25 + int len = sym->utf8_length(); 58.26 + if (len >= (int)sizeof(buf)) { 58.27 + st->print_cr(" %s...[%d]", sym->as_C_string(buf, sizeof(buf)), len); 58.28 + } else { 58.29 + st->print(" "); 58.30 + sym->print_on(st); st->cr(); 58.31 + } 58.32 +} 58.33 + 58.34 void print_oop(oop value, outputStream* st) { 58.35 if (value == NULL) { 58.36 st->print_cr(" NULL"); 58.37 - } else { 58.38 + } else if (java_lang_String::is_instance(value)) { 58.39 EXCEPTION_MARK; 58.40 Handle h_value (THREAD, value); 58.41 symbolHandle sym = java_lang_String::as_symbol(h_value, CATCH); 58.42 - if (sym->utf8_length() > 32) { 58.43 - st->print_cr(" ...."); 58.44 - } else { 58.45 - sym->print_on(st); st->cr(); 58.46 - } 58.47 + print_symbol(sym(), st); 58.48 + } else if (value->is_symbol()) { 58.49 + print_symbol(symbolOop(value), st); 58.50 + } else { 58.51 + st->print_cr(" " PTR_FORMAT, (intptr_t) value); 58.52 } 58.53 } 58.54 58.55 @@ -279,16 +292,27 @@ 58.56 } else if (tag.is_double()) { 58.57 st->print_cr(" %f", constants->double_at(i)); 58.58 } else if (tag.is_string()) { 58.59 - oop string = constants->resolved_string_at(i); 58.60 + oop string = constants->pseudo_string_at(i); 58.61 print_oop(string, st); 58.62 } else if (tag.is_unresolved_string()) { 58.63 - st->print_cr(" <unresolved string at %d>", i); 58.64 + const char* string = constants->string_at_noresolve(i); 58.65 + st->print_cr(" %s", string); 58.66 } else if (tag.is_klass()) { 58.67 st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name()); 58.68 } else if (tag.is_unresolved_klass()) { 58.69 st->print_cr(" <unresolved klass at %d>", i); 58.70 } else if (tag.is_object()) { 58.71 - st->print_cr(" " PTR_FORMAT, constants->object_at(i)); 58.72 + st->print(" <Object>"); 58.73 + print_oop(constants->object_at(i), st); 58.74 + } else if (tag.is_method_type()) { 58.75 + int i2 = constants->method_type_index_at(i); 58.76 + st->print(" <MethodType> %d", i2); 58.77 + print_oop(constants->symbol_at(i2), st); 58.78 + } else if (tag.is_method_handle()) { 58.79 + int kind = constants->method_handle_ref_kind_at(i); 58.80 + int i2 = constants->method_handle_index_at(i); 58.81 + st->print(" <MethodHandle of kind %d>", kind, i2); 58.82 + print_field_or_method(-i, i2, st); 58.83 } else { 58.84 st->print_cr(" bad tag=%d at %d", tag.value(), i); 58.85 } 58.86 @@ -297,7 +321,10 @@ 58.87 void BytecodePrinter::print_field_or_method(int i, outputStream* st) { 58.88 int orig_i = i; 58.89 if (!check_index(orig_i, i, st)) return; 58.90 + print_field_or_method(orig_i, i, st); 58.91 +} 58.92 58.93 +void BytecodePrinter::print_field_or_method(int orig_i, int i, outputStream* st) { 58.94 constantPoolOop constants = method()->constants(); 58.95 constantTag tag = constants->tag_at(i); 58.96 58.97 @@ -314,9 +341,11 @@ 58.98 return; 58.99 } 58.100 58.101 + symbolOop klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i)); 58.102 symbolOop name = constants->uncached_name_ref_at(i); 58.103 symbolOop signature = constants->uncached_signature_ref_at(i); 58.104 - st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string()); 58.105 + const char* sep = (tag.is_field() ? "/" : ""); 58.106 + st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string()); 58.107 } 58.108 58.109 58.110 @@ -340,12 +369,20 @@ 58.111 st->print_cr(" " INT32_FORMAT, get_short()); 58.112 break; 58.113 case Bytecodes::_ldc: 58.114 - print_constant(get_index_u1(), st); 58.115 + if (Bytecodes::uses_cp_cache(raw_code())) { 58.116 + print_constant(get_index_u1_cpcache(), st); 58.117 + } else { 58.118 + print_constant(get_index_u1(), st); 58.119 + } 58.120 break; 58.121 58.122 case Bytecodes::_ldc_w: 58.123 case Bytecodes::_ldc2_w: 58.124 - print_constant(get_index_u2(), st); 58.125 + if (Bytecodes::uses_cp_cache(raw_code())) { 58.126 + print_constant(get_index_u2_cpcache(), st); 58.127 + } else { 58.128 + print_constant(get_index_u2(), st); 58.129 + } 58.130 break; 58.131 58.132 case Bytecodes::_iload:
59.1 --- a/src/share/vm/interpreter/bytecodes.cpp Thu Jun 24 15:38:42 2010 -0700 59.2 +++ b/src/share/vm/interpreter/bytecodes.cpp Mon Jun 28 12:03:05 2010 -0400 59.3 @@ -489,6 +489,9 @@ 59.4 59.5 def(_return_register_finalizer , "return_register_finalizer" , "b" , NULL , T_VOID , 0, true, _return); 59.6 59.7 + def(_fast_aldc , "fast_aldc" , "bj" , NULL , T_OBJECT, 1, true, _ldc ); 59.8 + def(_fast_aldc_w , "fast_aldc_w" , "bJJ" , NULL , T_OBJECT, 1, true, _ldc_w ); 59.9 + 59.10 def(_shouldnotreachhere , "_shouldnotreachhere" , "b" , NULL , T_VOID , 0, false); 59.11 59.12 // platform specific JVM bytecodes
60.1 --- a/src/share/vm/interpreter/bytecodes.hpp Thu Jun 24 15:38:42 2010 -0700 60.2 +++ b/src/share/vm/interpreter/bytecodes.hpp Mon Jun 28 12:03:05 2010 -0400 60.3 @@ -270,6 +270,10 @@ 60.4 _fast_linearswitch , 60.5 _fast_binaryswitch , 60.6 60.7 + // special handling of oop constants: 60.8 + _fast_aldc , 60.9 + _fast_aldc_w , 60.10 + 60.11 _return_register_finalizer , 60.12 60.13 _shouldnotreachhere, // For debugging
61.1 --- a/src/share/vm/interpreter/interpreter.cpp Thu Jun 24 15:38:42 2010 -0700 61.2 +++ b/src/share/vm/interpreter/interpreter.cpp Mon Jun 28 12:03:05 2010 -0400 61.3 @@ -267,20 +267,6 @@ 61.4 } 61.5 #endif // PRODUCT 61.6 61.7 -static BasicType constant_pool_type(methodOop method, int index) { 61.8 - constantTag tag = method->constants()->tag_at(index); 61.9 - if (tag.is_int ()) return T_INT; 61.10 - else if (tag.is_float ()) return T_FLOAT; 61.11 - else if (tag.is_long ()) return T_LONG; 61.12 - else if (tag.is_double ()) return T_DOUBLE; 61.13 - else if (tag.is_string ()) return T_OBJECT; 61.14 - else if (tag.is_unresolved_string()) return T_OBJECT; 61.15 - else if (tag.is_klass ()) return T_OBJECT; 61.16 - else if (tag.is_unresolved_klass ()) return T_OBJECT; 61.17 - ShouldNotReachHere(); 61.18 - return T_ILLEGAL; 61.19 -} 61.20 - 61.21 61.22 //------------------------------------------------------------------------------------------------------------------------ 61.23 // Deoptimization support 61.24 @@ -330,13 +316,15 @@ 61.25 } 61.26 61.27 case Bytecodes::_ldc : 61.28 - type = constant_pool_type( method, *(bcp+1) ); 61.29 - break; 61.30 - 61.31 case Bytecodes::_ldc_w : // fall through 61.32 case Bytecodes::_ldc2_w: 61.33 - type = constant_pool_type( method, Bytes::get_Java_u2(bcp+1) ); 61.34 - break; 61.35 + { 61.36 + Thread *thread = Thread::current(); 61.37 + ResourceMark rm(thread); 61.38 + methodHandle mh(thread, method); 61.39 + type = Bytecode_loadconstant_at(mh, bci)->result_type(); 61.40 + break; 61.41 + } 61.42 61.43 default: 61.44 type = Bytecodes::result_type(code);
62.1 --- a/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jun 24 15:38:42 2010 -0700 62.2 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Mon Jun 28 12:03:05 2010 -0400 62.3 @@ -83,6 +83,18 @@ 62.4 } 62.5 IRT_END 62.6 62.7 +IRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::Code bytecode)) { 62.8 + assert(bytecode == Bytecodes::_fast_aldc || 62.9 + bytecode == Bytecodes::_fast_aldc_w, "wrong bc"); 62.10 + ResourceMark rm(thread); 62.11 + methodHandle m (thread, method(thread)); 62.12 + Bytecode_loadconstant* ldc = Bytecode_loadconstant_at(m, bci(thread)); 62.13 + oop result = ldc->resolve_constant(THREAD); 62.14 + DEBUG_ONLY(ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc->cache_index())); 62.15 + assert(result == cpce->f1(), "expected result for assembly code"); 62.16 +} 62.17 +IRT_END 62.18 + 62.19 62.20 //------------------------------------------------------------------------------------------------------------------------ 62.21 // Allocation 62.22 @@ -328,7 +340,7 @@ 62.23 typeArrayHandle h_extable (thread, h_method->exception_table()); 62.24 bool should_repeat; 62.25 int handler_bci; 62.26 - int current_bci = bcp(thread) - h_method->code_base(); 62.27 + int current_bci = bci(thread); 62.28 62.29 // Need to do this check first since when _do_not_unlock_if_synchronized 62.30 // is set, we don't want to trigger any classloading which may make calls 62.31 @@ -615,8 +627,7 @@ 62.32 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { 62.33 ResourceMark rm(thread); 62.34 methodHandle m (thread, method(thread)); 62.35 - int bci = m->bci_from(bcp(thread)); 62.36 - Bytecode_invoke* call = Bytecode_invoke_at(m, bci); 62.37 + Bytecode_invoke* call = Bytecode_invoke_at(m, bci(thread)); 62.38 symbolHandle signature (thread, call->signature()); 62.39 receiver = Handle(thread, 62.40 thread->last_frame().interpreter_callee_receiver(signature)); 62.41 @@ -1257,7 +1268,7 @@ 62.42 Bytecode_invoke* invoke = Bytecode_invoke_at(mh, bci); 62.43 ArgumentSizeComputer asc(invoke->signature()); 62.44 int size_of_arguments = (asc.size() + (invoke->has_receiver() ? 1 : 0)); // receiver 62.45 - Copy::conjoint_bytes(src_address, dest_address, 62.46 + Copy::conjoint_jbytes(src_address, dest_address, 62.47 size_of_arguments * Interpreter::stackElementSize); 62.48 IRT_END 62.49 #endif
63.1 --- a/src/share/vm/interpreter/interpreterRuntime.hpp Thu Jun 24 15:38:42 2010 -0700 63.2 +++ b/src/share/vm/interpreter/interpreterRuntime.hpp Mon Jun 28 12:03:05 2010 -0400 63.3 @@ -34,6 +34,7 @@ 63.4 static frame last_frame(JavaThread *thread) { return thread->last_frame(); } 63.5 static methodOop method(JavaThread *thread) { return last_frame(thread).interpreter_frame_method(); } 63.6 static address bcp(JavaThread *thread) { return last_frame(thread).interpreter_frame_bcp(); } 63.7 + static int bci(JavaThread *thread) { return last_frame(thread).interpreter_frame_bci(); } 63.8 static void set_bcp_and_mdp(address bcp, JavaThread*thread); 63.9 static Bytecodes::Code code(JavaThread *thread) { 63.10 // pass method to avoid calling unsafe bcp_to_method (partial fix 4926272) 63.11 @@ -59,6 +60,7 @@ 63.12 public: 63.13 // Constants 63.14 static void ldc (JavaThread* thread, bool wide); 63.15 + static void resolve_ldc (JavaThread* thread, Bytecodes::Code bytecode); 63.16 63.17 // Allocation 63.18 static void _new (JavaThread* thread, constantPoolOopDesc* pool, int index);
64.1 --- a/src/share/vm/interpreter/rewriter.cpp Thu Jun 24 15:38:42 2010 -0700 64.2 +++ b/src/share/vm/interpreter/rewriter.cpp Mon Jun 28 12:03:05 2010 -0400 64.3 @@ -38,6 +38,8 @@ 64.4 case JVM_CONSTANT_InterfaceMethodref: 64.5 case JVM_CONSTANT_Fieldref : // fall through 64.6 case JVM_CONSTANT_Methodref : // fall through 64.7 + case JVM_CONSTANT_MethodHandle : // fall through 64.8 + case JVM_CONSTANT_MethodType : // fall through 64.9 add_cp_cache_entry(i); 64.10 break; 64.11 } 64.12 @@ -131,6 +133,27 @@ 64.13 } 64.14 64.15 64.16 +// Rewrite some ldc bytecodes to _fast_aldc 64.17 +void Rewriter::maybe_rewrite_ldc(address bcp, int offset, bool is_wide) { 64.18 + assert((*bcp) == (is_wide ? Bytecodes::_ldc_w : Bytecodes::_ldc), ""); 64.19 + address p = bcp + offset; 64.20 + int cp_index = is_wide ? Bytes::get_Java_u2(p) : (u1)(*p); 64.21 + constantTag tag = _pool->tag_at(cp_index).value(); 64.22 + if (tag.is_method_handle() || tag.is_method_type()) { 64.23 + int cache_index = cp_entry_to_cp_cache(cp_index); 64.24 + if (is_wide) { 64.25 + (*bcp) = Bytecodes::_fast_aldc_w; 64.26 + assert(cache_index == (u2)cache_index, ""); 64.27 + Bytes::put_native_u2(p, cache_index); 64.28 + } else { 64.29 + (*bcp) = Bytecodes::_fast_aldc; 64.30 + assert(cache_index == (u1)cache_index, ""); 64.31 + (*p) = (u1)cache_index; 64.32 + } 64.33 + } 64.34 +} 64.35 + 64.36 + 64.37 // Rewrites a method given the index_map information 64.38 void Rewriter::scan_method(methodOop method) { 64.39 64.40 @@ -198,6 +221,12 @@ 64.41 case Bytecodes::_invokedynamic: 64.42 rewrite_invokedynamic(bcp, prefix_length+1); 64.43 break; 64.44 + case Bytecodes::_ldc: 64.45 + maybe_rewrite_ldc(bcp, prefix_length+1, false); 64.46 + break; 64.47 + case Bytecodes::_ldc_w: 64.48 + maybe_rewrite_ldc(bcp, prefix_length+1, true); 64.49 + break; 64.50 case Bytecodes::_jsr : // fall through 64.51 case Bytecodes::_jsr_w : nof_jsrs++; break; 64.52 case Bytecodes::_monitorenter : // fall through
65.1 --- a/src/share/vm/interpreter/rewriter.hpp Thu Jun 24 15:38:42 2010 -0700 65.2 +++ b/src/share/vm/interpreter/rewriter.hpp Mon Jun 28 12:03:05 2010 -0400 65.3 @@ -66,6 +66,7 @@ 65.4 void rewrite_Object_init(methodHandle m, TRAPS); 65.5 void rewrite_member_reference(address bcp, int offset); 65.6 void rewrite_invokedynamic(address bcp, int offset); 65.7 + void maybe_rewrite_ldc(address bcp, int offset, bool is_wide); 65.8 65.9 public: 65.10 // Driver routine:
66.1 --- a/src/share/vm/interpreter/templateTable.cpp Thu Jun 24 15:38:42 2010 -0700 66.2 +++ b/src/share/vm/interpreter/templateTable.cpp Mon Jun 28 12:03:05 2010 -0400 66.3 @@ -507,6 +507,9 @@ 66.4 def(Bytecodes::_fast_linearswitch , ubcp|disp|____|____, itos, vtos, fast_linearswitch , _ ); 66.5 def(Bytecodes::_fast_binaryswitch , ubcp|disp|____|____, itos, vtos, fast_binaryswitch , _ ); 66.6 66.7 + def(Bytecodes::_fast_aldc , ubcp|____|clvm|____, vtos, atos, fast_aldc , false ); 66.8 + def(Bytecodes::_fast_aldc_w , ubcp|____|clvm|____, vtos, atos, fast_aldc , true ); 66.9 + 66.10 def(Bytecodes::_return_register_finalizer , ____|disp|clvm|____, vtos, vtos, _return , vtos ); 66.11 66.12 def(Bytecodes::_shouldnotreachhere , ____|____|____|____, vtos, vtos, shouldnotreachhere , _ );
67.1 --- a/src/share/vm/interpreter/templateTable.hpp Thu Jun 24 15:38:42 2010 -0700 67.2 +++ b/src/share/vm/interpreter/templateTable.hpp Mon Jun 28 12:03:05 2010 -0400 67.3 @@ -123,6 +123,7 @@ 67.4 static void sipush(); 67.5 static void ldc(bool wide); 67.6 static void ldc2_w(); 67.7 + static void fast_aldc(bool wide); 67.8 67.9 static void locals_index(Register reg, int offset = 1); 67.10 static void iload();
68.1 --- a/src/share/vm/memory/cardTableModRefBS.cpp Thu Jun 24 15:38:42 2010 -0700 68.2 +++ b/src/share/vm/memory/cardTableModRefBS.cpp Mon Jun 28 12:03:05 2010 -0400 68.3 @@ -1,5 +1,5 @@ 68.4 /* 68.5 - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. 68.6 + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 68.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 68.8 * 68.9 * This code is free software; you can redistribute it and/or modify it 68.10 @@ -284,12 +284,19 @@ 68.11 committed_unique_to_self(ind, MemRegion(new_end_aligned, 68.12 cur_committed.end())); 68.13 if (!uncommit_region.is_empty()) { 68.14 - if (!os::uncommit_memory((char*)uncommit_region.start(), 68.15 - uncommit_region.byte_size())) { 68.16 - assert(false, "Card table contraction failed"); 68.17 - // The call failed so don't change the end of the 68.18 - // committed region. This is better than taking the 68.19 - // VM down. 68.20 + // It is not safe to uncommit cards if the boundary between 68.21 + // the generations is moving. A shrink can uncommit cards 68.22 + // owned by generation A but being used by generation B. 68.23 + if (!UseAdaptiveGCBoundary) { 68.24 + if (!os::uncommit_memory((char*)uncommit_region.start(), 68.25 + uncommit_region.byte_size())) { 68.26 + assert(false, "Card table contraction failed"); 68.27 + // The call failed so don't change the end of the 68.28 + // committed region. This is better than taking the 68.29 + // VM down. 68.30 + new_end_aligned = _committed[ind].end(); 68.31 + } 68.32 + } else { 68.33 new_end_aligned = _committed[ind].end(); 68.34 } 68.35 } 68.36 @@ -297,6 +304,19 @@ 68.37 // In any case, we can reset the end of the current committed entry. 68.38 _committed[ind].set_end(new_end_aligned); 68.39 68.40 +#ifdef ASSERT 68.41 + // Check that the last card in the new region is committed according 68.42 + // to the tables. 68.43 + bool covered = false; 68.44 + for (int cr = 0; cr < _cur_covered_regions; cr++) { 68.45 + if (_committed[cr].contains(new_end - 1)) { 68.46 + covered = true; 68.47 + break; 68.48 + } 68.49 + } 68.50 + assert(covered, "Card for end of new region not committed"); 68.51 +#endif 68.52 + 68.53 // The default of 0 is not necessarily clean cards. 68.54 jbyte* entry; 68.55 if (old_region.last() < _whole_heap.start()) { 68.56 @@ -354,6 +374,9 @@ 68.57 addr_for((jbyte*) _committed[ind].start()), 68.58 addr_for((jbyte*) _committed[ind].last())); 68.59 } 68.60 + // Touch the last card of the covered region to show that it 68.61 + // is committed (or SEGV). 68.62 + debug_only(*byte_for(_covered[ind].last());) 68.63 debug_only(verify_guard();) 68.64 } 68.65
69.1 --- a/src/share/vm/oops/constantPoolKlass.cpp Thu Jun 24 15:38:42 2010 -0700 69.2 +++ b/src/share/vm/oops/constantPoolKlass.cpp Mon Jun 28 12:03:05 2010 -0400 69.3 @@ -372,6 +372,13 @@ 69.4 entry->print_value_on(st); 69.5 } 69.6 break; 69.7 + case JVM_CONSTANT_MethodHandle : 69.8 + st->print("ref_kind=%d", cp->method_handle_ref_kind_at(index)); 69.9 + st->print(" ref_index=%d", cp->method_handle_index_at(index)); 69.10 + break; 69.11 + case JVM_CONSTANT_MethodType : 69.12 + st->print("signature_index=%d", cp->method_type_index_at(index)); 69.13 + break; 69.14 default: 69.15 ShouldNotReachHere(); 69.16 break; 69.17 @@ -437,6 +444,7 @@ 69.18 // can be non-perm, can be non-instance (array) 69.19 } 69.20 } 69.21 + // FIXME: verify JSR 292 tags JVM_CONSTANT_MethodHandle, etc. 69.22 base++; 69.23 } 69.24 guarantee(cp->tags()->is_perm(), "should be in permspace");
70.1 --- a/src/share/vm/oops/constantPoolOop.cpp Thu Jun 24 15:38:42 2010 -0700 70.2 +++ b/src/share/vm/oops/constantPoolOop.cpp Mon Jun 28 12:03:05 2010 -0400 70.3 @@ -358,6 +358,11 @@ 70.4 return klass_at_noresolve(ref_index); 70.5 } 70.6 70.7 +symbolOop constantPoolOopDesc::uncached_klass_ref_at_noresolve(int which) { 70.8 + jint ref_index = uncached_klass_ref_index_at(which); 70.9 + return klass_at_noresolve(ref_index); 70.10 +} 70.11 + 70.12 char* constantPoolOopDesc::string_at_noresolve(int which) { 70.13 // Test entry type in case string is resolved while in here. 70.14 oop entry = *(obj_at_addr(which)); 70.15 @@ -384,6 +389,119 @@ 70.16 } 70.17 } 70.18 70.19 +oop constantPoolOopDesc::resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS) { 70.20 + oop result_oop = NULL; 70.21 + if (cache_index >= 0) { 70.22 + assert(index < 0, "only one kind of index at a time"); 70.23 + ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); 70.24 + result_oop = cpc_entry->f1(); 70.25 + if (result_oop != NULL) { 70.26 + return result_oop; // that was easy... 70.27 + } 70.28 + index = cpc_entry->constant_pool_index(); 70.29 + } 70.30 + 70.31 + int tag_value = this_oop->tag_at(index).value(); 70.32 + switch (tag_value) { 70.33 + 70.34 + case JVM_CONSTANT_UnresolvedClass: 70.35 + case JVM_CONSTANT_UnresolvedClassInError: 70.36 + case JVM_CONSTANT_Class: 70.37 + { 70.38 + klassOop resolved = klass_at_impl(this_oop, index, CHECK_NULL); 70.39 + // ldc wants the java mirror. 70.40 + result_oop = resolved->klass_part()->java_mirror(); 70.41 + break; 70.42 + } 70.43 + 70.44 + case JVM_CONSTANT_String: 70.45 + case JVM_CONSTANT_UnresolvedString: 70.46 + if (this_oop->is_pseudo_string_at(index)) { 70.47 + result_oop = this_oop->pseudo_string_at(index); 70.48 + break; 70.49 + } 70.50 + result_oop = string_at_impl(this_oop, index, CHECK_NULL); 70.51 + break; 70.52 + 70.53 + case JVM_CONSTANT_Object: 70.54 + result_oop = this_oop->object_at(index); 70.55 + break; 70.56 + 70.57 + case JVM_CONSTANT_MethodHandle: 70.58 + { 70.59 + int ref_kind = this_oop->method_handle_ref_kind_at(index); 70.60 + int callee_index = this_oop->method_handle_klass_index_at(index); 70.61 + symbolHandle name(THREAD, this_oop->method_handle_name_ref_at(index)); 70.62 + symbolHandle signature(THREAD, this_oop->method_handle_signature_ref_at(index)); 70.63 + if (PrintMiscellaneous) 70.64 + tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s", 70.65 + ref_kind, index, this_oop->method_handle_index_at(index), 70.66 + callee_index, name->as_C_string(), signature->as_C_string()); 70.67 + KlassHandle callee; 70.68 + { klassOop k = klass_at_impl(this_oop, callee_index, CHECK_NULL); 70.69 + callee = KlassHandle(THREAD, k); 70.70 + } 70.71 + KlassHandle klass(THREAD, this_oop->pool_holder()); 70.72 + Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind, 70.73 + callee, name, signature, 70.74 + CHECK_NULL); 70.75 + result_oop = value(); 70.76 + // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error. 70.77 + break; 70.78 + } 70.79 + 70.80 + case JVM_CONSTANT_MethodType: 70.81 + { 70.82 + symbolHandle signature(THREAD, this_oop->method_type_signature_at(index)); 70.83 + if (PrintMiscellaneous) 70.84 + tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s", 70.85 + index, this_oop->method_type_index_at(index), 70.86 + signature->as_C_string()); 70.87 + KlassHandle klass(THREAD, this_oop->pool_holder()); 70.88 + bool ignore_is_on_bcp = false; 70.89 + Handle value = SystemDictionary::find_method_handle_type(signature, 70.90 + klass, 70.91 + ignore_is_on_bcp, 70.92 + CHECK_NULL); 70.93 + result_oop = value(); 70.94 + // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error. 70.95 + break; 70.96 + } 70.97 + 70.98 + /* maybe some day 70.99 + case JVM_CONSTANT_Integer: 70.100 + case JVM_CONSTANT_Float: 70.101 + case JVM_CONSTANT_Long: 70.102 + case JVM_CONSTANT_Double: 70.103 + result_oop = java_lang_boxing_object::create(...); 70.104 + break; 70.105 + */ 70.106 + 70.107 + default: 70.108 + DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", 70.109 + this_oop(), index, cache_index, tag_value) ); 70.110 + assert(false, "unexpected constant tag"); 70.111 + break; 70.112 + } 70.113 + 70.114 + if (cache_index >= 0) { 70.115 + // Cache the oop here also. 70.116 + Handle result(THREAD, result_oop); 70.117 + result_oop = NULL; // safety 70.118 + ObjectLocker ol(this_oop, THREAD); 70.119 + ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); 70.120 + oop result_oop2 = cpc_entry->f1(); 70.121 + if (result_oop2 != NULL) { 70.122 + // Race condition: May already be filled in while we were trying to lock. 70.123 + return result_oop2; 70.124 + } 70.125 + cpc_entry->set_f1(result()); 70.126 + return result(); 70.127 + } else { 70.128 + return result_oop; 70.129 + } 70.130 +} 70.131 + 70.132 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { 70.133 oop entry = *(this_oop->obj_at_addr(which)); 70.134 if (entry->is_symbol()) { 70.135 @@ -690,6 +808,28 @@ 70.136 } 70.137 } break; 70.138 70.139 + case JVM_CONSTANT_MethodType: 70.140 + { 70.141 + int k1 = method_type_index_at(index1); 70.142 + int k2 = cp2->method_type_index_at(index2); 70.143 + if (k1 == k2) { 70.144 + return true; 70.145 + } 70.146 + } break; 70.147 + 70.148 + case JVM_CONSTANT_MethodHandle: 70.149 + { 70.150 + int k1 = method_handle_ref_kind_at(index1); 70.151 + int k2 = cp2->method_handle_ref_kind_at(index2); 70.152 + if (k1 == k2) { 70.153 + int i1 = method_handle_index_at(index1); 70.154 + int i2 = cp2->method_handle_index_at(index2); 70.155 + if (i1 == i2) { 70.156 + return true; 70.157 + } 70.158 + } 70.159 + } break; 70.160 + 70.161 case JVM_CONSTANT_UnresolvedString: 70.162 { 70.163 symbolOop s1 = unresolved_string_at(index1); 70.164 @@ -863,6 +1003,19 @@ 70.165 to_cp->symbol_at_put(to_i, s); 70.166 } break; 70.167 70.168 + case JVM_CONSTANT_MethodType: 70.169 + { 70.170 + jint k = method_type_index_at(from_i); 70.171 + to_cp->method_type_index_at_put(to_i, k); 70.172 + } break; 70.173 + 70.174 + case JVM_CONSTANT_MethodHandle: 70.175 + { 70.176 + int k1 = method_handle_ref_kind_at(from_i); 70.177 + int k2 = method_handle_index_at(from_i); 70.178 + to_cp->method_handle_index_at_put(to_i, k1, k2); 70.179 + } break; 70.180 + 70.181 // Invalid is used as the tag for the second constant pool entry 70.182 // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should 70.183 // not be seen by itself. 70.184 @@ -1066,8 +1219,12 @@ 70.185 case JVM_CONSTANT_UnresolvedClassInError: 70.186 case JVM_CONSTANT_StringIndex: 70.187 case JVM_CONSTANT_UnresolvedString: 70.188 + case JVM_CONSTANT_MethodType: 70.189 return 3; 70.190 70.191 + case JVM_CONSTANT_MethodHandle: 70.192 + return 4; //tag, ref_kind, ref_index 70.193 + 70.194 case JVM_CONSTANT_Integer: 70.195 case JVM_CONSTANT_Float: 70.196 case JVM_CONSTANT_Fieldref: 70.197 @@ -1271,6 +1428,22 @@ 70.198 DBG(printf("JVM_CONSTANT_StringIndex: %hd", idx1)); 70.199 break; 70.200 } 70.201 + case JVM_CONSTANT_MethodHandle: { 70.202 + *bytes = JVM_CONSTANT_MethodHandle; 70.203 + int kind = method_handle_ref_kind_at(idx); 70.204 + idx1 = method_handle_index_at(idx); 70.205 + *(bytes+1) = (unsigned char) kind; 70.206 + Bytes::put_Java_u2((address) (bytes+2), idx1); 70.207 + DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1)); 70.208 + break; 70.209 + } 70.210 + case JVM_CONSTANT_MethodType: { 70.211 + *bytes = JVM_CONSTANT_MethodType; 70.212 + idx1 = method_type_index_at(idx); 70.213 + Bytes::put_Java_u2((address) (bytes+1), idx1); 70.214 + DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); 70.215 + break; 70.216 + } 70.217 } 70.218 DBG(printf("\n")); 70.219 bytes += ent_size;
71.1 --- a/src/share/vm/oops/constantPoolOop.hpp Thu Jun 24 15:38:42 2010 -0700 71.2 +++ b/src/share/vm/oops/constantPoolOop.hpp Mon Jun 28 12:03:05 2010 -0400 71.3 @@ -146,6 +146,16 @@ 71.4 oop_store_without_check(obj_at_addr(which), oop(s)); 71.5 } 71.6 71.7 + void method_handle_index_at_put(int which, int ref_kind, int ref_index) { 71.8 + tag_at_put(which, JVM_CONSTANT_MethodHandle); 71.9 + *int_at_addr(which) = ((jint) ref_index<<16) | ref_kind; 71.10 + } 71.11 + 71.12 + void method_type_index_at_put(int which, int ref_index) { 71.13 + tag_at_put(which, JVM_CONSTANT_MethodType); 71.14 + *int_at_addr(which) = ref_index; 71.15 + } 71.16 + 71.17 // Temporary until actual use 71.18 void unresolved_string_at_put(int which, symbolOop s) { 71.19 *obj_at_addr(which) = NULL; 71.20 @@ -357,6 +367,36 @@ 71.21 return *int_at_addr(which); 71.22 } 71.23 71.24 + int method_handle_ref_kind_at(int which) { 71.25 + assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); 71.26 + return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits 71.27 + } 71.28 + int method_handle_index_at(int which) { 71.29 + assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); 71.30 + return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits 71.31 + } 71.32 + int method_type_index_at(int which) { 71.33 + assert(tag_at(which).is_method_type(), "Corrupted constant pool"); 71.34 + return *int_at_addr(which); 71.35 + } 71.36 + // Derived queries: 71.37 + symbolOop method_handle_name_ref_at(int which) { 71.38 + int member = method_handle_index_at(which); 71.39 + return impl_name_ref_at(member, true); 71.40 + } 71.41 + symbolOop method_handle_signature_ref_at(int which) { 71.42 + int member = method_handle_index_at(which); 71.43 + return impl_signature_ref_at(member, true); 71.44 + } 71.45 + int method_handle_klass_index_at(int which) { 71.46 + int member = method_handle_index_at(which); 71.47 + return impl_klass_ref_index_at(member, true); 71.48 + } 71.49 + symbolOop method_type_signature_at(int which) { 71.50 + int sym = method_type_index_at(which); 71.51 + return symbol_at(sym); 71.52 + } 71.53 + 71.54 // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve, 71.55 // name_and_type_ref_index_at) all expect to be passed indices obtained 71.56 // directly from the bytecode, and extracted according to java byte order. 71.57 @@ -388,6 +428,17 @@ 71.58 resolve_string_constants_impl(h_this, CHECK); 71.59 } 71.60 71.61 + // Resolve late bound constants. 71.62 + oop resolve_constant_at(int index, TRAPS) { 71.63 + constantPoolHandle h_this(THREAD, this); 71.64 + return resolve_constant_at_impl(h_this, index, -1, THREAD); 71.65 + } 71.66 + 71.67 + oop resolve_cached_constant_at(int cache_index, TRAPS) { 71.68 + constantPoolHandle h_this(THREAD, this); 71.69 + return resolve_constant_at_impl(h_this, -1, cache_index, THREAD); 71.70 + } 71.71 + 71.72 // Klass name matches name at offset 71.73 bool klass_name_at_matches(instanceKlassHandle k, int which); 71.74 71.75 @@ -420,6 +471,7 @@ 71.76 // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the 71.77 // future by other Java code. These take constant pool indices rather than possibly-byte-swapped 71.78 // constant pool cache indices as do the peer methods above. 71.79 + symbolOop uncached_klass_ref_at_noresolve(int which); 71.80 symbolOop uncached_name_ref_at(int which) { return impl_name_ref_at(which, true); } 71.81 symbolOop uncached_signature_ref_at(int which) { return impl_signature_ref_at(which, true); } 71.82 int uncached_klass_ref_index_at(int which) { return impl_klass_ref_index_at(which, true); } 71.83 @@ -436,6 +488,8 @@ 71.84 71.85 #ifdef ASSERT 71.86 enum { CPCACHE_INDEX_TAG = 0x10000 }; // helps keep CP cache indices distinct from CP indices 71.87 +#else 71.88 + enum { CPCACHE_INDEX_TAG = 0 }; // in product mode, this zero value is a no-op 71.89 #endif //ASSERT 71.90 71.91 private: 71.92 @@ -469,6 +523,8 @@ 71.93 // Resolve string constants (to prevent allocation during compilation) 71.94 static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS); 71.95 71.96 + static oop resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS); 71.97 + 71.98 public: 71.99 // Merging constantPoolOop support: 71.100 bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS);
72.1 --- a/src/share/vm/oops/cpCacheOop.hpp Thu Jun 24 15:38:42 2010 -0700 72.2 +++ b/src/share/vm/oops/cpCacheOop.hpp Mon Jun 28 12:03:05 2010 -0400 72.3 @@ -110,6 +110,7 @@ 72.4 class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC { 72.5 friend class VMStructs; 72.6 friend class constantPoolCacheKlass; 72.7 + friend class constantPoolOopDesc; //resolve_constant_at_impl => set_f1 72.8 72.9 private: 72.10 volatile intx _indices; // constant pool index & rewrite bytecodes
73.1 --- a/src/share/vm/opto/compile.cpp Thu Jun 24 15:38:42 2010 -0700 73.2 +++ b/src/share/vm/opto/compile.cpp Mon Jun 28 12:03:05 2010 -0400 73.3 @@ -2000,6 +2000,17 @@ 73.4 } 73.5 } 73.6 73.7 +#ifdef ASSERT 73.8 + if( n->is_Mem() ) { 73.9 + Compile* C = Compile::current(); 73.10 + int alias_idx = C->get_alias_index(n->as_Mem()->adr_type()); 73.11 + assert( n->in(0) != NULL || alias_idx != Compile::AliasIdxRaw || 73.12 + // oop will be recorded in oop map if load crosses safepoint 73.13 + n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() || 73.14 + LoadNode::is_immutable_value(n->in(MemNode::Address))), 73.15 + "raw memory operations should have control edge"); 73.16 + } 73.17 +#endif 73.18 // Count FPU ops and common calls, implements item (3) 73.19 switch( nop ) { 73.20 // Count all float operations that may use FPU
74.1 --- a/src/share/vm/opto/graphKit.cpp Thu Jun 24 15:38:42 2010 -0700 74.2 +++ b/src/share/vm/opto/graphKit.cpp Mon Jun 28 12:03:05 2010 -0400 74.3 @@ -1789,9 +1789,10 @@ 74.4 74.5 void GraphKit::increment_counter(Node* counter_addr) { 74.6 int adr_type = Compile::AliasIdxRaw; 74.7 - Node* cnt = make_load(NULL, counter_addr, TypeInt::INT, T_INT, adr_type); 74.8 + Node* ctrl = control(); 74.9 + Node* cnt = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type); 74.10 Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1))); 74.11 - store_to_memory( NULL, counter_addr, incr, T_INT, adr_type ); 74.12 + store_to_memory( ctrl, counter_addr, incr, T_INT, adr_type ); 74.13 } 74.14 74.15 74.16 @@ -2771,11 +2772,7 @@ 74.17 // Update the counter for this lock. Don't bother using an atomic 74.18 // operation since we don't require absolute accuracy. 74.19 lock->create_lock_counter(map()->jvms()); 74.20 - int adr_type = Compile::AliasIdxRaw; 74.21 - Node* counter_addr = makecon(TypeRawPtr::make(lock->counter()->addr())); 74.22 - Node* cnt = make_load(NULL, counter_addr, TypeInt::INT, T_INT, adr_type); 74.23 - Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1))); 74.24 - store_to_memory(control(), counter_addr, incr, T_INT, adr_type); 74.25 + increment_counter(lock->counter()->addr()); 74.26 } 74.27 #endif 74.28
75.1 --- a/src/share/vm/opto/library_call.cpp Thu Jun 24 15:38:42 2010 -0700 75.2 +++ b/src/share/vm/opto/library_call.cpp Mon Jun 28 12:03:05 2010 -0400 75.3 @@ -3512,8 +3512,7 @@ 75.4 75.5 // Get the header out of the object, use LoadMarkNode when available 75.6 Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); 75.7 - Node* header = make_load(NULL, header_addr, TypeRawPtr::BOTTOM, T_ADDRESS); 75.8 - header = _gvn.transform( new (C, 2) CastP2XNode(NULL, header) ); 75.9 + Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type()); 75.10 75.11 // Test the header to see if it is unlocked. 75.12 Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); 75.13 @@ -5202,7 +5201,7 @@ 75.14 // super_check_offset, for the desired klass. 75.15 int sco_offset = Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc); 75.16 Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset); 75.17 - Node* n3 = new(C, 3) LoadINode(NULL, immutable_memory(), p3, TypeRawPtr::BOTTOM); 75.18 + Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr()); 75.19 Node* check_offset = _gvn.transform(n3); 75.20 Node* check_value = dest_elem_klass; 75.21
76.1 --- a/src/share/vm/opto/macro.cpp Thu Jun 24 15:38:42 2010 -0700 76.2 +++ b/src/share/vm/opto/macro.cpp Mon Jun 28 12:03:05 2010 -0400 76.3 @@ -1431,7 +1431,7 @@ 76.4 Node* mark_node = NULL; 76.5 // For now only enable fast locking for non-array types 76.6 if (UseBiasedLocking && (length == NULL)) { 76.7 - mark_node = make_load(NULL, rawmem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeRawPtr::BOTTOM, T_ADDRESS); 76.8 + mark_node = make_load(control, rawmem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeRawPtr::BOTTOM, T_ADDRESS); 76.9 } else { 76.10 mark_node = makecon(TypeRawPtr::make((address)markOopDesc::prototype())); 76.11 }
77.1 --- a/src/share/vm/opto/memnode.cpp Thu Jun 24 15:38:42 2010 -0700 77.2 +++ b/src/share/vm/opto/memnode.cpp Mon Jun 28 12:03:05 2010 -0400 77.3 @@ -815,6 +815,16 @@ 77.4 } 77.5 #endif 77.6 77.7 +#ifdef ASSERT 77.8 +//----------------------------is_immutable_value------------------------------- 77.9 +// Helper function to allow a raw load without control edge for some cases 77.10 +bool LoadNode::is_immutable_value(Node* adr) { 77.11 + return (adr->is_AddP() && adr->in(AddPNode::Base)->is_top() && 77.12 + adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && 77.13 + (adr->in(AddPNode::Offset)->find_intptr_t_con(-1) == 77.14 + in_bytes(JavaThread::osthread_offset()))); 77.15 +} 77.16 +#endif 77.17 77.18 //----------------------------LoadNode::make----------------------------------- 77.19 // Polymorphic factory method: 77.20 @@ -828,6 +838,11 @@ 77.21 assert(!(adr_type->isa_aryptr() && 77.22 adr_type->offset() == arrayOopDesc::length_offset_in_bytes()), 77.23 "use LoadRangeNode instead"); 77.24 + // Check control edge of raw loads 77.25 + assert( ctl != NULL || C->get_alias_index(adr_type) != Compile::AliasIdxRaw || 77.26 + // oop will be recorded in oop map if load crosses safepoint 77.27 + rt->isa_oopptr() || is_immutable_value(adr), 77.28 + "raw memory operations should have control edge"); 77.29 switch (bt) { 77.30 case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() ); 77.31 case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() ); 77.32 @@ -2064,6 +2079,8 @@ 77.33 // Polymorphic factory method: 77.34 StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, BasicType bt ) { 77.35 Compile* C = gvn.C; 77.36 + assert( C->get_alias_index(adr_type) != Compile::AliasIdxRaw || 77.37 + ctl != NULL, "raw memory operations should have control edge"); 77.38 77.39 switch (bt) { 77.40 case T_BOOLEAN:
78.1 --- a/src/share/vm/opto/memnode.hpp Thu Jun 24 15:38:42 2010 -0700 78.2 +++ b/src/share/vm/opto/memnode.hpp Mon Jun 28 12:03:05 2010 -0400 78.3 @@ -189,6 +189,10 @@ 78.4 #ifndef PRODUCT 78.5 virtual void dump_spec(outputStream *st) const; 78.6 #endif 78.7 +#ifdef ASSERT 78.8 + // Helper function to allow a raw load without control edge for some cases 78.9 + static bool is_immutable_value(Node* adr); 78.10 +#endif 78.11 protected: 78.12 const Type* load_array_final_field(const TypeKlassPtr *tkls, 78.13 ciKlass* klass) const;
79.1 --- a/src/share/vm/opto/parse1.cpp Thu Jun 24 15:38:42 2010 -0700 79.2 +++ b/src/share/vm/opto/parse1.cpp Mon Jun 28 12:03:05 2010 -0400 79.3 @@ -88,15 +88,16 @@ 79.4 Node *local_addrs_base) { 79.5 Node *mem = memory(Compile::AliasIdxRaw); 79.6 Node *adr = basic_plus_adr( local_addrs_base, local_addrs, -index*wordSize ); 79.7 + Node *ctl = control(); 79.8 79.9 // Very similar to LoadNode::make, except we handle un-aligned longs and 79.10 // doubles on Sparc. Intel can handle them just fine directly. 79.11 Node *l; 79.12 switch( bt ) { // Signature is flattened 79.13 - case T_INT: l = new (C, 3) LoadINode( 0, mem, adr, TypeRawPtr::BOTTOM ); break; 79.14 - case T_FLOAT: l = new (C, 3) LoadFNode( 0, mem, adr, TypeRawPtr::BOTTOM ); break; 79.15 - case T_ADDRESS: l = new (C, 3) LoadPNode( 0, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ); break; 79.16 - case T_OBJECT: l = new (C, 3) LoadPNode( 0, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break; 79.17 + case T_INT: l = new (C, 3) LoadINode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break; 79.18 + case T_FLOAT: l = new (C, 3) LoadFNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break; 79.19 + case T_ADDRESS: l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ); break; 79.20 + case T_OBJECT: l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break; 79.21 case T_LONG: 79.22 case T_DOUBLE: { 79.23 // Since arguments are in reverse order, the argument address 'adr' 79.24 @@ -104,12 +105,12 @@ 79.25 adr = basic_plus_adr( local_addrs_base, local_addrs, -(index+1)*wordSize ); 79.26 if( Matcher::misaligned_doubles_ok ) { 79.27 l = (bt == T_DOUBLE) 79.28 - ? (Node*)new (C, 3) LoadDNode( 0, mem, adr, TypeRawPtr::BOTTOM ) 79.29 - : (Node*)new (C, 3) LoadLNode( 0, mem, adr, TypeRawPtr::BOTTOM ); 79.30 + ? (Node*)new (C, 3) LoadDNode( ctl, mem, adr, TypeRawPtr::BOTTOM ) 79.31 + : (Node*)new (C, 3) LoadLNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); 79.32 } else { 79.33 l = (bt == T_DOUBLE) 79.34 - ? (Node*)new (C, 3) LoadD_unalignedNode( 0, mem, adr, TypeRawPtr::BOTTOM ) 79.35 - : (Node*)new (C, 3) LoadL_unalignedNode( 0, mem, adr, TypeRawPtr::BOTTOM ); 79.36 + ? (Node*)new (C, 3) LoadD_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM ) 79.37 + : (Node*)new (C, 3) LoadL_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); 79.38 } 79.39 break; 79.40 }
80.1 --- a/src/share/vm/opto/parse2.cpp Thu Jun 24 15:38:42 2010 -0700 80.2 +++ b/src/share/vm/opto/parse2.cpp Mon Jun 28 12:03:05 2010 -0400 80.3 @@ -1324,33 +1324,21 @@ 80.4 case Bytecodes::_ldc_w: 80.5 case Bytecodes::_ldc2_w: 80.6 // If the constant is unresolved, run this BC once in the interpreter. 80.7 - if (iter().is_unresolved_string()) { 80.8 - uncommon_trap(Deoptimization::make_trap_request 80.9 - (Deoptimization::Reason_unloaded, 80.10 - Deoptimization::Action_reinterpret, 80.11 - iter().get_constant_index()), 80.12 - NULL, "unresolved_string"); 80.13 - break; 80.14 - } else { 80.15 + { 80.16 ciConstant constant = iter().get_constant(); 80.17 - if (constant.basic_type() == T_OBJECT) { 80.18 - ciObject* c = constant.as_object(); 80.19 - if (c->is_klass()) { 80.20 - // The constant returned for a klass is the ciKlass for the 80.21 - // entry. We want the java_mirror so get it. 80.22 - ciKlass* klass = c->as_klass(); 80.23 - if (klass->is_loaded()) { 80.24 - constant = ciConstant(T_OBJECT, klass->java_mirror()); 80.25 - } else { 80.26 - uncommon_trap(Deoptimization::make_trap_request 80.27 - (Deoptimization::Reason_unloaded, 80.28 - Deoptimization::Action_reinterpret, 80.29 - iter().get_constant_index()), 80.30 - NULL, "unresolved_klass"); 80.31 - break; 80.32 - } 80.33 - } 80.34 + if (constant.basic_type() == T_OBJECT && 80.35 + !constant.as_object()->is_loaded()) { 80.36 + int index = iter().get_constant_pool_index(); 80.37 + constantTag tag = iter().get_constant_pool_tag(index); 80.38 + uncommon_trap(Deoptimization::make_trap_request 80.39 + (Deoptimization::Reason_unloaded, 80.40 + Deoptimization::Action_reinterpret, 80.41 + index), 80.42 + NULL, tag.internal_name()); 80.43 + break; 80.44 } 80.45 + assert(constant.basic_type() != T_OBJECT || !constant.as_object()->is_klass(), 80.46 + "must be java_mirror of klass"); 80.47 bool pushed = push_constant(constant, true); 80.48 guarantee(pushed, "must be possible to push this constant"); 80.49 }
81.1 --- a/src/share/vm/prims/jvm.h Thu Jun 24 15:38:42 2010 -0700 81.2 +++ b/src/share/vm/prims/jvm.h Mon Jun 28 12:03:05 2010 -0400 81.3 @@ -1044,7 +1044,22 @@ 81.4 JVM_CONSTANT_Fieldref, 81.5 JVM_CONSTANT_Methodref, 81.6 JVM_CONSTANT_InterfaceMethodref, 81.7 - JVM_CONSTANT_NameAndType 81.8 + JVM_CONSTANT_NameAndType, 81.9 + JVM_CONSTANT_MethodHandle = 15, // JSR 292 81.10 + JVM_CONSTANT_MethodType = 16 // JSR 292 81.11 +}; 81.12 + 81.13 +/* JVM_CONSTANT_MethodHandle subtypes */ 81.14 +enum { 81.15 + JVM_REF_getField = 1, 81.16 + JVM_REF_getStatic = 2, 81.17 + JVM_REF_putField = 3, 81.18 + JVM_REF_putStatic = 4, 81.19 + JVM_REF_invokeVirtual = 5, 81.20 + JVM_REF_invokeStatic = 6, 81.21 + JVM_REF_invokeSpecial = 7, 81.22 + JVM_REF_newInvokeSpecial = 8, 81.23 + JVM_REF_invokeInterface = 9 81.24 }; 81.25 81.26 /* Used in the newarray instruction. */
82.1 --- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Thu Jun 24 15:38:42 2010 -0700 82.2 +++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Mon Jun 28 12:03:05 2010 -0400 82.3 @@ -217,21 +217,21 @@ 82.4 82.5 class nmethodDesc: public CHeapObj { 82.6 private: 82.7 - methodHandle _method; 82.8 + jmethodID _jmethod_id; 82.9 address _code_begin; 82.10 address _code_end; 82.11 jvmtiAddrLocationMap* _map; 82.12 jint _map_length; 82.13 public: 82.14 - nmethodDesc(methodHandle method, address code_begin, address code_end, 82.15 + nmethodDesc(jmethodID jmethod_id, address code_begin, address code_end, 82.16 jvmtiAddrLocationMap* map, jint map_length) { 82.17 - _method = method; 82.18 + _jmethod_id = jmethod_id; 82.19 _code_begin = code_begin; 82.20 _code_end = code_end; 82.21 _map = map; 82.22 _map_length = map_length; 82.23 } 82.24 - methodHandle method() const { return _method; } 82.25 + jmethodID jmethod_id() const { return _jmethod_id; } 82.26 address code_begin() const { return _code_begin; } 82.27 address code_end() const { return _code_end; } 82.28 jvmtiAddrLocationMap* map() const { return _map; } 82.29 @@ -323,8 +323,7 @@ 82.30 JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &map, &map_length); 82.31 82.32 // record the nmethod details 82.33 - methodHandle mh(nm->method()); 82.34 - nmethodDesc* snm = new nmethodDesc(mh, 82.35 + nmethodDesc* snm = new nmethodDesc(nm->get_and_cache_jmethod_id(), 82.36 nm->code_begin(), 82.37 nm->code_end(), 82.38 map, 82.39 @@ -367,8 +366,7 @@ 82.40 // iterate over the list and post an event for each nmethod 82.41 nmethodDesc* nm_desc = collector.first(); 82.42 while (nm_desc != NULL) { 82.43 - methodOop method = nm_desc->method()(); 82.44 - jmethodID mid = method->jmethod_id(); 82.45 + jmethodID mid = nm_desc->jmethod_id(); 82.46 assert(mid != NULL, "checking"); 82.47 JvmtiExport::post_compiled_method_load(env, mid, 82.48 (jint)(nm_desc->code_end() - nm_desc->code_begin()),
83.1 --- a/src/share/vm/prims/methodComparator.cpp Thu Jun 24 15:38:42 2010 -0700 83.2 +++ b/src/share/vm/prims/methodComparator.cpp Mon Jun 28 12:03:05 2010 -0400 83.3 @@ -163,10 +163,10 @@ 83.4 83.5 case Bytecodes::_ldc : // fall through 83.6 case Bytecodes::_ldc_w : { 83.7 - Bytecode_loadconstant* ldc_old = Bytecode_loadconstant_at(_s_old->method()(), _s_old->bcp()); 83.8 - Bytecode_loadconstant* ldc_new = Bytecode_loadconstant_at(_s_new->method()(), _s_new->bcp()); 83.9 - int cpi_old = ldc_old->index(); 83.10 - int cpi_new = ldc_new->index(); 83.11 + Bytecode_loadconstant* ldc_old = Bytecode_loadconstant_at(_s_old->method(), _s_old->bci()); 83.12 + Bytecode_loadconstant* ldc_new = Bytecode_loadconstant_at(_s_new->method(), _s_new->bci()); 83.13 + int cpi_old = ldc_old->pool_index(); 83.14 + int cpi_new = ldc_new->pool_index(); 83.15 constantTag tag_old = _old_cp->tag_at(cpi_old); 83.16 constantTag tag_new = _new_cp->tag_at(cpi_new); 83.17 if (tag_old.is_int() || tag_old.is_float()) { 83.18 @@ -187,12 +187,30 @@ 83.19 if (strcmp(_old_cp->string_at_noresolve(cpi_old), 83.20 _new_cp->string_at_noresolve(cpi_new)) != 0) 83.21 return false; 83.22 - } else { // tag_old should be klass - 4881222 83.23 + } else if (tag_old.is_klass() || tag_old.is_unresolved_klass()) { 83.24 + // tag_old should be klass - 4881222 83.25 if (! (tag_new.is_unresolved_klass() || tag_new.is_klass())) 83.26 return false; 83.27 if (_old_cp->klass_at_noresolve(cpi_old) != 83.28 _new_cp->klass_at_noresolve(cpi_new)) 83.29 return false; 83.30 + } else if (tag_old.is_method_type() && tag_new.is_method_type()) { 83.31 + int mti_old = _old_cp->method_type_index_at(cpi_old); 83.32 + int mti_new = _new_cp->method_type_index_at(cpi_new); 83.33 + if ((_old_cp->symbol_at(mti_old) != _new_cp->symbol_at(mti_new))) 83.34 + return false; 83.35 + } else if (tag_old.is_method_handle() && tag_new.is_method_handle()) { 83.36 + if (_old_cp->method_handle_ref_kind_at(cpi_old) != 83.37 + _new_cp->method_handle_ref_kind_at(cpi_new)) 83.38 + return false; 83.39 + int mhi_old = _old_cp->method_handle_index_at(cpi_old); 83.40 + int mhi_new = _new_cp->method_handle_index_at(cpi_new); 83.41 + if ((_old_cp->uncached_klass_ref_at_noresolve(mhi_old) != _new_cp->uncached_klass_ref_at_noresolve(mhi_new)) || 83.42 + (_old_cp->uncached_name_ref_at(mhi_old) != _new_cp->uncached_name_ref_at(mhi_new)) || 83.43 + (_old_cp->uncached_signature_ref_at(mhi_old) != _new_cp->uncached_signature_ref_at(mhi_new))) 83.44 + return false; 83.45 + } else { 83.46 + return false; // unknown tag 83.47 } 83.48 break; 83.49 }
84.1 --- a/src/share/vm/runtime/arguments.cpp Thu Jun 24 15:38:42 2010 -0700 84.2 +++ b/src/share/vm/runtime/arguments.cpp Mon Jun 28 12:03:05 2010 -0400 84.3 @@ -1376,11 +1376,6 @@ 84.4 } 84.5 no_shared_spaces(); 84.6 84.7 - // Set the maximum pause time goal to be a reasonable default. 84.8 - if (FLAG_IS_DEFAULT(MaxGCPauseMillis)) { 84.9 - FLAG_SET_DEFAULT(MaxGCPauseMillis, 200); 84.10 - } 84.11 - 84.12 if (FLAG_IS_DEFAULT(MarkStackSize)) { 84.13 FLAG_SET_DEFAULT(MarkStackSize, 128 * TASKQUEUE_SIZE); 84.14 }
85.1 --- a/src/share/vm/runtime/globals.hpp Thu Jun 24 15:38:42 2010 -0700 85.2 +++ b/src/share/vm/runtime/globals.hpp Mon Jun 28 12:03:05 2010 -0400 85.3 @@ -1975,7 +1975,7 @@ 85.4 "Adaptive size policy maximum GC pause time goal in msec, " \ 85.5 "or (G1 Only) the max. GC time per MMU time slice") \ 85.6 \ 85.7 - product(intx, GCPauseIntervalMillis, 500, \ 85.8 + product(uintx, GCPauseIntervalMillis, 0, \ 85.9 "Time slice for MMU specification") \ 85.10 \ 85.11 product(uintx, MaxGCMinorPauseMillis, max_uintx, \
86.1 --- a/src/share/vm/runtime/jniHandles.cpp Thu Jun 24 15:38:42 2010 -0700 86.2 +++ b/src/share/vm/runtime/jniHandles.cpp Mon Jun 28 12:03:05 2010 -0400 86.3 @@ -66,6 +66,7 @@ 86.4 86.5 86.6 jobject JNIHandles::make_global(Handle obj) { 86.7 + assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); 86.8 jobject res = NULL; 86.9 if (!obj.is_null()) { 86.10 // ignore null handles 86.11 @@ -81,6 +82,7 @@ 86.12 86.13 86.14 jobject JNIHandles::make_weak_global(Handle obj) { 86.15 + assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); 86.16 jobject res = NULL; 86.17 if (!obj.is_null()) { 86.18 // ignore null handles
87.1 --- a/src/share/vm/runtime/sharedRuntime.cpp Thu Jun 24 15:38:42 2010 -0700 87.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp Mon Jun 28 12:03:05 2010 -0400 87.3 @@ -779,7 +779,7 @@ 87.4 87.5 // Find bytecode 87.6 Bytecode_invoke* bytecode = Bytecode_invoke_at(caller, bci); 87.7 - bc = bytecode->adjusted_invoke_code(); 87.8 + bc = bytecode->java_code(); 87.9 int bytecode_index = bytecode->index(); 87.10 87.11 // Find receiver for non-static call
88.1 --- a/src/share/vm/runtime/stubRoutines.cpp Thu Jun 24 15:38:42 2010 -0700 88.2 +++ b/src/share/vm/runtime/stubRoutines.cpp Mon Jun 28 12:03:05 2010 -0400 88.3 @@ -135,28 +135,32 @@ 88.4 static void test_arraycopy_func(address func, int alignment) { 88.5 int v = 0xcc; 88.6 int v2 = 0x11; 88.7 - jlong lbuffer[2]; 88.8 - jlong lbuffer2[2]; 88.9 - address buffer = (address) lbuffer; 88.10 - address buffer2 = (address) lbuffer2; 88.11 + jlong lbuffer[8]; 88.12 + jlong lbuffer2[8]; 88.13 + address fbuffer = (address) lbuffer; 88.14 + address fbuffer2 = (address) lbuffer2; 88.15 unsigned int i; 88.16 for (i = 0; i < sizeof(lbuffer); i++) { 88.17 - buffer[i] = v; buffer2[i] = v2; 88.18 + fbuffer[i] = v; fbuffer2[i] = v2; 88.19 } 88.20 + // C++ does not guarantee jlong[] array alignment to 8 bytes. 88.21 + // Use middle of array to check that memory before it is not modified. 88.22 + address buffer = (address) round_to((intptr_t)&lbuffer[4], BytesPerLong); 88.23 + address buffer2 = (address) round_to((intptr_t)&lbuffer2[4], BytesPerLong); 88.24 // do an aligned copy 88.25 ((arraycopy_fn)func)(buffer, buffer2, 0); 88.26 for (i = 0; i < sizeof(lbuffer); i++) { 88.27 - assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything"); 88.28 + assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything"); 88.29 } 88.30 // adjust destination alignment 88.31 ((arraycopy_fn)func)(buffer, buffer2 + alignment, 0); 88.32 for (i = 0; i < sizeof(lbuffer); i++) { 88.33 - assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything"); 88.34 + assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything"); 88.35 } 88.36 // adjust source alignment 88.37 ((arraycopy_fn)func)(buffer + alignment, buffer2, 0); 88.38 for (i = 0; i < sizeof(lbuffer); i++) { 88.39 - assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything"); 88.40 + assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything"); 88.41 } 88.42 } 88.43 #endif 88.44 @@ -183,7 +187,7 @@ 88.45 test_arraycopy_func(arrayof_##type##_arraycopy(), sizeof(HeapWord)); \ 88.46 test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord)) 88.47 88.48 - // Make sure all the arraycopy stubs properly handle zeros 88.49 + // Make sure all the arraycopy stubs properly handle zero count 88.50 TEST_ARRAYCOPY(jbyte); 88.51 TEST_ARRAYCOPY(jshort); 88.52 TEST_ARRAYCOPY(jint); 88.53 @@ -191,6 +195,25 @@ 88.54 88.55 #undef TEST_ARRAYCOPY 88.56 88.57 +#define TEST_COPYRTN(type) \ 88.58 + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_##type##s_atomic), sizeof(type)); \ 88.59 + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::arrayof_conjoint_##type##s), (int)MAX2(sizeof(HeapWord), sizeof(type))) 88.60 + 88.61 + // Make sure all the copy runtime routines properly handle zero count 88.62 + TEST_COPYRTN(jbyte); 88.63 + TEST_COPYRTN(jshort); 88.64 + TEST_COPYRTN(jint); 88.65 + TEST_COPYRTN(jlong); 88.66 + 88.67 +#undef TEST_COPYRTN 88.68 + 88.69 + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_words), sizeof(HeapWord)); 88.70 + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words), sizeof(HeapWord)); 88.71 + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words_atomic), sizeof(HeapWord)); 88.72 + // Aligned to BytesPerLong 88.73 + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_conjoint_words), sizeof(jlong)); 88.74 + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_disjoint_words), sizeof(jlong)); 88.75 + 88.76 #endif 88.77 } 88.78 88.79 @@ -221,15 +244,13 @@ 88.80 #ifndef PRODUCT 88.81 SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy 88.82 #endif // !PRODUCT 88.83 - assert(count != 0, "count should be non-zero"); 88.84 - Copy::conjoint_bytes_atomic(src, dest, count); 88.85 + Copy::conjoint_jbytes_atomic(src, dest, count); 88.86 JRT_END 88.87 88.88 JRT_LEAF(void, StubRoutines::jshort_copy(jshort* src, jshort* dest, size_t count)) 88.89 #ifndef PRODUCT 88.90 SharedRuntime::_jshort_array_copy_ctr++; // Slow-path short/char array copy 88.91 #endif // !PRODUCT 88.92 - assert(count != 0, "count should be non-zero"); 88.93 Copy::conjoint_jshorts_atomic(src, dest, count); 88.94 JRT_END 88.95 88.96 @@ -237,7 +258,6 @@ 88.97 #ifndef PRODUCT 88.98 SharedRuntime::_jint_array_copy_ctr++; // Slow-path int/float array copy 88.99 #endif // !PRODUCT 88.100 - assert(count != 0, "count should be non-zero"); 88.101 Copy::conjoint_jints_atomic(src, dest, count); 88.102 JRT_END 88.103 88.104 @@ -245,7 +265,6 @@ 88.105 #ifndef PRODUCT 88.106 SharedRuntime::_jlong_array_copy_ctr++; // Slow-path long/double array copy 88.107 #endif // !PRODUCT 88.108 - assert(count != 0, "count should be non-zero"); 88.109 Copy::conjoint_jlongs_atomic(src, dest, count); 88.110 JRT_END 88.111 88.112 @@ -263,15 +282,13 @@ 88.113 #ifndef PRODUCT 88.114 SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy 88.115 #endif // !PRODUCT 88.116 - assert(count != 0, "count should be non-zero"); 88.117 - Copy::arrayof_conjoint_bytes(src, dest, count); 88.118 + Copy::arrayof_conjoint_jbytes(src, dest, count); 88.119 JRT_END 88.120 88.121 JRT_LEAF(void, StubRoutines::arrayof_jshort_copy(HeapWord* src, HeapWord* dest, size_t count)) 88.122 #ifndef PRODUCT 88.123 SharedRuntime::_jshort_array_copy_ctr++; // Slow-path short/char array copy 88.124 #endif // !PRODUCT 88.125 - assert(count != 0, "count should be non-zero"); 88.126 Copy::arrayof_conjoint_jshorts(src, dest, count); 88.127 JRT_END 88.128 88.129 @@ -279,7 +296,6 @@ 88.130 #ifndef PRODUCT 88.131 SharedRuntime::_jint_array_copy_ctr++; // Slow-path int/float array copy 88.132 #endif // !PRODUCT 88.133 - assert(count != 0, "count should be non-zero"); 88.134 Copy::arrayof_conjoint_jints(src, dest, count); 88.135 JRT_END 88.136 88.137 @@ -287,7 +303,6 @@ 88.138 #ifndef PRODUCT 88.139 SharedRuntime::_jlong_array_copy_ctr++; // Slow-path int/float array copy 88.140 #endif // !PRODUCT 88.141 - assert(count != 0, "count should be non-zero"); 88.142 Copy::arrayof_conjoint_jlongs(src, dest, count); 88.143 JRT_END 88.144
89.1 --- a/src/share/vm/runtime/sweeper.cpp Thu Jun 24 15:38:42 2010 -0700 89.2 +++ b/src/share/vm/runtime/sweeper.cpp Mon Jun 28 12:03:05 2010 -0400 89.3 @@ -26,7 +26,7 @@ 89.4 # include "incls/_sweeper.cpp.incl" 89.5 89.6 long NMethodSweeper::_traversals = 0; // No. of stack traversals performed 89.7 -CodeBlob* NMethodSweeper::_current = NULL; // Current nmethod 89.8 +nmethod* NMethodSweeper::_current = NULL; // Current nmethod 89.9 int NMethodSweeper::_seen = 0 ; // No. of blobs we have currently processed in current pass of CodeCache 89.10 int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass 89.11 89.12 @@ -171,20 +171,16 @@ 89.13 // Since we will give up the CodeCache_lock, always skip ahead to an nmethod. 89.14 // Other blobs can be deleted by other threads 89.15 // Read next before we potentially delete current 89.16 - CodeBlob* next = CodeCache::next_nmethod(_current); 89.17 + nmethod* next = CodeCache::next_nmethod(_current); 89.18 89.19 // Now ready to process nmethod and give up CodeCache_lock 89.20 { 89.21 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 89.22 - process_nmethod((nmethod *)_current); 89.23 + process_nmethod(_current); 89.24 } 89.25 _seen++; 89.26 _current = next; 89.27 } 89.28 - 89.29 - // Skip forward to the next nmethod (if any). Code blobs other than nmethods 89.30 - // can be freed async to us and make _current invalid while we sleep. 89.31 - _current = CodeCache::next_nmethod(_current); 89.32 } 89.33 89.34 if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) {
90.1 --- a/src/share/vm/runtime/sweeper.hpp Thu Jun 24 15:38:42 2010 -0700 90.2 +++ b/src/share/vm/runtime/sweeper.hpp Mon Jun 28 12:03:05 2010 -0400 90.3 @@ -29,7 +29,7 @@ 90.4 90.5 class NMethodSweeper : public AllStatic { 90.6 static long _traversals; // Stack traversal count 90.7 - static CodeBlob* _current; // Current nmethod 90.8 + static nmethod* _current; // Current nmethod 90.9 static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache 90.10 static int _invocations; // No. of invocations left until we are completed with this pass 90.11
91.1 --- a/src/share/vm/runtime/thread.cpp Thu Jun 24 15:38:42 2010 -0700 91.2 +++ b/src/share/vm/runtime/thread.cpp Mon Jun 28 12:03:05 2010 -0400 91.3 @@ -2700,7 +2700,7 @@ 91.4 if (in_bytes(size_in_bytes) != 0) { 91.5 _popframe_preserved_args = NEW_C_HEAP_ARRAY(char, in_bytes(size_in_bytes)); 91.6 _popframe_preserved_args_size = in_bytes(size_in_bytes); 91.7 - Copy::conjoint_bytes(start, _popframe_preserved_args, _popframe_preserved_args_size); 91.8 + Copy::conjoint_jbytes(start, _popframe_preserved_args, _popframe_preserved_args_size); 91.9 } 91.10 } 91.11
92.1 --- a/src/share/vm/runtime/vframeArray.cpp Thu Jun 24 15:38:42 2010 -0700 92.2 +++ b/src/share/vm/runtime/vframeArray.cpp Mon Jun 28 12:03:05 2010 -0400 92.3 @@ -355,9 +355,9 @@ 92.4 } else { 92.5 base = iframe()->interpreter_frame_expression_stack(); 92.6 } 92.7 - Copy::conjoint_bytes(saved_args, 92.8 - base, 92.9 - popframe_preserved_args_size_in_bytes); 92.10 + Copy::conjoint_jbytes(saved_args, 92.11 + base, 92.12 + popframe_preserved_args_size_in_bytes); 92.13 thread->popframe_free_preserved_args(); 92.14 } 92.15 }
93.1 --- a/src/share/vm/runtime/virtualspace.cpp Thu Jun 24 15:38:42 2010 -0700 93.2 +++ b/src/share/vm/runtime/virtualspace.cpp Mon Jun 28 12:03:05 2010 -0400 93.3 @@ -111,6 +111,35 @@ 93.4 return result; 93.5 } 93.6 93.7 +// Helper method. 93.8 +static bool failed_to_reserve_as_requested(char* base, char* requested_address, 93.9 + const size_t size, bool special) 93.10 +{ 93.11 + if (base == requested_address || requested_address == NULL) 93.12 + return false; // did not fail 93.13 + 93.14 + if (base != NULL) { 93.15 + // Different reserve address may be acceptable in other cases 93.16 + // but for compressed oops heap should be at requested address. 93.17 + assert(UseCompressedOops, "currently requested address used only for compressed oops"); 93.18 + if (PrintCompressedOopsMode) { 93.19 + tty->cr(); 93.20 + tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address); 93.21 + } 93.22 + // OS ignored requested address. Try different address. 93.23 + if (special) { 93.24 + if (!os::release_memory_special(base, size)) { 93.25 + fatal("os::release_memory_special failed"); 93.26 + } 93.27 + } else { 93.28 + if (!os::release_memory(base, size)) { 93.29 + fatal("os::release_memory failed"); 93.30 + } 93.31 + } 93.32 + } 93.33 + return true; 93.34 +} 93.35 + 93.36 ReservedSpace::ReservedSpace(const size_t prefix_size, 93.37 const size_t prefix_align, 93.38 const size_t suffix_size, 93.39 @@ -129,6 +158,10 @@ 93.40 assert((suffix_align & prefix_align - 1) == 0, 93.41 "suffix_align not divisible by prefix_align"); 93.42 93.43 + // Assert that if noaccess_prefix is used, it is the same as prefix_align. 93.44 + assert(noaccess_prefix == 0 || 93.45 + noaccess_prefix == prefix_align, "noaccess prefix wrong"); 93.46 + 93.47 // Add in noaccess_prefix to prefix_size; 93.48 const size_t adjusted_prefix_size = prefix_size + noaccess_prefix; 93.49 const size_t size = adjusted_prefix_size + suffix_size; 93.50 @@ -150,15 +183,16 @@ 93.51 _noaccess_prefix = 0; 93.52 _executable = false; 93.53 93.54 - // Assert that if noaccess_prefix is used, it is the same as prefix_align. 93.55 - assert(noaccess_prefix == 0 || 93.56 - noaccess_prefix == prefix_align, "noaccess prefix wrong"); 93.57 - 93.58 // Optimistically try to reserve the exact size needed. 93.59 char* addr; 93.60 if (requested_address != 0) { 93.61 - addr = os::attempt_reserve_memory_at(size, 93.62 - requested_address-noaccess_prefix); 93.63 + requested_address -= noaccess_prefix; // adjust address 93.64 + assert(requested_address != NULL, "huge noaccess prefix?"); 93.65 + addr = os::attempt_reserve_memory_at(size, requested_address); 93.66 + if (failed_to_reserve_as_requested(addr, requested_address, size, false)) { 93.67 + // OS ignored requested address. Try different address. 93.68 + addr = NULL; 93.69 + } 93.70 } else { 93.71 addr = os::reserve_memory(size, NULL, prefix_align); 93.72 } 93.73 @@ -222,11 +256,20 @@ 93.74 bool special = large && !os::can_commit_large_page_memory(); 93.75 char* base = NULL; 93.76 93.77 + if (requested_address != 0) { 93.78 + requested_address -= noaccess_prefix; // adjust requested address 93.79 + assert(requested_address != NULL, "huge noaccess prefix?"); 93.80 + } 93.81 + 93.82 if (special) { 93.83 93.84 base = os::reserve_memory_special(size, requested_address, executable); 93.85 93.86 if (base != NULL) { 93.87 + if (failed_to_reserve_as_requested(base, requested_address, size, true)) { 93.88 + // OS ignored requested address. Try different address. 93.89 + return; 93.90 + } 93.91 // Check alignment constraints 93.92 if (alignment > 0) { 93.93 assert((uintptr_t) base % alignment == 0, 93.94 @@ -235,6 +278,13 @@ 93.95 _special = true; 93.96 } else { 93.97 // failed; try to reserve regular memory below 93.98 + if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) || 93.99 + !FLAG_IS_DEFAULT(LargePageSizeInBytes))) { 93.100 + if (PrintCompressedOopsMode) { 93.101 + tty->cr(); 93.102 + tty->print_cr("Reserve regular memory without large pages."); 93.103 + } 93.104 + } 93.105 } 93.106 } 93.107 93.108 @@ -248,8 +298,11 @@ 93.109 // important. If available space is not detected, return NULL. 93.110 93.111 if (requested_address != 0) { 93.112 - base = os::attempt_reserve_memory_at(size, 93.113 - requested_address-noaccess_prefix); 93.114 + base = os::attempt_reserve_memory_at(size, requested_address); 93.115 + if (failed_to_reserve_as_requested(base, requested_address, size, false)) { 93.116 + // OS ignored requested address. Try different address. 93.117 + base = NULL; 93.118 + } 93.119 } else { 93.120 base = os::reserve_memory(size, NULL, alignment); 93.121 } 93.122 @@ -365,7 +418,12 @@ 93.123 } 93.124 93.125 void ReservedSpace::protect_noaccess_prefix(const size_t size) { 93.126 - // If there is noaccess prefix, return. 93.127 + assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL && 93.128 + (size_t(_base + _size) > OopEncodingHeapMax) && 93.129 + Universe::narrow_oop_use_implicit_null_checks()), 93.130 + "noaccess_prefix should be used only with non zero based compressed oops"); 93.131 + 93.132 + // If there is no noaccess prefix, return. 93.133 if (_noaccess_prefix == 0) return; 93.134 93.135 assert(_noaccess_prefix >= (size_t)os::vm_page_size(), 93.136 @@ -377,6 +435,10 @@ 93.137 _special)) { 93.138 fatal("cannot protect protection page"); 93.139 } 93.140 + if (PrintCompressedOopsMode) { 93.141 + tty->cr(); 93.142 + tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix); 93.143 + } 93.144 93.145 _base += _noaccess_prefix; 93.146 _size -= _noaccess_prefix;
94.1 --- a/src/share/vm/utilities/constantTag.cpp Thu Jun 24 15:38:42 2010 -0700 94.2 +++ b/src/share/vm/utilities/constantTag.cpp Mon Jun 28 12:03:05 2010 -0400 94.3 @@ -28,56 +28,85 @@ 94.4 #ifndef PRODUCT 94.5 94.6 void constantTag::print_on(outputStream* st) const { 94.7 + st->print(internal_name()); 94.8 +} 94.9 + 94.10 +#endif // PRODUCT 94.11 + 94.12 +BasicType constantTag::basic_type() const { 94.13 switch (_tag) { 94.14 + case JVM_CONSTANT_Integer : 94.15 + return T_INT; 94.16 + case JVM_CONSTANT_Float : 94.17 + return T_FLOAT; 94.18 + case JVM_CONSTANT_Long : 94.19 + return T_LONG; 94.20 + case JVM_CONSTANT_Double : 94.21 + return T_DOUBLE; 94.22 + 94.23 case JVM_CONSTANT_Class : 94.24 - st->print("Class"); 94.25 - break; 94.26 - case JVM_CONSTANT_Fieldref : 94.27 - st->print("Field"); 94.28 - break; 94.29 - case JVM_CONSTANT_Methodref : 94.30 - st->print("Method"); 94.31 - break; 94.32 - case JVM_CONSTANT_InterfaceMethodref : 94.33 - st->print("InterfaceMethod"); 94.34 - break; 94.35 case JVM_CONSTANT_String : 94.36 - st->print("String"); 94.37 - break; 94.38 - case JVM_CONSTANT_Integer : 94.39 - st->print("Integer"); 94.40 - break; 94.41 - case JVM_CONSTANT_Float : 94.42 - st->print("Float"); 94.43 - break; 94.44 - case JVM_CONSTANT_Long : 94.45 - st->print("Long"); 94.46 - break; 94.47 - case JVM_CONSTANT_Double : 94.48 - st->print("Double"); 94.49 - break; 94.50 - case JVM_CONSTANT_NameAndType : 94.51 - st->print("NameAndType"); 94.52 - break; 94.53 - case JVM_CONSTANT_Utf8 : 94.54 - st->print("Utf8"); 94.55 - break; 94.56 case JVM_CONSTANT_UnresolvedClass : 94.57 - st->print("Unresolved class"); 94.58 - break; 94.59 + case JVM_CONSTANT_UnresolvedClassInError : 94.60 case JVM_CONSTANT_ClassIndex : 94.61 - st->print("Unresolved class index"); 94.62 - break; 94.63 case JVM_CONSTANT_UnresolvedString : 94.64 - st->print("Unresolved string"); 94.65 - break; 94.66 case JVM_CONSTANT_StringIndex : 94.67 - st->print("Unresolved string index"); 94.68 - break; 94.69 + case JVM_CONSTANT_MethodHandle : 94.70 + case JVM_CONSTANT_MethodType : 94.71 + case JVM_CONSTANT_Object : 94.72 + return T_OBJECT; 94.73 default: 94.74 ShouldNotReachHere(); 94.75 - break; 94.76 + return T_ILLEGAL; 94.77 } 94.78 } 94.79 94.80 -#endif // PRODUCT 94.81 + 94.82 + 94.83 +const char* constantTag::internal_name() const { 94.84 + switch (_tag) { 94.85 + case JVM_CONSTANT_Invalid : 94.86 + return "Invalid index"; 94.87 + case JVM_CONSTANT_Class : 94.88 + return "Class"; 94.89 + case JVM_CONSTANT_Fieldref : 94.90 + return "Field"; 94.91 + case JVM_CONSTANT_Methodref : 94.92 + return "Method"; 94.93 + case JVM_CONSTANT_InterfaceMethodref : 94.94 + return "InterfaceMethod"; 94.95 + case JVM_CONSTANT_String : 94.96 + return "String"; 94.97 + case JVM_CONSTANT_Integer : 94.98 + return "Integer"; 94.99 + case JVM_CONSTANT_Float : 94.100 + return "Float"; 94.101 + case JVM_CONSTANT_Long : 94.102 + return "Long"; 94.103 + case JVM_CONSTANT_Double : 94.104 + return "Double"; 94.105 + case JVM_CONSTANT_NameAndType : 94.106 + return "NameAndType"; 94.107 + case JVM_CONSTANT_MethodHandle : 94.108 + return "MethodHandle"; 94.109 + case JVM_CONSTANT_MethodType : 94.110 + return "MethodType"; 94.111 + case JVM_CONSTANT_Object : 94.112 + return "Object"; 94.113 + case JVM_CONSTANT_Utf8 : 94.114 + return "Utf8"; 94.115 + case JVM_CONSTANT_UnresolvedClass : 94.116 + return "Unresolved Class"; 94.117 + case JVM_CONSTANT_UnresolvedClassInError : 94.118 + return "Unresolved Class Error"; 94.119 + case JVM_CONSTANT_ClassIndex : 94.120 + return "Unresolved Class Index"; 94.121 + case JVM_CONSTANT_UnresolvedString : 94.122 + return "Unresolved String"; 94.123 + case JVM_CONSTANT_StringIndex : 94.124 + return "Unresolved String Index"; 94.125 + default: 94.126 + ShouldNotReachHere(); 94.127 + return "Illegal"; 94.128 + } 94.129 +}
95.1 --- a/src/share/vm/utilities/constantTag.hpp Thu Jun 24 15:38:42 2010 -0700 95.2 +++ b/src/share/vm/utilities/constantTag.hpp Mon Jun 28 12:03:05 2010 -0400 95.3 @@ -78,13 +78,24 @@ 95.4 bool is_field_or_method() const { return is_field() || is_method() || is_interface_method(); } 95.5 bool is_symbol() const { return is_utf8(); } 95.6 95.7 + bool is_method_type() const { return _tag == JVM_CONSTANT_MethodType; } 95.8 + bool is_method_handle() const { return _tag == JVM_CONSTANT_MethodHandle; } 95.9 + 95.10 + constantTag() { 95.11 + _tag = JVM_CONSTANT_Invalid; 95.12 + } 95.13 constantTag(jbyte tag) { 95.14 assert((tag >= 0 && tag <= JVM_CONSTANT_NameAndType) || 95.15 + (tag >= JVM_CONSTANT_MethodHandle && tag <= JVM_CONSTANT_MethodType) || 95.16 (tag >= JVM_CONSTANT_InternalMin && tag <= JVM_CONSTANT_InternalMax), "Invalid constant tag"); 95.17 _tag = tag; 95.18 } 95.19 95.20 jbyte value() { return _tag; } 95.21 95.22 + BasicType basic_type() const; // if used with ldc, what kind of value gets pushed? 95.23 + 95.24 + const char* internal_name() const; // for error reporting 95.25 + 95.26 void print_on(outputStream* st) const PRODUCT_RETURN; 95.27 };
96.1 --- a/src/share/vm/utilities/copy.cpp Thu Jun 24 15:38:42 2010 -0700 96.2 +++ b/src/share/vm/utilities/copy.cpp Mon Jun 28 12:03:05 2010 -0400 96.3 @@ -48,7 +48,7 @@ 96.4 Copy::conjoint_jshorts_atomic((jshort*) src, (jshort*) dst, size / sizeof(jshort)); 96.5 } else { 96.6 // Not aligned, so no need to be atomic. 96.7 - Copy::conjoint_bytes((void*) src, (void*) dst, size); 96.8 + Copy::conjoint_jbytes((void*) src, (void*) dst, size); 96.9 } 96.10 } 96.11
97.1 --- a/src/share/vm/utilities/copy.hpp Thu Jun 24 15:38:42 2010 -0700 97.2 +++ b/src/share/vm/utilities/copy.hpp Mon Jun 28 12:03:05 2010 -0400 97.3 @@ -73,6 +73,9 @@ 97.4 // whole alignment units. E.g., if BytesPerLong is 2x word alignment, an odd 97.5 // count may copy an extra word. In the arrayof case, we are allowed to copy 97.6 // only the number of copy units specified. 97.7 + // 97.8 + // All callees check count for 0. 97.9 + // 97.10 97.11 // HeapWords 97.12 97.13 @@ -99,7 +102,6 @@ 97.14 // Object-aligned words, conjoint, not atomic on each word 97.15 static void aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) { 97.16 assert_params_aligned(from, to); 97.17 - assert_non_zero(count); 97.18 pd_aligned_conjoint_words(from, to, count); 97.19 } 97.20 97.21 @@ -107,49 +109,42 @@ 97.22 static void aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) { 97.23 assert_params_aligned(from, to); 97.24 assert_disjoint(from, to, count); 97.25 - assert_non_zero(count); 97.26 pd_aligned_disjoint_words(from, to, count); 97.27 } 97.28 97.29 // bytes, jshorts, jints, jlongs, oops 97.30 97.31 // bytes, conjoint, not atomic on each byte (not that it matters) 97.32 - static void conjoint_bytes(void* from, void* to, size_t count) { 97.33 - assert_non_zero(count); 97.34 + static void conjoint_jbytes(void* from, void* to, size_t count) { 97.35 pd_conjoint_bytes(from, to, count); 97.36 } 97.37 97.38 // bytes, conjoint, atomic on each byte (not that it matters) 97.39 - static void conjoint_bytes_atomic(void* from, void* to, size_t count) { 97.40 - assert_non_zero(count); 97.41 + static void conjoint_jbytes_atomic(void* from, void* to, size_t count) { 97.42 pd_conjoint_bytes(from, to, count); 97.43 } 97.44 97.45 // jshorts, conjoint, atomic on each jshort 97.46 static void conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { 97.47 assert_params_ok(from, to, LogBytesPerShort); 97.48 - assert_non_zero(count); 97.49 pd_conjoint_jshorts_atomic(from, to, count); 97.50 } 97.51 97.52 // jints, conjoint, atomic on each jint 97.53 static void conjoint_jints_atomic(jint* from, jint* to, size_t count) { 97.54 assert_params_ok(from, to, LogBytesPerInt); 97.55 - assert_non_zero(count); 97.56 pd_conjoint_jints_atomic(from, to, count); 97.57 } 97.58 97.59 // jlongs, conjoint, atomic on each jlong 97.60 static void conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) { 97.61 assert_params_ok(from, to, LogBytesPerLong); 97.62 - assert_non_zero(count); 97.63 pd_conjoint_jlongs_atomic(from, to, count); 97.64 } 97.65 97.66 // oops, conjoint, atomic on each oop 97.67 static void conjoint_oops_atomic(oop* from, oop* to, size_t count) { 97.68 assert_params_ok(from, to, LogBytesPerHeapOop); 97.69 - assert_non_zero(count); 97.70 pd_conjoint_oops_atomic(from, to, count); 97.71 } 97.72 97.73 @@ -157,7 +152,6 @@ 97.74 static void conjoint_oops_atomic(narrowOop* from, narrowOop* to, size_t count) { 97.75 assert(sizeof(narrowOop) == sizeof(jint), "this cast is wrong"); 97.76 assert_params_ok(from, to, LogBytesPerInt); 97.77 - assert_non_zero(count); 97.78 pd_conjoint_jints_atomic((jint*)from, (jint*)to, count); 97.79 } 97.80 97.81 @@ -168,36 +162,31 @@ 97.82 static void conjoint_memory_atomic(void* from, void* to, size_t size); 97.83 97.84 // bytes, conjoint array, atomic on each byte (not that it matters) 97.85 - static void arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) { 97.86 - assert_non_zero(count); 97.87 + static void arrayof_conjoint_jbytes(HeapWord* from, HeapWord* to, size_t count) { 97.88 pd_arrayof_conjoint_bytes(from, to, count); 97.89 } 97.90 97.91 // jshorts, conjoint array, atomic on each jshort 97.92 static void arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) { 97.93 assert_params_ok(from, to, LogBytesPerShort); 97.94 - assert_non_zero(count); 97.95 pd_arrayof_conjoint_jshorts(from, to, count); 97.96 } 97.97 97.98 // jints, conjoint array, atomic on each jint 97.99 static void arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) { 97.100 assert_params_ok(from, to, LogBytesPerInt); 97.101 - assert_non_zero(count); 97.102 pd_arrayof_conjoint_jints(from, to, count); 97.103 } 97.104 97.105 // jlongs, conjoint array, atomic on each jlong 97.106 static void arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) { 97.107 assert_params_ok(from, to, LogBytesPerLong); 97.108 - assert_non_zero(count); 97.109 pd_arrayof_conjoint_jlongs(from, to, count); 97.110 } 97.111 97.112 // oops, conjoint array, atomic on each oop 97.113 static void arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) { 97.114 assert_params_ok(from, to, LogBytesPerHeapOop); 97.115 - assert_non_zero(count); 97.116 pd_arrayof_conjoint_oops(from, to, count); 97.117 } 97.118 97.119 @@ -319,14 +308,6 @@ 97.120 #endif 97.121 } 97.122 97.123 - static void assert_non_zero(size_t count) { 97.124 -#ifdef ASSERT 97.125 - if (count == 0) { 97.126 - basic_fatal("count must be non-zero"); 97.127 - } 97.128 -#endif 97.129 - } 97.130 - 97.131 static void assert_byte_count_ok(size_t byte_count, size_t unit_size) { 97.132 #ifdef ASSERT 97.133 if ((size_t)round_to(byte_count, unit_size) != byte_count) {