Mercurial > hg > truffle
comparison src/cpu/x86/vm/methodHandles_x86.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d7922586cf6 |
children | 75f33eecc1b3 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
45 return RegisterOrConstant(value); | 45 return RegisterOrConstant(value); |
46 } | 46 } |
47 | 47 |
48 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg) { | 48 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg) { |
49 if (VerifyMethodHandles) | 49 if (VerifyMethodHandles) |
50 verify_klass(_masm, klass_reg, SystemDictionaryHandles::Class_klass(), | 50 verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), |
51 "MH argument is a Class"); | 51 "MH argument is a Class"); |
52 __ load_heap_oop(klass_reg, Address(klass_reg, java_lang_Class::klass_offset_in_bytes())); | 52 __ movptr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset_in_bytes())); |
53 } | 53 } |
54 | 54 |
55 #ifdef ASSERT | 55 #ifdef ASSERT |
56 static int check_nonzero(const char* xname, int x) { | 56 static int check_nonzero(const char* xname, int x) { |
57 assert(x != 0, err_msg("%s should be nonzero", xname)); | 57 assert(x != 0, err_msg("%s should be nonzero", xname)); |
62 #define NONZERO(x) (x) | 62 #define NONZERO(x) (x) |
63 #endif //ASSERT | 63 #endif //ASSERT |
64 | 64 |
65 #ifdef ASSERT | 65 #ifdef ASSERT |
66 void MethodHandles::verify_klass(MacroAssembler* _masm, | 66 void MethodHandles::verify_klass(MacroAssembler* _masm, |
67 Register obj, KlassHandle klass, | 67 Register obj, SystemDictionary::WKID klass_id, |
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 Register temp = rdi; | 71 Register temp = rdi; |
74 Register temp2 = noreg; | 72 Register temp2 = noreg; |
75 LP64_ONLY(temp2 = rscratch1); // used by MacroAssembler::cmpptr | 73 LP64_ONLY(temp2 = rscratch1); // used by MacroAssembler::cmpptr |
76 Label L_ok, L_bad; | 74 Label L_ok, L_bad; |
77 BLOCK_COMMENT("verify_klass {"); | 75 BLOCK_COMMENT("verify_klass {"); |
135 #endif | 133 #endif |
136 // interp_only is an int, on little endian it is sufficient to test the byte only | 134 // interp_only is an int, on little endian it is sufficient to test the byte only |
137 // Is a cmpl faster? | 135 // Is a cmpl faster? |
138 __ cmpb(Address(rthread, JavaThread::interp_only_mode_offset()), 0); | 136 __ cmpb(Address(rthread, JavaThread::interp_only_mode_offset()), 0); |
139 __ jccb(Assembler::zero, run_compiled_code); | 137 __ jccb(Assembler::zero, run_compiled_code); |
140 __ jmp(Address(method, methodOopDesc::interpreter_entry_offset())); | 138 __ jmp(Address(method, Method::interpreter_entry_offset())); |
141 __ BIND(run_compiled_code); | 139 __ BIND(run_compiled_code); |
142 } | 140 } |
143 | 141 |
144 const ByteSize entry_offset = for_compiler_entry ? methodOopDesc::from_compiled_offset() : | 142 const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : |
145 methodOopDesc::from_interpreted_offset(); | 143 Method::from_interpreted_offset(); |
146 __ jmp(Address(method, entry_offset)); | 144 __ jmp(Address(method, entry_offset)); |
147 } | 145 } |
148 | 146 |
149 void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, | 147 void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, |
150 Register recv, Register method_temp, | 148 Register recv, Register method_temp, |
163 __ verify_oop(recv); | 161 __ verify_oop(recv); |
164 __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()))); | 162 __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()))); |
165 __ verify_oop(method_temp); | 163 __ verify_oop(method_temp); |
166 __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()))); | 164 __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()))); |
167 __ verify_oop(method_temp); | 165 __ verify_oop(method_temp); |
168 // the following assumes that a methodOop is normally compressed in the vmtarget field: | 166 // the following assumes that a Method* is normally compressed in the vmtarget field: |
169 __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()))); | 167 __ movptr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()))); |
170 __ verify_oop(method_temp); | |
171 | 168 |
172 if (VerifyMethodHandles && !for_compiler_entry) { | 169 if (VerifyMethodHandles && !for_compiler_entry) { |
173 // make sure recv is already on stack | 170 // make sure recv is already on stack |
174 __ load_sized_value(temp2, | 171 __ load_sized_value(temp2, |
175 Address(method_temp, methodOopDesc::size_of_parameters_offset()), | 172 Address(method_temp, Method::size_of_parameters_offset()), |
176 sizeof(u2), /*is_signed*/ false); | 173 sizeof(u2), /*is_signed*/ false); |
177 // assert(sizeof(u2) == sizeof(methodOopDesc::_size_of_parameters), ""); | 174 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); |
178 Label L; | 175 Label L; |
179 __ cmpptr(recv, __ argument_address(temp2, -1)); | 176 __ cmpptr(recv, __ argument_address(temp2, -1)); |
180 __ jcc(Assembler::equal, L); | 177 __ jcc(Assembler::equal, L); |
181 __ movptr(rax, __ argument_address(temp2, -1)); | 178 __ movptr(rax, __ argument_address(temp2, -1)); |
182 __ STOP("receiver not on stack"); | 179 __ STOP("receiver not on stack"); |
201 __ hlt(); // empty stubs make SG sick | 198 __ hlt(); // empty stubs make SG sick |
202 return NULL; | 199 return NULL; |
203 } | 200 } |
204 | 201 |
205 // rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted) | 202 // rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted) |
206 // rbx: methodOop | 203 // rbx: Method* |
207 // rdx: argument locator (parameter slot count, added to rsp) | 204 // rdx: argument locator (parameter slot count, added to rsp) |
208 // rcx: used as temp to hold mh or receiver | 205 // rcx: used as temp to hold mh or receiver |
209 // rax, rdi: garbage temps, blown away | 206 // rax, rdi: garbage temps, blown away |
210 Register rdx_argp = rdx; // argument list ptr, live on error paths | 207 Register rdx_argp = rdx; // argument list ptr, live on error paths |
211 Register rax_temp = rax; | 208 Register rax_temp = rax; |
219 address entry_point = __ pc(); | 216 address entry_point = __ pc(); |
220 | 217 |
221 if (VerifyMethodHandles) { | 218 if (VerifyMethodHandles) { |
222 Label L; | 219 Label L; |
223 BLOCK_COMMENT("verify_intrinsic_id {"); | 220 BLOCK_COMMENT("verify_intrinsic_id {"); |
224 __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) iid); | 221 __ cmpb(Address(rbx_method, Method::intrinsic_id_offset_in_bytes()), (int) iid); |
225 __ jcc(Assembler::equal, L); | 222 __ jcc(Assembler::equal, L); |
226 if (iid == vmIntrinsics::_linkToVirtual || | 223 if (iid == vmIntrinsics::_linkToVirtual || |
227 iid == vmIntrinsics::_linkToSpecial) { | 224 iid == vmIntrinsics::_linkToSpecial) { |
228 // could do this for all kinds, but would explode assembly code size | 225 // could do this for all kinds, but would explode assembly code size |
229 trace_method_handle(_masm, "bad methodOop::intrinsic_id"); | 226 trace_method_handle(_masm, "bad Method*::intrinsic_id"); |
230 } | 227 } |
231 __ STOP("bad methodOop::intrinsic_id"); | 228 __ STOP("bad Method*::intrinsic_id"); |
232 __ bind(L); | 229 __ bind(L); |
233 BLOCK_COMMENT("} verify_intrinsic_id"); | 230 BLOCK_COMMENT("} verify_intrinsic_id"); |
234 } | 231 } |
235 | 232 |
236 // First task: Find out how big the argument list is. | 233 // First task: Find out how big the argument list is. |
237 Address rdx_first_arg_addr; | 234 Address rdx_first_arg_addr; |
238 int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid); | 235 int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid); |
239 assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic"); | 236 assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic"); |
240 if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) { | 237 if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) { |
241 __ load_sized_value(rdx_argp, | 238 __ load_sized_value(rdx_argp, |
242 Address(rbx_method, methodOopDesc::size_of_parameters_offset()), | 239 Address(rbx_method, Method::size_of_parameters_offset()), |
243 sizeof(u2), /*is_signed*/ false); | 240 sizeof(u2), /*is_signed*/ false); |
244 // assert(sizeof(u2) == sizeof(methodOopDesc::_size_of_parameters), ""); | 241 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); |
245 rdx_first_arg_addr = __ argument_address(rdx_argp, -1); | 242 rdx_first_arg_addr = __ argument_address(rdx_argp, -1); |
246 } else { | 243 } else { |
247 DEBUG_ONLY(rdx_argp = noreg); | 244 DEBUG_ONLY(rdx_argp = noreg); |
248 } | 245 } |
249 | 246 |
341 | 338 |
342 } else { | 339 } else { |
343 // The method is a member invoker used by direct method handles. | 340 // The method is a member invoker used by direct method handles. |
344 if (VerifyMethodHandles) { | 341 if (VerifyMethodHandles) { |
345 // make sure the trailing argument really is a MemberName (caller responsibility) | 342 // make sure the trailing argument really is a MemberName (caller responsibility) |
346 verify_klass(_masm, member_reg, SystemDictionaryHandles::MemberName_klass(), | 343 verify_klass(_masm, member_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_invoke_MemberName), |
347 "MemberName required for invokeVirtual etc."); | 344 "MemberName required for invokeVirtual etc."); |
348 } | 345 } |
349 | 346 |
350 Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes())); | 347 Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes())); |
351 Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes())); | 348 Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes())); |
399 switch (iid) { | 396 switch (iid) { |
400 case vmIntrinsics::_linkToSpecial: | 397 case vmIntrinsics::_linkToSpecial: |
401 if (VerifyMethodHandles) { | 398 if (VerifyMethodHandles) { |
402 verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); | 399 verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); |
403 } | 400 } |
404 __ load_heap_oop(rbx_method, member_vmtarget); | 401 __ movptr(rbx_method, member_vmtarget); |
405 method_is_live = true; | 402 method_is_live = true; |
406 break; | 403 break; |
407 | 404 |
408 case vmIntrinsics::_linkToStatic: | 405 case vmIntrinsics::_linkToStatic: |
409 if (VerifyMethodHandles) { | 406 if (VerifyMethodHandles) { |
410 verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); | 407 verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); |
411 } | 408 } |
412 __ load_heap_oop(rbx_method, member_vmtarget); | 409 __ movptr(rbx_method, member_vmtarget); |
413 method_is_live = true; | 410 method_is_live = true; |
414 break; | 411 break; |
415 | 412 |
416 case vmIntrinsics::_linkToVirtual: | 413 case vmIntrinsics::_linkToVirtual: |
417 { | 414 { |
435 } | 432 } |
436 | 433 |
437 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget | 434 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget |
438 // at this point. And VerifyMethodHandles has already checked clazz, if needed. | 435 // at this point. And VerifyMethodHandles has already checked clazz, if needed. |
439 | 436 |
440 // get target methodOop & entry point | 437 // get target Method* & entry point |
441 __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method); | 438 __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method); |
442 method_is_live = true; | 439 method_is_live = true; |
443 break; | 440 break; |
444 } | 441 } |
445 | 442 |
651 __ popa(); | 648 __ popa(); |
652 __ leave(); | 649 __ leave(); |
653 BLOCK_COMMENT("} trace_method_handle"); | 650 BLOCK_COMMENT("} trace_method_handle"); |
654 } | 651 } |
655 #endif //PRODUCT | 652 #endif //PRODUCT |
656 |