--- old/src/hotspot/share/memory/metachunk.cpp 2018-02-26 14:42:47.812049000 +0100 +++ new/src/hotspot/share/memory/metachunk.cpp 2018-02-26 14:42:47.404018000 +0100 @@ -48,9 +48,16 @@ // Metachunk methods -Metachunk::Metachunk(size_t word_size, +Metachunk::Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size, VirtualSpaceNode* container) : Metabase(word_size), + _chunk_type(chunktype), + _is_class(is_class), +#ifdef ASSERT + _sentinel(CHUNK_SENTINEL), + _origin(origin_normal), + _use_count(0), +#endif _top(NULL), _container(container) { @@ -58,6 +65,7 @@ set_is_tagged_free(false); #ifdef ASSERT mangle(uninitMetaWordVal); + verify(); #endif } @@ -83,15 +91,16 @@ void Metachunk::print_on(outputStream* st) const { st->print_cr("Metachunk:" " bottom " PTR_FORMAT " top " PTR_FORMAT - " end " PTR_FORMAT " size " SIZE_FORMAT, - p2i(bottom()), p2i(_top), p2i(end()), word_size()); + " end " PTR_FORMAT " size " SIZE_FORMAT " (%s)", + p2i(bottom()), p2i(_top), p2i(end()), word_size(), + chunk_size_name(get_chunk_type())); if (Verbose) { st->print_cr(" used " SIZE_FORMAT " free " SIZE_FORMAT, used_word_size(), free_word_size()); } } -#ifndef PRODUCT +#ifdef ASSERT void Metachunk::mangle(juint word_value) { // Overwrite the payload of the chunk and not the links that // maintain list of chunks. @@ -99,16 +108,44 @@ size_t size = word_size() - overhead(); Copy::fill_to_words(start, size, word_value); } -#endif // PRODUCT void Metachunk::verify() { -#ifdef ASSERT - // Cannot walk through the blocks unless the blocks have - // headers with sizes. - assert(bottom() <= _top && - _top <= (MetaWord*)end(), - "Chunk has been smashed"); -#endif - return; + assert(is_valid_sentinel(), "Chunk " PTR_FORMAT ": sentinel invalid", p2i(this)); + const ChunkIndex chunk_type = get_chunk_type(); + assert(is_valid_chunktype(chunk_type), "Chunk " PTR_FORMAT ": Invalid chunk type.", p2i(this)); + if (chunk_type != HumongousIndex) { + assert(word_size() == get_size_for_nonhumongous_chunktype(chunk_type, is_class()), + "Chunk " PTR_FORMAT ": wordsize " SIZE_FORMAT " does not fit chunk type %s.", + p2i(this), word_size(), chunk_size_name(chunk_type)); + } + assert(is_valid_chunkorigin(get_origin()), "Chunk " PTR_FORMAT ": Invalid chunk origin.", p2i(this)); + assert(bottom() <= _top && _top <= (MetaWord*)end(), + "Chunk " PTR_FORMAT ": Chunk top out of chunk bounds.", p2i(this)); + + // For non-humongous chunks, starting address shall be aligned + // to its chunk size. Humongous chunks start address is + // aligned to specialized chunk size. + const size_t required_alignment = + (chunk_type != HumongousIndex ? word_size() : get_size_for_nonhumongous_chunktype(SpecializedIndex, is_class())) * sizeof(MetaWord); + assert(is_aligned((address)this, required_alignment), + "Chunk " PTR_FORMAT ": (size " SIZE_FORMAT ") not aligned to " SIZE_FORMAT ".", + p2i(this), word_size() * sizeof(MetaWord), required_alignment); +} + +#endif // ASSERT + +// Helper, returns a descriptive name for the given index. +const char* chunk_size_name(ChunkIndex index) { + switch (index) { + case SpecializedIndex: + return "specialized"; + case SmallIndex: + return "small"; + case MediumIndex: + return "medium"; + case HumongousIndex: + return "humongous"; + default: + return "Invalid index"; + } } -