275 assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), ""); |
275 assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), ""); |
276 // index >= 0; FIXME: inline and customize set_direct_or_vtable_call |
276 // index >= 0; FIXME: inline and customize set_direct_or_vtable_call |
277 set_direct_or_vtable_call(invoke_code, method, index, false); |
277 set_direct_or_vtable_call(invoke_code, method, index, false); |
278 } |
278 } |
279 |
279 |
280 void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) { |
280 void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, |
|
281 Klass* referenced_klass, |
|
282 const methodHandle& method, int index) { |
281 assert(method->method_holder()->verify_itable_index(index), ""); |
283 assert(method->method_holder()->verify_itable_index(index), ""); |
282 assert(invoke_code == Bytecodes::_invokeinterface, ""); |
284 assert(invoke_code == Bytecodes::_invokeinterface, ""); |
283 InstanceKlass* interf = method->method_holder(); |
285 InstanceKlass* interf = method->method_holder(); |
284 assert(interf->is_interface(), "must be an interface"); |
286 assert(interf->is_interface(), "must be an interface"); |
285 assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here"); |
287 assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here"); |
286 set_f1(interf); |
288 set_f1(referenced_klass); |
287 set_f2(index); |
289 set_f2((intx)method()); |
288 set_method_flags(as_TosState(method->result_type()), |
290 set_method_flags(as_TosState(method->result_type()), |
289 0, // no option bits |
291 0, // no option bits |
290 method()->size_of_parameters()); |
292 method()->size_of_parameters()); |
291 set_bytecode_1(Bytecodes::_invokeinterface); |
293 set_bytecode_1(Bytecodes::_invokeinterface); |
292 } |
294 } |
511 return resolved_references->obj_at(ref_index); |
513 return resolved_references->obj_at(ref_index); |
512 } |
514 } |
513 |
515 |
514 |
516 |
515 #if INCLUDE_JVMTI |
517 #if INCLUDE_JVMTI |
|
518 |
|
519 void log_adjust(const char* entry_type, Method* old_method, Method* new_method, bool* trace_name_printed) { |
|
520 if (log_is_enabled(Info, redefine, class, update)) { |
|
521 ResourceMark rm; |
|
522 if (!(*trace_name_printed)) { |
|
523 log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name()); |
|
524 *trace_name_printed = true; |
|
525 } |
|
526 log_debug(redefine, class, update, constantpool) |
|
527 ("cpc %s entry update: %s(%s)", entry_type, new_method->name()->as_C_string(), new_method->signature()->as_C_string()); |
|
528 } |
|
529 } |
|
530 |
516 // RedefineClasses() API support: |
531 // RedefineClasses() API support: |
517 // If this ConstantPoolCacheEntry refers to old_method then update it |
532 // If this ConstantPoolCacheEntry refers to old_method then update it |
518 // to refer to new_method. |
533 // to refer to new_method. |
519 bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method, |
534 void ConstantPoolCacheEntry::adjust_method_entry(Method* old_method, |
520 Method* new_method, bool * trace_name_printed) { |
535 Method* new_method, bool * trace_name_printed) { |
521 |
536 |
522 if (is_vfinal()) { |
537 if (is_vfinal()) { |
523 // virtual and final so _f2 contains method ptr instead of vtable index |
538 // virtual and final so _f2 contains method ptr instead of vtable index |
524 if (f2_as_vfinal_method() == old_method) { |
539 if (f2_as_vfinal_method() == old_method) { |
525 // match old_method so need an update |
540 // match old_method so need an update |
526 // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values |
541 // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values |
527 _f2 = (intptr_t)new_method; |
542 _f2 = (intptr_t)new_method; |
528 if (log_is_enabled(Info, redefine, class, update)) { |
543 log_adjust("vfinal", old_method, new_method, trace_name_printed); |
529 ResourceMark rm; |
544 } |
530 if (!(*trace_name_printed)) { |
545 return; |
531 log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name()); |
546 } |
532 *trace_name_printed = true; |
547 |
533 } |
548 assert (_f1 != NULL, "should not call with uninteresting entry"); |
534 log_debug(redefine, class, update, constantpool) |
549 |
535 ("cpc vf-entry update: %s(%s)", new_method->name()->as_C_string(), new_method->signature()->as_C_string()); |
550 if (!(_f1->is_method())) { |
536 } |
551 // _f1 is a Klass* for an interface, _f2 is the method |
537 return true; |
552 if (f2_as_interface_method() == old_method) { |
538 } |
553 _f2 = (intptr_t)new_method; |
539 |
554 log_adjust("interface", old_method, new_method, trace_name_printed); |
540 // f1() is not used with virtual entries so bail out |
555 } |
541 return false; |
556 } else if (_f1 == old_method) { |
542 } |
|
543 |
|
544 if (_f1 == NULL) { |
|
545 // NULL f1() means this is a virtual entry so bail out |
|
546 // We are assuming that the vtable index does not need change. |
|
547 return false; |
|
548 } |
|
549 |
|
550 if (_f1 == old_method) { |
|
551 _f1 = new_method; |
557 _f1 = new_method; |
552 if (log_is_enabled(Info, redefine, class, update)) { |
558 log_adjust("special, static or dynamic", old_method, new_method, trace_name_printed); |
553 ResourceMark rm; |
559 } |
554 if (!(*trace_name_printed)) { |
|
555 log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name()); |
|
556 *trace_name_printed = true; |
|
557 } |
|
558 log_debug(redefine, class, update, constantpool) |
|
559 ("cpc entry update: %s(%s)", new_method->name()->as_C_string(), new_method->signature()->as_C_string()); |
|
560 } |
|
561 return true; |
|
562 } |
|
563 |
|
564 return false; |
|
565 } |
560 } |
566 |
561 |
567 // a constant pool cache entry should never contain old or obsolete methods |
562 // a constant pool cache entry should never contain old or obsolete methods |
568 bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() { |
563 bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() { |
569 if (is_vfinal()) { |
564 Method* m = get_interesting_method_entry(NULL); |
570 // virtual and final so _f2 contains method ptr instead of vtable index |
565 // return false if m refers to a non-deleted old or obsolete method |
571 Metadata* f2 = (Metadata*)_f2; |
566 if (m != NULL) { |
572 // Return false if _f2 refers to an old or an obsolete method. |
567 assert(m->is_valid() && m->is_method(), "m is a valid method"); |
573 // _f2 == NULL || !_f2->is_method() are just as unexpected here. |
568 return !m->is_old() && !m->is_obsolete(); // old is always set for old and obsolete |
574 return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() && |
569 } else { |
575 !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete()); |
|
576 } else if (_f1 == NULL || |
|
577 (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) { |
|
578 // _f1 == NULL || !_f1->is_method() are OK here |
|
579 return true; |
570 return true; |
580 } |
571 } |
581 // return false if _f1 refers to a non-deleted old or obsolete method |
|
582 return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() && |
|
583 (f1_as_method()->is_deleted() || |
|
584 (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete()))); |
|
585 } |
572 } |
586 |
573 |
587 Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) { |
574 Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) { |
588 if (!is_method_entry()) { |
575 if (!is_method_entry()) { |
589 // not a method entry so not interesting by default |
576 // not a method entry so not interesting by default |