src/share/vm/oops/cpCache.cpp

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -399,12 +399,13 @@
   objArrayOop resolved_references = cpool->resolved_references();
   return resolved_references->obj_at(ref_index);
 }
 
 
+#if INCLUDE_JVMTI
 // RedefineClasses() API support:
-// If this constantPoolCacheEntry refers to old_method then update it
+// If this ConstantPoolCacheEntry refers to old_method then update it
 // to refer to new_method.
 bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
        Method* new_method, bool * trace_name_printed) {
 
   if (is_vfinal()) {

@@ -458,20 +459,28 @@
   }
 
   return false;
 }
 
-#ifndef PRODUCT
-bool ConstantPoolCacheEntry::check_no_old_entries() {
+// a constant pool cache entry should never contain old or obsolete methods
+bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
   if (is_vfinal()) {
+    // virtual and final so _f2 contains method ptr instead of vtable index
     Metadata* f2 = (Metadata*)_f2;
-    return (f2->is_valid() && f2->is_method() && !((Method*)f2)->is_old());
-  } else {
-    return (_f1 == NULL || (_f1->is_valid() && _f1->is_method() && !((Method*)_f1)->is_old()));
+    // Return false if _f2 refers to an old or an obsolete method.
+    // _f2 == NULL || !_f2->is_method() are just as unexpected here.
+    return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() &&
+            !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete());
+  } else if (_f1 == NULL ||
+             (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) {
+    // _f1 == NULL || !_f1->is_method() are OK here
+    return true;
   }
+  // return false if _f1 refers to an old or an obsolete method
+  return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() &&
+          !((Method*)_f1)->is_old() && !((Method*)_f1)->is_obsolete());
 }
-#endif
 
 bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) {
   if (!is_method_entry()) {
     // not a method entry so not interesting by default
     return false;

@@ -500,17 +509,19 @@
   }
 
   // the method is in the interesting class so the entry is interesting
   return true;
 }
+#endif // INCLUDE_JVMTI
 
 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
   // print separator
   if (index == 0) st->print_cr("                 -------------");
   // print entry
   st->print("%3d  ("PTR_FORMAT")  ", index, (intptr_t)this);
-    st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index());
+  st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(),
+               constant_pool_index());
   st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f1);
   st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f2);
   st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_flags);
   st->print_cr("                 -------------");
 }

@@ -550,12 +561,13 @@
       ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1;  // skip extra entries
     }
   }
 }
 
+#if INCLUDE_JVMTI
 // RedefineClasses() API support:
-// If any entry of this constantPoolCache points to any of
+// If any entry of this ConstantPoolCache points to any of
 // old_methods, replace it with the corresponding new_method.
 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods,
                                                      int methods_length, bool * trace_name_printed) {
 
   if (methods_length == 0) {

@@ -570,11 +582,11 @@
     if (!entry_at(i)->is_interesting_method_entry(old_holder)) {
       // skip uninteresting methods
       continue;
     }
 
-    // The constantPoolCache contains entries for several different
+    // The ConstantPoolCache contains entries for several different
     // things, but we only care about methods. In fact, we only care
     // about methods in the same class as the one that contains the
     // old_methods. At this point, we have an interesting entry.
 
     for (int j = 0; j < methods_length; j++) {

@@ -589,23 +601,31 @@
       }
     }
   }
 }
 
-#ifndef PRODUCT
-bool ConstantPoolCache::check_no_old_entries() {
+// the constant pool cache should never contain old or obsolete methods
+bool ConstantPoolCache::check_no_old_or_obsolete_entries() {
   for (int i = 1; i < length(); i++) {
     if (entry_at(i)->is_interesting_method_entry(NULL) &&
-       !entry_at(i)->check_no_old_entries()) {
+        !entry_at(i)->check_no_old_or_obsolete_entries()) {
       return false;
     }
   }
   return true;
 }
-#endif // PRODUCT
 
+void ConstantPoolCache::dump_cache() {
+  for (int i = 1; i < length(); i++) {
+    if (entry_at(i)->is_interesting_method_entry(NULL)) {
+      entry_at(i)->print(tty, i);
+    }
+  }
+}
+#endif // INCLUDE_JVMTI
 
+
 // Printing
 
 void ConstantPoolCache::print_on(outputStream* st) const {
   assert(is_constantPoolCache(), "obj must be constant pool cache");
   st->print_cr(internal_name());