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_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const;
353
354 public:
355
356 MethodFamily()
357 : _selected_target(NULL), _exception_message(NULL), _exception_name(NULL) {}
358
359 void set_target_if_empty(Method* m) {
360 if (_selected_target == NULL && !m->is_overpass()) {
361 _selected_target = m;
362 }
363 }
364
365 void record_qualified_method(Method* m) {
366 // If the method already exists in the set as qualified, this operation is
367 // redundant. If it already exists as disqualified, then we leave it as
368 // disqualfied. Thus we only add to the set if it's not already in the
369 // set.
370 if (!contains_method(m)) {
371 add_method(m, QUALIFIED);
397
398 // Qualified methods are maximally-specific methods
399 // These include public, instance concrete (=default) and abstract methods
400 GrowableArray<Method*> qualified_methods;
401 int num_defaults = 0;
402 int default_index = -1;
403 int qualified_index = -1;
404 for (int i = 0; i < _members.length(); ++i) {
405 Pair<Method*,QualifiedState> entry = _members.at(i);
406 if (entry.second == QUALIFIED) {
407 qualified_methods.append(entry.first);
408 qualified_index++;
409 if (entry.first->is_default_method()) {
410 num_defaults++;
411 default_index = qualified_index;
412
413 }
414 }
415 }
416
417 if (qualified_methods.length() == 0) {
418 _exception_message = generate_no_defaults_message(CHECK);
419 _exception_name = vmSymbols::java_lang_AbstractMethodError();
420 // If only one qualified method is default, select that
421 } else if (num_defaults == 1) {
422 _selected_target = qualified_methods.at(default_index);
423 } else if (num_defaults > 1) {
424 _exception_message = generate_conflicts_message(&qualified_methods,CHECK);
425 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
426 if (TraceDefaultMethods) {
427 _exception_message->print_value_on(tty);
428 tty->print_cr("");
429 }
430 }
431 // leave abstract methods alone, they will be found via normal search path
432 }
433
434 bool contains_signature(Symbol* query) {
435 for (int i = 0; i < _members.length(); ++i) {
436 if (query == _members.at(i).first->signature()) {
437 return true;
438 }
439 }
440 return false;
441 }
442
443 #ifndef PRODUCT
444 void print_sig_on(outputStream* str, Symbol* signature, int indent) const {
445 streamIndentor si(str, indent * 2);
446
447 str->indent().print_cr("Logical Method %s:", signature->as_C_string());
448
449 streamIndentor si2(str);
450 for (int i = 0; i < _members.length(); ++i) {
451 str->indent();
469 Klass* method_holder = _selected_target->method_holder();
470 if (!method_holder->is_interface()) {
471 tty->print(" : in superclass");
472 }
473 str->print_cr("");
474 }
475
476 void print_exception(outputStream* str, int indent) {
477 assert(throws_exception(), "Should be called otherwise");
478 assert(_exception_name != NULL, "exception_name should be set");
479 streamIndentor si(str, indent * 2);
480 str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string());
481 }
482 #endif // ndef PRODUCT
483 };
484
485 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const {
486 return SymbolTable::new_symbol("No qualifying defaults found", CHECK_NULL);
487 }
488
489 Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const {
490 stringStream ss;
491 ss.print("Conflicting default methods:");
492 for (int i = 0; i < methods->length(); ++i) {
493 Method* method = methods->at(i);
494 Symbol* klass = method->klass_name();
495 Symbol* name = method->name();
496 ss.print(" ");
497 ss.write((const char*)klass->bytes(), klass->utf8_length());
498 ss.print(".");
499 ss.write((const char*)name->bytes(), name->utf8_length());
500 }
501 return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL);
502 }
503
504
505 class StateRestorer;
506
507 // StatefulMethodFamily is a wrapper around a MethodFamily that maintains the
508 // qualification state during hierarchy visitation, and applies that state
|
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);
398
399 // Qualified methods are maximally-specific methods
400 // These include public, instance concrete (=default) and abstract methods
401 GrowableArray<Method*> qualified_methods;
402 int num_defaults = 0;
403 int default_index = -1;
404 int qualified_index = -1;
405 for (int i = 0; i < _members.length(); ++i) {
406 Pair<Method*,QualifiedState> entry = _members.at(i);
407 if (entry.second == QUALIFIED) {
408 qualified_methods.append(entry.first);
409 qualified_index++;
410 if (entry.first->is_default_method()) {
411 num_defaults++;
412 default_index = qualified_index;
413
414 }
415 }
416 }
417
418 if (num_defaults == 0) {
419 if (qualified_methods.length() == 0) {
420 _exception_message = generate_no_defaults_message(CHECK);
421 } else {
422 assert(root != NULL, "Null root class");
423 _exception_message = generate_method_message(root->name(), qualified_methods.at(0), CHECK);
424 }
425 _exception_name = vmSymbols::java_lang_AbstractMethodError();
426 // If only one qualified method is default, select that
427 } else if (num_defaults == 1) {
428 _selected_target = qualified_methods.at(default_index);
429 } else if (num_defaults > 1) {
430 _exception_message = generate_conflicts_message(&qualified_methods,CHECK);
431 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
432 if (TraceDefaultMethods) {
433 _exception_message->print_value_on(tty);
434 tty->print_cr("");
435 }
436 }
437 }
438
439 bool contains_signature(Symbol* query) {
440 for (int i = 0; i < _members.length(); ++i) {
441 if (query == _members.at(i).first->signature()) {
442 return true;
443 }
444 }
445 return false;
446 }
447
448 #ifndef PRODUCT
449 void print_sig_on(outputStream* str, Symbol* signature, int indent) const {
450 streamIndentor si(str, indent * 2);
451
452 str->indent().print_cr("Logical Method %s:", signature->as_C_string());
453
454 streamIndentor si2(str);
455 for (int i = 0; i < _members.length(); ++i) {
456 str->indent();
474 Klass* method_holder = _selected_target->method_holder();
475 if (!method_holder->is_interface()) {
476 tty->print(" : in superclass");
477 }
478 str->print_cr("");
479 }
480
481 void print_exception(outputStream* str, int indent) {
482 assert(throws_exception(), "Should be called otherwise");
483 assert(_exception_name != NULL, "exception_name should be set");
484 streamIndentor si(str, indent * 2);
485 str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string());
486 }
487 #endif // ndef PRODUCT
488 };
489
490 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const {
491 return SymbolTable::new_symbol("No qualifying defaults found", CHECK_NULL);
492 }
493
494 Symbol* MethodFamily::generate_method_message(Symbol *klass_name, Method* method, TRAPS) const {
495 stringStream ss;
496 ss.print("Method ");
497 Symbol* name = method->name();
498 Symbol* signature = method->signature();
499 ss.write((const char*)klass_name->bytes(), klass_name->utf8_length());
500 ss.print(".");
501 ss.write((const char*)name->bytes(), name->utf8_length());
502 ss.write((const char*)signature->bytes(), signature->utf8_length());
503 ss.print(" is abstract");
504 return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL);
505 }
506
507 Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const {
508 stringStream ss;
509 ss.print("Conflicting default methods:");
510 for (int i = 0; i < methods->length(); ++i) {
511 Method* method = methods->at(i);
512 Symbol* klass = method->klass_name();
513 Symbol* name = method->name();
514 ss.print(" ");
515 ss.write((const char*)klass->bytes(), klass->utf8_length());
516 ss.print(".");
517 ss.write((const char*)name->bytes(), name->utf8_length());
518 }
519 return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL);
520 }
521
522
523 class StateRestorer;
524
525 // StatefulMethodFamily is a wrapper around a MethodFamily that maintains the
526 // qualification state during hierarchy visitation, and applies that state
|