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
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/memory/metablock.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/memory/metaspace.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/oops/constMethod.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/oops/cpCache.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/oops/cpCache.hpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/oops/klass.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/oops/klass.hpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/oops/method.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/oops/methodData.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Mar 07 14:06:44 2013 -0500
+++ b/hotspot/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*) \