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(); |
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()); |