< prev index next > src/hotspot/share/memory/classLoaderMetaspace.cpp
Print this page
#include "memory/classLoaderMetaspace.hpp"
#include "memory/metaspace.hpp"
#include "memory/metaspaceUtils.hpp"
#include "memory/metaspace/chunkManager.hpp"
#include "memory/metaspace/internalStats.hpp"
+ #include "memory/metaspace/metablock.hpp"
#include "memory/metaspace/metaspaceArena.hpp"
#include "memory/metaspace/metaspaceArenaGrowthPolicy.hpp"
+ #include "memory/metaspace/metaspaceCommon.hpp"
+ #include "memory/metaspace/metaspaceContext.hpp"
#include "memory/metaspace/metaspaceSettings.hpp"
#include "memory/metaspace/metaspaceStatistics.hpp"
#include "memory/metaspace/runningCounters.hpp"
#include "memory/metaspaceTracer.hpp"
+ #include "oops/klass.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/debug.hpp"
using metaspace::ChunkManager;
+ using metaspace::MetaBlock;
using metaspace::MetaspaceArena;
+ using metaspace::MetaspaceContext;
using metaspace::ArenaGrowthPolicy;
using metaspace::RunningCounters;
using metaspace::InternalStats;
#define LOGFMT "CLMS @" PTR_FORMAT " "
#define LOGFMT_ARGS p2i(this)
ClassLoaderMetaspace::ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType space_type) :
+ ClassLoaderMetaspace(lock, space_type,
+ MetaspaceContext::context_nonclass(),
+ MetaspaceContext::context_class(),
+ CompressedKlassPointers::klass_alignment_in_words())
+ {}
+
+ ClassLoaderMetaspace::ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType space_type,
+ MetaspaceContext* non_class_context,
+ MetaspaceContext* class_context,
+ size_t klass_alignment_words) :
_lock(lock),
_space_type(space_type),
_non_class_space_arena(nullptr),
_class_space_arena(nullptr)
{
- ChunkManager* const non_class_cm =
- ChunkManager::chunkmanager_nonclass();
-
// Initialize non-class Arena
_non_class_space_arena = new MetaspaceArena(
- non_class_cm,
+ non_class_context,
ArenaGrowthPolicy::policy_for_space_type(space_type, false),
- RunningCounters::used_nonclass_counter(),
- "non-class sm");
+ Metaspace::min_allocation_alignment_words,
+ "non-class arena");
// If needed, initialize class arena
- if (Metaspace::using_class_space()) {
- ChunkManager* const class_cm =
- ChunkManager::chunkmanager_class();
+ if (class_context != nullptr) {
_class_space_arena = new MetaspaceArena(
- class_cm,
+ class_context,
ArenaGrowthPolicy::policy_for_space_type(space_type, true),
- RunningCounters::used_class_counter(),
- "class sm");
+ klass_alignment_words,
+ "class arena");
}
UL2(debug, "born (nonclass arena: " PTR_FORMAT ", class arena: " PTR_FORMAT ".",
p2i(_non_class_space_arena), p2i(_class_space_arena));
}
}
// Allocate word_size words from Metaspace.
MetaWord* ClassLoaderMetaspace::allocate(size_t word_size, Metaspace::MetadataType mdType) {
+ word_size = align_up(word_size, Metaspace::min_allocation_word_size);
MutexLocker fcl(lock(), Mutex::_no_safepoint_check_flag);
- if (Metaspace::is_class_space_allocation(mdType)) {
- return class_space_arena()->allocate(word_size);
+ MetaBlock result, wastage;
+ const bool is_class = have_class_space_arena() && mdType == Metaspace::ClassType;
+ if (is_class) {
+ assert(word_size >= (sizeof(Klass)/BytesPerWord), "weird size for klass: %zu", word_size);
+ result = class_space_arena()->allocate(word_size, wastage);
} else {
- return non_class_space_arena()->allocate(word_size);
+ result = non_class_space_arena()->allocate(word_size, wastage);
+ }
+ if (wastage.is_nonempty()) {
+ non_class_space_arena()->deallocate(wastage);
+ }
+ #ifdef ASSERT
+ if (result.is_nonempty()) {
+ const bool in_class_arena = class_space_arena() != nullptr ? class_space_arena()->contains(result) : false;
+ const bool in_nonclass_arena = non_class_space_arena()->contains(result);
+ assert((is_class && in_class_arena) || (!is_class && in_class_arena != in_nonclass_arena),
+ "block from neither arena " METABLOCKFORMAT "?", METABLOCKFORMATARGS(result));
}
+ #endif
+ return result.base();
}
// Attempt to expand the GC threshold to be good for at least another word_size words
// and allocate. Returns null if failure. Used during Metaspace GC.
MetaWord* ClassLoaderMetaspace::expand_and_allocate(size_t word_size, Metaspace::MetadataType mdType) {
}
// Prematurely returns a metaspace allocation to the _block_freelists
// because it is not needed anymore.
void ClassLoaderMetaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
- MutexLocker fcl(lock(), Mutex::_no_safepoint_check_flag);
- if (Metaspace::using_class_space() && is_class) {
- class_space_arena()->deallocate(ptr, word_size);
- } else {
- non_class_space_arena()->deallocate(ptr, word_size);
+ NOT_LP64(word_size = align_down(word_size, Metaspace::min_allocation_word_size);)
+ MetaBlock bl(ptr, word_size);
+ if (word_size >= Metaspace::min_allocation_word_size) {
+ MutexLocker fcl(lock(), Mutex::_no_safepoint_check_flag);
+ if (have_class_space_arena() && is_class) {
+ assert(class_space_arena()->contains(bl),
+ "Not from class arena " METABLOCKFORMAT "?", METABLOCKFORMATARGS(bl));
+ class_space_arena()->deallocate(MetaBlock(ptr, word_size));
+ } else {
+ non_class_space_arena()->deallocate(MetaBlock(ptr, word_size));
+ }
+ DEBUG_ONLY(InternalStats::inc_num_deallocs();)
}
- DEBUG_ONLY(InternalStats::inc_num_deallocs();)
}
// Update statistics. This walks all in-use chunks.
void ClassLoaderMetaspace::add_to_statistics(metaspace::ClmsStats* out) const {
MutexLocker fcl(lock(), Mutex::_no_safepoint_check_flag);
size_t used_nc, comm_nc, cap_nc;
size_t used_c = 0, comm_c = 0, cap_c = 0;
{
MutexLocker fcl(lock(), Mutex::_no_safepoint_check_flag);
usage_numbers(Metaspace::MetadataType::NonClassType, &used_nc, &comm_nc, &cap_nc);
- if (Metaspace::using_class_space()) {
+ if (have_class_space_arena()) {
usage_numbers(Metaspace::MetadataType::ClassType, &used_c, &comm_c, &cap_c);
}
}
if (p_used_words != nullptr) {
(*p_used_words) = used_nc + used_c;
< prev index next >