1 /*
2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
384
385
386 oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
387 if (is_f1_null() || !has_appendix())
388 return NULL;
389 const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset;
390 objArrayOop resolved_references = cpool->resolved_references();
391 return resolved_references->obj_at(ref_index);
392 }
393
394
395 oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
396 if (is_f1_null() || !has_method_type())
397 return NULL;
398 const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset;
399 objArrayOop resolved_references = cpool->resolved_references();
400 return resolved_references->obj_at(ref_index);
401 }
402
403
404 // RedefineClasses() API support:
405 // If this constantPoolCacheEntry refers to old_method then update it
406 // to refer to new_method.
407 bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
408 Method* new_method, bool * trace_name_printed) {
409
410 if (is_vfinal()) {
411 // virtual and final so _f2 contains method ptr instead of vtable index
412 if (f2_as_vfinal_method() == old_method) {
413 // match old_method so need an update
414 // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
415 _f2 = (intptr_t)new_method;
416 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
417 if (!(*trace_name_printed)) {
418 // RC_TRACE_MESG macro has an embedded ResourceMark
419 RC_TRACE_MESG(("adjust: name=%s",
420 old_method->method_holder()->external_name()));
421 *trace_name_printed = true;
422 }
423 // RC_TRACE macro has an embedded ResourceMark
424 RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)",
425 new_method->name()->as_C_string(),
443 _f1 = new_method;
444 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
445 if (!(*trace_name_printed)) {
446 // RC_TRACE_MESG macro has an embedded ResourceMark
447 RC_TRACE_MESG(("adjust: name=%s",
448 old_method->method_holder()->external_name()));
449 *trace_name_printed = true;
450 }
451 // RC_TRACE macro has an embedded ResourceMark
452 RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
453 new_method->name()->as_C_string(),
454 new_method->signature()->as_C_string()));
455 }
456
457 return true;
458 }
459
460 return false;
461 }
462
463 #ifndef PRODUCT
464 bool ConstantPoolCacheEntry::check_no_old_entries() {
465 if (is_vfinal()) {
466 Metadata* f2 = (Metadata*)_f2;
467 return (f2->is_valid() && f2->is_method() && !((Method*)f2)->is_old());
468 } else {
469 return (_f1 == NULL || (_f1->is_valid() && _f1->is_method() && !((Method*)_f1)->is_old()));
470 }
471 }
472 #endif
473
474 bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) {
475 if (!is_method_entry()) {
476 // not a method entry so not interesting by default
477 return false;
478 }
479
480 Method* m = NULL;
481 if (is_vfinal()) {
482 // virtual and final so _f2 contains method ptr instead of vtable index
483 m = f2_as_vfinal_method();
484 } else if (is_f1_null()) {
485 // NULL _f1 means this is a virtual entry so also not interesting
486 return false;
487 } else {
488 if (!(_f1->is_method())) {
489 // _f1 can also contain a Klass* for an interface
490 return false;
491 }
492 m = f1_as_method();
493 }
494
495 assert(m != NULL && m->is_method(), "sanity check");
496 if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
497 // robustness for above sanity checks or method is not in
498 // the interesting class
499 return false;
500 }
501
502 // the method is in the interesting class so the entry is interesting
503 return true;
504 }
505
506 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
507 // print separator
508 if (index == 0) st->print_cr(" -------------");
509 // print entry
510 st->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this);
511 st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index());
512 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f1);
513 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2);
514 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags);
515 st->print_cr(" -------------");
516 }
517
518 void ConstantPoolCacheEntry::verify(outputStream* st) const {
519 // not implemented yet
520 }
521
522 // Implementation of ConstantPoolCache
523
524 ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
525 int size = ConstantPoolCache::size(length);
526
527 return new (loader_data, size, false, THREAD) ConstantPoolCache(length);
528 }
529
530 void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) {
531 assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
535 e->initialize_entry(original_index);
536 assert(entry_at(i) == e, "sanity");
537 }
538 for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
539 const int cpci = invokedynamic_references_map[ref];
540 if (cpci >= 0) {
541 #ifdef ASSERT
542 // invokedynamic and invokehandle have more entries; check if they
543 // all point to the same constant pool cache entry.
544 for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
545 const int cpci_next = invokedynamic_references_map[ref + entry];
546 assert(cpci == cpci_next, err_msg_res("%d == %d", cpci, cpci_next));
547 }
548 #endif
549 entry_at(cpci)->initialize_resolved_reference_index(ref);
550 ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1; // skip extra entries
551 }
552 }
553 }
554
555 // RedefineClasses() API support:
556 // If any entry of this constantPoolCache points to any of
557 // old_methods, replace it with the corresponding new_method.
558 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods,
559 int methods_length, bool * trace_name_printed) {
560
561 if (methods_length == 0) {
562 // nothing to do if there are no methods
563 return;
564 }
565
566 // get shorthand for the interesting class
567 Klass* old_holder = old_methods[0]->method_holder();
568
569 for (int i = 0; i < length(); i++) {
570 if (!entry_at(i)->is_interesting_method_entry(old_holder)) {
571 // skip uninteresting methods
572 continue;
573 }
574
575 // The constantPoolCache contains entries for several different
576 // things, but we only care about methods. In fact, we only care
577 // about methods in the same class as the one that contains the
578 // old_methods. At this point, we have an interesting entry.
579
580 for (int j = 0; j < methods_length; j++) {
581 Method* old_method = old_methods[j];
582 Method* new_method = new_methods[j];
583
584 if (entry_at(i)->adjust_method_entry(old_method, new_method,
585 trace_name_printed)) {
586 // current old_method matched this entry and we updated it so
587 // break out and get to the next interesting entry if there one
588 break;
589 }
590 }
591 }
592 }
593
594 #ifndef PRODUCT
595 bool ConstantPoolCache::check_no_old_entries() {
596 for (int i = 1; i < length(); i++) {
597 if (entry_at(i)->is_interesting_method_entry(NULL) &&
598 !entry_at(i)->check_no_old_entries()) {
599 return false;
600 }
601 }
602 return true;
603 }
604 #endif // PRODUCT
605
606
607 // Printing
608
609 void ConstantPoolCache::print_on(outputStream* st) const {
610 assert(is_constantPoolCache(), "obj must be constant pool cache");
611 st->print_cr(internal_name());
612 // print constant pool cache entries
613 for (int i = 0; i < length(); i++) entry_at(i)->print(st, i);
614 }
615
616 void ConstantPoolCache::print_value_on(outputStream* st) const {
617 assert(is_constantPoolCache(), "obj must be constant pool cache");
618 st->print("cache [%d]", length());
619 print_address_on(st);
620 st->print(" for ");
621 constant_pool()->print_value_on(st);
622 }
623
624
625 // Verification
626
|
1 /*
2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
384
385
386 oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
387 if (is_f1_null() || !has_appendix())
388 return NULL;
389 const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset;
390 objArrayOop resolved_references = cpool->resolved_references();
391 return resolved_references->obj_at(ref_index);
392 }
393
394
395 oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
396 if (is_f1_null() || !has_method_type())
397 return NULL;
398 const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset;
399 objArrayOop resolved_references = cpool->resolved_references();
400 return resolved_references->obj_at(ref_index);
401 }
402
403
404 #if INCLUDE_JVMTI
405 // RedefineClasses() API support:
406 // If this ConstantPoolCacheEntry refers to old_method then update it
407 // to refer to new_method.
408 bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
409 Method* new_method, bool * trace_name_printed) {
410
411 if (is_vfinal()) {
412 // virtual and final so _f2 contains method ptr instead of vtable index
413 if (f2_as_vfinal_method() == old_method) {
414 // match old_method so need an update
415 // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
416 _f2 = (intptr_t)new_method;
417 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
418 if (!(*trace_name_printed)) {
419 // RC_TRACE_MESG macro has an embedded ResourceMark
420 RC_TRACE_MESG(("adjust: name=%s",
421 old_method->method_holder()->external_name()));
422 *trace_name_printed = true;
423 }
424 // RC_TRACE macro has an embedded ResourceMark
425 RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)",
426 new_method->name()->as_C_string(),
444 _f1 = new_method;
445 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
446 if (!(*trace_name_printed)) {
447 // RC_TRACE_MESG macro has an embedded ResourceMark
448 RC_TRACE_MESG(("adjust: name=%s",
449 old_method->method_holder()->external_name()));
450 *trace_name_printed = true;
451 }
452 // RC_TRACE macro has an embedded ResourceMark
453 RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
454 new_method->name()->as_C_string(),
455 new_method->signature()->as_C_string()));
456 }
457
458 return true;
459 }
460
461 return false;
462 }
463
464 // a constant pool cache entry should never contain old or obsolete methods
465 bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
466 if (is_vfinal()) {
467 // virtual and final so _f2 contains method ptr instead of vtable index
468 Metadata* f2 = (Metadata*)_f2;
469 // Return false if _f2 refers to an old or an obsolete method.
470 // _f2 == NULL || !_f2->is_method() are just as unexpected here.
471 return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() &&
472 !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete());
473 } else if (_f1 == NULL ||
474 (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) {
475 // _f1 == NULL || !_f1->is_method() are OK here
476 return true;
477 }
478 // return false if _f1 refers to an old or an obsolete method
479 return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() &&
480 !((Method*)_f1)->is_old() && !((Method*)_f1)->is_obsolete());
481 }
482
483 bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) {
484 if (!is_method_entry()) {
485 // not a method entry so not interesting by default
486 return false;
487 }
488
489 Method* m = NULL;
490 if (is_vfinal()) {
491 // virtual and final so _f2 contains method ptr instead of vtable index
492 m = f2_as_vfinal_method();
493 } else if (is_f1_null()) {
494 // NULL _f1 means this is a virtual entry so also not interesting
495 return false;
496 } else {
497 if (!(_f1->is_method())) {
498 // _f1 can also contain a Klass* for an interface
499 return false;
500 }
501 m = f1_as_method();
502 }
503
504 assert(m != NULL && m->is_method(), "sanity check");
505 if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
506 // robustness for above sanity checks or method is not in
507 // the interesting class
508 return false;
509 }
510
511 // the method is in the interesting class so the entry is interesting
512 return true;
513 }
514 #endif // INCLUDE_JVMTI
515
516 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
517 // print separator
518 if (index == 0) st->print_cr(" -------------");
519 // print entry
520 st->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this);
521 st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(),
522 constant_pool_index());
523 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f1);
524 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2);
525 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags);
526 st->print_cr(" -------------");
527 }
528
529 void ConstantPoolCacheEntry::verify(outputStream* st) const {
530 // not implemented yet
531 }
532
533 // Implementation of ConstantPoolCache
534
535 ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
536 int size = ConstantPoolCache::size(length);
537
538 return new (loader_data, size, false, THREAD) ConstantPoolCache(length);
539 }
540
541 void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) {
542 assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
546 e->initialize_entry(original_index);
547 assert(entry_at(i) == e, "sanity");
548 }
549 for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
550 const int cpci = invokedynamic_references_map[ref];
551 if (cpci >= 0) {
552 #ifdef ASSERT
553 // invokedynamic and invokehandle have more entries; check if they
554 // all point to the same constant pool cache entry.
555 for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
556 const int cpci_next = invokedynamic_references_map[ref + entry];
557 assert(cpci == cpci_next, err_msg_res("%d == %d", cpci, cpci_next));
558 }
559 #endif
560 entry_at(cpci)->initialize_resolved_reference_index(ref);
561 ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1; // skip extra entries
562 }
563 }
564 }
565
566 #if INCLUDE_JVMTI
567 // RedefineClasses() API support:
568 // If any entry of this ConstantPoolCache points to any of
569 // old_methods, replace it with the corresponding new_method.
570 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods,
571 int methods_length, bool * trace_name_printed) {
572
573 if (methods_length == 0) {
574 // nothing to do if there are no methods
575 return;
576 }
577
578 // get shorthand for the interesting class
579 Klass* old_holder = old_methods[0]->method_holder();
580
581 for (int i = 0; i < length(); i++) {
582 if (!entry_at(i)->is_interesting_method_entry(old_holder)) {
583 // skip uninteresting methods
584 continue;
585 }
586
587 // The ConstantPoolCache contains entries for several different
588 // things, but we only care about methods. In fact, we only care
589 // about methods in the same class as the one that contains the
590 // old_methods. At this point, we have an interesting entry.
591
592 for (int j = 0; j < methods_length; j++) {
593 Method* old_method = old_methods[j];
594 Method* new_method = new_methods[j];
595
596 if (entry_at(i)->adjust_method_entry(old_method, new_method,
597 trace_name_printed)) {
598 // current old_method matched this entry and we updated it so
599 // break out and get to the next interesting entry if there one
600 break;
601 }
602 }
603 }
604 }
605
606 // the constant pool cache should never contain old or obsolete methods
607 bool ConstantPoolCache::check_no_old_or_obsolete_entries() {
608 for (int i = 1; i < length(); i++) {
609 if (entry_at(i)->is_interesting_method_entry(NULL) &&
610 !entry_at(i)->check_no_old_or_obsolete_entries()) {
611 return false;
612 }
613 }
614 return true;
615 }
616
617 void ConstantPoolCache::dump_cache() {
618 for (int i = 1; i < length(); i++) {
619 if (entry_at(i)->is_interesting_method_entry(NULL)) {
620 entry_at(i)->print(tty, i);
621 }
622 }
623 }
624 #endif // INCLUDE_JVMTI
625
626
627 // Printing
628
629 void ConstantPoolCache::print_on(outputStream* st) const {
630 assert(is_constantPoolCache(), "obj must be constant pool cache");
631 st->print_cr(internal_name());
632 // print constant pool cache entries
633 for (int i = 0; i < length(); i++) entry_at(i)->print(st, i);
634 }
635
636 void ConstantPoolCache::print_value_on(outputStream* st) const {
637 assert(is_constantPoolCache(), "obj must be constant pool cache");
638 st->print("cache [%d]", length());
639 print_address_on(st);
640 st->print(" for ");
641 constant_pool()->print_value_on(st);
642 }
643
644
645 // Verification
646
|