332 Symbol* _exception_name; // If no unique target is found
333
334 bool contains_method(Method* method) {
335 int* lookup = _member_index.get(method);
336 return lookup != NULL;
337 }
338
339 void add_method(Method* method, QualifiedState state) {
340 Pair<Method*,QualifiedState> entry(method, state);
341 _member_index.put(method, _members.length());
342 _members.append(entry);
343 }
344
345 void disqualify_method(Method* method) {
346 int* index = _member_index.get(method);
347 guarantee(index != NULL && *index >= 0 && *index < _members.length(), "bad index");
348 _members.at(*index).second = DISQUALIFIED;
349 }
350
351 Symbol* generate_no_defaults_message(TRAPS) const;
352 Symbol* generate_method_message(Symbol *klass_name, Method* method, TRAPS) const;
353 Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const;
354
355 public:
356
357 MethodFamily()
358 : _selected_target(NULL), _exception_message(NULL), _exception_name(NULL) {}
359
360 void set_target_if_empty(Method* m) {
361 if (_selected_target == NULL && !m->is_overpass()) {
362 _selected_target = m;
363 }
364 }
365
366 void record_qualified_method(Method* m) {
367 // If the method already exists in the set as qualified, this operation is
368 // redundant. If it already exists as disqualified, then we leave it as
369 // disqualfied. Thus we only add to the set if it's not already in the
370 // set.
371 if (!contains_method(m)) {
372 add_method(m, QUALIFIED);
479 Klass* method_holder = _selected_target->method_holder();
480 if (!method_holder->is_interface()) {
481 tty->print(" : in superclass");
482 }
483 str->cr();
484 }
485
486 void print_exception(outputStream* str, int indent) {
487 assert(throws_exception(), "Should be called otherwise");
488 assert(_exception_name != NULL, "exception_name should be set");
489 streamIndentor si(str, indent * 2);
490 str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string());
491 }
492 #endif // ndef PRODUCT
493 };
494
495 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const {
496 return SymbolTable::new_symbol("No qualifying defaults found", THREAD);
497 }
498
499 Symbol* MethodFamily::generate_method_message(Symbol *klass_name, Method* method, TRAPS) const {
500 stringStream ss;
501 ss.print("Method ");
502 Symbol* name = method->name();
503 Symbol* signature = method->signature();
504 ss.write((const char*)klass_name->bytes(), klass_name->utf8_length());
505 ss.print(".");
506 ss.write((const char*)name->bytes(), name->utf8_length());
507 ss.write((const char*)signature->bytes(), signature->utf8_length());
508 ss.print(" is abstract");
509 return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD);
510 }
511
512 Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const {
513 stringStream ss;
514 ss.print("Conflicting default methods:");
515 for (int i = 0; i < methods->length(); ++i) {
516 Method* method = methods->at(i);
517 Symbol* klass = method->klass_name();
518 Symbol* name = method->name();
519 ss.print(" ");
601 _size_of_parameters(method->size_of_parameters()), _binding(NULL) {}
602
603 Symbol* name() const { return _name; }
604 Symbol* signature() const { return _signature; }
605 int size_of_parameters() const { return _size_of_parameters; }
606
607 void bind_family(MethodFamily* lm) { _binding = lm; }
608 bool is_bound() { return _binding != NULL; }
609 MethodFamily* get_binding() { return _binding; }
610
611 #ifndef PRODUCT
612 void print_on(outputStream* str) const {
613 print_slot(str, name(), signature());
614 }
615 #endif // ndef PRODUCT
616 };
617
618 static bool already_in_vtable_slots(GrowableArray<EmptyVtableSlot*>* slots, Method* m) {
619 bool found = false;
620 for (int j = 0; j < slots->length(); ++j) {
621 if (slots->at(j)->name() == m->name() &&
622 slots->at(j)->signature() == m->signature() ) {
623 found = true;
624 break;
625 }
626 }
627 return found;
628 }
629
630 static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots(
631 InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) {
632
633 assert(klass != NULL, "Must be valid class");
634
635 GrowableArray<EmptyVtableSlot*>* slots = new GrowableArray<EmptyVtableSlot*>();
636
637 // All miranda methods are obvious candidates
638 for (int i = 0; i < mirandas->length(); ++i) {
639 Method* m = mirandas->at(i);
640 if (!already_in_vtable_slots(slots, m)) {
641 slots->append(new EmptyVtableSlot(m));
642 }
|
332 Symbol* _exception_name; // If no unique target is found
333
334 bool contains_method(Method* method) {
335 int* lookup = _member_index.get(method);
336 return lookup != NULL;
337 }
338
339 void add_method(Method* method, QualifiedState state) {
340 Pair<Method*,QualifiedState> entry(method, state);
341 _member_index.put(method, _members.length());
342 _members.append(entry);
343 }
344
345 void disqualify_method(Method* method) {
346 int* index = _member_index.get(method);
347 guarantee(index != NULL && *index >= 0 && *index < _members.length(), "bad index");
348 _members.at(*index).second = DISQUALIFIED;
349 }
350
351 Symbol* generate_no_defaults_message(TRAPS) const;
352 Symbol* generate_method_message(Symbol* klass_name, Method* method, TRAPS) const;
353 Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const;
354
355 public:
356
357 MethodFamily()
358 : _selected_target(NULL), _exception_message(NULL), _exception_name(NULL) {}
359
360 void set_target_if_empty(Method* m) {
361 if (_selected_target == NULL && !m->is_overpass()) {
362 _selected_target = m;
363 }
364 }
365
366 void record_qualified_method(Method* m) {
367 // If the method already exists in the set as qualified, this operation is
368 // redundant. If it already exists as disqualified, then we leave it as
369 // disqualfied. Thus we only add to the set if it's not already in the
370 // set.
371 if (!contains_method(m)) {
372 add_method(m, QUALIFIED);
479 Klass* method_holder = _selected_target->method_holder();
480 if (!method_holder->is_interface()) {
481 tty->print(" : in superclass");
482 }
483 str->cr();
484 }
485
486 void print_exception(outputStream* str, int indent) {
487 assert(throws_exception(), "Should be called otherwise");
488 assert(_exception_name != NULL, "exception_name should be set");
489 streamIndentor si(str, indent * 2);
490 str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string());
491 }
492 #endif // ndef PRODUCT
493 };
494
495 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const {
496 return SymbolTable::new_symbol("No qualifying defaults found", THREAD);
497 }
498
499 Symbol* MethodFamily::generate_method_message(Symbol* klass_name, Method* method, TRAPS) const {
500 stringStream ss;
501 ss.print("Method ");
502 Symbol* name = method->name();
503 Symbol* signature = method->signature();
504 ss.write((const char*)klass_name->bytes(), klass_name->utf8_length());
505 ss.print(".");
506 ss.write((const char*)name->bytes(), name->utf8_length());
507 ss.write((const char*)signature->bytes(), signature->utf8_length());
508 ss.print(" is abstract");
509 return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD);
510 }
511
512 Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const {
513 stringStream ss;
514 ss.print("Conflicting default methods:");
515 for (int i = 0; i < methods->length(); ++i) {
516 Method* method = methods->at(i);
517 Symbol* klass = method->klass_name();
518 Symbol* name = method->name();
519 ss.print(" ");
601 _size_of_parameters(method->size_of_parameters()), _binding(NULL) {}
602
603 Symbol* name() const { return _name; }
604 Symbol* signature() const { return _signature; }
605 int size_of_parameters() const { return _size_of_parameters; }
606
607 void bind_family(MethodFamily* lm) { _binding = lm; }
608 bool is_bound() { return _binding != NULL; }
609 MethodFamily* get_binding() { return _binding; }
610
611 #ifndef PRODUCT
612 void print_on(outputStream* str) const {
613 print_slot(str, name(), signature());
614 }
615 #endif // ndef PRODUCT
616 };
617
618 static bool already_in_vtable_slots(GrowableArray<EmptyVtableSlot*>* slots, Method* m) {
619 bool found = false;
620 for (int j = 0; j < slots->length(); ++j) {
621 if (slots->at(j)->name()->equals(m->name()) &&
622 slots->at(j)->signature()->equals(m->signature()) ) {
623 found = true;
624 break;
625 }
626 }
627 return found;
628 }
629
630 static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots(
631 InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) {
632
633 assert(klass != NULL, "Must be valid class");
634
635 GrowableArray<EmptyVtableSlot*>* slots = new GrowableArray<EmptyVtableSlot*>();
636
637 // All miranda methods are obvious candidates
638 for (int i = 0; i < mirandas->length(); ++i) {
639 Method* m = mirandas->at(i);
640 if (!already_in_vtable_slots(slots, m)) {
641 slots->append(new EmptyVtableSlot(m));
642 }
|