src/share/vm/oops/klassVtable.cpp

Print this page

        

@@ -862,24 +862,25 @@
       }
     }
   }
   return updated;
 }
-void klassVtable::adjust_method_entries(Method** old_methods, Method** new_methods,
-                                        int methods_length, bool * trace_name_printed) {
-  // search the vtable for uses of either obsolete or EMCP methods
-  for (int j = 0; j < methods_length; j++) {
-    Method* old_method = old_methods[j];
-    Method* new_method = new_methods[j];
 
-    // In the vast majority of cases we could get the vtable index
-    // by using:  old_method->vtable_index()
-    // However, there are rare cases, eg. sun.awt.X11.XDecoratedPeer.getX()
-    // in sun.awt.X11.XFramePeer where methods occur more than once in the
-    // vtable, so, alas, we must do an exhaustive search.
+// search the vtable for uses of either obsolete or EMCP methods
+void klassVtable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
+
     for (int index = 0; index < length(); index++) {
-      if (unchecked_method_at(index) == old_method) {
+    Method* old_method = unchecked_method_at(index);
+    if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
+      continue; // skip uninteresting entries
+    }
+    assert(!old_method->is_deleted(), "vtable methods may not be deleted");
+    Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
+    assert(new_method != NULL, "method_with_idnum() should not be NULL");
+    if (old_method == new_method) {
+      continue;
+    }
         put_method_at(new_method, index);
           // For default methods, need to update the _default_methods array
           // which can only have one method entry for a given signature
           bool updated_default = false;
           if (old_method->is_default_method()) {

@@ -898,14 +899,11 @@
           RC_TRACE(0x00100000, ("vtable method update: %s(%s), updated default = %s",
                                 new_method->name()->as_C_string(),
                                 new_method->signature()->as_C_string(),
                                 updated_default ? "true" : "false"));
         }
-        // cannot 'break' here; see for-loop comment above.
       }
-    }
-  }
 }
 
 // a vtable should never contain old or obsolete methods
 bool klassVtable::check_no_old_or_obsolete_entries() {
   for (int i = 0; i < length(); i++) {

@@ -1192,24 +1190,25 @@
     ime++;
   }
 }
 
 #if INCLUDE_JVMTI
-void klassItable::adjust_method_entries(Method** old_methods, Method** new_methods,
-                                        int methods_length, bool * trace_name_printed) {
-  // search the itable for uses of either obsolete or EMCP methods
-  for (int j = 0; j < methods_length; j++) {
-    Method* old_method = old_methods[j];
-    Method* new_method = new_methods[j];
-    itableMethodEntry* ime = method_entry(0);
+// search the itable for uses of either obsolete or EMCP methods
+void klassItable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
 
-    // The itable can describe more than one interface and the same
-    // method signature can be specified by more than one interface.
-    // This means we have to do an exhaustive search to find all the
-    // old_method references.
-    for (int i = 0; i < _size_method_table; i++) {
-      if (ime->method() == old_method) {
+  itableMethodEntry* ime = method_entry(0);
+  for (int i = 0; i < _size_method_table; i++, ime++) {
+    Method* old_method = ime->method();
+    if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
+      continue; // skip uninteresting entries
+    }
+    assert(!old_method->is_deleted(), "itable methods may not be deleted");
+    Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
+    assert(new_method != NULL, "method_with_idnum() should not be NULL");
+    if (old_method == new_method) {
+      continue;
+    }
         ime->initialize(new_method);
 
         if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
           if (!(*trace_name_printed)) {
             // RC_TRACE_MESG macro has an embedded ResourceMark

@@ -1220,15 +1219,11 @@
           // RC_TRACE macro has an embedded ResourceMark
           RC_TRACE(0x00200000, ("itable method update: %s(%s)",
             new_method->name()->as_C_string(),
             new_method->signature()->as_C_string()));
         }
-        // cannot 'break' here; see for-loop comment above.
       }
-      ime++;
-    }
-  }
 }
 
 // an itable should never contain old or obsolete methods
 bool klassItable::check_no_old_or_obsolete_entries() {
   itableMethodEntry* ime = method_entry(0);