44 return RegisterOrConstant(value); |
44 return RegisterOrConstant(value); |
45 } |
45 } |
46 |
46 |
47 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) { |
47 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) { |
48 if (VerifyMethodHandles) |
48 if (VerifyMethodHandles) |
49 verify_klass(_masm, klass_reg, SystemDictionaryHandles::Class_klass(), temp_reg, temp2_reg, |
49 verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), temp_reg, temp2_reg, |
50 "MH argument is a Class"); |
50 "MH argument is a Class"); |
51 __ load_heap_oop(Address(klass_reg, java_lang_Class::klass_offset_in_bytes()), klass_reg); |
51 __ ld_ptr(Address(klass_reg, java_lang_Class::klass_offset_in_bytes()), klass_reg); |
52 } |
52 } |
53 |
53 |
54 #ifdef ASSERT |
54 #ifdef ASSERT |
55 static int check_nonzero(const char* xname, int x) { |
55 static int check_nonzero(const char* xname, int x) { |
56 assert(x != 0, err_msg("%s should be nonzero", xname)); |
56 assert(x != 0, err_msg("%s should be nonzero", xname)); |
61 #define NONZERO(x) (x) |
61 #define NONZERO(x) (x) |
62 #endif //ASSERT |
62 #endif //ASSERT |
63 |
63 |
64 #ifdef ASSERT |
64 #ifdef ASSERT |
65 void MethodHandles::verify_klass(MacroAssembler* _masm, |
65 void MethodHandles::verify_klass(MacroAssembler* _masm, |
66 Register obj_reg, KlassHandle klass, |
66 Register obj_reg, SystemDictionary::WKID klass_id, |
67 Register temp_reg, Register temp2_reg, |
67 Register temp_reg, Register temp2_reg, |
68 const char* error_message) { |
68 const char* error_message) { |
69 oop* klass_addr = klass.raw_value(); |
69 Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id); |
70 assert(klass_addr >= SystemDictionaryHandles::Object_klass().raw_value() && |
70 KlassHandle klass = SystemDictionary::well_known_klass(klass_id); |
71 klass_addr <= SystemDictionaryHandles::Long_klass().raw_value(), |
|
72 "must be one of the SystemDictionaryHandles"); |
|
73 bool did_save = false; |
71 bool did_save = false; |
74 if (temp_reg == noreg || temp2_reg == noreg) { |
72 if (temp_reg == noreg || temp2_reg == noreg) { |
75 temp_reg = L1; |
73 temp_reg = L1; |
76 temp2_reg = L2; |
74 temp2_reg = L2; |
77 __ save_frame_and_mov(0, obj_reg, L0); |
75 __ save_frame_and_mov(0, obj_reg, L0); |
81 Label L_ok, L_bad; |
79 Label L_ok, L_bad; |
82 BLOCK_COMMENT("verify_klass {"); |
80 BLOCK_COMMENT("verify_klass {"); |
83 __ verify_oop(obj_reg); |
81 __ verify_oop(obj_reg); |
84 __ br_null_short(obj_reg, Assembler::pn, L_bad); |
82 __ br_null_short(obj_reg, Assembler::pn, L_bad); |
85 __ load_klass(obj_reg, temp_reg); |
83 __ load_klass(obj_reg, temp_reg); |
86 __ set(ExternalAddress(klass_addr), temp2_reg); |
84 __ set(ExternalAddress((Metadata**)klass_addr), temp2_reg); |
87 __ ld_ptr(Address(temp2_reg, 0), temp2_reg); |
85 __ ld_ptr(Address(temp2_reg, 0), temp2_reg); |
88 __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok); |
86 __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok); |
89 intptr_t super_check_offset = klass->super_check_offset(); |
87 intptr_t super_check_offset = klass->super_check_offset(); |
90 __ ld_ptr(Address(temp_reg, super_check_offset), temp_reg); |
88 __ ld_ptr(Address(temp_reg, super_check_offset), temp_reg); |
91 __ set(ExternalAddress(klass_addr), temp2_reg); |
89 __ set(ExternalAddress((Metadata**)klass_addr), temp2_reg); |
92 __ ld_ptr(Address(temp2_reg, 0), temp2_reg); |
90 __ ld_ptr(Address(temp2_reg, 0), temp2_reg); |
93 __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok); |
91 __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok); |
94 __ BIND(L_bad); |
92 __ BIND(L_bad); |
95 if (did_save) __ restore(); |
93 if (did_save) __ restore(); |
96 __ STOP(error_message); |
94 __ STOP(error_message); |
121 #endif // ASSERT |
119 #endif // ASSERT |
122 |
120 |
123 void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp, |
121 void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp, |
124 bool for_compiler_entry) { |
122 bool for_compiler_entry) { |
125 assert(method == G5_method, "interpreter calling convention"); |
123 assert(method == G5_method, "interpreter calling convention"); |
126 __ verify_oop(method); |
|
127 |
124 |
128 if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) { |
125 if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) { |
129 Label run_compiled_code; |
126 Label run_compiled_code; |
130 // JVMTI events, such as single-stepping, are implemented partly by avoiding running |
127 // JVMTI events, such as single-stepping, are implemented partly by avoiding running |
131 // compiled code in threads for which the event is enabled. Check here for |
128 // compiled code in threads for which the event is enabled. Check here for |
132 // interp_only_mode if these events CAN be enabled. |
129 // interp_only_mode if these events CAN be enabled. |
133 __ verify_thread(); |
130 __ verify_thread(); |
134 const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset()); |
131 const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset()); |
135 __ ld(interp_only, temp); |
132 __ ld(interp_only, temp); |
136 __ cmp_and_br_short(temp, 0, Assembler::zero, Assembler::pt, run_compiled_code); |
133 __ cmp_and_br_short(temp, 0, Assembler::zero, Assembler::pt, run_compiled_code); |
137 __ ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target); |
134 __ ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), target); |
138 __ jmp(target, 0); |
135 __ jmp(target, 0); |
139 __ delayed()->nop(); |
136 __ delayed()->nop(); |
140 __ BIND(run_compiled_code); |
137 __ BIND(run_compiled_code); |
141 // Note: we could fill some delay slots here, but |
138 // Note: we could fill some delay slots here, but |
142 // it doesn't matter, since this is interpreter code. |
139 // it doesn't matter, since this is interpreter code. |
143 } |
140 } |
144 |
141 |
145 const ByteSize entry_offset = for_compiler_entry ? methodOopDesc::from_compiled_offset() : |
142 const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : |
146 methodOopDesc::from_interpreted_offset(); |
143 Method::from_interpreted_offset(); |
147 __ ld_ptr(G5_method, in_bytes(entry_offset), target); |
144 __ ld_ptr(G5_method, in_bytes(entry_offset), target); |
148 __ jmp(target, 0); |
145 __ jmp(target, 0); |
149 __ delayed()->nop(); |
146 __ delayed()->nop(); |
150 } |
147 } |
151 |
148 |
165 __ verify_oop(recv); |
162 __ verify_oop(recv); |
166 __ load_heap_oop(Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), method_temp); |
163 __ load_heap_oop(Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), method_temp); |
167 __ verify_oop(method_temp); |
164 __ verify_oop(method_temp); |
168 __ load_heap_oop(Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), method_temp); |
165 __ load_heap_oop(Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), method_temp); |
169 __ verify_oop(method_temp); |
166 __ verify_oop(method_temp); |
170 // the following assumes that a methodOop is normally compressed in the vmtarget field: |
167 // the following assumes that a Method* is normally compressed in the vmtarget field: |
171 __ load_heap_oop(Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())), method_temp); |
168 __ ld_ptr(Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())), method_temp); |
172 __ verify_oop(method_temp); |
|
173 |
169 |
174 if (VerifyMethodHandles && !for_compiler_entry) { |
170 if (VerifyMethodHandles && !for_compiler_entry) { |
175 // make sure recv is already on stack |
171 // make sure recv is already on stack |
176 __ load_sized_value(Address(method_temp, methodOopDesc::size_of_parameters_offset()), |
172 __ load_sized_value(Address(method_temp, Method::size_of_parameters_offset()), |
177 temp2, |
173 temp2, |
178 sizeof(u2), /*is_signed*/ false); |
174 sizeof(u2), /*is_signed*/ false); |
179 // assert(sizeof(u2) == sizeof(methodOopDesc::_size_of_parameters), ""); |
175 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); |
180 Label L; |
176 Label L; |
181 __ ld_ptr(__ argument_address(temp2, temp2, -1), temp2); |
177 __ ld_ptr(__ argument_address(temp2, temp2, -1), temp2); |
182 __ cmp_and_br_short(temp2, recv, Assembler::equal, Assembler::pt, L); |
178 __ cmp_and_br_short(temp2, recv, Assembler::equal, Assembler::pt, L); |
183 __ STOP("receiver not on stack"); |
179 __ STOP("receiver not on stack"); |
184 __ BIND(L); |
180 __ BIND(L); |
202 __ should_not_reach_here(); // empty stubs make SG sick |
198 __ should_not_reach_here(); // empty stubs make SG sick |
203 return NULL; |
199 return NULL; |
204 } |
200 } |
205 |
201 |
206 // I5_savedSP/O5_savedSP: sender SP (must preserve; see prepare_to_jump_from_interpreted) |
202 // I5_savedSP/O5_savedSP: sender SP (must preserve; see prepare_to_jump_from_interpreted) |
207 // G5_method: methodOop |
203 // G5_method: Method* |
208 // G4 (Gargs): incoming argument list (must preserve) |
204 // G4 (Gargs): incoming argument list (must preserve) |
209 // O0: used as temp to hold mh or receiver |
205 // O0: used as temp to hold mh or receiver |
210 // O1, O4: garbage temps, blown away |
206 // O1, O4: garbage temps, blown away |
211 Register O1_scratch = O1; |
207 Register O1_scratch = O1; |
212 Register O4_param_size = O4; // size of parameters |
208 Register O4_param_size = O4; // size of parameters |
218 address entry_point = __ pc(); |
214 address entry_point = __ pc(); |
219 |
215 |
220 if (VerifyMethodHandles) { |
216 if (VerifyMethodHandles) { |
221 Label L; |
217 Label L; |
222 BLOCK_COMMENT("verify_intrinsic_id {"); |
218 BLOCK_COMMENT("verify_intrinsic_id {"); |
223 __ ldub(Address(G5_method, methodOopDesc::intrinsic_id_offset_in_bytes()), O1_scratch); |
219 __ ldub(Address(G5_method, Method::intrinsic_id_offset_in_bytes()), O1_scratch); |
224 __ cmp_and_br_short(O1_scratch, (int) iid, Assembler::equal, Assembler::pt, L); |
220 __ cmp_and_br_short(O1_scratch, (int) iid, Assembler::equal, Assembler::pt, L); |
225 if (iid == vmIntrinsics::_linkToVirtual || |
221 if (iid == vmIntrinsics::_linkToVirtual || |
226 iid == vmIntrinsics::_linkToSpecial) { |
222 iid == vmIntrinsics::_linkToSpecial) { |
227 // could do this for all kinds, but would explode assembly code size |
223 // could do this for all kinds, but would explode assembly code size |
228 trace_method_handle(_masm, "bad methodOop::intrinsic_id"); |
224 trace_method_handle(_masm, "bad Method*::intrinsic_id"); |
229 } |
225 } |
230 __ STOP("bad methodOop::intrinsic_id"); |
226 __ STOP("bad Method*::intrinsic_id"); |
231 __ bind(L); |
227 __ bind(L); |
232 BLOCK_COMMENT("} verify_intrinsic_id"); |
228 BLOCK_COMMENT("} verify_intrinsic_id"); |
233 } |
229 } |
234 |
230 |
235 // First task: Find out how big the argument list is. |
231 // First task: Find out how big the argument list is. |
236 Address O4_first_arg_addr; |
232 Address O4_first_arg_addr; |
237 int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid); |
233 int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid); |
238 assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic"); |
234 assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic"); |
239 if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) { |
235 if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) { |
240 __ load_sized_value(Address(G5_method, methodOopDesc::size_of_parameters_offset()), |
236 __ load_sized_value(Address(G5_method, Method::size_of_parameters_offset()), |
241 O4_param_size, |
237 O4_param_size, |
242 sizeof(u2), /*is_signed*/ false); |
238 sizeof(u2), /*is_signed*/ false); |
243 // assert(sizeof(u2) == sizeof(methodOopDesc::_size_of_parameters), ""); |
239 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); |
244 O4_first_arg_addr = __ argument_address(O4_param_size, O4_param_size, -1); |
240 O4_first_arg_addr = __ argument_address(O4_param_size, O4_param_size, -1); |
245 } else { |
241 } else { |
246 DEBUG_ONLY(O4_param_size = noreg); |
242 DEBUG_ONLY(O4_param_size = noreg); |
247 } |
243 } |
248 |
244 |
329 |
325 |
330 } else { |
326 } else { |
331 // The method is a member invoker used by direct method handles. |
327 // The method is a member invoker used by direct method handles. |
332 if (VerifyMethodHandles) { |
328 if (VerifyMethodHandles) { |
333 // make sure the trailing argument really is a MemberName (caller responsibility) |
329 // make sure the trailing argument really is a MemberName (caller responsibility) |
334 verify_klass(_masm, member_reg, SystemDictionaryHandles::MemberName_klass(), |
330 verify_klass(_masm, member_reg, SystemDictionary::WK_KLASS_ENUM_NAME(MemberName_klass), |
335 temp1, temp2, |
331 temp1, temp2, |
336 "MemberName required for invokeVirtual etc."); |
332 "MemberName required for invokeVirtual etc."); |
337 } |
333 } |
338 |
334 |
339 Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes())); |
335 Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes())); |
388 switch (iid) { |
384 switch (iid) { |
389 case vmIntrinsics::_linkToSpecial: |
385 case vmIntrinsics::_linkToSpecial: |
390 if (VerifyMethodHandles) { |
386 if (VerifyMethodHandles) { |
391 verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); |
387 verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); |
392 } |
388 } |
393 __ load_heap_oop(member_vmtarget, G5_method); |
389 __ ld_ptr(member_vmtarget, G5_method); |
394 method_is_live = true; |
390 method_is_live = true; |
395 break; |
391 break; |
396 |
392 |
397 case vmIntrinsics::_linkToStatic: |
393 case vmIntrinsics::_linkToStatic: |
398 if (VerifyMethodHandles) { |
394 if (VerifyMethodHandles) { |
399 verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); |
395 verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); |
400 } |
396 } |
401 __ load_heap_oop(member_vmtarget, G5_method); |
397 __ ld_ptr(member_vmtarget, G5_method); |
402 method_is_live = true; |
398 method_is_live = true; |
403 break; |
399 break; |
404 |
400 |
405 case vmIntrinsics::_linkToVirtual: |
401 case vmIntrinsics::_linkToVirtual: |
406 { |
402 { |
423 } |
419 } |
424 |
420 |
425 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget |
421 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget |
426 // at this point. And VerifyMethodHandles has already checked clazz, if needed. |
422 // at this point. And VerifyMethodHandles has already checked clazz, if needed. |
427 |
423 |
428 // get target methodOop & entry point |
424 // get target Method* & entry point |
429 __ lookup_virtual_method(temp1_recv_klass, temp2_index, G5_method); |
425 __ lookup_virtual_method(temp1_recv_klass, temp2_index, G5_method); |
430 method_is_live = true; |
426 method_is_live = true; |
431 break; |
427 break; |
432 } |
428 } |
433 |
429 |