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