Mercurial > hg > truffle
comparison src/share/vm/oops/instanceKlass.cpp @ 12857:d37a0525c0fe
8024667: VM crashes with "assert(method() != NULL) failed: must have set method"
Summary: Check if data is in shared spaces before deallocating it.
Reviewed-by: coleenp, dcubed
author | hseigel |
---|---|
date | Sat, 12 Oct 2013 15:39:16 -0400 |
parents | d25557d03ec0 |
children | b8860472c377 |
comparison
equal
deleted
inserted
replaced
12856:3e265ce4d2dd | 12857:d37a0525c0fe |
---|---|
318 } | 318 } |
319 | 319 |
320 | 320 |
321 void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data, | 321 void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data, |
322 Array<Method*>* methods) { | 322 Array<Method*>* methods) { |
323 if (methods != NULL && methods != Universe::the_empty_method_array()) { | 323 if (methods != NULL && methods != Universe::the_empty_method_array() && |
324 !methods->is_shared()) { | |
324 for (int i = 0; i < methods->length(); i++) { | 325 for (int i = 0; i < methods->length(); i++) { |
325 Method* method = methods->at(i); | 326 Method* method = methods->at(i); |
326 if (method == NULL) continue; // maybe null if error processing | 327 if (method == NULL) continue; // maybe null if error processing |
327 // Only want to delete methods that are not executing for RedefineClasses. | 328 // Only want to delete methods that are not executing for RedefineClasses. |
328 // The previous version will point to them so they're not totally dangling | 329 // The previous version will point to them so they're not totally dangling |
342 Array<Klass*>* ti = transitive_interfaces; | 343 Array<Klass*>* ti = transitive_interfaces; |
343 if (ti != Universe::the_empty_klass_array() && ti != local_interfaces) { | 344 if (ti != Universe::the_empty_klass_array() && ti != local_interfaces) { |
344 // check that the interfaces don't come from super class | 345 // check that the interfaces don't come from super class |
345 Array<Klass*>* sti = (super_klass == NULL) ? NULL : | 346 Array<Klass*>* sti = (super_klass == NULL) ? NULL : |
346 InstanceKlass::cast(super_klass)->transitive_interfaces(); | 347 InstanceKlass::cast(super_klass)->transitive_interfaces(); |
347 if (ti != sti) { | 348 if (ti != sti && ti != NULL && !ti->is_shared()) { |
348 MetadataFactory::free_array<Klass*>(loader_data, ti); | 349 MetadataFactory::free_array<Klass*>(loader_data, ti); |
349 } | 350 } |
350 } | 351 } |
351 | 352 |
352 // local interfaces can be empty | 353 // local interfaces can be empty |
353 if (local_interfaces != Universe::the_empty_klass_array()) { | 354 if (local_interfaces != Universe::the_empty_klass_array() && |
355 local_interfaces != NULL && !local_interfaces->is_shared()) { | |
354 MetadataFactory::free_array<Klass*>(loader_data, local_interfaces); | 356 MetadataFactory::free_array<Klass*>(loader_data, local_interfaces); |
355 } | 357 } |
356 } | 358 } |
357 | 359 |
358 // This function deallocates the metadata and C heap pointers that the | 360 // This function deallocates the metadata and C heap pointers that the |
378 release_C_heap_structures(); | 380 release_C_heap_structures(); |
379 | 381 |
380 deallocate_methods(loader_data, methods()); | 382 deallocate_methods(loader_data, methods()); |
381 set_methods(NULL); | 383 set_methods(NULL); |
382 | 384 |
383 if (method_ordering() != Universe::the_empty_int_array()) { | 385 if (method_ordering() != NULL && |
386 method_ordering() != Universe::the_empty_int_array() && | |
387 !method_ordering()->is_shared()) { | |
384 MetadataFactory::free_array<int>(loader_data, method_ordering()); | 388 MetadataFactory::free_array<int>(loader_data, method_ordering()); |
385 } | 389 } |
386 set_method_ordering(NULL); | 390 set_method_ordering(NULL); |
387 | 391 |
388 // default methods can be empty | 392 // default methods can be empty |
389 if (default_methods() != NULL && | 393 if (default_methods() != NULL && |
390 default_methods() != Universe::the_empty_method_array()) { | 394 default_methods() != Universe::the_empty_method_array() && |
395 !default_methods()->is_shared()) { | |
391 MetadataFactory::free_array<Method*>(loader_data, default_methods()); | 396 MetadataFactory::free_array<Method*>(loader_data, default_methods()); |
392 } | 397 } |
393 // Do NOT deallocate the default methods, they are owned by superinterfaces. | 398 // Do NOT deallocate the default methods, they are owned by superinterfaces. |
394 set_default_methods(NULL); | 399 set_default_methods(NULL); |
395 | 400 |
396 // default methods vtable indices can be empty | 401 // default methods vtable indices can be empty |
397 if (default_vtable_indices() != NULL) { | 402 if (default_vtable_indices() != NULL && |
403 !default_vtable_indices()->is_shared()) { | |
398 MetadataFactory::free_array<int>(loader_data, default_vtable_indices()); | 404 MetadataFactory::free_array<int>(loader_data, default_vtable_indices()); |
399 } | 405 } |
400 set_default_vtable_indices(NULL); | 406 set_default_vtable_indices(NULL); |
401 | 407 |
402 | 408 |
403 // This array is in Klass, but remove it with the InstanceKlass since | 409 // This array is in Klass, but remove it with the InstanceKlass since |
404 // this place would be the only caller and it can share memory with transitive | 410 // this place would be the only caller and it can share memory with transitive |
405 // interfaces. | 411 // interfaces. |
406 if (secondary_supers() != Universe::the_empty_klass_array() && | 412 if (secondary_supers() != NULL && |
407 secondary_supers() != transitive_interfaces()) { | 413 secondary_supers() != Universe::the_empty_klass_array() && |
414 secondary_supers() != transitive_interfaces() && | |
415 !secondary_supers()->is_shared()) { | |
408 MetadataFactory::free_array<Klass*>(loader_data, secondary_supers()); | 416 MetadataFactory::free_array<Klass*>(loader_data, secondary_supers()); |
409 } | 417 } |
410 set_secondary_supers(NULL); | 418 set_secondary_supers(NULL); |
411 | 419 |
412 deallocate_interfaces(loader_data, super(), local_interfaces(), transitive_interfaces()); | 420 deallocate_interfaces(loader_data, super(), local_interfaces(), transitive_interfaces()); |
413 set_transitive_interfaces(NULL); | 421 set_transitive_interfaces(NULL); |
414 set_local_interfaces(NULL); | 422 set_local_interfaces(NULL); |
415 | 423 |
416 MetadataFactory::free_array<jushort>(loader_data, fields()); | 424 if (fields() != NULL && !fields()->is_shared()) { |
425 MetadataFactory::free_array<jushort>(loader_data, fields()); | |
426 } | |
417 set_fields(NULL, 0); | 427 set_fields(NULL, 0); |
418 | 428 |
419 // If a method from a redefined class is using this constant pool, don't | 429 // If a method from a redefined class is using this constant pool, don't |
420 // delete it, yet. The new class's previous version will point to this. | 430 // delete it, yet. The new class's previous version will point to this. |
421 if (constants() != NULL) { | 431 if (constants() != NULL) { |
422 assert (!constants()->on_stack(), "shouldn't be called if anything is onstack"); | 432 assert (!constants()->on_stack(), "shouldn't be called if anything is onstack"); |
423 MetadataFactory::free_metadata(loader_data, constants()); | 433 if (!constants()->is_shared()) { |
434 MetadataFactory::free_metadata(loader_data, constants()); | |
435 } | |
424 set_constants(NULL); | 436 set_constants(NULL); |
425 } | 437 } |
426 | 438 |
427 if (inner_classes() != Universe::the_empty_short_array()) { | 439 if (inner_classes() != NULL && |
440 inner_classes() != Universe::the_empty_short_array() && | |
441 !inner_classes()->is_shared()) { | |
428 MetadataFactory::free_array<jushort>(loader_data, inner_classes()); | 442 MetadataFactory::free_array<jushort>(loader_data, inner_classes()); |
429 } | 443 } |
430 set_inner_classes(NULL); | 444 set_inner_classes(NULL); |
431 | 445 |
432 // We should deallocate the Annotations instance | 446 // We should deallocate the Annotations instance if it's not in shared spaces. |
433 MetadataFactory::free_metadata(loader_data, annotations()); | 447 if (annotations() != NULL && !annotations()->is_shared()) { |
448 MetadataFactory::free_metadata(loader_data, annotations()); | |
449 } | |
434 set_annotations(NULL); | 450 set_annotations(NULL); |
435 } | 451 } |
436 | 452 |
437 bool InstanceKlass::should_be_initialized() const { | 453 bool InstanceKlass::should_be_initialized() const { |
438 return !is_initialized(); | 454 return !is_initialized(); |