src/share/vm/oops/cpCache.cpp

Print this page


   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  *


 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");
 532   for (int i = 0; i < length(); i++) {
 533     ConstantPoolCacheEntry* e = entry_at(i);
 534     int original_index = inverse_index_map[i];


 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  *


 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 // a constant pool cache entry should never contain old or obsolete methods
 464 bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
 465   if (is_vfinal()) {
 466     Metadata* f2 = (Metadata*)_f2;
 467     // Return false if _f2 refers to an old or an obsolete method.
 468     // _f2 == NULL || !_f2->is_method() are just as unexpected here.
 469     return (f2 != NULL && f2->is_valid() && f2->is_method() &&
 470             !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete());
 471   } else if (_f1 == NULL || (_f1->is_valid() && !_f1->is_method())) {
 472     // _f1 == NULL || !_f1->is_method() are OK here
 473     return true;
 474   }
 475   // return false if _f1 refers to an old or an obsolete method
 476   return (_f1->is_valid() && _f1->is_method() && !((Method*)_f1)->is_old() &&
 477           !((Method*)_f1)->is_obsolete());
 478 }

 479 
 480 bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) {
 481   if (!is_method_entry()) {
 482     // not a method entry so not interesting by default
 483     return false;
 484   }
 485 
 486   Method* m = NULL;
 487   if (is_vfinal()) {
 488     // virtual and final so _f2 contains method ptr instead of vtable index
 489     m = f2_as_vfinal_method();
 490   } else if (is_f1_null()) {
 491     // NULL _f1 means this is a virtual entry so also not interesting
 492     return false;
 493   } else {
 494     if (!(_f1->is_method())) {
 495       // _f1 can also contain a Klass* for an interface
 496       return false;
 497     }
 498     m = f1_as_method();
 499   }
 500 
 501   assert(m != NULL && m->is_method(), "sanity check");
 502   if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
 503     // robustness for above sanity checks or method is not in
 504     // the interesting class
 505     return false;
 506   }
 507 
 508   // the method is in the interesting class so the entry is interesting
 509   return true;
 510 }
 511 
 512 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
 513   // print separator
 514   if (index == 0) {
 515     // adds a searchable prefix when RedefineClasses() tracing is enabled
 516     RC_TRACE_NO_CR(0x00004000, (""));
 517     st->print_cr("                 -------------");
 518   }
 519   // print entry
 520   RC_TRACE_NO_CR(0x00004000, (""));
 521   st->print("%3d  ("PTR_FORMAT")  ", index, (intptr_t)this);
 522   st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(),
 523                constant_pool_index());
 524   RC_TRACE_NO_CR(0x00004000, (""));
 525   st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f1);
 526   RC_TRACE_NO_CR(0x00004000, (""));
 527   st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f2);
 528   RC_TRACE_NO_CR(0x00004000, (""));
 529   st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_flags);
 530   RC_TRACE_NO_CR(0x00004000, (""));
 531   st->print_cr("                 -------------");
 532 }
 533 
 534 void ConstantPoolCacheEntry::verify(outputStream* st) const {
 535   // not implemented yet
 536 }
 537 
 538 // Implementation of ConstantPoolCache
 539 
 540 ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
 541   int size = ConstantPoolCache::size(length);
 542 
 543   return new (loader_data, size, false, THREAD) ConstantPoolCache(length);
 544 }
 545 
 546 void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) {
 547   assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
 548   for (int i = 0; i < length(); i++) {
 549     ConstantPoolCacheEntry* e = entry_at(i);
 550     int original_index = inverse_index_map[i];


 552     assert(entry_at(i) == e, "sanity");
 553   }
 554   for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
 555     const int cpci = invokedynamic_references_map[ref];
 556     if (cpci >= 0) {
 557 #ifdef ASSERT
 558       // invokedynamic and invokehandle have more entries; check if they
 559       // all point to the same constant pool cache entry.
 560       for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
 561         const int cpci_next = invokedynamic_references_map[ref + entry];
 562         assert(cpci == cpci_next, err_msg_res("%d == %d", cpci, cpci_next));
 563       }
 564 #endif
 565       entry_at(cpci)->initialize_resolved_reference_index(ref);
 566       ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1;  // skip extra entries
 567     }
 568   }
 569 }
 570 
 571 // RedefineClasses() API support:
 572 // If any entry of this ConstantPoolCache points to any of
 573 // old_methods, replace it with the corresponding new_method.
 574 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods,
 575                                                      int methods_length, bool * trace_name_printed) {
 576 
 577   if (methods_length == 0) {
 578     // nothing to do if there are no methods
 579     return;
 580   }
 581 
 582   // get shorthand for the interesting class
 583   Klass* old_holder = old_methods[0]->method_holder();
 584 
 585   for (int i = 0; i < length(); i++) {
 586     if (!entry_at(i)->is_interesting_method_entry(old_holder)) {
 587       // skip uninteresting methods
 588       continue;
 589     }
 590 
 591     // The ConstantPoolCache contains entries for several different
 592     // things, but we only care about methods. In fact, we only care
 593     // about methods in the same class as the one that contains the
 594     // old_methods. At this point, we have an interesting entry.
 595 
 596     for (int j = 0; j < methods_length; j++) {
 597       Method* old_method = old_methods[j];
 598       Method* new_method = new_methods[j];
 599 
 600       if (entry_at(i)->adjust_method_entry(old_method, new_method,
 601           trace_name_printed)) {
 602         // current old_method matched this entry and we updated it so
 603         // break out and get to the next interesting entry if there one
 604         break;
 605       }
 606     }
 607   }
 608 }
 609 
 610 // the constant pool cache should never contain old or obsolete methods
 611 bool ConstantPoolCache::check_no_old_or_obsolete_entries() {
 612   for (int i = 1; i < length(); i++) {
 613     if (entry_at(i)->is_interesting_method_entry(NULL) &&
 614         !entry_at(i)->check_no_old_or_obsolete_entries()) {
 615       return false;
 616     }
 617   }
 618   return true;
 619 }

 620 
 621 void ConstantPoolCache::dump_cache() {
 622   for (int i = 1; i < length(); i++) {
 623     if (entry_at(i)->is_interesting_method_entry(NULL)) {
 624       // adds a searchable prefix when RedefineClasses() tracing is enabled
 625       RC_TRACE_NO_CR(0x00004000, (""));
 626       entry_at(i)->print(tty, i);
 627     }
 628   }
 629 }
 630 
 631 
 632 // Printing
 633 
 634 void ConstantPoolCache::print_on(outputStream* st) const {
 635   assert(is_constantPoolCache(), "obj must be constant pool cache");
 636   st->print_cr(internal_name());
 637   // print constant pool cache entries
 638   for (int i = 0; i < length(); i++) entry_at(i)->print(st, i);
 639 }
 640 
 641 void ConstantPoolCache::print_value_on(outputStream* st) const {
 642   assert(is_constantPoolCache(), "obj must be constant pool cache");
 643   st->print("cache [%d]", length());
 644   print_address_on(st);
 645   st->print(" for ");
 646   constant_pool()->print_value_on(st);
 647 }
 648 
 649 
 650 // Verification
 651