< prev index next >

src/hotspot/share/memory/metaspace/metaspaceCommon.hpp

Print this page
rev 60538 : imported patch jep387-all.patch

*** 1,7 **** /* ! * Copyright (c) 2018, 2019, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,8 ---- /* ! * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. ! * Copyright (c) 2018, 2020 SAP SE. 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 23,48 **** */ #ifndef SHARE_MEMORY_METASPACE_METASPACECOMMON_HPP #define SHARE_MEMORY_METASPACE_METASPACECOMMON_HPP #include "utilities/align.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" class outputStream; namespace metaspace { ! enum ChunkSizes { // in words. ! ClassSpecializedChunk = 128, ! SpecializedChunk = 128, ! ClassSmallChunk = 256, ! SmallChunk = 512, ! ClassMediumChunk = 4 * K, ! MediumChunk = 8 * K ! }; // Print a size, in words, scaled. void print_scaled_words(outputStream* st, size_t word_size, size_t scale = 0, int width = -1); // Convenience helper: prints a size value and a percentage. --- 24,66 ---- */ #ifndef SHARE_MEMORY_METASPACE_METASPACECOMMON_HPP #define SHARE_MEMORY_METASPACE_METASPACECOMMON_HPP + #include "runtime/globals.hpp" #include "utilities/align.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" class outputStream; namespace metaspace { ! ! // Metaspace allocation alignment: ! ! // 1) Metaspace allocations have to be aligned such that 64bit values are aligned ! // correctly. ! // ! // 2) Klass* structures allocated from Metaspace have to be aligned to KlassAlignmentInBytes. ! // ! // At the moment LogKlassAlignmentInBytes is 3, so KlassAlignmentInBytes == 8, ! // so (1) and (2) can both be fulfilled with an alignment of 8. Should we increase ! // KlassAlignmentInBytes at any time this will increase the necessary alignment as well. In ! // that case we may think about introducing a separate alignment just for the class space ! // since that alignment would only be needed for Klass structures. ! ! static const size_t allocation_alignment_bytes = 8; ! STATIC_ASSERT(allocation_alignment_bytes == (size_t)KlassAlignmentInBytes); ! ! static const size_t allocation_alignment_words = allocation_alignment_bytes / BytesPerWord; ! ! // Returns the raw word size allocated for a given net allocation ! size_t get_raw_word_size_for_requested_word_size(size_t word_size); ! ! ! // Utility functions // Print a size, in words, scaled. void print_scaled_words(outputStream* st, size_t word_size, size_t scale = 0, int width = -1); // Convenience helper: prints a size value and a percentage.
*** 58,150 **** // Prints a percentage value. Values smaller than 1% but not 0 are displayed as "<1%", values // larger than 99% but not 100% are displayed as ">100%". void print_percentage(outputStream* st, size_t total, size_t part); #define assert_is_aligned(value, alignment) \ assert(is_aligned((value), (alignment)), \ SIZE_FORMAT_HEX " is not aligned to " \ ! SIZE_FORMAT, (size_t)(uintptr_t)value, (alignment)) ! ! // Internal statistics. ! #ifdef ASSERT ! struct internal_statistics_t { ! // Number of allocations. ! uintx num_allocs; ! // Number of times a ClassLoaderMetaspace was born... ! uintx num_metaspace_births; ! // ... and died. ! uintx num_metaspace_deaths; ! // Number of times VirtualSpaceListNodes were created... ! uintx num_vsnodes_created; ! // ... and purged. ! uintx num_vsnodes_purged; ! // Number of times we expanded the committed section of the space. ! uintx num_committed_space_expanded; ! // Number of deallocations ! uintx num_deallocs; ! // Number of deallocations triggered from outside ("real" deallocations). ! uintx num_external_deallocs; ! // Number of times an allocation was satisfied from deallocated blocks. ! uintx num_allocs_from_deallocated_blocks; ! // Number of times a chunk was added to the freelist ! uintx num_chunks_added_to_freelist; ! // Number of times a chunk was removed from the freelist ! uintx num_chunks_removed_from_freelist; ! // Number of chunk merges ! uintx num_chunk_merges; ! // Number of chunk splits ! uintx num_chunk_splits; ! }; ! extern internal_statistics_t g_internal_statistics; #endif - // ChunkIndex defines the type of chunk. - // Chunk types differ by size: specialized < small < medium, chunks - // larger than medium are humongous chunks of varying size. - enum ChunkIndex { - ZeroIndex = 0, - SpecializedIndex = ZeroIndex, - SmallIndex = SpecializedIndex + 1, - MediumIndex = SmallIndex + 1, - HumongousIndex = MediumIndex + 1, - NumberOfFreeLists = 3, - NumberOfInUseLists = 4 - }; - - // Utility functions. - size_t get_size_for_nonhumongous_chunktype(ChunkIndex chunk_type, bool is_class); - ChunkIndex get_chunk_type_by_size(size_t size, bool is_class); - - ChunkIndex next_chunk_index(ChunkIndex i); - ChunkIndex prev_chunk_index(ChunkIndex i); - // Returns a descriptive name for a chunk type. - const char* chunk_size_name(ChunkIndex index); - - // Verify chunk sizes. - inline bool is_valid_chunksize(bool is_class, size_t size) { - const size_t reasonable_maximum_humongous_chunk_size = 1 * G; - return is_aligned(size, sizeof(MetaWord)) && - size < reasonable_maximum_humongous_chunk_size && - is_class ? - (size == ClassSpecializedChunk || size == ClassSmallChunk || size >= ClassMediumChunk) : - (size == SpecializedChunk || size == SmallChunk || size >= MediumChunk); - } - - // Verify chunk type. - inline bool is_valid_chunktype(ChunkIndex index) { - return index == SpecializedIndex || index == SmallIndex || - index == MediumIndex || index == HumongousIndex; - } - - inline bool is_valid_nonhumongous_chunktype(ChunkIndex index) { - return is_valid_chunktype(index) && index != HumongousIndex; - } // Pretty printing helpers const char* classes_plural(uintx num); const char* loaders_plural(uintx num); void print_number_of_classes(outputStream* out, uintx classes, uintx classes_shared); } // namespace metaspace #endif // SHARE_MEMORY_METASPACE_METASPACECOMMON_HPP --- 76,151 ---- // Prints a percentage value. Values smaller than 1% but not 0 are displayed as "<1%", values // larger than 99% but not 100% are displayed as ">100%". void print_percentage(outputStream* st, size_t total, size_t part); + #ifdef ASSERT #define assert_is_aligned(value, alignment) \ assert(is_aligned((value), (alignment)), \ SIZE_FORMAT_HEX " is not aligned to " \ ! SIZE_FORMAT_HEX, (size_t)(uintptr_t)value, (size_t)(alignment)) ! #else ! #define assert_is_aligned(value, alignment) #endif // Pretty printing helpers const char* classes_plural(uintx num); const char* loaders_plural(uintx num); void print_number_of_classes(outputStream* out, uintx classes, uintx classes_shared); + + // Since Metaspace verifications are expensive, we want to do them at a reduced rate, + // but not completely avoiding them. + // For that we introduce the macros SOMETIMES() and ASSERT_SOMETIMES() which will + // execute code or assert at intervals controlled via VerifyMetaspaceInterval. + #ifdef ASSERT + + #define EVERY_NTH(n) \ + { static int counter_ = 0; \ + if (n > 0) { \ + counter_ ++; \ + if (counter_ > n) { \ + counter_ = 0; \ + + #define END_EVERY_NTH } } } + + #define SOMETIMES(code) \ + EVERY_NTH(VerifyMetaspaceInterval) \ + { code } \ + END_EVERY_NTH + + #define ASSERT_SOMETIMES(condition, ...) \ + EVERY_NTH(VerifyMetaspaceInterval) \ + assert( (condition), __VA_ARGS__); \ + END_EVERY_NTH + + #else + + #define SOMETIMES(code) + #define ASSERT_SOMETIMES(condition, ...) + + #endif // ASSERT + + ///////// Logging ////////////// + + // What we log at which levels: + + // "info" : metaspace failed allocation, commit failure, reserve failure, metaspace oom, metaspace gc threshold changed, Arena created, destroyed, metaspace purged + + // "debug" : "info" + vslist extended, memory committed/uncommitted, chunk created/split/merged/enlarged, chunk returned + + // "trace" : "debug" + every single allocation and deallocation, internals + + #define HAVE_UL + + #ifdef HAVE_UL + #define UL(level, message) log_##level(metaspace)(LOGFMT ": " message, LOGFMT_ARGS); + #define UL2(level, message, ...) log_##level(metaspace)(LOGFMT ": " message, LOGFMT_ARGS, __VA_ARGS__); + #else + #define UL(level, ...) + #define UL2(level, ...) + #endif + } // namespace metaspace #endif // SHARE_MEMORY_METASPACE_METASPACECOMMON_HPP
< prev index next >