mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8024667: VM crashes with "assert(method() != NULL) failed: must have set method"
Check if data is in shared spaces before deallocating it. Reviewed-by: coleenp, dcubed
This commit is contained in:
parent
db171c7b5d
commit
7476c45011
2 changed files with 32 additions and 14 deletions
|
@ -320,7 +320,8 @@ InstanceKlass::InstanceKlass(int vtable_len,
|
|||
|
||||
void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data,
|
||||
Array<Method*>* methods) {
|
||||
if (methods != NULL && methods != Universe::the_empty_method_array()) {
|
||||
if (methods != NULL && methods != Universe::the_empty_method_array() &&
|
||||
!methods->is_shared()) {
|
||||
for (int i = 0; i < methods->length(); i++) {
|
||||
Method* method = methods->at(i);
|
||||
if (method == NULL) continue; // maybe null if error processing
|
||||
|
@ -344,13 +345,14 @@ void InstanceKlass::deallocate_interfaces(ClassLoaderData* loader_data,
|
|||
// check that the interfaces don't come from super class
|
||||
Array<Klass*>* sti = (super_klass == NULL) ? NULL :
|
||||
InstanceKlass::cast(super_klass)->transitive_interfaces();
|
||||
if (ti != sti) {
|
||||
if (ti != sti && ti != NULL && !ti->is_shared()) {
|
||||
MetadataFactory::free_array<Klass*>(loader_data, ti);
|
||||
}
|
||||
}
|
||||
|
||||
// local interfaces can be empty
|
||||
if (local_interfaces != Universe::the_empty_klass_array()) {
|
||||
if (local_interfaces != Universe::the_empty_klass_array() &&
|
||||
local_interfaces != NULL && !local_interfaces->is_shared()) {
|
||||
MetadataFactory::free_array<Klass*>(loader_data, local_interfaces);
|
||||
}
|
||||
}
|
||||
|
@ -380,21 +382,25 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
|||
deallocate_methods(loader_data, methods());
|
||||
set_methods(NULL);
|
||||
|
||||
if (method_ordering() != Universe::the_empty_int_array()) {
|
||||
if (method_ordering() != NULL &&
|
||||
method_ordering() != Universe::the_empty_int_array() &&
|
||||
!method_ordering()->is_shared()) {
|
||||
MetadataFactory::free_array<int>(loader_data, method_ordering());
|
||||
}
|
||||
set_method_ordering(NULL);
|
||||
|
||||
// default methods can be empty
|
||||
if (default_methods() != NULL &&
|
||||
default_methods() != Universe::the_empty_method_array()) {
|
||||
default_methods() != Universe::the_empty_method_array() &&
|
||||
!default_methods()->is_shared()) {
|
||||
MetadataFactory::free_array<Method*>(loader_data, default_methods());
|
||||
}
|
||||
// Do NOT deallocate the default methods, they are owned by superinterfaces.
|
||||
set_default_methods(NULL);
|
||||
|
||||
// default methods vtable indices can be empty
|
||||
if (default_vtable_indices() != NULL) {
|
||||
if (default_vtable_indices() != NULL &&
|
||||
!default_vtable_indices()->is_shared()) {
|
||||
MetadataFactory::free_array<int>(loader_data, default_vtable_indices());
|
||||
}
|
||||
set_default_vtable_indices(NULL);
|
||||
|
@ -403,8 +409,10 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
|||
// This array is in Klass, but remove it with the InstanceKlass since
|
||||
// this place would be the only caller and it can share memory with transitive
|
||||
// interfaces.
|
||||
if (secondary_supers() != Universe::the_empty_klass_array() &&
|
||||
secondary_supers() != transitive_interfaces()) {
|
||||
if (secondary_supers() != NULL &&
|
||||
secondary_supers() != Universe::the_empty_klass_array() &&
|
||||
secondary_supers() != transitive_interfaces() &&
|
||||
!secondary_supers()->is_shared()) {
|
||||
MetadataFactory::free_array<Klass*>(loader_data, secondary_supers());
|
||||
}
|
||||
set_secondary_supers(NULL);
|
||||
|
@ -413,24 +421,32 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
|||
set_transitive_interfaces(NULL);
|
||||
set_local_interfaces(NULL);
|
||||
|
||||
MetadataFactory::free_array<jushort>(loader_data, fields());
|
||||
if (fields() != NULL && !fields()->is_shared()) {
|
||||
MetadataFactory::free_array<jushort>(loader_data, fields());
|
||||
}
|
||||
set_fields(NULL, 0);
|
||||
|
||||
// If a method from a redefined class is using this constant pool, don't
|
||||
// delete it, yet. The new class's previous version will point to this.
|
||||
if (constants() != NULL) {
|
||||
assert (!constants()->on_stack(), "shouldn't be called if anything is onstack");
|
||||
MetadataFactory::free_metadata(loader_data, constants());
|
||||
if (!constants()->is_shared()) {
|
||||
MetadataFactory::free_metadata(loader_data, constants());
|
||||
}
|
||||
set_constants(NULL);
|
||||
}
|
||||
|
||||
if (inner_classes() != Universe::the_empty_short_array()) {
|
||||
if (inner_classes() != NULL &&
|
||||
inner_classes() != Universe::the_empty_short_array() &&
|
||||
!inner_classes()->is_shared()) {
|
||||
MetadataFactory::free_array<jushort>(loader_data, inner_classes());
|
||||
}
|
||||
set_inner_classes(NULL);
|
||||
|
||||
// We should deallocate the Annotations instance
|
||||
MetadataFactory::free_metadata(loader_data, annotations());
|
||||
// We should deallocate the Annotations instance if it's not in shared spaces.
|
||||
if (annotations() != NULL && !annotations()->is_shared()) {
|
||||
MetadataFactory::free_metadata(loader_data, annotations());
|
||||
}
|
||||
set_annotations(NULL);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue