255 |
255 |
256 // add miranda methods; it will also return the updated initialized |
256 // add miranda methods; it will also return the updated initialized |
257 // Interfaces do not need interface methods in their vtables |
257 // Interfaces do not need interface methods in their vtables |
258 // This includes miranda methods and during later processing, default methods |
258 // This includes miranda methods and during later processing, default methods |
259 if (!ik()->is_interface()) { |
259 if (!ik()->is_interface()) { |
260 initialized = fill_in_mirandas(initialized); |
260 initialized = fill_in_mirandas(initialized, THREAD); |
261 } |
261 } |
262 |
262 |
263 // In class hierarchies where the accessibility is not increasing (i.e., going from private -> |
263 // In class hierarchies where the accessibility is not increasing (i.e., going from private -> |
264 // package_private -> public/protected), the vtable might actually be smaller than our initial |
264 // package_private -> public/protected), the vtable might actually be smaller than our initial |
265 // calculation, for classfile versions for which we do not do transitive override |
265 // calculation, for classfile versions for which we do not do transitive override |
362 // Only called for InstanceKlass's, i.e. not for arrays |
362 // Only called for InstanceKlass's, i.e. not for arrays |
363 // If that changed, could not use _klass as handle for klass |
363 // If that changed, could not use _klass as handle for klass |
364 bool klassVtable::update_inherited_vtable(InstanceKlass* klass, const methodHandle& target_method, |
364 bool klassVtable::update_inherited_vtable(InstanceKlass* klass, const methodHandle& target_method, |
365 int super_vtable_len, int default_index, |
365 int super_vtable_len, int default_index, |
366 bool checkconstraints, TRAPS) { |
366 bool checkconstraints, TRAPS) { |
367 ResourceMark rm; |
367 ResourceMark rm(THREAD); |
368 bool allocate_new = true; |
368 bool allocate_new = true; |
369 assert(klass->is_instance_klass(), "must be InstanceKlass"); |
369 assert(klass->is_instance_klass(), "must be InstanceKlass"); |
370 |
370 |
371 Array<int>* def_vtable_indices = NULL; |
371 Array<int>* def_vtable_indices = NULL; |
372 bool is_default = false; |
372 bool is_default = false; |
900 // Discover miranda methods ("miranda" = "interface abstract, no binding"), |
900 // Discover miranda methods ("miranda" = "interface abstract, no binding"), |
901 // and append them into the vtable starting at index initialized, |
901 // and append them into the vtable starting at index initialized, |
902 // return the new value of initialized. |
902 // return the new value of initialized. |
903 // Miranda methods use vtable entries, but do not get assigned a vtable_index |
903 // Miranda methods use vtable entries, but do not get assigned a vtable_index |
904 // The vtable_index is discovered by searching from the end of the vtable |
904 // The vtable_index is discovered by searching from the end of the vtable |
905 int klassVtable::fill_in_mirandas(int initialized) { |
905 int klassVtable::fill_in_mirandas(int initialized, TRAPS) { |
|
906 ResourceMark rm(THREAD); |
906 GrowableArray<Method*> mirandas(20); |
907 GrowableArray<Method*> mirandas(20); |
907 get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), |
908 get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), |
908 ik()->default_methods(), ik()->local_interfaces(), |
909 ik()->default_methods(), ik()->local_interfaces(), |
909 klass()->is_interface()); |
910 klass()->is_interface()); |
910 for (int i = 0; i < mirandas.length(); i++) { |
911 for (int i = 0; i < mirandas.length(); i++) { |
911 if (log_develop_is_enabled(Trace, vtables)) { |
912 if (log_develop_is_enabled(Trace, vtables)) { |
912 Method* meth = mirandas.at(i); |
913 Method* meth = mirandas.at(i); |
913 ResourceMark rm(Thread::current()); |
|
914 LogTarget(Trace, vtables) lt; |
914 LogTarget(Trace, vtables) lt; |
915 LogStream ls(lt); |
915 LogStream ls(lt); |
916 if (meth != NULL) { |
916 if (meth != NULL) { |
917 char* sig = meth->name_and_sig_as_C_string(); |
917 char* sig = meth->name_and_sig_as_C_string(); |
918 ls.print("fill in mirandas with %s index %d, flags: ", |
918 ls.print("fill in mirandas with %s index %d, flags: ", |
1083 // Initialization |
1083 // Initialization |
1084 void klassItable::initialize_itable(bool checkconstraints, TRAPS) { |
1084 void klassItable::initialize_itable(bool checkconstraints, TRAPS) { |
1085 if (_klass->is_interface()) { |
1085 if (_klass->is_interface()) { |
1086 // This needs to go after vtable indices are assigned but |
1086 // This needs to go after vtable indices are assigned but |
1087 // before implementors need to know the number of itable indices. |
1087 // before implementors need to know the number of itable indices. |
1088 assign_itable_indices_for_interface(_klass); |
1088 assign_itable_indices_for_interface(_klass, THREAD); |
1089 } |
1089 } |
1090 |
1090 |
1091 // Cannot be setup doing bootstrapping, interfaces don't have |
1091 // Cannot be setup doing bootstrapping, interfaces don't have |
1092 // itables, and klass with only ones entry have empty itables |
1092 // itables, and klass with only ones entry have empty itables |
1093 if (Universe::is_bootstrapping() || |
1093 if (Universe::is_bootstrapping() || |
1096 |
1096 |
1097 // There's alway an extra itable entry so we can null-terminate it. |
1097 // There's alway an extra itable entry so we can null-terminate it. |
1098 guarantee(size_offset_table() >= 1, "too small"); |
1098 guarantee(size_offset_table() >= 1, "too small"); |
1099 int num_interfaces = size_offset_table() - 1; |
1099 int num_interfaces = size_offset_table() - 1; |
1100 if (num_interfaces > 0) { |
1100 if (num_interfaces > 0) { |
|
1101 ResourceMark rm(THREAD); |
1101 log_develop_debug(itables)("%3d: Initializing itables for %s", ++initialize_count, |
1102 log_develop_debug(itables)("%3d: Initializing itables for %s", ++initialize_count, |
1102 _klass->name()->as_C_string()); |
1103 _klass->name()->as_C_string()); |
1103 |
1104 |
1104 |
1105 |
1105 // Iterate through all interfaces |
1106 // Iterate through all interfaces |
1128 // e.g., CharSequence.toString (from initialize_vtable) |
1129 // e.g., CharSequence.toString (from initialize_vtable) |
1129 // if (m->has_vtable_index()) return false; // NO! |
1130 // if (m->has_vtable_index()) return false; // NO! |
1130 return true; |
1131 return true; |
1131 } |
1132 } |
1132 |
1133 |
1133 int klassItable::assign_itable_indices_for_interface(Klass* klass) { |
1134 int klassItable::assign_itable_indices_for_interface(Klass* klass, TRAPS) { |
1134 // an interface does not have an itable, but its methods need to be numbered |
1135 // an interface does not have an itable, but its methods need to be numbered |
|
1136 ResourceMark rm(THREAD); |
1135 log_develop_debug(itables)("%3d: Initializing itable indices for interface %s", |
1137 log_develop_debug(itables)("%3d: Initializing itable indices for interface %s", |
1136 ++initialize_count, klass->name()->as_C_string()); |
1138 ++initialize_count, klass->name()->as_C_string()); |
1137 Array<Method*>* methods = InstanceKlass::cast(klass)->methods(); |
1139 Array<Method*>* methods = InstanceKlass::cast(klass)->methods(); |
1138 int nof_methods = methods->length(); |
1140 int nof_methods = methods->length(); |
1139 int ime_num = 0; |
1141 int ime_num = 0; |
1141 Method* m = methods->at(i); |
1143 Method* m = methods->at(i); |
1142 if (interface_method_needs_itable_index(m)) { |
1144 if (interface_method_needs_itable_index(m)) { |
1143 assert(!m->is_final_method(), "no final interface methods"); |
1145 assert(!m->is_final_method(), "no final interface methods"); |
1144 // If m is already assigned a vtable index, do not disturb it. |
1146 // If m is already assigned a vtable index, do not disturb it. |
1145 if (log_develop_is_enabled(Trace, itables)) { |
1147 if (log_develop_is_enabled(Trace, itables)) { |
1146 ResourceMark rm; |
|
1147 LogTarget(Trace, itables) lt; |
1148 LogTarget(Trace, itables) lt; |
1148 LogStream ls(lt); |
1149 LogStream ls(lt); |
1149 assert(m != NULL, "methods can never be null"); |
1150 assert(m != NULL, "methods can never be null"); |
1150 const char* sig = m->name_and_sig_as_C_string(); |
1151 const char* sig = m->name_and_sig_as_C_string(); |
1151 if (m->has_vtable_index()) { |
1152 if (m->has_vtable_index()) { |
1505 _verify_count = Universe::verify_count(); |
1506 _verify_count = Universe::verify_count(); |
1506 #endif |
1507 #endif |
1507 oop* end_of_obj = (oop*)_klass + _klass->size(); |
1508 oop* end_of_obj = (oop*)_klass + _klass->size(); |
1508 oop* end_of_vtable = (oop *)&table()[_length]; |
1509 oop* end_of_vtable = (oop *)&table()[_length]; |
1509 if (end_of_vtable > end_of_obj) { |
1510 if (end_of_vtable > end_of_obj) { |
|
1511 ResourceMark rm; |
1510 fatal("klass %s: klass object too short (vtable extends beyond end)", |
1512 fatal("klass %s: klass object too short (vtable extends beyond end)", |
1511 _klass->internal_name()); |
1513 _klass->internal_name()); |
1512 } |
1514 } |
1513 |
1515 |
1514 for (int i = 0; i < _length; i++) table()[i].verify(this, st); |
1516 for (int i = 0; i < _length; i++) table()[i].verify(this, st); |