Skip to content

Commit daf2617

Browse files
committed
8338929: Make Metaspace::deallocate space-aware
Reviewed-by: coleenp, adinn
1 parent fa4ff78 commit daf2617

File tree

6 files changed

+54
-24
lines changed

6 files changed

+54
-24
lines changed

src/hotspot/share/memory/classLoaderMetaspace.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2020 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -130,9 +130,10 @@ MetaWord* ClassLoaderMetaspace::expand_and_allocate(size_t word_size, Metaspace:
130130

131131
// Prematurely returns a metaspace allocation to the _block_freelists
132132
// because it is not needed anymore.
133-
void ClassLoaderMetaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
133+
void ClassLoaderMetaspace::deallocate(MetaWord* ptr, size_t word_size) {
134134
MutexLocker fcl(lock(), Mutex::_no_safepoint_check_flag);
135-
if (Metaspace::using_class_space() && is_class) {
135+
const bool is_class = Metaspace::using_class_space() && Metaspace::is_in_class_space(ptr);
136+
if (is_class) {
136137
class_space_arena()->deallocate(ptr, word_size);
137138
} else {
138139
non_class_space_arena()->deallocate(ptr, word_size);

src/hotspot/share/memory/classLoaderMetaspace.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -92,7 +92,7 @@ class ClassLoaderMetaspace : public CHeapObj<mtClass> {
9292

9393
// Prematurely returns a metaspace allocation to the _block_freelists
9494
// because it is not needed anymore.
95-
void deallocate(MetaWord* ptr, size_t word_size, bool is_class);
95+
void deallocate(MetaWord* ptr, size_t word_size);
9696

9797
// Update statistics. This walks all in-use chunks.
9898
void add_to_statistics(metaspace::ClmsStats* out) const;

src/hotspot/share/memory/metadataFactory.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,7 @@ class MetadataFactory : AllStatic {
5454
assert(loader_data != nullptr, "shouldn't pass null");
5555
assert(!data->is_shared(), "cannot deallocate array in shared spaces");
5656
int size = data->size();
57-
loader_data->metaspace_non_null()->deallocate((MetaWord*)data, size, false);
57+
loader_data->metaspace_non_null()->deallocate((MetaWord*)data, size);
5858
}
5959
}
6060

@@ -68,15 +68,14 @@ class MetadataFactory : AllStatic {
6868
assert(!md->on_stack(), "can't deallocate things on stack");
6969
assert(!md->is_shared(), "cannot deallocate if in shared spaces");
7070
md->deallocate_contents(loader_data);
71-
bool is_klass = md->is_klass();
7271
// Call the destructor. This is currently used for MethodData which has a member
7372
// that needs to be destructed to release resources. Most Metadata derived classes have noop
7473
// destructors and/or cleanup using deallocate_contents.
7574
// T is a potentially const or volatile qualified pointer. Remove any const
7675
// or volatile so we can call the destructor of the type T points to.
7776
using U = std::remove_cv_t<T>;
7877
md->~U();
79-
loader_data->metaspace_non_null()->deallocate((MetaWord*)md, size, is_klass);
78+
loader_data->metaspace_non_null()->deallocate((MetaWord*)md, size);
8079
}
8180
}
8281
};

src/hotspot/share/memory/metaspace.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,8 @@ void MetaspaceGC::compute_new_size() {
538538
////// Metaspace methods /////
539539

540540
const MetaspaceTracer* Metaspace::_tracer = nullptr;
541+
const void* Metaspace::_class_space_start = nullptr;
542+
const void* Metaspace::_class_space_end = nullptr;
541543

542544
bool Metaspace::initialized() {
543545
return metaspace::MetaspaceContext::context_nonclass() != nullptr
@@ -570,6 +572,8 @@ void Metaspace::initialize_class_space(ReservedSpace rs) {
570572
"wrong alignment");
571573

572574
MetaspaceContext::initialize_class_space_context(rs);
575+
_class_space_start = rs.base();
576+
_class_space_end = rs.end();
573577
}
574578

575579
// Returns true if class space has been setup (initialize_class_space).
@@ -979,17 +983,15 @@ void Metaspace::purge(bool classes_unloaded) {
979983
MetaspaceCriticalAllocation::process();
980984
}
981985

982-
bool Metaspace::contains(const void* ptr) {
983-
if (MetaspaceShared::is_in_shared_metaspace(ptr)) {
984-
return true;
985-
}
986-
return contains_non_shared(ptr);
987-
}
988986

989-
bool Metaspace::contains_non_shared(const void* ptr) {
990-
if (using_class_space() && VirtualSpaceList::vslist_class()->contains((MetaWord*)ptr)) {
991-
return true;
992-
}
987+
// Returns true if pointer points into one of the metaspace regions, or
988+
// into the class space.
989+
bool Metaspace::is_in_shared_metaspace(const void* ptr) {
990+
return MetaspaceShared::is_in_shared_metaspace(ptr);
991+
}
993992

993+
// Returns true if pointer points into one of the non-class-space metaspace regions.
994+
bool Metaspace::is_in_nonclass_metaspace(const void* ptr) {
994995
return VirtualSpaceList::vslist_nonclass()->contains((MetaWord*)ptr);
995996
}
997+

src/hotspot/share/memory/metaspace.hpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2017, 2021 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -64,6 +64,10 @@ class Metaspace : public AllStatic {
6464

6565
static const MetaspaceTracer* _tracer;
6666

67+
// For quick pointer testing: extent of class space; nullptr if no class space.
68+
static const void* _class_space_start;
69+
static const void* _class_space_end;
70+
6771
static bool _initialized;
6872

6973
public:
@@ -113,8 +117,32 @@ class Metaspace : public AllStatic {
113117
static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
114118
MetaspaceObj::Type type);
115119

116-
static bool contains(const void* ptr);
117-
static bool contains_non_shared(const void* ptr);
120+
// Returns true if the pointer points into class space, non-class metaspace, or the
121+
// metadata portion of the CDS archive.
122+
static bool contains(const void* ptr) {
123+
return is_in_shared_metaspace(ptr) || // in cds
124+
is_in_class_space(ptr) || // in class space
125+
is_in_nonclass_metaspace(ptr); // in one of the non-class regions?
126+
}
127+
128+
// Returns true if the pointer points into class space or into non-class metaspace
129+
static bool contains_non_shared(const void* ptr) {
130+
return is_in_class_space(ptr) || // in class space
131+
is_in_nonclass_metaspace(ptr); // in one of the non-class regions?
132+
}
133+
134+
// Returns true if pointer points into the CDS klass region.
135+
static bool is_in_shared_metaspace(const void* ptr);
136+
137+
// Returns true if pointer points into one of the non-class-space metaspace regions.
138+
static bool is_in_nonclass_metaspace(const void* ptr);
139+
140+
// Returns true if pointer points into class space, false if it doesn't or if
141+
// there is no class space. Class space is a contiguous region, which is why
142+
// two address comparisons are enough.
143+
static inline bool is_in_class_space(const void* ptr) {
144+
return ptr < _class_space_end && ptr >= _class_space_start;
145+
}
118146

119147
// Free empty virtualspaces
120148
static void purge(bool classes_unloaded);

test/hotspot/gtest/metaspace/test_metaspace_misc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2020 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -67,7 +67,7 @@ TEST_VM(metaspace, misc_max_alloc_size) {
6767
ASSERT_NOT_NULL(p);
6868
}
6969
// And also, successfully deallocate it.
70-
cld->metaspace_non_null()->deallocate(p, sz, in_class_space);
70+
cld->metaspace_non_null()->deallocate(p, sz);
7171
}
7272
}
7373

0 commit comments

Comments
 (0)