Skip to content

Commit ad10493

Browse files
committed
8338526: Don't store abstract and interface Klasses in class metaspace
Reviewed-by: stuefe, iklam
1 parent 0d8e52b commit ad10493

File tree

19 files changed

+80
-50
lines changed

19 files changed

+80
-50
lines changed

src/hotspot/share/classfile/classFileParser.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ class ClassFileParser {
547547

548548
bool is_hidden() const { return _is_hidden; }
549549
bool is_interface() const { return _access_flags.is_interface(); }
550+
bool is_abstract() const { return _access_flags.is_abstract(); }
550551

551552
ClassLoaderData* loader_data() const { return _loader_data; }
552553
const Symbol* class_name() const { return _class_name; }

src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.cpp

Lines changed: 8 additions & 7 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
* 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
@@ -30,7 +30,6 @@
3030
#include "jfr/support/jfrThreadLocal.hpp"
3131
#include "jfr/utilities/jfrEpochQueue.inline.hpp"
3232
#include "jfr/utilities/jfrTypes.hpp"
33-
#include "memory/metaspace.hpp"
3433
#include "oops/compressedKlass.inline.hpp"
3534
#include "utilities/macros.hpp"
3635

@@ -75,13 +74,14 @@ static size_t element_size(bool compressed) {
7574
return compressed ? NARROW_ELEMENT_SIZE : ELEMENT_SIZE;
7675
}
7776

78-
static bool can_compress_element(traceid id) {
79-
return Metaspace::using_class_space() && id < uncompressed_threshold;
77+
static bool can_compress_element(const Klass* klass) {
78+
return CompressedKlassPointers::is_in_encoding_range(klass) &&
79+
JfrTraceId::load_raw(klass) < uncompressed_threshold;
8080
}
8181

8282
static size_t element_size(const Klass* klass) {
8383
assert(klass != nullptr, "invariant");
84-
return element_size(can_compress_element(JfrTraceId::load_raw(klass)));
84+
return element_size(can_compress_element(klass));
8585
}
8686

8787
static bool is_unloaded(traceid id, bool previous_epoch) {
@@ -137,7 +137,8 @@ static inline void store_traceid(JfrEpochQueueNarrowKlassElement* element, trace
137137
}
138138

139139
static void store_compressed_element(traceid id, const Klass* klass, u1* pos) {
140-
assert(can_compress_element(id), "invariant");
140+
assert(can_compress_element(klass), "invariant");
141+
assert(id == JfrTraceId::load_raw(klass), "invariant");
141142
JfrEpochQueueNarrowKlassElement* const element = new (pos) JfrEpochQueueNarrowKlassElement();
142143
store_traceid(element, id);
143144
element->compressed_klass = encode(klass);
@@ -153,7 +154,7 @@ static void store_element(const Klass* klass, u1* pos) {
153154
assert(pos != nullptr, "invariant");
154155
assert(klass != nullptr, "invariant");
155156
const traceid id = JfrTraceId::load_raw(klass);
156-
if (can_compress_element(id)) {
157+
if (can_compress_element(klass)) {
157158
store_compressed_element(id, klass, pos);
158159
return;
159160
}

src/hotspot/share/memory/allocation.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 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
@@ -75,14 +75,16 @@ void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
7575
size_t word_size,
7676
MetaspaceObj::Type type, TRAPS) throw() {
7777
// Klass has its own operator new
78-
return Metaspace::allocate(loader_data, word_size, type, THREAD);
78+
assert(type != ClassType, "class has its own operator new");
79+
return Metaspace::allocate(loader_data, word_size, type, /*use_class_space*/ false, THREAD);
7980
}
8081

8182
void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
8283
size_t word_size,
8384
MetaspaceObj::Type type) throw() {
8485
assert(!Thread::current()->is_Java_thread(), "only allowed by non-Java thread");
85-
return Metaspace::allocate(loader_data, word_size, type);
86+
assert(type != ClassType, "class has its own operator new");
87+
return Metaspace::allocate(loader_data, word_size, type, /*use_class_space*/ false);
8688
}
8789

8890
bool MetaspaceObj::is_valid(const MetaspaceObj* p) {

src/hotspot/share/memory/metaspace.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ size_t Metaspace::max_allocation_word_size() {
830830
// is suitable for calling from non-Java threads.
831831
// Callers are responsible for checking null.
832832
MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
833-
MetaspaceObj::Type type) {
833+
MetaspaceObj::Type type, bool use_class_space) {
834834
assert(word_size <= Metaspace::max_allocation_word_size(),
835835
"allocation size too large (" SIZE_FORMAT ")", word_size);
836836

@@ -840,7 +840,7 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
840840
// Deal with concurrent unloading failed allocation starvation
841841
MetaspaceCriticalAllocation::block_if_concurrent_purge();
842842

843-
MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
843+
MetadataType mdtype = use_class_space ? ClassType : NonClassType;
844844

845845
// Try to allocate metadata.
846846
MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
@@ -856,18 +856,18 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
856856
}
857857

858858
MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
859-
MetaspaceObj::Type type, TRAPS) {
859+
MetaspaceObj::Type type, bool use_class_space, TRAPS) {
860860

861861
if (HAS_PENDING_EXCEPTION) {
862862
assert(false, "Should not allocate with exception pending");
863863
return nullptr; // caller does a CHECK_NULL too
864864
}
865865
assert(!THREAD->owns_locks(), "allocating metaspace while holding mutex");
866866

867-
MetaWord* result = allocate(loader_data, word_size, type);
867+
MetaWord* result = allocate(loader_data, word_size, type, use_class_space);
868868

869869
if (result == nullptr) {
870-
MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
870+
MetadataType mdtype = use_class_space ? ClassType : NonClassType;
871871
tracer()->report_metaspace_allocation_failure(loader_data, word_size, type, mdtype);
872872

873873
// Allocation failed.

src/hotspot/share/memory/metaspace.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,12 @@ class Metaspace : public AllStatic {
110110
static size_t max_allocation_word_size();
111111

112112
static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
113-
MetaspaceObj::Type type, TRAPS);
113+
MetaspaceObj::Type type, bool use_class_space, TRAPS);
114114

115115
// Non-TRAPS version of allocate which can be called by a non-Java thread, that returns
116116
// null on failure.
117117
static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
118-
MetaspaceObj::Type type);
118+
MetaspaceObj::Type type, bool use_class_space);
119119

120120
// Returns true if the pointer points into class space, non-class metaspace, or the
121121
// metadata portion of the CDS archive.

src/hotspot/share/oops/annotations.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 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
@@ -89,7 +89,6 @@ class Annotations: public MetaspaceObj {
8989
// Turn metadata annotations into a Java heap object (oop)
9090
static typeArrayOop make_java_array(AnnotationArray* annotations, TRAPS);
9191

92-
bool is_klass() const { return false; }
9392
void metaspace_pointers_do(MetaspaceClosure* it);
9493
MetaspaceObj::Type type() const { return AnnotationsType; }
9594

src/hotspot/share/oops/array.inline.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 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
@@ -34,7 +34,7 @@ template <typename T>
3434
inline void* Array<T>::operator new(size_t size, ClassLoaderData* loader_data, int length, TRAPS) throw() {
3535
size_t word_size = Array::size(length);
3636
return (void*) Metaspace::allocate(loader_data, word_size,
37-
MetaspaceObj::array_type(sizeof(T)), THREAD);
37+
MetaspaceObj::array_type(sizeof(T)), false, THREAD);
3838
}
3939

4040
#endif // SHARE_OOPS_ARRAY_INLINE_HPP

src/hotspot/share/oops/arrayKlass.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
#include "oops/oop.inline.hpp"
4343
#include "runtime/handles.inline.hpp"
4444

45+
void* ArrayKlass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw() {
46+
return Metaspace::allocate(loader_data, word_size, MetaspaceObj::ClassType, true, THREAD);
47+
}
48+
4549
ArrayKlass::ArrayKlass() {
4650
assert(CDSConfig::is_dumping_static_archive() || CDSConfig::is_using_archive(), "only for CDS");
4751
}

src/hotspot/share/oops/arrayKlass.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 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
@@ -49,6 +49,8 @@ class ArrayKlass: public Klass {
4949
ArrayKlass(Symbol* name, KlassKind kind);
5050
ArrayKlass();
5151

52+
void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw();
53+
5254
public:
5355
// Testing operation
5456
DEBUG_ONLY(bool is_array_klass_slow() const { return true; })

src/hotspot/share/oops/compressedKlass.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 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
@@ -107,6 +107,18 @@ class CompressedKlassPointers : public AllStatic {
107107

108108
static inline narrowKlass encode_not_null(Klass* v);
109109
static inline narrowKlass encode(Klass* v);
110+
111+
// Returns whether the pointer is in the memory region used for encoding compressed
112+
// class pointers. This includes CDS.
113+
114+
// encoding encoding
115+
// base end (base+range)
116+
// |-----------------------------------------------------------------------|
117+
// |----CDS---| |--------------------class space---------------------------|
118+
119+
static inline bool is_in_encoding_range(const void* p) {
120+
return p >= _base && p < (_base + _range);
121+
}
110122
};
111123

112124
#endif // SHARE_OOPS_COMPRESSEDKLASS_HPP

0 commit comments

Comments
 (0)