Mercurial > hg > truffle
comparison src/share/vm/oops/klassVtable.cpp @ 697:922aedc96ef5
Merge
author | ysr |
---|---|
date | Fri, 03 Apr 2009 15:59:19 -0700 |
parents | d3676b4cb78c |
children | cff162798819 |
comparison
equal
deleted
inserted
replaced
696:f18338cf04b0 | 697:922aedc96ef5 |
---|---|
1 /* | 1 /* |
2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. | 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
43 void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length, | 43 void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length, |
44 int &num_miranda_methods, | 44 int &num_miranda_methods, |
45 klassOop super, | 45 klassOop super, |
46 objArrayOop methods, | 46 objArrayOop methods, |
47 AccessFlags class_flags, | 47 AccessFlags class_flags, |
48 oop classloader, | 48 Handle classloader, |
49 symbolOop classname, | 49 symbolHandle classname, |
50 objArrayOop local_interfaces | 50 objArrayOop local_interfaces, |
51 TRAPS | |
51 ) { | 52 ) { |
52 | 53 |
53 No_Safepoint_Verifier nsv; | 54 No_Safepoint_Verifier nsv; |
54 | 55 |
55 // set up default result values | 56 // set up default result values |
62 | 63 |
63 // go thru each method in the methods table to see if it needs a new entry | 64 // go thru each method in the methods table to see if it needs a new entry |
64 int len = methods->length(); | 65 int len = methods->length(); |
65 for (int i = 0; i < len; i++) { | 66 for (int i = 0; i < len; i++) { |
66 assert(methods->obj_at(i)->is_method(), "must be a methodOop"); | 67 assert(methods->obj_at(i)->is_method(), "must be a methodOop"); |
67 methodOop m = methodOop(methods->obj_at(i)); | 68 methodHandle mh(THREAD, methodOop(methods->obj_at(i))); |
68 | 69 |
69 if (needs_new_vtable_entry(m, super, classloader, classname, class_flags)) { | 70 if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) { |
70 vtable_length += vtableEntry::size(); // we need a new entry | 71 vtable_length += vtableEntry::size(); // we need a new entry |
71 } | 72 } |
72 } | 73 } |
73 | 74 |
74 // compute the number of mirandas methods that must be added to the end | 75 // compute the number of mirandas methods that must be added to the end |
115 superVtable->verify(tty, true); | 116 superVtable->verify(tty, true); |
116 #endif | 117 #endif |
117 superVtable->copy_vtable_to(table()); | 118 superVtable->copy_vtable_to(table()); |
118 #ifndef PRODUCT | 119 #ifndef PRODUCT |
119 if (PrintVtables && Verbose) { | 120 if (PrintVtables && Verbose) { |
121 ResourceMark rm; | |
120 tty->print_cr("copy vtable from %s to %s size %d", sk->internal_name(), klass()->internal_name(), _length); | 122 tty->print_cr("copy vtable from %s to %s size %d", sk->internal_name(), klass()->internal_name(), _length); |
121 } | 123 } |
122 #endif | 124 #endif |
123 return superVtable->length(); | 125 return superVtable->length(); |
124 } | 126 } |
157 | 159 |
158 objArrayHandle methods(THREAD, ik()->methods()); | 160 objArrayHandle methods(THREAD, ik()->methods()); |
159 int len = methods()->length(); | 161 int len = methods()->length(); |
160 int initialized = super_vtable_len; | 162 int initialized = super_vtable_len; |
161 | 163 |
162 // update_super_vtable can stop for gc - ensure using handles | 164 // update_inherited_vtable can stop for gc - ensure using handles |
163 for (int i = 0; i < len; i++) { | 165 for (int i = 0; i < len; i++) { |
164 HandleMark hm(THREAD); | 166 HandleMark hm(THREAD); |
165 assert(methods()->obj_at(i)->is_method(), "must be a methodOop"); | 167 assert(methods()->obj_at(i)->is_method(), "must be a methodOop"); |
166 methodHandle mh(THREAD, (methodOop)methods()->obj_at(i)); | 168 methodHandle mh(THREAD, (methodOop)methods()->obj_at(i)); |
167 | 169 |
168 bool needs_new_entry = update_super_vtable(ik(), mh, super_vtable_len, checkconstraints, CHECK); | 170 bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, checkconstraints, CHECK); |
169 | 171 |
170 if (needs_new_entry) { | 172 if (needs_new_entry) { |
171 put_method_at(mh(), initialized); | 173 put_method_at(mh(), initialized); |
172 mh()->set_vtable_index(initialized); // set primary vtable index | 174 mh()->set_vtable_index(initialized); // set primary vtable index |
173 initialized++; | 175 initialized++; |
175 } | 177 } |
176 | 178 |
177 // add miranda methods; it will also update the value of initialized | 179 // add miranda methods; it will also update the value of initialized |
178 fill_in_mirandas(initialized); | 180 fill_in_mirandas(initialized); |
179 | 181 |
180 // In class hierachieswhere the accesibility is not increasing (i.e., going from private -> | 182 // In class hierarchies where the accessibility is not increasing (i.e., going from private -> |
181 // package_private -> publicprotected), the vtable might actually be smaller than our initial | 183 // package_private -> publicprotected), the vtable might actually be smaller than our initial |
182 // calculation. | 184 // calculation. |
183 assert(initialized <= _length, "vtable initialization failed"); | 185 assert(initialized <= _length, "vtable initialization failed"); |
184 for(;initialized < _length; initialized++) { | 186 for(;initialized < _length; initialized++) { |
185 put_method_at(NULL, initialized); | 187 put_method_at(NULL, initialized); |
186 } | 188 } |
187 NOT_PRODUCT(verify(tty, true)); | 189 NOT_PRODUCT(verify(tty, true)); |
188 } | 190 } |
189 } | 191 } |
190 | 192 |
191 // Interates through the vtables to find the broadest access level. This | 193 // Called for cases where a method does not override its superclass' vtable entry |
192 // will always be monotomic for valid Java programs - but not neccesarily | 194 // For bytecodes not produced by javac together it is possible that a method does not override |
193 // for incompatible class files. | 195 // the superclass's method, but might indirectly override a super-super class's vtable entry |
194 klassVtable::AccessType klassVtable::vtable_accessibility_at(int i) { | 196 // If none found, return a null superk, else return the superk of the method this does override |
195 // This vtable is not implementing the specific method | 197 instanceKlass* klassVtable::find_transitive_override(instanceKlass* initialsuper, methodHandle target_method, |
196 if (i >= length()) return acc_private; | 198 int vtable_index, Handle target_loader, symbolHandle target_classname, Thread * THREAD) { |
197 | 199 instanceKlass* superk = initialsuper; |
198 // Compute AccessType for current method. public or protected we are done. | 200 while (superk != NULL && superk->super() != NULL) { |
199 methodOop m = method_at(i); | 201 instanceKlass* supersuperklass = instanceKlass::cast(superk->super()); |
200 if (m->is_protected() || m->is_public()) return acc_publicprotected; | 202 klassVtable* ssVtable = supersuperklass->vtable(); |
201 | 203 if (vtable_index < ssVtable->length()) { |
202 AccessType acc = m->is_package_private() ? acc_package_private : acc_private; | 204 methodOop super_method = ssVtable->method_at(vtable_index); |
203 | 205 #ifndef PRODUCT |
204 // Compute AccessType for method in super classes | 206 symbolHandle name(THREAD,target_method()->name()); |
205 klassOop super = klass()->super(); | 207 symbolHandle signature(THREAD,target_method()->signature()); |
206 AccessType super_acc = (super != NULL) ? instanceKlass::cast(klass()->super())->vtable()->vtable_accessibility_at(i) | 208 assert(super_method->name() == name() && super_method->signature() == signature(), "vtable entry name/sig mismatch"); |
207 : acc_private; | 209 #endif |
208 | 210 if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { |
209 // Merge | 211 #ifndef PRODUCT |
210 return (AccessType)MAX2((int)acc, (int)super_acc); | 212 if (PrintVtables && Verbose) { |
213 ResourceMark rm(THREAD); | |
214 tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", | |
215 supersuperklass->internal_name(), | |
216 _klass->internal_name(), (target_method() != NULL) ? | |
217 target_method()->name()->as_C_string() : "<NULL>", vtable_index); | |
218 super_method->access_flags().print_on(tty); | |
219 tty->print("overriders flags: "); | |
220 target_method->access_flags().print_on(tty); | |
221 tty->cr(); | |
222 } | |
223 #endif /*PRODUCT*/ | |
224 break; // return found superk | |
225 } | |
226 } else { | |
227 // super class has no vtable entry here, stop transitive search | |
228 superk = (instanceKlass*)NULL; | |
229 break; | |
230 } | |
231 // if no override found yet, continue to search up | |
232 superk = instanceKlass::cast(superk->super()); | |
233 } | |
234 | |
235 return superk; | |
211 } | 236 } |
212 | 237 |
213 | 238 |
214 // Update child's copy of super vtable for overrides | 239 // Update child's copy of super vtable for overrides |
215 // OR return true if a new vtable entry is required | 240 // OR return true if a new vtable entry is required |
216 // Only called for instanceKlass's, i.e. not for arrays | 241 // Only called for instanceKlass's, i.e. not for arrays |
217 // If that changed, could not use _klass as handle for klass | 242 // If that changed, could not use _klass as handle for klass |
218 bool klassVtable::update_super_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len, bool checkconstraints, TRAPS) { | 243 bool klassVtable::update_inherited_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len, |
244 bool checkconstraints, TRAPS) { | |
219 ResourceMark rm; | 245 ResourceMark rm; |
220 bool allocate_new = true; | 246 bool allocate_new = true; |
221 assert(klass->oop_is_instance(), "must be instanceKlass"); | 247 assert(klass->oop_is_instance(), "must be instanceKlass"); |
222 | 248 |
223 // Initialize the method's vtable index to "nonvirtual". | 249 // Initialize the method's vtable index to "nonvirtual". |
240 if (klass->super() == NULL) { | 266 if (klass->super() == NULL) { |
241 return allocate_new; | 267 return allocate_new; |
242 } | 268 } |
243 | 269 |
244 // private methods always have a new entry in the vtable | 270 // private methods always have a new entry in the vtable |
271 // specification interpretation since classic has | |
272 // private methods not overriding | |
245 if (target_method()->is_private()) { | 273 if (target_method()->is_private()) { |
246 return allocate_new; | 274 return allocate_new; |
247 } | 275 } |
248 | 276 |
249 // search through the vtable and update overridden entries | 277 // search through the vtable and update overridden entries |
250 // Since check_signature_loaders acquires SystemDictionary_lock | 278 // Since check_signature_loaders acquires SystemDictionary_lock |
251 // which can block for gc, once we are in this loop, use handles, not | 279 // which can block for gc, once we are in this loop, use handles |
252 // unhandled oops unless they are reinitialized for each loop | 280 // For classfiles built with >= jdk7, we now look for transitive overrides |
253 // handles for name, signature, klass, target_method | |
254 // not for match_method, holder | |
255 | 281 |
256 symbolHandle name(THREAD,target_method()->name()); | 282 symbolHandle name(THREAD,target_method()->name()); |
257 symbolHandle signature(THREAD,target_method()->signature()); | 283 symbolHandle signature(THREAD,target_method()->signature()); |
284 Handle target_loader(THREAD, _klass->class_loader()); | |
285 symbolHandle target_classname(THREAD, _klass->name()); | |
258 for(int i = 0; i < super_vtable_len; i++) { | 286 for(int i = 0; i < super_vtable_len; i++) { |
259 methodOop match_method = method_at(i); | 287 methodOop super_method = method_at(i); |
260 // Check if method name matches | 288 // Check if method name matches |
261 if (match_method->name() == name() && match_method->signature() == signature()) { | 289 if (super_method->name() == name() && super_method->signature() == signature()) { |
262 | 290 |
263 instanceKlass* holder = (THREAD, instanceKlass::cast(match_method->method_holder())); | 291 // get super_klass for method_holder for the found method |
264 | 292 instanceKlass* super_klass = instanceKlass::cast(super_method->method_holder()); |
265 // Check if the match_method is accessable from current class | 293 |
266 | 294 if ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) || |
267 bool same_package_init = false; | 295 ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) |
268 bool same_package_flag = false; | 296 && ((super_klass = find_transitive_override(super_klass, target_method, i, target_loader, |
269 bool simple_match = match_method->is_public() || match_method->is_protected(); | 297 target_classname, THREAD)) != (instanceKlass*)NULL))) { |
270 if (!simple_match) { | 298 // overriding, so no new entry |
271 same_package_init = true; | 299 allocate_new = false; |
272 same_package_flag = holder->is_same_class_package(_klass->class_loader(), _klass->name()); | |
273 | |
274 simple_match = match_method->is_package_private() && same_package_flag; | |
275 } | |
276 // match_method is the superclass' method. Note we can't override | |
277 // and shouldn't access superclass' ACC_PRIVATE methods | |
278 // (although they have been copied into our vtable) | |
279 // A simple form of this statement is: | |
280 // if ( (match_method->is_public() || match_method->is_protected()) || | |
281 // (match_method->is_package_private() && holder->is_same_class_package(klass->class_loader(), klass->name()))) { | |
282 // | |
283 // The complexity is introduced it avoid recomputing 'is_same_class_package' which is expensive. | |
284 if (simple_match) { | |
285 // Check if target_method and match_method has same level of accessibility. The accesibility of the | |
286 // match method is the "most-general" visibility of all entries at it's particular vtable index for | |
287 // all superclasses. This check must be done before we override the current entry in the vtable. | |
288 AccessType at = vtable_accessibility_at(i); | |
289 bool same_access = false; | |
290 | |
291 if ( (at == acc_publicprotected && (target_method()->is_public() || target_method()->is_protected()) | |
292 || (at == acc_package_private && (target_method()->is_package_private() && | |
293 (( same_package_init && same_package_flag) || | |
294 (!same_package_init && holder->is_same_class_package(_klass->class_loader(), _klass->name()))))))) { | |
295 same_access = true; | |
296 } | |
297 | 300 |
298 if (checkconstraints) { | 301 if (checkconstraints) { |
299 // Override vtable entry if passes loader constraint check | 302 // Override vtable entry if passes loader constraint check |
300 // if loader constraint checking requested | 303 // if loader constraint checking requested |
301 // No need to visit his super, since he and his super | 304 // No need to visit his super, since he and his super |
302 // have already made any needed loader constraints. | 305 // have already made any needed loader constraints. |
303 // Since loader constraints are transitive, it is enough | 306 // Since loader constraints are transitive, it is enough |
304 // to link to the first super, and we get all the others. | 307 // to link to the first super, and we get all the others. |
305 symbolHandle signature(THREAD, target_method()->signature()); | |
306 Handle this_loader(THREAD, _klass->class_loader()); | |
307 instanceKlassHandle super_klass(THREAD, _klass->super()); | |
308 Handle super_loader(THREAD, super_klass->class_loader()); | 308 Handle super_loader(THREAD, super_klass->class_loader()); |
309 | 309 |
310 if (this_loader() != super_loader()) { | 310 if (target_loader() != super_loader()) { |
311 ResourceMark rm(THREAD); | 311 ResourceMark rm(THREAD); |
312 char* failed_type_name = | 312 char* failed_type_name = |
313 SystemDictionary::check_signature_loaders(signature, this_loader, | 313 SystemDictionary::check_signature_loaders(signature, target_loader, |
314 super_loader, true, | 314 super_loader, true, |
315 CHECK_(false)); | 315 CHECK_(false)); |
316 if (failed_type_name != NULL) { | 316 if (failed_type_name != NULL) { |
317 const char* msg = "loader constraint violation: when resolving " | 317 const char* msg = "loader constraint violation: when resolving " |
318 "overridden method \"%s\" the class loader (instance" | 318 "overridden method \"%s\" the class loader (instance" |
319 " of %s) of the current class, %s, and its superclass loader " | 319 " of %s) of the current class, %s, and its superclass loader " |
320 "(instance of %s), have different Class objects for the type " | 320 "(instance of %s), have different Class objects for the type " |
321 "%s used in the signature"; | 321 "%s used in the signature"; |
322 char* sig = target_method()->name_and_sig_as_C_string(); | 322 char* sig = target_method()->name_and_sig_as_C_string(); |
323 const char* loader1 = SystemDictionary::loader_name(this_loader()); | 323 const char* loader1 = SystemDictionary::loader_name(target_loader()); |
324 char* current = _klass->name()->as_C_string(); | 324 char* current = _klass->name()->as_C_string(); |
325 const char* loader2 = SystemDictionary::loader_name(super_loader()); | 325 const char* loader2 = SystemDictionary::loader_name(super_loader()); |
326 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + | 326 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
327 strlen(current) + strlen(loader2) + strlen(failed_type_name); | 327 strlen(current) + strlen(loader2) + strlen(failed_type_name); |
328 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); | 328 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
329 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, | 329 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
330 failed_type_name); | 330 failed_type_name); |
331 THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); | 331 THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); |
332 } | 332 } |
333 } | 333 } |
334 } | |
335 | |
336 put_method_at(target_method(), i); | |
337 target_method()->set_vtable_index(i); | |
338 #ifndef PRODUCT | |
339 if (PrintVtables && Verbose) { | |
340 tty->print("overriding with %s::%s index %d, original flags: ", | |
341 _klass->internal_name(), (target_method() != NULL) ? | |
342 target_method()->name()->as_C_string() : "<NULL>", i); | |
343 super_method->access_flags().print_on(tty); | |
344 tty->print("overriders flags: "); | |
345 target_method->access_flags().print_on(tty); | |
346 tty->cr(); | |
334 } | 347 } |
335 put_method_at(target_method(), i); | 348 #endif /*PRODUCT*/ |
336 | 349 } else { |
337 | 350 // allocate_new = true; default. We might override one entry, |
338 if (same_access) { | 351 // but not override another. Once we override one, not need new |
339 // target and match has same accessiblity - share entry | |
340 allocate_new = false; | |
341 target_method()->set_vtable_index(i); | |
342 #ifndef PRODUCT | 352 #ifndef PRODUCT |
343 if (PrintVtables && Verbose) { | 353 if (PrintVtables && Verbose) { |
344 AccessType targetacc; | 354 tty->print("NOT overriding with %s::%s index %d, original flags: ", |
345 if (target_method()->is_protected() || | 355 _klass->internal_name(), (target_method() != NULL) ? |
346 target_method()->is_public()) { | 356 target_method()->name()->as_C_string() : "<NULL>", i); |
347 targetacc = acc_publicprotected; | 357 super_method->access_flags().print_on(tty); |
348 } else { | 358 tty->print("overriders flags: "); |
349 targetacc = target_method()->is_package_private() ? acc_package_private : acc_private; | 359 target_method->access_flags().print_on(tty); |
350 } | 360 tty->cr(); |
351 tty->print_cr("overriding with %s::%s index %d, original flags: %x overriders flags: %x", | 361 } |
352 _klass->internal_name(), (target_method() != NULL) ? | |
353 target_method()->name()->as_C_string() : "<NULL>", i, | |
354 at, targetacc); | |
355 } | |
356 #endif /*PRODUCT*/ | 362 #endif /*PRODUCT*/ |
357 } else { | |
358 #ifndef PRODUCT | |
359 if (PrintVtables && Verbose) { | |
360 AccessType targetacc; | |
361 if (target_method()->is_protected() || | |
362 target_method()->is_public()) { | |
363 targetacc = acc_publicprotected; | |
364 } else { | |
365 targetacc = target_method()->is_package_private() ? acc_package_private : acc_private; | |
366 } | |
367 tty->print_cr("override %s %s::%s at index %d, original flags: %x overriders flags: %x", | |
368 allocate_new ? "+ new" : "only", | |
369 _klass->internal_name(), (target_method() != NULL) ? | |
370 target_method()->name()->as_C_string() : "<NULL>", i, | |
371 at, targetacc); | |
372 } | |
373 #endif /*PRODUCT*/ | |
374 } | |
375 } | 363 } |
376 } | 364 } |
377 } | 365 } |
378 return allocate_new; | 366 return allocate_new; |
379 } | 367 } |
380 | |
381 | |
382 | 368 |
383 void klassVtable::put_method_at(methodOop m, int index) { | 369 void klassVtable::put_method_at(methodOop m, int index) { |
384 assert(m->is_oop_or_null(), "Not an oop or null"); | 370 assert(m->is_oop_or_null(), "Not an oop or null"); |
385 #ifndef PRODUCT | 371 #ifndef PRODUCT |
386 if (PrintVtables && Verbose) { | 372 if (PrintVtables && Verbose) { |
373 ResourceMark rm; | |
387 tty->print_cr("adding %s::%s at index %d", _klass->internal_name(), | 374 tty->print_cr("adding %s::%s at index %d", _klass->internal_name(), |
388 (m != NULL) ? m->name()->as_C_string() : "<NULL>", index); | 375 (m != NULL) ? m->name()->as_C_string() : "<NULL>", index); |
389 } | 376 } |
390 assert(unchecked_method_at(index)->is_oop_or_null(), "Not an oop or null"); | 377 assert(unchecked_method_at(index)->is_oop_or_null(), "Not an oop or null"); |
391 #endif | 378 #endif |
395 // Find out if a method "m" with superclass "super", loader "classloader" and | 382 // Find out if a method "m" with superclass "super", loader "classloader" and |
396 // name "classname" needs a new vtable entry. Let P be a class package defined | 383 // name "classname" needs a new vtable entry. Let P be a class package defined |
397 // by "classloader" and "classname". | 384 // by "classloader" and "classname". |
398 // NOTE: The logic used here is very similar to the one used for computing | 385 // NOTE: The logic used here is very similar to the one used for computing |
399 // the vtables indices for a method. We cannot directly use that function because, | 386 // the vtables indices for a method. We cannot directly use that function because, |
400 // when the Universe is boostrapping, a super's vtable might not be initialized. | 387 // we allocate the instanceKlass at load time, and that requires that the |
401 bool klassVtable::needs_new_vtable_entry(methodOop target_method, | 388 // superclass has been loaded. |
389 // However, the vtable entries are filled in at link time, and therefore | |
390 // the superclass' vtable may not yet have been filled in. | |
391 bool klassVtable::needs_new_vtable_entry(methodHandle target_method, | |
402 klassOop super, | 392 klassOop super, |
403 oop classloader, | 393 Handle classloader, |
404 symbolOop classname, | 394 symbolHandle classname, |
405 AccessFlags class_flags) { | 395 AccessFlags class_flags, |
406 if ((class_flags.is_final() || target_method->is_final()) || | 396 TRAPS) { |
397 if ((class_flags.is_final() || target_method()->is_final()) || | |
407 // a final method never needs a new entry; final methods can be statically | 398 // a final method never needs a new entry; final methods can be statically |
408 // resolved and they have to be present in the vtable only if they override | 399 // resolved and they have to be present in the vtable only if they override |
409 // a super's method, in which case they re-use its entry | 400 // a super's method, in which case they re-use its entry |
410 (target_method->is_static()) || | 401 (target_method()->is_static()) || |
411 // static methods don't need to be in vtable | 402 // static methods don't need to be in vtable |
412 (target_method->name() == vmSymbols::object_initializer_name()) | 403 (target_method()->name() == vmSymbols::object_initializer_name()) |
413 // <init> is never called dynamically-bound | 404 // <init> is never called dynamically-bound |
414 ) { | 405 ) { |
415 return false; | 406 return false; |
416 } | 407 } |
417 | 408 |
419 if (super == NULL) { | 410 if (super == NULL) { |
420 return true; | 411 return true; |
421 } | 412 } |
422 | 413 |
423 // private methods always have a new entry in the vtable | 414 // private methods always have a new entry in the vtable |
424 if (target_method->is_private()) { | 415 // specification interpretation since classic has |
416 // private methods not overriding | |
417 if (target_method()->is_private()) { | |
425 return true; | 418 return true; |
426 } | 419 } |
427 | 420 |
428 // search through the super class hierarchy to see if we need | 421 // search through the super class hierarchy to see if we need |
429 // a new entry | 422 // a new entry |
430 symbolOop name = target_method->name(); | 423 ResourceMark rm; |
431 symbolOop signature = target_method->signature(); | 424 symbolOop name = target_method()->name(); |
425 symbolOop signature = target_method()->signature(); | |
432 klassOop k = super; | 426 klassOop k = super; |
433 methodOop match_method = NULL; | 427 methodOop super_method = NULL; |
434 instanceKlass *holder = NULL; | 428 instanceKlass *holder = NULL; |
429 methodOop recheck_method = NULL; | |
435 while (k != NULL) { | 430 while (k != NULL) { |
436 // lookup through the hierarchy for a method with matching name and sign. | 431 // lookup through the hierarchy for a method with matching name and sign. |
437 match_method = instanceKlass::cast(k)->lookup_method(name, signature); | 432 super_method = instanceKlass::cast(k)->lookup_method(name, signature); |
438 if (match_method == NULL) { | 433 if (super_method == NULL) { |
439 break; // we still have to search for a matching miranda method | 434 break; // we still have to search for a matching miranda method |
440 } | 435 } |
441 // get the class holding the matching method | 436 // get the class holding the matching method |
442 holder = instanceKlass::cast(match_method->method_holder()); | 437 // make sure you use that class for is_override |
443 | 438 instanceKlass* superk = instanceKlass::cast(super_method->method_holder()); |
444 if (!match_method->is_static()) { // we want only instance method matches | 439 // we want only instance method matches |
445 if ((target_method->is_public() || target_method->is_protected()) && | 440 // pretend private methods are not in the super vtable |
446 (match_method->is_public() || match_method->is_protected())) { | 441 // since we do override around them: e.g. a.m pub/b.m private/c.m pub, |
447 // target and match are public/protected; we do not need a new entry | 442 // ignore private, c.m pub does override a.m pub |
443 // For classes that were not javac'd together, we also do transitive overriding around | |
444 // methods that have less accessibility | |
445 if ((!super_method->is_static()) && | |
446 (!super_method->is_private())) { | |
447 if (superk->is_override(super_method, classloader, classname, THREAD)) { | |
448 return false; | 448 return false; |
449 // else keep looking for transitive overrides | |
449 } | 450 } |
450 | 451 } |
451 if (target_method->is_package_private() && | 452 |
452 match_method->is_package_private() && | 453 // Start with lookup result and continue to search up |
453 holder->is_same_class_package(classloader, classname)) { | 454 k = superk->super(); // haven't found an override match yet; continue to look |
454 // target and match are P private; we do not need a new entry | |
455 return false; | |
456 } | |
457 } | |
458 | |
459 k = holder->super(); // haven't found a match yet; continue to look | |
460 } | 455 } |
461 | 456 |
462 // if the target method is public or protected it may have a matching | 457 // if the target method is public or protected it may have a matching |
463 // miranda method in the super, whose entry it should re-use. | 458 // miranda method in the super, whose entry it should re-use. |
464 if (target_method->is_public() || target_method->is_protected()) { | 459 // Actually, to handle cases that javac would not generate, we need |
465 instanceKlass *sk = instanceKlass::cast(super); | 460 // this check for all access permissions. |
466 if (sk->has_miranda_methods()) { | 461 instanceKlass *sk = instanceKlass::cast(super); |
467 if (sk->lookup_method_in_all_interfaces(name, signature) != NULL) { | 462 if (sk->has_miranda_methods()) { |
468 return false; // found a matching miranda; we do not need a new entry | 463 if (sk->lookup_method_in_all_interfaces(name, signature) != NULL) { |
469 } | 464 return false; // found a matching miranda; we do not need a new entry |
470 } | 465 } |
471 } | 466 } |
472 | |
473 return true; // found no match; we need a new entry | 467 return true; // found no match; we need a new entry |
474 } | 468 } |
475 | 469 |
476 // Support for miranda methods | 470 // Support for miranda methods |
477 | 471 |
882 if (num_interfaces > 0) { | 876 if (num_interfaces > 0) { |
883 if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, | 877 if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, |
884 _klass->name()->as_C_string()); | 878 _klass->name()->as_C_string()); |
885 | 879 |
886 | 880 |
887 // Interate through all interfaces | 881 // Iterate through all interfaces |
888 int i; | 882 int i; |
889 for(i = 0; i < num_interfaces; i++) { | 883 for(i = 0; i < num_interfaces; i++) { |
890 itableOffsetEntry* ioe = offset_entry(i); | 884 itableOffsetEntry* ioe = offset_entry(i); |
891 KlassHandle interf_h (THREAD, ioe->interface_klass()); | 885 KlassHandle interf_h (THREAD, ioe->interface_klass()); |
892 assert(interf_h() != NULL && ioe->offset() != 0, "bad offset entry in itable"); | 886 assert(interf_h() != NULL && ioe->offset() != 0, "bad offset entry in itable"); |
1010 // RC_TRACE macro has an embedded ResourceMark | 1004 // RC_TRACE macro has an embedded ResourceMark |
1011 RC_TRACE(0x00200000, ("itable method update: %s(%s)", | 1005 RC_TRACE(0x00200000, ("itable method update: %s(%s)", |
1012 new_method->name()->as_C_string(), | 1006 new_method->name()->as_C_string(), |
1013 new_method->signature()->as_C_string())); | 1007 new_method->signature()->as_C_string())); |
1014 } | 1008 } |
1009 break; | |
1015 } | 1010 } |
1016 ime++; | 1011 ime++; |
1017 } | 1012 } |
1018 } | 1013 } |
1019 } | 1014 } |
1149 // Adjust for <clinit>, which is left out of table if first method | 1144 // Adjust for <clinit>, which is left out of table if first method |
1150 if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->name() == vmSymbols::class_initializer_name()) { | 1145 if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->name() == vmSymbols::class_initializer_name()) { |
1151 index--; | 1146 index--; |
1152 } | 1147 } |
1153 return index; | 1148 return index; |
1149 } | |
1150 | |
1151 | |
1152 // inverse to compute_itable_index | |
1153 methodOop klassItable::method_for_itable_index(klassOop intf, int itable_index) { | |
1154 assert(instanceKlass::cast(intf)->is_interface(), "sanity check"); | |
1155 objArrayOop methods = instanceKlass::cast(intf)->methods(); | |
1156 | |
1157 int index = itable_index; | |
1158 // Adjust for <clinit>, which is left out of table if first method | |
1159 if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->name() == vmSymbols::class_initializer_name()) { | |
1160 index++; | |
1161 } | |
1162 | |
1163 if (itable_index < 0 || index >= methods->length()) | |
1164 return NULL; // help caller defend against bad indexes | |
1165 | |
1166 methodOop m = (methodOop)methods->obj_at(index); | |
1167 assert(compute_itable_index(m) == itable_index, "correct inverse"); | |
1168 | |
1169 return m; | |
1154 } | 1170 } |
1155 | 1171 |
1156 void klassVtable::verify(outputStream* st, bool forced) { | 1172 void klassVtable::verify(outputStream* st, bool forced) { |
1157 // make sure table is initialized | 1173 // make sure table is initialized |
1158 if (!Universe::is_fully_initialized()) return; | 1174 if (!Universe::is_fully_initialized()) return; |