< 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


 136     int number_of_interfaces() { return _class->local_interfaces()->length(); }
 137     int interface_index() { return _interface_index; }
 138     void set_super_visited() { _super_was_visited = true; }
 139     void increment_visited_interface() { ++_interface_index; }
 140     void set_all_interfaces_visited() {
 141       _interface_index = number_of_interfaces();
 142     }
 143     bool has_visited_super() { return _super_was_visited; }
 144     bool has_visited_all_interfaces() {
 145       return interface_index() >= number_of_interfaces();
 146     }
 147     InstanceKlass* interface_at(int index) {
 148       return InstanceKlass::cast(_class->local_interfaces()->at(index));
 149     }
 150     InstanceKlass* next_super() { return _class->java_super(); }
 151     InstanceKlass* next_interface() {
 152       return interface_at(interface_index());
 153     }
 154   };
 155 
 156   bool _cancelled;
 157   GrowableArray<Node*> _path;
 158 
 159   Node* current_top() const { return _path.top(); }
 160   bool has_more_nodes() const { return !_path.is_empty(); }
 161   void push(InstanceKlass* cls, void* data) {
 162     assert(cls != NULL, "Requires a valid instance class");
 163     Node* node = new Node(cls, data, has_super(cls));



 164     _path.push(node);
 165   }
 166   void pop() { _path.pop(); }
 167 
 168   void reset_iteration() {
 169     _cancelled = false;
 170     _path.clear();
 171   }
 172   bool is_cancelled() const { return _cancelled; }
 173 
 174   // This code used to skip interface classes because their only
 175   // superclass was j.l.Object which would be also covered by class
 176   // superclass hierarchy walks. Now that the starting point can be
 177   // an interface, we must ensure we catch j.l.Object as the super.
 178   static bool has_super(InstanceKlass* cls) {
 179     return cls->super() != NULL;
 180   }
 181 
 182   Node* node_at_depth(int i) const {
 183     return (i >= _path.length()) ? NULL : _path.at(_path.length() - i - 1);
 184   }
 185 
 186  protected:
 187 
 188   // Accessors available to the algorithm
 189   int current_depth() const { return _path.length() - 1; }
 190 
 191   InstanceKlass* class_at_depth(int i) {
 192     Node* n = node_at_depth(i);
 193     return n == NULL ? NULL : n->_class;
 194   }
 195   InstanceKlass* current_class() { return class_at_depth(0); }
 196 
 197   void* data_at_depth(int i) {
 198     Node* n = node_at_depth(i);
 199     return n == NULL ? NULL : n->_algorithm_data;
 200   }
 201   void* current_data() { return data_at_depth(0); }
 202 
 203   void cancel_iteration() { _cancelled = true; }
 204 
 205  public:
 206 
 207   void run(InstanceKlass* root) {
 208     ALGO* algo = static_cast<ALGO*>(this);
 209 
 210     reset_iteration();
 211 
 212     void* algo_data = algo->new_node_data(root);
 213     push(root, algo_data);
 214     bool top_needs_visit = true;
 215 
 216     do {
 217       Node* top = current_top();
 218       if (top_needs_visit) {
 219         if (algo->visit() == false) {
 220           // algorithm does not want to continue along this path.  Arrange
 221           // it so that this state is immediately popped off the stack
 222           top->set_super_visited();
 223           top->set_all_interfaces_visited();
 224         }
 225         top_needs_visit = false;
 226       }
 227 
 228       if (top->has_visited_super() && top->has_visited_all_interfaces()) {
 229         algo->free_node_data(top->_algorithm_data);
 230         pop();
 231       } else {
 232         InstanceKlass* next = NULL;
 233         if (top->has_visited_super() == false) {
 234           next = top->next_super();
 235           top->set_super_visited();
 236         } else {
 237           next = top->next_interface();
 238           top->increment_visited_interface();
 239         }
 240         assert(next != NULL, "Otherwise we shouldn't be here");
 241         algo_data = algo->new_node_data(next);
 242         push(next, algo_data);
 243         top_needs_visit = true;
 244       }
 245     } while (!is_cancelled() && has_more_nodes());
 246   }
 247 };
 248 
 249 class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> {
 250  private:
 251    outputStream* _st;
 252  public:
 253   bool visit() {
 254     InstanceKlass* cls = current_class();
 255     streamIndentor si(_st, current_depth() * 2);
 256     _st->indent().print_cr("%s", cls->name()->as_C_string());
 257     return true;
 258   }
 259 
 260   void* new_node_data(InstanceKlass* cls) { return NULL; }
 261   void free_node_data(void* data) { return; }
 262 
 263   PrintHierarchy(outputStream* st = tty) : _st(st) {}
 264 };
 265 


 607 }
 608 
 609 static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots(
 610     InstanceKlass* klass, const GrowableArray<Method*>* mirandas, TRAPS) {
 611 
 612   assert(klass != NULL, "Must be valid class");
 613 
 614   GrowableArray<EmptyVtableSlot*>* slots = new GrowableArray<EmptyVtableSlot*>();
 615 
 616   // All miranda methods are obvious candidates
 617   for (int i = 0; i < mirandas->length(); ++i) {
 618     Method* m = mirandas->at(i);
 619     if (!already_in_vtable_slots(slots, m)) {
 620       slots->append(new EmptyVtableSlot(m));
 621     }
 622   }
 623 
 624   // Also any overpasses in our superclasses, that we haven't implemented.
 625   // (can't use the vtable because it is not guaranteed to be initialized yet)
 626   InstanceKlass* super = klass->java_super();
 627   while (super != NULL) {
 628     for (int i = 0; i < super->methods()->length(); ++i) {
 629       Method* m = super->methods()->at(i);
 630       if (m->is_overpass() || m->is_static()) {
 631         // m is a method that would have been a miranda if not for the
 632         // default method processing that occurred on behalf of our superclass,
 633         // so it's a method we want to re-examine in this new context.  That is,
 634         // unless we have a real implementation of it in the current class.

 635         Method* impl = klass->lookup_method(m->name(), m->signature());
 636         if (impl == NULL || impl->is_overpass() || impl->is_static()) {
 637           if (!already_in_vtable_slots(slots, m)) {
 638             slots->append(new EmptyVtableSlot(m));
 639           }
 640         }
 641       }
 642     }
 643 
 644     // also any default methods in our superclasses
 645     if (super->default_methods() != NULL) {
 646       for (int i = 0; i < super->default_methods()->length(); ++i) {
 647         Method* m = super->default_methods()->at(i);
 648         // m is a method that would have been a miranda if not for the
 649         // default method processing that occurred on behalf of our superclass,
 650         // so it's a method we want to re-examine in this new context.  That is,
 651         // unless we have a real implementation of it in the current class.

 652         Method* impl = klass->lookup_method(m->name(), m->signature());
 653         if (impl == NULL || impl->is_overpass() || impl->is_static()) {
 654           if (!already_in_vtable_slots(slots, m)) {
 655             slots->append(new EmptyVtableSlot(m));
 656           }
 657         }
 658       }
 659     }
 660     super = super->java_super();
 661   }
 662 
 663   LogTarget(Debug, defaultmethods) lt;
 664   if (lt.is_enabled()) {
 665     lt.print("Slots that need filling:");
 666     ResourceMark rm;
 667     LogStream ls(lt);
 668     streamIndentor si(&ls);
 669     for (int i = 0; i < slots->length(); ++i) {
 670       ls.indent();
 671       slots->at(i)->print_on(&ls);
 672       ls.cr();
 673     }
 674   }


 732       } else {
 733         // This is the rule that methods in classes "win" (bad word) over
 734         // methods in interfaces. This works because of single inheritance.
 735         // Private methods in classes do not "win", they will be found
 736         // first on searching, but overriding for invokevirtual needs
 737         // to find default method candidates for the same signature
 738         _family->set_target_if_empty(m);
 739       }
 740     }
 741     return true;
 742   }
 743 
 744 };
 745 
 746 
 747 
 748 static void create_defaults_and_exceptions(
 749     GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS);
 750 
 751 static void generate_erased_defaults(
 752      InstanceKlass* klass, GrowableArray<EmptyVtableSlot*>* empty_slots,
 753      EmptyVtableSlot* slot, bool is_intf, TRAPS) {
 754 
 755   // sets up a set of methods with the same exact erased signature
 756   FindMethodsByErasedSig visitor(slot->name(), slot->signature(), is_intf);
 757   visitor.run(klass);
 758 
 759   MethodFamily* family;
 760   visitor.get_discovered_family(&family);
 761   if (family != NULL) {
 762     family->determine_target(klass, CHECK);
 763     slot->bind_family(family);
 764   }
 765 }
 766 
 767 static void merge_in_new_methods(InstanceKlass* klass,
 768     GrowableArray<Method*>* new_methods, TRAPS);
 769 static void create_default_methods( InstanceKlass* klass,
 770     GrowableArray<Method*>* new_methods, TRAPS);
 771 
 772 // This is the guts of the default methods implementation.  This is called just
 773 // after the classfile has been parsed if some ancestor has default methods.


 795   // Keep entire hierarchy alive for the duration of the computation
 796   constantPoolHandle cp(THREAD, klass->constants());
 797   KeepAliveRegistrar keepAlive(THREAD);
 798   KeepAliveVisitor loadKeepAlive(&keepAlive);
 799   loadKeepAlive.run(klass);
 800 
 801   LogTarget(Debug, defaultmethods) lt;
 802   if (lt.is_enabled()) {
 803     ResourceMark rm;
 804     lt.print("%s %s requires default method processing",
 805              klass->is_interface() ? "Interface" : "Class",
 806              klass->name()->as_klass_external_name());
 807     LogStream ls(lt);
 808     PrintHierarchy printer(&ls);
 809     printer.run(klass);
 810   }
 811 
 812   GrowableArray<EmptyVtableSlot*>* empty_slots =
 813       find_empty_vtable_slots(klass, mirandas, CHECK);
 814 

 815   for (int i = 0; i < empty_slots->length(); ++i) {
 816     EmptyVtableSlot* slot = empty_slots->at(i);
 817     LogTarget(Debug, defaultmethods) lt;
 818     if (lt.is_enabled()) {
 819       LogStream ls(lt);
 820       streamIndentor si(&ls, 2);
 821       ls.indent().print("Looking for default methods for slot ");
 822       slot->print_on(&ls);
 823       ls.cr();
 824     }
 825     generate_erased_defaults(klass, empty_slots, slot, klass->is_interface(), CHECK);
 826   }
 827   log_debug(defaultmethods)("Creating defaults and overpasses...");
 828   create_defaults_and_exceptions(empty_slots, klass, CHECK);

 829   log_debug(defaultmethods)("Default method processing complete");
 830 }
 831 
 832 static int assemble_method_error(
 833     BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) {
 834 
 835   Symbol* init = vmSymbols::object_initializer_name();
 836   Symbol* sig = vmSymbols::string_void_signature();
 837 
 838   BytecodeAssembler assem(buffer, cp);
 839 
 840   assem._new(errorName);
 841   assem.dup();
 842   assem.load_string(message);
 843   assem.invokespecial(errorName, init, sig);
 844   assem.athrow();
 845 
 846   return 3; // max stack size: [ exception, exception, string ]
 847 }
 848 




 136     int number_of_interfaces() { return _class->local_interfaces()->length(); }
 137     int interface_index() { return _interface_index; }
 138     void set_super_visited() { _super_was_visited = true; }
 139     void increment_visited_interface() { ++_interface_index; }
 140     void set_all_interfaces_visited() {
 141       _interface_index = number_of_interfaces();
 142     }
 143     bool has_visited_super() { return _super_was_visited; }
 144     bool has_visited_all_interfaces() {
 145       return interface_index() >= number_of_interfaces();
 146     }
 147     InstanceKlass* interface_at(int index) {
 148       return InstanceKlass::cast(_class->local_interfaces()->at(index));
 149     }
 150     InstanceKlass* next_super() { return _class->java_super(); }
 151     InstanceKlass* next_interface() {
 152       return interface_at(interface_index());
 153     }
 154   };
 155 
 156   bool _visited_object;
 157   GrowableArray<Node*> _path;
 158 
 159   Node* current_top() const { return _path.top(); }
 160   bool has_more_nodes() const { return !_path.is_empty(); }
 161   void push(InstanceKlass* cls, void* data) {
 162     assert(cls != NULL, "Requires a valid instance class");
 163     Node* node = new Node(cls, data, has_super(cls));
 164     if (cls == SystemDictionary::Object_klass()) {
 165       _visited_object = true;
 166     }
 167     _path.push(node);
 168   }
 169   void pop() { _path.pop(); }
 170 
 171   void reset_iteration() {

 172     _path.clear();
 173   }

 174 
 175   // This code used to skip interface classes because their only
 176   // superclass was j.l.Object which would be also covered by class
 177   // superclass hierarchy walks. Now that the starting point can be
 178   // an interface, we must ensure we catch j.l.Object as the super.
 179   bool has_super(InstanceKlass* cls) {
 180     return cls->super() != NULL && (!_visited_object || !cls->is_interface());
 181   }
 182 
 183   Node* node_at_depth(int i) const {
 184     return (i >= _path.length()) ? NULL : _path.at(_path.length() - i - 1);
 185   }
 186 
 187  protected:
 188 
 189   // Accessors available to the algorithm
 190   int current_depth() const { return _path.length() - 1; }
 191 
 192   InstanceKlass* class_at_depth(int i) {
 193     Node* n = node_at_depth(i);
 194     return n == NULL ? NULL : n->_class;
 195   }
 196   InstanceKlass* current_class() { return class_at_depth(0); }
 197 
 198   void* data_at_depth(int i) {
 199     Node* n = node_at_depth(i);
 200     return n == NULL ? NULL : n->_algorithm_data;
 201   }
 202   void* current_data() { return data_at_depth(0); }
 203 


 204  public:
 205 
 206   void run(InstanceKlass* root) {
 207     ALGO* algo = static_cast<ALGO*>(this);
 208 
 209     reset_iteration();
 210 
 211     void* algo_data = algo->new_node_data(root);
 212     push(root, algo_data);
 213     bool top_needs_visit = true;
 214 
 215     do {
 216       Node* top = current_top();
 217       if (top_needs_visit) {
 218         if (algo->visit() == false) {
 219           // algorithm does not want to continue along this path.  Arrange
 220           // it so that this state is immediately popped off the stack
 221           top->set_super_visited();
 222           top->set_all_interfaces_visited();
 223         }
 224         top_needs_visit = false;
 225       }
 226 
 227       if (top->has_visited_super() && top->has_visited_all_interfaces()) {
 228         algo->free_node_data(top->_algorithm_data);
 229         pop();
 230       } else {
 231         InstanceKlass* next = NULL;
 232         if (top->has_visited_super() == false) {
 233           next = top->next_super();
 234           top->set_super_visited();
 235         } else {
 236           next = top->next_interface();
 237           top->increment_visited_interface();
 238         }
 239         assert(next != NULL, "Otherwise we shouldn't be here");
 240         algo_data = algo->new_node_data(next);
 241         push(next, algo_data);
 242         top_needs_visit = true;
 243       }
 244     } while (has_more_nodes());
 245   }
 246 };
 247 
 248 class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> {
 249  private:
 250    outputStream* _st;
 251  public:
 252   bool visit() {
 253     InstanceKlass* cls = current_class();
 254     streamIndentor si(_st, current_depth() * 2);
 255     _st->indent().print_cr("%s", cls->name()->as_C_string());
 256     return true;
 257   }
 258 
 259   void* new_node_data(InstanceKlass* cls) { return NULL; }
 260   void free_node_data(void* data) { return; }
 261 
 262   PrintHierarchy(outputStream* st = tty) : _st(st) {}
 263 };
 264 


 606 }
 607 
 608 static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots(
 609     InstanceKlass* klass, const GrowableArray<Method*>* mirandas, TRAPS) {
 610 
 611   assert(klass != NULL, "Must be valid class");
 612 
 613   GrowableArray<EmptyVtableSlot*>* slots = new GrowableArray<EmptyVtableSlot*>();
 614 
 615   // All miranda methods are obvious candidates
 616   for (int i = 0; i < mirandas->length(); ++i) {
 617     Method* m = mirandas->at(i);
 618     if (!already_in_vtable_slots(slots, m)) {
 619       slots->append(new EmptyVtableSlot(m));
 620     }
 621   }
 622 
 623   // Also any overpasses in our superclasses, that we haven't implemented.
 624   // (can't use the vtable because it is not guaranteed to be initialized yet)
 625   InstanceKlass* super = klass->java_super();
 626   while (super != NULL && super != SystemDictionary::Object_klass()) {
 627     for (int i = 0; i < super->methods()->length(); ++i) {
 628       Method* m = super->methods()->at(i);
 629       if (m->is_overpass() || (m->is_static() && vmSymbols::class_initializer_name() != m->name())) {
 630         // m is a method that would have been a miranda if not for the
 631         // default method processing that occurred on behalf of our superclass,
 632         // so it's a method we want to re-examine in this new context.  That is,
 633         // unless we have a real implementation of it in the current class.
 634         if (!already_in_vtable_slots(slots, m)) {
 635           Method* impl = klass->lookup_method(m->name(), m->signature());
 636           if (impl == NULL || impl->is_overpass() || impl->is_static()) {

 637             slots->append(new EmptyVtableSlot(m));
 638           }
 639         }
 640       }
 641     }
 642 
 643     // also any default methods in our superclasses
 644     if (super->default_methods() != NULL) {
 645       for (int i = 0; i < super->default_methods()->length(); ++i) {
 646         Method* m = super->default_methods()->at(i);
 647         // m is a method that would have been a miranda if not for the
 648         // default method processing that occurred on behalf of our superclass,
 649         // so it's a method we want to re-examine in this new context.  That is,
 650         // unless we have a real implementation of it in the current class.
 651         if (!already_in_vtable_slots(slots, m)) {
 652           Method* impl = klass->lookup_method(m->name(), m->signature());
 653           if (impl == NULL || impl->is_overpass() || impl->is_static()) {

 654             slots->append(new EmptyVtableSlot(m));
 655           }
 656         }
 657       }
 658     }
 659     super = super->java_super();
 660   }
 661 
 662   LogTarget(Debug, defaultmethods) lt;
 663   if (lt.is_enabled()) {
 664     lt.print("Slots that need filling:");
 665     ResourceMark rm;
 666     LogStream ls(lt);
 667     streamIndentor si(&ls);
 668     for (int i = 0; i < slots->length(); ++i) {
 669       ls.indent();
 670       slots->at(i)->print_on(&ls);
 671       ls.cr();
 672     }
 673   }


 731       } else {
 732         // This is the rule that methods in classes "win" (bad word) over
 733         // methods in interfaces. This works because of single inheritance.
 734         // Private methods in classes do not "win", they will be found
 735         // first on searching, but overriding for invokevirtual needs
 736         // to find default method candidates for the same signature
 737         _family->set_target_if_empty(m);
 738       }
 739     }
 740     return true;
 741   }
 742 
 743 };
 744 
 745 
 746 
 747 static void create_defaults_and_exceptions(
 748     GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS);
 749 
 750 static void generate_erased_defaults(
 751      InstanceKlass* klass, EmptyVtableSlot* slot, bool is_intf, TRAPS) {

 752 
 753   // sets up a set of methods with the same exact erased signature
 754   FindMethodsByErasedSig visitor(slot->name(), slot->signature(), is_intf);
 755   visitor.run(klass);
 756 
 757   MethodFamily* family;
 758   visitor.get_discovered_family(&family);
 759   if (family != NULL) {
 760     family->determine_target(klass, CHECK);
 761     slot->bind_family(family);
 762   }
 763 }
 764 
 765 static void merge_in_new_methods(InstanceKlass* klass,
 766     GrowableArray<Method*>* new_methods, TRAPS);
 767 static void create_default_methods( InstanceKlass* klass,
 768     GrowableArray<Method*>* new_methods, TRAPS);
 769 
 770 // This is the guts of the default methods implementation.  This is called just
 771 // after the classfile has been parsed if some ancestor has default methods.


 793   // Keep entire hierarchy alive for the duration of the computation
 794   constantPoolHandle cp(THREAD, klass->constants());
 795   KeepAliveRegistrar keepAlive(THREAD);
 796   KeepAliveVisitor loadKeepAlive(&keepAlive);
 797   loadKeepAlive.run(klass);
 798 
 799   LogTarget(Debug, defaultmethods) lt;
 800   if (lt.is_enabled()) {
 801     ResourceMark rm;
 802     lt.print("%s %s requires default method processing",
 803              klass->is_interface() ? "Interface" : "Class",
 804              klass->name()->as_klass_external_name());
 805     LogStream ls(lt);
 806     PrintHierarchy printer(&ls);
 807     printer.run(klass);
 808   }
 809 
 810   GrowableArray<EmptyVtableSlot*>* empty_slots =
 811       find_empty_vtable_slots(klass, mirandas, CHECK);
 812 
 813   if (empty_slots->length() > 0) {
 814     for (int i = 0; i < empty_slots->length(); ++i) {
 815       EmptyVtableSlot* slot = empty_slots->at(i);
 816       LogTarget(Debug, defaultmethods) lt;
 817       if (lt.is_enabled()) {
 818         LogStream ls(lt);
 819         streamIndentor si(&ls, 2);
 820         ls.indent().print("Looking for default methods for slot ");
 821         slot->print_on(&ls);
 822         ls.cr();
 823       }
 824       generate_erased_defaults(klass, slot, klass->is_interface(), CHECK);
 825     }
 826     log_debug(defaultmethods)("Creating defaults and overpasses...");
 827     create_defaults_and_exceptions(empty_slots, klass, CHECK);
 828   }
 829   log_debug(defaultmethods)("Default method processing complete");
 830 }
 831 
 832 static int assemble_method_error(
 833     BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) {
 834 
 835   Symbol* init = vmSymbols::object_initializer_name();
 836   Symbol* sig = vmSymbols::string_void_signature();
 837 
 838   BytecodeAssembler assem(buffer, cp);
 839 
 840   assem._new(errorName);
 841   assem.dup();
 842   assem.load_string(message);
 843   assem.invokespecial(errorName, init, sig);
 844   assem.athrow();
 845 
 846   return 3; // max stack size: [ exception, exception, string ]
 847 }
 848 


< prev index next >