Wed, 22 Dec 2010 12:24:40 -0500
Merge
agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Tue Dec 21 23:39:42 2010 -0500 1.2 +++ b/.hgtags Wed Dec 22 12:24:40 2010 -0500 1.3 @@ -134,4 +134,5 @@ 1.4 5484e7c53fa7da5e869902437ee08a9ae10c1c69 jdk7-b119 1.5 f5603a6e50422046ebc0d2f1671d55cb8f1bf1e9 jdk7-b120 1.6 3f3653ab7af8dc1ddb9fa75dad56bf94f89e81a8 jdk7-b121 1.7 +3a548dc9cb456110ca8fc1514441a8c3bda0014d jdk7-b122 1.8 5484e7c53fa7da5e869902437ee08a9ae10c1c69 hs20-b03
2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Tue Dec 21 23:39:42 2010 -0500 2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Wed Dec 22 12:24:40 2010 -0500 2.3 @@ -60,10 +60,7 @@ 2.4 headerSize = type.getSize(); 2.5 elementSize = 0; 2.6 // fetch constants: 2.7 - MULTI_OPERAND_COUNT_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_multi_operand_count_offset").intValue(); 2.8 - MULTI_OPERAND_BASE_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_multi_operand_base_offset").intValue(); 2.9 INDY_BSM_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_bsm_offset").intValue(); 2.10 - INDY_NT_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_nt_offset").intValue(); 2.11 INDY_ARGC_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argc_offset").intValue(); 2.12 INDY_ARGV_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argv_offset").intValue(); 2.13 } 2.14 @@ -83,10 +80,7 @@ 2.15 private static long headerSize; 2.16 private static long elementSize; 2.17 2.18 - private static int MULTI_OPERAND_COUNT_OFFSET; 2.19 - private static int MULTI_OPERAND_BASE_OFFSET; 2.20 private static int INDY_BSM_OFFSET; 2.21 - private static int INDY_NT_OFFSET; 2.22 private static int INDY_ARGC_OFFSET; 2.23 private static int INDY_ARGV_OFFSET; 2.24 2.25 @@ -296,20 +290,23 @@ 2.26 } 2.27 2.28 /** Lookup for multi-operand (InvokeDynamic) entries. */ 2.29 - public int[] getMultiOperandsAt(int i) { 2.30 + public short[] getBootstrapSpecifierAt(int i) { 2.31 if (Assert.ASSERTS_ENABLED) { 2.32 Assert.that(getTagAt(i).isInvokeDynamic(), "Corrupted constant pool"); 2.33 } 2.34 - int pos = this.getIntAt(i); 2.35 - int countPos = pos + MULTI_OPERAND_COUNT_OFFSET; // == pos-1 2.36 - int basePos = pos + MULTI_OPERAND_BASE_OFFSET; // == pos 2.37 - if (countPos < 0) return null; // safety first 2.38 + if (getTagAt(i).value() == JVM_CONSTANT_InvokeDynamicTrans) 2.39 + return null; 2.40 + int bsmSpec = extractLowShortFromInt(this.getIntAt(i)); 2.41 TypeArray operands = getOperands(); 2.42 if (operands == null) return null; // safety first 2.43 - int length = operands.getIntAt(countPos); 2.44 - int[] values = new int[length]; 2.45 - for (int j = 0; j < length; j++) { 2.46 - values[j] = operands.getIntAt(basePos+j); 2.47 + int basePos = VM.getVM().buildIntFromShorts(operands.getShortAt(bsmSpec * 2 + 0), 2.48 + operands.getShortAt(bsmSpec * 2 + 1)); 2.49 + int argv = basePos + INDY_ARGV_OFFSET; 2.50 + int argc = operands.getShortAt(basePos + INDY_ARGC_OFFSET); 2.51 + int endPos = argv + argc; 2.52 + short[] values = new short[endPos - basePos]; 2.53 + for (int j = 0; j < values.length; j++) { 2.54 + values[j] = operands.getShortAt(basePos+j); 2.55 } 2.56 return values; 2.57 } 2.58 @@ -334,6 +331,7 @@ 2.59 case JVM_CONSTANT_MethodHandle: return "JVM_CONSTANT_MethodHandle"; 2.60 case JVM_CONSTANT_MethodType: return "JVM_CONSTANT_MethodType"; 2.61 case JVM_CONSTANT_InvokeDynamic: return "JVM_CONSTANT_InvokeDynamic"; 2.62 + case JVM_CONSTANT_InvokeDynamicTrans: return "JVM_CONSTANT_InvokeDynamic/transitional"; 2.63 case JVM_CONSTANT_Invalid: return "JVM_CONSTANT_Invalid"; 2.64 case JVM_CONSTANT_UnresolvedClass: return "JVM_CONSTANT_UnresolvedClass"; 2.65 case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError"; 2.66 @@ -393,6 +391,7 @@ 2.67 case JVM_CONSTANT_MethodHandle: 2.68 case JVM_CONSTANT_MethodType: 2.69 case JVM_CONSTANT_InvokeDynamic: 2.70 + case JVM_CONSTANT_InvokeDynamicTrans: 2.71 visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); 2.72 break; 2.73 } 2.74 @@ -556,19 +555,16 @@ 2.75 break; 2.76 } 2.77 2.78 + case JVM_CONSTANT_InvokeDynamicTrans: 2.79 case JVM_CONSTANT_InvokeDynamic: { 2.80 dos.writeByte(cpConstType); 2.81 - int[] values = getMultiOperandsAt(ci); 2.82 - for (int vn = 0; vn < values.length; vn++) { 2.83 - dos.writeShort(values[vn]); 2.84 - } 2.85 - int bootstrapMethodIndex = values[INDY_BSM_OFFSET]; 2.86 - int nameAndTypeIndex = values[INDY_NT_OFFSET]; 2.87 - int argumentCount = values[INDY_ARGC_OFFSET]; 2.88 - assert(INDY_ARGV_OFFSET + argumentCount == values.length); 2.89 - if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bootstrapMethodIndex 2.90 - + ", N&T = " + nameAndTypeIndex 2.91 - + ", argc = " + argumentCount); 2.92 + int value = getIntAt(ci); 2.93 + short bsmIndex = (short) extractLowShortFromInt(value); 2.94 + short nameAndTypeIndex = (short) extractHighShortFromInt(value); 2.95 + dos.writeShort(bsmIndex); 2.96 + dos.writeShort(nameAndTypeIndex); 2.97 + if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bsmIndex 2.98 + + ", N&T = " + nameAndTypeIndex); 2.99 break; 2.100 } 2.101
3.1 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Tue Dec 21 23:39:42 2010 -0500 3.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Wed Dec 22 12:24:40 2010 -0500 3.3 @@ -321,13 +321,16 @@ 3.4 break; 3.5 } 3.6 3.7 + case JVM_CONSTANT_InvokeDynamicTrans: 3.8 case JVM_CONSTANT_InvokeDynamic: { 3.9 dos.writeByte(cpConstType); 3.10 - int[] values = cpool.getMultiOperandsAt(ci); 3.11 - for (int vn = 0; vn < values.length; vn++) { 3.12 - dos.writeShort(values[vn]); 3.13 - } 3.14 - if (DEBUG) debugMessage("CP[" + ci + "] = INDY indexes = " + Arrays.toString(values)); 3.15 + int value = cpool.getIntAt(ci); 3.16 + short bsmIndex = (short) extractLowShortFromInt(value); 3.17 + short nameAndTypeIndex = (short) extractHighShortFromInt(value); 3.18 + dos.writeShort(bsmIndex); 3.19 + dos.writeShort(nameAndTypeIndex); 3.20 + if (DEBUG) debugMessage("CP[" + ci + "] = INDY bsm = " + 3.21 + bsmIndex + ", N&T = " + nameAndTypeIndex); 3.22 break; 3.23 } 3.24
4.1 --- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Tue Dec 21 23:39:42 2010 -0500 4.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Wed Dec 22 12:24:40 2010 -0500 4.3 @@ -463,7 +463,8 @@ 4.4 return buf.toString(); 4.5 } 4.6 4.7 - private String genListOfShort(int[] values) { 4.8 + private String genListOfShort(short[] values) { 4.9 + if (values == null || values.length == 0) return ""; 4.10 Formatter buf = new Formatter(genHTML); 4.11 buf.append('['); 4.12 for (int i = 0; i < values.length; i++) { 4.13 @@ -597,9 +598,11 @@ 4.14 buf.cell(Integer.toString(cpool.getIntAt(index))); 4.15 break; 4.16 4.17 + case JVM_CONSTANT_InvokeDynamicTrans: 4.18 case JVM_CONSTANT_InvokeDynamic: 4.19 buf.cell("JVM_CONSTANT_InvokeDynamic"); 4.20 - buf.cell(genListOfShort(cpool.getMultiOperandsAt(index))); 4.21 + buf.cell(genLowHighShort(cpool.getIntAt(index)) + 4.22 + genListOfShort(cpool.getBootstrapSpecifierAt(index))); 4.23 break; 4.24 4.25 default:
5.1 --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Tue Dec 21 23:39:42 2010 -0500 5.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Wed Dec 22 12:24:40 2010 -0500 5.3 @@ -40,7 +40,7 @@ 5.4 private static int JVM_CONSTANT_NameAndType = 12; 5.5 private static int JVM_CONSTANT_MethodHandle = 15; // JSR 292 5.6 private static int JVM_CONSTANT_MethodType = 16; // JSR 292 5.7 - // static int JVM_CONSTANT_InvokeDynamicTrans = 17; // JSR 292, only occurs in old class files 5.8 + private static int JVM_CONSTANT_InvokeDynamicTrans = 17; // JSR 292, only occurs in old class files 5.9 private static int JVM_CONSTANT_InvokeDynamic = 18; // JSR 292 5.10 private static int JVM_CONSTANT_Invalid = 0; // For bad value initialization 5.11 private static int JVM_CONSTANT_UnresolvedClass = 100; // Temporary tag until actual use 5.12 @@ -67,6 +67,8 @@ 5.13 this.tag = tag; 5.14 } 5.15 5.16 + public int value() { return tag; } 5.17 + 5.18 public boolean isKlass() { return tag == JVM_CONSTANT_Class; } 5.19 public boolean isField () { return tag == JVM_CONSTANT_Fieldref; } 5.20 public boolean isMethod() { return tag == JVM_CONSTANT_Methodref; } 5.21 @@ -81,6 +83,7 @@ 5.22 public boolean isMethodHandle() { return tag == JVM_CONSTANT_MethodHandle; } 5.23 public boolean isMethodType() { return tag == JVM_CONSTANT_MethodType; } 5.24 public boolean isInvokeDynamic() { return tag == JVM_CONSTANT_InvokeDynamic; } 5.25 + public boolean isInvokeDynamicTrans() { return tag == JVM_CONSTANT_InvokeDynamicTrans; } 5.26 5.27 public boolean isInvalid() { return tag == JVM_CONSTANT_Invalid; } 5.28
6.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp Tue Dec 21 23:39:42 2010 -0500 6.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp Wed Dec 22 12:24:40 2010 -0500 6.3 @@ -909,10 +909,10 @@ 6.4 #if defined(COMPILER2) && !defined(_LP64) 6.5 // Save & restore possible 64-bit Long arguments in G-regs 6.6 sllx(L0,32,G2); // Move old high G1 bits high in G2 6.7 - sllx(G1, 0,G1); // Clear current high G1 bits 6.8 + srl(G1, 0,G1); // Clear current high G1 bits 6.9 or3 (G1,G2,G1); // Recover 64-bit G1 6.10 sllx(L6,32,G2); // Move old high G4 bits high in G2 6.11 - sllx(G4, 0,G4); // Clear current high G4 bits 6.12 + srl(G4, 0,G4); // Clear current high G4 bits 6.13 or3 (G4,G2,G4); // Recover 64-bit G4 6.14 #endif 6.15 restore(O0, 0, G2_thread); 6.16 @@ -1443,6 +1443,45 @@ 6.17 } 6.18 } 6.19 6.20 +int MacroAssembler::size_of_set64(jlong value) { 6.21 + v9_dep(); 6.22 + 6.23 + int hi = (int)(value >> 32); 6.24 + int lo = (int)(value & ~0); 6.25 + int count = 0; 6.26 + 6.27 + // (Matcher::isSimpleConstant64 knows about the following optimizations.) 6.28 + if (Assembler::is_simm13(lo) && value == lo) { 6.29 + count++; 6.30 + } else if (hi == 0) { 6.31 + count++; 6.32 + if (low10(lo) != 0) 6.33 + count++; 6.34 + } 6.35 + else if (hi == -1) { 6.36 + count += 2; 6.37 + } 6.38 + else if (lo == 0) { 6.39 + if (Assembler::is_simm13(hi)) { 6.40 + count++; 6.41 + } else { 6.42 + count++; 6.43 + if (low10(hi) != 0) 6.44 + count++; 6.45 + } 6.46 + count++; 6.47 + } 6.48 + else { 6.49 + count += 2; 6.50 + if (low10(hi) != 0) 6.51 + count++; 6.52 + if (low10(lo) != 0) 6.53 + count++; 6.54 + count += 2; 6.55 + } 6.56 + return count; 6.57 +} 6.58 + 6.59 // compute size in bytes of sparc frame, given 6.60 // number of extraWords 6.61 int MacroAssembler::total_frame_size_in_bytes(int extraWords) {
7.1 --- a/src/cpu/sparc/vm/assembler_sparc.hpp Tue Dec 21 23:39:42 2010 -0500 7.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Wed Dec 22 12:24:40 2010 -0500 7.3 @@ -1621,6 +1621,10 @@ 7.4 7.5 void sub( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | rs2(s2) ); } 7.6 void sub( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 7.7 + 7.8 + // Note: offset is added to s2. 7.9 + inline void sub(Register s1, RegisterOrConstant s2, Register d, int offset = 0); 7.10 + 7.11 void subcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | rs2(s2) ); } 7.12 void subcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 7.13 void subc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | rs2(s2) ); } 7.14 @@ -1798,6 +1802,7 @@ 7.15 // branches that use right instruction for v8 vs. v9 7.16 inline void br( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); 7.17 inline void br( Condition c, bool a, Predict p, Label& L ); 7.18 + 7.19 inline void fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); 7.20 inline void fb( Condition c, bool a, Predict p, Label& L ); 7.21 7.22 @@ -1894,6 +1899,9 @@ 7.23 void patchable_set(intptr_t value, Register d); 7.24 void set64(jlong value, Register d, Register tmp); 7.25 7.26 + // Compute size of set64. 7.27 + static int size_of_set64(jlong value); 7.28 + 7.29 // sign-extend 32 to 64 7.30 inline void signx( Register s, Register d ) { sra( s, G0, d); } 7.31 inline void signx( Register d ) { sra( d, G0, d); }
8.1 --- a/src/cpu/sparc/vm/assembler_sparc.inline.hpp Tue Dec 21 23:39:42 2010 -0500 8.2 +++ b/src/cpu/sparc/vm/assembler_sparc.inline.hpp Wed Dec 22 12:24:40 2010 -0500 8.3 @@ -328,6 +328,11 @@ 8.4 inline void Assembler::stdcq( int crd, Register s1, Register s2) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | rs2(s2) ); } 8.5 inline void Assembler::stdcq( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } 8.6 8.7 +inline void Assembler::sub(Register s1, RegisterOrConstant s2, Register d, int offset) { 8.8 + if (s2.is_register()) sub(s1, s2.as_register(), d); 8.9 + else { sub(s1, s2.as_constant() + offset, d); offset = 0; } 8.10 + if (offset != 0) sub(d, offset, d); 8.11 +} 8.12 8.13 // pp 231 8.14
9.1 --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Tue Dec 21 23:39:42 2010 -0500 9.2 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Wed Dec 22 12:24:40 2010 -0500 9.3 @@ -434,7 +434,7 @@ 9.4 9.5 Register pre_val_reg = pre_val()->as_register(); 9.6 9.7 - ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false); 9.8 + ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/); 9.9 if (__ is_in_wdisp16_range(_continuation)) { 9.10 __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, 9.11 pre_val_reg, _continuation);
10.1 --- a/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp Tue Dec 21 23:39:42 2010 -0500 10.2 +++ b/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp Wed Dec 22 12:24:40 2010 -0500 10.3 @@ -155,4 +155,7 @@ 10.4 static bool is_caller_save_register (LIR_Opr reg); 10.5 static bool is_caller_save_register (Register r); 10.6 10.7 + static int nof_caller_save_cpu_regs() { return pd_nof_caller_save_cpu_regs_frame_map; } 10.8 + static int last_cpu_reg() { return pd_last_cpu_reg; } 10.9 + 10.10 #endif // CPU_SPARC_VM_C1_FRAMEMAP_SPARC_HPP
11.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Tue Dec 21 23:39:42 2010 -0500 11.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Dec 22 12:24:40 2010 -0500 11.3 @@ -100,6 +100,11 @@ 11.4 return false; 11.5 } 11.6 11.7 + if (UseCompressedOops) { 11.8 + if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false; 11.9 + if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false; 11.10 + } 11.11 + 11.12 if (dst->is_register()) { 11.13 if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) { 11.14 return !PatchALot; 11.15 @@ -253,7 +258,7 @@ 11.16 int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position 11.17 int count_offset = java_lang_String:: count_offset_in_bytes(); 11.18 11.19 - __ ld_ptr(str0, value_offset, tmp0); 11.20 + __ load_heap_oop(str0, value_offset, tmp0); 11.21 __ ld(str0, offset_offset, tmp2); 11.22 __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0); 11.23 __ ld(str0, count_offset, str0); 11.24 @@ -262,7 +267,7 @@ 11.25 // str1 may be null 11.26 add_debug_info_for_null_check_here(info); 11.27 11.28 - __ ld_ptr(str1, value_offset, tmp1); 11.29 + __ load_heap_oop(str1, value_offset, tmp1); 11.30 __ add(tmp0, tmp2, tmp0); 11.31 11.32 __ ld(str1, offset_offset, tmp2); 11.33 @@ -766,7 +771,7 @@ 11.34 11.35 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { 11.36 add_debug_info_for_null_check_here(op->info()); 11.37 - __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch); 11.38 + __ load_klass(O0, G3_scratch); 11.39 if (__ is_simm13(op->vtable_offset())) { 11.40 __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method); 11.41 } else { 11.42 @@ -780,138 +785,17 @@ 11.43 // the peephole pass fills the delay slot 11.44 } 11.45 11.46 - 11.47 -// load with 32-bit displacement 11.48 -int LIR_Assembler::load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo *info) { 11.49 - int load_offset = code_offset(); 11.50 - if (Assembler::is_simm13(disp)) { 11.51 - if (info != NULL) add_debug_info_for_null_check_here(info); 11.52 - switch(ld_type) { 11.53 - case T_BOOLEAN: // fall through 11.54 - case T_BYTE : __ ldsb(s, disp, d); break; 11.55 - case T_CHAR : __ lduh(s, disp, d); break; 11.56 - case T_SHORT : __ ldsh(s, disp, d); break; 11.57 - case T_INT : __ ld(s, disp, d); break; 11.58 - case T_ADDRESS:// fall through 11.59 - case T_ARRAY : // fall through 11.60 - case T_OBJECT: __ ld_ptr(s, disp, d); break; 11.61 - default : ShouldNotReachHere(); 11.62 - } 11.63 - } else { 11.64 - __ set(disp, O7); 11.65 - if (info != NULL) add_debug_info_for_null_check_here(info); 11.66 - load_offset = code_offset(); 11.67 - switch(ld_type) { 11.68 - case T_BOOLEAN: // fall through 11.69 - case T_BYTE : __ ldsb(s, O7, d); break; 11.70 - case T_CHAR : __ lduh(s, O7, d); break; 11.71 - case T_SHORT : __ ldsh(s, O7, d); break; 11.72 - case T_INT : __ ld(s, O7, d); break; 11.73 - case T_ADDRESS:// fall through 11.74 - case T_ARRAY : // fall through 11.75 - case T_OBJECT: __ ld_ptr(s, O7, d); break; 11.76 - default : ShouldNotReachHere(); 11.77 - } 11.78 - } 11.79 - if (ld_type == T_ARRAY || ld_type == T_OBJECT) __ verify_oop(d); 11.80 - return load_offset; 11.81 -} 11.82 - 11.83 - 11.84 -// store with 32-bit displacement 11.85 -void LIR_Assembler::store(Register value, Register base, int offset, BasicType type, CodeEmitInfo *info) { 11.86 - if (Assembler::is_simm13(offset)) { 11.87 - if (info != NULL) add_debug_info_for_null_check_here(info); 11.88 - switch (type) { 11.89 - case T_BOOLEAN: // fall through 11.90 - case T_BYTE : __ stb(value, base, offset); break; 11.91 - case T_CHAR : __ sth(value, base, offset); break; 11.92 - case T_SHORT : __ sth(value, base, offset); break; 11.93 - case T_INT : __ stw(value, base, offset); break; 11.94 - case T_ADDRESS:// fall through 11.95 - case T_ARRAY : // fall through 11.96 - case T_OBJECT: __ st_ptr(value, base, offset); break; 11.97 - default : ShouldNotReachHere(); 11.98 - } 11.99 - } else { 11.100 - __ set(offset, O7); 11.101 - if (info != NULL) add_debug_info_for_null_check_here(info); 11.102 - switch (type) { 11.103 - case T_BOOLEAN: // fall through 11.104 - case T_BYTE : __ stb(value, base, O7); break; 11.105 - case T_CHAR : __ sth(value, base, O7); break; 11.106 - case T_SHORT : __ sth(value, base, O7); break; 11.107 - case T_INT : __ stw(value, base, O7); break; 11.108 - case T_ADDRESS:// fall through 11.109 - case T_ARRAY : //fall through 11.110 - case T_OBJECT: __ st_ptr(value, base, O7); break; 11.111 - default : ShouldNotReachHere(); 11.112 - } 11.113 - } 11.114 - // Note: Do the store before verification as the code might be patched! 11.115 - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(value); 11.116 -} 11.117 - 11.118 - 11.119 -// load float with 32-bit displacement 11.120 -void LIR_Assembler::load(Register s, int disp, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) { 11.121 - FloatRegisterImpl::Width w; 11.122 - switch(ld_type) { 11.123 - case T_FLOAT : w = FloatRegisterImpl::S; break; 11.124 - case T_DOUBLE: w = FloatRegisterImpl::D; break; 11.125 - default : ShouldNotReachHere(); 11.126 - } 11.127 - 11.128 - if (Assembler::is_simm13(disp)) { 11.129 - if (info != NULL) add_debug_info_for_null_check_here(info); 11.130 - if (disp % BytesPerLong != 0 && w == FloatRegisterImpl::D) { 11.131 - __ ldf(FloatRegisterImpl::S, s, disp + BytesPerWord, d->successor()); 11.132 - __ ldf(FloatRegisterImpl::S, s, disp , d); 11.133 - } else { 11.134 - __ ldf(w, s, disp, d); 11.135 - } 11.136 - } else { 11.137 - __ set(disp, O7); 11.138 - if (info != NULL) add_debug_info_for_null_check_here(info); 11.139 - __ ldf(w, s, O7, d); 11.140 - } 11.141 -} 11.142 - 11.143 - 11.144 -// store float with 32-bit displacement 11.145 -void LIR_Assembler::store(FloatRegister value, Register base, int offset, BasicType type, CodeEmitInfo *info) { 11.146 - FloatRegisterImpl::Width w; 11.147 - switch(type) { 11.148 - case T_FLOAT : w = FloatRegisterImpl::S; break; 11.149 - case T_DOUBLE: w = FloatRegisterImpl::D; break; 11.150 - default : ShouldNotReachHere(); 11.151 - } 11.152 - 11.153 - if (Assembler::is_simm13(offset)) { 11.154 - if (info != NULL) add_debug_info_for_null_check_here(info); 11.155 - if (w == FloatRegisterImpl::D && offset % BytesPerLong != 0) { 11.156 - __ stf(FloatRegisterImpl::S, value->successor(), base, offset + BytesPerWord); 11.157 - __ stf(FloatRegisterImpl::S, value , base, offset); 11.158 - } else { 11.159 - __ stf(w, value, base, offset); 11.160 - } 11.161 - } else { 11.162 - __ set(offset, O7); 11.163 - if (info != NULL) add_debug_info_for_null_check_here(info); 11.164 - __ stf(w, value, O7, base); 11.165 - } 11.166 -} 11.167 - 11.168 - 11.169 -int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool unaligned) { 11.170 +int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) { 11.171 int store_offset; 11.172 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { 11.173 assert(!unaligned, "can't handle this"); 11.174 // for offsets larger than a simm13 we setup the offset in O7 11.175 __ set(offset, O7); 11.176 - store_offset = store(from_reg, base, O7, type); 11.177 + store_offset = store(from_reg, base, O7, type, wide); 11.178 } else { 11.179 - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register()); 11.180 + if (type == T_ARRAY || type == T_OBJECT) { 11.181 + __ verify_oop(from_reg->as_register()); 11.182 + } 11.183 store_offset = code_offset(); 11.184 switch (type) { 11.185 case T_BOOLEAN: // fall through 11.186 @@ -934,9 +818,22 @@ 11.187 __ stw(from_reg->as_register_hi(), base, offset + hi_word_offset_in_bytes); 11.188 #endif 11.189 break; 11.190 - case T_ADDRESS:// fall through 11.191 + case T_ADDRESS: 11.192 + __ st_ptr(from_reg->as_register(), base, offset); 11.193 + break; 11.194 case T_ARRAY : // fall through 11.195 - case T_OBJECT: __ st_ptr(from_reg->as_register(), base, offset); break; 11.196 + case T_OBJECT: 11.197 + { 11.198 + if (UseCompressedOops && !wide) { 11.199 + __ encode_heap_oop(from_reg->as_register(), G3_scratch); 11.200 + store_offset = code_offset(); 11.201 + __ stw(G3_scratch, base, offset); 11.202 + } else { 11.203 + __ st_ptr(from_reg->as_register(), base, offset); 11.204 + } 11.205 + break; 11.206 + } 11.207 + 11.208 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, offset); break; 11.209 case T_DOUBLE: 11.210 { 11.211 @@ -958,8 +855,10 @@ 11.212 } 11.213 11.214 11.215 -int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type) { 11.216 - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register()); 11.217 +int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide) { 11.218 + if (type == T_ARRAY || type == T_OBJECT) { 11.219 + __ verify_oop(from_reg->as_register()); 11.220 + } 11.221 int store_offset = code_offset(); 11.222 switch (type) { 11.223 case T_BOOLEAN: // fall through 11.224 @@ -975,9 +874,21 @@ 11.225 __ std(from_reg->as_register_hi(), base, disp); 11.226 #endif 11.227 break; 11.228 - case T_ADDRESS:// fall through 11.229 + case T_ADDRESS: 11.230 + __ st_ptr(from_reg->as_register(), base, disp); 11.231 + break; 11.232 case T_ARRAY : // fall through 11.233 - case T_OBJECT: __ st_ptr(from_reg->as_register(), base, disp); break; 11.234 + case T_OBJECT: 11.235 + { 11.236 + if (UseCompressedOops && !wide) { 11.237 + __ encode_heap_oop(from_reg->as_register(), G3_scratch); 11.238 + store_offset = code_offset(); 11.239 + __ stw(G3_scratch, base, disp); 11.240 + } else { 11.241 + __ st_ptr(from_reg->as_register(), base, disp); 11.242 + } 11.243 + break; 11.244 + } 11.245 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, disp); break; 11.246 case T_DOUBLE: __ stf(FloatRegisterImpl::D, from_reg->as_double_reg(), base, disp); break; 11.247 default : ShouldNotReachHere(); 11.248 @@ -986,14 +897,14 @@ 11.249 } 11.250 11.251 11.252 -int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool unaligned) { 11.253 +int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned) { 11.254 int load_offset; 11.255 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { 11.256 assert(base != O7, "destroying register"); 11.257 assert(!unaligned, "can't handle this"); 11.258 // for offsets larger than a simm13 we setup the offset in O7 11.259 __ set(offset, O7); 11.260 - load_offset = load(base, O7, to_reg, type); 11.261 + load_offset = load(base, O7, to_reg, type, wide); 11.262 } else { 11.263 load_offset = code_offset(); 11.264 switch(type) { 11.265 @@ -1030,9 +941,18 @@ 11.266 #endif 11.267 } 11.268 break; 11.269 - case T_ADDRESS:// fall through 11.270 + case T_ADDRESS: __ ld_ptr(base, offset, to_reg->as_register()); break; 11.271 case T_ARRAY : // fall through 11.272 - case T_OBJECT: __ ld_ptr(base, offset, to_reg->as_register()); break; 11.273 + case T_OBJECT: 11.274 + { 11.275 + if (UseCompressedOops && !wide) { 11.276 + __ lduw(base, offset, to_reg->as_register()); 11.277 + __ decode_heap_oop(to_reg->as_register()); 11.278 + } else { 11.279 + __ ld_ptr(base, offset, to_reg->as_register()); 11.280 + } 11.281 + break; 11.282 + } 11.283 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break; 11.284 case T_DOUBLE: 11.285 { 11.286 @@ -1048,23 +968,34 @@ 11.287 } 11.288 default : ShouldNotReachHere(); 11.289 } 11.290 - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register()); 11.291 + if (type == T_ARRAY || type == T_OBJECT) { 11.292 + __ verify_oop(to_reg->as_register()); 11.293 + } 11.294 } 11.295 return load_offset; 11.296 } 11.297 11.298 11.299 -int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type) { 11.300 +int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide) { 11.301 int load_offset = code_offset(); 11.302 switch(type) { 11.303 case T_BOOLEAN: // fall through 11.304 - case T_BYTE : __ ldsb(base, disp, to_reg->as_register()); break; 11.305 - case T_CHAR : __ lduh(base, disp, to_reg->as_register()); break; 11.306 - case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break; 11.307 - case T_INT : __ ld(base, disp, to_reg->as_register()); break; 11.308 - case T_ADDRESS:// fall through 11.309 + case T_BYTE : __ ldsb(base, disp, to_reg->as_register()); break; 11.310 + case T_CHAR : __ lduh(base, disp, to_reg->as_register()); break; 11.311 + case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break; 11.312 + case T_INT : __ ld(base, disp, to_reg->as_register()); break; 11.313 + case T_ADDRESS: __ ld_ptr(base, disp, to_reg->as_register()); break; 11.314 case T_ARRAY : // fall through 11.315 - case T_OBJECT: __ ld_ptr(base, disp, to_reg->as_register()); break; 11.316 + case T_OBJECT: 11.317 + { 11.318 + if (UseCompressedOops && !wide) { 11.319 + __ lduw(base, disp, to_reg->as_register()); 11.320 + __ decode_heap_oop(to_reg->as_register()); 11.321 + } else { 11.322 + __ ld_ptr(base, disp, to_reg->as_register()); 11.323 + } 11.324 + break; 11.325 + } 11.326 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, disp, to_reg->as_float_reg()); break; 11.327 case T_DOUBLE: __ ldf(FloatRegisterImpl::D, base, disp, to_reg->as_double_reg()); break; 11.328 case T_LONG : 11.329 @@ -1078,60 +1009,28 @@ 11.330 break; 11.331 default : ShouldNotReachHere(); 11.332 } 11.333 - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register()); 11.334 + if (type == T_ARRAY || type == T_OBJECT) { 11.335 + __ verify_oop(to_reg->as_register()); 11.336 + } 11.337 return load_offset; 11.338 } 11.339 11.340 - 11.341 -// load/store with an Address 11.342 -void LIR_Assembler::load(const Address& a, Register d, BasicType ld_type, CodeEmitInfo *info, int offset) { 11.343 - load(a.base(), a.disp() + offset, d, ld_type, info); 11.344 -} 11.345 - 11.346 - 11.347 -void LIR_Assembler::store(Register value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) { 11.348 - store(value, dest.base(), dest.disp() + offset, type, info); 11.349 -} 11.350 - 11.351 - 11.352 -// loadf/storef with an Address 11.353 -void LIR_Assembler::load(const Address& a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info, int offset) { 11.354 - load(a.base(), a.disp() + offset, d, ld_type, info); 11.355 -} 11.356 - 11.357 - 11.358 -void LIR_Assembler::store(FloatRegister value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) { 11.359 - store(value, dest.base(), dest.disp() + offset, type, info); 11.360 -} 11.361 - 11.362 - 11.363 -// load/store with an Address 11.364 -void LIR_Assembler::load(LIR_Address* a, Register d, BasicType ld_type, CodeEmitInfo *info) { 11.365 - load(as_Address(a), d, ld_type, info); 11.366 -} 11.367 - 11.368 - 11.369 -void LIR_Assembler::store(Register value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) { 11.370 - store(value, as_Address(dest), type, info); 11.371 -} 11.372 - 11.373 - 11.374 -// loadf/storef with an Address 11.375 -void LIR_Assembler::load(LIR_Address* a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) { 11.376 - load(as_Address(a), d, ld_type, info); 11.377 -} 11.378 - 11.379 - 11.380 -void LIR_Assembler::store(FloatRegister value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) { 11.381 - store(value, as_Address(dest), type, info); 11.382 -} 11.383 - 11.384 - 11.385 void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { 11.386 LIR_Const* c = src->as_constant_ptr(); 11.387 switch (c->type()) { 11.388 case T_INT: 11.389 - case T_FLOAT: 11.390 + case T_FLOAT: { 11.391 + Register src_reg = O7; 11.392 + int value = c->as_jint_bits(); 11.393 + if (value == 0) { 11.394 + src_reg = G0; 11.395 + } else { 11.396 + __ set(value, O7); 11.397 + } 11.398 + Address addr = frame_map()->address_for_slot(dest->single_stack_ix()); 11.399 + __ stw(src_reg, addr.base(), addr.disp()); 11.400 + break; 11.401 + } 11.402 case T_ADDRESS: { 11.403 Register src_reg = O7; 11.404 int value = c->as_jint_bits(); 11.405 @@ -1141,7 +1040,7 @@ 11.406 __ set(value, O7); 11.407 } 11.408 Address addr = frame_map()->address_for_slot(dest->single_stack_ix()); 11.409 - __ stw(src_reg, addr.base(), addr.disp()); 11.410 + __ st_ptr(src_reg, addr.base(), addr.disp()); 11.411 break; 11.412 } 11.413 case T_OBJECT: { 11.414 @@ -1178,14 +1077,12 @@ 11.415 } 11.416 11.417 11.418 -void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) { 11.419 +void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { 11.420 LIR_Const* c = src->as_constant_ptr(); 11.421 LIR_Address* addr = dest->as_address_ptr(); 11.422 Register base = addr->base()->as_pointer_register(); 11.423 - 11.424 - if (info != NULL) { 11.425 - add_debug_info_for_null_check_here(info); 11.426 - } 11.427 + int offset = -1; 11.428 + 11.429 switch (c->type()) { 11.430 case T_INT: 11.431 case T_FLOAT: 11.432 @@ -1199,10 +1096,10 @@ 11.433 } 11.434 if (addr->index()->is_valid()) { 11.435 assert(addr->disp() == 0, "must be zero"); 11.436 - store(tmp, base, addr->index()->as_pointer_register(), type); 11.437 + offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide); 11.438 } else { 11.439 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); 11.440 - store(tmp, base, addr->disp(), type); 11.441 + offset = store(tmp, base, addr->disp(), type, wide, false); 11.442 } 11.443 break; 11.444 } 11.445 @@ -1212,21 +1109,21 @@ 11.446 assert(Assembler::is_simm13(addr->disp()) && 11.447 Assembler::is_simm13(addr->disp() + 4), "can't handle larger addresses"); 11.448 11.449 - Register tmp = O7; 11.450 + LIR_Opr tmp = FrameMap::O7_opr; 11.451 int value_lo = c->as_jint_lo_bits(); 11.452 if (value_lo == 0) { 11.453 - tmp = G0; 11.454 + tmp = FrameMap::G0_opr; 11.455 } else { 11.456 __ set(value_lo, O7); 11.457 } 11.458 - store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT); 11.459 + offset = store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT, wide, false); 11.460 int value_hi = c->as_jint_hi_bits(); 11.461 if (value_hi == 0) { 11.462 - tmp = G0; 11.463 + tmp = FrameMap::G0_opr; 11.464 } else { 11.465 __ set(value_hi, O7); 11.466 } 11.467 - store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT); 11.468 + offset = store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT, wide, false); 11.469 break; 11.470 } 11.471 case T_OBJECT: { 11.472 @@ -1241,10 +1138,10 @@ 11.473 // handle either reg+reg or reg+disp address 11.474 if (addr->index()->is_valid()) { 11.475 assert(addr->disp() == 0, "must be zero"); 11.476 - store(tmp, base, addr->index()->as_pointer_register(), type); 11.477 + offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide); 11.478 } else { 11.479 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); 11.480 - store(tmp, base, addr->disp(), type); 11.481 + offset = store(tmp, base, addr->disp(), type, wide, false); 11.482 } 11.483 11.484 break; 11.485 @@ -1252,6 +1149,10 @@ 11.486 default: 11.487 Unimplemented(); 11.488 } 11.489 + if (info != NULL) { 11.490 + assert(offset != -1, "offset should've been set"); 11.491 + add_debug_info_for_null_check(offset, info); 11.492 + } 11.493 } 11.494 11.495 11.496 @@ -1336,7 +1237,7 @@ 11.497 assert(to_reg->is_single_cpu(), "Must be a cpu register."); 11.498 11.499 __ set(const_addrlit, O7); 11.500 - load(O7, 0, to_reg->as_register(), T_INT); 11.501 + __ ld(O7, 0, to_reg->as_register()); 11.502 } 11.503 } 11.504 break; 11.505 @@ -1429,7 +1330,7 @@ 11.506 11.507 11.508 void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, 11.509 - LIR_PatchCode patch_code, CodeEmitInfo* info, bool unaligned) { 11.510 + LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool unaligned) { 11.511 11.512 LIR_Address* addr = src_opr->as_address_ptr(); 11.513 LIR_Opr to_reg = dest; 11.514 @@ -1475,16 +1376,15 @@ 11.515 11.516 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); 11.517 if (disp_reg == noreg) { 11.518 - offset = load(src, disp_value, to_reg, type, unaligned); 11.519 + offset = load(src, disp_value, to_reg, type, wide, unaligned); 11.520 } else { 11.521 assert(!unaligned, "can't handle this"); 11.522 - offset = load(src, disp_reg, to_reg, type); 11.523 + offset = load(src, disp_reg, to_reg, type, wide); 11.524 } 11.525 11.526 if (patch != NULL) { 11.527 patching_epilog(patch, patch_code, src, info); 11.528 } 11.529 - 11.530 if (info != NULL) add_debug_info_for_null_check(offset, info); 11.531 } 11.532 11.533 @@ -1518,7 +1418,7 @@ 11.534 } 11.535 11.536 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; 11.537 - load(addr.base(), addr.disp(), dest, dest->type(), unaligned); 11.538 + load(addr.base(), addr.disp(), dest, dest->type(), true /*wide*/, unaligned); 11.539 } 11.540 11.541 11.542 @@ -1530,7 +1430,7 @@ 11.543 addr = frame_map()->address_for_slot(dest->double_stack_ix()); 11.544 } 11.545 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; 11.546 - store(from_reg, addr.base(), addr.disp(), from_reg->type(), unaligned); 11.547 + store(from_reg, addr.base(), addr.disp(), from_reg->type(), true /*wide*/, unaligned); 11.548 } 11.549 11.550 11.551 @@ -1578,7 +1478,7 @@ 11.552 11.553 void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type, 11.554 LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, 11.555 - bool unaligned) { 11.556 + bool wide, bool unaligned) { 11.557 LIR_Address* addr = dest->as_address_ptr(); 11.558 11.559 Register src = addr->base()->as_pointer_register(); 11.560 @@ -1622,10 +1522,10 @@ 11.561 11.562 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); 11.563 if (disp_reg == noreg) { 11.564 - offset = store(from_reg, src, disp_value, type, unaligned); 11.565 + offset = store(from_reg, src, disp_value, type, wide, unaligned); 11.566 } else { 11.567 assert(!unaligned, "can't handle this"); 11.568 - offset = store(from_reg, src, disp_reg, type); 11.569 + offset = store(from_reg, src, disp_reg, type, wide); 11.570 } 11.571 11.572 if (patch != NULL) { 11.573 @@ -2184,13 +2084,13 @@ 11.574 // make sure src and dst are non-null and load array length 11.575 if (flags & LIR_OpArrayCopy::src_null_check) { 11.576 __ tst(src); 11.577 - __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); 11.578 + __ brx(Assembler::equal, false, Assembler::pn, *stub->entry()); 11.579 __ delayed()->nop(); 11.580 } 11.581 11.582 if (flags & LIR_OpArrayCopy::dst_null_check) { 11.583 __ tst(dst); 11.584 - __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); 11.585 + __ brx(Assembler::equal, false, Assembler::pn, *stub->entry()); 11.586 __ delayed()->nop(); 11.587 } 11.588 11.589 @@ -2232,10 +2132,18 @@ 11.590 } 11.591 11.592 if (flags & LIR_OpArrayCopy::type_check) { 11.593 - __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp); 11.594 - __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); 11.595 - __ cmp(tmp, tmp2); 11.596 - __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry()); 11.597 + if (UseCompressedOops) { 11.598 + // We don't need decode because we just need to compare 11.599 + __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp); 11.600 + __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); 11.601 + __ cmp(tmp, tmp2); 11.602 + __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry()); 11.603 + } else { 11.604 + __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp); 11.605 + __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); 11.606 + __ cmp(tmp, tmp2); 11.607 + __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry()); 11.608 + } 11.609 __ delayed()->nop(); 11.610 } 11.611 11.612 @@ -2250,20 +2158,44 @@ 11.613 // but not necessarily exactly of type default_type. 11.614 Label known_ok, halt; 11.615 jobject2reg(op->expected_type()->constant_encoding(), tmp); 11.616 - __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); 11.617 - if (basic_type != T_OBJECT) { 11.618 - __ cmp(tmp, tmp2); 11.619 - __ br(Assembler::notEqual, false, Assembler::pn, halt); 11.620 - __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); 11.621 - __ cmp(tmp, tmp2); 11.622 - __ br(Assembler::equal, false, Assembler::pn, known_ok); 11.623 - __ delayed()->nop(); 11.624 + if (UseCompressedOops) { 11.625 + // tmp holds the default type. It currently comes uncompressed after the 11.626 + // load of a constant, so encode it. 11.627 + __ encode_heap_oop(tmp); 11.628 + // load the raw value of the dst klass, since we will be comparing 11.629 + // uncompressed values directly. 11.630 + __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); 11.631 + if (basic_type != T_OBJECT) { 11.632 + __ cmp(tmp, tmp2); 11.633 + __ br(Assembler::notEqual, false, Assembler::pn, halt); 11.634 + // load the raw value of the src klass. 11.635 + __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2); 11.636 + __ cmp(tmp, tmp2); 11.637 + __ br(Assembler::equal, false, Assembler::pn, known_ok); 11.638 + __ delayed()->nop(); 11.639 + } else { 11.640 + __ cmp(tmp, tmp2); 11.641 + __ br(Assembler::equal, false, Assembler::pn, known_ok); 11.642 + __ delayed()->cmp(src, dst); 11.643 + __ brx(Assembler::equal, false, Assembler::pn, known_ok); 11.644 + __ delayed()->nop(); 11.645 + } 11.646 } else { 11.647 - __ cmp(tmp, tmp2); 11.648 - __ br(Assembler::equal, false, Assembler::pn, known_ok); 11.649 - __ delayed()->cmp(src, dst); 11.650 - __ br(Assembler::equal, false, Assembler::pn, known_ok); 11.651 - __ delayed()->nop(); 11.652 + __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); 11.653 + if (basic_type != T_OBJECT) { 11.654 + __ cmp(tmp, tmp2); 11.655 + __ brx(Assembler::notEqual, false, Assembler::pn, halt); 11.656 + __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); 11.657 + __ cmp(tmp, tmp2); 11.658 + __ brx(Assembler::equal, false, Assembler::pn, known_ok); 11.659 + __ delayed()->nop(); 11.660 + } else { 11.661 + __ cmp(tmp, tmp2); 11.662 + __ brx(Assembler::equal, false, Assembler::pn, known_ok); 11.663 + __ delayed()->cmp(src, dst); 11.664 + __ brx(Assembler::equal, false, Assembler::pn, known_ok); 11.665 + __ delayed()->nop(); 11.666 + } 11.667 } 11.668 __ bind(halt); 11.669 __ stop("incorrect type information in arraycopy"); 11.670 @@ -2471,7 +2403,7 @@ 11.671 Label next_test; 11.672 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - 11.673 mdo_offset_bias); 11.674 - load(recv_addr, tmp1, T_OBJECT); 11.675 + __ ld_ptr(recv_addr, tmp1); 11.676 __ br_notnull(tmp1, false, Assembler::pt, next_test); 11.677 __ delayed()->nop(); 11.678 __ st_ptr(recv, recv_addr); 11.679 @@ -2487,11 +2419,8 @@ 11.680 11.681 void LIR_Assembler::setup_md_access(ciMethod* method, int bci, 11.682 ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias) { 11.683 - md = method->method_data(); 11.684 - if (md == NULL) { 11.685 - bailout("out of memory building methodDataOop"); 11.686 - return; 11.687 - } 11.688 + md = method->method_data_or_null(); 11.689 + assert(md != NULL, "Sanity"); 11.690 data = md->bci_to_data(bci); 11.691 assert(data != NULL, "need data for checkcast"); 11.692 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); 11.693 @@ -2563,7 +2492,7 @@ 11.694 11.695 // get object class 11.696 // not a safepoint as obj null check happens earlier 11.697 - load(obj, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); 11.698 + __ load_klass(obj, klass_RInfo); 11.699 if (op->fast_check()) { 11.700 assert_different_registers(klass_RInfo, k_RInfo); 11.701 __ cmp(k_RInfo, klass_RInfo); 11.702 @@ -2605,7 +2534,7 @@ 11.703 __ set(mdo_offset_bias, tmp1); 11.704 __ add(mdo, tmp1, mdo); 11.705 } 11.706 - load(Address(obj, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); 11.707 + __ load_klass(obj, recv); 11.708 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success); 11.709 // Jump over the failure case 11.710 __ ba(false, *success); 11.711 @@ -2674,11 +2603,12 @@ 11.712 __ br_null(value, false, Assembler::pn, done); 11.713 __ delayed()->nop(); 11.714 } 11.715 - load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception()); 11.716 - load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); 11.717 + add_debug_info_for_null_check_here(op->info_for_exception()); 11.718 + __ load_klass(array, k_RInfo); 11.719 + __ load_klass(value, klass_RInfo); 11.720 11.721 // get instance klass 11.722 - load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL); 11.723 + __ ld_ptr(Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)), k_RInfo); 11.724 // perform the fast part of the checking logic 11.725 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL); 11.726 11.727 @@ -2700,7 +2630,7 @@ 11.728 __ set(mdo_offset_bias, tmp1); 11.729 __ add(mdo, tmp1, mdo); 11.730 } 11.731 - load(Address(value, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); 11.732 + __ load_klass(value, recv); 11.733 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done); 11.734 __ ba(false, done); 11.735 __ delayed()->nop(); 11.736 @@ -2781,14 +2711,17 @@ 11.737 Register t2 = op->tmp2()->as_register(); 11.738 __ mov(cmp_value, t1); 11.739 __ mov(new_value, t2); 11.740 -#ifdef _LP64 11.741 if (op->code() == lir_cas_obj) { 11.742 - __ casx(addr, t1, t2); 11.743 - } else 11.744 -#endif 11.745 - { 11.746 + if (UseCompressedOops) { 11.747 + __ encode_heap_oop(t1); 11.748 + __ encode_heap_oop(t2); 11.749 __ cas(addr, t1, t2); 11.750 + } else { 11.751 + __ cas_ptr(addr, t1, t2); 11.752 } 11.753 + } else { 11.754 + __ cas(addr, t1, t2); 11.755 + } 11.756 __ cmp(t1, t2); 11.757 } else { 11.758 Unimplemented(); 11.759 @@ -2885,11 +2818,8 @@ 11.760 int bci = op->profiled_bci(); 11.761 11.762 // Update counter for all call types 11.763 - ciMethodData* md = method->method_data(); 11.764 - if (md == NULL) { 11.765 - bailout("out of memory building methodDataOop"); 11.766 - return; 11.767 - } 11.768 + ciMethodData* md = method->method_data_or_null(); 11.769 + assert(md != NULL, "Sanity"); 11.770 ciProfileData* data = md->bci_to_data(bci); 11.771 assert(data->is_CounterData(), "need CounterData for calls"); 11.772 assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); 11.773 @@ -2966,7 +2896,7 @@ 11.774 } 11.775 } 11.776 } else { 11.777 - load(Address(recv, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); 11.778 + __ load_klass(recv, recv); 11.779 Label update_done; 11.780 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done); 11.781 // Receiver did not match any saved receiver and there is no empty row for it. 11.782 @@ -3160,7 +3090,7 @@ 11.783 } else { 11.784 // use normal move for all other volatiles since they don't need 11.785 // special handling to remain atomic. 11.786 - move_op(src, dest, type, lir_patch_none, info, false, false); 11.787 + move_op(src, dest, type, lir_patch_none, info, false, false, false); 11.788 } 11.789 } 11.790
12.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp Tue Dec 21 23:39:42 2010 -0500 12.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp Wed Dec 22 12:24:40 2010 -0500 12.3 @@ -40,33 +40,11 @@ 12.4 // and then a load or store is emitted with ([O7] + [d]). 12.5 // 12.6 12.7 - // some load/store variants return the code_offset for proper positioning of debug info for null checks 12.8 + int store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned); 12.9 + int store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide); 12.10 12.11 - // load/store with 32 bit displacement 12.12 - int load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo* info = NULL); 12.13 - void store(Register value, Register base, int offset, BasicType type, CodeEmitInfo *info = NULL); 12.14 - 12.15 - // loadf/storef with 32 bit displacement 12.16 - void load(Register s, int disp, FloatRegister d, BasicType ld_type, CodeEmitInfo* info = NULL); 12.17 - void store(FloatRegister d, Register s1, int disp, BasicType st_type, CodeEmitInfo* info = NULL); 12.18 - 12.19 - // convienence methods for calling load/store with an Address 12.20 - void load(const Address& a, Register d, BasicType ld_type, CodeEmitInfo* info = NULL, int offset = 0); 12.21 - void store(Register d, const Address& a, BasicType st_type, CodeEmitInfo* info = NULL, int offset = 0); 12.22 - void load(const Address& a, FloatRegister d, BasicType ld_type, CodeEmitInfo* info = NULL, int offset = 0); 12.23 - void store(FloatRegister d, const Address& a, BasicType st_type, CodeEmitInfo* info = NULL, int offset = 0); 12.24 - 12.25 - // convienence methods for calling load/store with an LIR_Address 12.26 - void load(LIR_Address* a, Register d, BasicType ld_type, CodeEmitInfo* info = NULL); 12.27 - void store(Register d, LIR_Address* a, BasicType st_type, CodeEmitInfo* info = NULL); 12.28 - void load(LIR_Address* a, FloatRegister d, BasicType ld_type, CodeEmitInfo* info = NULL); 12.29 - void store(FloatRegister d, LIR_Address* a, BasicType st_type, CodeEmitInfo* info = NULL); 12.30 - 12.31 - int store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool unaligned = false); 12.32 - int store(LIR_Opr from_reg, Register base, Register disp, BasicType type); 12.33 - 12.34 - int load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool unaligned = false); 12.35 - int load(Register base, Register disp, LIR_Opr to_reg, BasicType type); 12.36 + int load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned); 12.37 + int load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide); 12.38 12.39 void monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register hdr, int monitor_no); 12.40
13.1 --- a/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Tue Dec 21 23:39:42 2010 -0500 13.2 +++ b/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Wed Dec 22 12:24:40 2010 -0500 13.3 @@ -40,7 +40,7 @@ 13.4 const Register temp_reg = G3_scratch; 13.5 // Note: needs more testing of out-of-line vs. inline slow case 13.6 verify_oop(receiver); 13.7 - ld_ptr(receiver, oopDesc::klass_offset_in_bytes(), temp_reg); 13.8 + load_klass(receiver, temp_reg); 13.9 cmp(temp_reg, iCache); 13.10 brx(Assembler::equal, true, Assembler::pt, L); 13.11 delayed()->nop(); 13.12 @@ -185,9 +185,19 @@ 13.13 } else { 13.14 set((intx)markOopDesc::prototype(), t1); 13.15 } 13.16 - st_ptr(t1 , obj, oopDesc::mark_offset_in_bytes ()); 13.17 - st_ptr(klass, obj, oopDesc::klass_offset_in_bytes ()); 13.18 - if (len->is_valid()) st(len , obj, arrayOopDesc::length_offset_in_bytes()); 13.19 + st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); 13.20 + if (UseCompressedOops) { 13.21 + // Save klass 13.22 + mov(klass, t1); 13.23 + encode_heap_oop_not_null(t1); 13.24 + stw(t1, obj, oopDesc::klass_offset_in_bytes()); 13.25 + } else { 13.26 + st_ptr(klass, obj, oopDesc::klass_offset_in_bytes()); 13.27 + } 13.28 + if (len->is_valid()) st(len, obj, arrayOopDesc::length_offset_in_bytes()); 13.29 + else if (UseCompressedOops) { 13.30 + store_klass_gap(G0, obj); 13.31 + } 13.32 } 13.33 13.34 13.35 @@ -235,7 +245,7 @@ 13.36 Register t1, // temp register 13.37 Register t2 // temp register 13.38 ) { 13.39 - const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes(); 13.40 + const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; 13.41 13.42 initialize_header(obj, klass, noreg, t1, t2); 13.43
14.1 --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Tue Dec 21 23:39:42 2010 -0500 14.2 +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Wed Dec 22 12:24:40 2010 -0500 14.3 @@ -612,7 +612,7 @@ 14.4 // load the klass and check the has finalizer flag 14.5 Label register_finalizer; 14.6 Register t = O1; 14.7 - __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), t); 14.8 + __ load_klass(O0, t); 14.9 __ ld(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc), t); 14.10 __ set(JVM_ACC_HAS_FINALIZER, G3); 14.11 __ andcc(G3, t, G0);
15.1 --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp Tue Dec 21 23:39:42 2010 -0500 15.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp Wed Dec 22 12:24:40 2010 -0500 15.3 @@ -689,8 +689,8 @@ 15.4 { 15.5 // Perform an in-place conversion to int or an int subword. 15.6 __ ldsw(G3_amh_vmargslot, O0_argslot); 15.7 + Address value; 15.8 Address vmarg = __ argument_address(O0_argslot); 15.9 - Address value; 15.10 bool value_left_justified = false; 15.11 15.12 switch (ek) { 15.13 @@ -700,9 +700,21 @@ 15.14 case _adapter_opt_l2i: 15.15 { 15.16 // just delete the extra slot 15.17 +#ifdef _LP64 15.18 + // In V9, longs are given 2 64-bit slots in the interpreter, but the 15.19 + // data is passed in only 1 slot. 15.20 + // Keep the second slot. 15.21 + __ add(Gargs, __ argument_offset(O0_argslot, -1), O0_argslot); 15.22 + remove_arg_slots(_masm, -stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch); 15.23 + value = Address(O0_argslot, 4); // Get least-significant 32-bit of 64-bit value. 15.24 + vmarg = Address(O0_argslot, Interpreter::stackElementSize); 15.25 +#else 15.26 + // Keep the first slot. 15.27 __ add(Gargs, __ argument_offset(O0_argslot), O0_argslot); 15.28 remove_arg_slots(_masm, -stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch); 15.29 - value = vmarg = Address(O0_argslot, 0); 15.30 + value = Address(O0_argslot, 0); 15.31 + vmarg = value; 15.32 +#endif 15.33 } 15.34 break; 15.35 case _adapter_opt_unboxi:
16.1 --- a/src/cpu/sparc/vm/sparc.ad Tue Dec 21 23:39:42 2010 -0500 16.2 +++ b/src/cpu/sparc/vm/sparc.ad Wed Dec 22 12:24:40 2010 -0500 16.3 @@ -667,6 +667,20 @@ 16.4 return offset; 16.5 } 16.6 16.7 +static inline jdouble replicate_immI(int con, int count, int width) { 16.8 + // Load a constant replicated "count" times with width "width" 16.9 + int bit_width = width * 8; 16.10 + jlong elt_val = con; 16.11 + elt_val &= (((jlong) 1) << bit_width) - 1; // mask off sign bits 16.12 + jlong val = elt_val; 16.13 + for (int i = 0; i < count - 1; i++) { 16.14 + val <<= bit_width; 16.15 + val |= elt_val; 16.16 + } 16.17 + jdouble dval = *((jdouble*) &val); // coerce to double type 16.18 + return dval; 16.19 +} 16.20 + 16.21 // Standard Sparc opcode form2 field breakdown 16.22 static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) { 16.23 f0 &= (1<<19)-1; // Mask displacement to 19 bits 16.24 @@ -1008,6 +1022,90 @@ 16.25 16.26 16.27 //============================================================================= 16.28 +const bool Matcher::constant_table_absolute_addressing = false; 16.29 +const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask; 16.30 + 16.31 +void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 16.32 + Compile* C = ra_->C; 16.33 + Compile::ConstantTable& constant_table = C->constant_table(); 16.34 + MacroAssembler _masm(&cbuf); 16.35 + 16.36 + Register r = as_Register(ra_->get_encode(this)); 16.37 + CodeSection* cs = __ code()->consts(); 16.38 + int consts_size = cs->align_at_start(cs->size()); 16.39 + 16.40 + if (UseRDPCForConstantTableBase) { 16.41 + // For the following RDPC logic to work correctly the consts 16.42 + // section must be allocated right before the insts section. This 16.43 + // assert checks for that. The layout and the SECT_* constants 16.44 + // are defined in src/share/vm/asm/codeBuffer.hpp. 16.45 + assert(CodeBuffer::SECT_CONSTS + 1 == CodeBuffer::SECT_INSTS, "must be"); 16.46 + int offset = __ offset(); 16.47 + int disp; 16.48 + 16.49 + // If the displacement from the current PC to the constant table 16.50 + // base fits into simm13 we set the constant table base to the 16.51 + // current PC. 16.52 + if (__ is_simm13(-(consts_size + offset))) { 16.53 + constant_table.set_table_base_offset(-(consts_size + offset)); 16.54 + disp = 0; 16.55 + } else { 16.56 + // If the offset of the top constant (last entry in the table) 16.57 + // fits into simm13 we set the constant table base to the actual 16.58 + // table base. 16.59 + if (__ is_simm13(constant_table.top_offset())) { 16.60 + constant_table.set_table_base_offset(0); 16.61 + disp = consts_size + offset; 16.62 + } else { 16.63 + // Otherwise we set the constant table base in the middle of the 16.64 + // constant table. 16.65 + int half_consts_size = consts_size / 2; 16.66 + assert(half_consts_size * 2 == consts_size, "sanity"); 16.67 + constant_table.set_table_base_offset(-half_consts_size); // table base offset gets added to the load displacement. 16.68 + disp = half_consts_size + offset; 16.69 + } 16.70 + } 16.71 + 16.72 + __ rdpc(r); 16.73 + 16.74 + if (disp != 0) { 16.75 + assert(r != O7, "need temporary"); 16.76 + __ sub(r, __ ensure_simm13_or_reg(disp, O7), r); 16.77 + } 16.78 + } 16.79 + else { 16.80 + // Materialize the constant table base. 16.81 + assert(constant_table.size() == consts_size, err_msg("must be: %d == %d", constant_table.size(), consts_size)); 16.82 + address baseaddr = cs->start() + -(constant_table.table_base_offset()); 16.83 + RelocationHolder rspec = internal_word_Relocation::spec(baseaddr); 16.84 + AddressLiteral base(baseaddr, rspec); 16.85 + __ set(base, r); 16.86 + } 16.87 +} 16.88 + 16.89 +uint MachConstantBaseNode::size(PhaseRegAlloc*) const { 16.90 + if (UseRDPCForConstantTableBase) { 16.91 + // This is really the worst case but generally it's only 1 instruction. 16.92 + return 4 /*rdpc*/ + 4 /*sub*/ + MacroAssembler::worst_case_size_of_set(); 16.93 + } else { 16.94 + return MacroAssembler::worst_case_size_of_set(); 16.95 + } 16.96 +} 16.97 + 16.98 +#ifndef PRODUCT 16.99 +void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 16.100 + char reg[128]; 16.101 + ra_->dump_register(this, reg); 16.102 + if (UseRDPCForConstantTableBase) { 16.103 + st->print("RDPC %s\t! constant table base", reg); 16.104 + } else { 16.105 + st->print("SET &constanttable,%s\t! constant table base", reg); 16.106 + } 16.107 +} 16.108 +#endif 16.109 + 16.110 + 16.111 +//============================================================================= 16.112 16.113 #ifndef PRODUCT 16.114 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { 16.115 @@ -2247,25 +2345,6 @@ 16.116 __ delayed()->nop(); 16.117 %} 16.118 16.119 - enc_class jump_enc( iRegX switch_val, o7RegI table) %{ 16.120 - MacroAssembler _masm(&cbuf); 16.121 - 16.122 - Register switch_reg = as_Register($switch_val$$reg); 16.123 - Register table_reg = O7; 16.124 - 16.125 - address table_base = __ address_table_constant(_index2label); 16.126 - RelocationHolder rspec = internal_word_Relocation::spec(table_base); 16.127 - 16.128 - // Move table address into a register. 16.129 - __ set(table_base, table_reg, rspec); 16.130 - 16.131 - // Jump to base address + switch value 16.132 - __ ld_ptr(table_reg, switch_reg, table_reg); 16.133 - __ jmp(table_reg, G0); 16.134 - __ delayed()->nop(); 16.135 - 16.136 - %} 16.137 - 16.138 enc_class enc_ba( Label labl ) %{ 16.139 MacroAssembler _masm(&cbuf); 16.140 Label &L = *($labl$$label); 16.141 @@ -2384,20 +2463,6 @@ 16.142 cbuf.insts()->emit_int32(op); 16.143 %} 16.144 16.145 - // Utility encoding for loading a 64 bit Pointer into a register 16.146 - // The 64 bit pointer is stored in the generated code stream 16.147 - enc_class SetPtr( immP src, iRegP rd ) %{ 16.148 - Register dest = reg_to_register_object($rd$$reg); 16.149 - MacroAssembler _masm(&cbuf); 16.150 - // [RGV] This next line should be generated from ADLC 16.151 - if ( _opnds[1]->constant_is_oop() ) { 16.152 - intptr_t val = $src$$constant; 16.153 - __ set_oop_constant((jobject)val, dest); 16.154 - } else { // non-oop pointers, e.g. card mark base, heap top 16.155 - __ set($src$$constant, dest); 16.156 - } 16.157 - %} 16.158 - 16.159 enc_class Set13( immI13 src, iRegI rd ) %{ 16.160 emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, $src$$constant ); 16.161 %} 16.162 @@ -2411,10 +2476,6 @@ 16.163 __ set($src$$constant, reg_to_register_object($rd$$reg)); 16.164 %} 16.165 16.166 - enc_class SetNull( iRegI rd ) %{ 16.167 - emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0 ); 16.168 - %} 16.169 - 16.170 enc_class call_epilog %{ 16.171 if( VerifyStackAtCalls ) { 16.172 MacroAssembler _masm(&cbuf); 16.173 @@ -2778,35 +2839,6 @@ 16.174 __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst); 16.175 %} 16.176 16.177 - enc_class LdImmL (immL src, iRegL dst, o7RegL tmp) %{ // Load Immediate 16.178 - MacroAssembler _masm(&cbuf); 16.179 - Register dest = reg_to_register_object($dst$$reg); 16.180 - Register temp = reg_to_register_object($tmp$$reg); 16.181 - __ set64( $src$$constant, dest, temp ); 16.182 - %} 16.183 - 16.184 - enc_class LdReplImmI(immI src, regD dst, o7RegP tmp, int count, int width) %{ 16.185 - // Load a constant replicated "count" times with width "width" 16.186 - int bit_width = $width$$constant * 8; 16.187 - jlong elt_val = $src$$constant; 16.188 - elt_val &= (((jlong)1) << bit_width) - 1; // mask off sign bits 16.189 - jlong val = elt_val; 16.190 - for (int i = 0; i < $count$$constant - 1; i++) { 16.191 - val <<= bit_width; 16.192 - val |= elt_val; 16.193 - } 16.194 - jdouble dval = *(jdouble*)&val; // coerce to double type 16.195 - MacroAssembler _masm(&cbuf); 16.196 - address double_address = __ double_constant(dval); 16.197 - RelocationHolder rspec = internal_word_Relocation::spec(double_address); 16.198 - AddressLiteral addrlit(double_address, rspec); 16.199 - 16.200 - __ sethi(addrlit, $tmp$$Register); 16.201 - // XXX This is a quick fix for 6833573. 16.202 - //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); 16.203 - __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec); 16.204 - %} 16.205 - 16.206 // Compiler ensures base is doubleword aligned and cnt is count of doublewords 16.207 enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{ 16.208 MacroAssembler _masm(&cbuf); 16.209 @@ -3521,6 +3553,29 @@ 16.210 interface(CONST_INTER); 16.211 %} 16.212 16.213 +// Pointer Immediate: 32 or 64-bit 16.214 +operand immP_set() %{ 16.215 + predicate(!VM_Version::is_niagara1_plus()); 16.216 + match(ConP); 16.217 + 16.218 + op_cost(5); 16.219 + // formats are generated automatically for constants and base registers 16.220 + format %{ %} 16.221 + interface(CONST_INTER); 16.222 +%} 16.223 + 16.224 +// Pointer Immediate: 32 or 64-bit 16.225 +// From Niagara2 processors on a load should be better than materializing. 16.226 +operand immP_load() %{ 16.227 + predicate(VM_Version::is_niagara1_plus()); 16.228 + match(ConP); 16.229 + 16.230 + op_cost(5); 16.231 + // formats are generated automatically for constants and base registers 16.232 + format %{ %} 16.233 + interface(CONST_INTER); 16.234 +%} 16.235 + 16.236 operand immP13() %{ 16.237 predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095)); 16.238 match(ConP); 16.239 @@ -3616,6 +3671,26 @@ 16.240 interface(CONST_INTER); 16.241 %} 16.242 16.243 +// Long Immediate: cheap (materialize in <= 3 instructions) 16.244 +operand immL_cheap() %{ 16.245 + predicate(!VM_Version::is_niagara1_plus() || MacroAssembler::size_of_set64(n->get_long()) <= 3); 16.246 + match(ConL); 16.247 + op_cost(0); 16.248 + 16.249 + format %{ %} 16.250 + interface(CONST_INTER); 16.251 +%} 16.252 + 16.253 +// Long Immediate: expensive (materialize in > 3 instructions) 16.254 +operand immL_expensive() %{ 16.255 + predicate(VM_Version::is_niagara1_plus() && MacroAssembler::size_of_set64(n->get_long()) > 3); 16.256 + match(ConL); 16.257 + op_cost(0); 16.258 + 16.259 + format %{ %} 16.260 + interface(CONST_INTER); 16.261 +%} 16.262 + 16.263 // Double Immediate 16.264 operand immD() %{ 16.265 match(ConD); 16.266 @@ -5981,25 +6056,59 @@ 16.267 ins_pipe(ialu_imm); 16.268 %} 16.269 16.270 -instruct loadConP(iRegP dst, immP src) %{ 16.271 - match(Set dst src); 16.272 +#ifndef _LP64 16.273 +instruct loadConP(iRegP dst, immP con) %{ 16.274 + match(Set dst con); 16.275 ins_cost(DEFAULT_COST * 3/2); 16.276 - format %{ "SET $src,$dst\t!ptr" %} 16.277 - // This rule does not use "expand" unlike loadConI because then 16.278 - // the result type is not known to be an Oop. An ADLC 16.279 - // enhancement will be needed to make that work - not worth it! 16.280 - 16.281 - ins_encode( SetPtr( src, dst ) ); 16.282 + format %{ "SET $con,$dst\t!ptr" %} 16.283 + ins_encode %{ 16.284 + // [RGV] This next line should be generated from ADLC 16.285 + if (_opnds[1]->constant_is_oop()) { 16.286 + intptr_t val = $con$$constant; 16.287 + __ set_oop_constant((jobject) val, $dst$$Register); 16.288 + } else { // non-oop pointers, e.g. card mark base, heap top 16.289 + __ set($con$$constant, $dst$$Register); 16.290 + } 16.291 + %} 16.292 ins_pipe(loadConP); 16.293 - 16.294 -%} 16.295 +%} 16.296 +#else 16.297 +instruct loadConP_set(iRegP dst, immP_set con) %{ 16.298 + match(Set dst con); 16.299 + ins_cost(DEFAULT_COST * 3/2); 16.300 + format %{ "SET $con,$dst\t! ptr" %} 16.301 + ins_encode %{ 16.302 + // [RGV] This next line should be generated from ADLC 16.303 + if (_opnds[1]->constant_is_oop()) { 16.304 + intptr_t val = $con$$constant; 16.305 + __ set_oop_constant((jobject) val, $dst$$Register); 16.306 + } else { // non-oop pointers, e.g. card mark base, heap top 16.307 + __ set($con$$constant, $dst$$Register); 16.308 + } 16.309 + %} 16.310 + ins_pipe(loadConP); 16.311 +%} 16.312 + 16.313 +instruct loadConP_load(iRegP dst, immP_load con) %{ 16.314 + match(Set dst con); 16.315 + ins_cost(MEMORY_REF_COST); 16.316 + format %{ "LD [$constanttablebase + $constantoffset],$dst\t! load from constant table: ptr=$con" %} 16.317 + ins_encode %{ 16.318 + RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register); 16.319 + __ ld_ptr($constanttablebase, con_offset, $dst$$Register); 16.320 + %} 16.321 + ins_pipe(loadConP); 16.322 +%} 16.323 +#endif // _LP64 16.324 16.325 instruct loadConP0(iRegP dst, immP0 src) %{ 16.326 match(Set dst src); 16.327 16.328 size(4); 16.329 format %{ "CLR $dst\t!ptr" %} 16.330 - ins_encode( SetNull( dst ) ); 16.331 + ins_encode %{ 16.332 + __ clr($dst$$Register); 16.333 + %} 16.334 ins_pipe(ialu_imm); 16.335 %} 16.336 16.337 @@ -6019,7 +6128,9 @@ 16.338 16.339 size(4); 16.340 format %{ "CLR $dst\t! compressed NULL ptr" %} 16.341 - ins_encode( SetNull( dst ) ); 16.342 + ins_encode %{ 16.343 + __ clr($dst$$Register); 16.344 + %} 16.345 ins_pipe(ialu_imm); 16.346 %} 16.347 16.348 @@ -6034,13 +6145,27 @@ 16.349 ins_pipe(ialu_hi_lo_reg); 16.350 %} 16.351 16.352 -instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{ 16.353 - // %%% maybe this should work like loadConD 16.354 - match(Set dst src); 16.355 +// Materialize long value (predicated by immL_cheap). 16.356 +instruct loadConL_set64(iRegL dst, immL_cheap con, o7RegL tmp) %{ 16.357 + match(Set dst con); 16.358 effect(KILL tmp); 16.359 - ins_cost(DEFAULT_COST * 4); 16.360 - format %{ "SET64 $src,$dst KILL $tmp\t! long" %} 16.361 - ins_encode( LdImmL(src, dst, tmp) ); 16.362 + ins_cost(DEFAULT_COST * 3); 16.363 + format %{ "SET64 $con,$dst KILL $tmp\t! cheap long" %} 16.364 + ins_encode %{ 16.365 + __ set64($con$$constant, $dst$$Register, $tmp$$Register); 16.366 + %} 16.367 + ins_pipe(loadConL); 16.368 +%} 16.369 + 16.370 +// Load long value from constant table (predicated by immL_expensive). 16.371 +instruct loadConL_ldx(iRegL dst, immL_expensive con) %{ 16.372 + match(Set dst con); 16.373 + ins_cost(MEMORY_REF_COST); 16.374 + format %{ "LDX [$constanttablebase + $constantoffset],$dst\t! load from constant table: long=$con" %} 16.375 + ins_encode %{ 16.376 + RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register); 16.377 + __ ldx($constanttablebase, con_offset, $dst$$Register); 16.378 + %} 16.379 ins_pipe(loadConL); 16.380 %} 16.381 16.382 @@ -6063,50 +6188,26 @@ 16.383 ins_pipe(ialu_imm); 16.384 %} 16.385 16.386 -instruct loadConF(regF dst, immF src, o7RegP tmp) %{ 16.387 - match(Set dst src); 16.388 +instruct loadConF(regF dst, immF con, o7RegI tmp) %{ 16.389 + match(Set dst con); 16.390 effect(KILL tmp); 16.391 - 16.392 -#ifdef _LP64 16.393 - size(8*4); 16.394 -#else 16.395 - size(2*4); 16.396 -#endif 16.397 - 16.398 - format %{ "SETHI hi(&$src),$tmp\t!get float $src from table\n\t" 16.399 - "LDF [$tmp+lo(&$src)],$dst" %} 16.400 + format %{ "LDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: float=$con" %} 16.401 ins_encode %{ 16.402 - address float_address = __ float_constant($src$$constant); 16.403 - RelocationHolder rspec = internal_word_Relocation::spec(float_address); 16.404 - AddressLiteral addrlit(float_address, rspec); 16.405 - 16.406 - __ sethi(addrlit, $tmp$$Register); 16.407 - __ ldf(FloatRegisterImpl::S, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); 16.408 + RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $tmp$$Register); 16.409 + __ ldf(FloatRegisterImpl::S, $constanttablebase, con_offset, $dst$$FloatRegister); 16.410 %} 16.411 ins_pipe(loadConFD); 16.412 %} 16.413 16.414 -instruct loadConD(regD dst, immD src, o7RegP tmp) %{ 16.415 - match(Set dst src); 16.416 +instruct loadConD(regD dst, immD con, o7RegI tmp) %{ 16.417 + match(Set dst con); 16.418 effect(KILL tmp); 16.419 - 16.420 -#ifdef _LP64 16.421 - size(8*4); 16.422 -#else 16.423 - size(2*4); 16.424 -#endif 16.425 - 16.426 - format %{ "SETHI hi(&$src),$tmp\t!get double $src from table\n\t" 16.427 - "LDDF [$tmp+lo(&$src)],$dst" %} 16.428 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: double=$con" %} 16.429 ins_encode %{ 16.430 - address double_address = __ double_constant($src$$constant); 16.431 - RelocationHolder rspec = internal_word_Relocation::spec(double_address); 16.432 - AddressLiteral addrlit(double_address, rspec); 16.433 - 16.434 - __ sethi(addrlit, $tmp$$Register); 16.435 // XXX This is a quick fix for 6833573. 16.436 - //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); 16.437 - __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec); 16.438 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset($con), $dst$$FloatRegister); 16.439 + RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $tmp$$Register); 16.440 + __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg)); 16.441 %} 16.442 ins_pipe(loadConFD); 16.443 %} 16.444 @@ -8558,16 +8659,16 @@ 16.445 %} 16.446 16.447 // Replicate scalar constant to packed byte values in Double register 16.448 -instruct Repl8B_immI(regD dst, immI13 src, o7RegP tmp) %{ 16.449 - match(Set dst (Replicate8B src)); 16.450 -#ifdef _LP64 16.451 - size(36); 16.452 -#else 16.453 - size(8); 16.454 -#endif 16.455 - format %{ "SETHI hi(&Repl8($src)),$tmp\t!get Repl8B($src) from table\n\t" 16.456 - "LDDF [$tmp+lo(&Repl8($src))],$dst" %} 16.457 - ins_encode( LdReplImmI(src, dst, tmp, (8), (1)) ); 16.458 +instruct Repl8B_immI(regD dst, immI13 con, o7RegI tmp) %{ 16.459 + match(Set dst (Replicate8B con)); 16.460 + effect(KILL tmp); 16.461 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl8B($con)" %} 16.462 + ins_encode %{ 16.463 + // XXX This is a quick fix for 6833573. 16.464 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), $dst$$FloatRegister); 16.465 + RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 8, 1)), $tmp$$Register); 16.466 + __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg)); 16.467 + %} 16.468 ins_pipe(loadConFD); 16.469 %} 16.470 16.471 @@ -8594,16 +8695,16 @@ 16.472 %} 16.473 16.474 // Replicate scalar constant to packed char values in Double register 16.475 -instruct Repl4C_immI(regD dst, immI src, o7RegP tmp) %{ 16.476 - match(Set dst (Replicate4C src)); 16.477 -#ifdef _LP64 16.478 - size(36); 16.479 -#else 16.480 - size(8); 16.481 -#endif 16.482 - format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4C($src) from table\n\t" 16.483 - "LDDF [$tmp+lo(&Repl4($src))],$dst" %} 16.484 - ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); 16.485 +instruct Repl4C_immI(regD dst, immI con, o7RegI tmp) %{ 16.486 + match(Set dst (Replicate4C con)); 16.487 + effect(KILL tmp); 16.488 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4C($con)" %} 16.489 + ins_encode %{ 16.490 + // XXX This is a quick fix for 6833573. 16.491 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister); 16.492 + RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 4, 2)), $tmp$$Register); 16.493 + __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg)); 16.494 + %} 16.495 ins_pipe(loadConFD); 16.496 %} 16.497 16.498 @@ -8630,16 +8731,16 @@ 16.499 %} 16.500 16.501 // Replicate scalar constant to packed short values in Double register 16.502 -instruct Repl4S_immI(regD dst, immI src, o7RegP tmp) %{ 16.503 - match(Set dst (Replicate4S src)); 16.504 -#ifdef _LP64 16.505 - size(36); 16.506 -#else 16.507 - size(8); 16.508 -#endif 16.509 - format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4S($src) from table\n\t" 16.510 - "LDDF [$tmp+lo(&Repl4($src))],$dst" %} 16.511 - ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); 16.512 +instruct Repl4S_immI(regD dst, immI con, o7RegI tmp) %{ 16.513 + match(Set dst (Replicate4S con)); 16.514 + effect(KILL tmp); 16.515 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4S($con)" %} 16.516 + ins_encode %{ 16.517 + // XXX This is a quick fix for 6833573. 16.518 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister); 16.519 + RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 4, 2)), $tmp$$Register); 16.520 + __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg)); 16.521 + %} 16.522 ins_pipe(loadConFD); 16.523 %} 16.524 16.525 @@ -8664,16 +8765,16 @@ 16.526 %} 16.527 16.528 // Replicate scalar zero constant to packed int values in Double register 16.529 -instruct Repl2I_immI(regD dst, immI src, o7RegP tmp) %{ 16.530 - match(Set dst (Replicate2I src)); 16.531 -#ifdef _LP64 16.532 - size(36); 16.533 -#else 16.534 - size(8); 16.535 -#endif 16.536 - format %{ "SETHI hi(&Repl2($src)),$tmp\t!get Repl2I($src) from table\n\t" 16.537 - "LDDF [$tmp+lo(&Repl2($src))],$dst" %} 16.538 - ins_encode( LdReplImmI(src, dst, tmp, (2), (4)) ); 16.539 +instruct Repl2I_immI(regD dst, immI con, o7RegI tmp) %{ 16.540 + match(Set dst (Replicate2I con)); 16.541 + effect(KILL tmp); 16.542 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl2I($con)" %} 16.543 + ins_encode %{ 16.544 + // XXX This is a quick fix for 6833573. 16.545 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), $dst$$FloatRegister); 16.546 + RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 2, 4)), $tmp$$Register); 16.547 + __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg)); 16.548 + %} 16.549 ins_pipe(loadConFD); 16.550 %} 16.551 16.552 @@ -8929,12 +9030,27 @@ 16.553 16.554 ins_cost(350); 16.555 16.556 - format %{ "SETHI [hi(table_base)],O7\n\t" 16.557 - "ADD O7, lo(table_base), O7\n\t" 16.558 - "LD [O7+$switch_val], O7\n\t" 16.559 + format %{ "ADD $constanttablebase, $constantoffset, O7\n\t" 16.560 + "LD [O7 + $switch_val], O7\n\t" 16.561 "JUMP O7" 16.562 %} 16.563 - ins_encode( jump_enc( switch_val, table) ); 16.564 + ins_encode %{ 16.565 + // Calculate table address into a register. 16.566 + Register table_reg; 16.567 + Register label_reg = O7; 16.568 + if (constant_offset() == 0) { 16.569 + table_reg = $constanttablebase; 16.570 + } else { 16.571 + table_reg = O7; 16.572 + RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset, O7); 16.573 + __ add($constanttablebase, con_offset, table_reg); 16.574 + } 16.575 + 16.576 + // Jump to base address + switch value 16.577 + __ ld_ptr(table_reg, $switch_val$$Register, label_reg); 16.578 + __ jmp(label_reg, G0); 16.579 + __ delayed()->nop(); 16.580 + %} 16.581 ins_pc_relative(1); 16.582 ins_pipe(ialu_reg_reg); 16.583 %}
17.1 --- a/src/cpu/sparc/vm/vm_version_sparc.hpp Tue Dec 21 23:39:42 2010 -0500 17.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Dec 22 12:24:40 2010 -0500 17.3 @@ -80,9 +80,6 @@ 17.4 static bool is_sparc64(int features) { return (features & fmaf_instructions_m) != 0; } 17.5 17.6 static int maximum_niagara1_processor_count() { return 32; } 17.7 - // Returns true if the platform is in the niagara line and 17.8 - // newer than the niagara1. 17.9 - static bool is_niagara1_plus(); 17.10 17.11 public: 17.12 // Initialization 17.13 @@ -105,6 +102,9 @@ 17.14 static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m; } 17.15 static bool is_sun4v() { return (_features & sun4v_m) != 0; } 17.16 static bool is_niagara1() { return is_niagara1(_features); } 17.17 + // Returns true if the platform is in the niagara line and 17.18 + // newer than the niagara1. 17.19 + static bool is_niagara1_plus(); 17.20 static bool is_sparc64() { return is_sparc64(_features); } 17.21 17.22 static bool has_fast_fxtof() { return has_v9() && !is_ultra3(); }
18.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Tue Dec 21 23:39:42 2010 -0500 18.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Wed Dec 22 12:24:40 2010 -0500 18.3 @@ -2649,6 +2649,37 @@ 18.4 emit_byte(0xC0 | encode); 18.5 } 18.6 18.7 +void Assembler::sqrtsd(XMMRegister dst, Address src) { 18.8 + NOT_LP64(assert(VM_Version::supports_sse2(), "")); 18.9 + InstructionMark im(this); 18.10 + emit_byte(0xF2); 18.11 + prefix(src, dst); 18.12 + emit_byte(0x0F); 18.13 + emit_byte(0x51); 18.14 + emit_operand(dst, src); 18.15 +} 18.16 + 18.17 +void Assembler::sqrtss(XMMRegister dst, XMMRegister src) { 18.18 + // HMM Table D-1 says sse2 18.19 + // NOT_LP64(assert(VM_Version::supports_sse(), "")); 18.20 + NOT_LP64(assert(VM_Version::supports_sse2(), "")); 18.21 + emit_byte(0xF3); 18.22 + int encode = prefix_and_encode(dst->encoding(), src->encoding()); 18.23 + emit_byte(0x0F); 18.24 + emit_byte(0x51); 18.25 + emit_byte(0xC0 | encode); 18.26 +} 18.27 + 18.28 +void Assembler::sqrtss(XMMRegister dst, Address src) { 18.29 + NOT_LP64(assert(VM_Version::supports_sse2(), "")); 18.30 + InstructionMark im(this); 18.31 + emit_byte(0xF3); 18.32 + prefix(src, dst); 18.33 + emit_byte(0x0F); 18.34 + emit_byte(0x51); 18.35 + emit_operand(dst, src); 18.36 +} 18.37 + 18.38 void Assembler::stmxcsr( Address dst) { 18.39 NOT_LP64(assert(VM_Version::supports_sse(), "")); 18.40 InstructionMark im(this); 18.41 @@ -4358,16 +4389,6 @@ 18.42 emit_byte(0xE8 | encode); 18.43 } 18.44 18.45 -void Assembler::sqrtsd(XMMRegister dst, Address src) { 18.46 - NOT_LP64(assert(VM_Version::supports_sse2(), "")); 18.47 - InstructionMark im(this); 18.48 - emit_byte(0xF2); 18.49 - prefix(src, dst); 18.50 - emit_byte(0x0F); 18.51 - emit_byte(0x51); 18.52 - emit_operand(dst, src); 18.53 -} 18.54 - 18.55 void Assembler::subq(Address dst, int32_t imm32) { 18.56 InstructionMark im(this); 18.57 prefixq(dst); 18.58 @@ -4929,10 +4950,6 @@ 18.59 } 18.60 18.61 18.62 -void MacroAssembler::movsd(XMMRegister dst, AddressLiteral src) { 18.63 - movsd(dst, as_Address(src)); 18.64 -} 18.65 - 18.66 void MacroAssembler::pop_callee_saved_registers() { 18.67 pop(rcx); 18.68 pop(rdx);
19.1 --- a/src/cpu/x86/vm/assembler_x86.hpp Tue Dec 21 23:39:42 2010 -0500 19.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp Wed Dec 22 12:24:40 2010 -0500 19.3 @@ -135,6 +135,7 @@ 19.4 // Using noreg ensures if the dead code is incorrectly live and executed it 19.5 // will cause an assertion failure 19.6 #define rscratch1 noreg 19.7 +#define rscratch2 noreg 19.8 19.9 #endif // _LP64 19.10 19.11 @@ -1352,6 +1353,10 @@ 19.12 void sqrtsd(XMMRegister dst, Address src); 19.13 void sqrtsd(XMMRegister dst, XMMRegister src); 19.14 19.15 + // Compute Square Root of Scalar Single-Precision Floating-Point Value 19.16 + void sqrtss(XMMRegister dst, Address src); 19.17 + void sqrtss(XMMRegister dst, XMMRegister src); 19.18 + 19.19 void std() { emit_byte(0xfd); } 19.20 19.21 void stmxcsr( Address dst ); 19.22 @@ -2124,6 +2129,9 @@ 19.23 void comisd(XMMRegister dst, Address src) { Assembler::comisd(dst, src); } 19.24 void comisd(XMMRegister dst, AddressLiteral src); 19.25 19.26 + void fadd_s(Address src) { Assembler::fadd_s(src); } 19.27 + void fadd_s(AddressLiteral src) { Assembler::fadd_s(as_Address(src)); } 19.28 + 19.29 void fldcw(Address src) { Assembler::fldcw(src); } 19.30 void fldcw(AddressLiteral src); 19.31 19.32 @@ -2137,6 +2145,9 @@ 19.33 void fld_x(Address src) { Assembler::fld_x(src); } 19.34 void fld_x(AddressLiteral src); 19.35 19.36 + void fmul_s(Address src) { Assembler::fmul_s(src); } 19.37 + void fmul_s(AddressLiteral src) { Assembler::fmul_s(as_Address(src)); } 19.38 + 19.39 void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } 19.40 void ldmxcsr(AddressLiteral src); 19.41 19.42 @@ -2153,10 +2164,50 @@ 19.43 19.44 public: 19.45 19.46 - void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); } 19.47 - void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); } 19.48 - void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } 19.49 - void movsd(XMMRegister dst, AddressLiteral src); 19.50 + void addsd(XMMRegister dst, XMMRegister src) { Assembler::addsd(dst, src); } 19.51 + void addsd(XMMRegister dst, Address src) { Assembler::addsd(dst, src); } 19.52 + void addsd(XMMRegister dst, AddressLiteral src) { Assembler::addsd(dst, as_Address(src)); } 19.53 + 19.54 + void addss(XMMRegister dst, XMMRegister src) { Assembler::addss(dst, src); } 19.55 + void addss(XMMRegister dst, Address src) { Assembler::addss(dst, src); } 19.56 + void addss(XMMRegister dst, AddressLiteral src) { Assembler::addss(dst, as_Address(src)); } 19.57 + 19.58 + void divsd(XMMRegister dst, XMMRegister src) { Assembler::divsd(dst, src); } 19.59 + void divsd(XMMRegister dst, Address src) { Assembler::divsd(dst, src); } 19.60 + void divsd(XMMRegister dst, AddressLiteral src) { Assembler::divsd(dst, as_Address(src)); } 19.61 + 19.62 + void divss(XMMRegister dst, XMMRegister src) { Assembler::divss(dst, src); } 19.63 + void divss(XMMRegister dst, Address src) { Assembler::divss(dst, src); } 19.64 + void divss(XMMRegister dst, AddressLiteral src) { Assembler::divss(dst, as_Address(src)); } 19.65 + 19.66 + void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); } 19.67 + void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); } 19.68 + void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } 19.69 + void movsd(XMMRegister dst, AddressLiteral src) { Assembler::movsd(dst, as_Address(src)); } 19.70 + 19.71 + void mulsd(XMMRegister dst, XMMRegister src) { Assembler::mulsd(dst, src); } 19.72 + void mulsd(XMMRegister dst, Address src) { Assembler::mulsd(dst, src); } 19.73 + void mulsd(XMMRegister dst, AddressLiteral src) { Assembler::mulsd(dst, as_Address(src)); } 19.74 + 19.75 + void mulss(XMMRegister dst, XMMRegister src) { Assembler::mulss(dst, src); } 19.76 + void mulss(XMMRegister dst, Address src) { Assembler::mulss(dst, src); } 19.77 + void mulss(XMMRegister dst, AddressLiteral src) { Assembler::mulss(dst, as_Address(src)); } 19.78 + 19.79 + void sqrtsd(XMMRegister dst, XMMRegister src) { Assembler::sqrtsd(dst, src); } 19.80 + void sqrtsd(XMMRegister dst, Address src) { Assembler::sqrtsd(dst, src); } 19.81 + void sqrtsd(XMMRegister dst, AddressLiteral src) { Assembler::sqrtsd(dst, as_Address(src)); } 19.82 + 19.83 + void sqrtss(XMMRegister dst, XMMRegister src) { Assembler::sqrtss(dst, src); } 19.84 + void sqrtss(XMMRegister dst, Address src) { Assembler::sqrtss(dst, src); } 19.85 + void sqrtss(XMMRegister dst, AddressLiteral src) { Assembler::sqrtss(dst, as_Address(src)); } 19.86 + 19.87 + void subsd(XMMRegister dst, XMMRegister src) { Assembler::subsd(dst, src); } 19.88 + void subsd(XMMRegister dst, Address src) { Assembler::subsd(dst, src); } 19.89 + void subsd(XMMRegister dst, AddressLiteral src) { Assembler::subsd(dst, as_Address(src)); } 19.90 + 19.91 + void subss(XMMRegister dst, XMMRegister src) { Assembler::subss(dst, src); } 19.92 + void subss(XMMRegister dst, Address src) { Assembler::subss(dst, src); } 19.93 + void subss(XMMRegister dst, AddressLiteral src) { Assembler::subss(dst, as_Address(src)); } 19.94 19.95 void ucomiss(XMMRegister dst, XMMRegister src) { Assembler::ucomiss(dst, src); } 19.96 void ucomiss(XMMRegister dst, Address src) { Assembler::ucomiss(dst, src); }
20.1 --- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Tue Dec 21 23:39:42 2010 -0500 20.2 +++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Wed Dec 22 12:24:40 2010 -0500 20.3 @@ -483,7 +483,7 @@ 20.4 20.5 Register pre_val_reg = pre_val()->as_register(); 20.6 20.7 - ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false); 20.8 + ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/); 20.9 20.10 __ cmpptr(pre_val_reg, (int32_t) NULL_WORD); 20.11 __ jcc(Assembler::equal, _continuation);
21.1 --- a/src/cpu/x86/vm/c1_Defs_x86.hpp Tue Dec 21 23:39:42 2010 -0500 21.2 +++ b/src/cpu/x86/vm/c1_Defs_x86.hpp Wed Dec 22 12:24:40 2010 -0500 21.3 @@ -61,8 +61,8 @@ 21.4 pd_nof_xmm_regs_linearscan = pd_nof_xmm_regs_frame_map, // number of registers visible to linear scan 21.5 pd_first_cpu_reg = 0, 21.6 pd_last_cpu_reg = NOT_LP64(5) LP64_ONLY(11), 21.7 - pd_first_byte_reg = 2, 21.8 - pd_last_byte_reg = 5, 21.9 + pd_first_byte_reg = NOT_LP64(2) LP64_ONLY(0), 21.10 + pd_last_byte_reg = NOT_LP64(5) LP64_ONLY(11), 21.11 pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, 21.12 pd_last_fpu_reg = pd_first_fpu_reg + 7, 21.13 pd_first_xmm_reg = pd_nof_cpu_regs_frame_map + pd_nof_fpu_regs_frame_map,
22.1 --- a/src/cpu/x86/vm/c1_FrameMap_x86.cpp Tue Dec 21 23:39:42 2010 -0500 22.2 +++ b/src/cpu/x86/vm/c1_FrameMap_x86.cpp Wed Dec 22 12:24:40 2010 -0500 22.3 @@ -158,9 +158,11 @@ 22.4 map_register( 6, r8); r8_opr = LIR_OprFact::single_cpu(6); 22.5 map_register( 7, r9); r9_opr = LIR_OprFact::single_cpu(7); 22.6 map_register( 8, r11); r11_opr = LIR_OprFact::single_cpu(8); 22.7 - map_register( 9, r12); r12_opr = LIR_OprFact::single_cpu(9); 22.8 - map_register(10, r13); r13_opr = LIR_OprFact::single_cpu(10); 22.9 - map_register(11, r14); r14_opr = LIR_OprFact::single_cpu(11); 22.10 + map_register( 9, r13); r13_opr = LIR_OprFact::single_cpu(9); 22.11 + map_register(10, r14); r14_opr = LIR_OprFact::single_cpu(10); 22.12 + // r12 is allocated conditionally. With compressed oops it holds 22.13 + // the heapbase value and is not visible to the allocator. 22.14 + map_register(11, r12); r12_opr = LIR_OprFact::single_cpu(11); 22.15 // The unallocatable registers are at the end 22.16 map_register(12, r10); r10_opr = LIR_OprFact::single_cpu(12); 22.17 map_register(13, r15); r15_opr = LIR_OprFact::single_cpu(13); 22.18 @@ -191,9 +193,9 @@ 22.19 _caller_save_cpu_regs[6] = r8_opr; 22.20 _caller_save_cpu_regs[7] = r9_opr; 22.21 _caller_save_cpu_regs[8] = r11_opr; 22.22 - _caller_save_cpu_regs[9] = r12_opr; 22.23 - _caller_save_cpu_regs[10] = r13_opr; 22.24 - _caller_save_cpu_regs[11] = r14_opr; 22.25 + _caller_save_cpu_regs[9] = r13_opr; 22.26 + _caller_save_cpu_regs[10] = r14_opr; 22.27 + _caller_save_cpu_regs[11] = r12_opr; 22.28 #endif // _LP64 22.29 22.30
23.1 --- a/src/cpu/x86/vm/c1_FrameMap_x86.hpp Tue Dec 21 23:39:42 2010 -0500 23.2 +++ b/src/cpu/x86/vm/c1_FrameMap_x86.hpp Wed Dec 22 12:24:40 2010 -0500 23.3 @@ -130,4 +130,15 @@ 23.4 return _caller_save_xmm_regs[i]; 23.5 } 23.6 23.7 + static int adjust_reg_range(int range) { 23.8 + // Reduce the number of available regs (to free r12) in case of compressed oops 23.9 + if (UseCompressedOops) return range - 1; 23.10 + return range; 23.11 + } 23.12 + 23.13 + static int nof_caller_save_cpu_regs() { return adjust_reg_range(pd_nof_caller_save_cpu_regs_frame_map); } 23.14 + static int last_cpu_reg() { return adjust_reg_range(pd_last_cpu_reg); } 23.15 + static int last_byte_reg() { return adjust_reg_range(pd_last_byte_reg); } 23.16 + 23.17 #endif // CPU_X86_VM_C1_FRAMEMAP_X86_HPP 23.18 +
24.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Tue Dec 21 23:39:42 2010 -0500 24.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Dec 22 12:24:40 2010 -0500 24.3 @@ -343,8 +343,8 @@ 24.4 Register receiver = FrameMap::receiver_opr->as_register(); 24.5 Register ic_klass = IC_Klass; 24.6 const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); 24.7 - 24.8 - if (!VerifyOops) { 24.9 + const bool do_post_padding = VerifyOops || UseCompressedOops; 24.10 + if (!do_post_padding) { 24.11 // insert some nops so that the verified entry point is aligned on CodeEntryAlignment 24.12 while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { 24.13 __ nop(); 24.14 @@ -352,8 +352,8 @@ 24.15 } 24.16 int offset = __ offset(); 24.17 __ inline_cache_check(receiver, IC_Klass); 24.18 - assert(__ offset() % CodeEntryAlignment == 0 || VerifyOops, "alignment must be correct"); 24.19 - if (VerifyOops) { 24.20 + assert(__ offset() % CodeEntryAlignment == 0 || do_post_padding, "alignment must be correct"); 24.21 + if (do_post_padding) { 24.22 // force alignment after the cache check. 24.23 // It's been verified to be aligned if !VerifyOops 24.24 __ align(CodeEntryAlignment); 24.25 @@ -559,16 +559,16 @@ 24.26 __ movptr (rax, arg1->as_register()); 24.27 24.28 // Get addresses of first characters from both Strings 24.29 - __ movptr (rsi, Address(rax, java_lang_String::value_offset_in_bytes())); 24.30 - __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); 24.31 - __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); 24.32 + __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes())); 24.33 + __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); 24.34 + __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); 24.35 24.36 24.37 // rbx, may be NULL 24.38 add_debug_info_for_null_check_here(info); 24.39 - __ movptr (rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); 24.40 - __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); 24.41 - __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); 24.42 + __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); 24.43 + __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); 24.44 + __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); 24.45 24.46 // compute minimum length (in rax) and difference of lengths (on top of stack) 24.47 if (VM_Version::supports_cmov()) { 24.48 @@ -696,10 +696,15 @@ 24.49 LIR_Const* c = src->as_constant_ptr(); 24.50 24.51 switch (c->type()) { 24.52 - case T_INT: 24.53 + case T_INT: { 24.54 + assert(patch_code == lir_patch_none, "no patching handled here"); 24.55 + __ movl(dest->as_register(), c->as_jint()); 24.56 + break; 24.57 + } 24.58 + 24.59 case T_ADDRESS: { 24.60 assert(patch_code == lir_patch_none, "no patching handled here"); 24.61 - __ movl(dest->as_register(), c->as_jint()); 24.62 + __ movptr(dest->as_register(), c->as_jint()); 24.63 break; 24.64 } 24.65 24.66 @@ -780,8 +785,11 @@ 24.67 switch (c->type()) { 24.68 case T_INT: // fall through 24.69 case T_FLOAT: 24.70 + __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); 24.71 + break; 24.72 + 24.73 case T_ADDRESS: 24.74 - __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); 24.75 + __ movptr(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); 24.76 break; 24.77 24.78 case T_OBJECT: 24.79 @@ -806,7 +814,7 @@ 24.80 } 24.81 } 24.82 24.83 -void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) { 24.84 +void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { 24.85 assert(src->is_constant(), "should not call otherwise"); 24.86 assert(dest->is_address(), "should not call otherwise"); 24.87 LIR_Const* c = src->as_constant_ptr(); 24.88 @@ -816,14 +824,21 @@ 24.89 switch (type) { 24.90 case T_INT: // fall through 24.91 case T_FLOAT: 24.92 + __ movl(as_Address(addr), c->as_jint_bits()); 24.93 + break; 24.94 + 24.95 case T_ADDRESS: 24.96 - __ movl(as_Address(addr), c->as_jint_bits()); 24.97 + __ movptr(as_Address(addr), c->as_jint_bits()); 24.98 break; 24.99 24.100 case T_OBJECT: // fall through 24.101 case T_ARRAY: 24.102 if (c->as_jobject() == NULL) { 24.103 - __ movptr(as_Address(addr), NULL_WORD); 24.104 + if (UseCompressedOops && !wide) { 24.105 + __ movl(as_Address(addr), (int32_t)NULL_WORD); 24.106 + } else { 24.107 + __ movptr(as_Address(addr), NULL_WORD); 24.108 + } 24.109 } else { 24.110 if (is_literal_address(addr)) { 24.111 ShouldNotReachHere(); 24.112 @@ -831,8 +846,14 @@ 24.113 } else { 24.114 #ifdef _LP64 24.115 __ movoop(rscratch1, c->as_jobject()); 24.116 - null_check_here = code_offset(); 24.117 - __ movptr(as_Address_lo(addr), rscratch1); 24.118 + if (UseCompressedOops && !wide) { 24.119 + __ encode_heap_oop(rscratch1); 24.120 + null_check_here = code_offset(); 24.121 + __ movl(as_Address_lo(addr), rscratch1); 24.122 + } else { 24.123 + null_check_here = code_offset(); 24.124 + __ movptr(as_Address_lo(addr), rscratch1); 24.125 + } 24.126 #else 24.127 __ movoop(as_Address(addr), c->as_jobject()); 24.128 #endif 24.129 @@ -1009,22 +1030,28 @@ 24.130 } 24.131 24.132 24.133 -void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool /* unaligned */) { 24.134 +void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide, bool /* unaligned */) { 24.135 LIR_Address* to_addr = dest->as_address_ptr(); 24.136 PatchingStub* patch = NULL; 24.137 + Register compressed_src = rscratch1; 24.138 24.139 if (type == T_ARRAY || type == T_OBJECT) { 24.140 __ verify_oop(src->as_register()); 24.141 +#ifdef _LP64 24.142 + if (UseCompressedOops && !wide) { 24.143 + __ movptr(compressed_src, src->as_register()); 24.144 + __ encode_heap_oop(compressed_src); 24.145 + } 24.146 +#endif 24.147 } 24.148 + 24.149 if (patch_code != lir_patch_none) { 24.150 patch = new PatchingStub(_masm, PatchingStub::access_field_id); 24.151 Address toa = as_Address(to_addr); 24.152 assert(toa.disp() != 0, "must have"); 24.153 } 24.154 - if (info != NULL) { 24.155 - add_debug_info_for_null_check_here(info); 24.156 - } 24.157 - 24.158 + 24.159 + int null_check_here = code_offset(); 24.160 switch (type) { 24.161 case T_FLOAT: { 24.162 if (src->is_single_xmm()) { 24.163 @@ -1050,13 +1077,17 @@ 24.164 break; 24.165 } 24.166 24.167 - case T_ADDRESS: // fall through 24.168 case T_ARRAY: // fall through 24.169 case T_OBJECT: // fall through 24.170 -#ifdef _LP64 24.171 + if (UseCompressedOops && !wide) { 24.172 + __ movl(as_Address(to_addr), compressed_src); 24.173 + } else { 24.174 + __ movptr(as_Address(to_addr), src->as_register()); 24.175 + } 24.176 + break; 24.177 + case T_ADDRESS: 24.178 __ movptr(as_Address(to_addr), src->as_register()); 24.179 break; 24.180 -#endif // _LP64 24.181 case T_INT: 24.182 __ movl(as_Address(to_addr), src->as_register()); 24.183 break; 24.184 @@ -1113,6 +1144,9 @@ 24.185 default: 24.186 ShouldNotReachHere(); 24.187 } 24.188 + if (info != NULL) { 24.189 + add_debug_info_for_null_check(null_check_here, info); 24.190 + } 24.191 24.192 if (patch_code != lir_patch_none) { 24.193 patching_epilog(patch, patch_code, to_addr->base()->as_register(), info); 24.194 @@ -1196,7 +1230,7 @@ 24.195 } 24.196 24.197 24.198 -void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool /* unaligned */) { 24.199 +void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool /* unaligned */) { 24.200 assert(src->is_address(), "should not call otherwise"); 24.201 assert(dest->is_register(), "should not call otherwise"); 24.202 24.203 @@ -1250,13 +1284,18 @@ 24.204 break; 24.205 } 24.206 24.207 - case T_ADDRESS: // fall through 24.208 case T_OBJECT: // fall through 24.209 case T_ARRAY: // fall through 24.210 -#ifdef _LP64 24.211 + if (UseCompressedOops && !wide) { 24.212 + __ movl(dest->as_register(), from_addr); 24.213 + } else { 24.214 + __ movptr(dest->as_register(), from_addr); 24.215 + } 24.216 + break; 24.217 + 24.218 + case T_ADDRESS: 24.219 __ movptr(dest->as_register(), from_addr); 24.220 break; 24.221 -#endif // _L64 24.222 case T_INT: 24.223 __ movl(dest->as_register(), from_addr); 24.224 break; 24.225 @@ -1351,6 +1390,11 @@ 24.226 } 24.227 24.228 if (type == T_ARRAY || type == T_OBJECT) { 24.229 +#ifdef _LP64 24.230 + if (UseCompressedOops && !wide) { 24.231 + __ decode_heap_oop(dest->as_register()); 24.232 + } 24.233 +#endif 24.234 __ verify_oop(dest->as_register()); 24.235 } 24.236 } 24.237 @@ -1672,11 +1716,8 @@ 24.238 ciMethod* method = op->profiled_method(); 24.239 assert(method != NULL, "Should have method"); 24.240 int bci = op->profiled_bci(); 24.241 - md = method->method_data(); 24.242 - if (md == NULL) { 24.243 - bailout("out of memory building methodDataOop"); 24.244 - return; 24.245 - } 24.246 + md = method->method_data_or_null(); 24.247 + assert(md != NULL, "Sanity"); 24.248 data = md->bci_to_data(bci); 24.249 assert(data != NULL, "need data for type check"); 24.250 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); 24.251 @@ -1690,7 +1731,7 @@ 24.252 } else if (obj == klass_RInfo) { 24.253 klass_RInfo = dst; 24.254 } 24.255 - if (k->is_loaded()) { 24.256 + if (k->is_loaded() && !UseCompressedOops) { 24.257 select_different_registers(obj, dst, k_RInfo, klass_RInfo); 24.258 } else { 24.259 Rtmp1 = op->tmp3()->as_register(); 24.260 @@ -1727,21 +1768,26 @@ 24.261 if (op->fast_check()) { 24.262 // get object class 24.263 // not a safepoint as obj null check happens earlier 24.264 - if (k->is_loaded()) { 24.265 #ifdef _LP64 24.266 - __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 24.267 -#else 24.268 - __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); 24.269 -#endif // _LP64 24.270 + if (UseCompressedOops) { 24.271 + __ load_klass(Rtmp1, obj); 24.272 + __ cmpptr(k_RInfo, Rtmp1); 24.273 } else { 24.274 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 24.275 } 24.276 +#else 24.277 + if (k->is_loaded()) { 24.278 + __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); 24.279 + } else { 24.280 + __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 24.281 + } 24.282 +#endif 24.283 __ jcc(Assembler::notEqual, *failure_target); 24.284 // successful cast, fall through to profile or jump 24.285 } else { 24.286 // get object class 24.287 // not a safepoint as obj null check happens earlier 24.288 - __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 24.289 + __ load_klass(klass_RInfo, obj); 24.290 if (k->is_loaded()) { 24.291 // See if we get an immediate positive hit 24.292 #ifdef _LP64 24.293 @@ -1796,7 +1842,7 @@ 24.294 Register mdo = klass_RInfo, recv = k_RInfo; 24.295 __ bind(profile_cast_success); 24.296 __ movoop(mdo, md->constant_encoding()); 24.297 - __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes())); 24.298 + __ load_klass(recv, obj); 24.299 Label update_done; 24.300 type_profile_helper(mdo, md, data, recv, success); 24.301 __ jmp(*success); 24.302 @@ -1830,11 +1876,8 @@ 24.303 ciMethod* method = op->profiled_method(); 24.304 assert(method != NULL, "Should have method"); 24.305 int bci = op->profiled_bci(); 24.306 - md = method->method_data(); 24.307 - if (md == NULL) { 24.308 - bailout("out of memory building methodDataOop"); 24.309 - return; 24.310 - } 24.311 + md = method->method_data_or_null(); 24.312 + assert(md != NULL, "Sanity"); 24.313 data = md->bci_to_data(bci); 24.314 assert(data != NULL, "need data for type check"); 24.315 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); 24.316 @@ -1860,10 +1903,10 @@ 24.317 } 24.318 24.319 add_debug_info_for_null_check_here(op->info_for_exception()); 24.320 - __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes())); 24.321 - __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes())); 24.322 - 24.323 - // get instance klass 24.324 + __ load_klass(k_RInfo, array); 24.325 + __ load_klass(klass_RInfo, value); 24.326 + 24.327 + // get instance klass (it's already uncompressed) 24.328 __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); 24.329 // perform the fast part of the checking logic 24.330 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); 24.331 @@ -1882,7 +1925,7 @@ 24.332 Register mdo = klass_RInfo, recv = k_RInfo; 24.333 __ bind(profile_cast_success); 24.334 __ movoop(mdo, md->constant_encoding()); 24.335 - __ movptr(recv, Address(value, oopDesc::klass_offset_in_bytes())); 24.336 + __ load_klass(recv, value); 24.337 Label update_done; 24.338 type_profile_helper(mdo, md, data, recv, &done); 24.339 __ jmpb(done); 24.340 @@ -1946,12 +1989,31 @@ 24.341 assert(cmpval != newval, "cmp and new values must be in different registers"); 24.342 assert(cmpval != addr, "cmp and addr must be in different registers"); 24.343 assert(newval != addr, "new value and addr must be in different registers"); 24.344 - if (os::is_MP()) { 24.345 - __ lock(); 24.346 - } 24.347 + 24.348 if ( op->code() == lir_cas_obj) { 24.349 - __ cmpxchgptr(newval, Address(addr, 0)); 24.350 - } else if (op->code() == lir_cas_int) { 24.351 +#ifdef _LP64 24.352 + if (UseCompressedOops) { 24.353 + __ encode_heap_oop(cmpval); 24.354 + __ mov(rscratch1, newval); 24.355 + __ encode_heap_oop(rscratch1); 24.356 + if (os::is_MP()) { 24.357 + __ lock(); 24.358 + } 24.359 + // cmpval (rax) is implicitly used by this instruction 24.360 + __ cmpxchgl(rscratch1, Address(addr, 0)); 24.361 + } else 24.362 +#endif 24.363 + { 24.364 + if (os::is_MP()) { 24.365 + __ lock(); 24.366 + } 24.367 + __ cmpxchgptr(newval, Address(addr, 0)); 24.368 + } 24.369 + } else { 24.370 + assert(op->code() == lir_cas_int, "lir_cas_int expected"); 24.371 + if (os::is_MP()) { 24.372 + __ lock(); 24.373 + } 24.374 __ cmpxchgl(newval, Address(addr, 0)); 24.375 } 24.376 #ifdef _LP64 24.377 @@ -3193,8 +3255,13 @@ 24.378 } 24.379 24.380 if (flags & LIR_OpArrayCopy::type_check) { 24.381 - __ movptr(tmp, src_klass_addr); 24.382 - __ cmpptr(tmp, dst_klass_addr); 24.383 + if (UseCompressedOops) { 24.384 + __ movl(tmp, src_klass_addr); 24.385 + __ cmpl(tmp, dst_klass_addr); 24.386 + } else { 24.387 + __ movptr(tmp, src_klass_addr); 24.388 + __ cmpptr(tmp, dst_klass_addr); 24.389 + } 24.390 __ jcc(Assembler::notEqual, *stub->entry()); 24.391 } 24.392 24.393 @@ -3209,13 +3276,23 @@ 24.394 // but not necessarily exactly of type default_type. 24.395 Label known_ok, halt; 24.396 __ movoop(tmp, default_type->constant_encoding()); 24.397 +#ifdef _LP64 24.398 + if (UseCompressedOops) { 24.399 + __ encode_heap_oop(tmp); 24.400 + } 24.401 +#endif 24.402 + 24.403 if (basic_type != T_OBJECT) { 24.404 - __ cmpptr(tmp, dst_klass_addr); 24.405 + 24.406 + if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr); 24.407 + else __ cmpptr(tmp, dst_klass_addr); 24.408 __ jcc(Assembler::notEqual, halt); 24.409 - __ cmpptr(tmp, src_klass_addr); 24.410 + if (UseCompressedOops) __ cmpl(tmp, src_klass_addr); 24.411 + else __ cmpptr(tmp, src_klass_addr); 24.412 __ jcc(Assembler::equal, known_ok); 24.413 } else { 24.414 - __ cmpptr(tmp, dst_klass_addr); 24.415 + if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr); 24.416 + else __ cmpptr(tmp, dst_klass_addr); 24.417 __ jcc(Assembler::equal, known_ok); 24.418 __ cmpptr(src, dst); 24.419 __ jcc(Assembler::equal, known_ok); 24.420 @@ -3289,11 +3366,8 @@ 24.421 int bci = op->profiled_bci(); 24.422 24.423 // Update counter for all call types 24.424 - ciMethodData* md = method->method_data(); 24.425 - if (md == NULL) { 24.426 - bailout("out of memory building methodDataOop"); 24.427 - return; 24.428 - } 24.429 + ciMethodData* md = method->method_data_or_null(); 24.430 + assert(md != NULL, "Sanity"); 24.431 ciProfileData* data = md->bci_to_data(bci); 24.432 assert(data->is_CounterData(), "need CounterData for calls"); 24.433 assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); 24.434 @@ -3344,7 +3418,7 @@ 24.435 } 24.436 } 24.437 } else { 24.438 - __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); 24.439 + __ load_klass(recv, recv); 24.440 Label update_done; 24.441 type_profile_helper(mdo, md, data, recv, &update_done); 24.442 // Receiver did not match any saved receiver and there is no empty row for it.
25.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Tue Dec 21 23:39:42 2010 -0500 25.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Dec 22 12:24:40 2010 -0500 25.3 @@ -874,6 +874,10 @@ 25.4 25.5 void LIRGenerator::do_ArrayCopy(Intrinsic* x) { 25.6 assert(x->number_of_arguments() == 5, "wrong type"); 25.7 + 25.8 + // Make all state_for calls early since they can emit code 25.9 + CodeEmitInfo* info = state_for(x, x->state()); 25.10 + 25.11 LIRItem src(x->argument_at(0), this); 25.12 LIRItem src_pos(x->argument_at(1), this); 25.13 LIRItem dst(x->argument_at(2), this); 25.14 @@ -916,7 +920,6 @@ 25.15 ciArrayKlass* expected_type; 25.16 arraycopy_helper(x, &flags, &expected_type); 25.17 25.18 - CodeEmitInfo* info = state_for(x, x->state()); // we may want to have stack (deoptimization?) 25.19 __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint 25.20 } 25.21 25.22 @@ -1151,9 +1154,12 @@ 25.23 stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); 25.24 } 25.25 LIR_Opr reg = rlock_result(x); 25.26 + LIR_Opr tmp3 = LIR_OprFact::illegalOpr; 25.27 + if (!x->klass()->is_loaded() || UseCompressedOops) { 25.28 + tmp3 = new_register(objectType); 25.29 + } 25.30 __ checkcast(reg, obj.result(), x->klass(), 25.31 - new_register(objectType), new_register(objectType), 25.32 - !x->klass()->is_loaded() ? new_register(objectType) : LIR_OprFact::illegalOpr, 25.33 + new_register(objectType), new_register(objectType), tmp3, 25.34 x->direct_compare(), info_for_exception, patching_info, stub, 25.35 x->profiled_method(), x->profiled_bci()); 25.36 } 25.37 @@ -1170,9 +1176,12 @@ 25.38 patching_info = state_for(x, x->state_before()); 25.39 } 25.40 obj.load_item(); 25.41 + LIR_Opr tmp3 = LIR_OprFact::illegalOpr; 25.42 + if (!x->klass()->is_loaded() || UseCompressedOops) { 25.43 + tmp3 = new_register(objectType); 25.44 + } 25.45 __ instanceof(reg, obj.result(), x->klass(), 25.46 - new_register(objectType), new_register(objectType), 25.47 - !x->klass()->is_loaded() ? new_register(objectType) : LIR_OprFact::illegalOpr, 25.48 + new_register(objectType), new_register(objectType), tmp3, 25.49 x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); 25.50 } 25.51
26.1 --- a/src/cpu/x86/vm/c1_LinearScan_x86.hpp Tue Dec 21 23:39:42 2010 -0500 26.2 +++ b/src/cpu/x86/vm/c1_LinearScan_x86.hpp Wed Dec 22 12:24:40 2010 -0500 26.3 @@ -31,18 +31,17 @@ 26.4 assert(FrameMap::rsp_opr->cpu_regnr() == 6, "wrong assumption below"); 26.5 assert(FrameMap::rbp_opr->cpu_regnr() == 7, "wrong assumption below"); 26.6 assert(reg_num >= 0, "invalid reg_num"); 26.7 - 26.8 - return reg_num < 6 || reg_num > 7; 26.9 #else 26.10 - // rsp and rbp, r10, r15 (numbers 6 ancd 7) are ignored 26.11 + // rsp and rbp, r10, r15 (numbers [12,15]) are ignored 26.12 + // r12 (number 11) is conditional on compressed oops. 26.13 + assert(FrameMap::r12_opr->cpu_regnr() == 11, "wrong assumption below"); 26.14 assert(FrameMap::r10_opr->cpu_regnr() == 12, "wrong assumption below"); 26.15 assert(FrameMap::r15_opr->cpu_regnr() == 13, "wrong assumption below"); 26.16 assert(FrameMap::rsp_opr->cpu_regnrLo() == 14, "wrong assumption below"); 26.17 assert(FrameMap::rbp_opr->cpu_regnrLo() == 15, "wrong assumption below"); 26.18 assert(reg_num >= 0, "invalid reg_num"); 26.19 - 26.20 - return reg_num < 12 || reg_num > 15; 26.21 #endif // _LP64 26.22 + return reg_num <= FrameMap::last_cpu_reg() || reg_num >= pd_nof_cpu_regs_frame_map; 26.23 } 26.24 26.25 inline int LinearScan::num_physical_regs(BasicType type) { 26.26 @@ -104,7 +103,7 @@ 26.27 if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::byte_reg)) { 26.28 assert(cur->type() != T_FLOAT && cur->type() != T_DOUBLE, "cpu regs only"); 26.29 _first_reg = pd_first_byte_reg; 26.30 - _last_reg = pd_last_byte_reg; 26.31 + _last_reg = FrameMap::last_byte_reg(); 26.32 return true; 26.33 } else if ((UseSSE >= 1 && cur->type() == T_FLOAT) || (UseSSE >= 2 && cur->type() == T_DOUBLE)) { 26.34 _first_reg = pd_first_xmm_reg;
27.1 --- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Tue Dec 21 23:39:42 2010 -0500 27.2 +++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Wed Dec 22 12:24:40 2010 -0500 27.3 @@ -155,11 +155,26 @@ 27.4 // This assumes that all prototype bits fit in an int32_t 27.5 movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype()); 27.6 } 27.7 +#ifdef _LP64 27.8 + if (UseCompressedOops) { // Take care not to kill klass 27.9 + movptr(t1, klass); 27.10 + encode_heap_oop_not_null(t1); 27.11 + movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1); 27.12 + } else 27.13 +#endif 27.14 + { 27.15 + movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass); 27.16 + } 27.17 27.18 - movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass); 27.19 if (len->is_valid()) { 27.20 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len); 27.21 } 27.22 +#ifdef _LP64 27.23 + else if (UseCompressedOops) { 27.24 + xorptr(t1, t1); 27.25 + store_klass_gap(obj, t1); 27.26 + } 27.27 +#endif 27.28 } 27.29 27.30 27.31 @@ -230,7 +245,7 @@ 27.32 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) { 27.33 assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0, 27.34 "con_size_in_bytes is not multiple of alignment"); 27.35 - const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes(); 27.36 + const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; 27.37 27.38 initialize_header(obj, klass, noreg, t1, t2); 27.39 27.40 @@ -317,13 +332,19 @@ 27.41 // check against inline cache 27.42 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); 27.43 int start_offset = offset(); 27.44 - cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes())); 27.45 + 27.46 + if (UseCompressedOops) { 27.47 + load_klass(rscratch1, receiver); 27.48 + cmpptr(rscratch1, iCache); 27.49 + } else { 27.50 + cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes())); 27.51 + } 27.52 // if icache check fails, then jump to runtime routine 27.53 // Note: RECEIVER must still contain the receiver! 27.54 jump_cc(Assembler::notEqual, 27.55 RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 27.56 const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); 27.57 - assert(offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); 27.58 + assert(UseCompressedOops || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); 27.59 } 27.60 27.61
28.1 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Tue Dec 21 23:39:42 2010 -0500 28.2 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Dec 22 12:24:40 2010 -0500 28.3 @@ -1261,7 +1261,7 @@ 28.4 // load the klass and check the has finalizer flag 28.5 Label register_finalizer; 28.6 Register t = rsi; 28.7 - __ movptr(t, Address(rax, oopDesc::klass_offset_in_bytes())); 28.8 + __ load_klass(t, rax); 28.9 __ movl(t, Address(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); 28.10 __ testl(t, JVM_ACC_HAS_FINALIZER); 28.11 __ jcc(Assembler::notZero, register_finalizer);
29.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Tue Dec 21 23:39:42 2010 -0500 29.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Dec 22 12:24:40 2010 -0500 29.3 @@ -2197,9 +2197,6 @@ 29.4 29.5 __ enter(); // required for proper stackwalking of RuntimeStub frame 29.6 29.7 - checkcast_copy_entry = __ pc(); 29.8 - BLOCK_COMMENT("Entry:"); 29.9 - 29.10 #ifdef ASSERT 29.11 // caller guarantees that the arrays really are different 29.12 // otherwise, we would have to make conjoint checks 29.13 @@ -2210,26 +2207,28 @@ 29.14 } 29.15 #endif //ASSERT 29.16 29.17 - // allocate spill slots for r13, r14 29.18 - enum { 29.19 - saved_r13_offset, 29.20 - saved_r14_offset, 29.21 - saved_rbp_offset, 29.22 - saved_rip_offset, 29.23 - saved_rarg0_offset 29.24 - }; 29.25 - __ subptr(rsp, saved_rbp_offset * wordSize); 29.26 - __ movptr(Address(rsp, saved_r13_offset * wordSize), r13); 29.27 - __ movptr(Address(rsp, saved_r14_offset * wordSize), r14); 29.28 setup_arg_regs(4); // from => rdi, to => rsi, length => rdx 29.29 // ckoff => rcx, ckval => r8 29.30 // r9 and r10 may be used to save non-volatile registers 29.31 #ifdef _WIN64 29.32 // last argument (#4) is on stack on Win64 29.33 - const int ckval_offset = saved_rarg0_offset + 4; 29.34 - __ movptr(ckval, Address(rsp, ckval_offset * wordSize)); 29.35 + __ movptr(ckval, Address(rsp, 6 * wordSize)); 29.36 #endif 29.37 29.38 + // Caller of this entry point must set up the argument registers. 29.39 + checkcast_copy_entry = __ pc(); 29.40 + BLOCK_COMMENT("Entry:"); 29.41 + 29.42 + // allocate spill slots for r13, r14 29.43 + enum { 29.44 + saved_r13_offset, 29.45 + saved_r14_offset, 29.46 + saved_rbp_offset 29.47 + }; 29.48 + __ subptr(rsp, saved_rbp_offset * wordSize); 29.49 + __ movptr(Address(rsp, saved_r13_offset * wordSize), r13); 29.50 + __ movptr(Address(rsp, saved_r14_offset * wordSize), r14); 29.51 + 29.52 // check that int operands are properly extended to size_t 29.53 assert_clean_int(length, rax); 29.54 assert_clean_int(ckoff, rax); 29.55 @@ -2443,11 +2442,10 @@ 29.56 const Register src_pos = c_rarg1; // source position 29.57 const Register dst = c_rarg2; // destination array oop 29.58 const Register dst_pos = c_rarg3; // destination position 29.59 - // elements count is on stack on Win64 29.60 -#ifdef _WIN64 29.61 -#define C_RARG4 Address(rsp, 6 * wordSize) 29.62 +#ifndef _WIN64 29.63 + const Register length = c_rarg4; 29.64 #else 29.65 -#define C_RARG4 c_rarg4 29.66 + const Address length(rsp, 6 * wordSize); // elements count is on stack on Win64 29.67 #endif 29.68 29.69 { int modulus = CodeEntryAlignment; 29.70 @@ -2514,27 +2512,27 @@ 29.71 // registers used as temp 29.72 const Register r11_length = r11; // elements count to copy 29.73 const Register r10_src_klass = r10; // array klass 29.74 - const Register r9_dst_klass = r9; // dest array klass 29.75 29.76 // if (length < 0) return -1; 29.77 - __ movl(r11_length, C_RARG4); // length (elements count, 32-bits value) 29.78 + __ movl(r11_length, length); // length (elements count, 32-bits value) 29.79 __ testl(r11_length, r11_length); 29.80 __ jccb(Assembler::negative, L_failed_0); 29.81 29.82 __ load_klass(r10_src_klass, src); 29.83 #ifdef ASSERT 29.84 // assert(src->klass() != NULL); 29.85 - BLOCK_COMMENT("assert klasses not null"); 29.86 - { Label L1, L2; 29.87 + { 29.88 + BLOCK_COMMENT("assert klasses not null {"); 29.89 + Label L1, L2; 29.90 __ testptr(r10_src_klass, r10_src_klass); 29.91 __ jcc(Assembler::notZero, L2); // it is broken if klass is NULL 29.92 __ bind(L1); 29.93 __ stop("broken null klass"); 29.94 __ bind(L2); 29.95 - __ load_klass(r9_dst_klass, dst); 29.96 - __ cmpq(r9_dst_klass, 0); 29.97 + __ load_klass(rax, dst); 29.98 + __ cmpq(rax, 0); 29.99 __ jcc(Assembler::equal, L1); // this would be broken also 29.100 - BLOCK_COMMENT("assert done"); 29.101 + BLOCK_COMMENT("} assert klasses not null done"); 29.102 } 29.103 #endif 29.104 29.105 @@ -2546,34 +2544,36 @@ 29.106 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0 29.107 // 29.108 29.109 - int lh_offset = klassOopDesc::header_size() * HeapWordSize + 29.110 - Klass::layout_helper_offset_in_bytes(); 29.111 + const int lh_offset = klassOopDesc::header_size() * HeapWordSize + 29.112 + Klass::layout_helper_offset_in_bytes(); 29.113 + 29.114 + // Handle objArrays completely differently... 29.115 + const jint objArray_lh = Klass::array_layout_helper(T_OBJECT); 29.116 + __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh); 29.117 + __ jcc(Assembler::equal, L_objArray); 29.118 + 29.119 + // if (src->klass() != dst->klass()) return -1; 29.120 + __ load_klass(rax, dst); 29.121 + __ cmpq(r10_src_klass, rax); 29.122 + __ jcc(Assembler::notEqual, L_failed); 29.123 29.124 const Register rax_lh = rax; // layout helper 29.125 - 29.126 __ movl(rax_lh, Address(r10_src_klass, lh_offset)); 29.127 29.128 - // Handle objArrays completely differently... 29.129 - jint objArray_lh = Klass::array_layout_helper(T_OBJECT); 29.130 - __ cmpl(rax_lh, objArray_lh); 29.131 - __ jcc(Assembler::equal, L_objArray); 29.132 - 29.133 - // if (src->klass() != dst->klass()) return -1; 29.134 - __ load_klass(r9_dst_klass, dst); 29.135 - __ cmpq(r10_src_klass, r9_dst_klass); 29.136 - __ jcc(Assembler::notEqual, L_failed); 29.137 - 29.138 // if (!src->is_Array()) return -1; 29.139 __ cmpl(rax_lh, Klass::_lh_neutral_value); 29.140 __ jcc(Assembler::greaterEqual, L_failed); 29.141 29.142 // At this point, it is known to be a typeArray (array_tag 0x3). 29.143 #ifdef ASSERT 29.144 - { Label L; 29.145 + { 29.146 + BLOCK_COMMENT("assert primitive array {"); 29.147 + Label L; 29.148 __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift)); 29.149 __ jcc(Assembler::greaterEqual, L); 29.150 __ stop("must be a primitive array"); 29.151 __ bind(L); 29.152 + BLOCK_COMMENT("} assert primitive array done"); 29.153 } 29.154 #endif 29.155 29.156 @@ -2631,11 +2631,14 @@ 29.157 29.158 __ BIND(L_copy_longs); 29.159 #ifdef ASSERT 29.160 - { Label L; 29.161 + { 29.162 + BLOCK_COMMENT("assert long copy {"); 29.163 + Label L; 29.164 __ cmpl(rax_elsize, LogBytesPerLong); 29.165 __ jcc(Assembler::equal, L); 29.166 __ stop("must be long copy, but elsize is wrong"); 29.167 __ bind(L); 29.168 + BLOCK_COMMENT("} assert long copy done"); 29.169 } 29.170 #endif 29.171 __ lea(from, Address(src, src_pos, Address::times_8, 0));// src_addr 29.172 @@ -2645,12 +2648,12 @@ 29.173 29.174 // objArrayKlass 29.175 __ BIND(L_objArray); 29.176 - // live at this point: r10_src_klass, src[_pos], dst[_pos] 29.177 + // live at this point: r10_src_klass, r11_length, src[_pos], dst[_pos] 29.178 29.179 Label L_plain_copy, L_checkcast_copy; 29.180 // test array classes for subtyping 29.181 - __ load_klass(r9_dst_klass, dst); 29.182 - __ cmpq(r10_src_klass, r9_dst_klass); // usual case is exact equality 29.183 + __ load_klass(rax, dst); 29.184 + __ cmpq(r10_src_klass, rax); // usual case is exact equality 29.185 __ jcc(Assembler::notEqual, L_checkcast_copy); 29.186 29.187 // Identically typed arrays can be copied without element-wise checks. 29.188 @@ -2666,41 +2669,33 @@ 29.189 __ jump(RuntimeAddress(oop_copy_entry)); 29.190 29.191 __ BIND(L_checkcast_copy); 29.192 - // live at this point: r10_src_klass, !r11_length 29.193 + // live at this point: r10_src_klass, r11_length, rax (dst_klass) 29.194 { 29.195 - // assert(r11_length == C_RARG4); // will reload from here 29.196 - Register r11_dst_klass = r11; 29.197 - __ load_klass(r11_dst_klass, dst); 29.198 - 29.199 // Before looking at dst.length, make sure dst is also an objArray. 29.200 - __ cmpl(Address(r11_dst_klass, lh_offset), objArray_lh); 29.201 + __ cmpl(Address(rax, lh_offset), objArray_lh); 29.202 __ jcc(Assembler::notEqual, L_failed); 29.203 29.204 // It is safe to examine both src.length and dst.length. 29.205 -#ifndef _WIN64 29.206 - arraycopy_range_checks(src, src_pos, dst, dst_pos, C_RARG4, 29.207 - rax, L_failed); 29.208 -#else 29.209 - __ movl(r11_length, C_RARG4); // reload 29.210 arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length, 29.211 rax, L_failed); 29.212 + 29.213 + const Register r11_dst_klass = r11; 29.214 __ load_klass(r11_dst_klass, dst); // reload 29.215 -#endif 29.216 29.217 // Marshal the base address arguments now, freeing registers. 29.218 __ lea(from, Address(src, src_pos, TIMES_OOP, 29.219 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); 29.220 __ lea(to, Address(dst, dst_pos, TIMES_OOP, 29.221 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); 29.222 - __ movl(count, C_RARG4); // length (reloaded) 29.223 + __ movl(count, length); // length (reloaded) 29.224 Register sco_temp = c_rarg3; // this register is free now 29.225 assert_different_registers(from, to, count, sco_temp, 29.226 r11_dst_klass, r10_src_klass); 29.227 assert_clean_int(count, sco_temp); 29.228 29.229 // Generate the type check. 29.230 - int sco_offset = (klassOopDesc::header_size() * HeapWordSize + 29.231 - Klass::super_check_offset_offset_in_bytes()); 29.232 + const int sco_offset = (klassOopDesc::header_size() * HeapWordSize + 29.233 + Klass::super_check_offset_offset_in_bytes()); 29.234 __ movl(sco_temp, Address(r11_dst_klass, sco_offset)); 29.235 assert_clean_int(sco_temp, rax); 29.236 generate_type_check(r10_src_klass, sco_temp, r11_dst_klass, L_plain_copy); 29.237 @@ -2709,12 +2704,14 @@ 29.238 int ek_offset = (klassOopDesc::header_size() * HeapWordSize + 29.239 objArrayKlass::element_klass_offset_in_bytes()); 29.240 __ movptr(r11_dst_klass, Address(r11_dst_klass, ek_offset)); 29.241 - __ movl(sco_temp, Address(r11_dst_klass, sco_offset)); 29.242 + __ movl( sco_temp, Address(r11_dst_klass, sco_offset)); 29.243 assert_clean_int(sco_temp, rax); 29.244 29.245 // the checkcast_copy loop needs two extra arguments: 29.246 assert(c_rarg3 == sco_temp, "#3 already in place"); 29.247 - __ movptr(C_RARG4, r11_dst_klass); // dst.klass.element_klass 29.248 + // Set up arguments for checkcast_copy_entry. 29.249 + setup_arg_regs(4); 29.250 + __ movptr(r8, r11_dst_klass); // dst.klass.element_klass, r8 is c_rarg4 on Linux/Solaris 29.251 __ jump(RuntimeAddress(checkcast_copy_entry)); 29.252 } 29.253 29.254 @@ -2727,8 +2724,6 @@ 29.255 return start; 29.256 } 29.257 29.258 -#undef length_arg 29.259 - 29.260 void generate_arraycopy_stubs() { 29.261 // Call the conjoint generation methods immediately after 29.262 // the disjoint ones so that short branches from the former
30.1 --- a/src/cpu/x86/vm/x86_32.ad Tue Dec 21 23:39:42 2010 -0500 30.2 +++ b/src/cpu/x86/vm/x86_32.ad Wed Dec 22 12:24:40 2010 -0500 30.3 @@ -507,6 +507,25 @@ 30.4 30.5 30.6 //============================================================================= 30.7 +const bool Matcher::constant_table_absolute_addressing = true; 30.8 +const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 30.9 + 30.10 +void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 30.11 + // Empty encoding 30.12 +} 30.13 + 30.14 +uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 30.15 + return 0; 30.16 +} 30.17 + 30.18 +#ifndef PRODUCT 30.19 +void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 30.20 + st->print("# MachConstantBaseNode (empty encoding)"); 30.21 +} 30.22 +#endif 30.23 + 30.24 + 30.25 +//============================================================================= 30.26 #ifndef PRODUCT 30.27 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 30.28 Compile* C = ra_->C; 30.29 @@ -1320,29 +1339,6 @@ 30.30 } 30.31 30.32 30.33 -static void emit_double_constant(CodeBuffer& cbuf, double x) { 30.34 - int mark = cbuf.insts()->mark_off(); 30.35 - MacroAssembler _masm(&cbuf); 30.36 - address double_address = __ double_constant(x); 30.37 - cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift 30.38 - emit_d32_reloc(cbuf, 30.39 - (int)double_address, 30.40 - internal_word_Relocation::spec(double_address), 30.41 - RELOC_DISP32); 30.42 -} 30.43 - 30.44 -static void emit_float_constant(CodeBuffer& cbuf, float x) { 30.45 - int mark = cbuf.insts()->mark_off(); 30.46 - MacroAssembler _masm(&cbuf); 30.47 - address float_address = __ float_constant(x); 30.48 - cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift 30.49 - emit_d32_reloc(cbuf, 30.50 - (int)float_address, 30.51 - internal_word_Relocation::spec(float_address), 30.52 - RELOC_DISP32); 30.53 -} 30.54 - 30.55 - 30.56 const bool Matcher::match_rule_supported(int opcode) { 30.57 if (!has_match_rule(opcode)) 30.58 return false; 30.59 @@ -1354,22 +1350,6 @@ 30.60 return regnum - 32; // The FP registers are in the second chunk 30.61 } 30.62 30.63 -bool is_positive_zero_float(jfloat f) { 30.64 - return jint_cast(f) == jint_cast(0.0F); 30.65 -} 30.66 - 30.67 -bool is_positive_one_float(jfloat f) { 30.68 - return jint_cast(f) == jint_cast(1.0F); 30.69 -} 30.70 - 30.71 -bool is_positive_zero_double(jdouble d) { 30.72 - return jlong_cast(d) == jlong_cast(0.0); 30.73 -} 30.74 - 30.75 -bool is_positive_one_double(jdouble d) { 30.76 - return jlong_cast(d) == jlong_cast(1.0); 30.77 -} 30.78 - 30.79 // This is UltraSparc specific, true just means we have fast l2f conversion 30.80 const bool Matcher::convL2FSupported(void) { 30.81 return true; 30.82 @@ -2036,67 +2016,6 @@ 30.83 %} 30.84 30.85 30.86 - enc_class LdImmD (immD src) %{ // Load Immediate 30.87 - if( is_positive_zero_double($src$$constant)) { 30.88 - // FLDZ 30.89 - emit_opcode(cbuf,0xD9); 30.90 - emit_opcode(cbuf,0xEE); 30.91 - } else if( is_positive_one_double($src$$constant)) { 30.92 - // FLD1 30.93 - emit_opcode(cbuf,0xD9); 30.94 - emit_opcode(cbuf,0xE8); 30.95 - } else { 30.96 - emit_opcode(cbuf,0xDD); 30.97 - emit_rm(cbuf, 0x0, 0x0, 0x5); 30.98 - emit_double_constant(cbuf, $src$$constant); 30.99 - } 30.100 - %} 30.101 - 30.102 - 30.103 - enc_class LdImmF (immF src) %{ // Load Immediate 30.104 - if( is_positive_zero_float($src$$constant)) { 30.105 - emit_opcode(cbuf,0xD9); 30.106 - emit_opcode(cbuf,0xEE); 30.107 - } else if( is_positive_one_float($src$$constant)) { 30.108 - emit_opcode(cbuf,0xD9); 30.109 - emit_opcode(cbuf,0xE8); 30.110 - } else { 30.111 - $$$emit8$primary; 30.112 - // Load immediate does not have a zero or sign extended version 30.113 - // for 8-bit immediates 30.114 - // First load to TOS, then move to dst 30.115 - emit_rm(cbuf, 0x0, 0x0, 0x5); 30.116 - emit_float_constant(cbuf, $src$$constant); 30.117 - } 30.118 - %} 30.119 - 30.120 - enc_class LdImmX (regX dst, immXF con) %{ // Load Immediate 30.121 - emit_rm(cbuf, 0x0, $dst$$reg, 0x5); 30.122 - emit_float_constant(cbuf, $con$$constant); 30.123 - %} 30.124 - 30.125 - enc_class LdImmXD (regXD dst, immXD con) %{ // Load Immediate 30.126 - emit_rm(cbuf, 0x0, $dst$$reg, 0x5); 30.127 - emit_double_constant(cbuf, $con$$constant); 30.128 - %} 30.129 - 30.130 - enc_class load_conXD (regXD dst, immXD con) %{ // Load double constant 30.131 - // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con) 30.132 - emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 30.133 - emit_opcode(cbuf, 0x0F); 30.134 - emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12); 30.135 - emit_rm(cbuf, 0x0, $dst$$reg, 0x5); 30.136 - emit_double_constant(cbuf, $con$$constant); 30.137 - %} 30.138 - 30.139 - enc_class Opc_MemImm_F(immF src) %{ 30.140 - cbuf.set_insts_mark(); 30.141 - $$$emit8$primary; 30.142 - emit_rm(cbuf, 0x0, $secondary, 0x5); 30.143 - emit_float_constant(cbuf, $src$$constant); 30.144 - %} 30.145 - 30.146 - 30.147 enc_class MovI2X_reg(regX dst, eRegI src) %{ 30.148 emit_opcode(cbuf, 0x66 ); // MOVD dst,src 30.149 emit_opcode(cbuf, 0x0F ); 30.150 @@ -4801,7 +4720,7 @@ 30.151 interface(CONST_INTER); 30.152 %} 30.153 30.154 -// Double Immediate 30.155 +// Double Immediate one 30.156 operand immD1() %{ 30.157 predicate( UseSSE<=1 && n->getd() == 1.0 ); 30.158 match(ConD); 30.159 @@ -4844,7 +4763,17 @@ 30.160 30.161 // Float Immediate zero 30.162 operand immF0() %{ 30.163 - predicate( UseSSE == 0 && n->getf() == 0.0 ); 30.164 + predicate(UseSSE == 0 && n->getf() == 0.0F); 30.165 + match(ConF); 30.166 + 30.167 + op_cost(5); 30.168 + format %{ %} 30.169 + interface(CONST_INTER); 30.170 +%} 30.171 + 30.172 +// Float Immediate one 30.173 +operand immF1() %{ 30.174 + predicate(UseSSE == 0 && n->getf() == 1.0F); 30.175 match(ConF); 30.176 30.177 op_cost(5); 30.178 @@ -7215,24 +7144,53 @@ 30.179 %} 30.180 30.181 // The instruction usage is guarded by predicate in operand immF(). 30.182 -instruct loadConF(regF dst, immF src) %{ 30.183 - match(Set dst src); 30.184 +instruct loadConF(regF dst, immF con) %{ 30.185 + match(Set dst con); 30.186 ins_cost(125); 30.187 - 30.188 - format %{ "FLD_S ST,$src\n\t" 30.189 + format %{ "FLD_S ST,[$constantaddress]\t# load from constant table: float=$con\n\t" 30.190 "FSTP $dst" %} 30.191 - opcode(0xD9, 0x00); /* D9 /0 */ 30.192 - ins_encode(LdImmF(src), Pop_Reg_F(dst) ); 30.193 - ins_pipe( fpu_reg_con ); 30.194 + ins_encode %{ 30.195 + __ fld_s($constantaddress($con)); 30.196 + __ fstp_d($dst$$reg); 30.197 + %} 30.198 + ins_pipe(fpu_reg_con); 30.199 +%} 30.200 + 30.201 +// The instruction usage is guarded by predicate in operand immF0(). 30.202 +instruct loadConF0(regF dst, immF0 con) %{ 30.203 + match(Set dst con); 30.204 + ins_cost(125); 30.205 + format %{ "FLDZ ST\n\t" 30.206 + "FSTP $dst" %} 30.207 + ins_encode %{ 30.208 + __ fldz(); 30.209 + __ fstp_d($dst$$reg); 30.210 + %} 30.211 + ins_pipe(fpu_reg_con); 30.212 +%} 30.213 + 30.214 +// The instruction usage is guarded by predicate in operand immF1(). 30.215 +instruct loadConF1(regF dst, immF1 con) %{ 30.216 + match(Set dst con); 30.217 + ins_cost(125); 30.218 + format %{ "FLD1 ST\n\t" 30.219 + "FSTP $dst" %} 30.220 + ins_encode %{ 30.221 + __ fld1(); 30.222 + __ fstp_d($dst$$reg); 30.223 + %} 30.224 + ins_pipe(fpu_reg_con); 30.225 %} 30.226 30.227 // The instruction usage is guarded by predicate in operand immXF(). 30.228 instruct loadConX(regX dst, immXF con) %{ 30.229 match(Set dst con); 30.230 ins_cost(125); 30.231 - format %{ "MOVSS $dst,[$con]" %} 30.232 - ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), LdImmX(dst, con)); 30.233 - ins_pipe( pipe_slow ); 30.234 + format %{ "MOVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 30.235 + ins_encode %{ 30.236 + __ movflt($dst$$XMMRegister, $constantaddress($con)); 30.237 + %} 30.238 + ins_pipe(pipe_slow); 30.239 %} 30.240 30.241 // The instruction usage is guarded by predicate in operand immXF0(). 30.242 @@ -7240,28 +7198,63 @@ 30.243 match(Set dst src); 30.244 ins_cost(100); 30.245 format %{ "XORPS $dst,$dst\t# float 0.0" %} 30.246 - ins_encode( Opcode(0x0F), Opcode(0x57), RegReg(dst,dst)); 30.247 - ins_pipe( pipe_slow ); 30.248 + ins_encode %{ 30.249 + __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 30.250 + %} 30.251 + ins_pipe(pipe_slow); 30.252 %} 30.253 30.254 // The instruction usage is guarded by predicate in operand immD(). 30.255 -instruct loadConD(regD dst, immD src) %{ 30.256 - match(Set dst src); 30.257 +instruct loadConD(regD dst, immD con) %{ 30.258 + match(Set dst con); 30.259 ins_cost(125); 30.260 30.261 - format %{ "FLD_D ST,$src\n\t" 30.262 + format %{ "FLD_D ST,[$constantaddress]\t# load from constant table: double=$con\n\t" 30.263 "FSTP $dst" %} 30.264 - ins_encode(LdImmD(src), Pop_Reg_D(dst) ); 30.265 - ins_pipe( fpu_reg_con ); 30.266 + ins_encode %{ 30.267 + __ fld_d($constantaddress($con)); 30.268 + __ fstp_d($dst$$reg); 30.269 + %} 30.270 + ins_pipe(fpu_reg_con); 30.271 +%} 30.272 + 30.273 +// The instruction usage is guarded by predicate in operand immD0(). 30.274 +instruct loadConD0(regD dst, immD0 con) %{ 30.275 + match(Set dst con); 30.276 + ins_cost(125); 30.277 + 30.278 + format %{ "FLDZ ST\n\t" 30.279 + "FSTP $dst" %} 30.280 + ins_encode %{ 30.281 + __ fldz(); 30.282 + __ fstp_d($dst$$reg); 30.283 + %} 30.284 + ins_pipe(fpu_reg_con); 30.285 +%} 30.286 + 30.287 +// The instruction usage is guarded by predicate in operand immD1(). 30.288 +instruct loadConD1(regD dst, immD1 con) %{ 30.289 + match(Set dst con); 30.290 + ins_cost(125); 30.291 + 30.292 + format %{ "FLD1 ST\n\t" 30.293 + "FSTP $dst" %} 30.294 + ins_encode %{ 30.295 + __ fld1(); 30.296 + __ fstp_d($dst$$reg); 30.297 + %} 30.298 + ins_pipe(fpu_reg_con); 30.299 %} 30.300 30.301 // The instruction usage is guarded by predicate in operand immXD(). 30.302 instruct loadConXD(regXD dst, immXD con) %{ 30.303 match(Set dst con); 30.304 ins_cost(125); 30.305 - format %{ "MOVSD $dst,[$con]" %} 30.306 - ins_encode(load_conXD(dst, con)); 30.307 - ins_pipe( pipe_slow ); 30.308 + format %{ "MOVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 30.309 + ins_encode %{ 30.310 + __ movdbl($dst$$XMMRegister, $constantaddress($con)); 30.311 + %} 30.312 + ins_pipe(pipe_slow); 30.313 %} 30.314 30.315 // The instruction usage is guarded by predicate in operand immXD0(). 30.316 @@ -10303,41 +10296,45 @@ 30.317 ins_pipe( fpu_reg_mem ); 30.318 %} 30.319 30.320 -instruct addD_reg_imm1(regD dst, immD1 src) %{ 30.321 +instruct addD_reg_imm1(regD dst, immD1 con) %{ 30.322 predicate(UseSSE<=1); 30.323 - match(Set dst (AddD dst src)); 30.324 + match(Set dst (AddD dst con)); 30.325 ins_cost(125); 30.326 format %{ "FLD1\n\t" 30.327 "DADDp $dst,ST" %} 30.328 - opcode(0xDE, 0x00); 30.329 - ins_encode( LdImmD(src), 30.330 - OpcP, RegOpc(dst) ); 30.331 - ins_pipe( fpu_reg ); 30.332 -%} 30.333 - 30.334 -instruct addD_reg_imm(regD dst, immD src) %{ 30.335 + ins_encode %{ 30.336 + __ fld1(); 30.337 + __ faddp($dst$$reg); 30.338 + %} 30.339 + ins_pipe(fpu_reg); 30.340 +%} 30.341 + 30.342 +instruct addD_reg_imm(regD dst, immD con) %{ 30.343 predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 ); 30.344 - match(Set dst (AddD dst src)); 30.345 + match(Set dst (AddD dst con)); 30.346 ins_cost(200); 30.347 - format %{ "FLD_D [$src]\n\t" 30.348 + format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t" 30.349 "DADDp $dst,ST" %} 30.350 - opcode(0xDE, 0x00); /* DE /0 */ 30.351 - ins_encode( LdImmD(src), 30.352 - OpcP, RegOpc(dst)); 30.353 - ins_pipe( fpu_reg_mem ); 30.354 + ins_encode %{ 30.355 + __ fld_d($constantaddress($con)); 30.356 + __ faddp($dst$$reg); 30.357 + %} 30.358 + ins_pipe(fpu_reg_mem); 30.359 %} 30.360 30.361 instruct addD_reg_imm_round(stackSlotD dst, regD src, immD con) %{ 30.362 predicate(UseSSE<=1 && _kids[0]->_kids[1]->_leaf->getd() != 0.0 && _kids[0]->_kids[1]->_leaf->getd() != 1.0 ); 30.363 match(Set dst (RoundDouble (AddD src con))); 30.364 ins_cost(200); 30.365 - format %{ "FLD_D [$con]\n\t" 30.366 + format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t" 30.367 "DADD ST,$src\n\t" 30.368 "FSTP_D $dst\t# D-round" %} 30.369 - opcode(0xD8, 0x00); /* D8 /0 */ 30.370 - ins_encode( LdImmD(con), 30.371 - OpcP, RegOpc(src), Pop_Mem_D(dst)); 30.372 - ins_pipe( fpu_mem_reg_con ); 30.373 + ins_encode %{ 30.374 + __ fld_d($constantaddress($con)); 30.375 + __ fadd($src$$reg); 30.376 + __ fstp_d(Address(rsp, $dst$$disp)); 30.377 + %} 30.378 + ins_pipe(fpu_mem_reg_con); 30.379 %} 30.380 30.381 // Add two double precision floating point values in xmm 30.382 @@ -10352,9 +10349,11 @@ 30.383 instruct addXD_imm(regXD dst, immXD con) %{ 30.384 predicate(UseSSE>=2); 30.385 match(Set dst (AddD dst con)); 30.386 - format %{ "ADDSD $dst,[$con]" %} 30.387 - ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), LdImmXD(dst, con) ); 30.388 - ins_pipe( pipe_slow ); 30.389 + format %{ "ADDSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 30.390 + ins_encode %{ 30.391 + __ addsd($dst$$XMMRegister, $constantaddress($con)); 30.392 + %} 30.393 + ins_pipe(pipe_slow); 30.394 %} 30.395 30.396 instruct addXD_mem(regXD dst, memory mem) %{ 30.397 @@ -10377,9 +10376,11 @@ 30.398 instruct subXD_imm(regXD dst, immXD con) %{ 30.399 predicate(UseSSE>=2); 30.400 match(Set dst (SubD dst con)); 30.401 - format %{ "SUBSD $dst,[$con]" %} 30.402 - ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), LdImmXD(dst, con) ); 30.403 - ins_pipe( pipe_slow ); 30.404 + format %{ "SUBSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 30.405 + ins_encode %{ 30.406 + __ subsd($dst$$XMMRegister, $constantaddress($con)); 30.407 + %} 30.408 + ins_pipe(pipe_slow); 30.409 %} 30.410 30.411 instruct subXD_mem(regXD dst, memory mem) %{ 30.412 @@ -10402,9 +10403,11 @@ 30.413 instruct mulXD_imm(regXD dst, immXD con) %{ 30.414 predicate(UseSSE>=2); 30.415 match(Set dst (MulD dst con)); 30.416 - format %{ "MULSD $dst,[$con]" %} 30.417 - ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), LdImmXD(dst, con) ); 30.418 - ins_pipe( pipe_slow ); 30.419 + format %{ "MULSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 30.420 + ins_encode %{ 30.421 + __ mulsd($dst$$XMMRegister, $constantaddress($con)); 30.422 + %} 30.423 + ins_pipe(pipe_slow); 30.424 %} 30.425 30.426 instruct mulXD_mem(regXD dst, memory mem) %{ 30.427 @@ -10428,9 +10431,11 @@ 30.428 instruct divXD_imm(regXD dst, immXD con) %{ 30.429 predicate(UseSSE>=2); 30.430 match(Set dst (DivD dst con)); 30.431 - format %{ "DIVSD $dst,[$con]" %} 30.432 - ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), LdImmXD(dst, con)); 30.433 - ins_pipe( pipe_slow ); 30.434 + format %{ "DIVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 30.435 + ins_encode %{ 30.436 + __ divsd($dst$$XMMRegister, $constantaddress($con)); 30.437 + %} 30.438 + ins_pipe(pipe_slow); 30.439 %} 30.440 30.441 instruct divXD_mem(regXD dst, memory mem) %{ 30.442 @@ -10481,16 +10486,17 @@ 30.443 ins_pipe( fpu_reg_reg ); 30.444 %} 30.445 30.446 -instruct mulD_reg_imm(regD dst, immD src) %{ 30.447 +instruct mulD_reg_imm(regD dst, immD con) %{ 30.448 predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 ); 30.449 - match(Set dst (MulD dst src)); 30.450 + match(Set dst (MulD dst con)); 30.451 ins_cost(200); 30.452 - format %{ "FLD_D [$src]\n\t" 30.453 + format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t" 30.454 "DMULp $dst,ST" %} 30.455 - opcode(0xDE, 0x1); /* DE /1 */ 30.456 - ins_encode( LdImmD(src), 30.457 - OpcP, RegOpc(dst) ); 30.458 - ins_pipe( fpu_reg_mem ); 30.459 + ins_encode %{ 30.460 + __ fld_d($constantaddress($con)); 30.461 + __ fmulp($dst$$reg); 30.462 + %} 30.463 + ins_pipe(fpu_reg_mem); 30.464 %} 30.465 30.466 30.467 @@ -11224,9 +11230,11 @@ 30.468 instruct addX_imm(regX dst, immXF con) %{ 30.469 predicate(UseSSE>=1); 30.470 match(Set dst (AddF dst con)); 30.471 - format %{ "ADDSS $dst,[$con]" %} 30.472 - ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), LdImmX(dst, con) ); 30.473 - ins_pipe( pipe_slow ); 30.474 + format %{ "ADDSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 30.475 + ins_encode %{ 30.476 + __ addss($dst$$XMMRegister, $constantaddress($con)); 30.477 + %} 30.478 + ins_pipe(pipe_slow); 30.479 %} 30.480 30.481 instruct addX_mem(regX dst, memory mem) %{ 30.482 @@ -11249,9 +11257,11 @@ 30.483 instruct subX_imm(regX dst, immXF con) %{ 30.484 predicate(UseSSE>=1); 30.485 match(Set dst (SubF dst con)); 30.486 - format %{ "SUBSS $dst,[$con]" %} 30.487 - ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), LdImmX(dst, con) ); 30.488 - ins_pipe( pipe_slow ); 30.489 + format %{ "SUBSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 30.490 + ins_encode %{ 30.491 + __ subss($dst$$XMMRegister, $constantaddress($con)); 30.492 + %} 30.493 + ins_pipe(pipe_slow); 30.494 %} 30.495 30.496 instruct subX_mem(regX dst, memory mem) %{ 30.497 @@ -11274,9 +11284,11 @@ 30.498 instruct mulX_imm(regX dst, immXF con) %{ 30.499 predicate(UseSSE>=1); 30.500 match(Set dst (MulF dst con)); 30.501 - format %{ "MULSS $dst,[$con]" %} 30.502 - ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), LdImmX(dst, con) ); 30.503 - ins_pipe( pipe_slow ); 30.504 + format %{ "MULSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 30.505 + ins_encode %{ 30.506 + __ mulss($dst$$XMMRegister, $constantaddress($con)); 30.507 + %} 30.508 + ins_pipe(pipe_slow); 30.509 %} 30.510 30.511 instruct mulX_mem(regX dst, memory mem) %{ 30.512 @@ -11299,9 +11311,11 @@ 30.513 instruct divX_imm(regX dst, immXF con) %{ 30.514 predicate(UseSSE>=1); 30.515 match(Set dst (DivF dst con)); 30.516 - format %{ "DIVSS $dst,[$con]" %} 30.517 - ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), LdImmX(dst, con) ); 30.518 - ins_pipe( pipe_slow ); 30.519 + format %{ "DIVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 30.520 + ins_encode %{ 30.521 + __ divss($dst$$XMMRegister, $constantaddress($con)); 30.522 + %} 30.523 + ins_pipe(pipe_slow); 30.524 %} 30.525 30.526 instruct divX_mem(regX dst, memory mem) %{ 30.527 @@ -11456,31 +11470,33 @@ 30.528 30.529 30.530 // Spill to obtain 24-bit precision 30.531 -instruct addF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{ 30.532 +instruct addF24_reg_imm(stackSlotF dst, regF src, immF con) %{ 30.533 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 30.534 - match(Set dst (AddF src1 src2)); 30.535 - format %{ "FLD $src1\n\t" 30.536 - "FADD $src2\n\t" 30.537 + match(Set dst (AddF src con)); 30.538 + format %{ "FLD $src\n\t" 30.539 + "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t" 30.540 "FSTP_S $dst" %} 30.541 - opcode(0xD8, 0x00); /* D8 /0 */ 30.542 - ins_encode( Push_Reg_F(src1), 30.543 - Opc_MemImm_F(src2), 30.544 - Pop_Mem_F(dst)); 30.545 - ins_pipe( fpu_mem_reg_con ); 30.546 + ins_encode %{ 30.547 + __ fld_s($src$$reg - 1); // FLD ST(i-1) 30.548 + __ fadd_s($constantaddress($con)); 30.549 + __ fstp_s(Address(rsp, $dst$$disp)); 30.550 + %} 30.551 + ins_pipe(fpu_mem_reg_con); 30.552 %} 30.553 // 30.554 // This instruction does not round to 24-bits 30.555 -instruct addF_reg_imm(regF dst, regF src1, immF src2) %{ 30.556 +instruct addF_reg_imm(regF dst, regF src, immF con) %{ 30.557 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 30.558 - match(Set dst (AddF src1 src2)); 30.559 - format %{ "FLD $src1\n\t" 30.560 - "FADD $src2\n\t" 30.561 - "FSTP_S $dst" %} 30.562 - opcode(0xD8, 0x00); /* D8 /0 */ 30.563 - ins_encode( Push_Reg_F(src1), 30.564 - Opc_MemImm_F(src2), 30.565 - Pop_Reg_F(dst)); 30.566 - ins_pipe( fpu_reg_reg_con ); 30.567 + match(Set dst (AddF src con)); 30.568 + format %{ "FLD $src\n\t" 30.569 + "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t" 30.570 + "FSTP $dst" %} 30.571 + ins_encode %{ 30.572 + __ fld_s($src$$reg - 1); // FLD ST(i-1) 30.573 + __ fadd_s($constantaddress($con)); 30.574 + __ fstp_d($dst$$reg); 30.575 + %} 30.576 + ins_pipe(fpu_reg_reg_con); 30.577 %} 30.578 30.579 // Spill to obtain 24-bit precision 30.580 @@ -11559,29 +11575,35 @@ 30.581 %} 30.582 30.583 // Spill to obtain 24-bit precision 30.584 -instruct mulF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{ 30.585 +instruct mulF24_reg_imm(stackSlotF dst, regF src, immF con) %{ 30.586 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 30.587 - match(Set dst (MulF src1 src2)); 30.588 - 30.589 - format %{ "FMULc $dst,$src1,$src2" %} 30.590 - opcode(0xD8, 0x1); /* D8 /1*/ 30.591 - ins_encode( Push_Reg_F(src1), 30.592 - Opc_MemImm_F(src2), 30.593 - Pop_Mem_F(dst)); 30.594 - ins_pipe( fpu_mem_reg_con ); 30.595 + match(Set dst (MulF src con)); 30.596 + 30.597 + format %{ "FLD $src\n\t" 30.598 + "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t" 30.599 + "FSTP_S $dst" %} 30.600 + ins_encode %{ 30.601 + __ fld_s($src$$reg - 1); // FLD ST(i-1) 30.602 + __ fmul_s($constantaddress($con)); 30.603 + __ fstp_s(Address(rsp, $dst$$disp)); 30.604 + %} 30.605 + ins_pipe(fpu_mem_reg_con); 30.606 %} 30.607 // 30.608 // This instruction does not round to 24-bits 30.609 -instruct mulF_reg_imm(regF dst, regF src1, immF src2) %{ 30.610 +instruct mulF_reg_imm(regF dst, regF src, immF con) %{ 30.611 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 30.612 - match(Set dst (MulF src1 src2)); 30.613 - 30.614 - format %{ "FMULc $dst. $src1, $src2" %} 30.615 - opcode(0xD8, 0x1); /* D8 /1*/ 30.616 - ins_encode( Push_Reg_F(src1), 30.617 - Opc_MemImm_F(src2), 30.618 - Pop_Reg_F(dst)); 30.619 - ins_pipe( fpu_reg_reg_con ); 30.620 + match(Set dst (MulF src con)); 30.621 + 30.622 + format %{ "FLD $src\n\t" 30.623 + "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t" 30.624 + "FSTP $dst" %} 30.625 + ins_encode %{ 30.626 + __ fld_s($src$$reg - 1); // FLD ST(i-1) 30.627 + __ fmul_s($constantaddress($con)); 30.628 + __ fstp_d($dst$$reg); 30.629 + %} 30.630 + ins_pipe(fpu_reg_reg_con); 30.631 %} 30.632 30.633 30.634 @@ -12939,16 +12961,11 @@ 30.635 instruct jumpXtnd(eRegI switch_val) %{ 30.636 match(Jump switch_val); 30.637 ins_cost(350); 30.638 - 30.639 - format %{ "JMP [table_base](,$switch_val,1)\n\t" %} 30.640 - 30.641 - ins_encode %{ 30.642 - address table_base = __ address_table_constant(_index2label); 30.643 - 30.644 + format %{ "JMP [$constantaddress](,$switch_val,1)\n\t" %} 30.645 + ins_encode %{ 30.646 // Jump to Address(table_base + switch_reg) 30.647 - InternalAddress table(table_base); 30.648 Address index(noreg, $switch_val$$Register, Address::times_1); 30.649 - __ jump(ArrayAddress(table, index)); 30.650 + __ jump(ArrayAddress($constantaddress, index)); 30.651 %} 30.652 ins_pc_relative(1); 30.653 ins_pipe(pipe_jmp);
31.1 --- a/src/cpu/x86/vm/x86_64.ad Tue Dec 21 23:39:42 2010 -0500 31.2 +++ b/src/cpu/x86/vm/x86_64.ad Wed Dec 22 12:24:40 2010 -0500 31.3 @@ -833,6 +833,25 @@ 31.4 31.5 31.6 //============================================================================= 31.7 +const bool Matcher::constant_table_absolute_addressing = true; 31.8 +const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 31.9 + 31.10 +void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 31.11 + // Empty encoding 31.12 +} 31.13 + 31.14 +uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 31.15 + return 0; 31.16 +} 31.17 + 31.18 +#ifndef PRODUCT 31.19 +void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 31.20 + st->print("# MachConstantBaseNode (empty encoding)"); 31.21 +} 31.22 +#endif 31.23 + 31.24 + 31.25 +//============================================================================= 31.26 #ifndef PRODUCT 31.27 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const 31.28 { 31.29 @@ -1922,28 +1941,6 @@ 31.30 return offset; 31.31 } 31.32 31.33 -static void emit_double_constant(CodeBuffer& cbuf, double x) { 31.34 - int mark = cbuf.insts()->mark_off(); 31.35 - MacroAssembler _masm(&cbuf); 31.36 - address double_address = __ double_constant(x); 31.37 - cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift 31.38 - emit_d32_reloc(cbuf, 31.39 - (int) (double_address - cbuf.insts_end() - 4), 31.40 - internal_word_Relocation::spec(double_address), 31.41 - RELOC_DISP32); 31.42 -} 31.43 - 31.44 -static void emit_float_constant(CodeBuffer& cbuf, float x) { 31.45 - int mark = cbuf.insts()->mark_off(); 31.46 - MacroAssembler _masm(&cbuf); 31.47 - address float_address = __ float_constant(x); 31.48 - cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift 31.49 - emit_d32_reloc(cbuf, 31.50 - (int) (float_address - cbuf.insts_end() - 4), 31.51 - internal_word_Relocation::spec(float_address), 31.52 - RELOC_DISP32); 31.53 -} 31.54 - 31.55 31.56 const bool Matcher::match_rule_supported(int opcode) { 31.57 if (!has_match_rule(opcode)) 31.58 @@ -2789,43 +2786,6 @@ 31.59 } 31.60 %} 31.61 31.62 - enc_class load_immF(regF dst, immF con) 31.63 - %{ 31.64 - // XXX reg_mem doesn't support RIP-relative addressing yet 31.65 - emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101 31.66 - emit_float_constant(cbuf, $con$$constant); 31.67 - %} 31.68 - 31.69 - enc_class load_immD(regD dst, immD con) 31.70 - %{ 31.71 - // XXX reg_mem doesn't support RIP-relative addressing yet 31.72 - emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101 31.73 - emit_double_constant(cbuf, $con$$constant); 31.74 - %} 31.75 - 31.76 - enc_class load_conF (regF dst, immF con) %{ // Load float constant 31.77 - emit_opcode(cbuf, 0xF3); 31.78 - if ($dst$$reg >= 8) { 31.79 - emit_opcode(cbuf, Assembler::REX_R); 31.80 - } 31.81 - emit_opcode(cbuf, 0x0F); 31.82 - emit_opcode(cbuf, 0x10); 31.83 - emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101 31.84 - emit_float_constant(cbuf, $con$$constant); 31.85 - %} 31.86 - 31.87 - enc_class load_conD (regD dst, immD con) %{ // Load double constant 31.88 - // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con) 31.89 - emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 31.90 - if ($dst$$reg >= 8) { 31.91 - emit_opcode(cbuf, Assembler::REX_R); 31.92 - } 31.93 - emit_opcode(cbuf, 0x0F); 31.94 - emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12); 31.95 - emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101 31.96 - emit_double_constant(cbuf, $con$$constant); 31.97 - %} 31.98 - 31.99 // Encode a reg-reg copy. If it is useless, then empty encoding. 31.100 enc_class enc_copy(rRegI dst, rRegI src) 31.101 %{ 31.102 @@ -2926,63 +2886,6 @@ 31.103 emit_d32(cbuf, 0x00); 31.104 %} 31.105 31.106 - enc_class jump_enc(rRegL switch_val, rRegI dest) %{ 31.107 - MacroAssembler masm(&cbuf); 31.108 - 31.109 - Register switch_reg = as_Register($switch_val$$reg); 31.110 - Register dest_reg = as_Register($dest$$reg); 31.111 - address table_base = masm.address_table_constant(_index2label); 31.112 - 31.113 - // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 31.114 - // to do that and the compiler is using that register as one it can allocate. 31.115 - // So we build it all by hand. 31.116 - // Address index(noreg, switch_reg, Address::times_1); 31.117 - // ArrayAddress dispatch(table, index); 31.118 - 31.119 - Address dispatch(dest_reg, switch_reg, Address::times_1); 31.120 - 31.121 - masm.lea(dest_reg, InternalAddress(table_base)); 31.122 - masm.jmp(dispatch); 31.123 - %} 31.124 - 31.125 - enc_class jump_enc_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 31.126 - MacroAssembler masm(&cbuf); 31.127 - 31.128 - Register switch_reg = as_Register($switch_val$$reg); 31.129 - Register dest_reg = as_Register($dest$$reg); 31.130 - address table_base = masm.address_table_constant(_index2label); 31.131 - 31.132 - // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 31.133 - // to do that and the compiler is using that register as one it can allocate. 31.134 - // So we build it all by hand. 31.135 - // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant); 31.136 - // ArrayAddress dispatch(table, index); 31.137 - 31.138 - Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant); 31.139 - 31.140 - masm.lea(dest_reg, InternalAddress(table_base)); 31.141 - masm.jmp(dispatch); 31.142 - %} 31.143 - 31.144 - enc_class jump_enc_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 31.145 - MacroAssembler masm(&cbuf); 31.146 - 31.147 - Register switch_reg = as_Register($switch_val$$reg); 31.148 - Register dest_reg = as_Register($dest$$reg); 31.149 - address table_base = masm.address_table_constant(_index2label); 31.150 - 31.151 - // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 31.152 - // to do that and the compiler is using that register as one it can allocate. 31.153 - // So we build it all by hand. 31.154 - // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 31.155 - // ArrayAddress dispatch(table, index); 31.156 - 31.157 - Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant); 31.158 - masm.lea(dest_reg, InternalAddress(table_base)); 31.159 - masm.jmp(dispatch); 31.160 - 31.161 - %} 31.162 - 31.163 enc_class lock_prefix() 31.164 %{ 31.165 if (os::is_MP()) { 31.166 @@ -6641,12 +6544,11 @@ 31.167 ins_pipe(ialu_reg); 31.168 %} 31.169 31.170 -instruct loadConP(rRegP dst, immP src) 31.171 -%{ 31.172 - match(Set dst src); 31.173 - 31.174 - format %{ "movq $dst, $src\t# ptr" %} 31.175 - ins_encode(load_immP(dst, src)); 31.176 +instruct loadConP(rRegP dst, immP con) %{ 31.177 + match(Set dst con); 31.178 + 31.179 + format %{ "movq $dst, $con\t# ptr" %} 31.180 + ins_encode(load_immP(dst, con)); 31.181 ins_pipe(ialu_reg_fat); // XXX 31.182 %} 31.183 31.184 @@ -6673,13 +6575,13 @@ 31.185 ins_pipe(ialu_reg); 31.186 %} 31.187 31.188 -instruct loadConF(regF dst, immF src) 31.189 -%{ 31.190 - match(Set dst src); 31.191 +instruct loadConF(regF dst, immF con) %{ 31.192 + match(Set dst con); 31.193 ins_cost(125); 31.194 - 31.195 - format %{ "movss $dst, [$src]" %} 31.196 - ins_encode(load_conF(dst, src)); 31.197 + format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 31.198 + ins_encode %{ 31.199 + __ movflt($dst$$XMMRegister, $constantaddress($con)); 31.200 + %} 31.201 ins_pipe(pipe_slow); 31.202 %} 31.203 31.204 @@ -6721,13 +6623,13 @@ 31.205 %} 31.206 31.207 // Use the same format since predicate() can not be used here. 31.208 -instruct loadConD(regD dst, immD src) 31.209 -%{ 31.210 - match(Set dst src); 31.211 +instruct loadConD(regD dst, immD con) %{ 31.212 + match(Set dst con); 31.213 ins_cost(125); 31.214 - 31.215 - format %{ "movsd $dst, [$src]" %} 31.216 - ins_encode(load_conD(dst, src)); 31.217 + format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 31.218 + ins_encode %{ 31.219 + __ movdbl($dst$$XMMRegister, $constantaddress($con)); 31.220 + %} 31.221 ins_pipe(pipe_slow); 31.222 %} 31.223 31.224 @@ -7694,9 +7596,18 @@ 31.225 predicate(false); 31.226 effect(TEMP dest); 31.227 31.228 - format %{ "leaq $dest, table_base\n\t" 31.229 + format %{ "leaq $dest, [$constantaddress]\n\t" 31.230 "jmp [$dest + $switch_val << $shift]\n\t" %} 31.231 - ins_encode(jump_enc_offset(switch_val, shift, dest)); 31.232 + ins_encode %{ 31.233 + // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 31.234 + // to do that and the compiler is using that register as one it can allocate. 31.235 + // So we build it all by hand. 31.236 + // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 31.237 + // ArrayAddress dispatch(table, index); 31.238 + Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 31.239 + __ lea($dest$$Register, $constantaddress); 31.240 + __ jmp(dispatch); 31.241 + %} 31.242 ins_pipe(pipe_jmp); 31.243 ins_pc_relative(1); 31.244 %} 31.245 @@ -7706,9 +7617,18 @@ 31.246 ins_cost(350); 31.247 effect(TEMP dest); 31.248 31.249 - format %{ "leaq $dest, table_base\n\t" 31.250 + format %{ "leaq $dest, [$constantaddress]\n\t" 31.251 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 31.252 - ins_encode(jump_enc_addr(switch_val, shift, offset, dest)); 31.253 + ins_encode %{ 31.254 + // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 31.255 + // to do that and the compiler is using that register as one it can allocate. 31.256 + // So we build it all by hand. 31.257 + // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 31.258 + // ArrayAddress dispatch(table, index); 31.259 + Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 31.260 + __ lea($dest$$Register, $constantaddress); 31.261 + __ jmp(dispatch); 31.262 + %} 31.263 ins_pipe(pipe_jmp); 31.264 ins_pc_relative(1); 31.265 %} 31.266 @@ -7718,9 +7638,18 @@ 31.267 ins_cost(350); 31.268 effect(TEMP dest); 31.269 31.270 - format %{ "leaq $dest, table_base\n\t" 31.271 + format %{ "leaq $dest, [$constantaddress]\n\t" 31.272 "jmp [$dest + $switch_val]\n\t" %} 31.273 - ins_encode(jump_enc(switch_val, dest)); 31.274 + ins_encode %{ 31.275 + // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 31.276 + // to do that and the compiler is using that register as one it can allocate. 31.277 + // So we build it all by hand. 31.278 + // Address index(noreg, switch_reg, Address::times_1); 31.279 + // ArrayAddress dispatch(table, index); 31.280 + Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 31.281 + __ lea($dest$$Register, $constantaddress); 31.282 + __ jmp(dispatch); 31.283 + %} 31.284 ins_pipe(pipe_jmp); 31.285 ins_pc_relative(1); 31.286 %} 31.287 @@ -10376,30 +10305,36 @@ 31.288 ins_pipe(pipe_slow); 31.289 %} 31.290 31.291 -instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2) 31.292 -%{ 31.293 - match(Set cr (CmpF src1 src2)); 31.294 +instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 31.295 + match(Set cr (CmpF src con)); 31.296 31.297 ins_cost(145); 31.298 - format %{ "ucomiss $src1, $src2\n\t" 31.299 + format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 31.300 "jnp,s exit\n\t" 31.301 "pushfq\t# saw NaN, set CF\n\t" 31.302 "andq [rsp], #0xffffff2b\n\t" 31.303 "popfq\n" 31.304 "exit: nop\t# avoid branch to branch" %} 31.305 - opcode(0x0F, 0x2E); 31.306 - ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2), 31.307 - cmpfp_fixup); 31.308 - ins_pipe(pipe_slow); 31.309 -%} 31.310 - 31.311 -instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{ 31.312 - match(Set cr (CmpF src1 src2)); 31.313 - 31.314 + ins_encode %{ 31.315 + Label L_exit; 31.316 + __ ucomiss($src$$XMMRegister, $constantaddress($con)); 31.317 + __ jcc(Assembler::noParity, L_exit); 31.318 + __ pushf(); 31.319 + __ andq(rsp, 0xffffff2b); 31.320 + __ popf(); 31.321 + __ bind(L_exit); 31.322 + __ nop(); 31.323 + %} 31.324 + ins_pipe(pipe_slow); 31.325 +%} 31.326 + 31.327 +instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 31.328 + match(Set cr (CmpF src con)); 31.329 ins_cost(100); 31.330 - format %{ "ucomiss $src1, $src2" %} 31.331 - opcode(0x0F, 0x2E); 31.332 - ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2)); 31.333 + format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 31.334 + ins_encode %{ 31.335 + __ ucomiss($src$$XMMRegister, $constantaddress($con)); 31.336 + %} 31.337 ins_pipe(pipe_slow); 31.338 %} 31.339 31.340 @@ -10458,30 +10393,36 @@ 31.341 ins_pipe(pipe_slow); 31.342 %} 31.343 31.344 -instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2) 31.345 -%{ 31.346 - match(Set cr (CmpD src1 src2)); 31.347 +instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 31.348 + match(Set cr (CmpD src con)); 31.349 31.350 ins_cost(145); 31.351 - format %{ "ucomisd $src1, [$src2]\n\t" 31.352 + format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 31.353 "jnp,s exit\n\t" 31.354 "pushfq\t# saw NaN, set CF\n\t" 31.355 "andq [rsp], #0xffffff2b\n\t" 31.356 "popfq\n" 31.357 "exit: nop\t# avoid branch to branch" %} 31.358 - opcode(0x66, 0x0F, 0x2E); 31.359 - ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2), 31.360 - cmpfp_fixup); 31.361 - ins_pipe(pipe_slow); 31.362 -%} 31.363 - 31.364 -instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{ 31.365 - match(Set cr (CmpD src1 src2)); 31.366 - 31.367 + ins_encode %{ 31.368 + Label L_exit; 31.369 + __ ucomisd($src$$XMMRegister, $constantaddress($con)); 31.370 + __ jcc(Assembler::noParity, L_exit); 31.371 + __ pushf(); 31.372 + __ andq(rsp, 0xffffff2b); 31.373 + __ popf(); 31.374 + __ bind(L_exit); 31.375 + __ nop(); 31.376 + %} 31.377 + ins_pipe(pipe_slow); 31.378 +%} 31.379 + 31.380 +instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 31.381 + match(Set cr (CmpD src con)); 31.382 ins_cost(100); 31.383 - format %{ "ucomisd $src1, [$src2]" %} 31.384 - opcode(0x66, 0x0F, 0x2E); 31.385 - ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2)); 31.386 + format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 31.387 + ins_encode %{ 31.388 + __ ucomisd($src$$XMMRegister, $constantaddress($con)); 31.389 + %} 31.390 ins_pipe(pipe_slow); 31.391 %} 31.392 31.393 @@ -10528,23 +10469,29 @@ 31.394 %} 31.395 31.396 // Compare into -1,0,1 31.397 -instruct cmpF_imm(rRegI dst, regF src1, immF src2, rFlagsReg cr) 31.398 -%{ 31.399 - match(Set dst (CmpF3 src1 src2)); 31.400 +instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 31.401 + match(Set dst (CmpF3 src con)); 31.402 effect(KILL cr); 31.403 31.404 ins_cost(275); 31.405 - format %{ "ucomiss $src1, [$src2]\n\t" 31.406 + format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 31.407 "movl $dst, #-1\n\t" 31.408 "jp,s done\n\t" 31.409 "jb,s done\n\t" 31.410 "setne $dst\n\t" 31.411 "movzbl $dst, $dst\n" 31.412 "done:" %} 31.413 - 31.414 - opcode(0x0F, 0x2E); 31.415 - ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2), 31.416 - cmpfp3(dst)); 31.417 + ins_encode %{ 31.418 + Label L_done; 31.419 + Register Rdst = $dst$$Register; 31.420 + __ ucomiss($src$$XMMRegister, $constantaddress($con)); 31.421 + __ movl(Rdst, -1); 31.422 + __ jcc(Assembler::parity, L_done); 31.423 + __ jcc(Assembler::below, L_done); 31.424 + __ setb(Assembler::notEqual, Rdst); 31.425 + __ movzbl(Rdst, Rdst); 31.426 + __ bind(L_done); 31.427 + %} 31.428 ins_pipe(pipe_slow); 31.429 %} 31.430 31.431 @@ -10591,23 +10538,29 @@ 31.432 %} 31.433 31.434 // Compare into -1,0,1 31.435 -instruct cmpD_imm(rRegI dst, regD src1, immD src2, rFlagsReg cr) 31.436 -%{ 31.437 - match(Set dst (CmpD3 src1 src2)); 31.438 +instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 31.439 + match(Set dst (CmpD3 src con)); 31.440 effect(KILL cr); 31.441 31.442 ins_cost(275); 31.443 - format %{ "ucomisd $src1, [$src2]\n\t" 31.444 + format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 31.445 "movl $dst, #-1\n\t" 31.446 "jp,s done\n\t" 31.447 "jb,s done\n\t" 31.448 "setne $dst\n\t" 31.449 "movzbl $dst, $dst\n" 31.450 "done:" %} 31.451 - 31.452 - opcode(0x66, 0x0F, 0x2E); 31.453 - ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2), 31.454 - cmpfp3(dst)); 31.455 + ins_encode %{ 31.456 + Register Rdst = $dst$$Register; 31.457 + Label L_done; 31.458 + __ ucomisd($src$$XMMRegister, $constantaddress($con)); 31.459 + __ movl(Rdst, -1); 31.460 + __ jcc(Assembler::parity, L_done); 31.461 + __ jcc(Assembler::below, L_done); 31.462 + __ setb(Assembler::notEqual, Rdst); 31.463 + __ movzbl(Rdst, Rdst); 31.464 + __ bind(L_done); 31.465 + %} 31.466 ins_pipe(pipe_slow); 31.467 %} 31.468 31.469 @@ -10633,14 +10586,13 @@ 31.470 ins_pipe(pipe_slow); 31.471 %} 31.472 31.473 -instruct addF_imm(regF dst, immF src) 31.474 -%{ 31.475 - match(Set dst (AddF dst src)); 31.476 - 31.477 - format %{ "addss $dst, [$src]" %} 31.478 +instruct addF_imm(regF dst, immF con) %{ 31.479 + match(Set dst (AddF dst con)); 31.480 + format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 31.481 ins_cost(150); // XXX 31.482 - opcode(0xF3, 0x0F, 0x58); 31.483 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 31.484 + ins_encode %{ 31.485 + __ addss($dst$$XMMRegister, $constantaddress($con)); 31.486 + %} 31.487 ins_pipe(pipe_slow); 31.488 %} 31.489 31.490 @@ -10666,14 +10618,13 @@ 31.491 ins_pipe(pipe_slow); 31.492 %} 31.493 31.494 -instruct addD_imm(regD dst, immD src) 31.495 -%{ 31.496 - match(Set dst (AddD dst src)); 31.497 - 31.498 - format %{ "addsd $dst, [$src]" %} 31.499 +instruct addD_imm(regD dst, immD con) %{ 31.500 + match(Set dst (AddD dst con)); 31.501 + format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 31.502 ins_cost(150); // XXX 31.503 - opcode(0xF2, 0x0F, 0x58); 31.504 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 31.505 + ins_encode %{ 31.506 + __ addsd($dst$$XMMRegister, $constantaddress($con)); 31.507 + %} 31.508 ins_pipe(pipe_slow); 31.509 %} 31.510 31.511 @@ -10699,14 +10650,13 @@ 31.512 ins_pipe(pipe_slow); 31.513 %} 31.514 31.515 -instruct subF_imm(regF dst, immF src) 31.516 -%{ 31.517 - match(Set dst (SubF dst src)); 31.518 - 31.519 - format %{ "subss $dst, [$src]" %} 31.520 +instruct subF_imm(regF dst, immF con) %{ 31.521 + match(Set dst (SubF dst con)); 31.522 + format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 31.523 ins_cost(150); // XXX 31.524 - opcode(0xF3, 0x0F, 0x5C); 31.525 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 31.526 + ins_encode %{ 31.527 + __ subss($dst$$XMMRegister, $constantaddress($con)); 31.528 + %} 31.529 ins_pipe(pipe_slow); 31.530 %} 31.531 31.532 @@ -10732,14 +10682,13 @@ 31.533 ins_pipe(pipe_slow); 31.534 %} 31.535 31.536 -instruct subD_imm(regD dst, immD src) 31.537 -%{ 31.538 - match(Set dst (SubD dst src)); 31.539 - 31.540 - format %{ "subsd $dst, [$src]" %} 31.541 +instruct subD_imm(regD dst, immD con) %{ 31.542 + match(Set dst (SubD dst con)); 31.543 + format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 31.544 ins_cost(150); // XXX 31.545 - opcode(0xF2, 0x0F, 0x5C); 31.546 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 31.547 + ins_encode %{ 31.548 + __ subsd($dst$$XMMRegister, $constantaddress($con)); 31.549 + %} 31.550 ins_pipe(pipe_slow); 31.551 %} 31.552 31.553 @@ -10765,14 +10714,13 @@ 31.554 ins_pipe(pipe_slow); 31.555 %} 31.556 31.557 -instruct mulF_imm(regF dst, immF src) 31.558 -%{ 31.559 - match(Set dst (MulF dst src)); 31.560 - 31.561 - format %{ "mulss $dst, [$src]" %} 31.562 +instruct mulF_imm(regF dst, immF con) %{ 31.563 + match(Set dst (MulF dst con)); 31.564 + format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 31.565 ins_cost(150); // XXX 31.566 - opcode(0xF3, 0x0F, 0x59); 31.567 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 31.568 + ins_encode %{ 31.569 + __ mulss($dst$$XMMRegister, $constantaddress($con)); 31.570 + %} 31.571 ins_pipe(pipe_slow); 31.572 %} 31.573 31.574 @@ -10798,14 +10746,13 @@ 31.575 ins_pipe(pipe_slow); 31.576 %} 31.577 31.578 -instruct mulD_imm(regD dst, immD src) 31.579 -%{ 31.580 - match(Set dst (MulD dst src)); 31.581 - 31.582 - format %{ "mulsd $dst, [$src]" %} 31.583 +instruct mulD_imm(regD dst, immD con) %{ 31.584 + match(Set dst (MulD dst con)); 31.585 + format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 31.586 ins_cost(150); // XXX 31.587 - opcode(0xF2, 0x0F, 0x59); 31.588 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 31.589 + ins_encode %{ 31.590 + __ mulsd($dst$$XMMRegister, $constantaddress($con)); 31.591 + %} 31.592 ins_pipe(pipe_slow); 31.593 %} 31.594 31.595 @@ -10831,14 +10778,13 @@ 31.596 ins_pipe(pipe_slow); 31.597 %} 31.598 31.599 -instruct divF_imm(regF dst, immF src) 31.600 -%{ 31.601 - match(Set dst (DivF dst src)); 31.602 - 31.603 - format %{ "divss $dst, [$src]" %} 31.604 +instruct divF_imm(regF dst, immF con) %{ 31.605 + match(Set dst (DivF dst con)); 31.606 + format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 31.607 ins_cost(150); // XXX 31.608 - opcode(0xF3, 0x0F, 0x5E); 31.609 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 31.610 + ins_encode %{ 31.611 + __ divss($dst$$XMMRegister, $constantaddress($con)); 31.612 + %} 31.613 ins_pipe(pipe_slow); 31.614 %} 31.615 31.616 @@ -10864,14 +10810,13 @@ 31.617 ins_pipe(pipe_slow); 31.618 %} 31.619 31.620 -instruct divD_imm(regD dst, immD src) 31.621 -%{ 31.622 - match(Set dst (DivD dst src)); 31.623 - 31.624 - format %{ "divsd $dst, [$src]" %} 31.625 +instruct divD_imm(regD dst, immD con) %{ 31.626 + match(Set dst (DivD dst con)); 31.627 + format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 31.628 ins_cost(150); // XXX 31.629 - opcode(0xF2, 0x0F, 0x5E); 31.630 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 31.631 + ins_encode %{ 31.632 + __ divsd($dst$$XMMRegister, $constantaddress($con)); 31.633 + %} 31.634 ins_pipe(pipe_slow); 31.635 %} 31.636 31.637 @@ -10897,14 +10842,13 @@ 31.638 ins_pipe(pipe_slow); 31.639 %} 31.640 31.641 -instruct sqrtF_imm(regF dst, immF src) 31.642 -%{ 31.643 - match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 31.644 - 31.645 - format %{ "sqrtss $dst, [$src]" %} 31.646 +instruct sqrtF_imm(regF dst, immF con) %{ 31.647 + match(Set dst (ConvD2F (SqrtD (ConvF2D con)))); 31.648 + format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 31.649 ins_cost(150); // XXX 31.650 - opcode(0xF3, 0x0F, 0x51); 31.651 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 31.652 + ins_encode %{ 31.653 + __ sqrtss($dst$$XMMRegister, $constantaddress($con)); 31.654 + %} 31.655 ins_pipe(pipe_slow); 31.656 %} 31.657 31.658 @@ -10930,14 +10874,13 @@ 31.659 ins_pipe(pipe_slow); 31.660 %} 31.661 31.662 -instruct sqrtD_imm(regD dst, immD src) 31.663 -%{ 31.664 - match(Set dst (SqrtD src)); 31.665 - 31.666 - format %{ "sqrtsd $dst, [$src]" %} 31.667 +instruct sqrtD_imm(regD dst, immD con) %{ 31.668 + match(Set dst (SqrtD con)); 31.669 + format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 31.670 ins_cost(150); // XXX 31.671 - opcode(0xF2, 0x0F, 0x51); 31.672 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 31.673 + ins_encode %{ 31.674 + __ sqrtsd($dst$$XMMRegister, $constantaddress($con)); 31.675 + %} 31.676 ins_pipe(pipe_slow); 31.677 %} 31.678
32.1 --- a/src/os/linux/vm/os_linux.cpp Tue Dec 21 23:39:42 2010 -0500 32.2 +++ b/src/os/linux/vm/os_linux.cpp Wed Dec 22 12:24:40 2010 -0500 32.3 @@ -115,6 +115,7 @@ 32.4 # include <link.h> 32.5 # include <stdint.h> 32.6 # include <inttypes.h> 32.7 +# include <sys/ioctl.h> 32.8 32.9 #define MAX_PATH (2 * K) 32.10 32.11 @@ -4433,6 +4434,15 @@ 32.12 return 1; 32.13 } 32.14 32.15 +int os::socket_available(int fd, jint *pbytes) { 32.16 + // Linux doc says EINTR not returned, unlike Solaris 32.17 + int ret = ::ioctl(fd, FIONREAD, pbytes); 32.18 + 32.19 + //%% note ioctl can return 0 when successful, JVM_SocketAvailable 32.20 + // is expected to return 0 on failure and 1 on success to the jdk. 32.21 + return (ret < 0) ? 0 : 1; 32.22 +} 32.23 + 32.24 // Map a block of memory. 32.25 char* os::map_memory(int fd, const char* file_name, size_t file_offset, 32.26 char *addr, size_t bytes, bool read_only,
33.1 --- a/src/os/linux/vm/os_linux.inline.hpp Tue Dec 21 23:39:42 2010 -0500 33.2 +++ b/src/os/linux/vm/os_linux.inline.hpp Wed Dec 22 12:24:40 2010 -0500 33.3 @@ -45,7 +45,6 @@ 33.4 #include <unistd.h> 33.5 #include <sys/socket.h> 33.6 #include <sys/poll.h> 33.7 -#include <sys/ioctl.h> 33.8 #include <netdb.h> 33.9 33.10 inline void* os::thread_local_storage_at(int index) { 33.11 @@ -268,16 +267,6 @@ 33.12 RESTARTABLE_RETURN_INT(::sendto(fd, buf, len, (unsigned int) flags, to, tolen)); 33.13 } 33.14 33.15 -inline int os::socket_available(int fd, jint *pbytes) { 33.16 - // Linux doc says EINTR not returned, unlike Solaris 33.17 - int ret = ::ioctl(fd, FIONREAD, pbytes); 33.18 - 33.19 - //%% note ioctl can return 0 when successful, JVM_SocketAvailable 33.20 - // is expected to return 0 on failure and 1 on success to the jdk. 33.21 - return (ret < 0) ? 0 : 1; 33.22 -} 33.23 - 33.24 - 33.25 inline int os::socket_shutdown(int fd, int howto){ 33.26 return ::shutdown(fd, howto); 33.27 }
34.1 --- a/src/os/linux/vm/vmError_linux.cpp Tue Dec 21 23:39:42 2010 -0500 34.2 +++ b/src/os/linux/vm/vmError_linux.cpp Wed Dec 22 12:24:40 2010 -0500 34.3 @@ -44,11 +44,11 @@ 34.4 jio_snprintf(p, buflen - len, 34.5 "\n\n" 34.6 "Do you want to debug the problem?\n\n" 34.7 - "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT "\n" 34.8 + "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT " (" INTPTR_FORMAT ")\n" 34.9 "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n" 34.10 "Otherwise, press RETURN to abort...", 34.11 os::current_process_id(), os::current_process_id(), 34.12 - os::current_thread_id()); 34.13 + os::current_thread_id(), os::current_thread_id()); 34.14 34.15 yes = os::message_box("Unexpected Error", buf); 34.16
35.1 --- a/src/share/vm/adlc/adlparse.cpp Tue Dec 21 23:39:42 2010 -0500 35.2 +++ b/src/share/vm/adlc/adlparse.cpp Wed Dec 22 12:24:40 2010 -0500 35.3 @@ -95,7 +95,7 @@ 35.4 if (ident == NULL) { // Empty line 35.5 continue; // Get the next line 35.6 } 35.7 - if (!strcmp(ident, "instruct")) instr_parse(); 35.8 + if (!strcmp(ident, "instruct")) instr_parse(); 35.9 else if (!strcmp(ident, "operand")) oper_parse(); 35.10 else if (!strcmp(ident, "opclass")) opclass_parse(); 35.11 else if (!strcmp(ident, "ins_attrib")) ins_attr_parse(); 35.12 @@ -216,24 +216,23 @@ 35.13 else if (!strcmp(ident, "encode")) { 35.14 parse_err(SYNERR, "Instructions specify ins_encode, not encode\n"); 35.15 } 35.16 - else if (!strcmp(ident, "ins_encode")) 35.17 - instr->_insencode = ins_encode_parse(*instr); 35.18 - else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr); 35.19 - else if (!strcmp(ident, "size")) instr->_size = size_parse(instr); 35.20 - else if (!strcmp(ident, "effect")) effect_parse(instr); 35.21 - else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr); 35.22 - else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse(); 35.23 + else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr); 35.24 + else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr); 35.25 + else if (!strcmp(ident, "size")) instr->_size = size_parse(instr); 35.26 + else if (!strcmp(ident, "effect")) effect_parse(instr); 35.27 + else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr); 35.28 + else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse(); 35.29 else if (!strcmp(ident, "constraint")) { 35.30 parse_err(SYNERR, "Instructions do not specify a constraint\n"); 35.31 } 35.32 else if (!strcmp(ident, "construct")) { 35.33 parse_err(SYNERR, "Instructions do not specify a construct\n"); 35.34 } 35.35 - else if (!strcmp(ident, "format")) instr->_format = format_parse(); 35.36 + else if (!strcmp(ident, "format")) instr->_format = format_parse(); 35.37 else if (!strcmp(ident, "interface")) { 35.38 parse_err(SYNERR, "Instructions do not specify an interface\n"); 35.39 } 35.40 - else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr); 35.41 + else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr); 35.42 else { // Done with staticly defined parts of instruction definition 35.43 // Check identifier to see if it is the name of an attribute 35.44 const Form *form = _globalNames[ident]; 35.45 @@ -323,7 +322,8 @@ 35.46 const char *optype2 = NULL; 35.47 // Can not have additional base operands in right side of match! 35.48 if ( ! right->base_operand( position, _globalNames, result2, name2, optype2) ) { 35.49 - assert( instr->_predicate == NULL, "ADLC does not support instruction chain rules with predicates"); 35.50 + if (instr->_predicate != NULL) 35.51 + parse_err(SYNERR, "ADLC does not support instruction chain rules with predicates"); 35.52 // Chain from input _ideal_operand_type_, 35.53 // Needed for shared roots of match-trees 35.54 ChainList *lst = (ChainList *)_AD._chainRules[optype]; 35.55 @@ -935,9 +935,9 @@ 35.56 // (2) 35.57 // If we are at a replacement variable, 35.58 // copy it and record in EncClass 35.59 - if ( _curchar == '$' ) { 35.60 + if (_curchar == '$') { 35.61 // Found replacement Variable 35.62 - char *rep_var = get_rep_var_ident_dup(); 35.63 + char* rep_var = get_rep_var_ident_dup(); 35.64 // Add flag to _strings list indicating we should check _rep_vars 35.65 encoding->add_rep_var(rep_var); 35.66 } 35.67 @@ -2774,47 +2774,122 @@ 35.68 35.69 //------------------------------ins_encode_parse_block------------------------- 35.70 // Parse the block form of ins_encode. See ins_encode_parse for more details 35.71 -InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) { 35.72 +void ADLParser::ins_encode_parse_block(InstructForm& inst) { 35.73 // Create a new encoding name based on the name of the instruction 35.74 // definition, which should be unique. 35.75 - const char * prefix = "__enc_"; 35.76 - char* ec_name = (char*)malloc(strlen(inst._ident) + strlen(prefix) + 1); 35.77 + const char* prefix = "__ins_encode_"; 35.78 + char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1); 35.79 sprintf(ec_name, "%s%s", prefix, inst._ident); 35.80 35.81 assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); 35.82 - EncClass *encoding = _AD._encode->add_EncClass(ec_name); 35.83 + EncClass* encoding = _AD._encode->add_EncClass(ec_name); 35.84 encoding->_linenum = linenum(); 35.85 35.86 // synthesize the arguments list for the enc_class from the 35.87 // arguments to the instruct definition. 35.88 - const char * param = NULL; 35.89 + const char* param = NULL; 35.90 inst._parameters.reset(); 35.91 while ((param = inst._parameters.iter()) != NULL) { 35.92 - OperandForm *opForm = (OperandForm*)inst._localNames[param]; 35.93 + OperandForm* opForm = (OperandForm*) inst._localNames[param]; 35.94 encoding->add_parameter(opForm->_ident, param); 35.95 } 35.96 35.97 - // Add the prologue to create the MacroAssembler 35.98 - encoding->add_code("\n" 35.99 - " // Define a MacroAssembler instance for use by the encoding. The\n" 35.100 - " // name is chosen to match the __ idiom used for assembly in other\n" 35.101 - " // parts of hotspot and assumes the existence of the standard\n" 35.102 - " // #define __ _masm.\n" 35.103 - " MacroAssembler _masm(&cbuf);\n"); 35.104 + // Define a MacroAssembler instance for use by the encoding. The 35.105 + // name is chosen to match the __ idiom used for assembly in other 35.106 + // parts of hotspot and assumes the existence of the standard 35.107 + // #define __ _masm. 35.108 + encoding->add_code(" MacroAssembler _masm(&cbuf);\n"); 35.109 35.110 // Parse the following %{ }% block 35.111 - enc_class_parse_block(encoding, ec_name); 35.112 + ins_encode_parse_block_impl(inst, encoding, ec_name); 35.113 35.114 // Build an encoding rule which invokes the encoding rule we just 35.115 // created, passing all arguments that we received. 35.116 - InsEncode *encrule = new InsEncode(); // Encode class for instruction 35.117 - NameAndList *params = encrule->add_encode(ec_name); 35.118 + InsEncode* encrule = new InsEncode(); // Encode class for instruction 35.119 + NameAndList* params = encrule->add_encode(ec_name); 35.120 inst._parameters.reset(); 35.121 while ((param = inst._parameters.iter()) != NULL) { 35.122 params->add_entry(param); 35.123 } 35.124 35.125 - return encrule; 35.126 + // Set encode class of this instruction. 35.127 + inst._insencode = encrule; 35.128 +} 35.129 + 35.130 + 35.131 +void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name) { 35.132 + skipws_no_preproc(); // Skip leading whitespace 35.133 + // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block 35.134 + if (_AD._adlocation_debug) { 35.135 + encoding->add_code(get_line_string()); 35.136 + } 35.137 + 35.138 + // Collect the parts of the encode description 35.139 + // (1) strings that are passed through to output 35.140 + // (2) replacement/substitution variable, preceeded by a '$' 35.141 + while ((_curchar != '%') && (*(_ptr+1) != '}')) { 35.142 + 35.143 + // (1) 35.144 + // Check if there is a string to pass through to output 35.145 + char *start = _ptr; // Record start of the next string 35.146 + while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) { 35.147 + // If at the start of a comment, skip past it 35.148 + if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) { 35.149 + skipws_no_preproc(); 35.150 + } else { 35.151 + // ELSE advance to the next character, or start of the next line 35.152 + next_char_or_line(); 35.153 + } 35.154 + } 35.155 + // If a string was found, terminate it and record in EncClass 35.156 + if (start != _ptr) { 35.157 + *_ptr = '\0'; // Terminate the string 35.158 + encoding->add_code(start); 35.159 + } 35.160 + 35.161 + // (2) 35.162 + // If we are at a replacement variable, 35.163 + // copy it and record in EncClass 35.164 + if (_curchar == '$') { 35.165 + // Found replacement Variable 35.166 + char* rep_var = get_rep_var_ident_dup(); 35.167 + 35.168 + // Add flag to _strings list indicating we should check _rep_vars 35.169 + encoding->add_rep_var(rep_var); 35.170 + 35.171 + skipws(); 35.172 + 35.173 + // Check if this instruct is a MachConstantNode. 35.174 + if (strcmp(rep_var, "constanttablebase") == 0) { 35.175 + // This instruct is a MachConstantNode. 35.176 + inst.set_is_mach_constant(true); 35.177 + 35.178 + if (_curchar == '(') { 35.179 + parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name); 35.180 + return; 35.181 + } 35.182 + } 35.183 + else if ((strcmp(rep_var, "constantaddress") == 0) || 35.184 + (strcmp(rep_var, "constantoffset") == 0)) { 35.185 + // This instruct is a MachConstantNode. 35.186 + inst.set_is_mach_constant(true); 35.187 + 35.188 + // If the constant keyword has an argument, parse it. 35.189 + if (_curchar == '(') constant_parse(inst); 35.190 + } 35.191 + } 35.192 + } // end while part of format description 35.193 + next_char(); // Skip '%' 35.194 + next_char(); // Skip '}' 35.195 + 35.196 + skipws(); 35.197 + 35.198 + if (_AD._adlocation_debug) { 35.199 + encoding->add_code(end_line_marker()); 35.200 + } 35.201 + 35.202 + // Debug Stuff 35.203 + if (_AD._adl_debug > 1) fprintf(stderr, "EncodingClass Form: %s\n", ec_name); 35.204 } 35.205 35.206 35.207 @@ -2838,7 +2913,7 @@ 35.208 // 35.209 // making it more compact to take advantage of the MacroAssembler and 35.210 // placing the assembly closer to it's use by instructions. 35.211 -InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) { 35.212 +void ADLParser::ins_encode_parse(InstructForm& inst) { 35.213 35.214 // Parse encode class name 35.215 skipws(); // Skip whitespace 35.216 @@ -2849,11 +2924,12 @@ 35.217 next_char(); // Skip '{' 35.218 35.219 // Parse the block form of ins_encode 35.220 - return ins_encode_parse_block(inst); 35.221 + ins_encode_parse_block(inst); 35.222 + return; 35.223 } 35.224 35.225 parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n"); 35.226 - return NULL; 35.227 + return; 35.228 } 35.229 next_char(); // move past '(' 35.230 skipws(); 35.231 @@ -2866,7 +2942,7 @@ 35.232 ec_name = get_ident(); 35.233 if (ec_name == NULL) { 35.234 parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n"); 35.235 - return NULL; 35.236 + return; 35.237 } 35.238 // Check that encoding is defined in the encode section 35.239 EncClass *encode_class = _AD._encode->encClass(ec_name); 35.240 @@ -2898,7 +2974,7 @@ 35.241 (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) && 35.242 ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) { 35.243 parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name); 35.244 - return NULL; 35.245 + return; 35.246 } 35.247 params->add_entry(param); 35.248 35.249 @@ -2915,7 +2991,7 @@ 35.250 // Only ',' or ')' are valid after a parameter name 35.251 parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", 35.252 ec_name); 35.253 - return NULL; 35.254 + return; 35.255 } 35.256 35.257 } else { 35.258 @@ -2923,11 +2999,11 @@ 35.259 // Did not find a parameter 35.260 if (_curchar == ',') { 35.261 parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name); 35.262 - return NULL; 35.263 + return; 35.264 } 35.265 if (_curchar != ')') { 35.266 parse_err(SYNERR, "Expected ')' after encode parameters.\n"); 35.267 - return NULL; 35.268 + return; 35.269 } 35.270 } 35.271 } // WHILE loop collecting parameters 35.272 @@ -2944,7 +3020,7 @@ 35.273 else if ( _curchar != ')' ) { 35.274 // If not a ',' then only a ')' is allowed 35.275 parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name); 35.276 - return NULL; 35.277 + return; 35.278 } 35.279 35.280 // Check for ',' separating parameters 35.281 @@ -2956,14 +3032,14 @@ 35.282 } // done parsing ins_encode methods and their parameters 35.283 if (_curchar != ')') { 35.284 parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n"); 35.285 - return NULL; 35.286 + return; 35.287 } 35.288 next_char(); // move past ')' 35.289 skipws(); // Skip leading whitespace 35.290 35.291 if ( _curchar != ';' ) { 35.292 parse_err(SYNERR, "Missing ';' at end of ins_encode.\n"); 35.293 - return NULL; 35.294 + return; 35.295 } 35.296 next_char(); // move past ';' 35.297 skipws(); // be friendly to oper_parse() 35.298 @@ -2971,7 +3047,113 @@ 35.299 // Debug Stuff 35.300 if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name); 35.301 35.302 - return encrule; 35.303 + // Set encode class of this instruction. 35.304 + inst._insencode = encrule; 35.305 +} 35.306 + 35.307 + 35.308 +//------------------------------constant_parse--------------------------------- 35.309 +// Parse a constant expression. 35.310 +void ADLParser::constant_parse(InstructForm& inst) { 35.311 + // Create a new encoding name based on the name of the instruction 35.312 + // definition, which should be unique. 35.313 + const char* prefix = "__constant_"; 35.314 + char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1); 35.315 + sprintf(ec_name, "%s%s", prefix, inst._ident); 35.316 + 35.317 + assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); 35.318 + EncClass* encoding = _AD._encode->add_EncClass(ec_name); 35.319 + encoding->_linenum = linenum(); 35.320 + 35.321 + // synthesize the arguments list for the enc_class from the 35.322 + // arguments to the instruct definition. 35.323 + const char* param = NULL; 35.324 + inst._parameters.reset(); 35.325 + while ((param = inst._parameters.iter()) != NULL) { 35.326 + OperandForm* opForm = (OperandForm*) inst._localNames[param]; 35.327 + encoding->add_parameter(opForm->_ident, param); 35.328 + } 35.329 + 35.330 + // Parse the following ( ) expression. 35.331 + constant_parse_expression(encoding, ec_name); 35.332 + 35.333 + // Build an encoding rule which invokes the encoding rule we just 35.334 + // created, passing all arguments that we received. 35.335 + InsEncode* encrule = new InsEncode(); // Encode class for instruction 35.336 + NameAndList* params = encrule->add_encode(ec_name); 35.337 + inst._parameters.reset(); 35.338 + while ((param = inst._parameters.iter()) != NULL) { 35.339 + params->add_entry(param); 35.340 + } 35.341 + 35.342 + // Set encode class of this instruction. 35.343 + inst._constant = encrule; 35.344 +} 35.345 + 35.346 + 35.347 +//------------------------------constant_parse_expression---------------------- 35.348 +void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) { 35.349 + skipws(); 35.350 + 35.351 + // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block 35.352 + if (_AD._adlocation_debug) { 35.353 + encoding->add_code(get_line_string()); 35.354 + } 35.355 + 35.356 + // Start code line. 35.357 + encoding->add_code(" _constant = C->constant_table().add"); 35.358 + 35.359 + // Parse everything in ( ) expression. 35.360 + encoding->add_code("("); 35.361 + next_char(); // Skip '(' 35.362 + int parens_depth = 1; 35.363 + 35.364 + // Collect the parts of the constant expression. 35.365 + // (1) strings that are passed through to output 35.366 + // (2) replacement/substitution variable, preceeded by a '$' 35.367 + while (parens_depth > 0) { 35.368 + if (_curchar == '(') { 35.369 + parens_depth++; 35.370 + encoding->add_code("("); 35.371 + next_char(); 35.372 + } 35.373 + else if (_curchar == ')') { 35.374 + parens_depth--; 35.375 + encoding->add_code(")"); 35.376 + next_char(); 35.377 + } 35.378 + else { 35.379 + // (1) 35.380 + // Check if there is a string to pass through to output 35.381 + char *start = _ptr; // Record start of the next string 35.382 + while ((_curchar != '$') && (_curchar != '(') && (_curchar != ')')) { 35.383 + next_char(); 35.384 + } 35.385 + // If a string was found, terminate it and record in EncClass 35.386 + if (start != _ptr) { 35.387 + *_ptr = '\0'; // Terminate the string 35.388 + encoding->add_code(start); 35.389 + } 35.390 + 35.391 + // (2) 35.392 + // If we are at a replacement variable, copy it and record in EncClass. 35.393 + if (_curchar == '$') { 35.394 + // Found replacement Variable 35.395 + char* rep_var = get_rep_var_ident_dup(); 35.396 + encoding->add_rep_var(rep_var); 35.397 + } 35.398 + } 35.399 + } 35.400 + 35.401 + // Finish code line. 35.402 + encoding->add_code(";"); 35.403 + 35.404 + if (_AD._adlocation_debug) { 35.405 + encoding->add_code(end_line_marker()); 35.406 + } 35.407 + 35.408 + // Debug Stuff 35.409 + if (_AD._adl_debug > 1) fprintf(stderr, "EncodingClass Form: %s\n", ec_name); 35.410 } 35.411 35.412
36.1 --- a/src/share/vm/adlc/adlparse.hpp Tue Dec 21 23:39:42 2010 -0500 36.2 +++ b/src/share/vm/adlc/adlparse.hpp Wed Dec 22 12:24:40 2010 -0500 36.3 @@ -156,8 +156,13 @@ 36.4 36.5 Attribute *attr_parse(char *ident);// Parse instr/operand attribute rule 36.6 // Parse instruction encode rule 36.7 - InsEncode *ins_encode_parse(InstructForm &inst); 36.8 - InsEncode *ins_encode_parse_block(InstructForm &inst); 36.9 + void ins_encode_parse(InstructForm &inst); 36.10 + void ins_encode_parse_block(InstructForm &inst); 36.11 + void ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name); 36.12 + 36.13 + void constant_parse(InstructForm& inst); 36.14 + void constant_parse_expression(EncClass* encoding, char* ec_name); 36.15 + 36.16 Opcode *opcode_parse(InstructForm *insr); // Parse instruction opcode 36.17 char *size_parse(InstructForm *insr); // Parse instruction size 36.18 Interface *interface_parse(); // Parse operand interface rule
37.1 --- a/src/share/vm/adlc/archDesc.hpp Tue Dec 21 23:39:42 2010 -0500 37.2 +++ b/src/share/vm/adlc/archDesc.hpp Wed Dec 22 12:24:40 2010 -0500 37.3 @@ -126,7 +126,6 @@ 37.4 void chain_rule(FILE *fp, const char *indent, const char *ideal, 37.5 const Expr *icost, const char *irule, 37.6 Dict &operands_chained_from, ProductionState &status); 37.7 - void chain_rule_c(FILE *fp, char *indent, char *ideal, char *irule); // %%%%% TODO: remove this 37.8 void expand_opclass(FILE *fp, const char *indent, const Expr *cost, 37.9 const char *result_type, ProductionState &status); 37.10 Expr *calc_cost(FILE *fp, const char *spaces, MatchList &mList, ProductionState &status); 37.11 @@ -301,13 +300,18 @@ 37.12 void buildMachNodeGenerator(FILE *fp_cpp); 37.13 37.14 // Generator for Expand methods for instructions with expand rules 37.15 - void defineExpand(FILE *fp, InstructForm *node); 37.16 + void defineExpand (FILE *fp, InstructForm *node); 37.17 // Generator for Peephole methods for instructions with peephole rules 37.18 - void definePeephole(FILE *fp, InstructForm *node); 37.19 + void definePeephole (FILE *fp, InstructForm *node); 37.20 // Generator for Size methods for instructions 37.21 - void defineSize(FILE *fp, InstructForm &node); 37.22 + void defineSize (FILE *fp, InstructForm &node); 37.23 + 37.24 +public: 37.25 + // Generator for EvalConstantValue methods for instructions 37.26 + void defineEvalConstant(FILE *fp, InstructForm &node); 37.27 // Generator for Emit methods for instructions 37.28 - void defineEmit(FILE *fp, InstructForm &node); 37.29 + void defineEmit (FILE *fp, InstructForm &node); 37.30 + 37.31 // Define a MachOper encode method 37.32 void define_oper_interface(FILE *fp, OperandForm &oper, FormDict &globals, 37.33 const char *name, const char *encoding);
38.1 --- a/src/share/vm/adlc/formssel.cpp Tue Dec 21 23:39:42 2010 -0500 38.2 +++ b/src/share/vm/adlc/formssel.cpp Wed Dec 22 12:24:40 2010 -0500 38.3 @@ -30,11 +30,14 @@ 38.4 InstructForm::InstructForm(const char *id, bool ideal_only) 38.5 : _ident(id), _ideal_only(ideal_only), 38.6 _localNames(cmpstr, hashstr, Form::arena), 38.7 - _effects(cmpstr, hashstr, Form::arena) { 38.8 + _effects(cmpstr, hashstr, Form::arena), 38.9 + _is_mach_constant(false) 38.10 +{ 38.11 _ftype = Form::INS; 38.12 38.13 _matrule = NULL; 38.14 _insencode = NULL; 38.15 + _constant = NULL; 38.16 _opcode = NULL; 38.17 _size = NULL; 38.18 _attribs = NULL; 38.19 @@ -58,11 +61,14 @@ 38.20 InstructForm::InstructForm(const char *id, InstructForm *instr, MatchRule *rule) 38.21 : _ident(id), _ideal_only(false), 38.22 _localNames(instr->_localNames), 38.23 - _effects(instr->_effects) { 38.24 + _effects(instr->_effects), 38.25 + _is_mach_constant(false) 38.26 +{ 38.27 _ftype = Form::INS; 38.28 38.29 _matrule = rule; 38.30 _insencode = instr->_insencode; 38.31 + _constant = instr->_constant; 38.32 _opcode = instr->_opcode; 38.33 _size = instr->_size; 38.34 _attribs = instr->_attribs; 38.35 @@ -1094,6 +1100,9 @@ 38.36 else if (is_ideal_nop()) { 38.37 return "MachNopNode"; 38.38 } 38.39 + else if (is_mach_constant()) { 38.40 + return "MachConstantNode"; 38.41 + } 38.42 else if (captures_bottom_type(globals)) { 38.43 return "MachTypeNode"; 38.44 } else { 38.45 @@ -1190,6 +1199,21 @@ 38.46 // 38.47 // Generate the format call for the replacement variable 38.48 void InstructForm::rep_var_format(FILE *fp, const char *rep_var) { 38.49 + // Handle special constant table variables. 38.50 + if (strcmp(rep_var, "constanttablebase") == 0) { 38.51 + fprintf(fp, "char reg[128]; ra->dump_register(in(mach_constant_base_node_input()), reg);\n"); 38.52 + fprintf(fp, "st->print(\"%%s\");\n"); 38.53 + return; 38.54 + } 38.55 + if (strcmp(rep_var, "constantoffset") == 0) { 38.56 + fprintf(fp, "st->print(\"#%%d\", constant_offset());\n"); 38.57 + return; 38.58 + } 38.59 + if (strcmp(rep_var, "constantaddress") == 0) { 38.60 + fprintf(fp, "st->print(\"constant table base + #%%d\", constant_offset());\n"); 38.61 + return; 38.62 + } 38.63 + 38.64 // Find replacement variable's type 38.65 const Form *form = _localNames[rep_var]; 38.66 if (form == NULL) { 38.67 @@ -1348,6 +1372,7 @@ 38.68 fprintf(fp,"\nInstruction: %s\n", (_ident?_ident:"")); 38.69 if (_matrule) _matrule->output(fp); 38.70 if (_insencode) _insencode->output(fp); 38.71 + if (_constant) _constant->output(fp); 38.72 if (_opcode) _opcode->output(fp); 38.73 if (_attribs) _attribs->output(fp); 38.74 if (_predicate) _predicate->output(fp);
39.1 --- a/src/share/vm/adlc/formssel.hpp Tue Dec 21 23:39:42 2010 -0500 39.2 +++ b/src/share/vm/adlc/formssel.hpp Wed Dec 22 12:24:40 2010 -0500 39.3 @@ -74,15 +74,16 @@ 39.4 //------------------------------InstructForm----------------------------------- 39.5 class InstructForm : public Form { 39.6 private: 39.7 - bool _ideal_only; // Not a user-defined instruction 39.8 + bool _ideal_only; // Not a user-defined instruction 39.9 // Members used for tracking CISC-spilling 39.10 - uint _cisc_spill_operand;// Which operand may cisc-spill 39.11 + uint _cisc_spill_operand;// Which operand may cisc-spill 39.12 void set_cisc_spill_operand(uint op_index) { _cisc_spill_operand = op_index; } 39.13 - bool _is_cisc_alternate; 39.14 + bool _is_cisc_alternate; 39.15 InstructForm *_cisc_spill_alternate;// cisc possible replacement 39.16 const char *_cisc_reg_mask_name; 39.17 InstructForm *_short_branch_form; 39.18 bool _is_short_branch; 39.19 + bool _is_mach_constant; // true if Node is a MachConstantNode 39.20 uint _alignment; 39.21 39.22 public: 39.23 @@ -94,6 +95,7 @@ 39.24 Opcode *_opcode; // Encoding of the opcode for instruction 39.25 char *_size; // Size of instruction 39.26 InsEncode *_insencode; // Encoding class instruction belongs to 39.27 + InsEncode *_constant; // Encoding class constant value belongs to 39.28 Attribute *_attribs; // List of Attribute rules 39.29 Predicate *_predicate; // Predicate test for this instruction 39.30 FormDict _effects; // Dictionary of effect rules 39.31 @@ -251,6 +253,9 @@ 39.32 bool is_short_branch() { return _is_short_branch; } 39.33 void set_short_branch(bool val) { _is_short_branch = val; } 39.34 39.35 + bool is_mach_constant() const { return _is_mach_constant; } 39.36 + void set_is_mach_constant(bool x) { _is_mach_constant = x; } 39.37 + 39.38 InstructForm *short_branch_form() { return _short_branch_form; } 39.39 bool has_short_branch_form() { return _short_branch_form != NULL; } 39.40 // Output short branch prototypes and method bodies
40.1 --- a/src/share/vm/adlc/output_c.cpp Tue Dec 21 23:39:42 2010 -0500 40.2 +++ b/src/share/vm/adlc/output_c.cpp Wed Dec 22 12:24:40 2010 -0500 40.3 @@ -1496,8 +1496,8 @@ 40.4 unsigned i; 40.5 40.6 // Generate Expand function header 40.7 - fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident); 40.8 - fprintf(fp,"Compile* C = Compile::current();\n"); 40.9 + fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident); 40.10 + fprintf(fp, " Compile* C = Compile::current();\n"); 40.11 // Generate expand code 40.12 if( node->expands() ) { 40.13 const char *opid; 40.14 @@ -1818,6 +1818,12 @@ 40.15 } 40.16 } 40.17 40.18 + // If the node is a MachConstantNode, insert the MachConstantBaseNode edge. 40.19 + // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input). 40.20 + if (node->is_mach_constant()) { 40.21 + fprintf(fp," add_req(C->mach_constant_base_node());\n"); 40.22 + } 40.23 + 40.24 fprintf(fp,"\n"); 40.25 if( node->expands() ) { 40.26 fprintf(fp," return result;\n"); 40.27 @@ -1924,7 +1930,17 @@ 40.28 // No state needed. 40.29 assert( _opclass == NULL, 40.30 "'primary', 'secondary' and 'tertiary' don't follow operand."); 40.31 - } else { 40.32 + } 40.33 + else if ((strcmp(rep_var, "constanttablebase") == 0) || 40.34 + (strcmp(rep_var, "constantoffset") == 0) || 40.35 + (strcmp(rep_var, "constantaddress") == 0)) { 40.36 + if (!_inst.is_mach_constant()) { 40.37 + _AD.syntax_err(_encoding._linenum, 40.38 + "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n", 40.39 + rep_var, _encoding._name); 40.40 + } 40.41 + } 40.42 + else { 40.43 // Lookup its position in parameter list 40.44 int param_no = _encoding.rep_var_index(rep_var); 40.45 if ( param_no == -1 ) { 40.46 @@ -2380,6 +2396,15 @@ 40.47 rep_var, _inst._ident, _encoding._name); 40.48 } 40.49 } 40.50 + else if (strcmp(rep_var, "constanttablebase") == 0) { 40.51 + fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))"); 40.52 + } 40.53 + else if (strcmp(rep_var, "constantoffset") == 0) { 40.54 + fprintf(_fp, "constant_offset()"); 40.55 + } 40.56 + else if (strcmp(rep_var, "constantaddress") == 0) { 40.57 + fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())"); 40.58 + } 40.59 else { 40.60 // Lookup its position in parameter list 40.61 int param_no = _encoding.rep_var_index(rep_var); 40.62 @@ -2465,37 +2490,39 @@ 40.63 fprintf(fp,"}\n"); 40.64 } 40.65 40.66 -void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) { 40.67 - InsEncode *ins_encode = inst._insencode; 40.68 +// defineEmit ----------------------------------------------------------------- 40.69 +void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) { 40.70 + InsEncode* encode = inst._insencode; 40.71 40.72 // (1) 40.73 // Output instruction's emit prototype 40.74 - fprintf(fp,"void %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n", 40.75 - inst._ident); 40.76 + fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident); 40.77 40.78 // If user did not define an encode section, 40.79 // provide stub that does not generate any machine code. 40.80 - if( (_encode == NULL) || (ins_encode == NULL) ) { 40.81 + if( (_encode == NULL) || (encode == NULL) ) { 40.82 fprintf(fp, " // User did not define an encode section.\n"); 40.83 - fprintf(fp,"}\n"); 40.84 + fprintf(fp, "}\n"); 40.85 return; 40.86 } 40.87 40.88 // Save current instruction's starting address (helps with relocation). 40.89 - fprintf(fp, " cbuf.set_insts_mark();\n"); 40.90 - 40.91 - // // // idx0 is only needed for syntactic purposes and only by "storeSSI" 40.92 - // fprintf( fp, " unsigned idx0 = 0;\n"); 40.93 + fprintf(fp, " cbuf.set_insts_mark();\n"); 40.94 + 40.95 + // For MachConstantNodes which are ideal jump nodes, fill the jump table. 40.96 + if (inst.is_mach_constant() && inst.is_ideal_jump()) { 40.97 + fprintf(fp, " ra_->C->constant_table().fill_jump_table(cbuf, (MachConstantNode*) this, _index2label);\n"); 40.98 + } 40.99 40.100 // Output each operand's offset into the array of registers. 40.101 - inst.index_temps( fp, _globalNames ); 40.102 + inst.index_temps(fp, _globalNames); 40.103 40.104 // Output this instruction's encodings 40.105 const char *ec_name; 40.106 bool user_defined = false; 40.107 - ins_encode->reset(); 40.108 - while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) { 40.109 - fprintf(fp, " {"); 40.110 + encode->reset(); 40.111 + while ((ec_name = encode->encode_class_iter()) != NULL) { 40.112 + fprintf(fp, " {\n"); 40.113 // Output user-defined encoding 40.114 user_defined = true; 40.115 40.116 @@ -2507,25 +2534,25 @@ 40.117 abort(); 40.118 } 40.119 40.120 - if (ins_encode->current_encoding_num_args() != encoding->num_args()) { 40.121 - globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", 40.122 - inst._ident, ins_encode->current_encoding_num_args(), 40.123 + if (encode->current_encoding_num_args() != encoding->num_args()) { 40.124 + globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", 40.125 + inst._ident, encode->current_encoding_num_args(), 40.126 ec_name, encoding->num_args()); 40.127 } 40.128 40.129 - DefineEmitState pending(fp, *this, *encoding, *ins_encode, inst ); 40.130 + DefineEmitState pending(fp, *this, *encoding, *encode, inst); 40.131 encoding->_code.reset(); 40.132 encoding->_rep_vars.reset(); 40.133 // Process list of user-defined strings, 40.134 // and occurrences of replacement variables. 40.135 // Replacement Vars are pushed into a list and then output 40.136 - while ( (ec_code = encoding->_code.iter()) != NULL ) { 40.137 - if ( ! encoding->_code.is_signal( ec_code ) ) { 40.138 + while ((ec_code = encoding->_code.iter()) != NULL) { 40.139 + if (!encoding->_code.is_signal(ec_code)) { 40.140 // Emit pending code 40.141 pending.emit(); 40.142 pending.clear(); 40.143 // Emit this code section 40.144 - fprintf(fp,"%s", ec_code); 40.145 + fprintf(fp, "%s", ec_code); 40.146 } else { 40.147 // A replacement variable or one of its subfields 40.148 // Obtain replacement variable from list 40.149 @@ -2536,7 +2563,7 @@ 40.150 // Emit pending code 40.151 pending.emit(); 40.152 pending.clear(); 40.153 - fprintf(fp, "}\n"); 40.154 + fprintf(fp, " }\n"); 40.155 } // end while instruction's encodings 40.156 40.157 // Check if user stated which encoding to user 40.158 @@ -2545,7 +2572,86 @@ 40.159 } 40.160 40.161 // (3) and (4) 40.162 - fprintf(fp,"}\n"); 40.163 + fprintf(fp, "}\n"); 40.164 +} 40.165 + 40.166 +// defineEvalConstant --------------------------------------------------------- 40.167 +void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) { 40.168 + InsEncode* encode = inst._constant; 40.169 + 40.170 + // (1) 40.171 + // Output instruction's emit prototype 40.172 + fprintf(fp, "void %sNode::eval_constant(Compile* C) {\n", inst._ident); 40.173 + 40.174 + // For ideal jump nodes, allocate a jump table. 40.175 + if (inst.is_ideal_jump()) { 40.176 + fprintf(fp, " _constant = C->constant_table().allocate_jump_table(this);\n"); 40.177 + } 40.178 + 40.179 + // If user did not define an encode section, 40.180 + // provide stub that does not generate any machine code. 40.181 + if ((_encode == NULL) || (encode == NULL)) { 40.182 + fprintf(fp, " // User did not define an encode section.\n"); 40.183 + fprintf(fp, "}\n"); 40.184 + return; 40.185 + } 40.186 + 40.187 + // Output this instruction's encodings 40.188 + const char *ec_name; 40.189 + bool user_defined = false; 40.190 + encode->reset(); 40.191 + while ((ec_name = encode->encode_class_iter()) != NULL) { 40.192 + fprintf(fp, " {\n"); 40.193 + // Output user-defined encoding 40.194 + user_defined = true; 40.195 + 40.196 + const char *ec_code = NULL; 40.197 + const char *ec_rep_var = NULL; 40.198 + EncClass *encoding = _encode->encClass(ec_name); 40.199 + if (encoding == NULL) { 40.200 + fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name); 40.201 + abort(); 40.202 + } 40.203 + 40.204 + if (encode->current_encoding_num_args() != encoding->num_args()) { 40.205 + globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", 40.206 + inst._ident, encode->current_encoding_num_args(), 40.207 + ec_name, encoding->num_args()); 40.208 + } 40.209 + 40.210 + DefineEmitState pending(fp, *this, *encoding, *encode, inst); 40.211 + encoding->_code.reset(); 40.212 + encoding->_rep_vars.reset(); 40.213 + // Process list of user-defined strings, 40.214 + // and occurrences of replacement variables. 40.215 + // Replacement Vars are pushed into a list and then output 40.216 + while ((ec_code = encoding->_code.iter()) != NULL) { 40.217 + if (!encoding->_code.is_signal(ec_code)) { 40.218 + // Emit pending code 40.219 + pending.emit(); 40.220 + pending.clear(); 40.221 + // Emit this code section 40.222 + fprintf(fp, "%s", ec_code); 40.223 + } else { 40.224 + // A replacement variable or one of its subfields 40.225 + // Obtain replacement variable from list 40.226 + ec_rep_var = encoding->_rep_vars.iter(); 40.227 + pending.add_rep_var(ec_rep_var); 40.228 + } 40.229 + } 40.230 + // Emit pending code 40.231 + pending.emit(); 40.232 + pending.clear(); 40.233 + fprintf(fp, " }\n"); 40.234 + } // end while instruction's encodings 40.235 + 40.236 + // Check if user stated which encoding to user 40.237 + if (user_defined == false) { 40.238 + fprintf(fp, " // User did not define which encode class to use.\n"); 40.239 + } 40.240 + 40.241 + // (3) and (4) 40.242 + fprintf(fp, "}\n"); 40.243 } 40.244 40.245 // --------------------------------------------------------------------------- 40.246 @@ -2952,6 +3058,7 @@ 40.247 // If there are multiple defs/kills, or an explicit expand rule, build rule 40.248 if( instr->expands() || instr->needs_projections() || 40.249 instr->has_temps() || 40.250 + instr->is_mach_constant() || 40.251 instr->_matrule != NULL && 40.252 instr->num_opnds() != instr->num_unique_opnds() ) 40.253 defineExpand(_CPP_EXPAND_file._fp, instr); 40.254 @@ -3032,8 +3139,9 @@ 40.255 // Ensure this is a machine-world instruction 40.256 if ( instr->ideal_only() ) continue; 40.257 40.258 - if (instr->_insencode) defineEmit(fp, *instr); 40.259 - if (instr->_size) defineSize(fp, *instr); 40.260 + if (instr->_insencode) defineEmit (fp, *instr); 40.261 + if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); 40.262 + if (instr->_size) defineSize (fp, *instr); 40.263 40.264 // side-call to generate output that used to be in the header file: 40.265 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
41.1 --- a/src/share/vm/adlc/output_h.cpp Tue Dec 21 23:39:42 2010 -0500 41.2 +++ b/src/share/vm/adlc/output_h.cpp Wed Dec 22 12:24:40 2010 -0500 41.3 @@ -1550,7 +1550,12 @@ 41.4 } 41.5 41.6 // virtual functions for encode and format 41.7 - // 41.8 + 41.9 + // Virtual function for evaluating the constant. 41.10 + if (instr->is_mach_constant()) { 41.11 + fprintf(fp," virtual void eval_constant(Compile* C);\n"); 41.12 + } 41.13 + 41.14 // Output the opcode function and the encode function here using the 41.15 // encoding class information in the _insencode slot. 41.16 if ( instr->_insencode ) { 41.17 @@ -1559,7 +1564,7 @@ 41.18 41.19 // virtual function for getting the size of an instruction 41.20 if ( instr->_size ) { 41.21 - fprintf(fp," virtual uint size(PhaseRegAlloc *ra_) const;\n"); 41.22 + fprintf(fp," virtual uint size(PhaseRegAlloc *ra_) const;\n"); 41.23 } 41.24 41.25 // Return the top-level ideal opcode. 41.26 @@ -1752,6 +1757,7 @@ 41.27 // Virtual methods which are only generated to override base class 41.28 if( instr->expands() || instr->needs_projections() || 41.29 instr->has_temps() || 41.30 + instr->is_mach_constant() || 41.31 instr->_matrule != NULL && 41.32 instr->num_opnds() != instr->num_unique_opnds() ) { 41.33 fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list, Node* mem);\n"); 41.34 @@ -1780,24 +1786,6 @@ 41.35 // Declare short branch methods, if applicable 41.36 instr->declare_short_branch_methods(fp); 41.37 41.38 - // Instructions containing a constant that will be entered into the 41.39 - // float/double table redefine the base virtual function 41.40 -#ifdef SPARC 41.41 - // Sparc doubles entries in the constant table require more space for 41.42 - // alignment. (expires 9/98) 41.43 - int table_entries = (3 * instr->num_consts( _globalNames, Form::idealD )) 41.44 - + instr->num_consts( _globalNames, Form::idealF ); 41.45 -#else 41.46 - int table_entries = instr->num_consts( _globalNames, Form::idealD ) 41.47 - + instr->num_consts( _globalNames, Form::idealF ); 41.48 -#endif 41.49 - if( table_entries != 0 ) { 41.50 - fprintf(fp," virtual int const_size() const {"); 41.51 - fprintf(fp, " return %d;", table_entries); 41.52 - fprintf(fp, " }\n"); 41.53 - } 41.54 - 41.55 - 41.56 // See if there is an "ins_pipe" declaration for this instruction 41.57 if (instr->_ins_pipe) { 41.58 fprintf(fp," static const Pipeline *pipeline_class();\n");
42.1 --- a/src/share/vm/asm/assembler.hpp Tue Dec 21 23:39:42 2010 -0500 42.2 +++ b/src/share/vm/asm/assembler.hpp Wed Dec 22 12:24:40 2010 -0500 42.3 @@ -292,7 +292,16 @@ 42.4 address start_a_const(int required_space, int required_align = sizeof(double)); 42.5 void end_a_const(); 42.6 42.7 - // fp constants support 42.8 + // constants support 42.9 + address long_constant(jlong c) { 42.10 + address ptr = start_a_const(sizeof(c), sizeof(c)); 42.11 + if (ptr != NULL) { 42.12 + *(jlong*)ptr = c; 42.13 + _code_pos = ptr + sizeof(c); 42.14 + end_a_const(); 42.15 + } 42.16 + return ptr; 42.17 + } 42.18 address double_constant(jdouble c) { 42.19 address ptr = start_a_const(sizeof(c), sizeof(c)); 42.20 if (ptr != NULL) { 42.21 @@ -311,6 +320,15 @@ 42.22 } 42.23 return ptr; 42.24 } 42.25 + address address_constant(address c) { 42.26 + address ptr = start_a_const(sizeof(c), sizeof(c)); 42.27 + if (ptr != NULL) { 42.28 + *(address*)ptr = c; 42.29 + _code_pos = ptr + sizeof(c); 42.30 + end_a_const(); 42.31 + } 42.32 + return ptr; 42.33 + } 42.34 address address_constant(address c, RelocationHolder const& rspec) { 42.35 address ptr = start_a_const(sizeof(c), sizeof(c)); 42.36 if (ptr != NULL) { 42.37 @@ -321,8 +339,6 @@ 42.38 } 42.39 return ptr; 42.40 } 42.41 - inline address address_constant(Label& L); 42.42 - inline address address_table_constant(GrowableArray<Label*> label); 42.43 42.44 // Bootstrapping aid to cope with delayed determination of constants. 42.45 // Returns a static address which will eventually contain the constant.
43.1 --- a/src/share/vm/asm/assembler.inline.hpp Tue Dec 21 23:39:42 2010 -0500 43.2 +++ b/src/share/vm/asm/assembler.inline.hpp Wed Dec 22 12:24:40 2010 -0500 43.3 @@ -114,32 +114,4 @@ 43.4 bind_loc(CodeBuffer::locator(pos, sect)); 43.5 } 43.6 43.7 -address AbstractAssembler::address_constant(Label& L) { 43.8 - address c = NULL; 43.9 - address ptr = start_a_const(sizeof(c), sizeof(c)); 43.10 - if (ptr != NULL) { 43.11 - relocate(Relocation::spec_simple(relocInfo::internal_word_type)); 43.12 - *(address*)ptr = c = code_section()->target(L, ptr); 43.13 - _code_pos = ptr + sizeof(c); 43.14 - end_a_const(); 43.15 - } 43.16 - return ptr; 43.17 -} 43.18 - 43.19 -address AbstractAssembler::address_table_constant(GrowableArray<Label*> labels) { 43.20 - int addressSize = sizeof(address); 43.21 - int sizeLabel = addressSize * labels.length(); 43.22 - address ptr = start_a_const(sizeLabel, addressSize); 43.23 - 43.24 - if (ptr != NULL) { 43.25 - address *labelLoc = (address*)ptr; 43.26 - for (int i=0; i < labels.length(); i++) { 43.27 - emit_address(code_section()->target(*labels.at(i), (address)&labelLoc[i])); 43.28 - code_section()->relocate((address)&labelLoc[i], relocInfo::internal_word_type); 43.29 - } 43.30 - end_a_const(); 43.31 - } 43.32 - return ptr; 43.33 -} 43.34 - 43.35 #endif // SHARE_VM_ASM_ASSEMBLER_INLINE_HPP
44.1 --- a/src/share/vm/asm/codeBuffer.cpp Tue Dec 21 23:39:42 2010 -0500 44.2 +++ b/src/share/vm/asm/codeBuffer.cpp Wed Dec 22 12:24:40 2010 -0500 44.3 @@ -131,6 +131,7 @@ 44.4 #ifdef ASSERT 44.5 // Save allocation type to execute assert in ~ResourceObj() 44.6 // which is called after this destructor. 44.7 + assert(_default_oop_recorder.allocated_on_stack(), "should be embedded object"); 44.8 ResourceObj::allocation_type at = _default_oop_recorder.get_allocation_type(); 44.9 Copy::fill_to_bytes(this, sizeof(*this), badResourceValue); 44.10 ResourceObj::set_allocation_type((address)(&_default_oop_recorder), at);
45.1 --- a/src/share/vm/c1/c1_Compilation.cpp Tue Dec 21 23:39:42 2010 -0500 45.2 +++ b/src/share/vm/c1/c1_Compilation.cpp Wed Dec 22 12:24:40 2010 -0500 45.3 @@ -298,8 +298,8 @@ 45.4 45.5 CHECK_BAILOUT_(no_frame_size); 45.6 45.7 - if (is_profiling()) { 45.8 - method()->build_method_data(); 45.9 + if (is_profiling() && !method()->ensure_method_data()) { 45.10 + BAILOUT_("mdo allocation failed", no_frame_size); 45.11 } 45.12 45.13 { 45.14 @@ -484,11 +484,11 @@ 45.15 if (is_profiling()) { 45.16 // Compilation failed, create MDO, which would signal the interpreter 45.17 // to start profiling on its own. 45.18 - _method->build_method_data(); 45.19 + _method->ensure_method_data(); 45.20 } 45.21 } else if (is_profiling() && _would_profile) { 45.22 - ciMethodData *md = method->method_data(); 45.23 - assert (md != NULL, "Should have MDO"); 45.24 + ciMethodData *md = method->method_data_or_null(); 45.25 + assert(md != NULL, "Sanity"); 45.26 md->set_would_profile(_would_profile); 45.27 } 45.28 }
46.1 --- a/src/share/vm/c1/c1_FrameMap.hpp Tue Dec 21 23:39:42 2010 -0500 46.2 +++ b/src/share/vm/c1/c1_FrameMap.hpp Wed Dec 22 12:24:40 2010 -0500 46.3 @@ -76,8 +76,8 @@ 46.4 nof_cpu_regs_reg_alloc = pd_nof_cpu_regs_reg_alloc, 46.5 nof_fpu_regs_reg_alloc = pd_nof_fpu_regs_reg_alloc, 46.6 46.7 - nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map, 46.8 - nof_caller_save_fpu_regs = pd_nof_caller_save_fpu_regs_frame_map, 46.9 + max_nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map, 46.10 + nof_caller_save_fpu_regs = pd_nof_caller_save_fpu_regs_frame_map, 46.11 46.12 spill_slot_size_in_bytes = 4 46.13 }; 46.14 @@ -97,7 +97,7 @@ 46.15 static Register _cpu_rnr2reg [nof_cpu_regs]; 46.16 static int _cpu_reg2rnr [nof_cpu_regs]; 46.17 46.18 - static LIR_Opr _caller_save_cpu_regs [nof_caller_save_cpu_regs]; 46.19 + static LIR_Opr _caller_save_cpu_regs [max_nof_caller_save_cpu_regs]; 46.20 static LIR_Opr _caller_save_fpu_regs [nof_caller_save_fpu_regs]; 46.21 46.22 int _framesize; 46.23 @@ -243,7 +243,7 @@ 46.24 VMReg regname(LIR_Opr opr) const; 46.25 46.26 static LIR_Opr caller_save_cpu_reg_at(int i) { 46.27 - assert(i >= 0 && i < nof_caller_save_cpu_regs, "out of bounds"); 46.28 + assert(i >= 0 && i < max_nof_caller_save_cpu_regs, "out of bounds"); 46.29 return _caller_save_cpu_regs[i]; 46.30 } 46.31
47.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Tue Dec 21 23:39:42 2010 -0500 47.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Wed Dec 22 12:24:40 2010 -0500 47.3 @@ -2795,7 +2795,7 @@ 47.4 get = append(new UnsafeGetRaw(as_BasicType(local->type()), e, 47.5 append(new Constant(new IntConstant(offset))), 47.6 0, 47.7 - true)); 47.8 + true /*unaligned*/, true /*wide*/)); 47.9 } 47.10 _state->store_local(index, get); 47.11 } 47.12 @@ -3377,6 +3377,9 @@ 47.13 INLINE_BAILOUT("total inlining greater than DesiredMethodLimit"); 47.14 } 47.15 47.16 + if (is_profiling() && !callee->ensure_method_data()) { 47.17 + INLINE_BAILOUT("mdo allocation failed"); 47.18 + } 47.19 #ifndef PRODUCT 47.20 // printing 47.21 if (PrintInlining) {
48.1 --- a/src/share/vm/c1/c1_IR.cpp Tue Dec 21 23:39:42 2010 -0500 48.2 +++ b/src/share/vm/c1/c1_IR.cpp Wed Dec 22 12:24:40 2010 -0500 48.3 @@ -504,7 +504,12 @@ 48.4 count_edges(start_block, NULL); 48.5 48.6 if (compilation()->is_profiling()) { 48.7 - compilation()->method()->method_data()->set_compilation_stats(_num_loops, _num_blocks); 48.8 + ciMethod *method = compilation()->method(); 48.9 + if (!method->is_accessor()) { 48.10 + ciMethodData* md = method->method_data_or_null(); 48.11 + assert(md != NULL, "Sanity"); 48.12 + md->set_compilation_stats(_num_loops, _num_blocks); 48.13 + } 48.14 } 48.15 48.16 if (_num_loops > 0) {
49.1 --- a/src/share/vm/c1/c1_Instruction.hpp Tue Dec 21 23:39:42 2010 -0500 49.2 +++ b/src/share/vm/c1/c1_Instruction.hpp Wed Dec 22 12:24:40 2010 -0500 49.3 @@ -2110,20 +2110,23 @@ 49.4 49.5 LEAF(UnsafeGetRaw, UnsafeRawOp) 49.6 private: 49.7 - bool _may_be_unaligned; // For OSREntry 49.8 + bool _may_be_unaligned, _is_wide; // For OSREntry 49.9 49.10 public: 49.11 - UnsafeGetRaw(BasicType basic_type, Value addr, bool may_be_unaligned) 49.12 + UnsafeGetRaw(BasicType basic_type, Value addr, bool may_be_unaligned, bool is_wide = false) 49.13 : UnsafeRawOp(basic_type, addr, false) { 49.14 _may_be_unaligned = may_be_unaligned; 49.15 + _is_wide = is_wide; 49.16 } 49.17 49.18 - UnsafeGetRaw(BasicType basic_type, Value base, Value index, int log2_scale, bool may_be_unaligned) 49.19 + UnsafeGetRaw(BasicType basic_type, Value base, Value index, int log2_scale, bool may_be_unaligned, bool is_wide = false) 49.20 : UnsafeRawOp(basic_type, base, index, log2_scale, false) { 49.21 _may_be_unaligned = may_be_unaligned; 49.22 + _is_wide = is_wide; 49.23 } 49.24 49.25 - bool may_be_unaligned() { return _may_be_unaligned; } 49.26 + bool may_be_unaligned() { return _may_be_unaligned; } 49.27 + bool is_wide() { return _is_wide; } 49.28 }; 49.29 49.30
50.1 --- a/src/share/vm/c1/c1_LIR.cpp Tue Dec 21 23:39:42 2010 -0500 50.2 +++ b/src/share/vm/c1/c1_LIR.cpp Wed Dec 22 12:24:40 2010 -0500 50.3 @@ -1742,6 +1742,8 @@ 50.4 return "unaligned move"; 50.5 case lir_move_volatile: 50.6 return "volatile_move"; 50.7 + case lir_move_wide: 50.8 + return "wide_move"; 50.9 default: 50.10 ShouldNotReachHere(); 50.11 return "illegal_op";
51.1 --- a/src/share/vm/c1/c1_LIR.hpp Tue Dec 21 23:39:42 2010 -0500 51.2 +++ b/src/share/vm/c1/c1_LIR.hpp Wed Dec 22 12:24:40 2010 -0500 51.3 @@ -985,6 +985,7 @@ 51.4 lir_move_normal, 51.5 lir_move_volatile, 51.6 lir_move_unaligned, 51.7 + lir_move_wide, 51.8 lir_move_max_flag 51.9 }; 51.10 51.11 @@ -1932,7 +1933,20 @@ 51.12 void move(LIR_Opr src, LIR_Opr dst, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_move, src, dst, dst->type(), lir_patch_none, info)); } 51.13 void move(LIR_Address* src, LIR_Opr dst, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_move, LIR_OprFact::address(src), dst, src->type(), lir_patch_none, info)); } 51.14 void move(LIR_Opr src, LIR_Address* dst, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_move, src, LIR_OprFact::address(dst), dst->type(), lir_patch_none, info)); } 51.15 - 51.16 + void move_wide(LIR_Address* src, LIR_Opr dst, CodeEmitInfo* info = NULL) { 51.17 + if (UseCompressedOops) { 51.18 + append(new LIR_Op1(lir_move, LIR_OprFact::address(src), dst, src->type(), lir_patch_none, info, lir_move_wide)); 51.19 + } else { 51.20 + move(src, dst, info); 51.21 + } 51.22 + } 51.23 + void move_wide(LIR_Opr src, LIR_Address* dst, CodeEmitInfo* info = NULL) { 51.24 + if (UseCompressedOops) { 51.25 + append(new LIR_Op1(lir_move, src, LIR_OprFact::address(dst), dst->type(), lir_patch_none, info, lir_move_wide)); 51.26 + } else { 51.27 + move(src, dst, info); 51.28 + } 51.29 + } 51.30 void volatile_move(LIR_Opr src, LIR_Opr dst, BasicType type, CodeEmitInfo* info = NULL, LIR_PatchCode patch_code = lir_patch_none) { append(new LIR_Op1(lir_move, src, dst, type, patch_code, info, lir_move_volatile)); } 51.31 51.32 void oop2reg (jobject o, LIR_Opr reg) { append(new LIR_Op1(lir_move, LIR_OprFact::oopConst(o), reg)); }
52.1 --- a/src/share/vm/c1/c1_LIRAssembler.cpp Tue Dec 21 23:39:42 2010 -0500 52.2 +++ b/src/share/vm/c1/c1_LIRAssembler.cpp Wed Dec 22 12:24:40 2010 -0500 52.3 @@ -489,7 +489,9 @@ 52.4 volatile_move_op(op->in_opr(), op->result_opr(), op->type(), op->info()); 52.5 } else { 52.6 move_op(op->in_opr(), op->result_opr(), op->type(), 52.7 - op->patch_code(), op->info(), op->pop_fpu_stack(), op->move_kind() == lir_move_unaligned); 52.8 + op->patch_code(), op->info(), op->pop_fpu_stack(), 52.9 + op->move_kind() == lir_move_unaligned, 52.10 + op->move_kind() == lir_move_wide); 52.11 } 52.12 break; 52.13 52.14 @@ -758,7 +760,7 @@ 52.15 } 52.16 52.17 52.18 -void LIR_Assembler::move_op(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned) { 52.19 +void LIR_Assembler::move_op(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned, bool wide) { 52.20 if (src->is_register()) { 52.21 if (dest->is_register()) { 52.22 assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here"); 52.23 @@ -767,7 +769,7 @@ 52.24 assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here"); 52.25 reg2stack(src, dest, type, pop_fpu_stack); 52.26 } else if (dest->is_address()) { 52.27 - reg2mem(src, dest, type, patch_code, info, pop_fpu_stack, unaligned); 52.28 + reg2mem(src, dest, type, patch_code, info, pop_fpu_stack, wide, unaligned); 52.29 } else { 52.30 ShouldNotReachHere(); 52.31 } 52.32 @@ -790,13 +792,13 @@ 52.33 const2stack(src, dest); 52.34 } else if (dest->is_address()) { 52.35 assert(patch_code == lir_patch_none, "no patching allowed here"); 52.36 - const2mem(src, dest, type, info); 52.37 + const2mem(src, dest, type, info, wide); 52.38 } else { 52.39 ShouldNotReachHere(); 52.40 } 52.41 52.42 } else if (src->is_address()) { 52.43 - mem2reg(src, dest, type, patch_code, info, unaligned); 52.44 + mem2reg(src, dest, type, patch_code, info, wide, unaligned); 52.45 52.46 } else { 52.47 ShouldNotReachHere();
53.1 --- a/src/share/vm/c1/c1_LIRAssembler.hpp Tue Dec 21 23:39:42 2010 -0500 53.2 +++ b/src/share/vm/c1/c1_LIRAssembler.hpp Wed Dec 22 12:24:40 2010 -0500 53.3 @@ -165,15 +165,17 @@ 53.4 53.5 void const2reg (LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info); 53.6 void const2stack(LIR_Opr src, LIR_Opr dest); 53.7 - void const2mem (LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info); 53.8 + void const2mem (LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide); 53.9 void reg2stack (LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack); 53.10 void reg2reg (LIR_Opr src, LIR_Opr dest); 53.11 - void reg2mem (LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned); 53.12 + void reg2mem (LIR_Opr src, LIR_Opr dest, BasicType type, 53.13 + LIR_PatchCode patch_code, CodeEmitInfo* info, 53.14 + bool pop_fpu_stack, bool wide, bool unaligned); 53.15 void stack2reg (LIR_Opr src, LIR_Opr dest, BasicType type); 53.16 void stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type); 53.17 void mem2reg (LIR_Opr src, LIR_Opr dest, BasicType type, 53.18 - LIR_PatchCode patch_code = lir_patch_none, 53.19 - CodeEmitInfo* info = NULL, bool unaligned = false); 53.20 + LIR_PatchCode patch_code, 53.21 + CodeEmitInfo* info, bool wide, bool unaligned); 53.22 53.23 void prefetchr (LIR_Opr src); 53.24 void prefetchw (LIR_Opr src); 53.25 @@ -211,7 +213,7 @@ 53.26 53.27 void roundfp_op(LIR_Opr src, LIR_Opr tmp, LIR_Opr dest, bool pop_fpu_stack); 53.28 void move_op(LIR_Opr src, LIR_Opr result, BasicType type, 53.29 - LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned); 53.30 + LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned, bool wide); 53.31 void volatile_move_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); 53.32 void comp_mem_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); // info set for null exceptions 53.33 void comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr result, LIR_Op2* op);
54.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Tue Dec 21 23:39:42 2010 -0500 54.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Wed Dec 22 12:24:40 2010 -0500 54.3 @@ -836,11 +836,8 @@ 54.4 if (if_instr->should_profile()) { 54.5 ciMethod* method = if_instr->profiled_method(); 54.6 assert(method != NULL, "method should be set if branch is profiled"); 54.7 - ciMethodData* md = method->method_data(); 54.8 - if (md == NULL) { 54.9 - bailout("out of memory building methodDataOop"); 54.10 - return; 54.11 - } 54.12 + ciMethodData* md = method->method_data_or_null(); 54.13 + assert(md != NULL, "Sanity"); 54.14 ciProfileData* data = md->bci_to_data(if_instr->profiled_bci()); 54.15 assert(data != NULL, "must have profiling data"); 54.16 assert(data->is_BranchData(), "need BranchData for two-way branches"); 54.17 @@ -864,11 +861,11 @@ 54.18 // MDO cells are intptr_t, so the data_reg width is arch-dependent. 54.19 LIR_Opr data_reg = new_pointer_register(); 54.20 LIR_Address* data_addr = new LIR_Address(md_reg, data_offset_reg, data_reg->type()); 54.21 - __ move(LIR_OprFact::address(data_addr), data_reg); 54.22 + __ move(data_addr, data_reg); 54.23 // Use leal instead of add to avoid destroying condition codes on x86 54.24 LIR_Address* fake_incr_value = new LIR_Address(data_reg, DataLayout::counter_increment, T_INT); 54.25 __ leal(LIR_OprFact::address(fake_incr_value), data_reg); 54.26 - __ move(data_reg, LIR_OprFact::address(data_addr)); 54.27 + __ move(data_reg, data_addr); 54.28 } 54.29 } 54.30 54.31 @@ -1009,12 +1006,12 @@ 54.32 operand_for_instruction(phi)); 54.33 54.34 LIR_Opr thread_reg = getThreadPointer(); 54.35 - __ move(new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT), 54.36 - exceptionOopOpr()); 54.37 - __ move(LIR_OprFact::oopConst(NULL), 54.38 - new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT)); 54.39 - __ move(LIR_OprFact::oopConst(NULL), 54.40 - new LIR_Address(thread_reg, in_bytes(JavaThread::exception_pc_offset()), T_OBJECT)); 54.41 + __ move_wide(new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT), 54.42 + exceptionOopOpr()); 54.43 + __ move_wide(LIR_OprFact::oopConst(NULL), 54.44 + new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT)); 54.45 + __ move_wide(LIR_OprFact::oopConst(NULL), 54.46 + new LIR_Address(thread_reg, in_bytes(JavaThread::exception_pc_offset()), T_OBJECT)); 54.47 54.48 LIR_Opr result = new_register(T_OBJECT); 54.49 __ move(exceptionOopOpr(), result); 54.50 @@ -1085,7 +1082,7 @@ 54.51 void LIRGenerator::do_Return(Return* x) { 54.52 if (compilation()->env()->dtrace_method_probes()) { 54.53 BasicTypeList signature; 54.54 - signature.append(T_INT); // thread 54.55 + signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread 54.56 signature.append(T_OBJECT); // methodOop 54.57 LIR_OprList* args = new LIR_OprList(); 54.58 args->append(getThreadPointer()); 54.59 @@ -1122,8 +1119,8 @@ 54.60 info = state_for(x); 54.61 } 54.62 __ move(new LIR_Address(rcvr.result(), oopDesc::klass_offset_in_bytes(), T_OBJECT), result, info); 54.63 - __ move(new LIR_Address(result, Klass::java_mirror_offset_in_bytes() + 54.64 - klassOopDesc::klass_part_offset_in_bytes(), T_OBJECT), result); 54.65 + __ move_wide(new LIR_Address(result, Klass::java_mirror_offset_in_bytes() + 54.66 + klassOopDesc::klass_part_offset_in_bytes(), T_OBJECT), result); 54.67 } 54.68 54.69 54.70 @@ -1131,7 +1128,7 @@ 54.71 void LIRGenerator::do_currentThread(Intrinsic* x) { 54.72 assert(x->number_of_arguments() == 0, "wrong type"); 54.73 LIR_Opr reg = rlock_result(x); 54.74 - __ load(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg); 54.75 + __ move_wide(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg); 54.76 } 54.77 54.78 54.79 @@ -1908,7 +1905,11 @@ 54.80 if (x->may_be_unaligned() && (dst_type == T_LONG || dst_type == T_DOUBLE)) { 54.81 __ unaligned_move(addr, reg); 54.82 } else { 54.83 - __ move(addr, reg); 54.84 + if (dst_type == T_OBJECT && x->is_wide()) { 54.85 + __ move_wide(addr, reg); 54.86 + } else { 54.87 + __ move(addr, reg); 54.88 + } 54.89 } 54.90 } 54.91 54.92 @@ -2215,11 +2216,8 @@ 54.93 if (x->should_profile()) { 54.94 ciMethod* method = x->profiled_method(); 54.95 assert(method != NULL, "method should be set if branch is profiled"); 54.96 - ciMethodData* md = method->method_data(); 54.97 - if (md == NULL) { 54.98 - bailout("out of memory building methodDataOop"); 54.99 - return; 54.100 - } 54.101 + ciMethodData* md = method->method_data_or_null(); 54.102 + assert(md != NULL, "Sanity"); 54.103 ciProfileData* data = md->bci_to_data(x->profiled_bci()); 54.104 assert(data != NULL, "must have profiling data"); 54.105 int offset; 54.106 @@ -2287,7 +2285,7 @@ 54.107 54.108 if (compilation()->env()->dtrace_method_probes()) { 54.109 BasicTypeList signature; 54.110 - signature.append(T_INT); // thread 54.111 + signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread 54.112 signature.append(T_OBJECT); // methodOop 54.113 LIR_OprList* args = new LIR_OprList(); 54.114 args->append(getThreadPointer()); 54.115 @@ -2352,11 +2350,14 @@ 54.116 } else { 54.117 LIR_Address* addr = loc->as_address_ptr(); 54.118 param->load_for_store(addr->type()); 54.119 - if (addr->type() == T_LONG || addr->type() == T_DOUBLE) { 54.120 - __ unaligned_move(param->result(), addr); 54.121 - } else { 54.122 - __ move(param->result(), addr); 54.123 - } 54.124 + if (addr->type() == T_OBJECT) { 54.125 + __ move_wide(param->result(), addr); 54.126 + } else 54.127 + if (addr->type() == T_LONG || addr->type() == T_DOUBLE) { 54.128 + __ unaligned_move(param->result(), addr); 54.129 + } else { 54.130 + __ move(param->result(), addr); 54.131 + } 54.132 } 54.133 } 54.134 54.135 @@ -2368,7 +2369,7 @@ 54.136 } else { 54.137 assert(loc->is_address(), "just checking"); 54.138 receiver->load_for_store(T_OBJECT); 54.139 - __ move(receiver->result(), loc); 54.140 + __ move_wide(receiver->result(), loc->as_address_ptr()); 54.141 } 54.142 } 54.143 } 54.144 @@ -2716,7 +2717,9 @@ 54.145 } else if (level == CompLevel_full_profile) { 54.146 offset = in_bytes(backedge ? methodDataOopDesc::backedge_counter_offset() : 54.147 methodDataOopDesc::invocation_counter_offset()); 54.148 - __ oop2reg(method->method_data()->constant_encoding(), counter_holder); 54.149 + ciMethodData* md = method->method_data_or_null(); 54.150 + assert(md != NULL, "Sanity"); 54.151 + __ oop2reg(md->constant_encoding(), counter_holder); 54.152 meth = new_register(T_OBJECT); 54.153 __ oop2reg(method->constant_encoding(), meth); 54.154 } else {
55.1 --- a/src/share/vm/c1/c1_LinearScan.cpp Tue Dec 21 23:39:42 2010 -0500 55.2 +++ b/src/share/vm/c1/c1_LinearScan.cpp Wed Dec 22 12:24:40 2010 -0500 55.3 @@ -1273,7 +1273,7 @@ 55.4 int caller_save_registers[LinearScan::nof_regs]; 55.5 55.6 int i; 55.7 - for (i = 0; i < FrameMap::nof_caller_save_cpu_regs; i++) { 55.8 + for (i = 0; i < FrameMap::nof_caller_save_cpu_regs(); i++) { 55.9 LIR_Opr opr = FrameMap::caller_save_cpu_reg_at(i); 55.10 assert(opr->is_valid() && opr->is_register(), "FrameMap should not return invalid operands"); 55.11 assert(reg_numHi(opr) == -1, "missing addition of range for hi-register"); 55.12 @@ -3557,7 +3557,7 @@ 55.13 55.14 // invalidate all caller save registers at calls 55.15 if (visitor.has_call()) { 55.16 - for (j = 0; j < FrameMap::nof_caller_save_cpu_regs; j++) { 55.17 + for (j = 0; j < FrameMap::nof_caller_save_cpu_regs(); j++) { 55.18 state_put(input_state, reg_num(FrameMap::caller_save_cpu_reg_at(j)), NULL); 55.19 } 55.20 for (j = 0; j < FrameMap::nof_caller_save_fpu_regs; j++) { 55.21 @@ -5596,7 +5596,7 @@ 55.22 _last_reg = pd_last_fpu_reg; 55.23 } else { 55.24 _first_reg = pd_first_cpu_reg; 55.25 - _last_reg = pd_last_cpu_reg; 55.26 + _last_reg = FrameMap::last_cpu_reg(); 55.27 } 55.28 55.29 assert(0 <= _first_reg && _first_reg < LinearScan::nof_regs, "out of range");
56.1 --- a/src/share/vm/c1/c1_Runtime1.cpp Tue Dec 21 23:39:42 2010 -0500 56.2 +++ b/src/share/vm/c1/c1_Runtime1.cpp Wed Dec 22 12:24:40 2010 -0500 56.3 @@ -1174,7 +1174,7 @@ 56.4 memmove(dst_addr, src_addr, length << l2es); 56.5 return ac_ok; 56.6 } else if (src->is_objArray() && dst->is_objArray()) { 56.7 - if (UseCompressedOops) { // will need for tiered 56.8 + if (UseCompressedOops) { 56.9 narrowOop *src_addr = objArrayOop(src)->obj_at_addr<narrowOop>(src_pos); 56.10 narrowOop *dst_addr = objArrayOop(dst)->obj_at_addr<narrowOop>(dst_pos); 56.11 return obj_arraycopy_work(src, src_addr, dst, dst_addr, length); 56.12 @@ -1210,10 +1210,11 @@ 56.13 assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well."); 56.14 if (UseCompressedOops) { 56.15 bs->write_ref_array_pre((narrowOop*)dst, num); 56.16 + Copy::conjoint_oops_atomic((narrowOop*) src, (narrowOop*) dst, num); 56.17 } else { 56.18 bs->write_ref_array_pre((oop*)dst, num); 56.19 + Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num); 56.20 } 56.21 - Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num); 56.22 bs->write_ref_array(dst, num); 56.23 JRT_END 56.24
57.1 --- a/src/share/vm/ci/ciMethod.cpp Tue Dec 21 23:39:42 2010 -0500 57.2 +++ b/src/share/vm/ci/ciMethod.cpp Wed Dec 22 12:24:40 2010 -0500 57.3 @@ -797,12 +797,13 @@ 57.4 57.5 57.6 // ------------------------------------------------------------------ 57.7 -// ciMethod::build_method_data 57.8 +// ciMethod::ensure_method_data 57.9 // 57.10 // Generate new methodDataOop objects at compile time. 57.11 -void ciMethod::build_method_data(methodHandle h_m) { 57.12 +// Return true if allocation was successful or no MDO is required. 57.13 +bool ciMethod::ensure_method_data(methodHandle h_m) { 57.14 EXCEPTION_CONTEXT; 57.15 - if (is_native() || is_abstract() || h_m()->is_accessor()) return; 57.16 + if (is_native() || is_abstract() || h_m()->is_accessor()) return true; 57.17 if (h_m()->method_data() == NULL) { 57.18 methodOopDesc::build_interpreter_method_data(h_m, THREAD); 57.19 if (HAS_PENDING_EXCEPTION) { 57.20 @@ -812,18 +813,22 @@ 57.21 if (h_m()->method_data() != NULL) { 57.22 _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data(); 57.23 _method_data->load_data(); 57.24 + return true; 57.25 } else { 57.26 _method_data = CURRENT_ENV->get_empty_methodData(); 57.27 + return false; 57.28 } 57.29 } 57.30 57.31 // public, retroactive version 57.32 -void ciMethod::build_method_data() { 57.33 +bool ciMethod::ensure_method_data() { 57.34 + bool result = true; 57.35 if (_method_data == NULL || _method_data->is_empty()) { 57.36 GUARDED_VM_ENTRY({ 57.37 - build_method_data(get_methodOop()); 57.38 + result = ensure_method_data(get_methodOop()); 57.39 }); 57.40 } 57.41 + return result; 57.42 } 57.43 57.44 57.45 @@ -839,11 +844,6 @@ 57.46 Thread* my_thread = JavaThread::current(); 57.47 methodHandle h_m(my_thread, get_methodOop()); 57.48 57.49 - // Create an MDO for the inlinee 57.50 - if (TieredCompilation && is_c1_compile(env->comp_level())) { 57.51 - build_method_data(h_m); 57.52 - } 57.53 - 57.54 if (h_m()->method_data() != NULL) { 57.55 _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data(); 57.56 _method_data->load_data(); 57.57 @@ -854,6 +854,15 @@ 57.58 57.59 } 57.60 57.61 +// ------------------------------------------------------------------ 57.62 +// ciMethod::method_data_or_null 57.63 +// Returns a pointer to ciMethodData if MDO exists on the VM side, 57.64 +// NULL otherwise. 57.65 +ciMethodData* ciMethod::method_data_or_null() { 57.66 + ciMethodData *md = method_data(); 57.67 + if (md->is_empty()) return NULL; 57.68 + return md; 57.69 +} 57.70 57.71 // ------------------------------------------------------------------ 57.72 // ciMethod::will_link
58.1 --- a/src/share/vm/ci/ciMethod.hpp Tue Dec 21 23:39:42 2010 -0500 58.2 +++ b/src/share/vm/ci/ciMethod.hpp Wed Dec 22 12:24:40 2010 -0500 58.3 @@ -106,7 +106,7 @@ 58.4 58.5 void check_is_loaded() const { assert(is_loaded(), "not loaded"); } 58.6 58.7 - void build_method_data(methodHandle h_m); 58.8 + bool ensure_method_data(methodHandle h_m); 58.9 58.10 void code_at_put(int bci, Bytecodes::Code code) { 58.11 Bytecodes::check(code); 58.12 @@ -121,6 +121,7 @@ 58.13 ciSymbol* name() const { return _name; } 58.14 ciInstanceKlass* holder() const { return _holder; } 58.15 ciMethodData* method_data(); 58.16 + ciMethodData* method_data_or_null(); 58.17 58.18 // Signature information. 58.19 ciSignature* signature() const { return _signature; } 58.20 @@ -230,7 +231,7 @@ 58.21 bool has_unloaded_classes_in_signature(); 58.22 bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const; 58.23 bool check_call(int refinfo_index, bool is_static) const; 58.24 - void build_method_data(); // make sure it exists in the VM also 58.25 + bool ensure_method_data(); // make sure it exists in the VM also 58.26 int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC 58.27 58.28 // JSR 292 support
59.1 --- a/src/share/vm/classfile/classFileParser.cpp Tue Dec 21 23:39:42 2010 -0500 59.2 +++ b/src/share/vm/classfile/classFileParser.cpp Wed Dec 22 12:24:40 2010 -0500 59.3 @@ -99,12 +99,6 @@ 59.4 unsigned int hashValues[SymbolTable::symbol_alloc_batch_size]; 59.5 int names_count = 0; 59.6 59.7 - // Side buffer for operands of variable-sized (InvokeDynamic) entries. 59.8 - GrowableArray<int>* operands = NULL; 59.9 -#ifdef ASSERT 59.10 - GrowableArray<int>* indy_instructions = new GrowableArray<int>(THREAD, 10); 59.11 -#endif 59.12 - 59.13 // parsing Index 0 is unused 59.14 for (int index = 1; index < length; index++) { 59.15 // Each of the following case guarantees one more byte in the stream 59.16 @@ -184,36 +178,20 @@ 59.17 "Class file version does not support constant tag %u in class file %s"), 59.18 tag, CHECK); 59.19 } 59.20 - if (!AllowTransitionalJSR292 && tag == JVM_CONSTANT_InvokeDynamicTrans) { 59.21 - classfile_parse_error( 59.22 + cfs->guarantee_more(5, CHECK); // bsm_index, nt, tag/access_flags 59.23 + u2 bootstrap_specifier_index = cfs->get_u2_fast(); 59.24 + u2 name_and_type_index = cfs->get_u2_fast(); 59.25 + if (tag == JVM_CONSTANT_InvokeDynamicTrans) { 59.26 + if (!AllowTransitionalJSR292) 59.27 + classfile_parse_error( 59.28 "This JVM does not support transitional InvokeDynamic tag %u in class file %s", 59.29 tag, CHECK); 59.30 + cp->invoke_dynamic_trans_at_put(index, bootstrap_specifier_index, name_and_type_index); 59.31 + break; 59.32 } 59.33 - bool trans_no_argc = AllowTransitionalJSR292 && (tag == JVM_CONSTANT_InvokeDynamicTrans); 59.34 - cfs->guarantee_more(7, CHECK); // bsm_index, nt, argc, ..., tag/access_flags 59.35 - u2 bootstrap_method_index = cfs->get_u2_fast(); 59.36 - u2 name_and_type_index = cfs->get_u2_fast(); 59.37 - int argument_count = trans_no_argc ? 0 : cfs->get_u2_fast(); 59.38 - cfs->guarantee_more(2*argument_count + 1, CHECK); // argv[argc]..., tag/access_flags 59.39 - int argv_offset = constantPoolOopDesc::_indy_argv_offset; 59.40 - int op_count = argv_offset + argument_count; // bsm, nt, argc, argv[]... 59.41 - int op_base = start_operand_group(operands, op_count, CHECK); 59.42 - assert(argv_offset == 3, "else adjust next 3 assignments"); 59.43 - operands->at_put(op_base + constantPoolOopDesc::_indy_bsm_offset, bootstrap_method_index); 59.44 - operands->at_put(op_base + constantPoolOopDesc::_indy_nt_offset, name_and_type_index); 59.45 - operands->at_put(op_base + constantPoolOopDesc::_indy_argc_offset, argument_count); 59.46 - for (int arg_i = 0; arg_i < argument_count; arg_i++) { 59.47 - int arg = cfs->get_u2_fast(); 59.48 - operands->at_put(op_base + constantPoolOopDesc::_indy_argv_offset + arg_i, arg); 59.49 - } 59.50 - cp->invoke_dynamic_at_put(index, op_base, op_count); 59.51 -#ifdef ASSERT 59.52 - // Record the steps just taken for later checking. 59.53 - indy_instructions->append(index); 59.54 - indy_instructions->append(bootstrap_method_index); 59.55 - indy_instructions->append(name_and_type_index); 59.56 - indy_instructions->append(argument_count); 59.57 -#endif //ASSERT 59.58 + if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index) 59.59 + _max_bootstrap_specifier_index = (int) bootstrap_specifier_index; // collect for later 59.60 + cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index); 59.61 } 59.62 break; 59.63 case JVM_CONSTANT_Integer : 59.64 @@ -316,23 +294,6 @@ 59.65 oopFactory::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK); 59.66 } 59.67 59.68 - if (operands != NULL && operands->length() > 0) { 59.69 - store_operand_array(operands, cp, CHECK); 59.70 - } 59.71 -#ifdef ASSERT 59.72 - // Re-assert the indy structures, now that assertion checking can work. 59.73 - for (int indy_i = 0; indy_i < indy_instructions->length(); ) { 59.74 - int index = indy_instructions->at(indy_i++); 59.75 - int bootstrap_method_index = indy_instructions->at(indy_i++); 59.76 - int name_and_type_index = indy_instructions->at(indy_i++); 59.77 - int argument_count = indy_instructions->at(indy_i++); 59.78 - assert(cp->check_invoke_dynamic_at(index, 59.79 - bootstrap_method_index, name_and_type_index, 59.80 - argument_count), 59.81 - "indy structure is OK"); 59.82 - } 59.83 -#endif //ASSERT 59.84 - 59.85 // Copy _current pointer of local copy back to stream(). 59.86 #ifdef ASSERT 59.87 assert(cfs0->current() == old_current, "non-exclusive use of stream()"); 59.88 @@ -340,41 +301,6 @@ 59.89 cfs0->set_current(cfs1.current()); 59.90 } 59.91 59.92 -int ClassFileParser::start_operand_group(GrowableArray<int>* &operands, int op_count, TRAPS) { 59.93 - if (operands == NULL) { 59.94 - operands = new GrowableArray<int>(THREAD, 100); 59.95 - int fillp_offset = constantPoolOopDesc::_multi_operand_buffer_fill_pointer_offset; 59.96 - while (operands->length() <= fillp_offset) 59.97 - operands->append(0); // force op_base > 0, for an error check 59.98 - DEBUG_ONLY(operands->at_put(fillp_offset, (int)badHeapWordVal)); 59.99 - } 59.100 - int cnt_pos = operands->append(op_count); 59.101 - int arg_pos = operands->length(); 59.102 - operands->at_grow(arg_pos + op_count - 1); // grow to include the operands 59.103 - assert(operands->length() == arg_pos + op_count, ""); 59.104 - int op_base = cnt_pos - constantPoolOopDesc::_multi_operand_count_offset; 59.105 - return op_base; 59.106 -} 59.107 - 59.108 -void ClassFileParser::store_operand_array(GrowableArray<int>* operands, constantPoolHandle cp, TRAPS) { 59.109 - // Collect the buffer of operands from variable-sized entries into a permanent array. 59.110 - int arraylen = operands->length(); 59.111 - int fillp_offset = constantPoolOopDesc::_multi_operand_buffer_fill_pointer_offset; 59.112 - assert(operands->at(fillp_offset) == (int)badHeapWordVal, "value unused so far"); 59.113 - operands->at_put(fillp_offset, arraylen); 59.114 - cp->multi_operand_buffer_grow(arraylen, CHECK); 59.115 - typeArrayOop operands_oop = cp->operands(); 59.116 - assert(operands_oop->length() == arraylen, ""); 59.117 - for (int i = 0; i < arraylen; i++) { 59.118 - operands_oop->int_at_put(i, operands->at(i)); 59.119 - } 59.120 - cp->set_operands(operands_oop); 59.121 - // The fill_pointer is used only by constantPoolOop::copy_entry_to and friends, 59.122 - // when constant pools need to be merged. Make sure it is sane now. 59.123 - assert(cp->multi_operand_buffer_fill_pointer() == arraylen, ""); 59.124 -} 59.125 - 59.126 - 59.127 bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); } 59.128 59.129 constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) { 59.130 @@ -401,7 +327,8 @@ 59.131 59.132 // first verification pass - validate cross references and fixup class and string constants 59.133 for (index = 1; index < length; index++) { // Index 0 is unused 59.134 - switch (cp->tag_at(index).value()) { 59.135 + jbyte tag = cp->tag_at(index).value(); 59.136 + switch (tag) { 59.137 case JVM_CONSTANT_Class : 59.138 ShouldNotReachHere(); // Only JVM_CONSTANT_ClassIndex should be present 59.139 break; 59.140 @@ -543,35 +470,23 @@ 59.141 } 59.142 break; 59.143 case JVM_CONSTANT_InvokeDynamicTrans : 59.144 - ShouldNotReachHere(); // this tag does not appear in the heap 59.145 case JVM_CONSTANT_InvokeDynamic : 59.146 { 59.147 - int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index); 59.148 int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index); 59.149 - check_property((bootstrap_method_ref_index == 0 && AllowTransitionalJSR292) 59.150 - || 59.151 - (valid_cp_range(bootstrap_method_ref_index, length) && 59.152 - (cp->tag_at(bootstrap_method_ref_index).is_method_handle())), 59.153 - "Invalid constant pool index %u in class file %s", 59.154 - bootstrap_method_ref_index, 59.155 - CHECK_(nullHandle)); 59.156 check_property(valid_cp_range(name_and_type_ref_index, length) && 59.157 cp->tag_at(name_and_type_ref_index).is_name_and_type(), 59.158 "Invalid constant pool index %u in class file %s", 59.159 name_and_type_ref_index, 59.160 CHECK_(nullHandle)); 59.161 - int argc = cp->invoke_dynamic_argument_count_at(index); 59.162 - for (int arg_i = 0; arg_i < argc; arg_i++) { 59.163 - int arg = cp->invoke_dynamic_argument_index_at(index, arg_i); 59.164 - check_property(valid_cp_range(arg, length) && 59.165 - cp->tag_at(arg).is_loadable_constant() || 59.166 - // temporary early forms of string and class: 59.167 - cp->tag_at(arg).is_klass_index() || 59.168 - cp->tag_at(arg).is_string_index(), 59.169 + if (tag == JVM_CONSTANT_InvokeDynamicTrans) { 59.170 + int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index); 59.171 + check_property(valid_cp_range(bootstrap_method_ref_index, length) && 59.172 + cp->tag_at(bootstrap_method_ref_index).is_method_handle(), 59.173 "Invalid constant pool index %u in class file %s", 59.174 - arg, 59.175 + bootstrap_method_ref_index, 59.176 CHECK_(nullHandle)); 59.177 } 59.178 + // bootstrap specifier index must be checked later, when BootstrapMethods attr is available 59.179 break; 59.180 } 59.181 default: 59.182 @@ -2429,6 +2344,76 @@ 59.183 k->set_generic_signature(cp->symbol_at(signature_index)); 59.184 } 59.185 59.186 +void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k, 59.187 + u4 attribute_byte_length, TRAPS) { 59.188 + ClassFileStream* cfs = stream(); 59.189 + u1* current_start = cfs->current(); 59.190 + 59.191 + cfs->guarantee_more(2, CHECK); // length 59.192 + int attribute_array_length = cfs->get_u2_fast(); 59.193 + 59.194 + guarantee_property(_max_bootstrap_specifier_index < attribute_array_length, 59.195 + "Short length on BootstrapMethods in class file %s", 59.196 + CHECK); 59.197 + 59.198 + // The attribute contains a counted array of counted tuples of shorts, 59.199 + // represending bootstrap specifiers: 59.200 + // length*{bootstrap_method_index, argument_count*{argument_index}} 59.201 + int operand_count = (attribute_byte_length - sizeof(u2)) / sizeof(u2); 59.202 + // operand_count = number of shorts in attr, except for leading length 59.203 + 59.204 + // The attribute is copied into a short[] array. 59.205 + // The array begins with a series of short[2] pairs, one for each tuple. 59.206 + int index_size = (attribute_array_length * 2); 59.207 + 59.208 + typeArrayOop operands_oop = oopFactory::new_permanent_intArray(index_size + operand_count, CHECK); 59.209 + typeArrayHandle operands(THREAD, operands_oop); 59.210 + operands_oop = NULL; // tidy 59.211 + 59.212 + int operand_fill_index = index_size; 59.213 + int cp_size = cp->length(); 59.214 + 59.215 + for (int n = 0; n < attribute_array_length; n++) { 59.216 + // Store a 32-bit offset into the header of the operand array. 59.217 + assert(constantPoolOopDesc::operand_offset_at(operands(), n) == 0, ""); 59.218 + constantPoolOopDesc::operand_offset_at_put(operands(), n, operand_fill_index); 59.219 + 59.220 + // Read a bootstrap specifier. 59.221 + cfs->guarantee_more(sizeof(u2) * 2, CHECK); // bsm, argc 59.222 + u2 bootstrap_method_index = cfs->get_u2_fast(); 59.223 + u2 argument_count = cfs->get_u2_fast(); 59.224 + check_property( 59.225 + valid_cp_range(bootstrap_method_index, cp_size) && 59.226 + cp->tag_at(bootstrap_method_index).is_method_handle(), 59.227 + "bootstrap_method_index %u has bad constant type in class file %s", 59.228 + CHECK); 59.229 + operands->short_at_put(operand_fill_index++, bootstrap_method_index); 59.230 + operands->short_at_put(operand_fill_index++, argument_count); 59.231 + 59.232 + cfs->guarantee_more(sizeof(u2) * argument_count, CHECK); // argv[argc] 59.233 + for (int j = 0; j < argument_count; j++) { 59.234 + u2 arg_index = cfs->get_u2_fast(); 59.235 + check_property( 59.236 + valid_cp_range(arg_index, cp_size) && 59.237 + cp->tag_at(arg_index).is_loadable_constant(), 59.238 + "argument_index %u has bad constant type in class file %s", 59.239 + CHECK); 59.240 + operands->short_at_put(operand_fill_index++, arg_index); 59.241 + } 59.242 + } 59.243 + 59.244 + assert(operand_fill_index == operands()->length(), "exact fill"); 59.245 + assert(constantPoolOopDesc::operand_array_length(operands()) == attribute_array_length, "correct decode"); 59.246 + 59.247 + u1* current_end = cfs->current(); 59.248 + guarantee_property(current_end == current_start + attribute_byte_length, 59.249 + "Bad length on BootstrapMethods in class file %s", 59.250 + CHECK); 59.251 + 59.252 + cp->set_operands(operands()); 59.253 +} 59.254 + 59.255 + 59.256 void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS) { 59.257 ClassFileStream* cfs = stream(); 59.258 // Set inner classes attribute to default sentinel 59.259 @@ -2438,6 +2423,7 @@ 59.260 bool parsed_sourcefile_attribute = false; 59.261 bool parsed_innerclasses_attribute = false; 59.262 bool parsed_enclosingmethod_attribute = false; 59.263 + bool parsed_bootstrap_methods_attribute = false; 59.264 u1* runtime_visible_annotations = NULL; 59.265 int runtime_visible_annotations_length = 0; 59.266 u1* runtime_invisible_annotations = NULL; 59.267 @@ -2536,6 +2522,12 @@ 59.268 classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK); 59.269 } 59.270 k->set_enclosing_method_indices(class_index, method_index); 59.271 + } else if (tag == vmSymbols::tag_bootstrap_methods() && 59.272 + _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { 59.273 + if (parsed_bootstrap_methods_attribute) 59.274 + classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); 59.275 + parsed_bootstrap_methods_attribute = true; 59.276 + parse_classfile_bootstrap_methods_attribute(cp, k, attribute_length, CHECK); 59.277 } else { 59.278 // Unknown attribute 59.279 cfs->skip_u1(attribute_length, CHECK); 59.280 @@ -2551,6 +2543,11 @@ 59.281 runtime_invisible_annotations_length, 59.282 CHECK); 59.283 k->set_class_annotations(annotations()); 59.284 + 59.285 + if (_max_bootstrap_specifier_index >= 0) { 59.286 + guarantee_property(parsed_bootstrap_methods_attribute, 59.287 + "Missing BootstrapMethods attribute in class file %s", CHECK); 59.288 + } 59.289 } 59.290 59.291 59.292 @@ -2868,6 +2865,7 @@ 59.293 PerfClassTraceTime::PARSE_CLASS); 59.294 59.295 _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false; 59.296 + _max_bootstrap_specifier_index = -1; 59.297 59.298 if (JvmtiExport::should_post_class_file_load_hook()) { 59.299 unsigned char* ptr = cfs->buffer();
60.1 --- a/src/share/vm/classfile/classFileParser.hpp Tue Dec 21 23:39:42 2010 -0500 60.2 +++ b/src/share/vm/classfile/classFileParser.hpp Wed Dec 22 12:24:40 2010 -0500 60.3 @@ -50,6 +50,8 @@ 60.4 bool _has_empty_finalizer; 60.5 bool _has_vanilla_constructor; 60.6 60.7 + int _max_bootstrap_specifier_index; 60.8 + 60.9 enum { fixed_buffer_size = 128 }; 60.10 u_char linenumbertable_buffer[fixed_buffer_size]; 60.11 60.12 @@ -66,9 +68,6 @@ 60.13 60.14 constantPoolHandle parse_constant_pool(TRAPS); 60.15 60.16 - static int start_operand_group(GrowableArray<int>* &operands, int op_count, TRAPS); 60.17 - static void store_operand_array(GrowableArray<int>* operands, constantPoolHandle cp, TRAPS); 60.18 - 60.19 // Interface parsing 60.20 objArrayHandle parse_interfaces(constantPoolHandle cp, 60.21 int length, 60.22 @@ -130,6 +129,7 @@ 60.23 void parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS); 60.24 void parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS); 60.25 void parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS); 60.26 + void parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k, u4 attribute_length, TRAPS); 60.27 60.28 // Annotations handling 60.29 typeArrayHandle assemble_annotations(u1* runtime_visible_annotations,
61.1 --- a/src/share/vm/classfile/systemDictionary.cpp Tue Dec 21 23:39:42 2010 -0500 61.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Wed Dec 22 12:24:40 2010 -0500 61.3 @@ -2010,7 +2010,7 @@ 61.4 scan = WKID(meth_group_end+1); 61.5 } 61.6 WKID indy_group_start = WK_KLASS_ENUM_NAME(Linkage_klass); 61.7 - WKID indy_group_end = WK_KLASS_ENUM_NAME(InvokeDynamic_klass); 61.8 + WKID indy_group_end = WK_KLASS_ENUM_NAME(CallSite_klass); 61.9 initialize_wk_klasses_until(indy_group_start, scan, CHECK); 61.10 if (EnableInvokeDynamic) { 61.11 initialize_wk_klasses_through(indy_group_end, scan, CHECK);
62.1 --- a/src/share/vm/classfile/systemDictionary.hpp Tue Dec 21 23:39:42 2010 -0500 62.2 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Dec 22 12:24:40 2010 -0500 62.3 @@ -156,8 +156,7 @@ 62.4 template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \ 62.5 template(Linkage_klass, java_dyn_Linkage, Opt) \ 62.6 template(CallSite_klass, java_dyn_CallSite, Opt) \ 62.7 - template(InvokeDynamic_klass, java_dyn_InvokeDynamic, Opt) \ 62.8 - /* Note: MethodHandle must be first, and InvokeDynamic last in group */ \ 62.9 + /* Note: MethodHandle must be first, and CallSite last in group */ \ 62.10 \ 62.11 template(StringBuffer_klass, java_lang_StringBuffer, Pre) \ 62.12 template(StringBuilder_klass, java_lang_StringBuilder, Pre) \
63.1 --- a/src/share/vm/classfile/vmSymbols.hpp Tue Dec 21 23:39:42 2010 -0500 63.2 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Dec 22 12:24:40 2010 -0500 63.3 @@ -132,6 +132,7 @@ 63.4 template(tag_runtime_invisible_parameter_annotations,"RuntimeInvisibleParameterAnnotations") \ 63.5 template(tag_annotation_default, "AnnotationDefault") \ 63.6 template(tag_enclosing_method, "EnclosingMethod") \ 63.7 + template(tag_bootstrap_methods, "BootstrapMethods") \ 63.8 \ 63.9 /* exception klasses: at least all exceptions thrown by the VM have entries here */ \ 63.10 template(java_lang_ArithmeticException, "java/lang/ArithmeticException") \
64.1 --- a/src/share/vm/code/compressedStream.cpp Tue Dec 21 23:39:42 2010 -0500 64.2 +++ b/src/share/vm/code/compressedStream.cpp Wed Dec 22 12:24:40 2010 -0500 64.3 @@ -197,6 +197,7 @@ 64.4 // compiler stack overflow is fixed. 64.5 #if _MSC_VER >=1400 && !defined(_WIN64) 64.6 #pragma optimize("", off) 64.7 +#pragma warning(disable: 4748) 64.8 #endif 64.9 64.10 // generator for an "interesting" set of critical values 64.11 @@ -276,6 +277,7 @@ 64.12 } 64.13 64.14 #if _MSC_VER >=1400 && !defined(_WIN64) 64.15 +#pragma warning(default: 4748) 64.16 #pragma optimize("", on) 64.17 #endif 64.18
65.1 --- a/src/share/vm/code/relocInfo.cpp Tue Dec 21 23:39:42 2010 -0500 65.2 +++ b/src/share/vm/code/relocInfo.cpp Wed Dec 22 12:24:40 2010 -0500 65.3 @@ -1093,8 +1093,8 @@ 65.4 tty->print_cr("(no relocs)"); 65.5 return; 65.6 } 65.7 - tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT, 65.8 - _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr); 65.9 + tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d", 65.10 + _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr, _current->addr_offset()); 65.11 if (current()->format() != 0) 65.12 tty->print(" format=%d", current()->format()); 65.13 if (datalen() == 1) {
66.1 --- a/src/share/vm/compiler/disassembler.cpp Tue Dec 21 23:39:42 2010 -0500 66.2 +++ b/src/share/vm/compiler/disassembler.cpp Wed Dec 22 12:24:40 2010 -0500 66.3 @@ -466,5 +466,18 @@ 66.4 env.set_total_ticks(total_bucket_count); 66.5 } 66.6 66.7 + // Print constant table. 66.8 + if (nm->consts_size() > 0) { 66.9 + nm->print_nmethod_labels(env.output(), nm->consts_begin()); 66.10 + int offset = 0; 66.11 + for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) { 66.12 + if ((offset % 8) == 0) { 66.13 + env.output()->print_cr(" " INTPTR_FORMAT " (offset: %4d): " PTR32_FORMAT " " PTR64_FORMAT, (intptr_t) p, offset, *((int32_t*) p), *((int64_t*) p)); 66.14 + } else { 66.15 + env.output()->print_cr(" " INTPTR_FORMAT " (offset: %4d): " PTR32_FORMAT, (intptr_t) p, offset, *((int32_t*) p)); 66.16 + } 66.17 + } 66.18 + } 66.19 + 66.20 env.decode_instructions(p, end); 66.21 }
67.1 --- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Tue Dec 21 23:39:42 2010 -0500 67.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Wed Dec 22 12:24:40 2010 -0500 67.3 @@ -277,7 +277,9 @@ 67.4 // completed. This will also notify the FullGCCount_lock in case a 67.5 // Java thread is waiting for a full GC to happen (e.g., it 67.6 // called System.gc() with +ExplicitGCInvokesConcurrent). 67.7 - g1->increment_full_collections_completed(true /* outer */); 67.8 + _sts.join(); 67.9 + g1->increment_full_collections_completed(true /* concurrent */); 67.10 + _sts.leave(); 67.11 } 67.12 assert(_should_terminate, "just checking"); 67.13
68.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Dec 21 23:39:42 2010 -0500 68.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Dec 22 12:24:40 2010 -0500 68.3 @@ -1389,7 +1389,7 @@ 68.4 } 68.5 68.6 // Update the number of full collections that have been completed. 68.7 - increment_full_collections_completed(false /* outer */); 68.8 + increment_full_collections_completed(false /* concurrent */); 68.9 68.10 if (PrintHeapAtGC) { 68.11 Universe::print_heap_after_gc(); 68.12 @@ -2176,9 +2176,14 @@ 68.13 (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)); 68.14 } 68.15 68.16 -void G1CollectedHeap::increment_full_collections_completed(bool outer) { 68.17 +void G1CollectedHeap::increment_full_collections_completed(bool concurrent) { 68.18 MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); 68.19 68.20 + // We assume that if concurrent == true, then the caller is a 68.21 + // concurrent thread that was joined the Suspendible Thread 68.22 + // Set. If there's ever a cheap way to check this, we should add an 68.23 + // assert here. 68.24 + 68.25 // We have already incremented _total_full_collections at the start 68.26 // of the GC, so total_full_collections() represents how many full 68.27 // collections have been started. 68.28 @@ -2192,17 +2197,18 @@ 68.29 // behind the number of full collections started. 68.30 68.31 // This is the case for the inner caller, i.e. a Full GC. 68.32 - assert(outer || 68.33 + assert(concurrent || 68.34 (full_collections_started == _full_collections_completed + 1) || 68.35 (full_collections_started == _full_collections_completed + 2), 68.36 - err_msg("for inner caller: full_collections_started = %u " 68.37 + err_msg("for inner caller (Full GC): full_collections_started = %u " 68.38 "is inconsistent with _full_collections_completed = %u", 68.39 full_collections_started, _full_collections_completed)); 68.40 68.41 // This is the case for the outer caller, i.e. the concurrent cycle. 68.42 - assert(!outer || 68.43 + assert(!concurrent || 68.44 (full_collections_started == _full_collections_completed + 1), 68.45 - err_msg("for outer caller: full_collections_started = %u " 68.46 + err_msg("for outer caller (concurrent cycle): " 68.47 + "full_collections_started = %u " 68.48 "is inconsistent with _full_collections_completed = %u", 68.49 full_collections_started, _full_collections_completed)); 68.50 68.51 @@ -2212,7 +2218,7 @@ 68.52 // we wake up any waiters (especially when ExplicitInvokesConcurrent 68.53 // is set) so that if a waiter requests another System.gc() it doesn't 68.54 // incorrectly see that a marking cyle is still in progress. 68.55 - if (outer) { 68.56 + if (concurrent) { 68.57 _cmThread->clear_in_progress(); 68.58 } 68.59
69.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Dec 21 23:39:42 2010 -0500 69.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Dec 22 12:24:40 2010 -0500 69.3 @@ -643,16 +643,16 @@ 69.4 // can happen in a nested fashion, i.e., we start a concurrent 69.5 // cycle, a Full GC happens half-way through it which ends first, 69.6 // and then the cycle notices that a Full GC happened and ends 69.7 - // too. The outer parameter is a boolean to help us do a bit tighter 69.8 - // consistency checking in the method. If outer is false, the caller 69.9 - // is the inner caller in the nesting (i.e., the Full GC). If outer 69.10 - // is true, the caller is the outer caller in this nesting (i.e., 69.11 - // the concurrent cycle). Further nesting is not currently 69.12 - // supported. The end of the this call also notifies the 69.13 - // FullGCCount_lock in case a Java thread is waiting for a full GC 69.14 - // to happen (e.g., it called System.gc() with 69.15 + // too. The concurrent parameter is a boolean to help us do a bit 69.16 + // tighter consistency checking in the method. If concurrent is 69.17 + // false, the caller is the inner caller in the nesting (i.e., the 69.18 + // Full GC). If concurrent is true, the caller is the outer caller 69.19 + // in this nesting (i.e., the concurrent cycle). Further nesting is 69.20 + // not currently supported. The end of the this call also notifies 69.21 + // the FullGCCount_lock in case a Java thread is waiting for a full 69.22 + // GC to happen (e.g., it called System.gc() with 69.23 // +ExplicitGCInvokesConcurrent). 69.24 - void increment_full_collections_completed(bool outer); 69.25 + void increment_full_collections_completed(bool concurrent); 69.26 69.27 unsigned int full_collections_completed() { 69.28 return _full_collections_completed;
70.1 --- a/src/share/vm/interpreter/bytecodeTracer.cpp Tue Dec 21 23:39:42 2010 -0500 70.2 +++ b/src/share/vm/interpreter/bytecodeTracer.cpp Wed Dec 22 12:24:40 2010 -0500 70.3 @@ -346,6 +346,7 @@ 70.4 break; 70.5 case JVM_CONSTANT_NameAndType: 70.6 case JVM_CONSTANT_InvokeDynamic: 70.7 + case JVM_CONSTANT_InvokeDynamicTrans: 70.8 has_klass = false; 70.9 break; 70.10 default:
71.1 --- a/src/share/vm/interpreter/rewriter.cpp Tue Dec 21 23:39:42 2010 -0500 71.2 +++ b/src/share/vm/interpreter/rewriter.cpp Wed Dec 22 12:24:40 2010 -0500 71.3 @@ -52,6 +52,7 @@ 71.4 case JVM_CONSTANT_MethodHandle : // fall through 71.5 case JVM_CONSTANT_MethodType : // fall through 71.6 case JVM_CONSTANT_InvokeDynamic : // fall through 71.7 + case JVM_CONSTANT_InvokeDynamicTrans: // fall through 71.8 add_cp_cache_entry(i); 71.9 break; 71.10 } 71.11 @@ -61,6 +62,7 @@ 71.12 "all cp cache indexes fit in a u2"); 71.13 71.14 _have_invoke_dynamic = ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamic)) != 0); 71.15 + _have_invoke_dynamic |= ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamicTrans)) != 0); 71.16 } 71.17 71.18 71.19 @@ -74,7 +76,7 @@ 71.20 oopFactory::new_constantPoolCache(length, methodOopDesc::IsUnsafeConc, CHECK); 71.21 cache->initialize(_cp_cache_map); 71.22 71.23 - // Don't bother to the next pass if there is no JVM_CONSTANT_InvokeDynamic. 71.24 + // Don't bother with the next pass if there is no JVM_CONSTANT_InvokeDynamic. 71.25 if (_have_invoke_dynamic) { 71.26 for (int i = 0; i < length; i++) { 71.27 int pool_index = cp_cache_entry_pool_index(i);
72.1 --- a/src/share/vm/memory/allocation.cpp Tue Dec 21 23:39:42 2010 -0500 72.2 +++ b/src/share/vm/memory/allocation.cpp Wed Dec 22 12:24:40 2010 -0500 72.3 @@ -73,7 +73,7 @@ 72.4 void ResourceObj::operator delete(void* p) { 72.5 assert(((ResourceObj *)p)->allocated_on_C_heap(), 72.6 "delete only allowed for C_HEAP objects"); 72.7 - DEBUG_ONLY(((ResourceObj *)p)->_allocation = (uintptr_t)badHeapOopVal;) 72.8 + DEBUG_ONLY(((ResourceObj *)p)->_allocation_t[0] = (uintptr_t)badHeapOopVal;) 72.9 FreeHeap(p); 72.10 } 72.11 72.12 @@ -83,43 +83,73 @@ 72.13 uintptr_t allocation = (uintptr_t)res; 72.14 assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least"); 72.15 assert(type <= allocation_mask, "incorrect allocation type"); 72.16 - ((ResourceObj *)res)->_allocation = ~(allocation + type); 72.17 + ResourceObj* resobj = (ResourceObj *)res; 72.18 + resobj->_allocation_t[0] = ~(allocation + type); 72.19 + if (type != STACK_OR_EMBEDDED) { 72.20 + // Called from operator new() and CollectionSetChooser(), 72.21 + // set verification value. 72.22 + resobj->_allocation_t[1] = (uintptr_t)&(resobj->_allocation_t[1]) + type; 72.23 + } 72.24 } 72.25 72.26 ResourceObj::allocation_type ResourceObj::get_allocation_type() const { 72.27 - assert(~(_allocation | allocation_mask) == (uintptr_t)this, "lost resource object"); 72.28 - return (allocation_type)((~_allocation) & allocation_mask); 72.29 + assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this, "lost resource object"); 72.30 + return (allocation_type)((~_allocation_t[0]) & allocation_mask); 72.31 +} 72.32 + 72.33 +bool ResourceObj::is_type_set() const { 72.34 + allocation_type type = (allocation_type)(_allocation_t[1] & allocation_mask); 72.35 + return get_allocation_type() == type && 72.36 + (_allocation_t[1] - type) == (uintptr_t)(&_allocation_t[1]); 72.37 } 72.38 72.39 ResourceObj::ResourceObj() { // default constructor 72.40 - if (~(_allocation | allocation_mask) != (uintptr_t)this) { 72.41 + if (~(_allocation_t[0] | allocation_mask) != (uintptr_t)this) { 72.42 + // Operator new() is not called for allocations 72.43 + // on stack and for embedded objects. 72.44 set_allocation_type((address)this, STACK_OR_EMBEDDED); 72.45 - } else if (allocated_on_stack()) { 72.46 - // For some reason we got a value which looks like an allocation on stack. 72.47 - // Pass if it is really allocated on stack. 72.48 - assert(Thread::current()->on_local_stack((address)this),"should be on stack"); 72.49 + } else if (allocated_on_stack()) { // STACK_OR_EMBEDDED 72.50 + // For some reason we got a value which resembles 72.51 + // an embedded or stack object (operator new() does not 72.52 + // set such type). Keep it since it is valid value 72.53 + // (even if it was garbage). 72.54 + // Ignore garbage in other fields. 72.55 + } else if (is_type_set()) { 72.56 + // Operator new() was called and type was set. 72.57 + assert(!allocated_on_stack(), 72.58 + err_msg("not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", 72.59 + this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); 72.60 } else { 72.61 - assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena(), 72.62 - "allocation_type should be set by operator new()"); 72.63 + // Operator new() was not called. 72.64 + // Assume that it is embedded or stack object. 72.65 + set_allocation_type((address)this, STACK_OR_EMBEDDED); 72.66 } 72.67 + _allocation_t[1] = 0; // Zap verification value 72.68 } 72.69 72.70 ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor 72.71 // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream. 72.72 + // Note: garbage may resembles valid value. 72.73 + assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(), 72.74 + err_msg("embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", 72.75 + this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); 72.76 set_allocation_type((address)this, STACK_OR_EMBEDDED); 72.77 + _allocation_t[1] = 0; // Zap verification value 72.78 } 72.79 72.80 ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment 72.81 // Used in InlineTree::ok_to_inline() for WarmCallInfo. 72.82 - assert(allocated_on_stack(), "copy only into local"); 72.83 - // Keep current _allocation value; 72.84 + assert(allocated_on_stack(), 72.85 + err_msg("copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", 72.86 + this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); 72.87 + // Keep current _allocation_t value; 72.88 return *this; 72.89 } 72.90 72.91 ResourceObj::~ResourceObj() { 72.92 // allocated_on_C_heap() also checks that encoded (in _allocation) address == this. 72.93 - if (!allocated_on_C_heap()) { // ResourceObj::delete() zaps _allocation for C_heap. 72.94 - _allocation = (uintptr_t)badHeapOopVal; // zap type 72.95 + if (!allocated_on_C_heap()) { // ResourceObj::delete() will zap _allocation for C_heap. 72.96 + _allocation_t[0] = (uintptr_t)badHeapOopVal; // zap type 72.97 } 72.98 } 72.99 #endif // ASSERT
73.1 --- a/src/share/vm/memory/allocation.hpp Tue Dec 21 23:39:42 2010 -0500 73.2 +++ b/src/share/vm/memory/allocation.hpp Wed Dec 22 12:24:40 2010 -0500 73.3 @@ -337,7 +337,9 @@ 73.4 // When this object is allocated on stack the new() operator is not 73.5 // called but garbage on stack may look like a valid allocation_type. 73.6 // Store negated 'this' pointer when new() is called to distinguish cases. 73.7 - uintptr_t _allocation; 73.8 + // Use second array's element for verification value to distinguish garbage. 73.9 + uintptr_t _allocation_t[2]; 73.10 + bool is_type_set() const; 73.11 public: 73.12 allocation_type get_allocation_type() const; 73.13 bool allocated_on_stack() const { return get_allocation_type() == STACK_OR_EMBEDDED; }
74.1 --- a/src/share/vm/oops/constantPoolKlass.cpp Tue Dec 21 23:39:42 2010 -0500 74.2 +++ b/src/share/vm/oops/constantPoolKlass.cpp Wed Dec 22 12:24:40 2010 -0500 74.3 @@ -399,6 +399,7 @@ 74.4 case JVM_CONSTANT_MethodType : 74.5 st->print("signature_index=%d", cp->method_type_index_at(index)); 74.6 break; 74.7 + case JVM_CONSTANT_InvokeDynamicTrans : 74.8 case JVM_CONSTANT_InvokeDynamic : 74.9 { 74.10 st->print("bootstrap_method_index=%d", cp->invoke_dynamic_bootstrap_method_ref_index_at(index));
75.1 --- a/src/share/vm/oops/constantPoolOop.cpp Tue Dec 21 23:39:42 2010 -0500 75.2 +++ b/src/share/vm/oops/constantPoolOop.cpp Wed Dec 22 12:24:40 2010 -0500 75.3 @@ -915,7 +915,8 @@ 75.4 { 75.5 int k1 = method_type_index_at(index1); 75.6 int k2 = cp2->method_type_index_at(index2); 75.7 - if (k1 == k2) { 75.8 + bool match = compare_entry_to(k1, cp2, k2, CHECK_false); 75.9 + if (match) { 75.10 return true; 75.11 } 75.12 } break; 75.13 @@ -927,28 +928,33 @@ 75.14 if (k1 == k2) { 75.15 int i1 = method_handle_index_at(index1); 75.16 int i2 = cp2->method_handle_index_at(index2); 75.17 - if (i1 == i2) { 75.18 + bool match = compare_entry_to(i1, cp2, i2, CHECK_false); 75.19 + if (match) { 75.20 return true; 75.21 } 75.22 } 75.23 } break; 75.24 75.25 case JVM_CONSTANT_InvokeDynamic: 75.26 + case JVM_CONSTANT_InvokeDynamicTrans: 75.27 { 75.28 - int op_count = multi_operand_count_at(index1); 75.29 - if (op_count == cp2->multi_operand_count_at(index2)) { 75.30 - bool all_equal = true; 75.31 - for (int op_i = 0; op_i < op_count; op_i++) { 75.32 - int k1 = multi_operand_ref_at(index1, op_i); 75.33 - int k2 = cp2->multi_operand_ref_at(index2, op_i); 75.34 - if (k1 != k2) { 75.35 - all_equal = false; 75.36 - break; 75.37 - } 75.38 + int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1); 75.39 + int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2); 75.40 + bool match = compare_entry_to(k1, cp2, k2, CHECK_false); 75.41 + if (!match) return false; 75.42 + k1 = invoke_dynamic_name_and_type_ref_index_at(index1); 75.43 + k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); 75.44 + match = compare_entry_to(k1, cp2, k2, CHECK_false); 75.45 + if (!match) return false; 75.46 + int argc = invoke_dynamic_argument_count_at(index1); 75.47 + if (argc == cp2->invoke_dynamic_argument_count_at(index2)) { 75.48 + for (int j = 0; j < argc; j++) { 75.49 + k1 = invoke_dynamic_argument_index_at(index1, j); 75.50 + k2 = cp2->invoke_dynamic_argument_index_at(index2, j); 75.51 + match = compare_entry_to(k1, cp2, k2, CHECK_false); 75.52 + if (!match) return false; 75.53 } 75.54 - if (all_equal) { 75.55 - return true; // got through loop; all elements equal 75.56 - } 75.57 + return true; // got through loop; all elements equal 75.58 } 75.59 } break; 75.60 75.61 @@ -984,44 +990,18 @@ 75.62 } // end compare_entry_to() 75.63 75.64 75.65 -// Grow this->operands() to the indicated length, unless it is already at least that long. 75.66 -void constantPoolOopDesc::multi_operand_buffer_grow(int min_length, TRAPS) { 75.67 - int old_length = multi_operand_buffer_fill_pointer(); 75.68 - if (old_length >= min_length) return; 75.69 - int new_length = min_length; 75.70 - assert(new_length > _multi_operand_buffer_fill_pointer_offset, ""); 75.71 - typeArrayHandle new_operands = oopFactory::new_permanent_intArray(new_length, CHECK); 75.72 - if (operands() == NULL) { 75.73 - new_operands->int_at_put(_multi_operand_buffer_fill_pointer_offset, old_length); 75.74 - } else { 75.75 - // copy fill pointer and everything else 75.76 - for (int i = 0; i < old_length; i++) { 75.77 - new_operands->int_at_put(i, operands()->int_at(i)); 75.78 - } 75.79 - } 75.80 - set_operands(new_operands()); 75.81 -} 75.82 - 75.83 - 75.84 // Copy this constant pool's entries at start_i to end_i (inclusive) 75.85 // to the constant pool to_cp's entries starting at to_i. A total of 75.86 // (end_i - start_i) + 1 entries are copied. 75.87 -void constantPoolOopDesc::copy_cp_to(int start_i, int end_i, 75.88 +void constantPoolOopDesc::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, 75.89 constantPoolHandle to_cp, int to_i, TRAPS) { 75.90 75.91 int dest_i = to_i; // leave original alone for debug purposes 75.92 75.93 - if (operands() != NULL) { 75.94 - // pre-grow the target CP's operand buffer 75.95 - int nops = this->multi_operand_buffer_fill_pointer(); 75.96 - nops += to_cp->multi_operand_buffer_fill_pointer(); 75.97 - to_cp->multi_operand_buffer_grow(nops, CHECK); 75.98 - } 75.99 + for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) { 75.100 + copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK); 75.101 75.102 - for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) { 75.103 - copy_entry_to(src_i, to_cp, dest_i, CHECK); 75.104 - 75.105 - switch (tag_at(src_i).value()) { 75.106 + switch (from_cp->tag_at(src_i).value()) { 75.107 case JVM_CONSTANT_Double: 75.108 case JVM_CONSTANT_Long: 75.109 // double and long take two constant pool entries 75.110 @@ -1036,30 +1016,81 @@ 75.111 break; 75.112 } 75.113 } 75.114 + 75.115 + int from_oplen = operand_array_length(from_cp->operands()); 75.116 + int old_oplen = operand_array_length(to_cp->operands()); 75.117 + if (from_oplen != 0) { 75.118 + // append my operands to the target's operands array 75.119 + if (old_oplen == 0) { 75.120 + to_cp->set_operands(from_cp->operands()); // reuse; do not merge 75.121 + } else { 75.122 + int old_len = to_cp->operands()->length(); 75.123 + int from_len = from_cp->operands()->length(); 75.124 + int old_off = old_oplen * sizeof(u2); 75.125 + int from_off = from_oplen * sizeof(u2); 75.126 + typeArrayHandle new_operands = oopFactory::new_permanent_shortArray(old_len + from_len, CHECK); 75.127 + int fillp = 0, len = 0; 75.128 + // first part of dest 75.129 + Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(0), 75.130 + new_operands->short_at_addr(fillp), 75.131 + (len = old_off) * sizeof(u2)); 75.132 + fillp += len; 75.133 + // first part of src 75.134 + Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(0), 75.135 + new_operands->short_at_addr(fillp), 75.136 + (len = from_off) * sizeof(u2)); 75.137 + fillp += len; 75.138 + // second part of dest 75.139 + Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(old_off), 75.140 + new_operands->short_at_addr(fillp), 75.141 + (len = old_len - old_off) * sizeof(u2)); 75.142 + fillp += len; 75.143 + // second part of src 75.144 + Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(from_off), 75.145 + new_operands->short_at_addr(fillp), 75.146 + (len = from_len - from_off) * sizeof(u2)); 75.147 + fillp += len; 75.148 + assert(fillp == new_operands->length(), ""); 75.149 + 75.150 + // Adjust indexes in the first part of the copied operands array. 75.151 + for (int j = 0; j < from_oplen; j++) { 75.152 + int offset = operand_offset_at(new_operands(), old_oplen + j); 75.153 + assert(offset == operand_offset_at(from_cp->operands(), j), "correct copy"); 75.154 + offset += old_len; // every new tuple is preceded by old_len extra u2's 75.155 + operand_offset_at_put(new_operands(), old_oplen + j, offset); 75.156 + } 75.157 + 75.158 + // replace target operands array with combined array 75.159 + to_cp->set_operands(new_operands()); 75.160 + } 75.161 + } 75.162 + 75.163 } // end copy_cp_to() 75.164 75.165 75.166 // Copy this constant pool's entry at from_i to the constant pool 75.167 // to_cp's entry at to_i. 75.168 -void constantPoolOopDesc::copy_entry_to(int from_i, constantPoolHandle to_cp, 75.169 - int to_i, TRAPS) { 75.170 +void constantPoolOopDesc::copy_entry_to(constantPoolHandle from_cp, int from_i, 75.171 + constantPoolHandle to_cp, int to_i, 75.172 + TRAPS) { 75.173 75.174 - switch (tag_at(from_i).value()) { 75.175 + int tag = from_cp->tag_at(from_i).value(); 75.176 + switch (tag) { 75.177 case JVM_CONSTANT_Class: 75.178 { 75.179 - klassOop k = klass_at(from_i, CHECK); 75.180 + klassOop k = from_cp->klass_at(from_i, CHECK); 75.181 to_cp->klass_at_put(to_i, k); 75.182 } break; 75.183 75.184 case JVM_CONSTANT_ClassIndex: 75.185 { 75.186 - jint ki = klass_index_at(from_i); 75.187 + jint ki = from_cp->klass_index_at(from_i); 75.188 to_cp->klass_index_at_put(to_i, ki); 75.189 } break; 75.190 75.191 case JVM_CONSTANT_Double: 75.192 { 75.193 - jdouble d = double_at(from_i); 75.194 + jdouble d = from_cp->double_at(from_i); 75.195 to_cp->double_at_put(to_i, d); 75.196 // double takes two constant pool entries so init second entry's tag 75.197 to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid); 75.198 @@ -1067,33 +1098,33 @@ 75.199 75.200 case JVM_CONSTANT_Fieldref: 75.201 { 75.202 - int class_index = uncached_klass_ref_index_at(from_i); 75.203 - int name_and_type_index = uncached_name_and_type_ref_index_at(from_i); 75.204 + int class_index = from_cp->uncached_klass_ref_index_at(from_i); 75.205 + int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i); 75.206 to_cp->field_at_put(to_i, class_index, name_and_type_index); 75.207 } break; 75.208 75.209 case JVM_CONSTANT_Float: 75.210 { 75.211 - jfloat f = float_at(from_i); 75.212 + jfloat f = from_cp->float_at(from_i); 75.213 to_cp->float_at_put(to_i, f); 75.214 } break; 75.215 75.216 case JVM_CONSTANT_Integer: 75.217 { 75.218 - jint i = int_at(from_i); 75.219 + jint i = from_cp->int_at(from_i); 75.220 to_cp->int_at_put(to_i, i); 75.221 } break; 75.222 75.223 case JVM_CONSTANT_InterfaceMethodref: 75.224 { 75.225 - int class_index = uncached_klass_ref_index_at(from_i); 75.226 - int name_and_type_index = uncached_name_and_type_ref_index_at(from_i); 75.227 + int class_index = from_cp->uncached_klass_ref_index_at(from_i); 75.228 + int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i); 75.229 to_cp->interface_method_at_put(to_i, class_index, name_and_type_index); 75.230 } break; 75.231 75.232 case JVM_CONSTANT_Long: 75.233 { 75.234 - jlong l = long_at(from_i); 75.235 + jlong l = from_cp->long_at(from_i); 75.236 to_cp->long_at_put(to_i, l); 75.237 // long takes two constant pool entries so init second entry's tag 75.238 to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid); 75.239 @@ -1101,39 +1132,39 @@ 75.240 75.241 case JVM_CONSTANT_Methodref: 75.242 { 75.243 - int class_index = uncached_klass_ref_index_at(from_i); 75.244 - int name_and_type_index = uncached_name_and_type_ref_index_at(from_i); 75.245 + int class_index = from_cp->uncached_klass_ref_index_at(from_i); 75.246 + int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i); 75.247 to_cp->method_at_put(to_i, class_index, name_and_type_index); 75.248 } break; 75.249 75.250 case JVM_CONSTANT_NameAndType: 75.251 { 75.252 - int name_ref_index = name_ref_index_at(from_i); 75.253 - int signature_ref_index = signature_ref_index_at(from_i); 75.254 + int name_ref_index = from_cp->name_ref_index_at(from_i); 75.255 + int signature_ref_index = from_cp->signature_ref_index_at(from_i); 75.256 to_cp->name_and_type_at_put(to_i, name_ref_index, signature_ref_index); 75.257 } break; 75.258 75.259 case JVM_CONSTANT_String: 75.260 { 75.261 - oop s = string_at(from_i, CHECK); 75.262 + oop s = from_cp->string_at(from_i, CHECK); 75.263 to_cp->string_at_put(to_i, s); 75.264 } break; 75.265 75.266 case JVM_CONSTANT_StringIndex: 75.267 { 75.268 - jint si = string_index_at(from_i); 75.269 + jint si = from_cp->string_index_at(from_i); 75.270 to_cp->string_index_at_put(to_i, si); 75.271 } break; 75.272 75.273 case JVM_CONSTANT_UnresolvedClass: 75.274 { 75.275 - symbolOop k = unresolved_klass_at(from_i); 75.276 + symbolOop k = from_cp->unresolved_klass_at(from_i); 75.277 to_cp->unresolved_klass_at_put(to_i, k); 75.278 } break; 75.279 75.280 case JVM_CONSTANT_UnresolvedClassInError: 75.281 { 75.282 - symbolOop k = unresolved_klass_at(from_i); 75.283 + symbolOop k = from_cp->unresolved_klass_at(from_i); 75.284 to_cp->unresolved_klass_at_put(to_i, k); 75.285 to_cp->tag_at_put(to_i, JVM_CONSTANT_UnresolvedClassInError); 75.286 } break; 75.287 @@ -1141,51 +1172,42 @@ 75.288 75.289 case JVM_CONSTANT_UnresolvedString: 75.290 { 75.291 - symbolOop s = unresolved_string_at(from_i); 75.292 + symbolOop s = from_cp->unresolved_string_at(from_i); 75.293 to_cp->unresolved_string_at_put(to_i, s); 75.294 } break; 75.295 75.296 case JVM_CONSTANT_Utf8: 75.297 { 75.298 - symbolOop s = symbol_at(from_i); 75.299 + symbolOop s = from_cp->symbol_at(from_i); 75.300 to_cp->symbol_at_put(to_i, s); 75.301 } break; 75.302 75.303 case JVM_CONSTANT_MethodType: 75.304 { 75.305 - jint k = method_type_index_at(from_i); 75.306 + jint k = from_cp->method_type_index_at(from_i); 75.307 to_cp->method_type_index_at_put(to_i, k); 75.308 } break; 75.309 75.310 case JVM_CONSTANT_MethodHandle: 75.311 { 75.312 - int k1 = method_handle_ref_kind_at(from_i); 75.313 - int k2 = method_handle_index_at(from_i); 75.314 + int k1 = from_cp->method_handle_ref_kind_at(from_i); 75.315 + int k2 = from_cp->method_handle_index_at(from_i); 75.316 to_cp->method_handle_index_at_put(to_i, k1, k2); 75.317 } break; 75.318 75.319 + case JVM_CONSTANT_InvokeDynamicTrans: 75.320 + { 75.321 + int k1 = from_cp->invoke_dynamic_bootstrap_method_ref_index_at(from_i); 75.322 + int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i); 75.323 + to_cp->invoke_dynamic_trans_at_put(to_i, k1, k2); 75.324 + } break; 75.325 + 75.326 case JVM_CONSTANT_InvokeDynamic: 75.327 { 75.328 - int op_count = multi_operand_count_at(from_i); 75.329 - int fillp = to_cp->multi_operand_buffer_fill_pointer(); 75.330 - int to_op_base = fillp - _multi_operand_count_offset; // fillp is count offset; get to base 75.331 - to_cp->multi_operand_buffer_grow(to_op_base + op_count, CHECK); 75.332 - to_cp->operands()->int_at_put(fillp++, op_count); 75.333 - assert(fillp == to_op_base + _multi_operand_base_offset, "just wrote count, will now write args"); 75.334 - for (int op_i = 0; op_i < op_count; op_i++) { 75.335 - int op = multi_operand_ref_at(from_i, op_i); 75.336 - to_cp->operands()->int_at_put(fillp++, op); 75.337 - } 75.338 - assert(fillp <= to_cp->operands()->length(), "oob"); 75.339 - to_cp->set_multi_operand_buffer_fill_pointer(fillp); 75.340 - to_cp->invoke_dynamic_at_put(to_i, to_op_base, op_count); 75.341 -#ifdef ASSERT 75.342 - int k1 = invoke_dynamic_bootstrap_method_ref_index_at(from_i); 75.343 - int k2 = invoke_dynamic_name_and_type_ref_index_at(from_i); 75.344 - int k3 = invoke_dynamic_argument_count_at(from_i); 75.345 - assert(to_cp->check_invoke_dynamic_at(to_i, k1, k2, k3), 75.346 - "indy structure is OK"); 75.347 -#endif //ASSERT 75.348 + int k1 = from_cp->invoke_dynamic_bootstrap_specifier_index(from_i); 75.349 + int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i); 75.350 + k1 += operand_array_length(to_cp->operands()); // to_cp might already have operands 75.351 + to_cp->invoke_dynamic_at_put(to_i, k1, k2); 75.352 } break; 75.353 75.354 // Invalid is used as the tag for the second constant pool entry 75.355 @@ -1195,7 +1217,6 @@ 75.356 75.357 default: 75.358 { 75.359 - jbyte bad_value = tag_at(from_i).value(); // leave a breadcrumb 75.360 ShouldNotReachHere(); 75.361 } break; 75.362 } 75.363 @@ -1406,8 +1427,9 @@ 75.364 return 5; 75.365 75.366 case JVM_CONSTANT_InvokeDynamic: 75.367 - // u1 tag, u2 bsm, u2 nt, u2 argc, u2 argv[argc] 75.368 - return 7 + 2 * invoke_dynamic_argument_count_at(idx); 75.369 + case JVM_CONSTANT_InvokeDynamicTrans: 75.370 + // u1 tag, u2 bsm, u2 nt 75.371 + return 5; 75.372 75.373 case JVM_CONSTANT_Long: 75.374 case JVM_CONSTANT_Double: 75.375 @@ -1620,19 +1642,15 @@ 75.376 DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); 75.377 break; 75.378 } 75.379 + case JVM_CONSTANT_InvokeDynamicTrans: 75.380 case JVM_CONSTANT_InvokeDynamic: { 75.381 - *bytes = JVM_CONSTANT_InvokeDynamic; 75.382 - idx1 = invoke_dynamic_bootstrap_method_ref_index_at(idx); 75.383 - idx2 = invoke_dynamic_name_and_type_ref_index_at(idx); 75.384 - int argc = invoke_dynamic_argument_count_at(idx); 75.385 + *bytes = tag; 75.386 + idx1 = extract_low_short_from_int(*int_at_addr(idx)); 75.387 + idx2 = extract_high_short_from_int(*int_at_addr(idx)); 75.388 + assert(idx2 == invoke_dynamic_name_and_type_ref_index_at(idx), "correct half of u4"); 75.389 Bytes::put_Java_u2((address) (bytes+1), idx1); 75.390 Bytes::put_Java_u2((address) (bytes+3), idx2); 75.391 - Bytes::put_Java_u2((address) (bytes+5), argc); 75.392 - for (int arg_i = 0; arg_i < argc; arg_i++) { 75.393 - int arg = invoke_dynamic_argument_index_at(idx, arg_i); 75.394 - Bytes::put_Java_u2((address) (bytes+7+2*arg_i), arg); 75.395 - } 75.396 - DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd [%d]", idx1, idx2, argc)); 75.397 + DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2)); 75.398 break; 75.399 } 75.400 }
76.1 --- a/src/share/vm/oops/constantPoolOop.hpp Tue Dec 21 23:39:42 2010 -0500 76.2 +++ b/src/share/vm/oops/constantPoolOop.hpp Wed Dec 22 12:24:40 2010 -0500 76.3 @@ -179,28 +179,16 @@ 76.4 *int_at_addr(which) = ref_index; 76.5 } 76.6 76.7 - void invoke_dynamic_at_put(int which, int operand_base, int operand_count) { 76.8 + void invoke_dynamic_at_put(int which, int bootstrap_specifier_index, int name_and_type_index) { 76.9 tag_at_put(which, JVM_CONSTANT_InvokeDynamic); 76.10 - *int_at_addr(which) = operand_base; // this is the real information 76.11 + *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index; 76.12 } 76.13 -#ifdef ASSERT 76.14 - bool check_invoke_dynamic_at(int which, 76.15 - int bootstrap_method_index, 76.16 - int name_and_type_index, 76.17 - int argument_count) { 76.18 - assert(invoke_dynamic_bootstrap_method_ref_index_at(which) == bootstrap_method_index, 76.19 - "already stored by caller"); 76.20 - assert(invoke_dynamic_name_and_type_ref_index_at(which) == name_and_type_index, 76.21 - "already stored by caller"); 76.22 - assert(invoke_dynamic_argument_count_at(which) == argument_count, 76.23 - "consistent argument count"); 76.24 - if (argument_count != 0) { 76.25 - invoke_dynamic_argument_index_at(which, 0); 76.26 - invoke_dynamic_argument_index_at(which, argument_count - 1); 76.27 - } 76.28 - return true; 76.29 + 76.30 + void invoke_dynamic_trans_at_put(int which, int bootstrap_method_index, int name_and_type_index) { 76.31 + tag_at_put(which, JVM_CONSTANT_InvokeDynamicTrans); 76.32 + *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_method_index; 76.33 + assert(AllowTransitionalJSR292, ""); 76.34 } 76.35 -#endif //ASSERT 76.36 76.37 // Temporary until actual use 76.38 void unresolved_string_at_put(int which, symbolOop s) { 76.39 @@ -443,75 +431,90 @@ 76.40 return symbol_at(sym); 76.41 } 76.42 76.43 - private: 76.44 - // some nodes (InvokeDynamic) have a variable number of operands, each a u2 value 76.45 - enum { _multi_operand_count_offset = -1, 76.46 - _multi_operand_base_offset = 0, 76.47 - _multi_operand_buffer_fill_pointer_offset = 0 // shared at front of operands array 76.48 - }; 76.49 - int multi_operand_buffer_length() { 76.50 - return operands() == NULL ? 0 : operands()->length(); 76.51 + int invoke_dynamic_name_and_type_ref_index_at(int which) { 76.52 + assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); 76.53 + return extract_high_short_from_int(*int_at_addr(which)); 76.54 } 76.55 - int multi_operand_buffer_fill_pointer() { 76.56 - return operands() == NULL 76.57 - ? _multi_operand_buffer_fill_pointer_offset + 1 76.58 - : operands()->int_at(_multi_operand_buffer_fill_pointer_offset); 76.59 + int invoke_dynamic_bootstrap_specifier_index(int which) { 76.60 + assert(tag_at(which).value() == JVM_CONSTANT_InvokeDynamic, "Corrupted constant pool"); 76.61 + return extract_low_short_from_int(*int_at_addr(which)); 76.62 } 76.63 - void multi_operand_buffer_grow(int min_length, TRAPS); 76.64 - void set_multi_operand_buffer_fill_pointer(int fillp) { 76.65 - assert(operands() != NULL, ""); 76.66 - operands()->int_at_put(_multi_operand_buffer_fill_pointer_offset, fillp); 76.67 + int invoke_dynamic_operand_base(int which) { 76.68 + int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which); 76.69 + return operand_offset_at(operands(), bootstrap_specifier_index); 76.70 } 76.71 - int multi_operand_base_at(int which) { 76.72 - assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); 76.73 - int op_base = *int_at_addr(which); 76.74 - assert(op_base > _multi_operand_buffer_fill_pointer_offset, "Corrupted operand base"); 76.75 - return op_base; 76.76 + // The first part of the operands array consists of an index into the second part. 76.77 + // Extract a 32-bit index value from the first part. 76.78 + static int operand_offset_at(typeArrayOop operands, int bootstrap_specifier_index) { 76.79 + int n = (bootstrap_specifier_index * 2); 76.80 + assert(n >= 0 && n+2 <= operands->length(), "oob"); 76.81 + // The first 32-bit index points to the beginning of the second part 76.82 + // of the operands array. Make sure this index is in the first part. 76.83 + DEBUG_ONLY(int second_part = build_int_from_shorts(operands->short_at(0), 76.84 + operands->short_at(1))); 76.85 + assert(second_part == 0 || n+2 <= second_part, "oob (2)"); 76.86 + int offset = build_int_from_shorts(operands->short_at(n+0), 76.87 + operands->short_at(n+1)); 76.88 + // The offset itself must point into the second part of the array. 76.89 + assert(offset == 0 || offset >= second_part && offset <= operands->length(), "oob (3)"); 76.90 + return offset; 76.91 } 76.92 - int multi_operand_count_at(int which) { 76.93 - int op_base = multi_operand_base_at(which); 76.94 - assert((uint)(op_base + _multi_operand_count_offset) < (uint)operands()->length(), "oob"); 76.95 - int count = operands()->int_at(op_base + _multi_operand_count_offset); 76.96 - return count; 76.97 + static void operand_offset_at_put(typeArrayOop operands, int bootstrap_specifier_index, int offset) { 76.98 + int n = bootstrap_specifier_index * 2; 76.99 + assert(n >= 0 && n+2 <= operands->length(), "oob"); 76.100 + operands->short_at_put(n+0, extract_low_short_from_int(offset)); 76.101 + operands->short_at_put(n+1, extract_high_short_from_int(offset)); 76.102 } 76.103 - int multi_operand_ref_at(int which, int i) { 76.104 - int op_base = multi_operand_base_at(which); 76.105 - assert((uint)i < (uint)multi_operand_count_at(which), "oob"); 76.106 - assert((uint)(op_base + _multi_operand_base_offset + i) < (uint)operands()->length(), "oob"); 76.107 - return operands()->int_at(op_base + _multi_operand_base_offset + i); 76.108 - } 76.109 - void set_multi_operand_ref_at(int which, int i, int ref) { 76.110 - DEBUG_ONLY(multi_operand_ref_at(which, i)); // trigger asserts 76.111 - int op_base = multi_operand_base_at(which); 76.112 - operands()->int_at_put(op_base + _multi_operand_base_offset + i, ref); 76.113 + static int operand_array_length(typeArrayOop operands) { 76.114 + if (operands == NULL || operands->length() == 0) return 0; 76.115 + int second_part = operand_offset_at(operands, 0); 76.116 + return (second_part / 2); 76.117 } 76.118 76.119 - public: 76.120 - // layout of InvokeDynamic: 76.121 +#ifdef ASSERT 76.122 + // operand tuples fit together exactly, end to end 76.123 + static int operand_limit_at(typeArrayOop operands, int bootstrap_specifier_index) { 76.124 + int nextidx = bootstrap_specifier_index + 1; 76.125 + if (nextidx == operand_array_length(operands)) 76.126 + return operands->length(); 76.127 + else 76.128 + return operand_offset_at(operands, nextidx); 76.129 + } 76.130 + int invoke_dynamic_operand_limit(int which) { 76.131 + int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which); 76.132 + return operand_limit_at(operands(), bootstrap_specifier_index); 76.133 + } 76.134 +#endif //ASSERT 76.135 + 76.136 + // layout of InvokeDynamic bootstrap method specifier (in second part of operands array): 76.137 enum { 76.138 _indy_bsm_offset = 0, // CONSTANT_MethodHandle bsm 76.139 - _indy_nt_offset = 1, // CONSTANT_NameAndType descr 76.140 - _indy_argc_offset = 2, // u2 argc 76.141 - _indy_argv_offset = 3 // u2 argv[argc] 76.142 + _indy_argc_offset = 1, // u2 argc 76.143 + _indy_argv_offset = 2 // u2 argv[argc] 76.144 }; 76.145 int invoke_dynamic_bootstrap_method_ref_index_at(int which) { 76.146 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); 76.147 - return multi_operand_ref_at(which, _indy_bsm_offset); 76.148 - } 76.149 - int invoke_dynamic_name_and_type_ref_index_at(int which) { 76.150 - assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); 76.151 - return multi_operand_ref_at(which, _indy_nt_offset); 76.152 + if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans) 76.153 + return extract_low_short_from_int(*int_at_addr(which)); 76.154 + int op_base = invoke_dynamic_operand_base(which); 76.155 + return operands()->short_at(op_base + _indy_bsm_offset); 76.156 } 76.157 int invoke_dynamic_argument_count_at(int which) { 76.158 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); 76.159 - int argc = multi_operand_ref_at(which, _indy_argc_offset); 76.160 - DEBUG_ONLY(int op_count = multi_operand_count_at(which)); 76.161 - assert(_indy_argv_offset + argc == op_count, "consistent inner and outer counts"); 76.162 + if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans) 76.163 + return 0; 76.164 + int op_base = invoke_dynamic_operand_base(which); 76.165 + int argc = operands()->short_at(op_base + _indy_argc_offset); 76.166 + DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc; 76.167 + int next_offset = invoke_dynamic_operand_limit(which)); 76.168 + assert(end_offset == next_offset, "matched ending"); 76.169 return argc; 76.170 } 76.171 int invoke_dynamic_argument_index_at(int which, int j) { 76.172 - assert((uint)j < (uint)invoke_dynamic_argument_count_at(which), "oob"); 76.173 - return multi_operand_ref_at(which, _indy_argv_offset + j); 76.174 + int op_base = invoke_dynamic_operand_base(which); 76.175 + DEBUG_ONLY(int argc = operands()->short_at(op_base + _indy_argc_offset)); 76.176 + assert((uint)j < (uint)argc, "oob"); 76.177 + return operands()->short_at(op_base + _indy_argv_offset + j); 76.178 } 76.179 76.180 // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve, 76.181 @@ -659,9 +662,12 @@ 76.182 public: 76.183 // Merging constantPoolOop support: 76.184 bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS); 76.185 - void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i, 76.186 - TRAPS); 76.187 - void copy_entry_to(int from_i, constantPoolHandle to_cp, int to_i, TRAPS); 76.188 + void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS) { 76.189 + constantPoolHandle h_this(THREAD, this); 76.190 + copy_cp_to_impl(h_this, start_i, end_i, to_cp, to_i, THREAD); 76.191 + } 76.192 + static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS); 76.193 + static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS); 76.194 int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS); 76.195 int orig_length() const { return _orig_length; } 76.196 void set_orig_length(int orig_length) { _orig_length = orig_length; }
77.1 --- a/src/share/vm/opto/c2_globals.hpp Tue Dec 21 23:39:42 2010 -0500 77.2 +++ b/src/share/vm/opto/c2_globals.hpp Wed Dec 22 12:24:40 2010 -0500 77.3 @@ -284,6 +284,9 @@ 77.4 develop(bool, SparcV9RegsHiBitsZero, true, \ 77.5 "Assume Sparc V9 I&L registers on V8+ systems are zero-extended") \ 77.6 \ 77.7 + product(bool, UseRDPCForConstantTableBase, false, \ 77.8 + "Use Sparc RDPC instruction for the constant table base.") \ 77.9 + \ 77.10 develop(intx, PrintIdealGraphLevel, 0, \ 77.11 "Print ideal graph to XML file / network interface. " \ 77.12 "By default attempts to connect to the visualizer on a socket.") \
78.1 --- a/src/share/vm/opto/chaitin.cpp Tue Dec 21 23:39:42 2010 -0500 78.2 +++ b/src/share/vm/opto/chaitin.cpp Wed Dec 22 12:24:40 2010 -0500 78.3 @@ -1782,7 +1782,7 @@ 78.4 for(uint i2 = 1; i2 < _maxlrg; i2++ ) { 78.5 tty->print("L%d: ",i2); 78.6 if( i2 < _ifg->_maxlrg ) lrgs(i2).dump( ); 78.7 - else tty->print("new LRG"); 78.8 + else tty->print_cr("new LRG"); 78.9 } 78.10 tty->print_cr(""); 78.11 78.12 @@ -1993,7 +1993,7 @@ 78.13 } 78.14 78.15 //------------------------------dump_lrg--------------------------------------- 78.16 -void PhaseChaitin::dump_lrg( uint lidx ) const { 78.17 +void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const { 78.18 tty->print_cr("---dump of L%d---",lidx); 78.19 78.20 if( _ifg ) { 78.21 @@ -2002,9 +2002,11 @@ 78.22 return; 78.23 } 78.24 tty->print("L%d: ",lidx); 78.25 - lrgs(lidx).dump( ); 78.26 + if( lidx < _ifg->_maxlrg ) lrgs(lidx).dump( ); 78.27 + else tty->print_cr("new LRG"); 78.28 } 78.29 - if( _ifg ) { tty->print("Neighbors: %d - ", _ifg->neighbor_cnt(lidx)); 78.30 + if( _ifg && lidx < _ifg->_maxlrg) { 78.31 + tty->print("Neighbors: %d - ", _ifg->neighbor_cnt(lidx)); 78.32 _ifg->neighbors(lidx)->dump(); 78.33 tty->cr(); 78.34 } 78.35 @@ -2024,16 +2026,18 @@ 78.36 dump(n); 78.37 continue; 78.38 } 78.39 - uint cnt = n->req(); 78.40 - for( uint k = 1; k < cnt; k++ ) { 78.41 - Node *m = n->in(k); 78.42 - if (!m) continue; // be robust in the dumper 78.43 - if( Find_const(m) == lidx ) { 78.44 - if( !dump_once++ ) { 78.45 - tty->cr(); 78.46 - b->dump_head( &_cfg._bbs ); 78.47 + if (!defs_only) { 78.48 + uint cnt = n->req(); 78.49 + for( uint k = 1; k < cnt; k++ ) { 78.50 + Node *m = n->in(k); 78.51 + if (!m) continue; // be robust in the dumper 78.52 + if( Find_const(m) == lidx ) { 78.53 + if( !dump_once++ ) { 78.54 + tty->cr(); 78.55 + b->dump_head( &_cfg._bbs ); 78.56 + } 78.57 + dump(n); 78.58 } 78.59 - dump(n); 78.60 } 78.61 } 78.62 }
79.1 --- a/src/share/vm/opto/chaitin.hpp Tue Dec 21 23:39:42 2010 -0500 79.2 +++ b/src/share/vm/opto/chaitin.hpp Wed Dec 22 12:24:40 2010 -0500 79.3 @@ -512,7 +512,11 @@ 79.4 void dump( const Block * b ) const; 79.5 void dump_degree_lists() const; 79.6 void dump_simplified() const; 79.7 - void dump_lrg( uint lidx ) const; 79.8 + void dump_lrg( uint lidx, bool defs_only) const; 79.9 + void dump_lrg( uint lidx) const { 79.10 + // dump defs and uses by default 79.11 + dump_lrg(lidx, false); 79.12 + } 79.13 void dump_bb( uint pre_order ) const; 79.14 79.15 // Verify that base pointers and derived pointers are still sane
80.1 --- a/src/share/vm/opto/compile.cpp Tue Dec 21 23:39:42 2010 -0500 80.2 +++ b/src/share/vm/opto/compile.cpp Wed Dec 22 12:24:40 2010 -0500 80.3 @@ -75,6 +75,18 @@ 80.4 # include "adfiles/ad_zero.hpp" 80.5 #endif 80.6 80.7 + 80.8 +// -------------------- Compile::mach_constant_base_node ----------------------- 80.9 +// Constant table base node singleton. 80.10 +MachConstantBaseNode* Compile::mach_constant_base_node() { 80.11 + if (_mach_constant_base_node == NULL) { 80.12 + _mach_constant_base_node = new (C) MachConstantBaseNode(); 80.13 + _mach_constant_base_node->add_req(C->root()); 80.14 + } 80.15 + return _mach_constant_base_node; 80.16 +} 80.17 + 80.18 + 80.19 /// Support for intrinsics. 80.20 80.21 // Return the index at which m must be inserted (or already exists). 80.22 @@ -432,13 +444,14 @@ 80.23 } 80.24 80.25 80.26 -void Compile::init_scratch_buffer_blob() { 80.27 - if( scratch_buffer_blob() != NULL ) return; 80.28 +void Compile::init_scratch_buffer_blob(int const_size) { 80.29 + if (scratch_buffer_blob() != NULL) return; 80.30 80.31 // Construct a temporary CodeBuffer to have it construct a BufferBlob 80.32 // Cache this BufferBlob for this compile. 80.33 ResourceMark rm; 80.34 - int size = (MAX_inst_size + MAX_stubs_size + MAX_const_size); 80.35 + _scratch_const_size = const_size; 80.36 + int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size); 80.37 BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size); 80.38 // Record the buffer blob for next time. 80.39 set_scratch_buffer_blob(blob); 80.40 @@ -455,9 +468,19 @@ 80.41 } 80.42 80.43 80.44 +void Compile::clear_scratch_buffer_blob() { 80.45 + assert(scratch_buffer_blob(), "no BufferBlob set"); 80.46 + set_scratch_buffer_blob(NULL); 80.47 + set_scratch_locs_memory(NULL); 80.48 +} 80.49 + 80.50 + 80.51 //-----------------------scratch_emit_size------------------------------------- 80.52 // Helper function that computes size by emitting code 80.53 uint Compile::scratch_emit_size(const Node* n) { 80.54 + // Start scratch_emit_size section. 80.55 + set_in_scratch_emit_size(true); 80.56 + 80.57 // Emit into a trash buffer and count bytes emitted. 80.58 // This is a pretty expensive way to compute a size, 80.59 // but it works well enough if seldom used. 80.60 @@ -476,13 +499,20 @@ 80.61 address blob_end = (address)locs_buf; 80.62 assert(blob->content_contains(blob_end), "sanity"); 80.63 CodeBuffer buf(blob_begin, blob_end - blob_begin); 80.64 - buf.initialize_consts_size(MAX_const_size); 80.65 + buf.initialize_consts_size(_scratch_const_size); 80.66 buf.initialize_stubs_size(MAX_stubs_size); 80.67 assert(locs_buf != NULL, "sanity"); 80.68 - int lsize = MAX_locs_size / 2; 80.69 - buf.insts()->initialize_shared_locs(&locs_buf[0], lsize); 80.70 - buf.stubs()->initialize_shared_locs(&locs_buf[lsize], lsize); 80.71 + int lsize = MAX_locs_size / 3; 80.72 + buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize); 80.73 + buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize); 80.74 + buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize); 80.75 + 80.76 + // Do the emission. 80.77 n->emit(buf, this->regalloc()); 80.78 + 80.79 + // End scratch_emit_size section. 80.80 + set_in_scratch_emit_size(false); 80.81 + 80.82 return buf.insts_size(); 80.83 } 80.84 80.85 @@ -516,10 +546,13 @@ 80.86 _orig_pc_slot(0), 80.87 _orig_pc_slot_offset_in_bytes(0), 80.88 _has_method_handle_invokes(false), 80.89 + _mach_constant_base_node(NULL), 80.90 _node_bundling_limit(0), 80.91 _node_bundling_base(NULL), 80.92 _java_calls(0), 80.93 _inner_loops(0), 80.94 + _scratch_const_size(-1), 80.95 + _in_scratch_emit_size(false), 80.96 #ifndef PRODUCT 80.97 _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")), 80.98 _printer(IdealGraphPrinter::printer()), 80.99 @@ -553,7 +586,7 @@ 80.100 if (ProfileTraps) { 80.101 // Make sure the method being compiled gets its own MDO, 80.102 // so we can at least track the decompile_count(). 80.103 - method()->build_method_data(); 80.104 + method()->ensure_method_data(); 80.105 } 80.106 80.107 Init(::AliasLevel); 80.108 @@ -783,6 +816,7 @@ 80.109 _failure_reason(NULL), 80.110 _code_buffer("Compile::Fill_buffer"), 80.111 _has_method_handle_invokes(false), 80.112 + _mach_constant_base_node(NULL), 80.113 _node_bundling_limit(0), 80.114 _node_bundling_base(NULL), 80.115 _java_calls(0), 80.116 @@ -2862,3 +2896,207 @@ 80.117 _log->done("phase nodes='%d'", C->unique()); 80.118 } 80.119 } 80.120 + 80.121 +//============================================================================= 80.122 +// Two Constant's are equal when the type and the value are equal. 80.123 +bool Compile::Constant::operator==(const Constant& other) { 80.124 + if (type() != other.type() ) return false; 80.125 + if (can_be_reused() != other.can_be_reused()) return false; 80.126 + // For floating point values we compare the bit pattern. 80.127 + switch (type()) { 80.128 + case T_FLOAT: return (_value.i == other._value.i); 80.129 + case T_LONG: 80.130 + case T_DOUBLE: return (_value.j == other._value.j); 80.131 + case T_OBJECT: 80.132 + case T_ADDRESS: return (_value.l == other._value.l); 80.133 + case T_VOID: return (_value.l == other._value.l); // jump-table entries 80.134 + default: ShouldNotReachHere(); 80.135 + } 80.136 + return false; 80.137 +} 80.138 + 80.139 +// Emit constants grouped in the following order: 80.140 +static BasicType type_order[] = { 80.141 + T_FLOAT, // 32-bit 80.142 + T_OBJECT, // 32 or 64-bit 80.143 + T_ADDRESS, // 32 or 64-bit 80.144 + T_DOUBLE, // 64-bit 80.145 + T_LONG, // 64-bit 80.146 + T_VOID, // 32 or 64-bit (jump-tables are at the end of the constant table for code emission reasons) 80.147 + T_ILLEGAL 80.148 +}; 80.149 + 80.150 +static int type_to_size_in_bytes(BasicType t) { 80.151 + switch (t) { 80.152 + case T_LONG: return sizeof(jlong ); 80.153 + case T_FLOAT: return sizeof(jfloat ); 80.154 + case T_DOUBLE: return sizeof(jdouble); 80.155 + // We use T_VOID as marker for jump-table entries (labels) which 80.156 + // need an interal word relocation. 80.157 + case T_VOID: 80.158 + case T_ADDRESS: 80.159 + case T_OBJECT: return sizeof(jobject); 80.160 + } 80.161 + 80.162 + ShouldNotReachHere(); 80.163 + return -1; 80.164 +} 80.165 + 80.166 +void Compile::ConstantTable::calculate_offsets_and_size() { 80.167 + int size = 0; 80.168 + for (int t = 0; type_order[t] != T_ILLEGAL; t++) { 80.169 + BasicType type = type_order[t]; 80.170 + 80.171 + for (int i = 0; i < _constants.length(); i++) { 80.172 + Constant con = _constants.at(i); 80.173 + if (con.type() != type) continue; // Skip other types. 80.174 + 80.175 + // Align size for type. 80.176 + int typesize = type_to_size_in_bytes(con.type()); 80.177 + size = align_size_up(size, typesize); 80.178 + 80.179 + // Set offset. 80.180 + con.set_offset(size); 80.181 + _constants.at_put(i, con); 80.182 + 80.183 + // Add type size. 80.184 + size = size + typesize; 80.185 + } 80.186 + } 80.187 + 80.188 + // Align size up to the next section start (which is insts; see 80.189 + // CodeBuffer::align_at_start). 80.190 + assert(_size == -1, "already set?"); 80.191 + _size = align_size_up(size, CodeEntryAlignment); 80.192 + 80.193 + if (Matcher::constant_table_absolute_addressing) { 80.194 + set_table_base_offset(0); // No table base offset required 80.195 + } else { 80.196 + if (UseRDPCForConstantTableBase) { 80.197 + // table base offset is set in MachConstantBaseNode::emit 80.198 + } else { 80.199 + // When RDPC is not used, the table base is set into the middle of 80.200 + // the constant table. 80.201 + int half_size = _size / 2; 80.202 + assert(half_size * 2 == _size, "sanity"); 80.203 + set_table_base_offset(-half_size); 80.204 + } 80.205 + } 80.206 +} 80.207 + 80.208 +void Compile::ConstantTable::emit(CodeBuffer& cb) { 80.209 + MacroAssembler _masm(&cb); 80.210 + for (int t = 0; type_order[t] != T_ILLEGAL; t++) { 80.211 + BasicType type = type_order[t]; 80.212 + 80.213 + for (int i = 0; i < _constants.length(); i++) { 80.214 + Constant con = _constants.at(i); 80.215 + if (con.type() != type) continue; // Skip other types. 80.216 + 80.217 + address constant_addr; 80.218 + switch (con.type()) { 80.219 + case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break; 80.220 + case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break; 80.221 + case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break; 80.222 + case T_OBJECT: { 80.223 + jobject obj = con.get_jobject(); 80.224 + int oop_index = _masm.oop_recorder()->find_index(obj); 80.225 + constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index)); 80.226 + break; 80.227 + } 80.228 + case T_ADDRESS: { 80.229 + address addr = (address) con.get_jobject(); 80.230 + constant_addr = _masm.address_constant(addr); 80.231 + break; 80.232 + } 80.233 + // We use T_VOID as marker for jump-table entries (labels) which 80.234 + // need an interal word relocation. 80.235 + case T_VOID: { 80.236 + // Write a dummy word. The real value is filled in later 80.237 + // in fill_jump_table_in_constant_table. 80.238 + address addr = (address) con.get_jobject(); 80.239 + constant_addr = _masm.address_constant(addr); 80.240 + break; 80.241 + } 80.242 + default: ShouldNotReachHere(); 80.243 + } 80.244 + assert(constant_addr != NULL, "consts section too small"); 80.245 + assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset())); 80.246 + } 80.247 + } 80.248 +} 80.249 + 80.250 +int Compile::ConstantTable::find_offset(Constant& con) const { 80.251 + int idx = _constants.find(con); 80.252 + assert(idx != -1, "constant must be in constant table"); 80.253 + int offset = _constants.at(idx).offset(); 80.254 + assert(offset != -1, "constant table not emitted yet?"); 80.255 + return offset; 80.256 +} 80.257 + 80.258 +void Compile::ConstantTable::add(Constant& con) { 80.259 + if (con.can_be_reused()) { 80.260 + int idx = _constants.find(con); 80.261 + if (idx != -1 && _constants.at(idx).can_be_reused()) { 80.262 + return; 80.263 + } 80.264 + } 80.265 + (void) _constants.append(con); 80.266 +} 80.267 + 80.268 +Compile::Constant Compile::ConstantTable::add(BasicType type, jvalue value) { 80.269 + Constant con(type, value); 80.270 + add(con); 80.271 + return con; 80.272 +} 80.273 + 80.274 +Compile::Constant Compile::ConstantTable::add(MachOper* oper) { 80.275 + jvalue value; 80.276 + BasicType type = oper->type()->basic_type(); 80.277 + switch (type) { 80.278 + case T_LONG: value.j = oper->constantL(); break; 80.279 + case T_FLOAT: value.f = oper->constantF(); break; 80.280 + case T_DOUBLE: value.d = oper->constantD(); break; 80.281 + case T_OBJECT: 80.282 + case T_ADDRESS: value.l = (jobject) oper->constant(); break; 80.283 + default: ShouldNotReachHere(); 80.284 + } 80.285 + return add(type, value); 80.286 +} 80.287 + 80.288 +Compile::Constant Compile::ConstantTable::allocate_jump_table(MachConstantNode* n) { 80.289 + jvalue value; 80.290 + // We can use the node pointer here to identify the right jump-table 80.291 + // as this method is called from Compile::Fill_buffer right before 80.292 + // the MachNodes are emitted and the jump-table is filled (means the 80.293 + // MachNode pointers do not change anymore). 80.294 + value.l = (jobject) n; 80.295 + Constant con(T_VOID, value, false); // Labels of a jump-table cannot be reused. 80.296 + for (uint i = 0; i < n->outcnt(); i++) { 80.297 + add(con); 80.298 + } 80.299 + return con; 80.300 +} 80.301 + 80.302 +void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const { 80.303 + // If called from Compile::scratch_emit_size do nothing. 80.304 + if (Compile::current()->in_scratch_emit_size()) return; 80.305 + 80.306 + assert(labels.is_nonempty(), "must be"); 80.307 + assert((uint) labels.length() == n->outcnt(), err_msg("must be equal: %d == %d", labels.length(), n->outcnt())); 80.308 + 80.309 + // Since MachConstantNode::constant_offset() also contains 80.310 + // table_base_offset() we need to subtract the table_base_offset() 80.311 + // to get the plain offset into the constant table. 80.312 + int offset = n->constant_offset() - table_base_offset(); 80.313 + 80.314 + MacroAssembler _masm(&cb); 80.315 + address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset); 80.316 + 80.317 + for (int i = 0; i < labels.length(); i++) { 80.318 + address* constant_addr = &jump_table_base[i]; 80.319 + assert(*constant_addr == (address) n, "all jump-table entries must contain node pointer"); 80.320 + *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr); 80.321 + cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type); 80.322 + } 80.323 +}
81.1 --- a/src/share/vm/opto/compile.hpp Tue Dec 21 23:39:42 2010 -0500 81.2 +++ b/src/share/vm/opto/compile.hpp Wed Dec 22 12:24:40 2010 -0500 81.3 @@ -48,7 +48,10 @@ 81.4 class InlineTree; 81.5 class Int_Array; 81.6 class Matcher; 81.7 +class MachConstantNode; 81.8 +class MachConstantBaseNode; 81.9 class MachNode; 81.10 +class MachOper; 81.11 class MachSafePointNode; 81.12 class Node; 81.13 class Node_Array; 81.14 @@ -139,6 +142,81 @@ 81.15 trapHistLength = methodDataOopDesc::_trap_hist_limit 81.16 }; 81.17 81.18 + // Constant entry of the constant table. 81.19 + class Constant { 81.20 + private: 81.21 + BasicType _type; 81.22 + jvalue _value; 81.23 + int _offset; // offset of this constant (in bytes) relative to the constant table base. 81.24 + bool _can_be_reused; // true (default) if the value can be shared with other users. 81.25 + 81.26 + public: 81.27 + Constant() : _type(T_ILLEGAL), _offset(-1), _can_be_reused(true) { _value.l = 0; } 81.28 + Constant(BasicType type, jvalue value, bool can_be_reused = true) : 81.29 + _type(type), 81.30 + _value(value), 81.31 + _offset(-1), 81.32 + _can_be_reused(can_be_reused) 81.33 + {} 81.34 + 81.35 + bool operator==(const Constant& other); 81.36 + 81.37 + BasicType type() const { return _type; } 81.38 + 81.39 + jlong get_jlong() const { return _value.j; } 81.40 + jfloat get_jfloat() const { return _value.f; } 81.41 + jdouble get_jdouble() const { return _value.d; } 81.42 + jobject get_jobject() const { return _value.l; } 81.43 + 81.44 + int offset() const { return _offset; } 81.45 + void set_offset(int offset) { _offset = offset; } 81.46 + 81.47 + bool can_be_reused() const { return _can_be_reused; } 81.48 + }; 81.49 + 81.50 + // Constant table. 81.51 + class ConstantTable { 81.52 + private: 81.53 + GrowableArray<Constant> _constants; // Constants of this table. 81.54 + int _size; // Size in bytes the emitted constant table takes (including padding). 81.55 + int _table_base_offset; // Offset of the table base that gets added to the constant offsets. 81.56 + 81.57 + public: 81.58 + ConstantTable() : 81.59 + _size(-1), 81.60 + _table_base_offset(-1) // We can use -1 here since the constant table is always bigger than 2 bytes (-(size / 2), see MachConstantBaseNode::emit). 81.61 + {} 81.62 + 81.63 + int size() const { assert(_size != -1, "size not yet calculated"); return _size; } 81.64 + 81.65 + void set_table_base_offset(int x) { assert(_table_base_offset == -1, "set only once"); _table_base_offset = x; } 81.66 + int table_base_offset() const { assert(_table_base_offset != -1, "table base offset not yet set"); return _table_base_offset; } 81.67 + 81.68 + void emit(CodeBuffer& cb); 81.69 + 81.70 + // Returns the offset of the last entry (the top) of the constant table. 81.71 + int top_offset() const { assert(_constants.top().offset() != -1, "constant not yet bound"); return _constants.top().offset(); } 81.72 + 81.73 + void calculate_offsets_and_size(); 81.74 + int find_offset(Constant& con) const; 81.75 + 81.76 + void add(Constant& con); 81.77 + Constant add(BasicType type, jvalue value); 81.78 + Constant add(MachOper* oper); 81.79 + Constant add(jfloat f) { 81.80 + jvalue value; value.f = f; 81.81 + return add(T_FLOAT, value); 81.82 + } 81.83 + Constant add(jdouble d) { 81.84 + jvalue value; value.d = d; 81.85 + return add(T_DOUBLE, value); 81.86 + } 81.87 + 81.88 + // Jump table 81.89 + Constant allocate_jump_table(MachConstantNode* n); 81.90 + void fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const; 81.91 + }; 81.92 + 81.93 private: 81.94 // Fixed parameters to this compilation. 81.95 const int _compile_id; 81.96 @@ -212,6 +290,11 @@ 81.97 Node* _recent_alloc_obj; 81.98 Node* _recent_alloc_ctl; 81.99 81.100 + // Constant table 81.101 + ConstantTable _constant_table; // The constant table for this compile. 81.102 + MachConstantBaseNode* _mach_constant_base_node; // Constant table base node singleton. 81.103 + 81.104 + 81.105 // Blocked array of debugging and profiling information, 81.106 // tracked per node. 81.107 enum { _log2_node_notes_block_size = 8, 81.108 @@ -272,6 +355,8 @@ 81.109 static int _CompiledZap_count; // counter compared against CompileZap[First/Last] 81.110 BufferBlob* _scratch_buffer_blob; // For temporary code buffers. 81.111 relocInfo* _scratch_locs_memory; // For temporary code buffers. 81.112 + int _scratch_const_size; // For temporary code buffers. 81.113 + bool _in_scratch_emit_size; // true when in scratch_emit_size. 81.114 81.115 public: 81.116 // Accessors 81.117 @@ -454,6 +539,12 @@ 81.118 _recent_alloc_obj = obj; 81.119 } 81.120 81.121 + // Constant table 81.122 + ConstantTable& constant_table() { return _constant_table; } 81.123 + 81.124 + MachConstantBaseNode* mach_constant_base_node(); 81.125 + bool has_mach_constant_base_node() const { return _mach_constant_base_node != NULL; } 81.126 + 81.127 // Handy undefined Node 81.128 Node* top() const { return _top; } 81.129 81.130 @@ -605,13 +696,16 @@ 81.131 Dependencies* dependencies() { return env()->dependencies(); } 81.132 static int CompiledZap_count() { return _CompiledZap_count; } 81.133 BufferBlob* scratch_buffer_blob() { return _scratch_buffer_blob; } 81.134 - void init_scratch_buffer_blob(); 81.135 + void init_scratch_buffer_blob(int const_size); 81.136 + void clear_scratch_buffer_blob(); 81.137 void set_scratch_buffer_blob(BufferBlob* b) { _scratch_buffer_blob = b; } 81.138 relocInfo* scratch_locs_memory() { return _scratch_locs_memory; } 81.139 void set_scratch_locs_memory(relocInfo* b) { _scratch_locs_memory = b; } 81.140 81.141 // emit to scratch blob, report resulting size 81.142 uint scratch_emit_size(const Node* n); 81.143 + void set_in_scratch_emit_size(bool x) { _in_scratch_emit_size = x; } 81.144 + bool in_scratch_emit_size() const { return _in_scratch_emit_size; } 81.145 81.146 enum ScratchBufferBlob { 81.147 MAX_inst_size = 1024, 81.148 @@ -692,7 +786,7 @@ 81.149 void Fill_buffer(); 81.150 81.151 // Determine which variable sized branches can be shortened 81.152 - void Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size, int& const_size); 81.153 + void Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size); 81.154 81.155 // Compute the size of first NumberOfLoopInstrToAlign instructions 81.156 // at the head of a loop.
82.1 --- a/src/share/vm/opto/gcm.cpp Tue Dec 21 23:39:42 2010 -0500 82.2 +++ b/src/share/vm/opto/gcm.cpp Wed Dec 22 12:24:40 2010 -0500 82.3 @@ -89,7 +89,7 @@ 82.4 assert(in0 != NULL, "Only control-dependent"); 82.5 const Node *p = in0->is_block_proj(); 82.6 if (p != NULL && p != n) { // Control from a block projection? 82.7 - assert(!n->pinned() || n->is_SafePointScalarObject(), "only SafePointScalarObject pinned node is expected here"); 82.8 + assert(!n->pinned() || n->is_MachConstantBase() || n->is_SafePointScalarObject(), "only pinned MachConstantBase or SafePointScalarObject node is expected here"); 82.9 // Find trailing Region 82.10 Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block 82.11 uint j = 0;
83.1 --- a/src/share/vm/opto/graphKit.cpp Tue Dec 21 23:39:42 2010 -0500 83.2 +++ b/src/share/vm/opto/graphKit.cpp Wed Dec 22 12:24:40 2010 -0500 83.3 @@ -1841,7 +1841,7 @@ 83.4 83.5 // Note: If ProfileTraps is true, and if a deopt. actually 83.6 // occurs here, the runtime will make sure an MDO exists. There is 83.7 - // no need to call method()->build_method_data() at this point. 83.8 + // no need to call method()->ensure_method_data() at this point. 83.9 83.10 #ifdef ASSERT 83.11 if (!must_throw) {
84.1 --- a/src/share/vm/opto/machnode.cpp Tue Dec 21 23:39:42 2010 -0500 84.2 +++ b/src/share/vm/opto/machnode.cpp Wed Dec 22 12:24:40 2010 -0500 84.3 @@ -489,6 +489,20 @@ 84.4 } 84.5 #endif 84.6 84.7 + 84.8 +//============================================================================= 84.9 +int MachConstantNode::constant_offset() { 84.10 + int offset = _constant.offset(); 84.11 + // Bind the offset lazily. 84.12 + if (offset == -1) { 84.13 + Compile::ConstantTable& constant_table = Compile::current()->constant_table(); 84.14 + offset = constant_table.table_base_offset() + constant_table.find_offset(_constant); 84.15 + _constant.set_offset(offset); 84.16 + } 84.17 + return offset; 84.18 +} 84.19 + 84.20 + 84.21 //============================================================================= 84.22 #ifndef PRODUCT 84.23 void MachNullCheckNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
85.1 --- a/src/share/vm/opto/machnode.hpp Tue Dec 21 23:39:42 2010 -0500 85.2 +++ b/src/share/vm/opto/machnode.hpp Wed Dec 22 12:24:40 2010 -0500 85.3 @@ -231,9 +231,6 @@ 85.4 // Return number of relocatable values contained in this instruction 85.5 virtual int reloc() const { return 0; } 85.6 85.7 - // Return number of words used for double constants in this instruction 85.8 - virtual int const_size() const { return 0; } 85.9 - 85.10 // Hash and compare over operands. Used to do GVN on machine Nodes. 85.11 virtual uint hash() const; 85.12 virtual uint cmp( const Node &n ) const; 85.13 @@ -348,6 +345,65 @@ 85.14 #endif 85.15 }; 85.16 85.17 +//------------------------------MachConstantBaseNode-------------------------- 85.18 +// Machine node that represents the base address of the constant table. 85.19 +class MachConstantBaseNode : public MachIdealNode { 85.20 +public: 85.21 + static const RegMask& _out_RegMask; // We need the out_RegMask statically in MachConstantNode::in_RegMask(). 85.22 + 85.23 +public: 85.24 + MachConstantBaseNode() : MachIdealNode() { 85.25 + init_class_id(Class_MachConstantBase); 85.26 + } 85.27 + virtual const class Type* bottom_type() const { return TypeRawPtr::NOTNULL; } 85.28 + virtual uint ideal_reg() const { return Op_RegP; } 85.29 + virtual uint oper_input_base() const { return 1; } 85.30 + 85.31 + virtual void emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const; 85.32 + virtual uint size(PhaseRegAlloc* ra_) const; 85.33 + virtual bool pinned() const { return UseRDPCForConstantTableBase; } 85.34 + 85.35 + static const RegMask& static_out_RegMask() { return _out_RegMask; } 85.36 + virtual const RegMask& out_RegMask() const { return static_out_RegMask(); } 85.37 + 85.38 +#ifndef PRODUCT 85.39 + virtual const char* Name() const { return "MachConstantBaseNode"; } 85.40 + virtual void format(PhaseRegAlloc*, outputStream* st) const; 85.41 +#endif 85.42 +}; 85.43 + 85.44 +//------------------------------MachConstantNode------------------------------- 85.45 +// Machine node that holds a constant which is stored in the constant table. 85.46 +class MachConstantNode : public MachNode { 85.47 +protected: 85.48 + Compile::Constant _constant; // This node's constant. 85.49 + 85.50 +public: 85.51 + MachConstantNode() : MachNode() { 85.52 + init_class_id(Class_MachConstant); 85.53 + } 85.54 + 85.55 + virtual void eval_constant(Compile* C) { 85.56 +#ifdef ASSERT 85.57 + tty->print("missing MachConstantNode eval_constant function: "); 85.58 + dump(); 85.59 +#endif 85.60 + ShouldNotCallThis(); 85.61 + } 85.62 + 85.63 + virtual const RegMask &in_RegMask(uint idx) const { 85.64 + if (idx == mach_constant_base_node_input()) 85.65 + return MachConstantBaseNode::static_out_RegMask(); 85.66 + return MachNode::in_RegMask(idx); 85.67 + } 85.68 + 85.69 + // Input edge of MachConstantBaseNode. 85.70 + uint mach_constant_base_node_input() const { return req() - 1; } 85.71 + 85.72 + int constant_offset(); 85.73 + int constant_offset() const { return ((MachConstantNode*) this)->constant_offset(); } 85.74 +}; 85.75 + 85.76 //------------------------------MachUEPNode----------------------------------- 85.77 // Machine Unvalidated Entry Point Node 85.78 class MachUEPNode : public MachIdealNode {
86.1 --- a/src/share/vm/opto/matcher.hpp Tue Dec 21 23:39:42 2010 -0500 86.2 +++ b/src/share/vm/opto/matcher.hpp Wed Dec 22 12:24:40 2010 -0500 86.3 @@ -365,6 +365,10 @@ 86.4 // registers? True for Intel but false for most RISCs 86.5 static const bool clone_shift_expressions; 86.6 86.7 + // Should constant table entries be accessed with loads using 86.8 + // absolute addressing? True for x86 but false for most RISCs. 86.9 + static const bool constant_table_absolute_addressing; 86.10 + 86.11 static bool narrow_oop_use_complex_address(); 86.12 86.13 // Generate implicit null check for narrow oops if it can fold
87.1 --- a/src/share/vm/opto/memnode.cpp Tue Dec 21 23:39:42 2010 -0500 87.2 +++ b/src/share/vm/opto/memnode.cpp Wed Dec 22 12:24:40 2010 -0500 87.3 @@ -3599,10 +3599,12 @@ 87.4 intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, max_jint); 87.5 if (zeroes_done + BytesPerLong >= size_limit) { 87.6 assert(allocation() != NULL, ""); 87.7 - Node* klass_node = allocation()->in(AllocateNode::KlassNode); 87.8 - ciKlass* k = phase->type(klass_node)->is_klassptr()->klass(); 87.9 - if (zeroes_done == k->layout_helper()) 87.10 - zeroes_done = size_limit; 87.11 + if (allocation()->Opcode() == Op_Allocate) { 87.12 + Node* klass_node = allocation()->in(AllocateNode::KlassNode); 87.13 + ciKlass* k = phase->type(klass_node)->is_klassptr()->klass(); 87.14 + if (zeroes_done == k->layout_helper()) 87.15 + zeroes_done = size_limit; 87.16 + } 87.17 } 87.18 if (zeroes_done < size_limit) { 87.19 rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr,
88.1 --- a/src/share/vm/opto/node.hpp Tue Dec 21 23:39:42 2010 -0500 88.2 +++ b/src/share/vm/opto/node.hpp Wed Dec 22 12:24:40 2010 -0500 88.3 @@ -81,6 +81,8 @@ 88.4 class MachCallNode; 88.5 class MachCallRuntimeNode; 88.6 class MachCallStaticJavaNode; 88.7 +class MachConstantBaseNode; 88.8 +class MachConstantNode; 88.9 class MachIfNode; 88.10 class MachNode; 88.11 class MachNullCheckNode; 88.12 @@ -566,10 +568,12 @@ 88.13 DEFINE_CLASS_ID(MachCallDynamicJava, MachCallJava, 1) 88.14 DEFINE_CLASS_ID(MachCallRuntime, MachCall, 1) 88.15 DEFINE_CLASS_ID(MachCallLeaf, MachCallRuntime, 0) 88.16 - DEFINE_CLASS_ID(MachSpillCopy, Mach, 1) 88.17 - DEFINE_CLASS_ID(MachNullCheck, Mach, 2) 88.18 - DEFINE_CLASS_ID(MachIf, Mach, 3) 88.19 - DEFINE_CLASS_ID(MachTemp, Mach, 4) 88.20 + DEFINE_CLASS_ID(MachSpillCopy, Mach, 1) 88.21 + DEFINE_CLASS_ID(MachNullCheck, Mach, 2) 88.22 + DEFINE_CLASS_ID(MachIf, Mach, 3) 88.23 + DEFINE_CLASS_ID(MachTemp, Mach, 4) 88.24 + DEFINE_CLASS_ID(MachConstantBase, Mach, 5) 88.25 + DEFINE_CLASS_ID(MachConstant, Mach, 6) 88.26 88.27 DEFINE_CLASS_ID(Proj, Node, 2) 88.28 DEFINE_CLASS_ID(CatchProj, Proj, 0) 88.29 @@ -734,6 +738,8 @@ 88.30 DEFINE_CLASS_QUERY(MachCallLeaf) 88.31 DEFINE_CLASS_QUERY(MachCallRuntime) 88.32 DEFINE_CLASS_QUERY(MachCallStaticJava) 88.33 + DEFINE_CLASS_QUERY(MachConstantBase) 88.34 + DEFINE_CLASS_QUERY(MachConstant) 88.35 DEFINE_CLASS_QUERY(MachIf) 88.36 DEFINE_CLASS_QUERY(MachNullCheck) 88.37 DEFINE_CLASS_QUERY(MachReturn)
89.1 --- a/src/share/vm/opto/output.cpp Tue Dec 21 23:39:42 2010 -0500 89.2 +++ b/src/share/vm/opto/output.cpp Wed Dec 22 12:24:40 2010 -0500 89.3 @@ -61,11 +61,6 @@ 89.4 // RootNode goes 89.5 assert( _cfg->_broot->_nodes.size() == 0, "" ); 89.6 89.7 - // Initialize the space for the BufferBlob used to find and verify 89.8 - // instruction size in MachNode::emit_size() 89.9 - init_scratch_buffer_blob(); 89.10 - if (failing()) return; // Out of memory 89.11 - 89.12 // The number of new nodes (mostly MachNop) is proportional to 89.13 // the number of java calls and inner loops which are aligned. 89.14 if ( C->check_node_count((NodeLimitFudgeFactor + C->java_calls()*3 + 89.15 @@ -333,7 +328,7 @@ 89.16 //----------------------Shorten_branches--------------------------------------- 89.17 // The architecture description provides short branch variants for some long 89.18 // branch instructions. Replace eligible long branches with short branches. 89.19 -void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size, int& const_size) { 89.20 +void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size) { 89.21 89.22 // fill in the nop array for bundling computations 89.23 MachNode *_nop_list[Bundle::_nop_count]; 89.24 @@ -353,12 +348,11 @@ 89.25 // Size in bytes of all relocation entries, including those in local stubs. 89.26 // Start with 2-bytes of reloc info for the unvalidated entry point 89.27 reloc_size = 1; // Number of relocation entries 89.28 - const_size = 0; // size of fp constants in words 89.29 89.30 // Make three passes. The first computes pessimistic blk_starts, 89.31 - // relative jmp_end, reloc_size and const_size information. 89.32 - // The second performs short branch substitution using the pessimistic 89.33 - // sizing. The third inserts nops where needed. 89.34 + // relative jmp_end and reloc_size information. The second performs 89.35 + // short branch substitution using the pessimistic sizing. The 89.36 + // third inserts nops where needed. 89.37 89.38 Node *nj; // tmp 89.39 89.40 @@ -381,7 +375,6 @@ 89.41 MachNode *mach = nj->as_Mach(); 89.42 blk_size += (mach->alignment_required() - 1) * relocInfo::addr_unit(); // assume worst case padding 89.43 reloc_size += mach->reloc(); 89.44 - const_size += mach->const_size(); 89.45 if( mach->is_MachCall() ) { 89.46 MachCallNode *mcall = mach->as_MachCall(); 89.47 // This destination address is NOT PC-relative 89.48 @@ -398,10 +391,6 @@ 89.49 if (min_offset_from_last_call == 0) { 89.50 blk_size += nop_size; 89.51 } 89.52 - } else if (mach->ideal_Opcode() == Op_Jump) { 89.53 - const_size += b->_num_succs; // Address table size 89.54 - // The size is valid even for 64 bit since it is 89.55 - // multiplied by 2*jintSize on this method exit. 89.56 } 89.57 } 89.58 min_offset_from_last_call += inst_size; 89.59 @@ -562,10 +551,6 @@ 89.60 // a relocation index. 89.61 // The CodeBuffer will expand the locs array if this estimate is too low. 89.62 reloc_size *= 10 / sizeof(relocInfo); 89.63 - 89.64 - // Adjust const_size to number of bytes 89.65 - const_size *= 2*jintSize; // both float and double take two words per entry 89.66 - 89.67 } 89.68 89.69 //------------------------------FillLocArray----------------------------------- 89.70 @@ -1102,10 +1087,39 @@ 89.71 blk_labels[i].init(); 89.72 } 89.73 89.74 + if (has_mach_constant_base_node()) { 89.75 + // Fill the constant table. 89.76 + // Note: This must happen before Shorten_branches. 89.77 + for (i = 0; i < _cfg->_num_blocks; i++) { 89.78 + Block* b = _cfg->_blocks[i]; 89.79 + 89.80 + for (uint j = 0; j < b->_nodes.size(); j++) { 89.81 + Node* n = b->_nodes[j]; 89.82 + 89.83 + // If the node is a MachConstantNode evaluate the constant 89.84 + // value section. 89.85 + if (n->is_MachConstant()) { 89.86 + MachConstantNode* machcon = n->as_MachConstant(); 89.87 + machcon->eval_constant(C); 89.88 + } 89.89 + } 89.90 + } 89.91 + 89.92 + // Calculate the offsets of the constants and the size of the 89.93 + // constant table (including the padding to the next section). 89.94 + constant_table().calculate_offsets_and_size(); 89.95 + const_req = constant_table().size(); 89.96 + } 89.97 + 89.98 + // Initialize the space for the BufferBlob used to find and verify 89.99 + // instruction size in MachNode::emit_size() 89.100 + init_scratch_buffer_blob(const_req); 89.101 + if (failing()) return; // Out of memory 89.102 + 89.103 // If this machine supports different size branch offsets, then pre-compute 89.104 // the length of the blocks 89.105 if( _matcher->is_short_branch_offset(-1, 0) ) { 89.106 - Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req); 89.107 + Shorten_branches(blk_labels, code_req, locs_req, stub_req); 89.108 labels_not_set = false; 89.109 } 89.110 89.111 @@ -1121,12 +1135,12 @@ 89.112 code_req = const_req = stub_req = exception_handler_req = deopt_handler_req = 0x10; // force expansion 89.113 89.114 int total_req = 89.115 + const_req + 89.116 code_req + 89.117 pad_req + 89.118 stub_req + 89.119 exception_handler_req + 89.120 - deopt_handler_req + // deopt handler 89.121 - const_req; 89.122 + deopt_handler_req; // deopt handler 89.123 89.124 if (has_method_handle_invokes()) 89.125 total_req += deopt_handler_req; // deopt MH handler 89.126 @@ -1180,6 +1194,11 @@ 89.127 89.128 NonSafepointEmitter non_safepoints(this); // emit non-safepoints lazily 89.129 89.130 + // Emit the constant table. 89.131 + if (has_mach_constant_base_node()) { 89.132 + constant_table().emit(*cb); 89.133 + } 89.134 + 89.135 // ------------------ 89.136 // Now fill in the code buffer 89.137 Node *delay_slot = NULL; 89.138 @@ -1196,12 +1215,13 @@ 89.139 cb->flush_bundle(true); 89.140 89.141 // Define the label at the beginning of the basic block 89.142 - if( labels_not_set ) 89.143 - MacroAssembler(cb).bind( blk_labels[b->_pre_order] ); 89.144 - 89.145 - else 89.146 - assert( blk_labels[b->_pre_order].loc_pos() == cb->insts_size(), 89.147 - "label position does not match code offset" ); 89.148 + if (labels_not_set) { 89.149 + MacroAssembler(cb).bind(blk_labels[b->_pre_order]); 89.150 + } else { 89.151 + assert(blk_labels[b->_pre_order].loc_pos() == cb->insts_size(), 89.152 + err_msg("label position does not match code offset: %d != %d", 89.153 + blk_labels[b->_pre_order].loc_pos(), cb->insts_size())); 89.154 + } 89.155 89.156 uint last_inst = b->_nodes.size(); 89.157 89.158 @@ -1718,9 +1738,17 @@ 89.159 // Create a data structure for all the scheduling information 89.160 Scheduling scheduling(Thread::current()->resource_area(), *this); 89.161 89.162 + // Initialize the space for the BufferBlob used to find and verify 89.163 + // instruction size in MachNode::emit_size() 89.164 + init_scratch_buffer_blob(MAX_const_size); 89.165 + if (failing()) return; // Out of memory 89.166 + 89.167 // Walk backwards over each basic block, computing the needed alignment 89.168 // Walk over all the basic blocks 89.169 scheduling.DoScheduling(); 89.170 + 89.171 + // Clear the BufferBlob used for scheduling. 89.172 + clear_scratch_buffer_blob(); 89.173 } 89.174 89.175 //------------------------------ComputeLocalLatenciesForward-------------------
90.1 --- a/src/share/vm/opto/postaloc.cpp Tue Dec 21 23:39:42 2010 -0500 90.2 +++ b/src/share/vm/opto/postaloc.cpp Wed Dec 22 12:24:40 2010 -0500 90.3 @@ -200,6 +200,19 @@ 90.4 // then reloaded BUT survives in a register the whole way. 90.5 Node *val = skip_copies(n->in(k)); 90.6 90.7 + if (val == x && nk_idx != 0 && 90.8 + regnd[nk_reg] != NULL && regnd[nk_reg] != x && 90.9 + n2lidx(x) == n2lidx(regnd[nk_reg])) { 90.10 + // When rematerialzing nodes and stretching lifetimes, the 90.11 + // allocator will reuse the original def for multidef LRG instead 90.12 + // of the current reaching def because it can't know it's safe to 90.13 + // do so. After allocation completes if they are in the same LRG 90.14 + // then it should use the current reaching def instead. 90.15 + n->set_req(k, regnd[nk_reg]); 90.16 + blk_adjust += yank_if_dead(val, current_block, &value, ®nd); 90.17 + val = skip_copies(n->in(k)); 90.18 + } 90.19 + 90.20 if( val == x ) return blk_adjust; // No progress? 90.21 90.22 bool single = is_single_register(val->ideal_reg());
91.1 --- a/src/share/vm/opto/reg_split.cpp Tue Dec 21 23:39:42 2010 -0500 91.2 +++ b/src/share/vm/opto/reg_split.cpp Wed Dec 22 12:24:40 2010 -0500 91.3 @@ -1239,6 +1239,7 @@ 91.4 // Cycle through this block's predecessors, collecting Reaches 91.5 // info for each spilled LRG and update edges. 91.6 // Walk the phis list to patch inputs, split phis, and name phis 91.7 + uint lrgs_before_phi_split = maxlrg; 91.8 for( insidx = 0; insidx < phis->size(); insidx++ ) { 91.9 Node *phi = phis->at(insidx); 91.10 assert(phi->is_Phi(),"This list must only contain Phi Nodes"); 91.11 @@ -1273,7 +1274,16 @@ 91.12 assert( def, "must have reaching def" ); 91.13 // If input up/down sense and reg-pressure DISagree 91.14 if( def->rematerialize() ) { 91.15 - def = split_Rematerialize( def, pred, pred->end_idx(), maxlrg, splits, slidx, lrg2reach, Reachblock, false ); 91.16 + // Place the rematerialized node above any MSCs created during 91.17 + // phi node splitting. end_idx points at the insertion point 91.18 + // so look at the node before it. 91.19 + int insert = pred->end_idx(); 91.20 + while (insert >= 1 && 91.21 + pred->_nodes[insert - 1]->is_SpillCopy() && 91.22 + Find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) { 91.23 + insert--; 91.24 + } 91.25 + def = split_Rematerialize( def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false ); 91.26 if( !def ) return 0; // Bail out 91.27 } 91.28 // Update the Phi's input edge array
92.1 --- a/src/share/vm/prims/jvm.h Tue Dec 21 23:39:42 2010 -0500 92.2 +++ b/src/share/vm/prims/jvm.h Wed Dec 22 12:24:40 2010 -0500 92.3 @@ -1063,7 +1063,8 @@ 92.4 JVM_CONSTANT_MethodHandle = 15, // JSR 292 92.5 JVM_CONSTANT_MethodType = 16, // JSR 292 92.6 JVM_CONSTANT_InvokeDynamicTrans = 17, // JSR 292, only occurs in old class files 92.7 - JVM_CONSTANT_InvokeDynamic = 18 // JSR 292 92.8 + JVM_CONSTANT_InvokeDynamic = 18, // JSR 292 92.9 + JVM_CONSTANT_ExternalMax = 18 // Last tag found in classfiles 92.10 }; 92.11 92.12 /* JVM_CONSTANT_MethodHandle subtypes */
93.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue Dec 21 23:39:42 2010 -0500 93.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Dec 22 12:24:40 2010 -0500 93.3 @@ -214,7 +214,7 @@ 93.4 case JVM_CONSTANT_Double: // fall through 93.5 case JVM_CONSTANT_Long: 93.6 { 93.7 - scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p, 93.8 + constantPoolOopDesc::copy_entry_to(scratch_cp, scratch_i, *merge_cp_p, *merge_cp_length_p, 93.9 THREAD); 93.10 93.11 if (scratch_i != *merge_cp_length_p) { 93.12 @@ -239,7 +239,7 @@ 93.13 case JVM_CONSTANT_UnresolvedClass: // fall through 93.14 case JVM_CONSTANT_UnresolvedString: 93.15 { 93.16 - scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p, 93.17 + constantPoolOopDesc::copy_entry_to(scratch_cp, scratch_i, *merge_cp_p, *merge_cp_length_p, 93.18 THREAD); 93.19 93.20 if (scratch_i != *merge_cp_length_p) { 93.21 @@ -1093,13 +1093,13 @@ 93.22 case JVM_CONSTANT_Long: 93.23 // just copy the entry to *merge_cp_p, but double and long take 93.24 // two constant pool entries 93.25 - old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0); 93.26 + constantPoolOopDesc::copy_entry_to(old_cp, old_i, *merge_cp_p, old_i, CHECK_0); 93.27 old_i++; 93.28 break; 93.29 93.30 default: 93.31 // just copy the entry to *merge_cp_p 93.32 - old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0); 93.33 + constantPoolOopDesc::copy_entry_to(old_cp, old_i, *merge_cp_p, old_i, CHECK_0); 93.34 break; 93.35 } 93.36 } // end for each old_cp entry
94.1 --- a/src/share/vm/prims/methodHandleWalk.cpp Tue Dec 21 23:39:42 2010 -0500 94.2 +++ b/src/share/vm/prims/methodHandleWalk.cpp Wed Dec 22 12:24:40 2010 -0500 94.3 @@ -968,16 +968,11 @@ 94.4 94.5 if (tailcall) { 94.6 // Actually, in order to make these methods more recognizable, 94.7 - // let's put them in holder classes MethodHandle and InvokeDynamic. 94.8 - // That way stack walkers and compiler heuristics can recognize them. 94.9 - _target_klass = (for_invokedynamic() 94.10 - ? SystemDictionary::InvokeDynamic_klass() 94.11 - : SystemDictionary::MethodHandle_klass()); 94.12 + // let's put them in holder class MethodHandle. That way stack 94.13 + // walkers and compiler heuristics can recognize them. 94.14 + _target_klass = SystemDictionary::MethodHandle_klass(); 94.15 } 94.16 94.17 - // instanceKlass* ik = instanceKlass::cast(klass); 94.18 - // tty->print_cr("MethodHandleCompiler::make_invoke: %s %s.%s%s", Bytecodes::name(op), ik->external_name(), name->as_C_string(), signature->as_C_string()); 94.19 - 94.20 // Inline the method. 94.21 InvocationCounter* ic = m->invocation_counter(); 94.22 ic->set_carry_flag();
95.1 --- a/src/share/vm/prims/methodHandleWalk.hpp Tue Dec 21 23:39:42 2010 -0500 95.2 +++ b/src/share/vm/prims/methodHandleWalk.hpp Wed Dec 22 12:24:40 2010 -0500 95.3 @@ -412,8 +412,7 @@ 95.4 95.5 // Tests if the given class is a MH adapter holder. 95.6 static bool klass_is_method_handle_adapter_holder(klassOop klass) { 95.7 - return (klass == SystemDictionary::MethodHandle_klass() || 95.8 - klass == SystemDictionary::InvokeDynamic_klass()); 95.9 + return (klass == SystemDictionary::MethodHandle_klass()); 95.10 } 95.11 }; 95.12
96.1 --- a/src/share/vm/prims/methodHandles.cpp Tue Dec 21 23:39:42 2010 -0500 96.2 +++ b/src/share/vm/prims/methodHandles.cpp Wed Dec 22 12:24:40 2010 -0500 96.3 @@ -485,9 +485,8 @@ 96.4 Handle polymorphic_method_type; 96.5 bool polymorphic_signature = false; 96.6 if ((flags & ALL_KINDS) == IS_METHOD && 96.7 - (defc() == SystemDictionary::InvokeDynamic_klass() || 96.8 - (defc() == SystemDictionary::MethodHandle_klass() && 96.9 - methodOopDesc::is_method_handle_invoke_name(name())))) 96.10 + (defc() == SystemDictionary::MethodHandle_klass() && 96.11 + methodOopDesc::is_method_handle_invoke_name(name()))) 96.12 polymorphic_signature = true; 96.13 96.14 // convert the external string or reflective type to an internal signature
97.1 --- a/src/share/vm/runtime/arguments.cpp Tue Dec 21 23:39:42 2010 -0500 97.2 +++ b/src/share/vm/runtime/arguments.cpp Wed Dec 22 12:24:40 2010 -0500 97.3 @@ -1007,24 +1007,9 @@ 97.4 void Arguments::check_compressed_oops_compat() { 97.5 #ifdef _LP64 97.6 assert(UseCompressedOops, "Precondition"); 97.7 -# if defined(COMPILER1) && !defined(TIERED) 97.8 - // Until c1 supports compressed oops turn them off. 97.9 - FLAG_SET_DEFAULT(UseCompressedOops, false); 97.10 -# else 97.11 // Is it on by default or set on ergonomically 97.12 bool is_on_by_default = FLAG_IS_DEFAULT(UseCompressedOops) || FLAG_IS_ERGO(UseCompressedOops); 97.13 97.14 - // Tiered currently doesn't work with compressed oops 97.15 - if (TieredCompilation) { 97.16 - if (is_on_by_default) { 97.17 - FLAG_SET_DEFAULT(UseCompressedOops, false); 97.18 - return; 97.19 - } else { 97.20 - vm_exit_during_initialization( 97.21 - "Tiered compilation is not supported with compressed oops yet", NULL); 97.22 - } 97.23 - } 97.24 - 97.25 // If dumping an archive or forcing its use, disable compressed oops if possible 97.26 if (DumpSharedSpaces || RequireSharedSpaces) { 97.27 if (is_on_by_default) { 97.28 @@ -1038,9 +1023,7 @@ 97.29 // UseSharedSpaces is on by default. With compressed oops, we turn it off. 97.30 FLAG_SET_DEFAULT(UseSharedSpaces, false); 97.31 } 97.32 - 97.33 -# endif // defined(COMPILER1) && !defined(TIERED) 97.34 -#endif // _LP64 97.35 +#endif 97.36 } 97.37 97.38 void Arguments::set_tiered_flags() { 97.39 @@ -3075,11 +3058,9 @@ 97.40 // Set flags based on ergonomics. 97.41 set_ergonomics_flags(); 97.42 97.43 -#ifdef _LP64 97.44 if (UseCompressedOops) { 97.45 check_compressed_oops_compat(); 97.46 } 97.47 -#endif 97.48 97.49 // Check the GC selections again. 97.50 if (!check_gc_consistency()) {
98.1 --- a/src/share/vm/runtime/thread.cpp Tue Dec 21 23:39:42 2010 -0500 98.2 +++ b/src/share/vm/runtime/thread.cpp Wed Dec 22 12:24:40 2010 -0500 98.3 @@ -3231,12 +3231,6 @@ 98.4 warning("java.lang.ArithmeticException has not been initialized"); 98.5 warning("java.lang.StackOverflowError has not been initialized"); 98.6 } 98.7 - 98.8 - if (EnableInvokeDynamic) { 98.9 - // JSR 292: An intialized java.dyn.InvokeDynamic is required in 98.10 - // the compiler. 98.11 - initialize_class(vmSymbolHandles::java_dyn_InvokeDynamic(), CHECK_0); 98.12 - } 98.13 } 98.14 98.15 // See : bugid 4211085.
99.1 --- a/src/share/vm/runtime/vmStructs.cpp Tue Dec 21 23:39:42 2010 -0500 99.2 +++ b/src/share/vm/runtime/vmStructs.cpp Wed Dec 22 12:24:40 2010 -0500 99.3 @@ -1676,10 +1676,7 @@ 99.4 /* constantPoolOop layout enum for InvokeDynamic */ \ 99.5 /*************************************************/ \ 99.6 \ 99.7 - declare_constant(constantPoolOopDesc::_multi_operand_count_offset) \ 99.8 - declare_constant(constantPoolOopDesc::_multi_operand_base_offset) \ 99.9 declare_constant(constantPoolOopDesc::_indy_bsm_offset) \ 99.10 - declare_constant(constantPoolOopDesc::_indy_nt_offset) \ 99.11 declare_constant(constantPoolOopDesc::_indy_argc_offset) \ 99.12 declare_constant(constantPoolOopDesc::_indy_argv_offset) \ 99.13 \
100.1 --- a/src/share/vm/utilities/constantTag.cpp Tue Dec 21 23:39:42 2010 -0500 100.2 +++ b/src/share/vm/utilities/constantTag.cpp Wed Dec 22 12:24:40 2010 -0500 100.3 @@ -93,6 +93,8 @@ 100.4 return "MethodType"; 100.5 case JVM_CONSTANT_InvokeDynamic : 100.6 return "InvokeDynamic"; 100.7 + case JVM_CONSTANT_InvokeDynamicTrans : 100.8 + return "InvokeDynamic/transitional"; 100.9 case JVM_CONSTANT_Object : 100.10 return "Object"; 100.11 case JVM_CONSTANT_Utf8 :
101.1 --- a/src/share/vm/utilities/constantTag.hpp Tue Dec 21 23:39:42 2010 -0500 101.2 +++ b/src/share/vm/utilities/constantTag.hpp Wed Dec 22 12:24:40 2010 -0500 101.3 @@ -86,7 +86,8 @@ 101.4 101.5 bool is_method_type() const { return _tag == JVM_CONSTANT_MethodType; } 101.6 bool is_method_handle() const { return _tag == JVM_CONSTANT_MethodHandle; } 101.7 - bool is_invoke_dynamic() const { return _tag == JVM_CONSTANT_InvokeDynamic; } 101.8 + bool is_invoke_dynamic() const { return (_tag == JVM_CONSTANT_InvokeDynamic || 101.9 + _tag == JVM_CONSTANT_InvokeDynamicTrans); } 101.10 101.11 bool is_loadable_constant() const { 101.12 return ((_tag >= JVM_CONSTANT_Integer && _tag <= JVM_CONSTANT_String) ||
102.1 --- a/src/share/vm/utilities/debug.cpp Tue Dec 21 23:39:42 2010 -0500 102.2 +++ b/src/share/vm/utilities/debug.cpp Wed Dec 22 12:24:40 2010 -0500 102.3 @@ -399,8 +399,14 @@ 102.4 extern "C" void disnm(intptr_t p) { 102.5 Command c("disnm"); 102.6 CodeBlob* cb = CodeCache::find_blob((address) p); 102.7 - cb->print(); 102.8 - Disassembler::decode(cb); 102.9 + nmethod* nm = cb->as_nmethod_or_null(); 102.10 + if (nm) { 102.11 + nm->print(); 102.12 + Disassembler::decode(nm); 102.13 + } else { 102.14 + cb->print(); 102.15 + Disassembler::decode(cb); 102.16 + } 102.17 } 102.18 102.19
103.1 --- a/test/compiler/6991596/Test6991596.java Tue Dec 21 23:39:42 2010 -0500 103.2 +++ b/test/compiler/6991596/Test6991596.java Wed Dec 22 12:24:40 2010 -0500 103.3 @@ -35,7 +35,7 @@ 103.4 public class Test6991596 { 103.5 private static final Class CLASS = Test6991596.class; 103.6 private static final String NAME = "foo"; 103.7 - private static final boolean DEBUG = false; 103.8 + private static final boolean DEBUG = System.getProperty("DEBUG", "false").equals("true"); 103.9 103.10 public static void main(String[] args) throws Throwable { 103.11 testboolean(); 103.12 @@ -47,7 +47,7 @@ 103.13 } 103.14 103.15 // Helpers to get various methods. 103.16 - static MethodHandle getmh1(Class ret, Class arg) { 103.17 + static MethodHandle getmh1(Class ret, Class arg) throws NoAccessException { 103.18 return MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(ret, arg)); 103.19 } 103.20 static MethodHandle getmh2(MethodHandle mh1, Class ret, Class arg) { 103.21 @@ -76,38 +76,38 @@ 103.22 MethodHandle mh2 = getmh2(mh1, boolean.class, boolean.class); 103.23 // TODO add this for all cases when the bugs are fixed. 103.24 //MethodHandle mh3 = getmh3(mh1, boolean.class, boolean.class); 103.25 - boolean a = mh1.<boolean>invokeExact((boolean) x); 103.26 - boolean b = mh2.<boolean>invokeExact(x); 103.27 + boolean a = (boolean) mh1.invokeExact((boolean) x); 103.28 + boolean b = (boolean) mh2.invokeExact(x); 103.29 //boolean c = mh3.<boolean>invokeExact((boolean) x); 103.30 - assert a == b : a + " != " + b; 103.31 - //assert c == x : c + " != " + x; 103.32 + check(x, a, b); 103.33 + //check(x, c, x); 103.34 } 103.35 103.36 // byte 103.37 { 103.38 MethodHandle mh1 = getmh1( byte.class, byte.class ); 103.39 MethodHandle mh2 = getmh2(mh1, byte.class, boolean.class); 103.40 - byte a = mh1.<byte>invokeExact((byte) (x ? 1 : 0)); 103.41 - byte b = mh2.<byte>invokeExact(x); 103.42 - assert a == b : a + " != " + b; 103.43 + byte a = (byte) mh1.invokeExact((byte) (x ? 1 : 0)); 103.44 + byte b = (byte) mh2.invokeExact(x); 103.45 + check(x, a, b); 103.46 } 103.47 103.48 // char 103.49 { 103.50 MethodHandle mh1 = getmh1( char.class, char.class); 103.51 MethodHandle mh2 = getmh2(mh1, char.class, boolean.class); 103.52 - char a = mh1.<char>invokeExact((char) (x ? 1 : 0)); 103.53 - char b = mh2.<char>invokeExact(x); 103.54 - assert a == b : a + " != " + b; 103.55 + char a = (char) mh1.invokeExact((char) (x ? 1 : 0)); 103.56 + char b = (char) mh2.invokeExact(x); 103.57 + check(x, a, b); 103.58 } 103.59 103.60 // short 103.61 { 103.62 MethodHandle mh1 = getmh1( short.class, short.class); 103.63 MethodHandle mh2 = getmh2(mh1, short.class, boolean.class); 103.64 - short a = mh1.<short>invokeExact((short) (x ? 1 : 0)); 103.65 - short b = mh2.<short>invokeExact(x); 103.66 - assert a == b : a + " != " + b; 103.67 + short a = (short) mh1.invokeExact((short) (x ? 1 : 0)); 103.68 + short b = (short) mh2.invokeExact(x); 103.69 + check(x, a, b); 103.70 } 103.71 } 103.72 103.73 @@ -134,36 +134,36 @@ 103.74 { 103.75 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 103.76 MethodHandle mh2 = getmh2(mh1, boolean.class, byte.class); 103.77 - boolean a = mh1.<boolean>invokeExact((x & 1) == 1); 103.78 - boolean b = mh2.<boolean>invokeExact(x); 103.79 - assert a == b : a + " != " + b; 103.80 + boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 103.81 + boolean b = (boolean) mh2.invokeExact(x); 103.82 + check(x, a, b); 103.83 } 103.84 103.85 // byte 103.86 { 103.87 MethodHandle mh1 = getmh1( byte.class, byte.class); 103.88 MethodHandle mh2 = getmh2(mh1, byte.class, byte.class); 103.89 - byte a = mh1.<byte>invokeExact((byte) x); 103.90 - byte b = mh2.<byte>invokeExact(x); 103.91 - assert a == b : a + " != " + b; 103.92 + byte a = (byte) mh1.invokeExact((byte) x); 103.93 + byte b = (byte) mh2.invokeExact(x); 103.94 + check(x, a, b); 103.95 } 103.96 103.97 // char 103.98 { 103.99 MethodHandle mh1 = getmh1( char.class, char.class); 103.100 MethodHandle mh2 = getmh2(mh1, char.class, byte.class); 103.101 - char a = mh1.<char>invokeExact((char) x); 103.102 - char b = mh2.<char>invokeExact(x); 103.103 - assert a == b : a + " != " + b; 103.104 + char a = (char) mh1.invokeExact((char) x); 103.105 + char b = (char) mh2.invokeExact(x); 103.106 + check(x, a, b); 103.107 } 103.108 103.109 // short 103.110 { 103.111 MethodHandle mh1 = getmh1( short.class, short.class); 103.112 MethodHandle mh2 = getmh2(mh1, short.class, byte.class); 103.113 - short a = mh1.<short>invokeExact((short) x); 103.114 - short b = mh2.<short>invokeExact(x); 103.115 - assert a == b : a + " != " + b; 103.116 + short a = (short) mh1.invokeExact((short) x); 103.117 + short b = (short) mh2.invokeExact(x); 103.118 + check(x, a, b); 103.119 } 103.120 } 103.121 103.122 @@ -188,36 +188,36 @@ 103.123 { 103.124 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 103.125 MethodHandle mh2 = getmh2(mh1, boolean.class, char.class); 103.126 - boolean a = mh1.<boolean>invokeExact((x & 1) == 1); 103.127 - boolean b = mh2.<boolean>invokeExact(x); 103.128 - assert a == b : a + " != " + b; 103.129 + boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 103.130 + boolean b = (boolean) mh2.invokeExact(x); 103.131 + check(x, a, b); 103.132 } 103.133 103.134 // byte 103.135 { 103.136 MethodHandle mh1 = getmh1( byte.class, byte.class); 103.137 MethodHandle mh2 = getmh2(mh1, byte.class, char.class); 103.138 - byte a = mh1.<byte>invokeExact((byte) x); 103.139 - byte b = mh2.<byte>invokeExact(x); 103.140 - assert a == b : a + " != " + b; 103.141 + byte a = (byte) mh1.invokeExact((byte) x); 103.142 + byte b = (byte) mh2.invokeExact(x); 103.143 + check(x, a, b); 103.144 } 103.145 103.146 // char 103.147 { 103.148 MethodHandle mh1 = getmh1( char.class, char.class); 103.149 MethodHandle mh2 = getmh2(mh1, char.class, char.class); 103.150 - char a = mh1.<char>invokeExact((char) x); 103.151 - char b = mh2.<char>invokeExact(x); 103.152 - assert a == b : a + " != " + b; 103.153 + char a = (char) mh1.invokeExact((char) x); 103.154 + char b = (char) mh2.invokeExact(x); 103.155 + check(x, a, b); 103.156 } 103.157 103.158 // short 103.159 { 103.160 MethodHandle mh1 = getmh1( short.class, short.class); 103.161 MethodHandle mh2 = getmh2(mh1, short.class, char.class); 103.162 - short a = mh1.<short>invokeExact((short) x); 103.163 - short b = mh2.<short>invokeExact(x); 103.164 - assert a == b : a + " != " + b; 103.165 + short a = (short) mh1.invokeExact((short) x); 103.166 + short b = (short) mh2.invokeExact(x); 103.167 + check(x, a, b); 103.168 } 103.169 } 103.170 103.171 @@ -248,36 +248,36 @@ 103.172 { 103.173 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 103.174 MethodHandle mh2 = getmh2(mh1, boolean.class, short.class); 103.175 - boolean a = mh1.<boolean>invokeExact((x & 1) == 1); 103.176 - boolean b = mh2.<boolean>invokeExact(x); 103.177 - assert a == b : a + " != " + b; 103.178 + boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 103.179 + boolean b = (boolean) mh2.invokeExact(x); 103.180 + check(x, a, b); 103.181 } 103.182 103.183 // byte 103.184 { 103.185 MethodHandle mh1 = getmh1( byte.class, byte.class); 103.186 MethodHandle mh2 = getmh2(mh1, byte.class, short.class); 103.187 - byte a = mh1.<byte>invokeExact((byte) x); 103.188 - byte b = mh2.<byte>invokeExact(x); 103.189 - assert a == b : a + " != " + b; 103.190 + byte a = (byte) mh1.invokeExact((byte) x); 103.191 + byte b = (byte) mh2.invokeExact(x); 103.192 + check(x, a, b); 103.193 } 103.194 103.195 // char 103.196 { 103.197 MethodHandle mh1 = getmh1( char.class, char.class); 103.198 MethodHandle mh2 = getmh2(mh1, char.class, short.class); 103.199 - char a = mh1.<char>invokeExact((char) x); 103.200 - char b = mh2.<char>invokeExact(x); 103.201 - assert a == b : a + " != " + b; 103.202 + char a = (char) mh1.invokeExact((char) x); 103.203 + char b = (char) mh2.invokeExact(x); 103.204 + check(x, a, b); 103.205 } 103.206 103.207 // short 103.208 { 103.209 MethodHandle mh1 = getmh1( short.class, short.class); 103.210 MethodHandle mh2 = getmh2(mh1, short.class, short.class); 103.211 - short a = mh1.<short>invokeExact((short) x); 103.212 - short b = mh2.<short>invokeExact(x); 103.213 - assert a == b : a + " != " + b; 103.214 + short a = (short) mh1.invokeExact((short) x); 103.215 + short b = (short) mh2.invokeExact(x); 103.216 + check(x, a, b); 103.217 } 103.218 } 103.219 103.220 @@ -316,45 +316,46 @@ 103.221 { 103.222 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 103.223 MethodHandle mh2 = getmh2(mh1, boolean.class, int.class); 103.224 - boolean a = mh1.<boolean>invokeExact((x & 1) == 1); 103.225 - boolean b = mh2.<boolean>invokeExact(x); 103.226 - assert a == b : a + " != " + b; 103.227 + boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 103.228 + boolean b = (boolean) mh2.invokeExact(x); 103.229 + check(x, a, b); 103.230 } 103.231 103.232 // byte 103.233 { 103.234 MethodHandle mh1 = getmh1( byte.class, byte.class); 103.235 MethodHandle mh2 = getmh2(mh1, byte.class, int.class); 103.236 - byte a = mh1.<byte>invokeExact((byte) x); 103.237 - byte b = mh2.<byte>invokeExact(x); 103.238 - assert a == b : a + " != " + b; 103.239 + byte a = (byte) mh1.invokeExact((byte) x); 103.240 + byte b = (byte) mh2.invokeExact(x); 103.241 + check(x, a, b); 103.242 } 103.243 103.244 // char 103.245 { 103.246 MethodHandle mh1 = getmh1( char.class, char.class); 103.247 MethodHandle mh2 = getmh2(mh1, char.class, int.class); 103.248 - char a = mh1.<char>invokeExact((char) x); 103.249 - char b = mh2.<char>invokeExact(x); 103.250 - assert a == b : a + " != " + b; 103.251 + char a = (char) mh1.invokeExact((char) x); 103.252 + char b = (char) mh2.invokeExact(x); 103.253 + check(x, a, b); 103.254 } 103.255 103.256 // short 103.257 { 103.258 MethodHandle mh1 = getmh1( short.class, short.class); 103.259 MethodHandle mh2 = getmh2(mh1, short.class, int.class); 103.260 - short a = mh1.<short>invokeExact((short) x); 103.261 - short b = mh2.<short>invokeExact(x); 103.262 + short a = (short) mh1.invokeExact((short) x); 103.263 + short b = (short) mh2.invokeExact(x); 103.264 assert a == b : a + " != " + b; 103.265 + check(x, a, b); 103.266 } 103.267 103.268 // int 103.269 { 103.270 MethodHandle mh1 = getmh1( int.class, int.class); 103.271 MethodHandle mh2 = getmh2(mh1, int.class, int.class); 103.272 - int a = mh1.<int>invokeExact((int) x); 103.273 - int b = mh2.<int>invokeExact(x); 103.274 - assert a == b : a + " != " + b; 103.275 + int a = (int) mh1.invokeExact((int) x); 103.276 + int b = (int) mh2.invokeExact(x); 103.277 + check(x, a, b); 103.278 } 103.279 } 103.280 103.281 @@ -395,48 +396,65 @@ 103.282 { 103.283 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 103.284 MethodHandle mh2 = getmh2(mh1, boolean.class, long.class); 103.285 - boolean a = mh1.<boolean>invokeExact((x & 1L) == 1L); 103.286 - boolean b = mh2.<boolean>invokeExact(x); 103.287 - assert a == b : a + " != " + b; 103.288 + boolean a = (boolean) mh1.invokeExact((x & 1L) == 1L); 103.289 + boolean b = (boolean) mh2.invokeExact(x); 103.290 + check(x, a, b); 103.291 } 103.292 103.293 // byte 103.294 { 103.295 MethodHandle mh1 = getmh1( byte.class, byte.class); 103.296 MethodHandle mh2 = getmh2(mh1, byte.class, long.class); 103.297 - byte a = mh1.<byte>invokeExact((byte) x); 103.298 - byte b = mh2.<byte>invokeExact(x); 103.299 - assert a == b : a + " != " + b; 103.300 + byte a = (byte) mh1.invokeExact((byte) x); 103.301 + byte b = (byte) mh2.invokeExact(x); 103.302 + check(x, a, b); 103.303 } 103.304 103.305 // char 103.306 { 103.307 MethodHandle mh1 = getmh1( char.class, char.class); 103.308 MethodHandle mh2 = getmh2(mh1, char.class, long.class); 103.309 - char a = mh1.<char>invokeExact((char) x); 103.310 - char b = mh2.<char>invokeExact(x); 103.311 - assert a == b : a + " != " + b; 103.312 + char a = (char) mh1.invokeExact((char) x); 103.313 + char b = (char) mh2.invokeExact(x); 103.314 + check(x, a, b); 103.315 } 103.316 103.317 // short 103.318 { 103.319 MethodHandle mh1 = getmh1( short.class, short.class); 103.320 MethodHandle mh2 = getmh2(mh1, short.class, long.class); 103.321 - short a = mh1.<short>invokeExact((short) x); 103.322 - short b = mh2.<short>invokeExact(x); 103.323 - assert a == b : a + " != " + b; 103.324 + short a = (short) mh1.invokeExact((short) x); 103.325 + short b = (short) mh2.invokeExact(x); 103.326 + check(x, a, b); 103.327 } 103.328 103.329 // int 103.330 { 103.331 MethodHandle mh1 = getmh1( int.class, int.class); 103.332 MethodHandle mh2 = getmh2(mh1, int.class, long.class); 103.333 - int a = mh1.<int>invokeExact((int) x); 103.334 - int b = mh2.<int>invokeExact(x); 103.335 - assert a == b : a + " != " + b; 103.336 + int a = (int) mh1.invokeExact((int) x); 103.337 + int b = (int) mh2.invokeExact(x); 103.338 + check(x, a, b); 103.339 } 103.340 + } 103.341 103.342 - } 103.343 + static void check(boolean x, boolean e, boolean a) { p(z2h(x), z2h(e), z2h(a)); assert e == a : z2h(x) + ": " + z2h(e) + " != " + z2h(a); } 103.344 + static void check(boolean x, byte e, byte a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); } 103.345 + static void check(boolean x, int e, int a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); } 103.346 + 103.347 + static void check(int x, boolean e, boolean a) { p(i2h(x), z2h(e), z2h(a)); assert e == a : i2h(x) + ": " + z2h(e) + " != " + z2h(a); } 103.348 + static void check(int x, byte e, byte a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); } 103.349 + static void check(int x, int e, int a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); } 103.350 + 103.351 + static void check(long x, boolean e, boolean a) { p(l2h(x), z2h(e), z2h(a)); assert e == a : l2h(x) + ": " + z2h(e) + " != " + z2h(a); } 103.352 + static void check(long x, byte e, byte a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); } 103.353 + static void check(long x, int e, int a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); } 103.354 + 103.355 + static void p(String x, String e, String a) { if (DEBUG) System.out.println(x + ": expected: " + e + ", actual: " + a); } 103.356 + 103.357 + static String z2h(boolean x) { return x ? "1" : "0"; } 103.358 + static String i2h(int x) { return Integer.toHexString(x); } 103.359 + static String l2h(long x) { return Long.toHexString(x); } 103.360 103.361 // to int 103.362 public static boolean foo(boolean i) { return i; }
104.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 104.2 +++ b/test/compiler/7002666/Test7002666.java Wed Dec 22 12:24:40 2010 -0500 104.3 @@ -0,0 +1,57 @@ 104.4 +/* 104.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 104.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 104.7 + * 104.8 + * This code is free software; you can redistribute it and/or modify it 104.9 + * under the terms of the GNU General Public License version 2 only, as 104.10 + * published by the Free Software Foundation. 104.11 + * 104.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 104.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 104.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 104.15 + * version 2 for more details (a copy is included in the LICENSE file that 104.16 + * accompanied this code). 104.17 + * 104.18 + * You should have received a copy of the GNU General Public License version 104.19 + * 2 along with this work; if not, write to the Free Software Foundation, 104.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 104.21 + * 104.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 104.23 + * or visit www.oracle.com if you need additional information or have any 104.24 + * questions. 104.25 + * 104.26 + */ 104.27 + 104.28 +/** 104.29 + * @test 104.30 + * @bug 7002666 104.31 + * @summary eclipse CDT projects crash with compressed oops 104.32 + * 104.33 + * @run main/othervm -Xbatch -XX:CompileOnly=Test7002666.test,java/lang/reflect/Array Test7002666 104.34 + * 104.35 + * This will only reliably fail with a fastdebug build since it relies 104.36 + * on seeing garbage in the heap to die. It could be made more 104.37 + * reliable in product mode but that would require greatly increasing 104.38 + * the runtime. 104.39 + */ 104.40 + 104.41 +public class Test7002666 { 104.42 + public static void main(String[] args) { 104.43 + for (int i = 0; i < 25000; i++) { 104.44 + Object[] a = test(Test7002666.class, new Test7002666()); 104.45 + if (a[0] != null) { 104.46 + // The element should be null but if it's not then 104.47 + // we've hit the bug. This will most likely crash but 104.48 + // at least throw an exception. 104.49 + System.err.println(a[0]); 104.50 + throw new InternalError(a[0].toString()); 104.51 + 104.52 + } 104.53 + } 104.54 + } 104.55 + public static Object[] test(Class c, Object o) { 104.56 + // allocate an array small enough to be trigger the bug 104.57 + Object[] a = (Object[])java.lang.reflect.Array.newInstance(c, 1); 104.58 + return a; 104.59 + } 104.60 +}