Skip to content

Commit 2c1da6c

Browse files
committedJun 12, 2024
8332139: SymbolTableHash::Node allocations allocates twice the required memory
Reviewed-by: iwalulya, coleenp
1 parent ba67ad6 commit 2c1da6c

File tree

4 files changed

+20
-5
lines changed

4 files changed

+20
-5
lines changed
 

‎src/hotspot/share/classfile/symbolTable.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ class SymbolTableConfig : public AllStatic {
172172
// Deleting permanent symbol should not occur very often (insert race condition),
173173
// so log it.
174174
log_trace_symboltable_helper(&value, "Freeing permanent symbol");
175-
size_t alloc_size = _local_table->get_node_size() + value.byte_size() + value.effective_length();
175+
size_t alloc_size = SymbolTableHash::get_dynamic_node_size(value.byte_size());
176176
if (!SymbolTable::arena()->Afree(memory, alloc_size)) {
177177
log_trace_symboltable_helper(&value, "Leaked permanent symbol");
178178
}
@@ -182,7 +182,7 @@ class SymbolTableConfig : public AllStatic {
182182

183183
private:
184184
static void* allocate_node_impl(size_t size, Value const& value) {
185-
size_t alloc_size = size + value.byte_size() + value.effective_length();
185+
size_t alloc_size = SymbolTableHash::get_dynamic_node_size(value.byte_size());
186186
#if INCLUDE_CDS
187187
if (CDSConfig::is_dumping_static_archive()) {
188188
MutexLocker ml(DumpRegion_lock, Mutex::_no_safepoint_check_flag);

‎src/hotspot/share/oops/symbol.hpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class Symbol : public MetaspaceObj {
122122
};
123123

124124
static int byte_size(int length) {
125-
// minimum number of natural words needed to hold these bits (no non-heap version)
125+
// minimum number of bytes needed to hold these bits (no non-heap version)
126126
return (int)(sizeof(Symbol) + (length > 2 ? length - 2 : 0));
127127
}
128128
static int size(int length) {
@@ -146,8 +146,6 @@ class Symbol : public MetaspaceObj {
146146

147147
int size() const { return size(utf8_length()); }
148148
int byte_size() const { return byte_size(utf8_length()); };
149-
// length without the _body
150-
size_t effective_length() const { return (size_t)byte_size() - sizeof(Symbol); }
151149

152150
// Symbols should be stored in the read-only region of CDS archive.
153151
static bool is_read_only_by_default() { return true; }

‎src/hotspot/share/utilities/concurrentHashTable.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ class ConcurrentHashTable : public CHeapObj<F> {
9191

9292
void print_on(outputStream* st) const {};
9393
void print_value_on(outputStream* st) const {};
94+
95+
static bool is_dynamic_sized_value_compatible() {
96+
// To support dynamically sized Value types, where part of the payload is
97+
// allocated beyond the end of the object, it must be that the _value
98+
// field ends where the Node object ends. (No end padding).
99+
return offset_of(Node, _value) + sizeof(_value) == sizeof(Node);
100+
}
94101
};
95102

96103
// Only constructed with placement new from an array allocated with MEMFLAGS
@@ -419,6 +426,7 @@ class ConcurrentHashTable : public CHeapObj<F> {
419426

420427
size_t get_size_log2(Thread* thread);
421428
static size_t get_node_size() { return sizeof(Node); }
429+
static size_t get_dynamic_node_size(size_t value_size);
422430
bool is_max_size_reached() { return _size_limit_reached; }
423431

424432
// This means no paused bucket resize operation is going to resume

‎src/hotspot/share/utilities/concurrentHashTable.inline.hpp

+9
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,15 @@ inline size_t ConcurrentHashTable<CONFIG, F>::
10551055
return _table->_log2_size;
10561056
}
10571057

1058+
template <typename CONFIG, MEMFLAGS F>
1059+
inline size_t ConcurrentHashTable<CONFIG, F>::
1060+
get_dynamic_node_size(size_t value_size)
1061+
{
1062+
assert(Node::is_dynamic_sized_value_compatible(), "VALUE must be compatible");
1063+
assert(value_size >= sizeof(VALUE), "must include the VALUE");
1064+
return sizeof(Node) - sizeof(VALUE) + value_size;
1065+
}
1066+
10581067
template <typename CONFIG, MEMFLAGS F>
10591068
inline bool ConcurrentHashTable<CONFIG, F>::
10601069
shrink(Thread* thread, size_t size_limit_log2)

0 commit comments

Comments
 (0)
Please sign in to comment.