提交 6cdf051d 编写于 作者: C coleenp

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
上级 8bb9dd15
...@@ -84,15 +84,13 @@ void Rewriter::make_constant_pool_cache(TRAPS) { ...@@ -84,15 +84,13 @@ void Rewriter::make_constant_pool_cache(TRAPS) {
const int length = _cp_cache_map.length(); const int length = _cp_cache_map.length();
ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data(); ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data();
ConstantPoolCache* cache = 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 // initialize object cache in constant pool
_pool->initialize_resolved_references(loader_data, _resolved_references_map, _pool->initialize_resolved_references(loader_data, _resolved_references_map,
_resolved_reference_limit, _resolved_reference_limit,
CHECK); CHECK);
No_Safepoint_Verifier nsv;
cache->initialize(_cp_cache_map, _invokedynamic_references_map);
_pool->set_cache(cache); _pool->set_cache(cache);
cache->set_constant_pool(_pool()); cache->set_constant_pool(_pool());
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -65,10 +65,9 @@ Metablock* Metablock::initialize(MetaWord* p, size_t word_size) { ...@@ -65,10 +65,9 @@ Metablock* Metablock::initialize(MetaWord* p, size_t word_size) {
} }
Metablock* result = (Metablock*) p; Metablock* result = (Metablock*) p;
// Clear the memory
Copy::fill_to_aligned_words((HeapWord*)result, word_size);
#ifdef ASSERT #ifdef ASSERT
// Add just to catch missing initializations
Copy::fill_to_words((HeapWord*) result, word_size, 0xf1f1f1f1);
result->set_word_size(word_size); result->set_word_size(word_size);
#endif #endif
return result; return result;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -52,7 +52,6 @@ const bool metaspace_slow_verify = false; ...@@ -52,7 +52,6 @@ const bool metaspace_slow_verify = false;
const uint metadata_deallocate_a_lot_block = 10; const uint metadata_deallocate_a_lot_block = 10;
const uint metadata_deallocate_a_lock_chunk = 3; const uint metadata_deallocate_a_lock_chunk = 3;
size_t const allocation_from_dictionary_limit = 64 * K; size_t const allocation_from_dictionary_limit = 64 * K;
const size_t metadata_deallocate = 0xf5f5f5f5;
MetaWord* last_allocated = 0; MetaWord* last_allocated = 0;
......
...@@ -58,6 +58,12 @@ ConstMethod::ConstMethod(int byte_code_size, ...@@ -58,6 +58,12 @@ ConstMethod::ConstMethod(int byte_code_size,
set_inlined_tables_length(sizes); set_inlined_tables_length(sizes);
set_method_type(method_type); set_method_type(method_type);
assert(this->size() == size, "wrong size for object"); 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);
} }
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
void ConstantPoolCacheEntry::initialize_entry(int index) { void ConstantPoolCacheEntry::initialize_entry(int index) {
assert(0 < index && index < 0x10000, "sanity check"); assert(0 < index && index < 0x10000, "sanity check");
_indices = index; _indices = index;
_f1 = NULL;
_f2 = _flags = 0;
assert(constant_pool_index() == index, ""); assert(constant_pool_index() == index, "");
} }
...@@ -533,13 +535,17 @@ void ConstantPoolCacheEntry::verify(outputStream* st) const { ...@@ -533,13 +535,17 @@ void ConstantPoolCacheEntry::verify(outputStream* st) const {
// Implementation of ConstantPoolCache // 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); 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"); assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
for (int i = 0; i < length(); i++) { for (int i = 0; i < length(); i++) {
ConstantPoolCacheEntry* e = entry_at(i); ConstantPoolCacheEntry* e = entry_at(i);
......
...@@ -377,14 +377,21 @@ class ConstantPoolCache: public MetaspaceObj { ...@@ -377,14 +377,21 @@ class ConstantPoolCache: public MetaspaceObj {
debug_only(friend class ClassVerifier;) debug_only(friend class ClassVerifier;)
// Constructor // 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++) { for (int i = 0; i < length; i++) {
assert(entry_at(i)->is_f1_null(), "Failed to clear?"); assert(entry_at(i)->is_f1_null(), "Failed to clear?");
} }
} }
// Initialization
void initialize(const intArray& inverse_index_map, const intArray& invokedynamic_references_map);
public: 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; } bool is_constantPoolCache() const { return true; }
int length() const { return _length; } int length() const { return _length; }
...@@ -405,9 +412,6 @@ class ConstantPoolCache: public MetaspaceObj { ...@@ -405,9 +412,6 @@ class ConstantPoolCache: public MetaspaceObj {
friend class ConstantPoolCacheEntry; friend class ConstantPoolCacheEntry;
public: public:
// Initialization
void initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map);
// Accessors // Accessors
void set_constant_pool(ConstantPool* pool) { _constant_pool = pool; } void set_constant_pool(ConstantPool* pool) { _constant_pool = pool; }
ConstantPool* constant_pool() const { return _constant_pool; } ConstantPool* constant_pool() const { return _constant_pool; }
......
...@@ -220,63 +220,71 @@ InstanceKlass::InstanceKlass(int vtable_len, ...@@ -220,63 +220,71 @@ InstanceKlass::InstanceKlass(int vtable_len,
bool is_anonymous) { bool is_anonymous) {
No_Safepoint_Verifier no_safepoint; // until k becomes parsable No_Safepoint_Verifier no_safepoint; // until k becomes parsable
int size = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size, int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
access_flags.is_interface(), is_anonymous); access_flags.is_interface(), is_anonymous);
// The sizes of these these three variables are used for determining the // 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 // 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. // sizes before the first GC, i.e., when we allocate the mirror.
this->set_vtable_length(vtable_len); set_vtable_length(vtable_len);
this->set_itable_length(itable_len); set_itable_length(itable_len);
this->set_static_field_size(static_field_size); set_static_field_size(static_field_size);
this->set_nonstatic_oop_map_size(nonstatic_oop_map_size); set_nonstatic_oop_map_size(nonstatic_oop_map_size);
this->set_access_flags(access_flags); set_access_flags(access_flags);
this->set_is_anonymous(is_anonymous); _misc_flags = 0; // initialize to zero
assert(this->size() == size, "wrong size for object"); set_is_anonymous(is_anonymous);
assert(size() == iksize, "wrong size for object");
this->set_array_klasses(NULL);
this->set_methods(NULL); set_array_klasses(NULL);
this->set_method_ordering(NULL); set_methods(NULL);
this->set_local_interfaces(NULL); set_method_ordering(NULL);
this->set_transitive_interfaces(NULL); set_local_interfaces(NULL);
this->init_implementor(); set_transitive_interfaces(NULL);
this->set_fields(NULL, 0); init_implementor();
this->set_constants(NULL); set_fields(NULL, 0);
this->set_class_loader_data(NULL); set_constants(NULL);
this->set_protection_domain(NULL); set_class_loader_data(NULL);
this->set_signers(NULL); set_protection_domain(NULL);
this->set_source_file_name(NULL); set_signers(NULL);
this->set_source_debug_extension(NULL, 0); set_source_file_name(NULL);
this->set_array_name(NULL); set_source_debug_extension(NULL, 0);
this->set_inner_classes(NULL); set_array_name(NULL);
this->set_static_oop_field_count(0); set_inner_classes(NULL);
this->set_nonstatic_field_size(0); set_static_oop_field_count(0);
this->set_is_marked_dependent(false); set_nonstatic_field_size(0);
this->set_init_state(InstanceKlass::allocated); set_is_marked_dependent(false);
this->set_init_thread(NULL); set_init_state(InstanceKlass::allocated);
this->set_init_lock(NULL); set_init_thread(NULL);
this->set_reference_type(rt); set_init_lock(NULL);
this->set_oop_map_cache(NULL); set_reference_type(rt);
this->set_jni_ids(NULL); set_oop_map_cache(NULL);
this->set_osr_nmethods_head(NULL); set_jni_ids(NULL);
this->set_breakpoints(NULL); set_osr_nmethods_head(NULL);
this->init_previous_versions(); set_breakpoints(NULL);
this->set_generic_signature(NULL); init_previous_versions();
this->release_set_methods_jmethod_ids(NULL); set_generic_signature(NULL);
this->release_set_methods_cached_itable_indices(NULL); release_set_methods_jmethod_ids(NULL);
this->set_annotations(NULL); release_set_methods_cached_itable_indices(NULL);
this->set_jvmti_cached_class_field_map(NULL); set_annotations(NULL);
this->set_initial_method_idnum(0); 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 // initialize the non-header words to zero
intptr_t* p = (intptr_t*)this; 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; p[index] = NULL_WORD;
} }
// Set temporary value until parseClassFile updates it with the real instance // Set temporary value until parseClassFile updates it with the real instance
// size. // size.
this->set_layout_helper(Klass::instance_layout_helper(0, true)); set_layout_helper(Klass::instance_layout_helper(0, true));
} }
...@@ -2781,7 +2789,7 @@ void InstanceKlass::print_on(outputStream* st) const { ...@@ -2781,7 +2789,7 @@ void InstanceKlass::print_on(outputStream* st) const {
st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr(); 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"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"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) { if (source_file_name() != NULL) {
st->print(BULLET"source file: "); st->print(BULLET"source file: ");
source_file_name()->print_value_on(st); source_file_name()->print_value_on(st);
......
...@@ -269,6 +269,8 @@ class InstanceKlass: public Klass { ...@@ -269,6 +269,8 @@ class InstanceKlass: public Klass {
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
NOT_PRODUCT(int _verify_count;) // to avoid redundant verifies
// Method array. // Method array.
Array<Method*>* _methods; Array<Method*>* _methods;
// Interface (Klass*s) this class declares locally to implement. // Interface (Klass*s) this class declares locally to implement.
...@@ -586,7 +588,7 @@ class InstanceKlass: public Klass { ...@@ -586,7 +588,7 @@ class InstanceKlass: public Klass {
// symbol unloading support (refcount already added) // symbol unloading support (refcount already added)
Symbol* array_name() { return _array_name; } 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 // nonstatic oop-map blocks
static int nonstatic_oop_map_size(unsigned int oop_map_count) { static int nonstatic_oop_map_size(unsigned int oop_map_count) {
......
...@@ -146,16 +146,16 @@ void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word ...@@ -146,16 +146,16 @@ void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word
Klass::Klass() { Klass::Klass() {
Klass* k = this; Klass* k = this;
{ // Preinitialize supertype information. // Preinitialize supertype information.
// A later call to initialize_supers() may update these settings: // A later call to initialize_supers() may update these settings:
set_super(NULL); set_super(NULL);
for (juint i = 0; i < Klass::primary_super_limit(); i++) { for (juint i = 0; i < Klass::primary_super_limit(); i++) {
_primary_supers[i] = NULL; _primary_supers[i] = NULL;
}
set_secondary_supers(NULL);
_primary_supers[0] = k;
set_super_check_offset(in_bytes(primary_supers_offset()));
} }
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_java_mirror(NULL);
set_modifier_flags(0); set_modifier_flags(0);
......
...@@ -79,7 +79,6 @@ ...@@ -79,7 +79,6 @@
// [last_biased_lock_bulk_revocation_time] (64 bits) // [last_biased_lock_bulk_revocation_time] (64 bits)
// [prototype_header] // [prototype_header]
// [biased_lock_revocation_count] // [biased_lock_revocation_count]
// [verify_count ] - not in product
// [alloc_count ] // [alloc_count ]
// [_modified_oops] // [_modified_oops]
// [_accumulated_modified_oops] // [_accumulated_modified_oops]
...@@ -172,10 +171,6 @@ class Klass : public Metadata { ...@@ -172,10 +171,6 @@ class Klass : public Metadata {
markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type
jint _biased_lock_revocation_count; jint _biased_lock_revocation_count;
#ifndef PRODUCT
int _verify_count; // to avoid redundant verifies
#endif
juint _alloc_count; // allocation profiling support juint _alloc_count; // allocation profiling support
TRACE_DEFINE_KLASS_TRACE_ID; TRACE_DEFINE_KLASS_TRACE_ID;
......
...@@ -77,20 +77,14 @@ Method* Method::allocate(ClassLoaderData* loader_data, ...@@ -77,20 +77,14 @@ Method* Method::allocate(ClassLoaderData* loader_data,
return new (loader_data, size, false, THREAD) Method(cm, access_flags, size); return new (loader_data, size, false, THREAD) Method(cm, access_flags, size);
} }
Method::Method(ConstMethod* xconst, Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
AccessFlags access_flags, int size) {
No_Safepoint_Verifier no_safepoint; No_Safepoint_Verifier no_safepoint;
set_constMethod(xconst); set_constMethod(xconst);
set_access_flags(access_flags); set_access_flags(access_flags);
set_method_size(size); set_method_size(size);
set_name_index(0);
set_signature_index(0);
#ifdef CC_INTERP #ifdef CC_INTERP
set_result_index(T_VOID); set_result_index(T_VOID);
#endif #endif
set_constants(NULL);
set_max_stack(0);
set_max_locals(0);
set_intrinsic_id(vmIntrinsics::_none); set_intrinsic_id(vmIntrinsics::_none);
set_jfr_towrite(false); set_jfr_towrite(false);
set_method_data(NULL); set_method_data(NULL);
......
...@@ -652,23 +652,25 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) { ...@@ -652,23 +652,25 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
// Set the method back-pointer. // Set the method back-pointer.
_method = method(); _method = method();
if (TieredCompilation) { _invocation_counter.init();
_invocation_counter.init(); _backedge_counter.init();
_backedge_counter.init(); _invocation_counter_start = 0;
_invocation_counter_start = 0; _backedge_counter_start = 0;
_backedge_counter_start = 0; _num_loops = 0;
_num_loops = 0; _num_blocks = 0;
_num_blocks = 0; _highest_comp_level = 0;
_highest_comp_level = 0; _highest_osr_comp_level = 0;
_highest_osr_comp_level = 0; _would_profile = true;
_would_profile = true;
}
set_creation_mileage(mileage_of(method())); set_creation_mileage(mileage_of(method()));
// Initialize flags and trap history. // Initialize flags and trap history.
_nof_decompiles = 0; _nof_decompiles = 0;
_nof_overflow_recompiles = 0; _nof_overflow_recompiles = 0;
_nof_overflow_traps = 0; _nof_overflow_traps = 0;
_eflags = 0;
_arg_local = 0;
_arg_stack = 0;
_arg_returned = 0;
assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align"); assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align");
Copy::zero_to_words((HeapWord*) &_trap_hist, Copy::zero_to_words((HeapWord*) &_trap_hist,
sizeof(_trap_hist) / sizeof(HeapWord)); sizeof(_trap_hist) / sizeof(HeapWord));
...@@ -677,6 +679,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) { ...@@ -677,6 +679,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
// corresponding data cells. // corresponding data cells.
int data_size = 0; int data_size = 0;
int empty_bc_count = 0; // number of bytecodes lacking data int empty_bc_count = 0; // number of bytecodes lacking data
_data[0] = 0; // apparently not set below.
BytecodeStream stream(method); BytecodeStream stream(method);
Bytecodes::Code c; Bytecodes::Code c;
while ((c = stream.next()) >= 0) { while ((c = stream.next()) >= 0) {
...@@ -710,6 +713,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) { ...@@ -710,6 +713,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
post_initialize(&stream); post_initialize(&stream);
set_size(object_size); set_size(object_size);
} }
// Get a measure of how much mileage the method has on it. // Get a measure of how much mileage the method has on it.
......
...@@ -336,7 +336,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary; ...@@ -336,7 +336,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(Klass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _access_flags, AccessFlags) \
nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _subklass, Klass*) \
nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _next_sibling, Klass*) \
nonproduct_nonstatic_field(Klass, _verify_count, int) \
nonstatic_field(Klass, _alloc_count, juint) \ nonstatic_field(Klass, _alloc_count, juint) \
nonstatic_field(MethodData, _size, int) \ nonstatic_field(MethodData, _size, int) \
nonstatic_field(MethodData, _method, Method*) \ nonstatic_field(MethodData, _method, Method*) \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册