< prev index next >

src/hotspot/share/classfile/defaultMethods.cpp

Print this page
rev 53926 : 8219713: Reduce work in DefaultMethods::generate_default_methods
Reviewed-by: TBD

@@ -151,34 +151,35 @@
     InstanceKlass* next_interface() {
       return interface_at(interface_index());
     }
   };
 
-  bool _cancelled;
+  bool _visited_object;
   GrowableArray<Node*> _path;
 
   Node* current_top() const { return _path.top(); }
   bool has_more_nodes() const { return !_path.is_empty(); }
   void push(InstanceKlass* cls, void* data) {
     assert(cls != NULL, "Requires a valid instance class");
     Node* node = new Node(cls, data, has_super(cls));
+    if (cls == SystemDictionary::Object_klass()) {
+      _visited_object = true;
+    }
     _path.push(node);
   }
   void pop() { _path.pop(); }
 
   void reset_iteration() {
-    _cancelled = false;
     _path.clear();
   }
-  bool is_cancelled() const { return _cancelled; }
 
   // This code used to skip interface classes because their only
   // superclass was j.l.Object which would be also covered by class
   // superclass hierarchy walks. Now that the starting point can be
   // an interface, we must ensure we catch j.l.Object as the super.
-  static bool has_super(InstanceKlass* cls) {
-    return cls->super() != NULL;
+  bool has_super(InstanceKlass* cls) {
+    return cls->super() != NULL && (!_visited_object || !cls->is_interface());
   }
 
   Node* node_at_depth(int i) const {
     return (i >= _path.length()) ? NULL : _path.at(_path.length() - i - 1);
   }

@@ -198,12 +199,10 @@
     Node* n = node_at_depth(i);
     return n == NULL ? NULL : n->_algorithm_data;
   }
   void* current_data() { return data_at_depth(0); }
 
-  void cancel_iteration() { _cancelled = true; }
-
  public:
 
   void run(InstanceKlass* root) {
     ALGO* algo = static_cast<ALGO*>(this);
 

@@ -240,11 +239,11 @@
         assert(next != NULL, "Otherwise we shouldn't be here");
         algo_data = algo->new_node_data(next);
         push(next, algo_data);
         top_needs_visit = true;
       }
-    } while (!is_cancelled() && has_more_nodes());
+    } while (has_more_nodes());
   }
 };
 
 class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> {
  private:

@@ -622,21 +621,21 @@
   }
 
   // Also any overpasses in our superclasses, that we haven't implemented.
   // (can't use the vtable because it is not guaranteed to be initialized yet)
   InstanceKlass* super = klass->java_super();
-  while (super != NULL) {
+  while (super != NULL && super != SystemDictionary::Object_klass()) {
     for (int i = 0; i < super->methods()->length(); ++i) {
       Method* m = super->methods()->at(i);
-      if (m->is_overpass() || m->is_static()) {
+      if (m->is_overpass() || (m->is_static() && vmSymbols::class_initializer_name() != m->name())) {
         // m is a method that would have been a miranda if not for the
         // default method processing that occurred on behalf of our superclass,
         // so it's a method we want to re-examine in this new context.  That is,
         // unless we have a real implementation of it in the current class.
+        if (!already_in_vtable_slots(slots, m)) {
         Method* impl = klass->lookup_method(m->name(), m->signature());
         if (impl == NULL || impl->is_overpass() || impl->is_static()) {
-          if (!already_in_vtable_slots(slots, m)) {
             slots->append(new EmptyVtableSlot(m));
           }
         }
       }
     }

@@ -647,13 +646,13 @@
         Method* m = super->default_methods()->at(i);
         // m is a method that would have been a miranda if not for the
         // default method processing that occurred on behalf of our superclass,
         // so it's a method we want to re-examine in this new context.  That is,
         // unless we have a real implementation of it in the current class.
+        if (!already_in_vtable_slots(slots, m)) {
         Method* impl = klass->lookup_method(m->name(), m->signature());
         if (impl == NULL || impl->is_overpass() || impl->is_static()) {
-          if (!already_in_vtable_slots(slots, m)) {
             slots->append(new EmptyVtableSlot(m));
           }
         }
       }
     }

@@ -747,12 +746,11 @@
 
 static void create_defaults_and_exceptions(
     GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS);
 
 static void generate_erased_defaults(
-     InstanceKlass* klass, GrowableArray<EmptyVtableSlot*>* empty_slots,
-     EmptyVtableSlot* slot, bool is_intf, TRAPS) {
+     InstanceKlass* klass, EmptyVtableSlot* slot, bool is_intf, TRAPS) {
 
   // sets up a set of methods with the same exact erased signature
   FindMethodsByErasedSig visitor(slot->name(), slot->signature(), is_intf);
   visitor.run(klass);
 

@@ -810,24 +808,26 @@
   }
 
   GrowableArray<EmptyVtableSlot*>* empty_slots =
       find_empty_vtable_slots(klass, mirandas, CHECK);
 
+  if (empty_slots->length() > 0) {
   for (int i = 0; i < empty_slots->length(); ++i) {
     EmptyVtableSlot* slot = empty_slots->at(i);
     LogTarget(Debug, defaultmethods) lt;
     if (lt.is_enabled()) {
       LogStream ls(lt);
       streamIndentor si(&ls, 2);
       ls.indent().print("Looking for default methods for slot ");
       slot->print_on(&ls);
       ls.cr();
     }
-    generate_erased_defaults(klass, empty_slots, slot, klass->is_interface(), CHECK);
+      generate_erased_defaults(klass, slot, klass->is_interface(), CHECK);
   }
   log_debug(defaultmethods)("Creating defaults and overpasses...");
   create_defaults_and_exceptions(empty_slots, klass, CHECK);
+  }
   log_debug(defaultmethods)("Default method processing complete");
 }
 
 static int assemble_method_error(
     BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) {
< prev index next >