Thu, 14 Oct 2010 10:46:38 -0700
Merge
1.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp Fri Oct 08 09:29:09 2010 -0700 1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 2.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 3.2 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 4.2 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 5.2 +++ b/src/cpu/sparc/vm/c1_LinearScan_sparc.hpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 6.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 7.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 8.2 +++ b/src/cpu/sparc/vm/stubRoutines_sparc.hpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 9.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 10.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 11.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 12.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 13.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 14.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 15.2 +++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 16.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 17.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 18.2 +++ b/src/cpu/zero/vm/interpreterRT_zero.hpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 19.2 +++ b/src/share/vm/asm/codeBuffer.hpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 20.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 21.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 22.2 +++ b/src/share/vm/ci/ciTypeFlow.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 23.2 +++ b/src/share/vm/classfile/classFileParser.cpp Thu Oct 14 10:46:38 2010 -0700 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 Fri Oct 08 09:29:09 2010 -0700 24.2 +++ b/src/share/vm/code/nmethod.cpp Thu Oct 14 10:46:38 2010 -0700 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/oops/methodOop.cpp Fri Oct 08 09:29:09 2010 -0700 25.2 +++ b/src/share/vm/oops/methodOop.cpp Thu Oct 14 10:46:38 2010 -0700 25.3 @@ -758,7 +758,7 @@ 25.4 25.5 OrderAccess::storestore(); 25.6 #ifdef SHARK 25.7 - mh->_from_interpreted_entry = code->instructions_begin(); 25.8 + mh->_from_interpreted_entry = code->insts_begin(); 25.9 #else 25.10 mh->_from_compiled_entry = code->verified_entry_point(); 25.11 OrderAccess::storestore();
26.1 --- a/src/share/vm/oops/oop.inline.hpp Fri Oct 08 09:29:09 2010 -0700 26.2 +++ b/src/share/vm/oops/oop.inline.hpp Thu Oct 14 10:46:38 2010 -0700 26.3 @@ -173,7 +173,7 @@ 26.4 address base = Universe::narrow_oop_base(); 26.5 int shift = Universe::narrow_oop_shift(); 26.6 oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift)); 26.7 - assert(check_obj_alignment(result), "Address not aligned"); 26.8 + assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result)); 26.9 return result; 26.10 } 26.11
27.1 --- a/src/share/vm/opto/library_call.cpp Fri Oct 08 09:29:09 2010 -0700 27.2 +++ b/src/share/vm/opto/library_call.cpp Thu Oct 14 10:46:38 2010 -0700 27.3 @@ -4761,7 +4761,7 @@ 27.4 Node* cv = generate_checkcast_arraycopy(adr_type, 27.5 dest_elem_klass, 27.6 src, src_offset, dest, dest_offset, 27.7 - copy_length); 27.8 + ConvI2X(copy_length)); 27.9 if (cv == NULL) cv = intcon(-1); // failure (no stub available) 27.10 checked_control = control(); 27.11 checked_i_o = i_o(); 27.12 @@ -5206,7 +5206,7 @@ 27.13 int sco_offset = Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc); 27.14 Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset); 27.15 Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr()); 27.16 - Node* check_offset = _gvn.transform(n3); 27.17 + Node* check_offset = ConvI2X(_gvn.transform(n3)); 27.18 Node* check_value = dest_elem_klass; 27.19 27.20 Node* src_start = array_element_address(src, src_offset, T_OBJECT);
28.1 --- a/src/share/vm/opto/loopTransform.cpp Fri Oct 08 09:29:09 2010 -0700 28.2 +++ b/src/share/vm/opto/loopTransform.cpp Thu Oct 14 10:46:38 2010 -0700 28.3 @@ -2684,7 +2684,14 @@ 28.4 fill_name, TypeAryPtr::get_array_body_type(t)); 28.5 call->init_req(TypeFunc::Parms+0, from); 28.6 call->init_req(TypeFunc::Parms+1, store_value); 28.7 +#ifdef _LP64 28.8 + len = new (C, 2) ConvI2LNode(len); 28.9 + _igvn.register_new_node_with_optimizer(len); 28.10 +#endif 28.11 call->init_req(TypeFunc::Parms+2, len); 28.12 +#ifdef _LP64 28.13 + call->init_req(TypeFunc::Parms+3, C->top()); 28.14 +#endif 28.15 call->init_req( TypeFunc::Control, head->init_control()); 28.16 call->init_req( TypeFunc::I_O , C->top() ) ; // does no i/o 28.17 call->init_req( TypeFunc::Memory , mem_phi->in(LoopNode::EntryControl) );
29.1 --- a/src/share/vm/opto/runtime.cpp Fri Oct 08 09:29:09 2010 -0700 29.2 +++ b/src/share/vm/opto/runtime.cpp Thu Oct 14 10:46:38 2010 -0700 29.3 @@ -646,12 +646,14 @@ 29.4 29.5 29.6 const TypeFunc* OptoRuntime::array_fill_Type() { 29.7 - // create input type (domain) 29.8 - const Type** fields = TypeTuple::fields(3); 29.9 - fields[TypeFunc::Parms+0] = TypePtr::NOTNULL; 29.10 - fields[TypeFunc::Parms+1] = TypeInt::INT; 29.11 - fields[TypeFunc::Parms+2] = TypeInt::INT; 29.12 - const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 3, fields); 29.13 + // create input type (domain): pointer, int, size_t 29.14 + const Type** fields = TypeTuple::fields(3 LP64_ONLY( + 1)); 29.15 + int argp = TypeFunc::Parms; 29.16 + fields[argp++] = TypePtr::NOTNULL; 29.17 + fields[argp++] = TypeInt::INT; 29.18 + fields[argp++] = TypeX_X; // size in whatevers (size_t) 29.19 + LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length 29.20 + const TypeTuple *domain = TypeTuple::make(argp, fields); 29.21 29.22 // create result type 29.23 fields = TypeTuple::fields(1);
30.1 --- a/src/share/vm/prims/methodHandles.cpp Fri Oct 08 09:29:09 2010 -0700 30.2 +++ b/src/share/vm/prims/methodHandles.cpp Thu Oct 14 10:46:38 2010 -0700 30.3 @@ -1568,7 +1568,7 @@ 30.4 if (ptype != T_INT) { 30.5 int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT); 30.6 jint value = argument->int_field(value_offset); 30.7 - int vminfo = adapter_subword_vminfo(ptype); 30.8 + int vminfo = adapter_unbox_subword_vminfo(ptype); 30.9 jint subword = truncate_subword_from_vminfo(value, vminfo); 30.10 if (value != subword) { 30.11 err = "bound subword value does not fit into the subword type"; 30.12 @@ -2018,12 +2018,12 @@ 30.13 assert(src == T_INT || is_subword_type(src), "source is not float"); 30.14 // Subword-related cases are int -> {boolean,byte,char,short}. 30.15 ek_opt = _adapter_opt_i2i; 30.16 - vminfo = adapter_subword_vminfo(dest); 30.17 + vminfo = adapter_prim_to_prim_subword_vminfo(dest); 30.18 break; 30.19 case 2 *4+ 1: 30.20 if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) { 30.21 ek_opt = _adapter_opt_l2i; 30.22 - vminfo = adapter_subword_vminfo(dest); 30.23 + vminfo = adapter_prim_to_prim_subword_vminfo(dest); 30.24 } else if (src == T_DOUBLE && dest == T_FLOAT) { 30.25 ek_opt = _adapter_opt_d2f; 30.26 } else { 30.27 @@ -2051,7 +2051,7 @@ 30.28 switch (type2size[dest]) { 30.29 case 1: 30.30 ek_opt = _adapter_opt_unboxi; 30.31 - vminfo = adapter_subword_vminfo(dest); 30.32 + vminfo = adapter_unbox_subword_vminfo(dest); 30.33 break; 30.34 case 2: 30.35 ek_opt = _adapter_opt_unboxl;
31.1 --- a/src/share/vm/prims/methodHandles.hpp Fri Oct 08 09:29:09 2010 -0700 31.2 +++ b/src/share/vm/prims/methodHandles.hpp Thu Oct 14 10:46:38 2010 -0700 31.3 @@ -226,11 +226,20 @@ 31.4 } 31.5 31.6 enum { CONV_VMINFO_SIGN_FLAG = 0x80 }; 31.7 - static int adapter_subword_vminfo(BasicType dest) { 31.8 - if (dest == T_BOOLEAN) return (BitsPerInt - 1); 31.9 - if (dest == T_CHAR) return (BitsPerInt - 16); 31.10 - if (dest == T_BYTE) return (BitsPerInt - 8) | CONV_VMINFO_SIGN_FLAG; 31.11 - if (dest == T_SHORT) return (BitsPerInt - 16) | CONV_VMINFO_SIGN_FLAG; 31.12 + // Shift values for prim-to-prim conversions. 31.13 + static int adapter_prim_to_prim_subword_vminfo(BasicType dest) { 31.14 + if (dest == T_BOOLEAN) return (BitsPerInt - 1); // boolean is 1 bit 31.15 + if (dest == T_CHAR) return (BitsPerInt - BitsPerShort); 31.16 + if (dest == T_BYTE) return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG; 31.17 + if (dest == T_SHORT) return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG; 31.18 + return 0; // case T_INT 31.19 + } 31.20 + // Shift values for unboxing a primitive. 31.21 + static int adapter_unbox_subword_vminfo(BasicType dest) { 31.22 + if (dest == T_BOOLEAN) return (BitsPerInt - BitsPerByte ); // implemented as 1 byte 31.23 + if (dest == T_CHAR) return (BitsPerInt - BitsPerShort); 31.24 + if (dest == T_BYTE) return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG; 31.25 + if (dest == T_SHORT) return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG; 31.26 return 0; // case T_INT 31.27 } 31.28 // Here is the transformation the i2i adapter must perform:
32.1 --- a/src/share/vm/shark/sharkCompiler.hpp Fri Oct 08 09:29:09 2010 -0700 32.2 +++ b/src/share/vm/shark/sharkCompiler.hpp Thu Oct 14 10:46:38 2010 -0700 32.3 @@ -103,8 +103,7 @@ 32.4 // Global access 32.5 public: 32.6 static SharkCompiler* compiler() { 32.7 - AbstractCompiler *compiler = 32.8 - CompileBroker::compiler(CompLevel_fast_compile); 32.9 + AbstractCompiler *compiler = CompileBroker::compiler(CompLevel_simple); 32.10 assert(compiler->is_shark() && compiler->is_initialized(), "should be"); 32.11 return (SharkCompiler *) compiler; 32.12 }
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/test/compiler/6987555/Test6987555.java Thu Oct 14 10:46:38 2010 -0700 33.3 @@ -0,0 +1,177 @@ 33.4 +/* 33.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.7 + * 33.8 + * This code is free software; you can redistribute it and/or modify it 33.9 + * under the terms of the GNU General Public License version 2 only, as 33.10 + * published by the Free Software Foundation. 33.11 + * 33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 33.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 33.15 + * version 2 for more details (a copy is included in the LICENSE file that 33.16 + * accompanied this code). 33.17 + * 33.18 + * You should have received a copy of the GNU General Public License version 33.19 + * 2 along with this work; if not, write to the Free Software Foundation, 33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 33.21 + * 33.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 33.23 + * or visit www.oracle.com if you need additional information or have any 33.24 + * questions. 33.25 + * 33.26 + */ 33.27 + 33.28 +/** 33.29 + * @test 33.30 + * @bug 6987555 33.31 + * @summary JSR 292 unboxing to a boolean value fails on big-endian SPARC 33.32 + * 33.33 + * @run main/othervm -Xint -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6987555 33.34 + */ 33.35 + 33.36 +import java.dyn.*; 33.37 + 33.38 +public class Test6987555 { 33.39 + private static final Class CLASS = Test6987555.class; 33.40 + private static final String NAME = "foo"; 33.41 + private static final boolean DEBUG = false; 33.42 + 33.43 + public static void main(String[] args) throws Throwable { 33.44 + testboolean(); 33.45 + testbyte(); 33.46 + testchar(); 33.47 + testshort(); 33.48 + testint(); 33.49 + } 33.50 + 33.51 + // boolean 33.52 + static void testboolean() throws Throwable { 33.53 + doboolean(false); 33.54 + doboolean(true); 33.55 + } 33.56 + static void doboolean(boolean x) throws Throwable { 33.57 + if (DEBUG) System.out.println("boolean=" + x); 33.58 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(boolean.class, boolean.class)); 33.59 + MethodHandle mh2 = mh1.asType(MethodType.methodType(boolean.class, Boolean.class)); 33.60 + boolean a = mh1.<boolean>invokeExact(x); 33.61 + boolean b = mh2.<boolean>invokeExact(Boolean.valueOf(x)); 33.62 + assert a == b : a + " != " + b; 33.63 + } 33.64 + 33.65 + // byte 33.66 + static void testbyte() throws Throwable { 33.67 + byte[] a = new byte[] { 33.68 + Byte.MIN_VALUE, 33.69 + Byte.MIN_VALUE + 1, 33.70 + -0x0F, 33.71 + -1, 33.72 + 0, 33.73 + 1, 33.74 + 0x0F, 33.75 + Byte.MAX_VALUE - 1, 33.76 + Byte.MAX_VALUE 33.77 + }; 33.78 + for (int i = 0; i < a.length; i++) { 33.79 + dobyte(a[i]); 33.80 + } 33.81 + } 33.82 + static void dobyte(byte x) throws Throwable { 33.83 + if (DEBUG) System.out.println("byte=" + x); 33.84 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(byte.class, byte.class)); 33.85 + MethodHandle mh2 = mh1.asType(MethodType.methodType(byte.class, Byte.class)); 33.86 + byte a = mh1.<byte>invokeExact(x); 33.87 + byte b = mh2.<byte>invokeExact(Byte.valueOf(x)); 33.88 + assert a == b : a + " != " + b; 33.89 + } 33.90 + 33.91 + // char 33.92 + static void testchar() throws Throwable { 33.93 + char[] a = new char[] { 33.94 + Character.MIN_VALUE, 33.95 + Character.MIN_VALUE + 1, 33.96 + 0x000F, 33.97 + 0x00FF, 33.98 + 0x0FFF, 33.99 + Character.MAX_VALUE - 1, 33.100 + Character.MAX_VALUE 33.101 + }; 33.102 + for (int i = 0; i < a.length; i++) { 33.103 + dochar(a[i]); 33.104 + } 33.105 + } 33.106 + static void dochar(char x) throws Throwable { 33.107 + if (DEBUG) System.out.println("char=" + x); 33.108 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(char.class, char.class)); 33.109 + MethodHandle mh2 = mh1.asType(MethodType.methodType(char.class, Character.class)); 33.110 + char a = mh1.<char>invokeExact(x); 33.111 + char b = mh2.<char>invokeExact(Character.valueOf(x)); 33.112 + assert a == b : a + " != " + b; 33.113 + } 33.114 + 33.115 + // short 33.116 + static void testshort() throws Throwable { 33.117 + short[] a = new short[] { 33.118 + Short.MIN_VALUE, 33.119 + Short.MIN_VALUE + 1, 33.120 + -0x0FFF, 33.121 + -0x00FF, 33.122 + -0x000F, 33.123 + -1, 33.124 + 0, 33.125 + 1, 33.126 + 0x000F, 33.127 + 0x00FF, 33.128 + 0x0FFF, 33.129 + Short.MAX_VALUE - 1, 33.130 + Short.MAX_VALUE 33.131 + }; 33.132 + for (int i = 0; i < a.length; i++) { 33.133 + doshort(a[i]); 33.134 + } 33.135 + } 33.136 + static void doshort(short x) throws Throwable { 33.137 + if (DEBUG) System.out.println("short=" + x); 33.138 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(short.class, short.class)); 33.139 + MethodHandle mh2 = mh1.asType(MethodType.methodType(short.class, Short.class)); 33.140 + short a = mh1.<short>invokeExact(x); 33.141 + short b = mh2.<short>invokeExact(Short.valueOf(x)); 33.142 + assert a == b : a + " != " + b; 33.143 + } 33.144 + 33.145 + // int 33.146 + static void testint() throws Throwable { 33.147 + int[] a = new int[] { 33.148 + Integer.MIN_VALUE, 33.149 + Integer.MIN_VALUE + 1, 33.150 + -0x00000FFF, 33.151 + -0x000000FF, 33.152 + -0x0000000F, 33.153 + -1, 33.154 + 0, 33.155 + 1, 33.156 + 0x0000000F, 33.157 + 0x000000FF, 33.158 + 0x00000FFF, 33.159 + Integer.MAX_VALUE - 1, 33.160 + Integer.MAX_VALUE 33.161 + }; 33.162 + for (int i = 0; i < a.length; i++) { 33.163 + doint(a[i]); 33.164 + } 33.165 + } 33.166 + static void doint(int x) throws Throwable { 33.167 + if (DEBUG) System.out.println("int=" + x); 33.168 + MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(int.class, int.class)); 33.169 + MethodHandle mh2 = mh1.asType(MethodType.methodType(int.class, Integer.class)); 33.170 + int a = mh1.<int>invokeExact(x); 33.171 + int b = mh2.<int>invokeExact(Integer.valueOf(x)); 33.172 + assert a == b : a + " != " + b; 33.173 + } 33.174 + 33.175 + public static boolean foo(boolean i) { return i; } 33.176 + public static byte foo(byte i) { return i; } 33.177 + public static char foo(char i) { return i; } 33.178 + public static short foo(short i) { return i; } 33.179 + public static int foo(int i) { return i; } 33.180 +}