Fri, 15 Oct 2010 15:12:04 -0400
Merge
src/cpu/x86/vm/methodHandles_x86.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp Wed Oct 13 11:46:46 2010 -0400 1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp Fri Oct 15 15:12:04 2010 -0400 1.3 @@ -3094,11 +3094,10 @@ 1.4 void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg, 1.5 Register temp_reg, 1.6 Label& wrong_method_type) { 1.7 - if (UseCompressedOops) unimplemented("coop"); // field accesses must decode 1.8 assert_different_registers(mtype_reg, mh_reg, temp_reg); 1.9 // compare method type against that of the receiver 1.10 RegisterOrConstant mhtype_offset = delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg); 1.11 - ld_ptr(mh_reg, mhtype_offset, temp_reg); 1.12 + load_heap_oop(mh_reg, mhtype_offset, temp_reg); 1.13 cmp(temp_reg, mtype_reg); 1.14 br(Assembler::notEqual, false, Assembler::pn, wrong_method_type); 1.15 delayed()->nop(); 1.16 @@ -3112,16 +3111,15 @@ 1.17 void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, 1.18 Register temp_reg) { 1.19 assert_different_registers(vmslots_reg, mh_reg, temp_reg); 1.20 - if (UseCompressedOops) unimplemented("coop"); // field accesses must decode 1.21 // load mh.type.form.vmslots 1.22 if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) { 1.23 // hoist vmslots into every mh to avoid dependent load chain 1.24 - ld( Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)), vmslots_reg); 1.25 + ld( Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)), vmslots_reg); 1.26 } else { 1.27 Register temp2_reg = vmslots_reg; 1.28 - ld_ptr(Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)), temp2_reg); 1.29 - ld_ptr(Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)), temp2_reg); 1.30 - ld( Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg); 1.31 + load_heap_oop(Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)), temp2_reg); 1.32 + load_heap_oop(Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)), temp2_reg); 1.33 + ld( Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg); 1.34 } 1.35 } 1.36 1.37 @@ -3130,9 +3128,8 @@ 1.38 assert(mh_reg == G3_method_handle, "caller must put MH object in G3"); 1.39 assert_different_registers(mh_reg, temp_reg); 1.40 1.41 - if (UseCompressedOops) unimplemented("coop"); // field accesses must decode 1.42 - 1.43 // pick out the interpreted side of the handler 1.44 + // NOTE: vmentry is not an oop! 1.45 ld_ptr(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg); 1.46 1.47 // off we go... 1.48 @@ -4653,6 +4650,11 @@ 1.49 } 1.50 } 1.51 1.52 +void MacroAssembler::load_heap_oop(Register s1, RegisterOrConstant s2, Register d) { 1.53 + if (s2.is_constant()) load_heap_oop(s1, s2.as_constant(), d); 1.54 + else load_heap_oop(s1, s2.as_register(), d); 1.55 +} 1.56 + 1.57 void MacroAssembler::store_heap_oop(Register d, Register s1, Register s2) { 1.58 if (UseCompressedOops) { 1.59 assert(s1 != d && s2 != d, "not enough registers");
2.1 --- a/src/cpu/sparc/vm/assembler_sparc.hpp Wed Oct 13 11:46:46 2010 -0400 2.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Fri Oct 15 15:12:04 2010 -0400 2.3 @@ -825,6 +825,12 @@ 2.4 // test if -4096 <= x <= 4095 2.5 static bool is_simm13(int x) { return is_simm(x, 13); } 2.6 2.7 + // test if label is in simm16 range in words (wdisp16). 2.8 + bool is_in_wdisp16_range(Label& L) { 2.9 + intptr_t d = intptr_t(pc()) - intptr_t(target(L)); 2.10 + return is_simm(d, 18); 2.11 + } 2.12 + 2.13 enum ASIs { // page 72, v9 2.14 ASI_PRIMARY = 0x80, 2.15 ASI_PRIMARY_LITTLE = 0x88 2.16 @@ -2103,6 +2109,7 @@ 2.17 void load_heap_oop(const Address& s, Register d); 2.18 void load_heap_oop(Register s1, Register s2, Register d); 2.19 void load_heap_oop(Register s1, int simm13a, Register d); 2.20 + void load_heap_oop(Register s1, RegisterOrConstant s2, Register d); 2.21 void store_heap_oop(Register d, Register s1, Register s2); 2.22 void store_heap_oop(Register d, Register s1, int simm13a); 2.23 void store_heap_oop(Register d, const Address& a, int offset = 0); 2.24 @@ -2225,7 +2232,7 @@ 2.25 void stop(const char* msg); // prints msg, dumps registers and stops execution 2.26 void warn(const char* msg); // prints msg, but don't stop 2.27 void untested(const char* what = ""); 2.28 - void unimplemented(const char* what = "") { char* b = new char[1024]; sprintf(b, "unimplemented: %s", what); stop(b); } 2.29 + void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, 1024, "unimplemented: %s", what); stop(b); } 2.30 void should_not_reach_here() { stop("should not reach here"); } 2.31 void print_CPU_state(); 2.32
3.1 --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Wed Oct 13 11:46:46 2010 -0400 3.2 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Fri Oct 15 15:12:04 2010 -0400 3.3 @@ -425,8 +425,13 @@ 3.4 Register pre_val_reg = pre_val()->as_register(); 3.5 3.6 ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false); 3.7 - __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, 3.8 - pre_val_reg, _continuation); 3.9 + if (__ is_in_wdisp16_range(_continuation)) { 3.10 + __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, 3.11 + pre_val_reg, _continuation); 3.12 + } else { 3.13 + __ cmp(pre_val_reg, G0); 3.14 + __ brx(Assembler::equal, false, Assembler::pn, _continuation); 3.15 + } 3.16 __ delayed()->nop(); 3.17 3.18 __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id)); 3.19 @@ -452,8 +457,13 @@ 3.20 assert(new_val()->is_register(), "Precondition."); 3.21 Register addr_reg = addr()->as_pointer_register(); 3.22 Register new_val_reg = new_val()->as_register(); 3.23 - __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, 3.24 - new_val_reg, _continuation); 3.25 + if (__ is_in_wdisp16_range(_continuation)) { 3.26 + __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, 3.27 + new_val_reg, _continuation); 3.28 + } else { 3.29 + __ cmp(new_val_reg, G0); 3.30 + __ brx(Assembler::equal, false, Assembler::pn, _continuation); 3.31 + } 3.32 __ delayed()->nop(); 3.33 3.34 __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_post_barrier_slow_id));
4.1 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Wed Oct 13 11:46:46 2010 -0400 4.2 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Fri Oct 15 15:12:04 2010 -0400 4.3 @@ -664,7 +664,7 @@ 4.4 // Use temps to avoid kills 4.5 LIR_Opr t1 = FrameMap::G1_opr; 4.6 LIR_Opr t2 = FrameMap::G3_opr; 4.7 - LIR_Opr addr = new_pointer_register(); 4.8 + LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register(); 4.9 4.10 // get address of field 4.11 obj.load_item();
5.1 --- a/src/cpu/sparc/vm/c1_LinearScan_sparc.hpp Wed Oct 13 11:46:46 2010 -0400 5.2 +++ b/src/cpu/sparc/vm/c1_LinearScan_sparc.hpp Fri Oct 15 15:12:04 2010 -0400 5.3 @@ -64,7 +64,7 @@ 5.4 _first_reg = pd_first_callee_saved_reg; 5.5 _last_reg = pd_last_callee_saved_reg; 5.6 return true; 5.7 - } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT) { 5.8 + } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT || cur->type() == T_ADDRESS) { 5.9 _first_reg = pd_first_cpu_reg; 5.10 _last_reg = pd_last_allocatable_cpu_reg; 5.11 return true;
6.1 --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp Wed Oct 13 11:46:46 2010 -0400 6.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp Fri Oct 15 15:12:04 2010 -0400 6.3 @@ -27,6 +27,14 @@ 6.4 6.5 #define __ _masm-> 6.6 6.7 +#ifdef PRODUCT 6.8 +#define BLOCK_COMMENT(str) /* nothing */ 6.9 +#else 6.10 +#define BLOCK_COMMENT(str) __ block_comment(str) 6.11 +#endif 6.12 + 6.13 +#define BIND(label) bind(label); BLOCK_COMMENT(#label ":") 6.14 + 6.15 address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm, 6.16 address interpreted_entry) { 6.17 // Just before the actual machine code entry point, allocate space 6.18 @@ -90,8 +98,8 @@ 6.19 } 6.20 6.21 // given the MethodType, find out where the MH argument is buried 6.22 - __ ld_ptr(Address(G5_method_type, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O0_argslot); 6.23 - __ ldsw( Address(O0_argslot, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O0_argslot); 6.24 + __ load_heap_oop(Address(G5_method_type, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O0_argslot); 6.25 + __ ldsw( Address(O0_argslot, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O0_argslot); 6.26 __ ld_ptr(__ argument_address(O0_argslot), G3_method_handle); 6.27 6.28 __ check_method_handle_type(G5_method_type, G3_method_handle, O1_scratch, wrong_method_type); 6.29 @@ -105,6 +113,7 @@ 6.30 static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register temp_reg, const char* error_message) { 6.31 // Verify that argslot lies within (Gargs, FP]. 6.32 Label L_ok, L_bad; 6.33 + BLOCK_COMMENT("{ verify_argslot"); 6.34 #ifdef _LP64 6.35 __ add(FP, STACK_BIAS, temp_reg); 6.36 __ cmp(argslot_reg, temp_reg); 6.37 @@ -119,6 +128,7 @@ 6.38 __ bind(L_bad); 6.39 __ stop(error_message); 6.40 __ bind(L_ok); 6.41 + BLOCK_COMMENT("} verify_argslot"); 6.42 } 6.43 #endif 6.44 6.45 @@ -175,6 +185,7 @@ 6.46 // for (temp = sp + size; temp < argslot; temp++) 6.47 // temp[-size] = temp[0] 6.48 // argslot -= size; 6.49 + BLOCK_COMMENT("insert_arg_slots {"); 6.50 RegisterOrConstant offset = __ regcon_sll_ptr(arg_slots, LogBytesPerWord, temp3_reg); 6.51 6.52 // Keep the stack pointer 2*wordSize aligned. 6.53 @@ -187,7 +198,7 @@ 6.54 6.55 { 6.56 Label loop; 6.57 - __ bind(loop); 6.58 + __ BIND(loop); 6.59 // pull one word down each time through the loop 6.60 __ ld_ptr(Address(temp_reg, 0), temp2_reg); 6.61 __ st_ptr(temp2_reg, Address(temp_reg, offset)); 6.62 @@ -199,6 +210,7 @@ 6.63 6.64 // Now move the argslot down, to point to the opened-up space. 6.65 __ add(argslot_reg, offset, argslot_reg); 6.66 + BLOCK_COMMENT("} insert_arg_slots"); 6.67 } 6.68 6.69 6.70 @@ -235,6 +247,7 @@ 6.71 } 6.72 #endif // ASSERT 6.73 6.74 + BLOCK_COMMENT("remove_arg_slots {"); 6.75 // Pull up everything shallower than argslot. 6.76 // Then remove the excess space on the stack. 6.77 // The stacked return address gets pulled up with everything else. 6.78 @@ -246,7 +259,7 @@ 6.79 __ sub(argslot_reg, wordSize, temp_reg); // source pointer for copy 6.80 { 6.81 Label loop; 6.82 - __ bind(loop); 6.83 + __ BIND(loop); 6.84 // pull one word up each time through the loop 6.85 __ ld_ptr(Address(temp_reg, 0), temp2_reg); 6.86 __ st_ptr(temp2_reg, Address(temp_reg, offset)); 6.87 @@ -265,29 +278,35 @@ 6.88 const int TwoWordAlignmentMask = right_n_bits(LogBytesPerWord + 1); 6.89 RegisterOrConstant masked_offset = __ regcon_andn_ptr(offset, TwoWordAlignmentMask, temp_reg); 6.90 __ add(SP, masked_offset, SP); 6.91 + BLOCK_COMMENT("} remove_arg_slots"); 6.92 } 6.93 6.94 6.95 #ifndef PRODUCT 6.96 extern "C" void print_method_handle(oop mh); 6.97 void trace_method_handle_stub(const char* adaptername, 6.98 - oop mh) { 6.99 -#if 0 6.100 - intptr_t* entry_sp, 6.101 - intptr_t* saved_sp, 6.102 - intptr_t* saved_bp) { 6.103 - // called as a leaf from native code: do not block the JVM! 6.104 - intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset]; 6.105 - intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset]; 6.106 - printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n", 6.107 - adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp); 6.108 - if (last_sp != saved_sp) 6.109 - printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp); 6.110 -#endif 6.111 - 6.112 + oopDesc* mh) { 6.113 printf("MH %s mh="INTPTR_FORMAT"\n", adaptername, (intptr_t) mh); 6.114 print_method_handle(mh); 6.115 } 6.116 +void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { 6.117 + if (!TraceMethodHandles) return; 6.118 + BLOCK_COMMENT("trace_method_handle {"); 6.119 + // save: Gargs, O5_savedSP 6.120 + __ save_frame(16); 6.121 + __ set((intptr_t) adaptername, O0); 6.122 + __ mov(G3_method_handle, O1); 6.123 + __ mov(G3_method_handle, L3); 6.124 + __ mov(Gargs, L4); 6.125 + __ mov(G5_method_type, L5); 6.126 + __ call_VM_leaf(L7, CAST_FROM_FN_PTR(address, trace_method_handle_stub)); 6.127 + 6.128 + __ mov(L3, G3_method_handle); 6.129 + __ mov(L4, Gargs); 6.130 + __ mov(L5, G5_method_type); 6.131 + __ restore(); 6.132 + BLOCK_COMMENT("} trace_method_handle"); 6.133 +} 6.134 #endif // PRODUCT 6.135 6.136 // which conversion op types are implemented here? 6.137 @@ -348,18 +367,8 @@ 6.138 } 6.139 6.140 address interp_entry = __ pc(); 6.141 - if (UseCompressedOops) __ unimplemented("UseCompressedOops"); 6.142 6.143 -#ifndef PRODUCT 6.144 - if (TraceMethodHandles) { 6.145 - // save: Gargs, O5_savedSP 6.146 - __ save(SP, -16*wordSize, SP); 6.147 - __ set((intptr_t) entry_name(ek), O0); 6.148 - __ mov(G3_method_handle, O1); 6.149 - __ call_VM_leaf(Lscratch, CAST_FROM_FN_PTR(address, trace_method_handle_stub)); 6.150 - __ restore(SP, 16*wordSize, SP); 6.151 - } 6.152 -#endif // PRODUCT 6.153 + trace_method_handle(_masm, entry_name(ek)); 6.154 6.155 switch ((int) ek) { 6.156 case _raise_exception: 6.157 @@ -413,7 +422,7 @@ 6.158 case _invokestatic_mh: 6.159 case _invokespecial_mh: 6.160 { 6.161 - __ ld_ptr(G3_mh_vmtarget, G5_method); // target is a methodOop 6.162 + __ load_heap_oop(G3_mh_vmtarget, G5_method); // target is a methodOop 6.163 __ verify_oop(G5_method); 6.164 // Same as TemplateTable::invokestatic or invokespecial, 6.165 // minus the CP setup and profiling: 6.166 @@ -468,7 +477,7 @@ 6.167 // minus the CP setup and profiling: 6.168 __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch); 6.169 Register O1_intf = O1_scratch; 6.170 - __ ld_ptr(G3_mh_vmtarget, O1_intf); 6.171 + __ load_heap_oop(G3_mh_vmtarget, O1_intf); 6.172 __ ldsw(G3_dmh_vmindex, G5_index); 6.173 __ ld_ptr(__ argument_address(O0_argslot, -1), G3_method_handle); 6.174 __ null_check(G3_method_handle, oopDesc::klass_offset_in_bytes()); 6.175 @@ -523,7 +532,7 @@ 6.176 insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, O0_argslot, O1_scratch, O2_scratch, G5_index); 6.177 6.178 // Store bound argument into the new stack slot: 6.179 - __ ld_ptr(G3_bmh_argument, O1_scratch); 6.180 + __ load_heap_oop(G3_bmh_argument, O1_scratch); 6.181 if (arg_type == T_OBJECT) { 6.182 __ st_ptr(O1_scratch, Address(O0_argslot, 0)); 6.183 } else { 6.184 @@ -541,12 +550,12 @@ 6.185 } 6.186 6.187 if (direct_to_method) { 6.188 - __ ld_ptr(G3_mh_vmtarget, G5_method); // target is a methodOop 6.189 + __ load_heap_oop(G3_mh_vmtarget, G5_method); // target is a methodOop 6.190 __ verify_oop(G5_method); 6.191 __ jump_indirect_to(G5_method_fie, O1_scratch); 6.192 __ delayed()->nop(); 6.193 } else { 6.194 - __ ld_ptr(G3_mh_vmtarget, G3_method_handle); // target is a methodOop 6.195 + __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); // target is a methodOop 6.196 __ verify_oop(G3_method_handle); 6.197 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 6.198 } 6.199 @@ -556,7 +565,7 @@ 6.200 case _adapter_retype_only: 6.201 case _adapter_retype_raw: 6.202 // Immediately jump to the next MH layer: 6.203 - __ ld_ptr(G3_mh_vmtarget, G3_method_handle); 6.204 + __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); 6.205 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 6.206 // This is OK when all parameter types widen. 6.207 // It is also OK when a return type narrows. 6.208 @@ -572,8 +581,8 @@ 6.209 Address vmarg = __ argument_address(O0_argslot); 6.210 6.211 // What class are we casting to? 6.212 - __ ld_ptr(G3_amh_argument, G5_klass); // This is a Class object! 6.213 - __ ld_ptr(Address(G5_klass, java_lang_Class::klass_offset_in_bytes()), G5_klass); 6.214 + __ load_heap_oop(G3_amh_argument, G5_klass); // This is a Class object! 6.215 + __ load_heap_oop(Address(G5_klass, java_lang_Class::klass_offset_in_bytes()), G5_klass); 6.216 6.217 Label done; 6.218 __ ld_ptr(vmarg, O1_scratch); 6.219 @@ -590,14 +599,14 @@ 6.220 6.221 // If we get here, the type check failed! 6.222 __ ldsw(G3_amh_vmargslot, O0_argslot); // reload argslot field 6.223 - __ ld_ptr(G3_amh_argument, O3_scratch); // required class 6.224 + __ load_heap_oop(G3_amh_argument, O3_scratch); // required class 6.225 __ ld_ptr(vmarg, O2_scratch); // bad object 6.226 __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot); 6.227 __ delayed()->mov(Bytecodes::_checkcast, O1_scratch); // who is complaining? 6.228 6.229 __ bind(done); 6.230 // Get the new MH: 6.231 - __ ld_ptr(G3_mh_vmtarget, G3_method_handle); 6.232 + __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); 6.233 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 6.234 } 6.235 break; 6.236 @@ -676,7 +685,7 @@ 6.237 __ st(O1_scratch, vmarg); 6.238 6.239 // Get the new MH: 6.240 - __ ld_ptr(G3_mh_vmtarget, G3_method_handle); 6.241 + __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); 6.242 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 6.243 } 6.244 break; 6.245 @@ -721,7 +730,7 @@ 6.246 ShouldNotReachHere(); 6.247 } 6.248 6.249 - __ ld_ptr(G3_mh_vmtarget, G3_method_handle); 6.250 + __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); 6.251 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 6.252 } 6.253 break; 6.254 @@ -851,7 +860,7 @@ 6.255 } 6.256 } 6.257 6.258 - __ ld_ptr(G3_mh_vmtarget, G3_method_handle); 6.259 + __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); 6.260 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 6.261 } 6.262 break; 6.263 @@ -895,7 +904,7 @@ 6.264 __ brx(Assembler::less, false, Assembler::pt, loop); 6.265 __ delayed()->nop(); // FILLME 6.266 6.267 - __ ld_ptr(G3_mh_vmtarget, G3_method_handle); 6.268 + __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); 6.269 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 6.270 } 6.271 break; 6.272 @@ -913,7 +922,7 @@ 6.273 6.274 remove_arg_slots(_masm, G5_stack_move, O0_argslot, O1_scratch, O2_scratch, O3_scratch); 6.275 6.276 - __ ld_ptr(G3_mh_vmtarget, G3_method_handle); 6.277 + __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); 6.278 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 6.279 } 6.280 break;
7.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Oct 13 11:46:46 2010 -0400 7.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri Oct 15 15:12:04 2010 -0400 7.3 @@ -2586,6 +2586,8 @@ 7.4 __ restore(); 7.5 #endif 7.6 7.7 + assert_clean_int(O2_count, G1); // Make sure 'count' is clean int. 7.8 + 7.9 #ifdef ASSERT 7.10 // caller guarantees that the arrays really are different 7.11 // otherwise, we would have to make conjoint checks 7.12 @@ -2600,8 +2602,6 @@ 7.13 } 7.14 #endif //ASSERT 7.15 7.16 - assert_clean_int(O2_count, G1); // Make sure 'count' is clean int. 7.17 - 7.18 checkcast_copy_entry = __ pc(); 7.19 // caller can pass a 64-bit byte count here (from generic stub) 7.20 BLOCK_COMMENT("Entry:");
8.1 --- a/src/cpu/sparc/vm/stubRoutines_sparc.hpp Wed Oct 13 11:46:46 2010 -0400 8.2 +++ b/src/cpu/sparc/vm/stubRoutines_sparc.hpp Fri Oct 15 15:12:04 2010 -0400 8.3 @@ -43,7 +43,7 @@ 8.4 8.5 // MethodHandles adapters 8.6 enum method_handles_platform_dependent_constants { 8.7 - method_handles_adapters_code_size = 12000 8.8 + method_handles_adapters_code_size = 15000 8.9 }; 8.10 8.11 class Sparc {
9.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Oct 13 11:46:46 2010 -0400 9.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Oct 15 15:12:04 2010 -0400 9.3 @@ -3273,7 +3273,7 @@ 9.4 __ sll(Rret, LogBytesPerWord, Rret); 9.5 __ ld_ptr(Rtemp, Rret, Rret); // get return address 9.6 9.7 - __ ld_ptr(G5_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle); 9.8 + __ load_heap_oop(G5_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle); 9.9 __ null_check(G3_method_handle); 9.10 9.11 // Adjust Rret first so Llast_SP can be same as Rret
10.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Wed Oct 13 11:46:46 2010 -0400 10.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Fri Oct 15 15:12:04 2010 -0400 10.3 @@ -7709,9 +7709,14 @@ 10.4 void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg, 10.5 Register temp_reg, 10.6 Label& wrong_method_type) { 10.7 - if (UseCompressedOops) unimplemented(); // field accesses must decode 10.8 + Address type_addr(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)); 10.9 // compare method type against that of the receiver 10.10 - cmpptr(mtype_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); 10.11 + if (UseCompressedOops) { 10.12 + load_heap_oop(temp_reg, type_addr); 10.13 + cmpptr(mtype_reg, temp_reg); 10.14 + } else { 10.15 + cmpptr(mtype_reg, type_addr); 10.16 + } 10.17 jcc(Assembler::notEqual, wrong_method_type); 10.18 } 10.19 10.20 @@ -7723,15 +7728,14 @@ 10.21 void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, 10.22 Register temp_reg) { 10.23 assert_different_registers(vmslots_reg, mh_reg, temp_reg); 10.24 - if (UseCompressedOops) unimplemented(); // field accesses must decode 10.25 // load mh.type.form.vmslots 10.26 if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) { 10.27 // hoist vmslots into every mh to avoid dependent load chain 10.28 movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg))); 10.29 } else { 10.30 Register temp2_reg = vmslots_reg; 10.31 - movptr(temp2_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); 10.32 - movptr(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg))); 10.33 + load_heap_oop(temp2_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); 10.34 + load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg))); 10.35 movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg))); 10.36 } 10.37 } 10.38 @@ -7745,9 +7749,8 @@ 10.39 assert(mh_reg == rcx, "caller must put MH object in rcx"); 10.40 assert_different_registers(mh_reg, temp_reg); 10.41 10.42 - if (UseCompressedOops) unimplemented(); // field accesses must decode 10.43 - 10.44 // pick out the interpreted side of the handler 10.45 + // NOTE: vmentry is not an oop! 10.46 movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg))); 10.47 10.48 // off we go... 10.49 @@ -8238,6 +8241,40 @@ 10.50 movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src); 10.51 } 10.52 10.53 +void MacroAssembler::load_heap_oop(Register dst, Address src) { 10.54 +#ifdef _LP64 10.55 + if (UseCompressedOops) { 10.56 + movl(dst, src); 10.57 + decode_heap_oop(dst); 10.58 + } else 10.59 +#endif 10.60 + movptr(dst, src); 10.61 +} 10.62 + 10.63 +void MacroAssembler::store_heap_oop(Address dst, Register src) { 10.64 +#ifdef _LP64 10.65 + if (UseCompressedOops) { 10.66 + assert(!dst.uses(src), "not enough registers"); 10.67 + encode_heap_oop(src); 10.68 + movl(dst, src); 10.69 + } else 10.70 +#endif 10.71 + movptr(dst, src); 10.72 +} 10.73 + 10.74 +// Used for storing NULLs. 10.75 +void MacroAssembler::store_heap_oop_null(Address dst) { 10.76 +#ifdef _LP64 10.77 + if (UseCompressedOops) { 10.78 + movl(dst, (int32_t)NULL_WORD); 10.79 + } else { 10.80 + movslq(dst, (int32_t)NULL_WORD); 10.81 + } 10.82 +#else 10.83 + movl(dst, (int32_t)NULL_WORD); 10.84 +#endif 10.85 +} 10.86 + 10.87 #ifdef _LP64 10.88 void MacroAssembler::store_klass_gap(Register dst, Register src) { 10.89 if (UseCompressedOops) { 10.90 @@ -8246,34 +8283,6 @@ 10.91 } 10.92 } 10.93 10.94 -void MacroAssembler::load_heap_oop(Register dst, Address src) { 10.95 - if (UseCompressedOops) { 10.96 - movl(dst, src); 10.97 - decode_heap_oop(dst); 10.98 - } else { 10.99 - movq(dst, src); 10.100 - } 10.101 -} 10.102 - 10.103 -void MacroAssembler::store_heap_oop(Address dst, Register src) { 10.104 - if (UseCompressedOops) { 10.105 - assert(!dst.uses(src), "not enough registers"); 10.106 - encode_heap_oop(src); 10.107 - movl(dst, src); 10.108 - } else { 10.109 - movq(dst, src); 10.110 - } 10.111 -} 10.112 - 10.113 -// Used for storing NULLs. 10.114 -void MacroAssembler::store_heap_oop_null(Address dst) { 10.115 - if (UseCompressedOops) { 10.116 - movl(dst, (int32_t)NULL_WORD); 10.117 - } else { 10.118 - movslq(dst, (int32_t)NULL_WORD); 10.119 - } 10.120 -} 10.121 - 10.122 #ifdef ASSERT 10.123 void MacroAssembler::verify_heapbase(const char* msg) { 10.124 assert (UseCompressedOops, "should be compressed");
11.1 --- a/src/cpu/x86/vm/assembler_x86.hpp Wed Oct 13 11:46:46 2010 -0400 11.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp Fri Oct 15 15:12:04 2010 -0400 11.3 @@ -1682,24 +1682,24 @@ 11.4 void load_klass(Register dst, Register src); 11.5 void store_klass(Register dst, Register src); 11.6 11.7 + void load_heap_oop(Register dst, Address src); 11.8 + void store_heap_oop(Address dst, Register src); 11.9 + 11.10 + // Used for storing NULL. All other oop constants should be 11.11 + // stored using routines that take a jobject. 11.12 + void store_heap_oop_null(Address dst); 11.13 + 11.14 void load_prototype_header(Register dst, Register src); 11.15 11.16 #ifdef _LP64 11.17 void store_klass_gap(Register dst, Register src); 11.18 11.19 - void load_heap_oop(Register dst, Address src); 11.20 - void store_heap_oop(Address dst, Register src); 11.21 - 11.22 // This dummy is to prevent a call to store_heap_oop from 11.23 // converting a zero (like NULL) into a Register by giving 11.24 // the compiler two choices it can't resolve 11.25 11.26 void store_heap_oop(Address dst, void* dummy); 11.27 11.28 - // Used for storing NULL. All other oop constants should be 11.29 - // stored using routines that take a jobject. 11.30 - void store_heap_oop_null(Address dst); 11.31 - 11.32 void encode_heap_oop(Register r); 11.33 void decode_heap_oop(Register r); 11.34 void encode_heap_oop_not_null(Register r); 11.35 @@ -1927,7 +1927,7 @@ 11.36 11.37 void untested() { stop("untested"); } 11.38 11.39 - void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, sizeof(b), "unimplemented: %s", what); stop(b); } 11.40 + void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, 1024, "unimplemented: %s", what); stop(b); } 11.41 11.42 void should_not_reach_here() { stop("should not reach here"); } 11.43
12.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Oct 13 11:46:46 2010 -0400 12.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Oct 15 15:12:04 2010 -0400 12.3 @@ -1941,8 +1941,6 @@ 12.4 __ cmpxchgptr(newval, Address(addr, 0)); 12.5 } else if (op->code() == lir_cas_int) { 12.6 __ cmpxchgl(newval, Address(addr, 0)); 12.7 - } else { 12.8 - LP64_ONLY(__ cmpxchgq(newval, Address(addr, 0))); 12.9 } 12.10 #ifdef _LP64 12.11 } else if (op->code() == lir_cas_long) {
13.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Oct 13 11:46:46 2010 -0400 13.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Fri Oct 15 15:12:04 2010 -0400 13.3 @@ -765,7 +765,7 @@ 13.4 ShouldNotReachHere(); 13.5 } 13.6 13.7 - LIR_Opr addr = new_pointer_register(); 13.8 + LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register(); 13.9 LIR_Address* a; 13.10 if(offset.result()->is_constant()) { 13.11 a = new LIR_Address(obj.result(),
14.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp Wed Oct 13 11:46:46 2010 -0400 14.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Fri Oct 15 15:12:04 2010 -0400 14.3 @@ -123,11 +123,9 @@ 14.4 } 14.5 14.6 // given the MethodType, find out where the MH argument is buried 14.7 - __ movptr(rdx_temp, Address(rax_mtype, 14.8 - __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp))); 14.9 + __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp))); 14.10 Register rdx_vmslots = rdx_temp; 14.11 - __ movl(rdx_vmslots, Address(rdx_temp, 14.12 - __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp))); 14.13 + __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp))); 14.14 __ movptr(rcx_recv, __ argument_address(rdx_vmslots)); 14.15 14.16 trace_method_handle(_masm, "invokeExact"); 14.17 @@ -154,20 +152,18 @@ 14.18 rcx_argslot, rbx_temp, rdx_temp); 14.19 14.20 // load up an adapter from the calling type (Java weaves this) 14.21 - __ movptr(rdx_temp, Address(rax_mtype, 14.22 - __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp))); 14.23 + __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp))); 14.24 Register rdx_adapter = rdx_temp; 14.25 - // movptr(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes())); 14.26 + // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes())); 14.27 // deal with old JDK versions: 14.28 - __ lea(rdi_temp, Address(rdx_temp, 14.29 - __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp))); 14.30 + __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp))); 14.31 __ cmpptr(rdi_temp, rdx_temp); 14.32 Label sorry_no_invoke_generic; 14.33 - __ jccb(Assembler::below, sorry_no_invoke_generic); 14.34 + __ jcc(Assembler::below, sorry_no_invoke_generic); 14.35 14.36 - __ movptr(rdx_adapter, Address(rdi_temp, 0)); 14.37 + __ load_heap_oop(rdx_adapter, Address(rdi_temp, 0)); 14.38 __ testptr(rdx_adapter, rdx_adapter); 14.39 - __ jccb(Assembler::zero, sorry_no_invoke_generic); 14.40 + __ jcc(Assembler::zero, sorry_no_invoke_generic); 14.41 __ movptr(Address(rcx_argslot, 1 * Interpreter::stackElementSize), rdx_adapter); 14.42 // As a trusted first argument, pass the type being called, so the adapter knows 14.43 // the actual types of the arguments and return values. 14.44 @@ -431,7 +427,6 @@ 14.45 } 14.46 14.47 address interp_entry = __ pc(); 14.48 - if (UseCompressedOops) __ unimplemented("UseCompressedOops"); 14.49 14.50 trace_method_handle(_masm, entry_name(ek)); 14.51 14.52 @@ -489,7 +484,7 @@ 14.53 case _invokespecial_mh: 14.54 { 14.55 Register rbx_method = rbx_temp; 14.56 - __ movptr(rbx_method, rcx_mh_vmtarget); // target is a methodOop 14.57 + __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop 14.58 __ verify_oop(rbx_method); 14.59 // same as TemplateTable::invokestatic or invokespecial, 14.60 // minus the CP setup and profiling: 14.61 @@ -546,8 +541,8 @@ 14.62 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp); 14.63 Register rdx_intf = rdx_temp; 14.64 Register rbx_index = rbx_temp; 14.65 - __ movptr(rdx_intf, rcx_mh_vmtarget); 14.66 - __ movl(rbx_index, rcx_dmh_vmindex); 14.67 + __ load_heap_oop(rdx_intf, rcx_mh_vmtarget); 14.68 + __ movl(rbx_index, rcx_dmh_vmindex); 14.69 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1)); 14.70 __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes()); 14.71 14.72 @@ -602,7 +597,7 @@ 14.73 rax_argslot, rbx_temp, rdx_temp); 14.74 14.75 // store bound argument into the new stack slot: 14.76 - __ movptr(rbx_temp, rcx_bmh_argument); 14.77 + __ load_heap_oop(rbx_temp, rcx_bmh_argument); 14.78 Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type)); 14.79 if (arg_type == T_OBJECT) { 14.80 __ movptr(Address(rax_argslot, 0), rbx_temp); 14.81 @@ -620,11 +615,11 @@ 14.82 14.83 if (direct_to_method) { 14.84 Register rbx_method = rbx_temp; 14.85 - __ movptr(rbx_method, rcx_mh_vmtarget); 14.86 + __ load_heap_oop(rbx_method, rcx_mh_vmtarget); 14.87 __ verify_oop(rbx_method); 14.88 __ jmp(rbx_method_fie); 14.89 } else { 14.90 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.91 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.92 __ verify_oop(rcx_recv); 14.93 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 14.94 } 14.95 @@ -634,7 +629,7 @@ 14.96 case _adapter_retype_only: 14.97 case _adapter_retype_raw: 14.98 // immediately jump to the next MH layer: 14.99 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.100 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.101 __ verify_oop(rcx_recv); 14.102 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 14.103 // This is OK when all parameter types widen. 14.104 @@ -651,13 +646,13 @@ 14.105 vmarg = __ argument_address(rax_argslot); 14.106 14.107 // What class are we casting to? 14.108 - __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object! 14.109 - __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); 14.110 + __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object! 14.111 + __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); 14.112 14.113 Label done; 14.114 __ movptr(rdx_temp, vmarg); 14.115 __ testptr(rdx_temp, rdx_temp); 14.116 - __ jccb(Assembler::zero, done); // no cast if null 14.117 + __ jcc(Assembler::zero, done); // no cast if null 14.118 __ load_klass(rdx_temp, rdx_temp); 14.119 14.120 // live at this point: 14.121 @@ -672,14 +667,15 @@ 14.122 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field 14.123 __ movptr(rdx_temp, vmarg); 14.124 14.125 - __ pushptr(rcx_amh_argument); // required class 14.126 - __ push(rdx_temp); // bad object 14.127 - __ push((int)Bytecodes::_checkcast); // who is complaining? 14.128 + __ load_heap_oop(rbx_klass, rcx_amh_argument); // required class 14.129 + __ push(rbx_klass); 14.130 + __ push(rdx_temp); // bad object 14.131 + __ push((int)Bytecodes::_checkcast); // who is complaining? 14.132 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 14.133 14.134 __ bind(done); 14.135 // get the new MH: 14.136 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.137 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.138 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 14.139 } 14.140 break; 14.141 @@ -741,7 +737,7 @@ 14.142 assert(CONV_VMINFO_SHIFT == 0, "preshifted"); 14.143 14.144 // get the new MH: 14.145 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.146 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.147 // (now we are done with the old MH) 14.148 14.149 // original 32-bit vmdata word must be of this form: 14.150 @@ -816,7 +812,7 @@ 14.151 ShouldNotReachHere(); 14.152 } 14.153 14.154 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.155 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.156 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 14.157 } 14.158 break; 14.159 @@ -858,7 +854,7 @@ 14.160 rax_argslot, rbx_temp, rdx_temp); 14.161 } 14.162 14.163 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.164 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.165 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 14.166 } 14.167 break; 14.168 @@ -969,7 +965,7 @@ 14.169 } 14.170 } 14.171 14.172 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.173 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.174 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 14.175 } 14.176 break; 14.177 @@ -1029,7 +1025,7 @@ 14.178 14.179 __ pop(rdi); // restore temp 14.180 14.181 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.182 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.183 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 14.184 } 14.185 break; 14.186 @@ -1052,7 +1048,7 @@ 14.187 14.188 __ pop(rdi); // restore temp 14.189 14.190 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.191 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.192 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 14.193 } 14.194 break; 14.195 @@ -1103,8 +1099,8 @@ 14.196 14.197 // Check the array type. 14.198 Register rbx_klass = rbx_temp; 14.199 - __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object! 14.200 - __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); 14.201 + __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object! 14.202 + __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); 14.203 14.204 Label ok_array_klass, bad_array_klass, bad_array_length; 14.205 __ check_klass_subtype(rdx_array_klass, rbx_klass, rdi, ok_array_klass); 14.206 @@ -1186,7 +1182,7 @@ 14.207 14.208 // Arguments are spread. Move to next method handle. 14.209 UNPUSH_RSI_RDI; 14.210 - __ movptr(rcx_recv, rcx_mh_vmtarget); 14.211 + __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 14.212 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 14.213 14.214 __ bind(bad_array_klass);
15.1 --- a/src/cpu/x86/vm/stubRoutines_x86_64.hpp Wed Oct 13 11:46:46 2010 -0400 15.2 +++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp Fri Oct 15 15:12:04 2010 -0400 15.3 @@ -35,7 +35,7 @@ 15.4 15.5 // MethodHandles adapters 15.6 enum method_handles_platform_dependent_constants { 15.7 - method_handles_adapters_code_size = 26000 15.8 + method_handles_adapters_code_size = 40000 15.9 }; 15.10 15.11 class x86 {
16.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Oct 13 11:46:46 2010 -0400 16.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Fri Oct 15 15:12:04 2010 -0400 16.3 @@ -3111,19 +3111,22 @@ 16.4 16.5 // rax: CallSite object (f1) 16.6 // rbx: unused (f2) 16.7 + // rcx: receiver address 16.8 // rdx: flags (unused) 16.9 16.10 + Register rax_callsite = rax; 16.11 + Register rcx_method_handle = rcx; 16.12 + 16.13 if (ProfileInterpreter) { 16.14 - Label L; 16.15 // %%% should make a type profile for any invokedynamic that takes a ref argument 16.16 // profile this call 16.17 __ profile_call(rsi); 16.18 } 16.19 16.20 - __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx))); 16.21 - __ null_check(rcx); 16.22 + __ movptr(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx))); 16.23 + __ null_check(rcx_method_handle); 16.24 __ prepare_to_jump_from_interpreted(); 16.25 - __ jump_to_method_handle_entry(rcx, rdx); 16.26 + __ jump_to_method_handle_entry(rcx_method_handle, rdx); 16.27 } 16.28 16.29 //----------------------------------------------------------------------------------------------------
17.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Oct 13 11:46:46 2010 -0400 17.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Oct 15 15:12:04 2010 -0400 17.3 @@ -3120,17 +3120,19 @@ 17.4 // rcx: receiver address 17.5 // rdx: flags (unused) 17.6 17.7 + Register rax_callsite = rax; 17.8 + Register rcx_method_handle = rcx; 17.9 + 17.10 if (ProfileInterpreter) { 17.11 - Label L; 17.12 // %%% should make a type profile for any invokedynamic that takes a ref argument 17.13 // profile this call 17.14 __ profile_call(r13); 17.15 } 17.16 17.17 - __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx))); 17.18 - __ null_check(rcx); 17.19 + __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx))); 17.20 + __ null_check(rcx_method_handle); 17.21 __ prepare_to_jump_from_interpreted(); 17.22 - __ jump_to_method_handle_entry(rcx, rdx); 17.23 + __ jump_to_method_handle_entry(rcx_method_handle, rdx); 17.24 } 17.25 17.26
18.1 --- a/src/cpu/zero/vm/interpreterRT_zero.hpp Wed Oct 13 11:46:46 2010 -0400 18.2 +++ b/src/cpu/zero/vm/interpreterRT_zero.hpp Fri Oct 15 15:12:04 2010 -0400 18.3 @@ -92,15 +92,15 @@ 18.4 18.5 public: 18.6 SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) 18.7 - : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->code_end()), 18.8 + : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->insts_end()), 18.9 _cb(buffer) { 18.10 - _cb->set_code_end((address) (cif() + 1)); 18.11 + _cb->set_insts_end((address) (cif() + 1)); 18.12 } 18.13 18.14 private: 18.15 void push(intptr_t value) { 18.16 - intptr_t *dst = (intptr_t *) _cb->code_end(); 18.17 - _cb->set_code_end((address) (dst + 1)); 18.18 + intptr_t *dst = (intptr_t *) _cb->insts_end(); 18.19 + _cb->set_insts_end((address) (dst + 1)); 18.20 *dst = value; 18.21 } 18.22 };
19.1 --- a/src/share/vm/asm/codeBuffer.hpp Wed Oct 13 11:46:46 2010 -0400 19.2 +++ b/src/share/vm/asm/codeBuffer.hpp Fri Oct 15 15:12:04 2010 -0400 19.3 @@ -168,8 +168,8 @@ 19.4 bool allocates(address pc) const { return pc >= _start && pc < _limit; } 19.5 bool allocates2(address pc) const { return pc >= _start && pc <= _limit; } 19.6 19.7 - void set_end(address pc) { assert(allocates2(pc),""); _end = pc; } 19.8 - void set_mark(address pc) { assert(contains2(pc),"not in codeBuffer"); 19.9 + void set_end(address pc) { assert(allocates2(pc), err_msg("not in CodeBuffer memory: " PTR_FORMAT " <= " PTR_FORMAT " <= " PTR_FORMAT, _start, pc, _limit)); _end = pc; } 19.10 + void set_mark(address pc) { assert(contains2(pc), "not in codeBuffer"); 19.11 _mark = pc; } 19.12 void set_mark_off(int offset) { assert(contains2(offset+_start),"not in codeBuffer"); 19.13 _mark = offset + _start; }
20.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Wed Oct 13 11:46:46 2010 -0400 20.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Fri Oct 15 15:12:04 2010 -0400 20.3 @@ -1350,6 +1350,7 @@ 20.4 addr = ptr; 20.5 } 20.6 assert(addr->is_register(), "must be a register at this point"); 20.7 + assert(addr->type() == T_OBJECT, "addr should point to an object"); 20.8 20.9 LIR_Opr xor_res = new_pointer_register(); 20.10 LIR_Opr xor_shift_res = new_pointer_register();
21.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp Wed Oct 13 11:46:46 2010 -0400 21.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Fri Oct 15 15:12:04 2010 -0400 21.3 @@ -471,7 +471,7 @@ 21.4 ciField* field = fields->at(i); 21.5 int offset = field->offset_in_bytes(); 21.6 int size = (field->_type == NULL) ? heapOopSize : field->size_in_bytes(); 21.7 - assert(last_offset <= offset, "no field overlap"); 21.8 + assert(last_offset <= offset, err_msg("no field overlap: %d <= %d", last_offset, offset)); 21.9 if (last_offset > (int)sizeof(oopDesc)) 21.10 assert((offset - last_offset) < BytesPerLong, "no big holes"); 21.11 // Note: Two consecutive T_BYTE fields will be separated by wordSize-1
22.1 --- a/src/share/vm/ci/ciTypeFlow.cpp Wed Oct 13 11:46:46 2010 -0400 22.2 +++ b/src/share/vm/ci/ciTypeFlow.cpp Fri Oct 15 15:12:04 2010 -0400 22.3 @@ -1945,7 +1945,7 @@ 22.4 _has_irreducible_entry = false; 22.5 _osr_bci = osr_bci; 22.6 _failure_reason = NULL; 22.7 - assert(start_bci() >= 0 && start_bci() < code_size() , "correct osr_bci argument"); 22.8 + assert(0 <= start_bci() && start_bci() < code_size() , err_msg("correct osr_bci argument: 0 <= %d < %d", start_bci(), code_size())); 22.9 _work_list = NULL; 22.10 22.11 _ciblock_count = _methodBlocks->num_blocks();
23.1 --- a/src/share/vm/classfile/classFileParser.cpp Wed Oct 13 11:46:46 2010 -0400 23.2 +++ b/src/share/vm/classfile/classFileParser.cpp Fri Oct 15 15:12:04 2010 -0400 23.3 @@ -2702,13 +2702,15 @@ 23.4 // Adjust the field type from byte to an unmanaged pointer. 23.5 assert(fac_ptr->nonstatic_byte_count > 0, ""); 23.6 fac_ptr->nonstatic_byte_count -= 1; 23.7 - (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset, 23.8 - word_sig_index); 23.9 - fac_ptr->nonstatic_word_count += 1; 23.10 + 23.11 + (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index); 23.12 + assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64"); 23.13 + if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1; 23.14 + else fac_ptr->nonstatic_word_count += 1; 23.15 23.16 FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i + instanceKlass::low_offset); 23.17 assert(atype == NONSTATIC_BYTE, ""); 23.18 - FieldAllocationType new_atype = NONSTATIC_WORD; 23.19 + FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD; 23.20 (*fields_ptr)->ushort_at_put(i + instanceKlass::low_offset, new_atype); 23.21 23.22 found_vmentry = true;
24.1 --- a/src/share/vm/code/nmethod.cpp Wed Oct 13 11:46:46 2010 -0400 24.2 +++ b/src/share/vm/code/nmethod.cpp Fri Oct 15 15:12:04 2010 -0400 24.3 @@ -1421,7 +1421,7 @@ 24.4 } 24.5 24.6 #ifdef SHARK 24.7 - ((SharkCompiler *) compiler())->free_compiled_method(instructions_begin()); 24.8 + ((SharkCompiler *) compiler())->free_compiled_method(insts_begin()); 24.9 #endif // SHARK 24.10 24.11 ((CodeBlob*)(this))->flush();
25.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Oct 13 11:46:46 2010 -0400 25.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Oct 15 15:12:04 2010 -0400 25.3 @@ -791,7 +791,7 @@ 25.4 int _worker_i; 25.5 public: 25.6 RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, int worker_i = 0) : 25.7 - _cl(g1->g1_rem_set()->as_HRInto_G1RemSet(), worker_i), 25.8 + _cl(g1->g1_rem_set(), worker_i), 25.9 _worker_i(worker_i), 25.10 _g1h(g1) 25.11 { } 25.12 @@ -890,7 +890,7 @@ 25.13 abandon_cur_alloc_region(); 25.14 abandon_gc_alloc_regions(); 25.15 assert(_cur_alloc_region == NULL, "Invariant."); 25.16 - g1_rem_set()->as_HRInto_G1RemSet()->cleanupHRRS(); 25.17 + g1_rem_set()->cleanupHRRS(); 25.18 tear_down_region_lists(); 25.19 set_used_regions_to_need_zero_fill(); 25.20 25.21 @@ -1506,15 +1506,11 @@ 25.22 } 25.23 25.24 // Also create a G1 rem set. 25.25 - if (G1UseHRIntoRS) { 25.26 - if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { 25.27 - _g1_rem_set = new HRInto_G1RemSet(this, (CardTableModRefBS*)mr_bs()); 25.28 - } else { 25.29 - vm_exit_during_initialization("G1 requires a cardtable mod ref bs."); 25.30 - return JNI_ENOMEM; 25.31 - } 25.32 + if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { 25.33 + _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs()); 25.34 } else { 25.35 - _g1_rem_set = new StupidG1RemSet(this); 25.36 + vm_exit_during_initialization("G1 requires a cardtable mod ref bs."); 25.37 + return JNI_ENOMEM; 25.38 } 25.39 25.40 // Carve out the G1 part of the heap. 25.41 @@ -2706,8 +2702,7 @@ 25.42 } 25.43 25.44 size_t G1CollectedHeap::cards_scanned() { 25.45 - HRInto_G1RemSet* g1_rset = (HRInto_G1RemSet*) g1_rem_set(); 25.46 - return g1_rset->cardsScanned(); 25.47 + return g1_rem_set()->cardsScanned(); 25.48 } 25.49 25.50 void 25.51 @@ -3850,6 +3845,54 @@ 25.52 undo_waste() * HeapWordSize / K); 25.53 } 25.54 25.55 +#ifdef ASSERT 25.56 +bool G1ParScanThreadState::verify_ref(narrowOop* ref) const { 25.57 + assert(ref != NULL, "invariant"); 25.58 + assert(UseCompressedOops, "sanity"); 25.59 + assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref)); 25.60 + oop p = oopDesc::load_decode_heap_oop(ref); 25.61 + assert(_g1h->is_in_g1_reserved(p), 25.62 + err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); 25.63 + return true; 25.64 +} 25.65 + 25.66 +bool G1ParScanThreadState::verify_ref(oop* ref) const { 25.67 + assert(ref != NULL, "invariant"); 25.68 + if (has_partial_array_mask(ref)) { 25.69 + // Must be in the collection set--it's already been copied. 25.70 + oop p = clear_partial_array_mask(ref); 25.71 + assert(_g1h->obj_in_cs(p), 25.72 + err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); 25.73 + } else { 25.74 + oop p = oopDesc::load_decode_heap_oop(ref); 25.75 + assert(_g1h->is_in_g1_reserved(p), 25.76 + err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); 25.77 + } 25.78 + return true; 25.79 +} 25.80 + 25.81 +bool G1ParScanThreadState::verify_task(StarTask ref) const { 25.82 + if (ref.is_narrow()) { 25.83 + return verify_ref((narrowOop*) ref); 25.84 + } else { 25.85 + return verify_ref((oop*) ref); 25.86 + } 25.87 +} 25.88 +#endif // ASSERT 25.89 + 25.90 +void G1ParScanThreadState::trim_queue() { 25.91 + StarTask ref; 25.92 + do { 25.93 + // Drain the overflow stack first, so other threads can steal. 25.94 + while (refs()->pop_overflow(ref)) { 25.95 + deal_with_reference(ref); 25.96 + } 25.97 + while (refs()->pop_local(ref)) { 25.98 + deal_with_reference(ref); 25.99 + } 25.100 + } while (!refs()->is_empty()); 25.101 +} 25.102 + 25.103 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) : 25.104 _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()), 25.105 _par_scan_state(par_scan_state) { } 25.106 @@ -4052,38 +4095,39 @@ 25.107 : _g1h(g1h), _par_scan_state(par_scan_state), 25.108 _queues(queues), _terminator(terminator) {} 25.109 25.110 - void do_void() { 25.111 - G1ParScanThreadState* pss = par_scan_state(); 25.112 - while (true) { 25.113 + void do_void(); 25.114 + 25.115 +private: 25.116 + inline bool offer_termination(); 25.117 +}; 25.118 + 25.119 +bool G1ParEvacuateFollowersClosure::offer_termination() { 25.120 + G1ParScanThreadState* const pss = par_scan_state(); 25.121 + pss->start_term_time(); 25.122 + const bool res = terminator()->offer_termination(); 25.123 + pss->end_term_time(); 25.124 + return res; 25.125 +} 25.126 + 25.127 +void G1ParEvacuateFollowersClosure::do_void() { 25.128 + StarTask stolen_task; 25.129 + G1ParScanThreadState* const pss = par_scan_state(); 25.130 + pss->trim_queue(); 25.131 + 25.132 + do { 25.133 + while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { 25.134 + assert(pss->verify_task(stolen_task), "sanity"); 25.135 + if (stolen_task.is_narrow()) { 25.136 + pss->push_on_queue((narrowOop*) stolen_task); 25.137 + } else { 25.138 + pss->push_on_queue((oop*) stolen_task); 25.139 + } 25.140 pss->trim_queue(); 25.141 - 25.142 - StarTask stolen_task; 25.143 - if (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { 25.144 - // slightly paranoid tests; I'm trying to catch potential 25.145 - // problems before we go into push_on_queue to know where the 25.146 - // problem is coming from 25.147 - assert((oop*)stolen_task != NULL, "Error"); 25.148 - if (stolen_task.is_narrow()) { 25.149 - assert(UseCompressedOops, "Error"); 25.150 - narrowOop* p = (narrowOop*) stolen_task; 25.151 - assert(has_partial_array_mask(p) || 25.152 - _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "Error"); 25.153 - pss->push_on_queue(p); 25.154 - } else { 25.155 - oop* p = (oop*) stolen_task; 25.156 - assert(has_partial_array_mask(p) || _g1h->is_in_g1_reserved(*p), "Error"); 25.157 - pss->push_on_queue(p); 25.158 - } 25.159 - continue; 25.160 - } 25.161 - pss->start_term_time(); 25.162 - if (terminator()->offer_termination()) break; 25.163 - pss->end_term_time(); 25.164 } 25.165 - pss->end_term_time(); 25.166 - pss->retire_alloc_buffers(); 25.167 - } 25.168 -}; 25.169 + } while (!offer_termination()); 25.170 + 25.171 + pss->retire_alloc_buffers(); 25.172 +} 25.173 25.174 class G1ParTask : public AbstractGangTask { 25.175 protected: 25.176 @@ -4182,8 +4226,7 @@ 25.177 pss.print_termination_stats(i); 25.178 } 25.179 25.180 - assert(pss.refs_to_scan() == 0, "Task queue should be empty"); 25.181 - assert(pss.overflowed_refs_to_scan() == 0, "Overflow queue should be empty"); 25.182 + assert(pss.refs()->is_empty(), "should be empty"); 25.183 double end_time_ms = os::elapsedTime() * 1000.0; 25.184 _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms); 25.185 }
26.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Oct 13 11:46:46 2010 -0400 26.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Oct 15 15:12:04 2010 -0400 26.3 @@ -1651,49 +1651,17 @@ 26.4 size_t alloc_buffer_waste() const { return _alloc_buffer_waste; } 26.5 size_t undo_waste() const { return _undo_waste; } 26.6 26.7 +#ifdef ASSERT 26.8 + bool verify_ref(narrowOop* ref) const; 26.9 + bool verify_ref(oop* ref) const; 26.10 + bool verify_task(StarTask ref) const; 26.11 +#endif // ASSERT 26.12 + 26.13 template <class T> void push_on_queue(T* ref) { 26.14 - assert(ref != NULL, "invariant"); 26.15 - assert(has_partial_array_mask(ref) || 26.16 - _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(ref)), "invariant"); 26.17 -#ifdef ASSERT 26.18 - if (has_partial_array_mask(ref)) { 26.19 - oop p = clear_partial_array_mask(ref); 26.20 - // Verify that we point into the CS 26.21 - assert(_g1h->obj_in_cs(p), "Should be in CS"); 26.22 - } 26.23 -#endif 26.24 + assert(verify_ref(ref), "sanity"); 26.25 refs()->push(ref); 26.26 } 26.27 26.28 - void pop_from_queue(StarTask& ref) { 26.29 - if (refs()->pop_local(ref)) { 26.30 - assert((oop*)ref != NULL, "pop_local() returned true"); 26.31 - assert(UseCompressedOops || !ref.is_narrow(), "Error"); 26.32 - assert(has_partial_array_mask((oop*)ref) || 26.33 - _g1h->is_in_g1_reserved(ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)ref) 26.34 - : oopDesc::load_decode_heap_oop((oop*)ref)), 26.35 - "invariant"); 26.36 - } else { 26.37 - StarTask null_task; 26.38 - ref = null_task; 26.39 - } 26.40 - } 26.41 - 26.42 - void pop_from_overflow_queue(StarTask& ref) { 26.43 - StarTask new_ref; 26.44 - refs()->pop_overflow(new_ref); 26.45 - assert((oop*)new_ref != NULL, "pop() from a local non-empty stack"); 26.46 - assert(UseCompressedOops || !new_ref.is_narrow(), "Error"); 26.47 - assert(has_partial_array_mask((oop*)new_ref) || 26.48 - _g1h->is_in_g1_reserved(new_ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)new_ref) 26.49 - : oopDesc::load_decode_heap_oop((oop*)new_ref)), 26.50 - "invariant"); 26.51 - ref = new_ref; 26.52 - } 26.53 - 26.54 - int refs_to_scan() { return (int)refs()->size(); } 26.55 - int overflowed_refs_to_scan() { return (int)refs()->overflow_stack()->size(); } 26.56 - 26.57 template <class T> void update_rs(HeapRegion* from, T* p, int tid) { 26.58 if (G1DeferredRSUpdate) { 26.59 deferred_rs_update(from, p, tid); 26.60 @@ -1818,59 +1786,15 @@ 26.61 } 26.62 } 26.63 26.64 -public: 26.65 - void trim_queue() { 26.66 - // I've replicated the loop twice, first to drain the overflow 26.67 - // queue, second to drain the task queue. This is better than 26.68 - // having a single loop, which checks both conditions and, inside 26.69 - // it, either pops the overflow queue or the task queue, as each 26.70 - // loop is tighter. Also, the decision to drain the overflow queue 26.71 - // first is not arbitrary, as the overflow queue is not visible 26.72 - // to the other workers, whereas the task queue is. So, we want to 26.73 - // drain the "invisible" entries first, while allowing the other 26.74 - // workers to potentially steal the "visible" entries. 26.75 - 26.76 - while (refs_to_scan() > 0 || overflowed_refs_to_scan() > 0) { 26.77 - while (overflowed_refs_to_scan() > 0) { 26.78 - StarTask ref_to_scan; 26.79 - assert((oop*)ref_to_scan == NULL, "Constructed above"); 26.80 - pop_from_overflow_queue(ref_to_scan); 26.81 - // We shouldn't have pushed it on the queue if it was not 26.82 - // pointing into the CSet. 26.83 - assert((oop*)ref_to_scan != NULL, "Follows from inner loop invariant"); 26.84 - if (ref_to_scan.is_narrow()) { 26.85 - assert(UseCompressedOops, "Error"); 26.86 - narrowOop* p = (narrowOop*)ref_to_scan; 26.87 - assert(!has_partial_array_mask(p) && 26.88 - _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity"); 26.89 - deal_with_reference(p); 26.90 - } else { 26.91 - oop* p = (oop*)ref_to_scan; 26.92 - assert((has_partial_array_mask(p) && _g1h->is_in_g1_reserved(clear_partial_array_mask(p))) || 26.93 - _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity"); 26.94 - deal_with_reference(p); 26.95 - } 26.96 - } 26.97 - 26.98 - while (refs_to_scan() > 0) { 26.99 - StarTask ref_to_scan; 26.100 - assert((oop*)ref_to_scan == NULL, "Constructed above"); 26.101 - pop_from_queue(ref_to_scan); 26.102 - if ((oop*)ref_to_scan != NULL) { 26.103 - if (ref_to_scan.is_narrow()) { 26.104 - assert(UseCompressedOops, "Error"); 26.105 - narrowOop* p = (narrowOop*)ref_to_scan; 26.106 - assert(!has_partial_array_mask(p) && 26.107 - _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity"); 26.108 - deal_with_reference(p); 26.109 - } else { 26.110 - oop* p = (oop*)ref_to_scan; 26.111 - assert((has_partial_array_mask(p) && _g1h->obj_in_cs(clear_partial_array_mask(p))) || 26.112 - _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity"); 26.113 - deal_with_reference(p); 26.114 - } 26.115 - } 26.116 - } 26.117 + void deal_with_reference(StarTask ref) { 26.118 + assert(verify_task(ref), "sanity"); 26.119 + if (ref.is_narrow()) { 26.120 + deal_with_reference((narrowOop*)ref); 26.121 + } else { 26.122 + deal_with_reference((oop*)ref); 26.123 } 26.124 } 26.125 + 26.126 +public: 26.127 + void trim_queue(); 26.128 };
27.1 --- a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Wed Oct 13 11:46:46 2010 -0400 27.2 +++ b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Fri Oct 15 15:12:04 2010 -0400 27.3 @@ -25,8 +25,6 @@ 27.4 class HeapRegion; 27.5 class G1CollectedHeap; 27.6 class G1RemSet; 27.7 -class HRInto_G1RemSet; 27.8 -class G1RemSet; 27.9 class ConcurrentMark; 27.10 class DirtyCardToOopClosure; 27.11 class CMBitMap;
28.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp Wed Oct 13 11:46:46 2010 -0400 28.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Oct 15 15:12:04 2010 -0400 28.3 @@ -97,13 +97,6 @@ 28.4 } 28.5 }; 28.6 28.7 -void 28.8 -StupidG1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, 28.9 - int worker_i) { 28.10 - IntoCSRegionClosure rc(_g1, oc); 28.11 - _g1->heap_region_iterate(&rc); 28.12 -} 28.13 - 28.14 class VerifyRSCleanCardOopClosure: public OopClosure { 28.15 G1CollectedHeap* _g1; 28.16 public: 28.17 @@ -119,8 +112,9 @@ 28.18 } 28.19 }; 28.20 28.21 -HRInto_G1RemSet::HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs) 28.22 - : G1RemSet(g1), _ct_bs(ct_bs), _g1p(_g1->g1_policy()), 28.23 +G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs) 28.24 + : _g1(g1), _conc_refine_cards(0), 28.25 + _ct_bs(ct_bs), _g1p(_g1->g1_policy()), 28.26 _cg1r(g1->concurrent_g1_refine()), 28.27 _traversal_in_progress(false), 28.28 _cset_rs_update_cl(NULL), 28.29 @@ -134,7 +128,7 @@ 28.30 } 28.31 } 28.32 28.33 -HRInto_G1RemSet::~HRInto_G1RemSet() { 28.34 +G1RemSet::~G1RemSet() { 28.35 delete _seq_task; 28.36 for (uint i = 0; i < n_workers(); i++) { 28.37 assert(_cset_rs_update_cl[i] == NULL, "it should be"); 28.38 @@ -277,7 +271,7 @@ 28.39 // p threads 28.40 // Then thread t will start at region t * floor (n/p) 28.41 28.42 -HeapRegion* HRInto_G1RemSet::calculateStartRegion(int worker_i) { 28.43 +HeapRegion* G1RemSet::calculateStartRegion(int worker_i) { 28.44 HeapRegion* result = _g1p->collection_set(); 28.45 if (ParallelGCThreads > 0) { 28.46 size_t cs_size = _g1p->collection_set_size(); 28.47 @@ -290,7 +284,7 @@ 28.48 return result; 28.49 } 28.50 28.51 -void HRInto_G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) { 28.52 +void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) { 28.53 double rs_time_start = os::elapsedTime(); 28.54 HeapRegion *startRegion = calculateStartRegion(worker_i); 28.55 28.56 @@ -340,7 +334,7 @@ 28.57 } 28.58 }; 28.59 28.60 -void HRInto_G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) { 28.61 +void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) { 28.62 double start = os::elapsedTime(); 28.63 // Apply the given closure to all remaining log entries. 28.64 RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq); 28.65 @@ -439,12 +433,11 @@ 28.66 } 28.67 }; 28.68 28.69 -void HRInto_G1RemSet::cleanupHRRS() { 28.70 +void G1RemSet::cleanupHRRS() { 28.71 HeapRegionRemSet::cleanup(); 28.72 } 28.73 28.74 -void 28.75 -HRInto_G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, 28.76 +void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, 28.77 int worker_i) { 28.78 #if CARD_REPEAT_HISTO 28.79 ct_freq_update_histo_and_reset(); 28.80 @@ -508,8 +501,7 @@ 28.81 _cset_rs_update_cl[worker_i] = NULL; 28.82 } 28.83 28.84 -void HRInto_G1RemSet:: 28.85 -prepare_for_oops_into_collection_set_do() { 28.86 +void G1RemSet::prepare_for_oops_into_collection_set_do() { 28.87 #if G1_REM_SET_LOGGING 28.88 PrintRSClosure cl; 28.89 _g1->collection_set_iterate(&cl); 28.90 @@ -581,7 +573,7 @@ 28.91 // RSet updating, 28.92 // * the post-write barrier shouldn't be logging updates to young 28.93 // regions (but there is a situation where this can happen - see 28.94 - // the comment in HRInto_G1RemSet::concurrentRefineOneCard below - 28.95 + // the comment in G1RemSet::concurrentRefineOneCard below - 28.96 // that should not be applicable here), and 28.97 // * during actual RSet updating, the filtering of cards in young 28.98 // regions in HeapRegion::oops_on_card_seq_iterate_careful is 28.99 @@ -601,7 +593,7 @@ 28.100 } 28.101 }; 28.102 28.103 -void HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do() { 28.104 +void G1RemSet::cleanup_after_oops_into_collection_set_do() { 28.105 guarantee( _cards_scanned != NULL, "invariant" ); 28.106 _total_cards_scanned = 0; 28.107 for (uint i = 0; i < n_workers(); ++i) 28.108 @@ -692,12 +684,12 @@ 28.109 } 28.110 }; 28.111 28.112 -void HRInto_G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) { 28.113 +void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) { 28.114 ScrubRSClosure scrub_cl(region_bm, card_bm); 28.115 _g1->heap_region_iterate(&scrub_cl); 28.116 } 28.117 28.118 -void HRInto_G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm, 28.119 +void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm, 28.120 int worker_num, int claim_val) { 28.121 ScrubRSClosure scrub_cl(region_bm, card_bm); 28.122 _g1->heap_region_par_iterate_chunked(&scrub_cl, worker_num, claim_val); 28.123 @@ -741,7 +733,7 @@ 28.124 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 28.125 }; 28.126 28.127 -bool HRInto_G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i, 28.128 +bool G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i, 28.129 bool check_for_refs_into_cset) { 28.130 // Construct the region representing the card. 28.131 HeapWord* start = _ct_bs->addr_for(card_ptr); 28.132 @@ -820,7 +812,7 @@ 28.133 return trigger_cl.value(); 28.134 } 28.135 28.136 -bool HRInto_G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i, 28.137 +bool G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i, 28.138 bool check_for_refs_into_cset) { 28.139 // If the card is no longer dirty, nothing to do. 28.140 if (*card_ptr != CardTableModRefBS::dirty_card_val()) { 28.141 @@ -995,7 +987,7 @@ 28.142 } 28.143 }; 28.144 28.145 -void HRInto_G1RemSet::print_summary_info() { 28.146 +void G1RemSet::print_summary_info() { 28.147 G1CollectedHeap* g1 = G1CollectedHeap::heap(); 28.148 28.149 #if CARD_REPEAT_HISTO 28.150 @@ -1029,30 +1021,26 @@ 28.151 g1->concurrent_g1_refine()->threads_do(&p); 28.152 gclog_or_tty->print_cr(""); 28.153 28.154 - if (G1UseHRIntoRS) { 28.155 - HRRSStatsIter blk; 28.156 - g1->heap_region_iterate(&blk); 28.157 - gclog_or_tty->print_cr(" Total heap region rem set sizes = " SIZE_FORMAT "K." 28.158 - " Max = " SIZE_FORMAT "K.", 28.159 - blk.total_mem_sz()/K, blk.max_mem_sz()/K); 28.160 - gclog_or_tty->print_cr(" Static structures = " SIZE_FORMAT "K," 28.161 - " free_lists = " SIZE_FORMAT "K.", 28.162 - HeapRegionRemSet::static_mem_size()/K, 28.163 - HeapRegionRemSet::fl_mem_size()/K); 28.164 - gclog_or_tty->print_cr(" %d occupied cards represented.", 28.165 - blk.occupied()); 28.166 - gclog_or_tty->print_cr(" Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )" 28.167 - ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.", 28.168 - blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(), 28.169 - (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K, 28.170 - (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K); 28.171 - gclog_or_tty->print_cr(" Did %d coarsenings.", 28.172 - HeapRegionRemSet::n_coarsenings()); 28.173 - 28.174 - } 28.175 + HRRSStatsIter blk; 28.176 + g1->heap_region_iterate(&blk); 28.177 + gclog_or_tty->print_cr(" Total heap region rem set sizes = " SIZE_FORMAT "K." 28.178 + " Max = " SIZE_FORMAT "K.", 28.179 + blk.total_mem_sz()/K, blk.max_mem_sz()/K); 28.180 + gclog_or_tty->print_cr(" Static structures = " SIZE_FORMAT "K," 28.181 + " free_lists = " SIZE_FORMAT "K.", 28.182 + HeapRegionRemSet::static_mem_size()/K, 28.183 + HeapRegionRemSet::fl_mem_size()/K); 28.184 + gclog_or_tty->print_cr(" %d occupied cards represented.", 28.185 + blk.occupied()); 28.186 + gclog_or_tty->print_cr(" Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )" 28.187 + ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.", 28.188 + blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(), 28.189 + (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K, 28.190 + (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K); 28.191 + gclog_or_tty->print_cr(" Did %d coarsenings.", HeapRegionRemSet::n_coarsenings()); 28.192 } 28.193 28.194 -void HRInto_G1RemSet::prepare_for_verify() { 28.195 +void G1RemSet::prepare_for_verify() { 28.196 if (G1HRRSFlushLogBuffersOnVerify && 28.197 (VerifyBeforeGC || VerifyAfterGC) 28.198 && !_g1->full_collection()) {
29.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp Wed Oct 13 11:46:46 2010 -0400 29.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp Fri Oct 15 15:12:04 2010 -0400 29.3 @@ -27,107 +27,18 @@ 29.4 29.5 class G1CollectedHeap; 29.6 class CardTableModRefBarrierSet; 29.7 -class HRInto_G1RemSet; 29.8 class ConcurrentG1Refine; 29.9 29.10 +// A G1RemSet in which each heap region has a rem set that records the 29.11 +// external heap references into it. Uses a mod ref bs to track updates, 29.12 +// so that they can be used to update the individual region remsets. 29.13 + 29.14 class G1RemSet: public CHeapObj { 29.15 protected: 29.16 G1CollectedHeap* _g1; 29.17 unsigned _conc_refine_cards; 29.18 size_t n_workers(); 29.19 29.20 -public: 29.21 - G1RemSet(G1CollectedHeap* g1) : 29.22 - _g1(g1), _conc_refine_cards(0) 29.23 - {} 29.24 - 29.25 - // Invoke "blk->do_oop" on all pointers into the CS in object in regions 29.26 - // outside the CS (having invoked "blk->set_region" to set the "from" 29.27 - // region correctly beforehand.) The "worker_i" param is for the 29.28 - // parallel case where the number of the worker thread calling this 29.29 - // function can be helpful in partitioning the work to be done. It 29.30 - // should be the same as the "i" passed to the calling thread's 29.31 - // work(i) function. In the sequential case this param will be ingored. 29.32 - virtual void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, 29.33 - int worker_i) = 0; 29.34 - 29.35 - // Prepare for and cleanup after an oops_into_collection_set_do 29.36 - // call. Must call each of these once before and after (in sequential 29.37 - // code) any threads call oops into collection set do. (This offers an 29.38 - // opportunity to sequential setup and teardown of structures needed by a 29.39 - // parallel iteration over the CS's RS.) 29.40 - virtual void prepare_for_oops_into_collection_set_do() = 0; 29.41 - virtual void cleanup_after_oops_into_collection_set_do() = 0; 29.42 - 29.43 - // If "this" is of the given subtype, return "this", else "NULL". 29.44 - virtual HRInto_G1RemSet* as_HRInto_G1RemSet() { return NULL; } 29.45 - 29.46 - // Record, if necessary, the fact that *p (where "p" is in region "from", 29.47 - // and is, a fortiori, required to be non-NULL) has changed to its new value. 29.48 - virtual void write_ref(HeapRegion* from, oop* p) = 0; 29.49 - virtual void write_ref(HeapRegion* from, narrowOop* p) = 0; 29.50 - virtual void par_write_ref(HeapRegion* from, oop* p, int tid) = 0; 29.51 - virtual void par_write_ref(HeapRegion* from, narrowOop* p, int tid) = 0; 29.52 - 29.53 - // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region 29.54 - // or card, respectively, such that a region or card with a corresponding 29.55 - // 0 bit contains no part of any live object. Eliminates any remembered 29.56 - // set entries that correspond to dead heap ranges. 29.57 - virtual void scrub(BitMap* region_bm, BitMap* card_bm) = 0; 29.58 - // Like the above, but assumes is called in parallel: "worker_num" is the 29.59 - // parallel thread id of the current thread, and "claim_val" is the 29.60 - // value that should be used to claim heap regions. 29.61 - virtual void scrub_par(BitMap* region_bm, BitMap* card_bm, 29.62 - int worker_num, int claim_val) = 0; 29.63 - 29.64 - // Refine the card corresponding to "card_ptr". If "sts" is non-NULL, 29.65 - // join and leave around parts that must be atomic wrt GC. (NULL means 29.66 - // being done at a safepoint.) 29.67 - // With some implementations of this routine, when check_for_refs_into_cset 29.68 - // is true, a true result may be returned if the given card contains oops 29.69 - // that have references into the current collection set. 29.70 - virtual bool concurrentRefineOneCard(jbyte* card_ptr, int worker_i, 29.71 - bool check_for_refs_into_cset) { 29.72 - return false; 29.73 - } 29.74 - 29.75 - // Print any relevant summary info. 29.76 - virtual void print_summary_info() {} 29.77 - 29.78 - // Prepare remebered set for verification. 29.79 - virtual void prepare_for_verify() {}; 29.80 -}; 29.81 - 29.82 - 29.83 -// The simplest possible G1RemSet: iterates over all objects in non-CS 29.84 -// regions, searching for pointers into the CS. 29.85 -class StupidG1RemSet: public G1RemSet { 29.86 -public: 29.87 - StupidG1RemSet(G1CollectedHeap* g1) : G1RemSet(g1) {} 29.88 - 29.89 - void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, 29.90 - int worker_i); 29.91 - 29.92 - void prepare_for_oops_into_collection_set_do() {} 29.93 - void cleanup_after_oops_into_collection_set_do() {} 29.94 - 29.95 - // Nothing is necessary in the version below. 29.96 - void write_ref(HeapRegion* from, oop* p) {} 29.97 - void write_ref(HeapRegion* from, narrowOop* p) {} 29.98 - void par_write_ref(HeapRegion* from, oop* p, int tid) {} 29.99 - void par_write_ref(HeapRegion* from, narrowOop* p, int tid) {} 29.100 - 29.101 - void scrub(BitMap* region_bm, BitMap* card_bm) {} 29.102 - void scrub_par(BitMap* region_bm, BitMap* card_bm, 29.103 - int worker_num, int claim_val) {} 29.104 - 29.105 -}; 29.106 - 29.107 -// A G1RemSet in which each heap region has a rem set that records the 29.108 -// external heap references into it. Uses a mod ref bs to track updates, 29.109 -// so that they can be used to update the individual region remsets. 29.110 - 29.111 -class HRInto_G1RemSet: public G1RemSet { 29.112 protected: 29.113 enum SomePrivateConstants { 29.114 UpdateRStoMergeSync = 0, 29.115 @@ -175,28 +86,32 @@ 29.116 // scanned. 29.117 void cleanupHRRS(); 29.118 29.119 - HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs); 29.120 - ~HRInto_G1RemSet(); 29.121 + G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs); 29.122 + ~G1RemSet(); 29.123 29.124 + // Invoke "blk->do_oop" on all pointers into the CS in objects in regions 29.125 + // outside the CS (having invoked "blk->set_region" to set the "from" 29.126 + // region correctly beforehand.) The "worker_i" param is for the 29.127 + // parallel case where the number of the worker thread calling this 29.128 + // function can be helpful in partitioning the work to be done. It 29.129 + // should be the same as the "i" passed to the calling thread's 29.130 + // work(i) function. In the sequential case this param will be ingored. 29.131 void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, 29.132 int worker_i); 29.133 29.134 + // Prepare for and cleanup after an oops_into_collection_set_do 29.135 + // call. Must call each of these once before and after (in sequential 29.136 + // code) any threads call oops_into_collection_set_do. (This offers an 29.137 + // opportunity to sequential setup and teardown of structures needed by a 29.138 + // parallel iteration over the CS's RS.) 29.139 void prepare_for_oops_into_collection_set_do(); 29.140 void cleanup_after_oops_into_collection_set_do(); 29.141 + 29.142 void scanRS(OopsInHeapRegionClosure* oc, int worker_i); 29.143 - template <class T> void scanNewRefsRS_work(OopsInHeapRegionClosure* oc, int worker_i); 29.144 - void scanNewRefsRS(OopsInHeapRegionClosure* oc, int worker_i) { 29.145 - if (UseCompressedOops) { 29.146 - scanNewRefsRS_work<narrowOop>(oc, worker_i); 29.147 - } else { 29.148 - scanNewRefsRS_work<oop>(oc, worker_i); 29.149 - } 29.150 - } 29.151 void updateRS(DirtyCardQueue* into_cset_dcq, int worker_i); 29.152 + 29.153 HeapRegion* calculateStartRegion(int i); 29.154 29.155 - HRInto_G1RemSet* as_HRInto_G1RemSet() { return this; } 29.156 - 29.157 CardTableModRefBS* ct_bs() { return _ct_bs; } 29.158 size_t cardsScanned() { return _total_cards_scanned; } 29.159 29.160 @@ -219,17 +134,31 @@ 29.161 29.162 bool self_forwarded(oop obj); 29.163 29.164 + // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region 29.165 + // or card, respectively, such that a region or card with a corresponding 29.166 + // 0 bit contains no part of any live object. Eliminates any remembered 29.167 + // set entries that correspond to dead heap ranges. 29.168 void scrub(BitMap* region_bm, BitMap* card_bm); 29.169 + 29.170 + // Like the above, but assumes is called in parallel: "worker_num" is the 29.171 + // parallel thread id of the current thread, and "claim_val" is the 29.172 + // value that should be used to claim heap regions. 29.173 void scrub_par(BitMap* region_bm, BitMap* card_bm, 29.174 int worker_num, int claim_val); 29.175 29.176 - // If check_for_refs_into_cset is true then a true result is returned 29.177 - // if the card contains oops that have references into the current 29.178 - // collection set. 29.179 + // Refine the card corresponding to "card_ptr". If "sts" is non-NULL, 29.180 + // join and leave around parts that must be atomic wrt GC. (NULL means 29.181 + // being done at a safepoint.) 29.182 + // If check_for_refs_into_cset is true, a true result is returned 29.183 + // if the given card contains oops that have references into the 29.184 + // current collection set. 29.185 virtual bool concurrentRefineOneCard(jbyte* card_ptr, int worker_i, 29.186 bool check_for_refs_into_cset); 29.187 29.188 + // Print any relevant summary info. 29.189 virtual void print_summary_info(); 29.190 + 29.191 + // Prepare remembered set for verification. 29.192 virtual void prepare_for_verify(); 29.193 }; 29.194 29.195 @@ -250,13 +179,13 @@ 29.196 29.197 class UpdateRSOopClosure: public OopClosure { 29.198 HeapRegion* _from; 29.199 - HRInto_G1RemSet* _rs; 29.200 + G1RemSet* _rs; 29.201 int _worker_i; 29.202 29.203 template <class T> void do_oop_work(T* p); 29.204 29.205 public: 29.206 - UpdateRSOopClosure(HRInto_G1RemSet* rs, int worker_i = 0) : 29.207 + UpdateRSOopClosure(G1RemSet* rs, int worker_i = 0) : 29.208 _from(NULL), _rs(rs), _worker_i(worker_i) { 29.209 guarantee(_rs != NULL, "Requires an HRIntoG1RemSet"); 29.210 }
30.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp Wed Oct 13 11:46:46 2010 -0400 30.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp Fri Oct 15 15:12:04 2010 -0400 30.3 @@ -30,16 +30,18 @@ 30.4 } 30.5 } 30.6 30.7 -template <class T> inline void HRInto_G1RemSet::write_ref_nv(HeapRegion* from, T* p) { 30.8 +template <class T> 30.9 +inline void G1RemSet::write_ref_nv(HeapRegion* from, T* p) { 30.10 par_write_ref_nv(from, p, 0); 30.11 } 30.12 30.13 -inline bool HRInto_G1RemSet::self_forwarded(oop obj) { 30.14 +inline bool G1RemSet::self_forwarded(oop obj) { 30.15 bool result = (obj->is_forwarded() && (obj->forwardee()== obj)); 30.16 return result; 30.17 } 30.18 30.19 -template <class T> inline void HRInto_G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) { 30.20 +template <class T> 30.21 +inline void G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) { 30.22 oop obj = oopDesc::load_decode_heap_oop(p); 30.23 #ifdef ASSERT 30.24 // can't do because of races 30.25 @@ -77,7 +79,7 @@ 30.26 // Deferred updates to the CSet are either discarded (in the normal case), 30.27 // or processed (if an evacuation failure occurs) at the end 30.28 // of the collection. 30.29 - // See HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do(). 30.30 + // See G1RemSet::cleanup_after_oops_into_collection_set_do(). 30.31 } else { 30.32 #if G1_REM_SET_LOGGING 30.33 gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS" 30.34 @@ -91,12 +93,14 @@ 30.35 } 30.36 } 30.37 30.38 -template <class T> inline void UpdateRSOopClosure::do_oop_work(T* p) { 30.39 +template <class T> 30.40 +inline void UpdateRSOopClosure::do_oop_work(T* p) { 30.41 assert(_from != NULL, "from region must be non-NULL"); 30.42 _rs->par_write_ref(_from, p, _worker_i); 30.43 } 30.44 30.45 -template <class T> inline void UpdateRSetImmediate::do_oop_work(T* p) { 30.46 +template <class T> 30.47 +inline void UpdateRSetImmediate::do_oop_work(T* p) { 30.48 assert(_from->is_in_reserved(p), "paranoia"); 30.49 T heap_oop = oopDesc::load_heap_oop(p); 30.50 if (!oopDesc::is_null(heap_oop) && !_from->is_survivor()) {
31.1 --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Oct 13 11:46:46 2010 -0400 31.2 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Oct 15 15:12:04 2010 -0400 31.3 @@ -40,9 +40,6 @@ 31.4 develop(intx, G1PolicyVerbose, 0, \ 31.5 "The verbosity level on G1 policy decisions") \ 31.6 \ 31.7 - develop(bool, G1UseHRIntoRS, true, \ 31.8 - "Determines whether the 'advanced' HR Into rem set is used.") \ 31.9 - \ 31.10 develop(intx, G1MarkingVerboseLevel, 0, \ 31.11 "Level (0-4) of verboseness of the marking code") \ 31.12 \
32.1 --- a/src/share/vm/gc_implementation/includeDB_gc_g1 Wed Oct 13 11:46:46 2010 -0400 32.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_g1 Fri Oct 15 15:12:04 2010 -0400 32.3 @@ -310,10 +310,16 @@ 32.4 32.5 heapRegionSeq.inline.hpp heapRegionSeq.hpp 32.6 32.7 +instanceKlass.cpp g1RemSet.inline.hpp 32.8 + 32.9 +instanceRefKlass.cpp g1RemSet.inline.hpp 32.10 + 32.11 klass.hpp g1OopClosures.hpp 32.12 32.13 memoryService.cpp g1MemoryPool.hpp 32.14 32.15 +objArrayKlass.cpp g1RemSet.inline.hpp 32.16 + 32.17 ptrQueue.cpp allocation.hpp 32.18 ptrQueue.cpp allocation.inline.hpp 32.19 ptrQueue.cpp mutex.hpp
33.1 --- a/src/share/vm/oops/methodOop.cpp Wed Oct 13 11:46:46 2010 -0400 33.2 +++ b/src/share/vm/oops/methodOop.cpp Fri Oct 15 15:12:04 2010 -0400 33.3 @@ -758,7 +758,7 @@ 33.4 33.5 OrderAccess::storestore(); 33.6 #ifdef SHARK 33.7 - mh->_from_interpreted_entry = code->instructions_begin(); 33.8 + mh->_from_interpreted_entry = code->insts_begin(); 33.9 #else 33.10 mh->_from_compiled_entry = code->verified_entry_point(); 33.11 OrderAccess::storestore();
34.1 --- a/src/share/vm/oops/oop.inline.hpp Wed Oct 13 11:46:46 2010 -0400 34.2 +++ b/src/share/vm/oops/oop.inline.hpp Fri Oct 15 15:12:04 2010 -0400 34.3 @@ -173,7 +173,7 @@ 34.4 address base = Universe::narrow_oop_base(); 34.5 int shift = Universe::narrow_oop_shift(); 34.6 oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift)); 34.7 - assert(check_obj_alignment(result), "Address not aligned"); 34.8 + assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result)); 34.9 return result; 34.10 } 34.11
35.1 --- a/src/share/vm/opto/library_call.cpp Wed Oct 13 11:46:46 2010 -0400 35.2 +++ b/src/share/vm/opto/library_call.cpp Fri Oct 15 15:12:04 2010 -0400 35.3 @@ -4761,7 +4761,7 @@ 35.4 Node* cv = generate_checkcast_arraycopy(adr_type, 35.5 dest_elem_klass, 35.6 src, src_offset, dest, dest_offset, 35.7 - copy_length); 35.8 + ConvI2X(copy_length)); 35.9 if (cv == NULL) cv = intcon(-1); // failure (no stub available) 35.10 checked_control = control(); 35.11 checked_i_o = i_o(); 35.12 @@ -5206,7 +5206,7 @@ 35.13 int sco_offset = Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc); 35.14 Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset); 35.15 Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr()); 35.16 - Node* check_offset = _gvn.transform(n3); 35.17 + Node* check_offset = ConvI2X(_gvn.transform(n3)); 35.18 Node* check_value = dest_elem_klass; 35.19 35.20 Node* src_start = array_element_address(src, src_offset, T_OBJECT);
36.1 --- a/src/share/vm/opto/loopTransform.cpp Wed Oct 13 11:46:46 2010 -0400 36.2 +++ b/src/share/vm/opto/loopTransform.cpp Fri Oct 15 15:12:04 2010 -0400 36.3 @@ -2684,7 +2684,14 @@ 36.4 fill_name, TypeAryPtr::get_array_body_type(t)); 36.5 call->init_req(TypeFunc::Parms+0, from); 36.6 call->init_req(TypeFunc::Parms+1, store_value); 36.7 +#ifdef _LP64 36.8 + len = new (C, 2) ConvI2LNode(len); 36.9 + _igvn.register_new_node_with_optimizer(len); 36.10 +#endif 36.11 call->init_req(TypeFunc::Parms+2, len); 36.12 +#ifdef _LP64 36.13 + call->init_req(TypeFunc::Parms+3, C->top()); 36.14 +#endif 36.15 call->init_req( TypeFunc::Control, head->init_control()); 36.16 call->init_req( TypeFunc::I_O , C->top() ) ; // does no i/o 36.17 call->init_req( TypeFunc::Memory , mem_phi->in(LoopNode::EntryControl) );
37.1 --- a/src/share/vm/opto/runtime.cpp Wed Oct 13 11:46:46 2010 -0400 37.2 +++ b/src/share/vm/opto/runtime.cpp Fri Oct 15 15:12:04 2010 -0400 37.3 @@ -646,12 +646,14 @@ 37.4 37.5 37.6 const TypeFunc* OptoRuntime::array_fill_Type() { 37.7 - // create input type (domain) 37.8 - const Type** fields = TypeTuple::fields(3); 37.9 - fields[TypeFunc::Parms+0] = TypePtr::NOTNULL; 37.10 - fields[TypeFunc::Parms+1] = TypeInt::INT; 37.11 - fields[TypeFunc::Parms+2] = TypeInt::INT; 37.12 - const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 3, fields); 37.13 + // create input type (domain): pointer, int, size_t 37.14 + const Type** fields = TypeTuple::fields(3 LP64_ONLY( + 1)); 37.15 + int argp = TypeFunc::Parms; 37.16 + fields[argp++] = TypePtr::NOTNULL; 37.17 + fields[argp++] = TypeInt::INT; 37.18 + fields[argp++] = TypeX_X; // size in whatevers (size_t) 37.19 + LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length 37.20 + const TypeTuple *domain = TypeTuple::make(argp, fields); 37.21 37.22 // create result type 37.23 fields = TypeTuple::fields(1);
38.1 --- a/src/share/vm/prims/methodHandles.cpp Wed Oct 13 11:46:46 2010 -0400 38.2 +++ b/src/share/vm/prims/methodHandles.cpp Fri Oct 15 15:12:04 2010 -0400 38.3 @@ -1568,7 +1568,7 @@ 38.4 if (ptype != T_INT) { 38.5 int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT); 38.6 jint value = argument->int_field(value_offset); 38.7 - int vminfo = adapter_subword_vminfo(ptype); 38.8 + int vminfo = adapter_unbox_subword_vminfo(ptype); 38.9 jint subword = truncate_subword_from_vminfo(value, vminfo); 38.10 if (value != subword) { 38.11 err = "bound subword value does not fit into the subword type"; 38.12 @@ -2018,12 +2018,12 @@ 38.13 assert(src == T_INT || is_subword_type(src), "source is not float"); 38.14 // Subword-related cases are int -> {boolean,byte,char,short}. 38.15 ek_opt = _adapter_opt_i2i; 38.16 - vminfo = adapter_subword_vminfo(dest); 38.17 + vminfo = adapter_prim_to_prim_subword_vminfo(dest); 38.18 break; 38.19 case 2 *4+ 1: 38.20 if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) { 38.21 ek_opt = _adapter_opt_l2i; 38.22 - vminfo = adapter_subword_vminfo(dest); 38.23 + vminfo = adapter_prim_to_prim_subword_vminfo(dest); 38.24 } else if (src == T_DOUBLE && dest == T_FLOAT) { 38.25 ek_opt = _adapter_opt_d2f; 38.26 } else { 38.27 @@ -2051,7 +2051,7 @@ 38.28 switch (type2size[dest]) { 38.29 case 1: 38.30 ek_opt = _adapter_opt_unboxi; 38.31 - vminfo = adapter_subword_vminfo(dest); 38.32 + vminfo = adapter_unbox_subword_vminfo(dest); 38.33 break; 38.34 case 2: 38.35 ek_opt = _adapter_opt_unboxl;
39.1 --- a/src/share/vm/prims/methodHandles.hpp Wed Oct 13 11:46:46 2010 -0400 39.2 +++ b/src/share/vm/prims/methodHandles.hpp Fri Oct 15 15:12:04 2010 -0400 39.3 @@ -226,11 +226,20 @@ 39.4 } 39.5 39.6 enum { CONV_VMINFO_SIGN_FLAG = 0x80 }; 39.7 - static int adapter_subword_vminfo(BasicType dest) { 39.8 - if (dest == T_BOOLEAN) return (BitsPerInt - 1); 39.9 - if (dest == T_CHAR) return (BitsPerInt - 16); 39.10 - if (dest == T_BYTE) return (BitsPerInt - 8) | CONV_VMINFO_SIGN_FLAG; 39.11 - if (dest == T_SHORT) return (BitsPerInt - 16) | CONV_VMINFO_SIGN_FLAG; 39.12 + // Shift values for prim-to-prim conversions. 39.13 + static int adapter_prim_to_prim_subword_vminfo(BasicType dest) { 39.14 + if (dest == T_BOOLEAN) return (BitsPerInt - 1); // boolean is 1 bit 39.15 + if (dest == T_CHAR) return (BitsPerInt - BitsPerShort); 39.16 + if (dest == T_BYTE) return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG; 39.17 + if (dest == T_SHORT) return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG; 39.18 + return 0; // case T_INT 39.19 + } 39.20 + // Shift values for unboxing a primitive. 39.21 + static int adapter_unbox_subword_vminfo(BasicType dest) { 39.22 + if (dest == T_BOOLEAN) return (BitsPerInt - BitsPerByte ); // implemented as 1 byte 39.23 + if (dest == T_CHAR) return (BitsPerInt - BitsPerShort); 39.24 + if (dest == T_BYTE) return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG; 39.25 + if (dest == T_SHORT) return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG; 39.26 return 0; // case T_INT 39.27 } 39.28 // Here is the transformation the i2i adapter must perform:
40.1 --- a/src/share/vm/shark/sharkCompiler.hpp Wed Oct 13 11:46:46 2010 -0400 40.2 +++ b/src/share/vm/shark/sharkCompiler.hpp Fri Oct 15 15:12:04 2010 -0400 40.3 @@ -103,8 +103,7 @@ 40.4 // Global access 40.5 public: 40.6 static SharkCompiler* compiler() { 40.7 - AbstractCompiler *compiler = 40.8 - CompileBroker::compiler(CompLevel_fast_compile); 40.9 + AbstractCompiler *compiler = CompileBroker::compiler(CompLevel_simple); 40.10 assert(compiler->is_shark() && compiler->is_initialized(), "should be"); 40.11 return (SharkCompiler *) compiler; 40.12 }
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/test/compiler/6987555/Test6987555.java Fri Oct 15 15:12:04 2010 -0400 41.3 @@ -0,0 +1,177 @@ 41.4 +/* 41.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 41.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41.7 + * 41.8 + * This code is free software; you can redistribute it and/or modify it 41.9 + * under the terms of the GNU General Public License version 2 only, as 41.10 + * published by the Free Software Foundation. 41.11 + * 41.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 41.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 41.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 41.15 + * version 2 for more details (a copy is included in the LICENSE file that 41.16 + * accompanied this code). 41.17 + * 41.18 + * You should have received a copy of the GNU General Public License version 41.19 + * 2 along with this work; if not, write to the Free Software Foundation, 41.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 41.21 + * 41.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 41.23 + * or visit www.oracle.com if you need additional information or have any 41.24 + * questions. 41.25 + * 41.26 + */ 41.27 + 41.28 +/** 41.29 + * @test 41.30 + * @bug 6987555 41.31 + * @summary JSR 292 unboxing to a boolean value fails on big-endian SPARC 41.32 + * 41.33 + * @run main/othervm -Xint -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6987555 41.34 + */ 41.35 + 41.36 +import java.dyn.*; 41.37 + 41.38 +public class Test6987555 { 41.39 + private static final Class CLASS = Test6987555.class; 41.40 + private static final String NAME = "foo"; 41.41 + private static final boolean DEBUG = false; 41.42 + 41.43 + public static void main(String[] args) throws Throwable { 41.44 + testboolean(); 41.45 + testbyte(); 41.46 + testchar(); 41.47 + testshort(); 41.48 + testint(); 41.49 + } 41.50 + 41.51 + // boolean 41.52 + static void testboolean() throws Throwable { 41.53 + doboolean(false); 41.54 + doboolean(true); 41.55 + } 41.56 + static void doboolean(boolean x) throws Throwable { 41.57 + if (DEBUG) System.out.println("boolean=" + x); 41.58 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(boolean.class, boolean.class)); 41.59 + MethodHandle mh2 = mh1.asType(MethodType.methodType(boolean.class, Boolean.class)); 41.60 + boolean a = mh1.<boolean>invokeExact(x); 41.61 + boolean b = mh2.<boolean>invokeExact(Boolean.valueOf(x)); 41.62 + assert a == b : a + " != " + b; 41.63 + } 41.64 + 41.65 + // byte 41.66 + static void testbyte() throws Throwable { 41.67 + byte[] a = new byte[] { 41.68 + Byte.MIN_VALUE, 41.69 + Byte.MIN_VALUE + 1, 41.70 + -0x0F, 41.71 + -1, 41.72 + 0, 41.73 + 1, 41.74 + 0x0F, 41.75 + Byte.MAX_VALUE - 1, 41.76 + Byte.MAX_VALUE 41.77 + }; 41.78 + for (int i = 0; i < a.length; i++) { 41.79 + dobyte(a[i]); 41.80 + } 41.81 + } 41.82 + static void dobyte(byte x) throws Throwable { 41.83 + if (DEBUG) System.out.println("byte=" + x); 41.84 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(byte.class, byte.class)); 41.85 + MethodHandle mh2 = mh1.asType(MethodType.methodType(byte.class, Byte.class)); 41.86 + byte a = mh1.<byte>invokeExact(x); 41.87 + byte b = mh2.<byte>invokeExact(Byte.valueOf(x)); 41.88 + assert a == b : a + " != " + b; 41.89 + } 41.90 + 41.91 + // char 41.92 + static void testchar() throws Throwable { 41.93 + char[] a = new char[] { 41.94 + Character.MIN_VALUE, 41.95 + Character.MIN_VALUE + 1, 41.96 + 0x000F, 41.97 + 0x00FF, 41.98 + 0x0FFF, 41.99 + Character.MAX_VALUE - 1, 41.100 + Character.MAX_VALUE 41.101 + }; 41.102 + for (int i = 0; i < a.length; i++) { 41.103 + dochar(a[i]); 41.104 + } 41.105 + } 41.106 + static void dochar(char x) throws Throwable { 41.107 + if (DEBUG) System.out.println("char=" + x); 41.108 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(char.class, char.class)); 41.109 + MethodHandle mh2 = mh1.asType(MethodType.methodType(char.class, Character.class)); 41.110 + char a = mh1.<char>invokeExact(x); 41.111 + char b = mh2.<char>invokeExact(Character.valueOf(x)); 41.112 + assert a == b : a + " != " + b; 41.113 + } 41.114 + 41.115 + // short 41.116 + static void testshort() throws Throwable { 41.117 + short[] a = new short[] { 41.118 + Short.MIN_VALUE, 41.119 + Short.MIN_VALUE + 1, 41.120 + -0x0FFF, 41.121 + -0x00FF, 41.122 + -0x000F, 41.123 + -1, 41.124 + 0, 41.125 + 1, 41.126 + 0x000F, 41.127 + 0x00FF, 41.128 + 0x0FFF, 41.129 + Short.MAX_VALUE - 1, 41.130 + Short.MAX_VALUE 41.131 + }; 41.132 + for (int i = 0; i < a.length; i++) { 41.133 + doshort(a[i]); 41.134 + } 41.135 + } 41.136 + static void doshort(short x) throws Throwable { 41.137 + if (DEBUG) System.out.println("short=" + x); 41.138 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(short.class, short.class)); 41.139 + MethodHandle mh2 = mh1.asType(MethodType.methodType(short.class, Short.class)); 41.140 + short a = mh1.<short>invokeExact(x); 41.141 + short b = mh2.<short>invokeExact(Short.valueOf(x)); 41.142 + assert a == b : a + " != " + b; 41.143 + } 41.144 + 41.145 + // int 41.146 + static void testint() throws Throwable { 41.147 + int[] a = new int[] { 41.148 + Integer.MIN_VALUE, 41.149 + Integer.MIN_VALUE + 1, 41.150 + -0x00000FFF, 41.151 + -0x000000FF, 41.152 + -0x0000000F, 41.153 + -1, 41.154 + 0, 41.155 + 1, 41.156 + 0x0000000F, 41.157 + 0x000000FF, 41.158 + 0x00000FFF, 41.159 + Integer.MAX_VALUE - 1, 41.160 + Integer.MAX_VALUE 41.161 + }; 41.162 + for (int i = 0; i < a.length; i++) { 41.163 + doint(a[i]); 41.164 + } 41.165 + } 41.166 + static void doint(int x) throws Throwable { 41.167 + if (DEBUG) System.out.println("int=" + x); 41.168 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(int.class, int.class)); 41.169 + MethodHandle mh2 = mh1.asType(MethodType.methodType(int.class, Integer.class)); 41.170 + int a = mh1.<int>invokeExact(x); 41.171 + int b = mh2.<int>invokeExact(Integer.valueOf(x)); 41.172 + assert a == b : a + " != " + b; 41.173 + } 41.174 + 41.175 + public static boolean foo(boolean i) { return i; } 41.176 + public static byte foo(byte i) { return i; } 41.177 + public static char foo(char i) { return i; } 41.178 + public static short foo(short i) { return i; } 41.179 + public static int foo(int i) { return i; } 41.180 +}