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