comparison src/share/vm/oops/klassVtable.cpp @ 6934:4735d2c84362

7200776: Implement default methods in interfaces Summary: Add generic type analysis and default method selection algorithms Reviewed-by: coleenp, acorn
author kamg
date Thu, 11 Oct 2012 12:25:42 -0400
parents d8ce2825b193
children 18fb7da42534
comparison
equal deleted inserted replaced
6921:a1b8cf9cf970 6934:4735d2c84362
52 // interface I. Let's say there is a method m in I that neither C nor any 52 // interface I. Let's say there is a method m in I that neither C nor any
53 // of its super classes implement (i.e there is no method of any access, with 53 // of its super classes implement (i.e there is no method of any access, with
54 // the same name and signature as m), then m is a Miranda method which is 54 // the same name and signature as m), then m is a Miranda method which is
55 // entered as a public abstract method in C's vtable. From then on it should 55 // entered as a public abstract method in C's vtable. From then on it should
56 // treated as any other public method in C for method over-ride purposes. 56 // treated as any other public method in C for method over-ride purposes.
57 void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length, 57 void klassVtable::compute_vtable_size_and_num_mirandas(
58 int &num_miranda_methods, 58 int* vtable_length_ret, int* num_new_mirandas,
59 Klass* super, 59 GrowableArray<Method*>* all_mirandas, Klass* super,
60 Array<Method*>* methods, 60 Array<Method*>* methods, AccessFlags class_flags,
61 AccessFlags class_flags, 61 Handle classloader, Symbol* classname, Array<Klass*>* local_interfaces,
62 Handle classloader, 62 TRAPS) {
63 Symbol* classname,
64 Array<Klass*>* local_interfaces,
65 TRAPS
66 ) {
67
68 No_Safepoint_Verifier nsv; 63 No_Safepoint_Verifier nsv;
69 64
70 // set up default result values 65 // set up default result values
71 vtable_length = 0; 66 int vtable_length = 0;
72 num_miranda_methods = 0;
73 67
74 // start off with super's vtable length 68 // start off with super's vtable length
75 InstanceKlass* sk = (InstanceKlass*)super; 69 InstanceKlass* sk = (InstanceKlass*)super;
76 vtable_length = super == NULL ? 0 : sk->vtable_length(); 70 vtable_length = super == NULL ? 0 : sk->vtable_length();
77 71
84 if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) { 78 if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) {
85 vtable_length += vtableEntry::size(); // we need a new entry 79 vtable_length += vtableEntry::size(); // we need a new entry
86 } 80 }
87 } 81 }
88 82
83 GrowableArray<Method*> new_mirandas(20);
89 // compute the number of mirandas methods that must be added to the end 84 // compute the number of mirandas methods that must be added to the end
90 num_miranda_methods = get_num_mirandas(super, methods, local_interfaces); 85 get_mirandas(&new_mirandas, all_mirandas, super, methods, local_interfaces);
91 vtable_length += (num_miranda_methods * vtableEntry::size()); 86 *num_new_mirandas = new_mirandas.length();
87
88 vtable_length += *num_new_mirandas * vtableEntry::size();
92 89
93 if (Universe::is_bootstrapping() && vtable_length == 0) { 90 if (Universe::is_bootstrapping() && vtable_length == 0) {
94 // array classes don't have their superclass set correctly during 91 // array classes don't have their superclass set correctly during
95 // bootstrapping 92 // bootstrapping
96 vtable_length = Universe::base_vtable_size(); 93 vtable_length = Universe::base_vtable_size();
107 } 104 }
108 assert(super != NULL || vtable_length == Universe::base_vtable_size(), 105 assert(super != NULL || vtable_length == Universe::base_vtable_size(),
109 "bad vtable size for class Object"); 106 "bad vtable size for class Object");
110 assert(vtable_length % vtableEntry::size() == 0, "bad vtable length"); 107 assert(vtable_length % vtableEntry::size() == 0, "bad vtable length");
111 assert(vtable_length >= Universe::base_vtable_size(), "vtable too small"); 108 assert(vtable_length >= Universe::base_vtable_size(), "vtable too small");
109
110 *vtable_length_ret = vtable_length;
112 } 111 }
113 112
114 int klassVtable::index_of(Method* m, int len) const { 113 int klassVtable::index_of(Method* m, int len) const {
115 assert(m->vtable_index() >= 0, "do not ask this of non-vtable methods"); 114 assert(m->vtable_index() >= 0, "do not ask this of non-vtable methods");
116 return m->vtable_index(); 115 return m->vtable_index();
189 initialized++; 188 initialized++;
190 } 189 }
191 } 190 }
192 191
193 // add miranda methods; it will also update the value of initialized 192 // add miranda methods; it will also update the value of initialized
194 fill_in_mirandas(initialized); 193 fill_in_mirandas(&initialized);
195 194
196 // In class hierarchies where the accessibility is not increasing (i.e., going from private -> 195 // In class hierarchies where the accessibility is not increasing (i.e., going from private ->
197 // package_private -> publicprotected), the vtable might actually be smaller than our initial 196 // package_private -> publicprotected), the vtable might actually be smaller than our initial
198 // calculation. 197 // calculation.
199 assert(initialized <= _length, "vtable initialization failed"); 198 assert(initialized <= _length, "vtable initialization failed");
247 } 246 }
248 247
249 return superk; 248 return superk;
250 } 249 }
251 250
251 // Methods that are "effectively" final don't need vtable entries.
252 bool method_is_effectively_final(
253 AccessFlags klass_flags, methodHandle target) {
254 return target->is_final() || klass_flags.is_final() && !target->is_overpass();
255 }
252 256
253 // Update child's copy of super vtable for overrides 257 // Update child's copy of super vtable for overrides
254 // OR return true if a new vtable entry is required 258 // OR return true if a new vtable entry is required
255 // Only called for InstanceKlass's, i.e. not for arrays 259 // Only called for InstanceKlass's, i.e. not for arrays
256 // If that changed, could not use _klass as handle for klass 260 // If that changed, could not use _klass as handle for klass
267 // Static and <init> methods are never in 271 // Static and <init> methods are never in
268 if (target_method()->is_static() || target_method()->name() == vmSymbols::object_initializer_name()) { 272 if (target_method()->is_static() || target_method()->name() == vmSymbols::object_initializer_name()) {
269 return false; 273 return false;
270 } 274 }
271 275
272 if (klass->is_final() || target_method()->is_final()) { 276 if (method_is_effectively_final(klass->access_flags(), target_method)) {
273 // a final method never needs a new entry; final methods can be statically 277 // a final method never needs a new entry; final methods can be statically
274 // resolved and they have to be present in the vtable only if they override 278 // resolved and they have to be present in the vtable only if they override
275 // a super's method, in which case they re-use its entry 279 // a super's method, in which case they re-use its entry
276 allocate_new = false; 280 allocate_new = false;
277 } 281 }
404 Klass* super, 408 Klass* super,
405 Handle classloader, 409 Handle classloader,
406 Symbol* classname, 410 Symbol* classname,
407 AccessFlags class_flags, 411 AccessFlags class_flags,
408 TRAPS) { 412 TRAPS) {
409 if ((class_flags.is_final() || target_method()->is_final()) || 413
414 if (method_is_effectively_final(class_flags, target_method) ||
410 // a final method never needs a new entry; final methods can be statically 415 // a final method never needs a new entry; final methods can be statically
411 // resolved and they have to be present in the vtable only if they override 416 // resolved and they have to be present in the vtable only if they override
412 // a super's method, in which case they re-use its entry 417 // a super's method, in which case they re-use its entry
413 (target_method()->is_static()) || 418 (target_method()->is_static()) ||
414 // static methods don't need to be in vtable 419 // static methods don't need to be in vtable
500 Klass* method_holder = m->method_holder(); 505 Klass* method_holder = m->method_holder();
501 InstanceKlass *mhk = InstanceKlass::cast(method_holder); 506 InstanceKlass *mhk = InstanceKlass::cast(method_holder);
502 507
503 // miranda methods are interface methods in a class's vtable 508 // miranda methods are interface methods in a class's vtable
504 if (mhk->is_interface()) { 509 if (mhk->is_interface()) {
505 assert(m->is_public() && m->is_abstract(), "should be public and abstract"); 510 assert(m->is_public(), "should be public");
506 assert(ik()->implements_interface(method_holder) , "this class should implement the interface"); 511 assert(ik()->implements_interface(method_holder) , "this class should implement the interface");
507 assert(is_miranda(m, ik()->methods(), ik()->super()), "should be a miranda_method"); 512 assert(is_miranda(m, ik()->methods(), ik()->super()), "should be a miranda_method");
508 return true; 513 return true;
509 } 514 }
510 return false; 515 return false;
530 } 535 }
531 536
532 return false; 537 return false;
533 } 538 }
534 539
535 void klassVtable::add_new_mirandas_to_list(GrowableArray<Method*>* list_of_current_mirandas, 540 void klassVtable::add_new_mirandas_to_lists(
536 Array<Method*>* current_interface_methods, 541 GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas,
537 Array<Method*>* class_methods, 542 Array<Method*>* current_interface_methods, Array<Method*>* class_methods,
538 Klass* super) { 543 Klass* super) {
539 // iterate thru the current interface's method to see if it a miranda 544 // iterate thru the current interface's method to see if it a miranda
540 int num_methods = current_interface_methods->length(); 545 int num_methods = current_interface_methods->length();
541 for (int i = 0; i < num_methods; i++) { 546 for (int i = 0; i < num_methods; i++) {
542 Method* im = current_interface_methods->at(i); 547 Method* im = current_interface_methods->at(i);
543 bool is_duplicate = false; 548 bool is_duplicate = false;
544 int num_of_current_mirandas = list_of_current_mirandas->length(); 549 int num_of_current_mirandas = new_mirandas->length();
545 // check for duplicate mirandas in different interfaces we implement 550 // check for duplicate mirandas in different interfaces we implement
546 for (int j = 0; j < num_of_current_mirandas; j++) { 551 for (int j = 0; j < num_of_current_mirandas; j++) {
547 Method* miranda = list_of_current_mirandas->at(j); 552 Method* miranda = new_mirandas->at(j);
548 if ((im->name() == miranda->name()) && 553 if ((im->name() == miranda->name()) &&
549 (im->signature() == miranda->signature())) { 554 (im->signature() == miranda->signature())) {
550 is_duplicate = true; 555 is_duplicate = true;
551 break; 556 break;
552 } 557 }
555 if (!is_duplicate) { // we don't want duplicate miranda entries in the vtable 560 if (!is_duplicate) { // we don't want duplicate miranda entries in the vtable
556 if (is_miranda(im, class_methods, super)) { // is it a miranda at all? 561 if (is_miranda(im, class_methods, super)) { // is it a miranda at all?
557 InstanceKlass *sk = InstanceKlass::cast(super); 562 InstanceKlass *sk = InstanceKlass::cast(super);
558 // check if it is a duplicate of a super's miranda 563 // check if it is a duplicate of a super's miranda
559 if (sk->lookup_method_in_all_interfaces(im->name(), im->signature()) == NULL) { 564 if (sk->lookup_method_in_all_interfaces(im->name(), im->signature()) == NULL) {
560 list_of_current_mirandas->append(im); 565 new_mirandas->append(im);
566 }
567 if (all_mirandas != NULL) {
568 all_mirandas->append(im);
561 } 569 }
562 } 570 }
563 } 571 }
564 } 572 }
565 } 573 }
566 574
567 void klassVtable::get_mirandas(GrowableArray<Method*>* mirandas, 575 void klassVtable::get_mirandas(GrowableArray<Method*>* new_mirandas,
576 GrowableArray<Method*>* all_mirandas,
568 Klass* super, Array<Method*>* class_methods, 577 Klass* super, Array<Method*>* class_methods,
569 Array<Klass*>* local_interfaces) { 578 Array<Klass*>* local_interfaces) {
570 assert((mirandas->length() == 0) , "current mirandas must be 0"); 579 assert((new_mirandas->length() == 0) , "current mirandas must be 0");
571 580
572 // iterate thru the local interfaces looking for a miranda 581 // iterate thru the local interfaces looking for a miranda
573 int num_local_ifs = local_interfaces->length(); 582 int num_local_ifs = local_interfaces->length();
574 for (int i = 0; i < num_local_ifs; i++) { 583 for (int i = 0; i < num_local_ifs; i++) {
575 InstanceKlass *ik = InstanceKlass::cast(local_interfaces->at(i)); 584 InstanceKlass *ik = InstanceKlass::cast(local_interfaces->at(i));
576 add_new_mirandas_to_list(mirandas, ik->methods(), class_methods, super); 585 add_new_mirandas_to_lists(new_mirandas, all_mirandas,
586 ik->methods(), class_methods, super);
577 // iterate thru each local's super interfaces 587 // iterate thru each local's super interfaces
578 Array<Klass*>* super_ifs = ik->transitive_interfaces(); 588 Array<Klass*>* super_ifs = ik->transitive_interfaces();
579 int num_super_ifs = super_ifs->length(); 589 int num_super_ifs = super_ifs->length();
580 for (int j = 0; j < num_super_ifs; j++) { 590 for (int j = 0; j < num_super_ifs; j++) {
581 InstanceKlass *sik = InstanceKlass::cast(super_ifs->at(j)); 591 InstanceKlass *sik = InstanceKlass::cast(super_ifs->at(j));
582 add_new_mirandas_to_list(mirandas, sik->methods(), class_methods, super); 592 add_new_mirandas_to_lists(new_mirandas, all_mirandas,
583 } 593 sik->methods(), class_methods, super);
584 } 594 }
585 } 595 }
586
587 // get number of mirandas
588 int klassVtable::get_num_mirandas(Klass* super, Array<Method*>* class_methods, Array<Klass*>* local_interfaces) {
589 ResourceMark rm;
590 GrowableArray<Method*>* mirandas = new GrowableArray<Method*>(20);
591 get_mirandas(mirandas, super, class_methods, local_interfaces);
592 return mirandas->length();
593 } 596 }
594 597
595 // fill in mirandas 598 // fill in mirandas
596 void klassVtable::fill_in_mirandas(int& initialized) { 599 void klassVtable::fill_in_mirandas(int* initialized) {
597 ResourceMark rm; 600 GrowableArray<Method*> mirandas(20);
598 GrowableArray<Method*>* mirandas = new GrowableArray<Method*>(20); 601 get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(),
599 InstanceKlass *this_ik = ik(); 602 ik()->local_interfaces());
600 get_mirandas(mirandas, this_ik->super(), this_ik->methods(), this_ik->local_interfaces()); 603 for (int i = 0; i < mirandas.length(); i++) {
601 int num_mirandas = mirandas->length(); 604 put_method_at(mirandas.at(i), *initialized);
602 for (int i = 0; i < num_mirandas; i++) { 605 ++(*initialized);
603 put_method_at(mirandas->at(i), initialized);
604 initialized++;
605 } 606 }
606 } 607 }
607 608
608 void klassVtable::copy_vtable_to(vtableEntry* start) { 609 void klassVtable::copy_vtable_to(vtableEntry* start) {
609 Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size()); 610 Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size());