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");


 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     // virtual and final so _f2 contains method ptr instead of vtable index
 467     Metadata* f2 = (Metadata*)_f2;
 468     // Return false if _f2 refers to an old or an obsolete method.
 469     // _f2 == NULL || !_f2->is_method() are just as unexpected here.
 470     return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() &&
 471             !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete());
 472   } else if (_f1 == NULL ||
 473              (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) {
 474     // _f1 == NULL || !_f1->is_method() are OK here
 475     return true;
 476   }
 477   // return false if _f1 refers to an old or an obsolete method
 478   return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() &&
 479           !((Method*)_f1)->is_old() && !((Method*)_f1)->is_obsolete());
 480 }

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


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

 613 
 614 void ConstantPoolCache::dump_cache() {
 615   for (int i = 1; i < length(); i++) {
 616     if (entry_at(i)->is_interesting_method_entry(NULL)) {
 617       entry_at(i)->print(tty, i);
 618     }
 619   }
 620 }
 621 
 622 
 623 // Printing
 624 
 625 void ConstantPoolCache::print_on(outputStream* st) const {
 626   assert(is_constantPoolCache(), "obj must be constant pool cache");
 627   st->print_cr(internal_name());
 628   // print constant pool cache entries
 629   for (int i = 0; i < length(); i++) entry_at(i)->print(st, i);
 630 }
 631 
 632 void ConstantPoolCache::print_value_on(outputStream* st) const {
 633   assert(is_constantPoolCache(), "obj must be constant pool cache");
 634   st->print("cache [%d]", length());
 635   print_address_on(st);
 636   st->print(" for ");
 637   constant_pool()->print_value_on(st);
 638 }
 639 
 640 
 641 // Verification
 642