changeset 4277:3efdfd6ddbf2

8003553: NPG: metaspace objects should be zeroed in constructors Summary: Zero metadata in constructors, not in allocation (and some in constructors) Reviewed-by: jmasa, sspitsyn
author coleenp
date Fri, 08 Mar 2013 11:47:57 -0500
parents 6b803ba47588
children 35ef86296a5d
files src/share/vm/interpreter/rewriter.cpp src/share/vm/memory/metablock.cpp src/share/vm/memory/metaspace.cpp src/share/vm/oops/constMethod.cpp src/share/vm/oops/cpCache.cpp src/share/vm/oops/cpCache.hpp src/share/vm/oops/instanceKlass.cpp src/share/vm/oops/instanceKlass.hpp src/share/vm/oops/klass.cpp src/share/vm/oops/klass.hpp src/share/vm/oops/method.cpp src/share/vm/oops/methodData.cpp src/share/vm/runtime/vmStructs.cpp
diffstat 13 files changed, 112 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/interpreter/rewriter.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/interpreter/rewriter.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -84,15 +84,13 @@
   const int length = _cp_cache_map.length();
   ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data();
   ConstantPoolCache* cache =
-      ConstantPoolCache::allocate(loader_data, length, CHECK);
+      ConstantPoolCache::allocate(loader_data, length, _cp_cache_map,
+                                  _invokedynamic_references_map, CHECK);
 
   // initialize object cache in constant pool
   _pool->initialize_resolved_references(loader_data, _resolved_references_map,
                                         _resolved_reference_limit,
                                         CHECK);
-
-  No_Safepoint_Verifier nsv;
-  cache->initialize(_cp_cache_map, _invokedynamic_references_map);
   _pool->set_cache(cache);
   cache->set_constant_pool(_pool());
 }
--- a/src/share/vm/memory/metablock.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/memory/metablock.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,10 +65,9 @@
   }
 
   Metablock* result = (Metablock*) p;
-
-  // Clear the memory
-  Copy::fill_to_aligned_words((HeapWord*)result, word_size);
 #ifdef ASSERT
+  // Add just to catch missing initializations
+  Copy::fill_to_words((HeapWord*) result, word_size, 0xf1f1f1f1);
   result->set_word_size(word_size);
 #endif
   return result;
--- a/src/share/vm/memory/metaspace.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/memory/metaspace.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,6 @@
 const uint metadata_deallocate_a_lot_block = 10;
 const uint metadata_deallocate_a_lock_chunk = 3;
 size_t const allocation_from_dictionary_limit = 64 * K;
-const size_t metadata_deallocate = 0xf5f5f5f5;
 
 MetaWord* last_allocated = 0;
 
--- a/src/share/vm/oops/constMethod.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/oops/constMethod.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -58,6 +58,12 @@
   set_inlined_tables_length(sizes);
   set_method_type(method_type);
   assert(this->size() == size, "wrong size for object");
+  set_name_index(0);
+  set_signature_index(0);
+  set_constants(NULL);
+  set_max_stack(0);
+  set_max_locals(0);
+  set_method_idnum(0);
 }
 
 
--- a/src/share/vm/oops/cpCache.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/oops/cpCache.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -44,6 +44,8 @@
 void ConstantPoolCacheEntry::initialize_entry(int index) {
   assert(0 < index && index < 0x10000, "sanity check");
   _indices = index;
+  _f1 = NULL;
+  _f2 = _flags = 0;
   assert(constant_pool_index() == index, "");
 }
 
@@ -533,13 +535,17 @@
 
 // Implementation of ConstantPoolCache
 
-ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
+ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data,
+                                     int length,
+                                     const intStack& index_map,
+                                     const intStack& invokedynamic_map, TRAPS) {
   int size = ConstantPoolCache::size(length);
 
-  return new (loader_data, size, false, THREAD) ConstantPoolCache(length);
+  return new (loader_data, size, false, THREAD) ConstantPoolCache(length, index_map, invokedynamic_map);
 }
 
-void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) {
+void ConstantPoolCache::initialize(const intArray& inverse_index_map,
+                                   const intArray& invokedynamic_references_map) {
   assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
   for (int i = 0; i < length(); i++) {
     ConstantPoolCacheEntry* e = entry_at(i);
--- a/src/share/vm/oops/cpCache.hpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/oops/cpCache.hpp	Fri Mar 08 11:47:57 2013 -0500
@@ -377,14 +377,21 @@
   debug_only(friend class ClassVerifier;)
 
   // Constructor
-  ConstantPoolCache(int length) : _length(length), _constant_pool(NULL) {
+  ConstantPoolCache(int length, const intStack& inverse_index_map,
+                    const intStack& invokedynamic_references_map) :
+                                        _length(length), _constant_pool(NULL) {
+    initialize(inverse_index_map, invokedynamic_references_map);
     for (int i = 0; i < length; i++) {
       assert(entry_at(i)->is_f1_null(), "Failed to clear?");
     }
   }
 
+  // Initialization
+  void initialize(const intArray& inverse_index_map, const intArray& invokedynamic_references_map);
  public:
-  static ConstantPoolCache* allocate(ClassLoaderData* loader_data, int length, TRAPS);
+  static ConstantPoolCache* allocate(ClassLoaderData* loader_data, int length,
+                                     const intStack& inverse_index_map,
+                                     const intStack& invokedynamic_references_map, TRAPS);
   bool is_constantPoolCache() const { return true; }
 
   int length() const                             { return _length; }
@@ -405,9 +412,6 @@
   friend class ConstantPoolCacheEntry;
 
  public:
-  // Initialization
-  void initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map);
-
   // Accessors
   void set_constant_pool(ConstantPool* pool)   { _constant_pool = pool; }
   ConstantPool* constant_pool() const          { return _constant_pool; }
--- a/src/share/vm/oops/instanceKlass.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/oops/instanceKlass.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -220,63 +220,71 @@
                              bool is_anonymous) {
   No_Safepoint_Verifier no_safepoint; // until k becomes parsable
 
-  int size = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
-                                 access_flags.is_interface(), is_anonymous);
+  int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
+                                   access_flags.is_interface(), is_anonymous);
 
   // The sizes of these these three variables are used for determining the
   // size of the instanceKlassOop. It is critical that these are set to the right
   // sizes before the first GC, i.e., when we allocate the mirror.
-  this->set_vtable_length(vtable_len);
-  this->set_itable_length(itable_len);
-  this->set_static_field_size(static_field_size);
-  this->set_nonstatic_oop_map_size(nonstatic_oop_map_size);
-  this->set_access_flags(access_flags);
-  this->set_is_anonymous(is_anonymous);
-  assert(this->size() == size, "wrong size for object");
-
-  this->set_array_klasses(NULL);
-  this->set_methods(NULL);
-  this->set_method_ordering(NULL);
-  this->set_local_interfaces(NULL);
-  this->set_transitive_interfaces(NULL);
-  this->init_implementor();
-  this->set_fields(NULL, 0);
-  this->set_constants(NULL);
-  this->set_class_loader_data(NULL);
-  this->set_protection_domain(NULL);
-  this->set_signers(NULL);
-  this->set_source_file_name(NULL);
-  this->set_source_debug_extension(NULL, 0);
-  this->set_array_name(NULL);
-  this->set_inner_classes(NULL);
-  this->set_static_oop_field_count(0);
-  this->set_nonstatic_field_size(0);
-  this->set_is_marked_dependent(false);
-  this->set_init_state(InstanceKlass::allocated);
-  this->set_init_thread(NULL);
-  this->set_init_lock(NULL);
-  this->set_reference_type(rt);
-  this->set_oop_map_cache(NULL);
-  this->set_jni_ids(NULL);
-  this->set_osr_nmethods_head(NULL);
-  this->set_breakpoints(NULL);
-  this->init_previous_versions();
-  this->set_generic_signature(NULL);
-  this->release_set_methods_jmethod_ids(NULL);
-  this->release_set_methods_cached_itable_indices(NULL);
-  this->set_annotations(NULL);
-  this->set_jvmti_cached_class_field_map(NULL);
-  this->set_initial_method_idnum(0);
+  set_vtable_length(vtable_len);
+  set_itable_length(itable_len);
+  set_static_field_size(static_field_size);
+  set_nonstatic_oop_map_size(nonstatic_oop_map_size);
+  set_access_flags(access_flags);
+  _misc_flags = 0;  // initialize to zero
+  set_is_anonymous(is_anonymous);
+  assert(size() == iksize, "wrong size for object");
+
+  set_array_klasses(NULL);
+  set_methods(NULL);
+  set_method_ordering(NULL);
+  set_local_interfaces(NULL);
+  set_transitive_interfaces(NULL);
+  init_implementor();
+  set_fields(NULL, 0);
+  set_constants(NULL);
+  set_class_loader_data(NULL);
+  set_protection_domain(NULL);
+  set_signers(NULL);
+  set_source_file_name(NULL);
+  set_source_debug_extension(NULL, 0);
+  set_array_name(NULL);
+  set_inner_classes(NULL);
+  set_static_oop_field_count(0);
+  set_nonstatic_field_size(0);
+  set_is_marked_dependent(false);
+  set_init_state(InstanceKlass::allocated);
+  set_init_thread(NULL);
+  set_init_lock(NULL);
+  set_reference_type(rt);
+  set_oop_map_cache(NULL);
+  set_jni_ids(NULL);
+  set_osr_nmethods_head(NULL);
+  set_breakpoints(NULL);
+  init_previous_versions();
+  set_generic_signature(NULL);
+  release_set_methods_jmethod_ids(NULL);
+  release_set_methods_cached_itable_indices(NULL);
+  set_annotations(NULL);
+  set_jvmti_cached_class_field_map(NULL);
+  set_initial_method_idnum(0);
+  _dependencies = NULL;
+  set_jvmti_cached_class_field_map(NULL);
+  set_cached_class_file(NULL, 0);
+  set_initial_method_idnum(0);
+  set_minor_version(0);
+  set_major_version(0);
+  NOT_PRODUCT(_verify_count = 0;)
 
   // initialize the non-header words to zero
   intptr_t* p = (intptr_t*)this;
-  for (int index = InstanceKlass::header_size(); index < size; index++) {
+  for (int index = InstanceKlass::header_size(); index < iksize; index++) {
     p[index] = NULL_WORD;
   }
 
   // Set temporary value until parseClassFile updates it with the real instance
   // size.
-  this->set_layout_helper(Klass::instance_layout_helper(0, true));
+  set_layout_helper(Klass::instance_layout_helper(0, true));
 }
 
 
@@ -2781,7 +2789,7 @@
   st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr();
   st->print(BULLET"host class:        "); host_klass()->print_value_on_maybe_null(st); st->cr();
   st->print(BULLET"signers:           "); signers()->print_value_on(st);               st->cr();
-  st->print(BULLET"init_lock:         "); ((oop)init_lock())->print_value_on(st);             st->cr();
+  st->print(BULLET"init_lock:         "); ((oop)_init_lock)->print_value_on(st);             st->cr();
   if (source_file_name() != NULL) {
     st->print(BULLET"source file:       ");
     source_file_name()->print_value_on(st);
--- a/src/share/vm/oops/instanceKlass.hpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/oops/instanceKlass.hpp	Fri Mar 08 11:47:57 2013 -0500
@@ -269,6 +269,8 @@
 
   JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map;  // JVMTI: used during heap iteration
 
+  NOT_PRODUCT(int _verify_count;)  // to avoid redundant verifies
+
   // Method array.
   Array<Method*>* _methods;
   // Interface (Klass*s) this class declares locally to implement.
@@ -586,7 +588,7 @@
 
   // symbol unloading support (refcount already added)
   Symbol* array_name()                     { return _array_name; }
-  void set_array_name(Symbol* name)        { assert(_array_name == NULL, "name already created"); _array_name = name; }
+  void set_array_name(Symbol* name)        { assert(_array_name == NULL  || name == NULL, "name already created"); _array_name = name; }
 
   // nonstatic oop-map blocks
   static int nonstatic_oop_map_size(unsigned int oop_map_count) {
--- a/src/share/vm/oops/klass.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/oops/klass.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -146,16 +146,16 @@
 Klass::Klass() {
   Klass* k = this;
 
-  { // Preinitialize supertype information.
-    // A later call to initialize_supers() may update these settings:
-    set_super(NULL);
-    for (juint i = 0; i < Klass::primary_super_limit(); i++) {
-      _primary_supers[i] = NULL;
-    }
-    set_secondary_supers(NULL);
-    _primary_supers[0] = k;
-    set_super_check_offset(in_bytes(primary_supers_offset()));
+  // Preinitialize supertype information.
+  // A later call to initialize_supers() may update these settings:
+  set_super(NULL);
+  for (juint i = 0; i < Klass::primary_super_limit(); i++) {
+    _primary_supers[i] = NULL;
   }
+  set_secondary_supers(NULL);
+  set_secondary_super_cache(NULL);
+  _primary_supers[0] = k;
+  set_super_check_offset(in_bytes(primary_supers_offset()));
 
   set_java_mirror(NULL);
   set_modifier_flags(0);
--- a/src/share/vm/oops/klass.hpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/oops/klass.hpp	Fri Mar 08 11:47:57 2013 -0500
@@ -79,7 +79,6 @@
 //    [last_biased_lock_bulk_revocation_time] (64 bits)
 //    [prototype_header]
 //    [biased_lock_revocation_count]
-//    [verify_count  ] - not in product
 //    [alloc_count   ]
 //    [_modified_oops]
 //    [_accumulated_modified_oops]
@@ -172,10 +171,6 @@
   markOop  _prototype_header;   // Used when biased locking is both enabled and disabled for this type
   jint     _biased_lock_revocation_count;
 
-#ifndef PRODUCT
-  int           _verify_count;  // to avoid redundant verifies
-#endif
-
   juint    _alloc_count;        // allocation profiling support
 
   TRACE_DEFINE_KLASS_TRACE_ID;
--- a/src/share/vm/oops/method.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/oops/method.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -77,20 +77,14 @@
   return new (loader_data, size, false, THREAD) Method(cm, access_flags, size);
 }
 
-Method::Method(ConstMethod* xconst,
-                             AccessFlags access_flags, int size) {
+Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
   No_Safepoint_Verifier no_safepoint;
   set_constMethod(xconst);
   set_access_flags(access_flags);
   set_method_size(size);
-  set_name_index(0);
-  set_signature_index(0);
 #ifdef CC_INTERP
   set_result_index(T_VOID);
 #endif
-  set_constants(NULL);
-  set_max_stack(0);
-  set_max_locals(0);
   set_intrinsic_id(vmIntrinsics::_none);
   set_jfr_towrite(false);
   set_method_data(NULL);
--- a/src/share/vm/oops/methodData.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/oops/methodData.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -652,23 +652,25 @@
   // Set the method back-pointer.
   _method = method();
 
-  if (TieredCompilation) {
-    _invocation_counter.init();
-    _backedge_counter.init();
-    _invocation_counter_start = 0;
-    _backedge_counter_start = 0;
-    _num_loops = 0;
-    _num_blocks = 0;
-    _highest_comp_level = 0;
-    _highest_osr_comp_level = 0;
-    _would_profile = true;
-  }
+  _invocation_counter.init();
+  _backedge_counter.init();
+  _invocation_counter_start = 0;
+  _backedge_counter_start = 0;
+  _num_loops = 0;
+  _num_blocks = 0;
+  _highest_comp_level = 0;
+  _highest_osr_comp_level = 0;
+  _would_profile = true;
   set_creation_mileage(mileage_of(method()));
 
   // Initialize flags and trap history.
   _nof_decompiles = 0;
   _nof_overflow_recompiles = 0;
   _nof_overflow_traps = 0;
+  _eflags = 0;
+  _arg_local = 0;
+  _arg_stack = 0;
+  _arg_returned = 0;
   assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align");
   Copy::zero_to_words((HeapWord*) &_trap_hist,
                       sizeof(_trap_hist) / sizeof(HeapWord));
@@ -677,6 +679,7 @@
   // corresponding data cells.
   int data_size = 0;
   int empty_bc_count = 0;  // number of bytecodes lacking data
+  _data[0] = 0;  // apparently not set below.
   BytecodeStream stream(method);
   Bytecodes::Code c;
   while ((c = stream.next()) >= 0) {
@@ -710,6 +713,7 @@
   post_initialize(&stream);
 
   set_size(object_size);
+
 }
 
 // Get a measure of how much mileage the method has on it.
--- a/src/share/vm/runtime/vmStructs.cpp	Thu Mar 07 14:06:44 2013 -0500
+++ b/src/share/vm/runtime/vmStructs.cpp	Fri Mar 08 11:47:57 2013 -0500
@@ -336,7 +336,6 @@
   nonstatic_field(Klass,                       _access_flags,                                 AccessFlags)                           \
   nonstatic_field(Klass,                       _subklass,                                     Klass*)                                \
   nonstatic_field(Klass,                       _next_sibling,                                 Klass*)                                \
-  nonproduct_nonstatic_field(Klass,            _verify_count,                                 int)                                   \
   nonstatic_field(Klass,                       _alloc_count,                                  juint)                                 \
   nonstatic_field(MethodData,           _size,                                         int)                                   \
   nonstatic_field(MethodData,           _method,                                       Method*)                        \