Mercurial > hg > truffle
comparison src/cpu/sparc/vm/methodHandles_sparc.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 |
---|---|
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 |