Mercurial > hg > truffle
comparison src/share/vm/ci/ciMethod.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 | 7f813940ac35 |
children | 18fb7da42534 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
27 #include "ci/ciExceptionHandler.hpp" | 27 #include "ci/ciExceptionHandler.hpp" |
28 #include "ci/ciInstanceKlass.hpp" | 28 #include "ci/ciInstanceKlass.hpp" |
29 #include "ci/ciMethod.hpp" | 29 #include "ci/ciMethod.hpp" |
30 #include "ci/ciMethodBlocks.hpp" | 30 #include "ci/ciMethodBlocks.hpp" |
31 #include "ci/ciMethodData.hpp" | 31 #include "ci/ciMethodData.hpp" |
32 #include "ci/ciMethodKlass.hpp" | |
33 #include "ci/ciStreams.hpp" | 32 #include "ci/ciStreams.hpp" |
34 #include "ci/ciSymbol.hpp" | 33 #include "ci/ciSymbol.hpp" |
35 #include "ci/ciUtilities.hpp" | 34 #include "ci/ciUtilities.hpp" |
36 #include "classfile/systemDictionary.hpp" | 35 #include "classfile/systemDictionary.hpp" |
37 #include "compiler/abstractCompiler.hpp" | 36 #include "compiler/abstractCompiler.hpp" |
49 #include "utilities/bitMap.inline.hpp" | 48 #include "utilities/bitMap.inline.hpp" |
50 #include "utilities/xmlstream.hpp" | 49 #include "utilities/xmlstream.hpp" |
51 #ifdef COMPILER2 | 50 #ifdef COMPILER2 |
52 #include "ci/bcEscapeAnalyzer.hpp" | 51 #include "ci/bcEscapeAnalyzer.hpp" |
53 #include "ci/ciTypeFlow.hpp" | 52 #include "ci/ciTypeFlow.hpp" |
54 #include "oops/methodOop.hpp" | 53 #include "oops/method.hpp" |
55 #endif | 54 #endif |
56 #ifdef SHARK | 55 #ifdef SHARK |
57 #include "ci/ciTypeFlow.hpp" | 56 #include "ci/ciTypeFlow.hpp" |
58 #include "oops/methodOop.hpp" | 57 #include "oops/method.hpp" |
59 #endif | 58 #endif |
60 | 59 |
61 // ciMethod | 60 // ciMethod |
62 // | 61 // |
63 // This class represents a methodOop in the HotSpot virtual | 62 // This class represents a Method* in the HotSpot virtual |
64 // machine. | 63 // machine. |
65 | 64 |
66 | 65 |
67 // ------------------------------------------------------------------ | 66 // ------------------------------------------------------------------ |
68 // ciMethod::ciMethod | 67 // ciMethod::ciMethod |
69 // | 68 // |
70 // Loaded method. | 69 // Loaded method. |
71 ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) { | 70 ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) { |
72 assert(h_m() != NULL, "no null method"); | 71 assert(h_m() != NULL, "no null method"); |
73 | 72 |
74 // These fields are always filled in in loaded methods. | 73 // These fields are always filled in in loaded methods. |
75 _flags = ciFlags(h_m()->access_flags()); | 74 _flags = ciFlags(h_m()->access_flags()); |
76 | 75 |
104 } | 103 } |
105 } else { | 104 } else { |
106 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); | 105 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); |
107 } | 106 } |
108 | 107 |
109 if (instanceKlass::cast(h_m()->method_holder())->is_linked()) { | 108 if (InstanceKlass::cast(h_m()->method_holder())->is_linked()) { |
110 _can_be_statically_bound = h_m()->can_be_statically_bound(); | 109 _can_be_statically_bound = h_m()->can_be_statically_bound(); |
111 } else { | 110 } else { |
112 // Have to use a conservative value in this case. | 111 // Have to use a conservative value in this case. |
113 _can_be_statically_bound = false; | 112 _can_be_statically_bound = false; |
114 } | 113 } |
121 _can_be_statically_bound = false; | 120 _can_be_statically_bound = false; |
122 | 121 |
123 // generating _signature may allow GC and therefore move m. | 122 // generating _signature may allow GC and therefore move m. |
124 // These fields are always filled in. | 123 // These fields are always filled in. |
125 _name = env->get_symbol(h_m()->name()); | 124 _name = env->get_symbol(h_m()->name()); |
126 _holder = env->get_object(h_m()->method_holder())->as_instance_klass(); | 125 _holder = env->get_instance_klass(h_m()->method_holder()); |
127 ciSymbol* sig_symbol = env->get_symbol(h_m()->signature()); | 126 ciSymbol* sig_symbol = env->get_symbol(h_m()->signature()); |
128 constantPoolHandle cpool = h_m()->constants(); | 127 constantPoolHandle cpool = h_m()->constants(); |
129 _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol); | 128 _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol); |
130 _method_data = NULL; | 129 _method_data = NULL; |
131 // Take a snapshot of these values, so they will be commensurate with the MDO. | 130 // Take a snapshot of these values, so they will be commensurate with the MDO. |
149 // Unloaded method. | 148 // Unloaded method. |
150 ciMethod::ciMethod(ciInstanceKlass* holder, | 149 ciMethod::ciMethod(ciInstanceKlass* holder, |
151 ciSymbol* name, | 150 ciSymbol* name, |
152 ciSymbol* signature, | 151 ciSymbol* signature, |
153 ciInstanceKlass* accessor) : | 152 ciInstanceKlass* accessor) : |
154 ciObject(ciMethodKlass::make()), | 153 ciMetadata((Metadata*)NULL), |
155 _name( name), | 154 _name( name), |
156 _holder( holder), | 155 _holder( holder), |
157 _intrinsic_id( vmIntrinsics::_none), | 156 _intrinsic_id( vmIntrinsics::_none), |
158 _liveness( NULL), | 157 _liveness( NULL), |
159 _can_be_statically_bound(false), | 158 _can_be_statically_bound(false), |
178 // Load the bytecodes and exception handler table for this method. | 177 // Load the bytecodes and exception handler table for this method. |
179 void ciMethod::load_code() { | 178 void ciMethod::load_code() { |
180 VM_ENTRY_MARK; | 179 VM_ENTRY_MARK; |
181 assert(is_loaded(), "only loaded methods have code"); | 180 assert(is_loaded(), "only loaded methods have code"); |
182 | 181 |
183 methodOop me = get_methodOop(); | 182 Method* me = get_Method(); |
184 Arena* arena = CURRENT_THREAD_ENV->arena(); | 183 Arena* arena = CURRENT_THREAD_ENV->arena(); |
185 | 184 |
186 // Load the bytecodes. | 185 // Load the bytecodes. |
187 _code = (address)arena->Amalloc(code_size()); | 186 _code = (address)arena->Amalloc(code_size()); |
188 memcpy(_code, me->code_base(), code_size()); | 187 memcpy(_code, me->code_base(), code_size()); |
189 | 188 |
190 // Revert any breakpoint bytecodes in ci's copy | 189 // Revert any breakpoint bytecodes in ci's copy |
191 if (me->number_of_breakpoints() > 0) { | 190 if (me->number_of_breakpoints() > 0) { |
192 BreakpointInfo* bp = instanceKlass::cast(me->method_holder())->breakpoints(); | 191 BreakpointInfo* bp = InstanceKlass::cast(me->method_holder())->breakpoints(); |
193 for (; bp != NULL; bp = bp->next()) { | 192 for (; bp != NULL; bp = bp->next()) { |
194 if (bp->match(me)) { | 193 if (bp->match(me)) { |
195 code_at_put(bp->bci(), bp->orig_bytecode()); | 194 code_at_put(bp->bci(), bp->orig_bytecode()); |
196 } | 195 } |
197 } | 196 } |
234 // | 233 // |
235 // length unknown until decompression | 234 // length unknown until decompression |
236 bool ciMethod::has_linenumber_table() const { | 235 bool ciMethod::has_linenumber_table() const { |
237 check_is_loaded(); | 236 check_is_loaded(); |
238 VM_ENTRY_MARK; | 237 VM_ENTRY_MARK; |
239 return get_methodOop()->has_linenumber_table(); | 238 return get_Method()->has_linenumber_table(); |
240 } | 239 } |
241 | 240 |
242 | 241 |
243 // ------------------------------------------------------------------ | 242 // ------------------------------------------------------------------ |
244 // ciMethod::compressed_linenumber_table | 243 // ciMethod::compressed_linenumber_table |
245 u_char* ciMethod::compressed_linenumber_table() const { | 244 u_char* ciMethod::compressed_linenumber_table() const { |
246 check_is_loaded(); | 245 check_is_loaded(); |
247 VM_ENTRY_MARK; | 246 VM_ENTRY_MARK; |
248 return get_methodOop()->compressed_linenumber_table(); | 247 return get_Method()->compressed_linenumber_table(); |
249 } | 248 } |
250 | 249 |
251 | 250 |
252 // ------------------------------------------------------------------ | 251 // ------------------------------------------------------------------ |
253 // ciMethod::line_number_from_bci | 252 // ciMethod::line_number_from_bci |
254 int ciMethod::line_number_from_bci(int bci) const { | 253 int ciMethod::line_number_from_bci(int bci) const { |
255 check_is_loaded(); | 254 check_is_loaded(); |
256 VM_ENTRY_MARK; | 255 VM_ENTRY_MARK; |
257 return get_methodOop()->line_number_from_bci(bci); | 256 return get_Method()->line_number_from_bci(bci); |
258 } | 257 } |
259 | 258 |
260 | 259 |
261 // ------------------------------------------------------------------ | 260 // ------------------------------------------------------------------ |
262 // ciMethod::vtable_index | 261 // ciMethod::vtable_index |
264 // Get the position of this method's entry in the vtable, if any. | 263 // Get the position of this method's entry in the vtable, if any. |
265 int ciMethod::vtable_index() { | 264 int ciMethod::vtable_index() { |
266 check_is_loaded(); | 265 check_is_loaded(); |
267 assert(holder()->is_linked(), "must be linked"); | 266 assert(holder()->is_linked(), "must be linked"); |
268 VM_ENTRY_MARK; | 267 VM_ENTRY_MARK; |
269 return get_methodOop()->vtable_index(); | 268 return get_Method()->vtable_index(); |
270 } | 269 } |
271 | 270 |
272 | 271 |
273 #ifdef SHARK | 272 #ifdef SHARK |
274 // ------------------------------------------------------------------ | 273 // ------------------------------------------------------------------ |
277 // Get the position of this method's entry in the itable, if any. | 276 // Get the position of this method's entry in the itable, if any. |
278 int ciMethod::itable_index() { | 277 int ciMethod::itable_index() { |
279 check_is_loaded(); | 278 check_is_loaded(); |
280 assert(holder()->is_linked(), "must be linked"); | 279 assert(holder()->is_linked(), "must be linked"); |
281 VM_ENTRY_MARK; | 280 VM_ENTRY_MARK; |
282 return klassItable::compute_itable_index(get_methodOop()); | 281 return klassItable::compute_itable_index(get_Method()); |
283 } | 282 } |
284 #endif // SHARK | 283 #endif // SHARK |
285 | 284 |
286 | 285 |
287 // ------------------------------------------------------------------ | 286 // ------------------------------------------------------------------ |
290 // Get the address of this method's native code, if any. | 289 // Get the address of this method's native code, if any. |
291 address ciMethod::native_entry() { | 290 address ciMethod::native_entry() { |
292 check_is_loaded(); | 291 check_is_loaded(); |
293 assert(flags().is_native(), "must be native method"); | 292 assert(flags().is_native(), "must be native method"); |
294 VM_ENTRY_MARK; | 293 VM_ENTRY_MARK; |
295 methodOop method = get_methodOop(); | 294 Method* method = get_Method(); |
296 address entry = method->native_function(); | 295 address entry = method->native_function(); |
297 assert(entry != NULL, "must be valid entry point"); | 296 assert(entry != NULL, "must be valid entry point"); |
298 return entry; | 297 return entry; |
299 } | 298 } |
300 | 299 |
304 // | 303 // |
305 // Get the entry point for running this method in the interpreter. | 304 // Get the entry point for running this method in the interpreter. |
306 address ciMethod::interpreter_entry() { | 305 address ciMethod::interpreter_entry() { |
307 check_is_loaded(); | 306 check_is_loaded(); |
308 VM_ENTRY_MARK; | 307 VM_ENTRY_MARK; |
309 methodHandle mh(THREAD, get_methodOop()); | 308 methodHandle mh(THREAD, get_Method()); |
310 return Interpreter::entry_for_method(mh); | 309 return Interpreter::entry_for_method(mh); |
311 } | 310 } |
312 | 311 |
313 | 312 |
314 // ------------------------------------------------------------------ | 313 // ------------------------------------------------------------------ |
319 check_is_loaded(); | 318 check_is_loaded(); |
320 if (_balanced_monitors) return true; | 319 if (_balanced_monitors) return true; |
321 | 320 |
322 // Analyze the method to see if monitors are used properly. | 321 // Analyze the method to see if monitors are used properly. |
323 VM_ENTRY_MARK; | 322 VM_ENTRY_MARK; |
324 methodHandle method(THREAD, get_methodOop()); | 323 methodHandle method(THREAD, get_Method()); |
325 assert(method->has_monitor_bytecodes(), "should have checked this"); | 324 assert(method->has_monitor_bytecodes(), "should have checked this"); |
326 | 325 |
327 // Check to see if a previous compilation computed the | 326 // Check to see if a previous compilation computed the |
328 // monitor-matching analysis. | 327 // monitor-matching analysis. |
329 if (method->guaranteed_monitor_matching()) { | 328 if (method->guaranteed_monitor_matching()) { |
424 // OSR when loading the locals. | 423 // OSR when loading the locals. |
425 | 424 |
426 BitMap ciMethod::live_local_oops_at_bci(int bci) { | 425 BitMap ciMethod::live_local_oops_at_bci(int bci) { |
427 VM_ENTRY_MARK; | 426 VM_ENTRY_MARK; |
428 InterpreterOopMap mask; | 427 InterpreterOopMap mask; |
429 OopMapCache::compute_one_oop_map(get_methodOop(), bci, &mask); | 428 OopMapCache::compute_one_oop_map(get_Method(), bci, &mask); |
430 int mask_size = max_locals(); | 429 int mask_size = max_locals(); |
431 BitMap result(mask_size); | 430 BitMap result(mask_size); |
432 result.clear(); | 431 result.clear(); |
433 int i; | 432 int i; |
434 for (i = 0; i < mask_size ; i++ ) { | 433 for (i = 0; i < mask_size ; i++ ) { |
605 VM_ENTRY_MARK; | 604 VM_ENTRY_MARK; |
606 | 605 |
607 methodHandle target; | 606 methodHandle target; |
608 { | 607 { |
609 MutexLocker locker(Compile_lock); | 608 MutexLocker locker(Compile_lock); |
610 klassOop context = actual_recv->get_klassOop(); | 609 Klass* context = actual_recv->get_Klass(); |
611 target = Dependencies::find_unique_concrete_method(context, | 610 target = Dependencies::find_unique_concrete_method(context, |
612 root_m->get_methodOop()); | 611 root_m->get_Method()); |
613 // %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods. | 612 // %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods. |
614 } | 613 } |
615 | 614 |
616 #ifndef PRODUCT | 615 #ifndef PRODUCT |
617 if (TraceDependencies && target() != NULL && target() != root_m->get_methodOop()) { | 616 if (TraceDependencies && target() != NULL && target() != root_m->get_Method()) { |
618 tty->print("found a non-root unique target method"); | 617 tty->print("found a non-root unique target method"); |
619 tty->print_cr(" context = %s", instanceKlass::cast(actual_recv->get_klassOop())->external_name()); | 618 tty->print_cr(" context = %s", InstanceKlass::cast(actual_recv->get_Klass())->external_name()); |
620 tty->print(" method = "); | 619 tty->print(" method = "); |
621 target->print_short_name(tty); | 620 target->print_short_name(tty); |
622 tty->cr(); | 621 tty->cr(); |
623 } | 622 } |
624 #endif //PRODUCT | 623 #endif //PRODUCT |
625 | 624 |
626 if (target() == NULL) { | 625 if (target() == NULL) { |
627 return NULL; | 626 return NULL; |
628 } | 627 } |
629 if (target() == root_m->get_methodOop()) { | 628 if (target() == root_m->get_Method()) { |
630 return root_m; | 629 return root_m; |
631 } | 630 } |
632 if (!root_m->is_public() && | 631 if (!root_m->is_public() && |
633 !root_m->is_protected()) { | 632 !root_m->is_protected()) { |
634 // If we are going to reason about inheritance, it's easiest | 633 // If we are going to reason about inheritance, it's easiest |
638 // methods in other packages. | 637 // methods in other packages. |
639 // %%% TO DO: Work out logic for package-private methods | 638 // %%% TO DO: Work out logic for package-private methods |
640 // with the same name but different vtable indexes. | 639 // with the same name but different vtable indexes. |
641 return NULL; | 640 return NULL; |
642 } | 641 } |
643 return CURRENT_THREAD_ENV->get_object(target())->as_method(); | 642 return CURRENT_THREAD_ENV->get_method(target()); |
644 } | 643 } |
645 | 644 |
646 // ------------------------------------------------------------------ | 645 // ------------------------------------------------------------------ |
647 // ciMethod::resolve_invoke | 646 // ciMethod::resolve_invoke |
648 // | 647 // |
650 // Return NULL if the call has no target or the target is abstract. | 649 // Return NULL if the call has no target or the target is abstract. |
651 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver) { | 650 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver) { |
652 check_is_loaded(); | 651 check_is_loaded(); |
653 VM_ENTRY_MARK; | 652 VM_ENTRY_MARK; |
654 | 653 |
655 KlassHandle caller_klass (THREAD, caller->get_klassOop()); | 654 KlassHandle caller_klass (THREAD, caller->get_Klass()); |
656 KlassHandle h_recv (THREAD, exact_receiver->get_klassOop()); | 655 KlassHandle h_recv (THREAD, exact_receiver->get_Klass()); |
657 KlassHandle h_resolved (THREAD, holder()->get_klassOop()); | 656 KlassHandle h_resolved (THREAD, holder()->get_Klass()); |
658 Symbol* h_name = name()->get_symbol(); | 657 Symbol* h_name = name()->get_symbol(); |
659 Symbol* h_signature = signature()->get_symbol(); | 658 Symbol* h_signature = signature()->get_symbol(); |
660 | 659 |
661 methodHandle m; | 660 methodHandle m; |
662 // Only do exact lookup if receiver klass has been linked. Otherwise, | 661 // Only do exact lookup if receiver klass has been linked. Otherwise, |
663 // the vtable has not been setup, and the LinkResolver will fail. | 662 // the vtable has not been setup, and the LinkResolver will fail. |
664 if (h_recv->oop_is_javaArray() | 663 if (h_recv->oop_is_array() |
665 || | 664 || |
666 instanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { | 665 InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { |
667 if (holder()->is_interface()) { | 666 if (holder()->is_interface()) { |
668 m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); | 667 m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); |
669 } else { | 668 } else { |
670 m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); | 669 m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); |
671 } | 670 } |
675 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) | 674 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) |
676 return NULL; | 675 return NULL; |
677 } | 676 } |
678 | 677 |
679 ciMethod* result = this; | 678 ciMethod* result = this; |
680 if (m() != get_methodOop()) { | 679 if (m() != get_Method()) { |
681 result = CURRENT_THREAD_ENV->get_object(m())->as_method(); | 680 result = CURRENT_THREAD_ENV->get_method(m()); |
682 } | 681 } |
683 | 682 |
684 // Don't return abstract methods because they aren't | 683 // Don't return abstract methods because they aren't |
685 // optimizable or interesting. | 684 // optimizable or interesting. |
686 if (result->is_abstract()) { | 685 if (result->is_abstract()) { |
692 | 691 |
693 // ------------------------------------------------------------------ | 692 // ------------------------------------------------------------------ |
694 // ciMethod::resolve_vtable_index | 693 // ciMethod::resolve_vtable_index |
695 // | 694 // |
696 // Given a known receiver klass, find the vtable index for the call. | 695 // Given a known receiver klass, find the vtable index for the call. |
697 // Return methodOopDesc::invalid_vtable_index if the vtable_index is unknown. | 696 // Return Method::invalid_vtable_index if the vtable_index is unknown. |
698 int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) { | 697 int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) { |
699 check_is_loaded(); | 698 check_is_loaded(); |
700 | 699 |
701 int vtable_index = methodOopDesc::invalid_vtable_index; | 700 int vtable_index = Method::invalid_vtable_index; |
702 // Only do lookup if receiver klass has been linked. Otherwise, | 701 // Only do lookup if receiver klass has been linked. Otherwise, |
703 // the vtable has not been setup, and the LinkResolver will fail. | 702 // the vtable has not been setup, and the LinkResolver will fail. |
704 if (!receiver->is_interface() | 703 if (!receiver->is_interface() |
705 && (!receiver->is_instance_klass() || | 704 && (!receiver->is_instance_klass() || |
706 receiver->as_instance_klass()->is_linked())) { | 705 receiver->as_instance_klass()->is_linked())) { |
707 VM_ENTRY_MARK; | 706 VM_ENTRY_MARK; |
708 | 707 |
709 KlassHandle caller_klass (THREAD, caller->get_klassOop()); | 708 KlassHandle caller_klass (THREAD, caller->get_Klass()); |
710 KlassHandle h_recv (THREAD, receiver->get_klassOop()); | 709 KlassHandle h_recv (THREAD, receiver->get_Klass()); |
711 Symbol* h_name = name()->get_symbol(); | 710 Symbol* h_name = name()->get_symbol(); |
712 Symbol* h_signature = signature()->get_symbol(); | 711 Symbol* h_signature = signature()->get_symbol(); |
713 | 712 |
714 vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass); | 713 vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass); |
715 if (vtable_index == methodOopDesc::nonvirtual_vtable_index) { | 714 if (vtable_index == Method::nonvirtual_vtable_index) { |
716 // A statically bound method. Return "no such index". | 715 // A statically bound method. Return "no such index". |
717 vtable_index = methodOopDesc::invalid_vtable_index; | 716 vtable_index = Method::invalid_vtable_index; |
718 } | 717 } |
719 } | 718 } |
720 | 719 |
721 return vtable_index; | 720 return vtable_index; |
722 } | 721 } |
801 } | 800 } |
802 | 801 |
803 // ------------------------------------------------------------------ | 802 // ------------------------------------------------------------------ |
804 // ciMethod::ensure_method_data | 803 // ciMethod::ensure_method_data |
805 // | 804 // |
806 // Generate new methodDataOop objects at compile time. | 805 // Generate new MethodData* objects at compile time. |
807 // Return true if allocation was successful or no MDO is required. | 806 // Return true if allocation was successful or no MDO is required. |
808 bool ciMethod::ensure_method_data(methodHandle h_m) { | 807 bool ciMethod::ensure_method_data(methodHandle h_m) { |
809 EXCEPTION_CONTEXT; | 808 EXCEPTION_CONTEXT; |
810 if (is_native() || is_abstract() || h_m()->is_accessor()) return true; | 809 if (is_native() || is_abstract() || h_m()->is_accessor()) return true; |
811 if (h_m()->method_data() == NULL) { | 810 if (h_m()->method_data() == NULL) { |
812 methodOopDesc::build_interpreter_method_data(h_m, THREAD); | 811 Method::build_interpreter_method_data(h_m, THREAD); |
813 if (HAS_PENDING_EXCEPTION) { | 812 if (HAS_PENDING_EXCEPTION) { |
814 CLEAR_PENDING_EXCEPTION; | 813 CLEAR_PENDING_EXCEPTION; |
815 } | 814 } |
816 } | 815 } |
817 if (h_m()->method_data() != NULL) { | 816 if (h_m()->method_data() != NULL) { |
818 _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data(); | 817 _method_data = CURRENT_ENV->get_method_data(h_m()->method_data()); |
819 _method_data->load_data(); | 818 _method_data->load_data(); |
820 return true; | 819 return true; |
821 } else { | 820 } else { |
822 _method_data = CURRENT_ENV->get_empty_methodData(); | 821 _method_data = CURRENT_ENV->get_empty_methodData(); |
823 return false; | 822 return false; |
827 // public, retroactive version | 826 // public, retroactive version |
828 bool ciMethod::ensure_method_data() { | 827 bool ciMethod::ensure_method_data() { |
829 bool result = true; | 828 bool result = true; |
830 if (_method_data == NULL || _method_data->is_empty()) { | 829 if (_method_data == NULL || _method_data->is_empty()) { |
831 GUARDED_VM_ENTRY({ | 830 GUARDED_VM_ENTRY({ |
832 result = ensure_method_data(get_methodOop()); | 831 result = ensure_method_data(get_Method()); |
833 }); | 832 }); |
834 } | 833 } |
835 return result; | 834 return result; |
836 } | 835 } |
837 | 836 |
844 return _method_data; | 843 return _method_data; |
845 } | 844 } |
846 VM_ENTRY_MARK; | 845 VM_ENTRY_MARK; |
847 ciEnv* env = CURRENT_ENV; | 846 ciEnv* env = CURRENT_ENV; |
848 Thread* my_thread = JavaThread::current(); | 847 Thread* my_thread = JavaThread::current(); |
849 methodHandle h_m(my_thread, get_methodOop()); | 848 methodHandle h_m(my_thread, get_Method()); |
850 | 849 |
851 if (h_m()->method_data() != NULL) { | 850 if (h_m()->method_data() != NULL) { |
852 _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data(); | 851 _method_data = CURRENT_ENV->get_method_data(h_m()->method_data()); |
853 _method_data->load_data(); | 852 _method_data->load_data(); |
854 } else { | 853 } else { |
855 _method_data = CURRENT_ENV->get_empty_methodData(); | 854 _method_data = CURRENT_ENV->get_empty_methodData(); |
856 } | 855 } |
857 return _method_data; | 856 return _method_data; |
892 // | 891 // |
893 // Should this method be excluded from compilation? | 892 // Should this method be excluded from compilation? |
894 bool ciMethod::should_exclude() { | 893 bool ciMethod::should_exclude() { |
895 check_is_loaded(); | 894 check_is_loaded(); |
896 VM_ENTRY_MARK; | 895 VM_ENTRY_MARK; |
897 methodHandle mh(THREAD, get_methodOop()); | 896 methodHandle mh(THREAD, get_Method()); |
898 bool ignore; | 897 bool ignore; |
899 return CompilerOracle::should_exclude(mh, ignore); | 898 return CompilerOracle::should_exclude(mh, ignore); |
900 } | 899 } |
901 | 900 |
902 // ------------------------------------------------------------------ | 901 // ------------------------------------------------------------------ |
904 // | 903 // |
905 // Should this method be inlined during compilation? | 904 // Should this method be inlined during compilation? |
906 bool ciMethod::should_inline() { | 905 bool ciMethod::should_inline() { |
907 check_is_loaded(); | 906 check_is_loaded(); |
908 VM_ENTRY_MARK; | 907 VM_ENTRY_MARK; |
909 methodHandle mh(THREAD, get_methodOop()); | 908 methodHandle mh(THREAD, get_Method()); |
910 return CompilerOracle::should_inline(mh); | 909 return CompilerOracle::should_inline(mh); |
911 } | 910 } |
912 | 911 |
913 // ------------------------------------------------------------------ | 912 // ------------------------------------------------------------------ |
914 // ciMethod::should_not_inline | 913 // ciMethod::should_not_inline |
915 // | 914 // |
916 // Should this method be disallowed from inlining during compilation? | 915 // Should this method be disallowed from inlining during compilation? |
917 bool ciMethod::should_not_inline() { | 916 bool ciMethod::should_not_inline() { |
918 check_is_loaded(); | 917 check_is_loaded(); |
919 VM_ENTRY_MARK; | 918 VM_ENTRY_MARK; |
920 methodHandle mh(THREAD, get_methodOop()); | 919 methodHandle mh(THREAD, get_Method()); |
921 return CompilerOracle::should_not_inline(mh); | 920 return CompilerOracle::should_not_inline(mh); |
922 } | 921 } |
923 | 922 |
924 // ------------------------------------------------------------------ | 923 // ------------------------------------------------------------------ |
925 // ciMethod::should_print_assembly | 924 // ciMethod::should_print_assembly |
926 // | 925 // |
927 // Should the compiler print the generated code for this method? | 926 // Should the compiler print the generated code for this method? |
928 bool ciMethod::should_print_assembly() { | 927 bool ciMethod::should_print_assembly() { |
929 check_is_loaded(); | 928 check_is_loaded(); |
930 VM_ENTRY_MARK; | 929 VM_ENTRY_MARK; |
931 methodHandle mh(THREAD, get_methodOop()); | 930 methodHandle mh(THREAD, get_Method()); |
932 return CompilerOracle::should_print(mh); | 931 return CompilerOracle::should_print(mh); |
933 } | 932 } |
934 | 933 |
935 // ------------------------------------------------------------------ | 934 // ------------------------------------------------------------------ |
936 // ciMethod::break_at_execute | 935 // ciMethod::break_at_execute |
938 // Should the compiler insert a breakpoint into the generated code | 937 // Should the compiler insert a breakpoint into the generated code |
939 // method? | 938 // method? |
940 bool ciMethod::break_at_execute() { | 939 bool ciMethod::break_at_execute() { |
941 check_is_loaded(); | 940 check_is_loaded(); |
942 VM_ENTRY_MARK; | 941 VM_ENTRY_MARK; |
943 methodHandle mh(THREAD, get_methodOop()); | 942 methodHandle mh(THREAD, get_Method()); |
944 return CompilerOracle::should_break_at(mh); | 943 return CompilerOracle::should_break_at(mh); |
945 } | 944 } |
946 | 945 |
947 // ------------------------------------------------------------------ | 946 // ------------------------------------------------------------------ |
948 // ciMethod::has_option | 947 // ciMethod::has_option |
949 // | 948 // |
950 bool ciMethod::has_option(const char* option) { | 949 bool ciMethod::has_option(const char* option) { |
951 check_is_loaded(); | 950 check_is_loaded(); |
952 VM_ENTRY_MARK; | 951 VM_ENTRY_MARK; |
953 methodHandle mh(THREAD, get_methodOop()); | 952 methodHandle mh(THREAD, get_Method()); |
954 return CompilerOracle::has_option_string(mh, option); | 953 return CompilerOracle::has_option_string(mh, option); |
955 } | 954 } |
956 | 955 |
957 // ------------------------------------------------------------------ | 956 // ------------------------------------------------------------------ |
958 // ciMethod::can_be_compiled | 957 // ciMethod::can_be_compiled |
978 if (is_c1_compile(env->comp_level())) { | 977 if (is_c1_compile(env->comp_level())) { |
979 _is_c1_compilable = false; | 978 _is_c1_compilable = false; |
980 } else { | 979 } else { |
981 _is_c2_compilable = false; | 980 _is_c2_compilable = false; |
982 } | 981 } |
983 get_methodOop()->set_not_compilable(env->comp_level()); | 982 get_Method()->set_not_compilable(env->comp_level()); |
984 } | 983 } |
985 | 984 |
986 // ------------------------------------------------------------------ | 985 // ------------------------------------------------------------------ |
987 // ciMethod::can_be_osr_compiled | 986 // ciMethod::can_be_osr_compiled |
988 // | 987 // |
993 // is currently unused. | 992 // is currently unused. |
994 bool ciMethod::can_be_osr_compiled(int entry_bci) { | 993 bool ciMethod::can_be_osr_compiled(int entry_bci) { |
995 check_is_loaded(); | 994 check_is_loaded(); |
996 VM_ENTRY_MARK; | 995 VM_ENTRY_MARK; |
997 ciEnv* env = CURRENT_ENV; | 996 ciEnv* env = CURRENT_ENV; |
998 return !get_methodOop()->is_not_osr_compilable(env->comp_level()); | 997 return !get_Method()->is_not_osr_compilable(env->comp_level()); |
999 } | 998 } |
1000 | 999 |
1001 // ------------------------------------------------------------------ | 1000 // ------------------------------------------------------------------ |
1002 // ciMethod::has_compiled_code | 1001 // ciMethod::has_compiled_code |
1003 bool ciMethod::has_compiled_code() { | 1002 bool ciMethod::has_compiled_code() { |
1004 VM_ENTRY_MARK; | 1003 VM_ENTRY_MARK; |
1005 return get_methodOop()->code() != NULL; | 1004 return get_Method()->code() != NULL; |
1006 } | 1005 } |
1007 | 1006 |
1008 int ciMethod::comp_level() { | 1007 int ciMethod::comp_level() { |
1009 check_is_loaded(); | 1008 check_is_loaded(); |
1010 VM_ENTRY_MARK; | 1009 VM_ENTRY_MARK; |
1011 nmethod* nm = get_methodOop()->code(); | 1010 nmethod* nm = get_Method()->code(); |
1012 if (nm != NULL) return nm->comp_level(); | 1011 if (nm != NULL) return nm->comp_level(); |
1013 return 0; | 1012 return 0; |
1014 } | 1013 } |
1015 | 1014 |
1016 int ciMethod::highest_osr_comp_level() { | 1015 int ciMethod::highest_osr_comp_level() { |
1017 check_is_loaded(); | 1016 check_is_loaded(); |
1018 VM_ENTRY_MARK; | 1017 VM_ENTRY_MARK; |
1019 return get_methodOop()->highest_osr_comp_level(); | 1018 return get_Method()->highest_osr_comp_level(); |
1020 } | 1019 } |
1021 | 1020 |
1022 // ------------------------------------------------------------------ | 1021 // ------------------------------------------------------------------ |
1023 // ciMethod::code_size_for_inlining | 1022 // ciMethod::code_size_for_inlining |
1024 // | 1023 // |
1025 // Code size for inlining decisions. This method returns a code | 1024 // Code size for inlining decisions. This method returns a code |
1026 // size of 1 for methods which has the ForceInline annotation. | 1025 // size of 1 for methods which has the ForceInline annotation. |
1027 int ciMethod::code_size_for_inlining() { | 1026 int ciMethod::code_size_for_inlining() { |
1028 check_is_loaded(); | 1027 check_is_loaded(); |
1029 if (get_methodOop()->force_inline()) { | 1028 if (get_Method()->force_inline()) { |
1030 return 1; | 1029 return 1; |
1031 } | 1030 } |
1032 return code_size(); | 1031 return code_size(); |
1033 } | 1032 } |
1034 | 1033 |
1040 // junk like exception handler, stubs, and constant table, which are | 1039 // junk like exception handler, stubs, and constant table, which are |
1041 // not highly relevant to an inlined method. So we use the more | 1040 // not highly relevant to an inlined method. So we use the more |
1042 // specific accessor nmethod::insts_size. | 1041 // specific accessor nmethod::insts_size. |
1043 int ciMethod::instructions_size(int comp_level) { | 1042 int ciMethod::instructions_size(int comp_level) { |
1044 GUARDED_VM_ENTRY( | 1043 GUARDED_VM_ENTRY( |
1045 nmethod* code = get_methodOop()->code(); | 1044 nmethod* code = get_Method()->code(); |
1046 if (code != NULL && (comp_level == CompLevel_any || comp_level == code->comp_level())) { | 1045 if (code != NULL && (comp_level == CompLevel_any || comp_level == code->comp_level())) { |
1047 return code->insts_end() - code->verified_entry_point(); | 1046 return code->insts_end() - code->verified_entry_point(); |
1048 } | 1047 } |
1049 return 0; | 1048 return 0; |
1050 ) | 1049 ) |
1052 | 1051 |
1053 // ------------------------------------------------------------------ | 1052 // ------------------------------------------------------------------ |
1054 // ciMethod::log_nmethod_identity | 1053 // ciMethod::log_nmethod_identity |
1055 void ciMethod::log_nmethod_identity(xmlStream* log) { | 1054 void ciMethod::log_nmethod_identity(xmlStream* log) { |
1056 GUARDED_VM_ENTRY( | 1055 GUARDED_VM_ENTRY( |
1057 nmethod* code = get_methodOop()->code(); | 1056 nmethod* code = get_Method()->code(); |
1058 if (code != NULL) { | 1057 if (code != NULL) { |
1059 code->log_identity(log); | 1058 code->log_identity(log); |
1060 } | 1059 } |
1061 ) | 1060 ) |
1062 } | 1061 } |
1065 // ciMethod::is_not_reached | 1064 // ciMethod::is_not_reached |
1066 bool ciMethod::is_not_reached(int bci) { | 1065 bool ciMethod::is_not_reached(int bci) { |
1067 check_is_loaded(); | 1066 check_is_loaded(); |
1068 VM_ENTRY_MARK; | 1067 VM_ENTRY_MARK; |
1069 return Interpreter::is_not_reached( | 1068 return Interpreter::is_not_reached( |
1070 methodHandle(THREAD, get_methodOop()), bci); | 1069 methodHandle(THREAD, get_Method()), bci); |
1071 } | 1070 } |
1072 | 1071 |
1073 // ------------------------------------------------------------------ | 1072 // ------------------------------------------------------------------ |
1074 // ciMethod::was_never_executed | 1073 // ciMethod::was_never_executed |
1075 bool ciMethod::was_executed_more_than(int times) { | 1074 bool ciMethod::was_executed_more_than(int times) { |
1076 VM_ENTRY_MARK; | 1075 VM_ENTRY_MARK; |
1077 return get_methodOop()->was_executed_more_than(times); | 1076 return get_Method()->was_executed_more_than(times); |
1078 } | 1077 } |
1079 | 1078 |
1080 // ------------------------------------------------------------------ | 1079 // ------------------------------------------------------------------ |
1081 // ciMethod::has_unloaded_classes_in_signature | 1080 // ciMethod::has_unloaded_classes_in_signature |
1082 bool ciMethod::has_unloaded_classes_in_signature() { | 1081 bool ciMethod::has_unloaded_classes_in_signature() { |
1083 VM_ENTRY_MARK; | 1082 VM_ENTRY_MARK; |
1084 { | 1083 { |
1085 EXCEPTION_MARK; | 1084 EXCEPTION_MARK; |
1086 methodHandle m(THREAD, get_methodOop()); | 1085 methodHandle m(THREAD, get_Method()); |
1087 bool has_unloaded = methodOopDesc::has_unloaded_classes_in_signature(m, (JavaThread *)THREAD); | 1086 bool has_unloaded = Method::has_unloaded_classes_in_signature(m, (JavaThread *)THREAD); |
1088 if( HAS_PENDING_EXCEPTION ) { | 1087 if( HAS_PENDING_EXCEPTION ) { |
1089 CLEAR_PENDING_EXCEPTION; | 1088 CLEAR_PENDING_EXCEPTION; |
1090 return true; // Declare that we may have unloaded classes | 1089 return true; // Declare that we may have unloaded classes |
1091 } | 1090 } |
1092 return has_unloaded; | 1091 return has_unloaded; |
1095 | 1094 |
1096 // ------------------------------------------------------------------ | 1095 // ------------------------------------------------------------------ |
1097 // ciMethod::is_klass_loaded | 1096 // ciMethod::is_klass_loaded |
1098 bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const { | 1097 bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const { |
1099 VM_ENTRY_MARK; | 1098 VM_ENTRY_MARK; |
1100 return get_methodOop()->is_klass_loaded(refinfo_index, must_be_resolved); | 1099 return get_Method()->is_klass_loaded(refinfo_index, must_be_resolved); |
1101 } | 1100 } |
1102 | 1101 |
1103 // ------------------------------------------------------------------ | 1102 // ------------------------------------------------------------------ |
1104 // ciMethod::check_call | 1103 // ciMethod::check_call |
1105 bool ciMethod::check_call(int refinfo_index, bool is_static) const { | 1104 bool ciMethod::check_call(int refinfo_index, bool is_static) const { |
1106 VM_ENTRY_MARK; | 1105 VM_ENTRY_MARK; |
1107 { | 1106 { |
1108 EXCEPTION_MARK; | 1107 EXCEPTION_MARK; |
1109 HandleMark hm(THREAD); | 1108 HandleMark hm(THREAD); |
1110 constantPoolHandle pool (THREAD, get_methodOop()->constants()); | 1109 constantPoolHandle pool (THREAD, get_Method()->constants()); |
1111 methodHandle spec_method; | 1110 methodHandle spec_method; |
1112 KlassHandle spec_klass; | 1111 KlassHandle spec_klass; |
1113 Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual); | 1112 Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual); |
1114 LinkResolver::resolve_method_statically(spec_method, spec_klass, code, pool, refinfo_index, THREAD); | 1113 LinkResolver::resolve_method_statically(spec_method, spec_klass, code, pool, refinfo_index, THREAD); |
1115 if (HAS_PENDING_EXCEPTION) { | 1114 if (HAS_PENDING_EXCEPTION) { |
1126 // ciMethod::print_codes | 1125 // ciMethod::print_codes |
1127 // | 1126 // |
1128 // Print the bytecodes for this method. | 1127 // Print the bytecodes for this method. |
1129 void ciMethod::print_codes_on(outputStream* st) { | 1128 void ciMethod::print_codes_on(outputStream* st) { |
1130 check_is_loaded(); | 1129 check_is_loaded(); |
1131 GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(st);) | 1130 GUARDED_VM_ENTRY(get_Method()->print_codes_on(st);) |
1132 } | 1131 } |
1133 | 1132 |
1134 | 1133 |
1135 #define FETCH_FLAG_FROM_VM(flag_accessor) { \ | 1134 #define FETCH_FLAG_FROM_VM(flag_accessor) { \ |
1136 check_is_loaded(); \ | 1135 check_is_loaded(); \ |
1137 VM_ENTRY_MARK; \ | 1136 VM_ENTRY_MARK; \ |
1138 return get_methodOop()->flag_accessor(); \ | 1137 return get_Method()->flag_accessor(); \ |
1139 } | 1138 } |
1140 | 1139 |
1141 bool ciMethod::is_empty_method() const { FETCH_FLAG_FROM_VM(is_empty_method); } | 1140 bool ciMethod::is_empty_method() const { FETCH_FLAG_FROM_VM(is_empty_method); } |
1142 bool ciMethod::is_vanilla_constructor() const { FETCH_FLAG_FROM_VM(is_vanilla_constructor); } | 1141 bool ciMethod::is_vanilla_constructor() const { FETCH_FLAG_FROM_VM(is_vanilla_constructor); } |
1143 bool ciMethod::has_loops () const { FETCH_FLAG_FROM_VM(has_loops); } | 1142 bool ciMethod::has_loops () const { FETCH_FLAG_FROM_VM(has_loops); } |
1172 // ciMethod::print_codes | 1171 // ciMethod::print_codes |
1173 // | 1172 // |
1174 // Print a range of the bytecodes for this method. | 1173 // Print a range of the bytecodes for this method. |
1175 void ciMethod::print_codes_on(int from, int to, outputStream* st) { | 1174 void ciMethod::print_codes_on(int from, int to, outputStream* st) { |
1176 check_is_loaded(); | 1175 check_is_loaded(); |
1177 GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(from, to, st);) | 1176 GUARDED_VM_ENTRY(get_Method()->print_codes_on(from, to, st);) |
1178 } | 1177 } |
1179 | 1178 |
1180 // ------------------------------------------------------------------ | 1179 // ------------------------------------------------------------------ |
1181 // ciMethod::print_name | 1180 // ciMethod::print_name |
1182 // | 1181 // |
1183 // Print the name of this method, including signature and some flags. | 1182 // Print the name of this method, including signature and some flags. |
1184 void ciMethod::print_name(outputStream* st) { | 1183 void ciMethod::print_name(outputStream* st) { |
1185 check_is_loaded(); | 1184 check_is_loaded(); |
1186 GUARDED_VM_ENTRY(get_methodOop()->print_name(st);) | 1185 GUARDED_VM_ENTRY(get_Method()->print_name(st);) |
1187 } | 1186 } |
1188 | 1187 |
1189 // ------------------------------------------------------------------ | 1188 // ------------------------------------------------------------------ |
1190 // ciMethod::print_short_name | 1189 // ciMethod::print_short_name |
1191 // | 1190 // |
1192 // Print the name of this method, without signature. | 1191 // Print the name of this method, without signature. |
1193 void ciMethod::print_short_name(outputStream* st) { | 1192 void ciMethod::print_short_name(outputStream* st) { |
1194 if (is_loaded()) { | 1193 if (is_loaded()) { |
1195 GUARDED_VM_ENTRY(get_methodOop()->print_short_name(st);); | 1194 GUARDED_VM_ENTRY(get_Method()->print_short_name(st);); |
1196 } else { | 1195 } else { |
1197 // Fall back if method is not loaded. | 1196 // Fall back if method is not loaded. |
1198 holder()->print_name_on(st); | 1197 holder()->print_name_on(st); |
1199 st->print("::"); | 1198 st->print("::"); |
1200 name()->print_symbol_on(st); | 1199 name()->print_symbol_on(st); |
1206 // ------------------------------------------------------------------ | 1205 // ------------------------------------------------------------------ |
1207 // ciMethod::print_impl | 1206 // ciMethod::print_impl |
1208 // | 1207 // |
1209 // Implementation of the print method. | 1208 // Implementation of the print method. |
1210 void ciMethod::print_impl(outputStream* st) { | 1209 void ciMethod::print_impl(outputStream* st) { |
1211 ciObject::print_impl(st); | 1210 ciMetadata::print_impl(st); |
1212 st->print(" name="); | 1211 st->print(" name="); |
1213 name()->print_symbol_on(st); | 1212 name()->print_symbol_on(st); |
1214 st->print(" holder="); | 1213 st->print(" holder="); |
1215 holder()->print_name_on(st); | 1214 holder()->print_name_on(st); |
1216 st->print(" signature="); | 1215 st->print(" signature="); |