# HG changeset patch # User coleenp # Date 1362761277 18000 # Node ID 3efdfd6ddbf29fa872ea607c49a7f5ec6d77c36a # Parent 6b803ba4758829a9a5aace17be6487481ce25a58 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 diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/interpreter/rewriter.cpp --- 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()); } diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/memory/metablock.cpp --- 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; diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/memory/metaspace.cpp --- 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; diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/oops/constMethod.cpp --- 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); } diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/oops/cpCache.cpp --- 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); diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/oops/cpCache.hpp --- 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; } diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/oops/instanceKlass.cpp --- 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); diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/oops/instanceKlass.hpp --- 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* _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) { diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/oops/klass.cpp --- 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); diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/oops/klass.hpp --- 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; diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/oops/method.cpp --- 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); diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/oops/methodData.cpp --- 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. diff -r 6b803ba47588 -r 3efdfd6ddbf2 src/share/vm/runtime/vmStructs.cpp --- 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*) \