8024667: VM crashes with "assert(method() != NULL) failed: must have set method"

Sat, 12 Oct 2013 15:39:16 -0400

author
hseigel
date
Sat, 12 Oct 2013 15:39:16 -0400
changeset 5896
d37a0525c0fe
parent 5895
3e265ce4d2dd
child 5897
2f8728d92483

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

src/share/vm/memory/metadataFactory.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/instanceKlass.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/memory/metadataFactory.hpp	Sat Oct 12 13:09:18 2013 -0400
     1.2 +++ b/src/share/vm/memory/metadataFactory.hpp	Sat Oct 12 15:39:16 2013 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -65,6 +65,7 @@
    1.11    static void free_array(ClassLoaderData* loader_data, Array<T>* data) {
    1.12      if (data != NULL) {
    1.13        assert(loader_data != NULL, "shouldn't pass null");
    1.14 +      assert(!data->is_shared(), "cannot deallocate array in shared spaces");
    1.15        int size = data->size();
    1.16        if (DumpSharedSpaces) {
    1.17          loader_data->ro_metaspace()->deallocate((MetaWord*)data, size, false);
    1.18 @@ -83,6 +84,7 @@
    1.19        // Call metadata's deallocate function which will call deallocate fields
    1.20        assert(!DumpSharedSpaces, "cannot deallocate metadata when dumping CDS archive");
    1.21        assert(!md->on_stack(), "can't deallocate things on stack");
    1.22 +      assert(!md->is_shared(), "cannot deallocate if in shared spaces");
    1.23        md->deallocate_contents(loader_data);
    1.24        loader_data->metaspace_non_null()->deallocate((MetaWord*)md, size, md->is_klass());
    1.25      }
     2.1 --- a/src/share/vm/oops/instanceKlass.cpp	Sat Oct 12 13:09:18 2013 -0400
     2.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Sat Oct 12 15:39:16 2013 -0400
     2.3 @@ -320,7 +320,8 @@
     2.4  
     2.5  void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data,
     2.6                                         Array<Method*>* methods) {
     2.7 -  if (methods != NULL && methods != Universe::the_empty_method_array()) {
     2.8 +  if (methods != NULL && methods != Universe::the_empty_method_array() &&
     2.9 +      !methods->is_shared()) {
    2.10      for (int i = 0; i < methods->length(); i++) {
    2.11        Method* method = methods->at(i);
    2.12        if (method == NULL) continue;  // maybe null if error processing
    2.13 @@ -344,13 +345,14 @@
    2.14      // check that the interfaces don't come from super class
    2.15      Array<Klass*>* sti = (super_klass == NULL) ? NULL :
    2.16                      InstanceKlass::cast(super_klass)->transitive_interfaces();
    2.17 -    if (ti != sti) {
    2.18 +    if (ti != sti && ti != NULL && !ti->is_shared()) {
    2.19        MetadataFactory::free_array<Klass*>(loader_data, ti);
    2.20      }
    2.21    }
    2.22  
    2.23    // local interfaces can be empty
    2.24 -  if (local_interfaces != Universe::the_empty_klass_array()) {
    2.25 +  if (local_interfaces != Universe::the_empty_klass_array() &&
    2.26 +      local_interfaces != NULL && !local_interfaces->is_shared()) {
    2.27      MetadataFactory::free_array<Klass*>(loader_data, local_interfaces);
    2.28    }
    2.29  }
    2.30 @@ -380,21 +382,25 @@
    2.31    deallocate_methods(loader_data, methods());
    2.32    set_methods(NULL);
    2.33  
    2.34 -  if (method_ordering() != Universe::the_empty_int_array()) {
    2.35 +  if (method_ordering() != NULL &&
    2.36 +      method_ordering() != Universe::the_empty_int_array() &&
    2.37 +      !method_ordering()->is_shared()) {
    2.38      MetadataFactory::free_array<int>(loader_data, method_ordering());
    2.39    }
    2.40    set_method_ordering(NULL);
    2.41  
    2.42    // default methods can be empty
    2.43    if (default_methods() != NULL &&
    2.44 -      default_methods() != Universe::the_empty_method_array()) {
    2.45 +      default_methods() != Universe::the_empty_method_array() &&
    2.46 +      !default_methods()->is_shared()) {
    2.47      MetadataFactory::free_array<Method*>(loader_data, default_methods());
    2.48    }
    2.49    // Do NOT deallocate the default methods, they are owned by superinterfaces.
    2.50    set_default_methods(NULL);
    2.51  
    2.52    // default methods vtable indices can be empty
    2.53 -  if (default_vtable_indices() != NULL) {
    2.54 +  if (default_vtable_indices() != NULL &&
    2.55 +      !default_vtable_indices()->is_shared()) {
    2.56      MetadataFactory::free_array<int>(loader_data, default_vtable_indices());
    2.57    }
    2.58    set_default_vtable_indices(NULL);
    2.59 @@ -403,8 +409,10 @@
    2.60    // This array is in Klass, but remove it with the InstanceKlass since
    2.61    // this place would be the only caller and it can share memory with transitive
    2.62    // interfaces.
    2.63 -  if (secondary_supers() != Universe::the_empty_klass_array() &&
    2.64 -      secondary_supers() != transitive_interfaces()) {
    2.65 +  if (secondary_supers() != NULL &&
    2.66 +      secondary_supers() != Universe::the_empty_klass_array() &&
    2.67 +      secondary_supers() != transitive_interfaces() &&
    2.68 +      !secondary_supers()->is_shared()) {
    2.69      MetadataFactory::free_array<Klass*>(loader_data, secondary_supers());
    2.70    }
    2.71    set_secondary_supers(NULL);
    2.72 @@ -413,24 +421,32 @@
    2.73    set_transitive_interfaces(NULL);
    2.74    set_local_interfaces(NULL);
    2.75  
    2.76 -  MetadataFactory::free_array<jushort>(loader_data, fields());
    2.77 +  if (fields() != NULL && !fields()->is_shared()) {
    2.78 +    MetadataFactory::free_array<jushort>(loader_data, fields());
    2.79 +  }
    2.80    set_fields(NULL, 0);
    2.81  
    2.82    // If a method from a redefined class is using this constant pool, don't
    2.83    // delete it, yet.  The new class's previous version will point to this.
    2.84    if (constants() != NULL) {
    2.85      assert (!constants()->on_stack(), "shouldn't be called if anything is onstack");
    2.86 -    MetadataFactory::free_metadata(loader_data, constants());
    2.87 +    if (!constants()->is_shared()) {
    2.88 +      MetadataFactory::free_metadata(loader_data, constants());
    2.89 +    }
    2.90      set_constants(NULL);
    2.91    }
    2.92  
    2.93 -  if (inner_classes() != Universe::the_empty_short_array()) {
    2.94 +  if (inner_classes() != NULL &&
    2.95 +      inner_classes() != Universe::the_empty_short_array() &&
    2.96 +      !inner_classes()->is_shared()) {
    2.97      MetadataFactory::free_array<jushort>(loader_data, inner_classes());
    2.98    }
    2.99    set_inner_classes(NULL);
   2.100  
   2.101 -  // We should deallocate the Annotations instance
   2.102 -  MetadataFactory::free_metadata(loader_data, annotations());
   2.103 +  // We should deallocate the Annotations instance if it's not in shared spaces.
   2.104 +  if (annotations() != NULL && !annotations()->is_shared()) {
   2.105 +    MetadataFactory::free_metadata(loader_data, annotations());
   2.106 +  }
   2.107    set_annotations(NULL);
   2.108  }
   2.109  

mercurial