Skip to content

Commit c401e77

Browse files
committed
update: mutable data for all CodeBlobs with relocations
1 parent 52dd527 commit c401e77

File tree

5 files changed

+59
-76
lines changed

5 files changed

+59
-76
lines changed

src/hotspot/share/code/codeBlob.cpp

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,34 +62,23 @@ unsigned int CodeBlob::align_code_offset(int offset) {
6262
}
6363

6464
// This must be consistent with the CodeBlob constructor's layout actions.
65-
unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size, bool external_mutable_data) {
66-
unsigned int size = header_size;
67-
if (!external_mutable_data) {
68-
// In a standard CodeBlob, the relocation_info is located before the code section.
69-
// However, in an nmethod, the relocation_info is stored in the mutable data, so
70-
// it does not contribute to the nmethod's total size, as it is moved to the C heap.
71-
size += align_up(cb->total_relocation_size(), oopSize);
72-
}
65+
unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size) {
7366
// align the size to CodeEntryAlignment
74-
size = align_code_offset(size);
67+
unsigned int size = align_code_offset(header_size);
7568
size += align_up(cb->total_content_size(), oopSize);
76-
if (!external_mutable_data) {
77-
size += align_up(cb->total_oop_size(), oopSize);
78-
size += align_up(cb->total_metadata_size(), oopSize);
79-
}
8069
return size;
8170
}
8271

8372
CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size,
8473
int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments,
85-
bool external_mutable_data) :
74+
int mutable_data_size) :
8675
_oop_maps(nullptr), // will be set by set_oop_maps() call
8776
_name(name),
8877
_size(size),
8978
_relocation_size(align_up(cb->total_relocation_size(), oopSize)),
90-
_content_offset(CodeBlob::align_code_offset(header_size + (external_mutable_data ? 0 : _relocation_size))),
79+
_content_offset(CodeBlob::align_code_offset(header_size)),
9180
_code_offset(_content_offset + cb->total_offset_of(cb->insts())),
92-
_data_offset(_content_offset + align_up(cb->total_content_size(), oopSize)),
81+
_code_end_offset(_content_offset + align_up(cb->total_content_size(), oopSize)),
9382
_frame_size(frame_size),
9483
S390_ONLY(_ctable_offset(0) COMMA)
9584
_header_size(header_size),
@@ -102,13 +91,23 @@ CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size
10291
assert(is_aligned(_size, oopSize), "unaligned size");
10392
assert(is_aligned(header_size, oopSize), "unaligned size");
10493
assert(is_aligned(_relocation_size, oopSize), "unaligned size");
105-
assert(_data_offset <= _size, "codeBlob is too small: %d > %d", _data_offset, _size);
94+
assert(_code_end_offset <= _size, "codeBlob is too small: %d > %d", _code_end_offset, _size);
10695
assert(code_end() == content_end(), "must be the same - see code_end()");
10796
#ifdef COMPILER1
10897
// probably wrong for tiered
10998
assert(_frame_size >= -1, "must use frame size or -1 for runtime stubs");
11099
#endif // COMPILER1
111100

101+
// The mutable_data_size is either calculated by the nmethod constructor to account
102+
// for reloc_info and additional data, or it is set here to accommodate only the relocation data.
103+
_mutable_data_size = (mutable_data_size == 0) ? cb->total_relocation_size() : mutable_data_size;
104+
if (_mutable_data_size > 0) {
105+
_mutable_data = (address)os::malloc(_mutable_data_size, mtCode);
106+
if (_mutable_data == nullptr) {
107+
vm_exit_out_of_memory(_mutable_data_size, OOM_MALLOC_ERROR, "codebuffer: no space for mutable data");
108+
}
109+
}
110+
112111
set_oop_maps(oop_maps);
113112
}
114113

@@ -120,7 +119,7 @@ CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, int size, uint16_t heade
120119
_relocation_size(0),
121120
_content_offset(CodeBlob::align_code_offset(header_size)),
122121
_code_offset(_content_offset),
123-
_data_offset(size),
122+
_code_end_offset(size),
124123
_frame_size(0),
125124
S390_ONLY(_ctable_offset(0) COMMA)
126125
_header_size(header_size),

src/hotspot/share/code/codeBlob.hpp

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ class CodeBlob {
108108
int _relocation_size; // size of relocation (could be bigger than 64Kb)
109109
int _content_offset; // offset to where content region begins (this includes consts, insts, stubs)
110110
int _code_offset; // offset to where instructions region begins (this includes insts, stubs)
111-
112-
int _data_offset; // offset to where data region begins
111+
int _code_end_offset; // offset to where code region ends
113112
int _frame_size; // size of stack frame in words (NOT slots. On x64 these are 64bit words)
114113

115114
S390_ONLY(int _ctable_offset;)
@@ -134,7 +133,7 @@ class CodeBlob {
134133

135134
CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size,
136135
int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments,
137-
bool external_mutable_data = false);
136+
int mutable_data_size = 0);
138137

139138
// Simple CodeBlob used for simple BufferBlob.
140139
CodeBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size);
@@ -148,7 +147,7 @@ class CodeBlob {
148147
}
149148

150149
// Returns the space needed for CodeBlob
151-
static unsigned int allocation_size(CodeBuffer* cb, int header_size, bool external_mutable_data = false);
150+
static unsigned int allocation_size(CodeBuffer* cb, int header_size);
152151
static unsigned int align_code_offset(int offset);
153152

154153
// Deletion
@@ -177,33 +176,25 @@ class CodeBlob {
177176
address mutable_data_begin() const { return _mutable_data; }
178177
address mutable_data_end() const { return _mutable_data + _mutable_data_size; }
179178
int mutable_data_size() const { return _mutable_data_size; }
180-
bool relocInfo_in_mutable_data() const { return _mutable_data != nullptr; }
181179

182180
// Boundaries
183181
address header_begin() const { return (address) this; }
184182
address header_end() const { return ((address) this) + _header_size; }
185-
relocInfo* relocation_begin() const { return relocInfo_in_mutable_data() ?
186-
(relocInfo*)_mutable_data : (relocInfo*) header_end(); }
183+
relocInfo* relocation_begin() const { return (relocInfo*)_mutable_data; }
187184
relocInfo* relocation_end() const { return (relocInfo*)((address)relocation_begin() + _relocation_size); }
188185
address content_begin() const { return (address) header_begin() + _content_offset; }
189-
address content_end() const { return (address) header_begin() + _data_offset; }
186+
address content_end() const { return (address) header_begin() + _code_end_offset; }
190187
address code_begin() const { return (address) header_begin() + _code_offset; }
191188
// code_end == content_end is true for all types of blobs for now, it is also checked in the constructor
192-
address code_end() const { return (address) header_begin() + _data_offset; }
193-
address data_begin() const { return (address) header_begin() + _data_offset; }
194-
address data_end() const { return (address) header_begin() + _size; }
195-
address blob_end() const { return data_end(); }
196-
197-
// [relocations, oops, metatada, jvmci_data] stays in _mutable_data or in nmethod with _data_offset
198-
address mdata_begin() const { return (_mutable_data != nullptr) ? _mutable_data :
199-
(address) header_begin() + _data_offset; }
200-
address mdata_end() const { return (_mutable_data != nullptr) ? _mutable_data + _mutable_data_size:
201-
(address) header_begin() + _size; }
189+
address code_end() const { return (address) header_begin() + _code_end_offset; }
190+
address blob_end() const { return (address) header_begin() + _size; }
202191

192+
// [relocations, oops, metatada, jvmci_data] stays in _mutable_data
193+
address mdata_begin() const { return mutable_data_begin(); }
194+
address mdata_end() const { return mutable_data_end(); }
203195
// Offsets
204196
int content_offset() const { return _content_offset; }
205197
int code_offset() const { return _code_offset; }
206-
int data_offset() const { return _data_offset; }
207198

208199
// This field holds the beginning of the const section in the old code buffer.
209200
// It is needed to fix relocations of pc-relative loads when resizing the
@@ -221,7 +212,7 @@ class CodeBlob {
221212
// Only used from CodeCache::free_unused_tail() after the Interpreter blob was trimmed
222213
void adjust_size(size_t used) {
223214
_size = (int)used;
224-
_data_offset = (int)used;
215+
_code_end_offset = (int)used;
225216
}
226217

227218
// Containment

src/hotspot/share/code/nmethod.cpp

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,14 @@ static void assert_no_oops_or_metadata(nmethod* nm) {
10771077
}
10781078
#endif
10791079

1080+
static int required_mutable_data_space(CodeBuffer* code_buffer,
1081+
int jvmci_data_size = 0) {
1082+
return align_up(code_buffer->total_relocation_size(), oopSize) +
1083+
align_up(code_buffer->total_oop_size(), oopSize) +
1084+
align_up(jvmci_data_size, oopSize) +
1085+
align_up(code_buffer->total_metadata_size(), oopSize);
1086+
}
1087+
10801088
nmethod* nmethod::new_native_nmethod(const methodHandle& method,
10811089
int compile_id,
10821090
CodeBuffer *code_buffer,
@@ -1101,6 +1109,8 @@ nmethod* nmethod::new_native_nmethod(const methodHandle& method,
11011109
offsets.set_value(CodeOffsets::Exceptions, exception_handler);
11021110
}
11031111

1112+
int mutable_data_size = required_mutable_data_space(code_buffer);
1113+
11041114
// MH intrinsics are dispatch stubs which are compatible with NonNMethod space.
11051115
// IsUnloadingBehaviour::is_unloading needs to handle them separately.
11061116
bool allow_NonNMethod_space = method->can_be_allocated_in_NonNMethod_space();
@@ -1110,7 +1120,7 @@ nmethod* nmethod::new_native_nmethod(const methodHandle& method,
11101120
code_buffer, frame_size,
11111121
basic_lock_owner_sp_offset,
11121122
basic_lock_sp_offset,
1113-
oop_maps);
1123+
oop_maps, mutable_data_size);
11141124
DEBUG_ONLY( if (allow_NonNMethod_space) assert_no_oops_or_metadata(nm); )
11151125
NOT_PRODUCT(if (nm != nullptr) native_nmethod_stats.note_native_nmethod(nm));
11161126
}
@@ -1148,7 +1158,7 @@ nmethod* nmethod::new_nmethod(const methodHandle& method,
11481158
code_buffer->finalize_oop_references(method);
11491159
// create nmethod
11501160
nmethod* nm = nullptr;
1151-
int nmethod_size = CodeBlob::allocation_size(code_buffer, sizeof(nmethod), true);
1161+
int nmethod_size = CodeBlob::allocation_size(code_buffer, sizeof(nmethod));
11521162

11531163
int immutable_data_size =
11541164
adjust_pcs_size(debug_info->pcs_size())
@@ -1170,27 +1180,15 @@ nmethod* nmethod::new_nmethod(const methodHandle& method,
11701180
}
11711181
}
11721182

1173-
int mutable_data_size = align_up(code_buffer->total_relocation_size(), oopSize) +
1174-
+ align_up(code_buffer->total_oop_size(), oopSize) +
1175-
+ align_up(code_buffer->total_metadata_size(), oopSize);
1176-
#if INCLUDE_JVMCI
1177-
mutable_data_size += align_up(compiler->is_jvmci() ? jvmci_data->size() : 0, oopSize);
1178-
#endif
1179-
address mutable_data = nullptr;
1180-
if (mutable_data_size > 0) {
1181-
mutable_data = (address)os::malloc(mutable_data_size, mtCode);
1182-
if (mutable_data == nullptr) {
1183-
vm_exit_out_of_memory(mutable_data_size, OOM_MALLOC_ERROR, "nmethod: no space for mutable data");
1184-
return nullptr;
1185-
}
1186-
}
1183+
int mutable_data_size = required_mutable_data_space(code_buffer
1184+
JVMCI_ONLY(COMMA (compiler->is_jvmci() ? jvmci_data->size() : 0)));
11871185

11881186
{
11891187
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
11901188

11911189
nm = new (nmethod_size, comp_level)
11921190
nmethod(method(), compiler->type(), nmethod_size, immutable_data_size, mutable_data_size,
1193-
compile_id, entry_bci, immutable_data, mutable_data, offsets, orig_pc_offset,
1191+
compile_id, entry_bci, immutable_data, offsets, orig_pc_offset,
11941192
debug_info, dependencies, code_buffer, frame_size, oop_maps,
11951193
handler_table, nul_chk_table, compiler, comp_level
11961194
#if INCLUDE_JVMCI
@@ -1292,9 +1290,10 @@ nmethod::nmethod(
12921290
int frame_size,
12931291
ByteSize basic_lock_owner_sp_offset,
12941292
ByteSize basic_lock_sp_offset,
1295-
OopMapSet* oop_maps )
1293+
OopMapSet* oop_maps,
1294+
int mutable_data_size)
12961295
: CodeBlob("native nmethod", CodeBlobKind::Nmethod, code_buffer, nmethod_size, sizeof(nmethod),
1297-
offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
1296+
offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, mutable_data_size),
12981297
_deoptimization_generation(0),
12991298
_gc_epoch(CodeCache::gc_epoch()),
13001299
_method(method),
@@ -1328,14 +1327,17 @@ nmethod::nmethod(
13281327
_deopt_mh_handler_offset = 0;
13291328
_unwind_handler_offset = 0;
13301329

1331-
CHECKED_CAST(_metadata_offset, uint16_t, (align_up(code_buffer->total_oop_size(), oopSize)));
1332-
int data_end_offset = _metadata_offset + align_up(code_buffer->total_metadata_size(), wordSize);
1330+
int reloc_size = align_up(code_buffer->total_relocation_size(), oopSize);
1331+
int oop_size = align_up(code_buffer->total_oop_size(), oopSize);
1332+
int metadata_size = align_up(code_buffer->total_metadata_size(), wordSize);
1333+
CHECKED_CAST(_metadata_offset, uint16_t, reloc_size + oop_size);
1334+
int data_end_offset = _metadata_offset + metadata_size;
13331335
#if INCLUDE_JVMCI
13341336
// jvmci_data_size is 0 in native wrapper but we need to set offset
13351337
// to correctly calculate metadata_end address
13361338
CHECKED_CAST(_jvmci_data_offset, uint16_t, data_end_offset);
13371339
#endif
1338-
assert((data_offset() + data_end_offset) <= nmethod_size, "wrong nmethod's size: %d < %d", nmethod_size, (data_offset() + data_end_offset));
1340+
assert(data_end_offset <= mutable_data_size, "wrong nmutable_data_size: %d < %d", data_end_offset, mutable_data_size);
13391341

13401342
// native wrapper does not have read-only data but we need unique not null address
13411343
_immutable_data = blob_end();
@@ -1419,7 +1421,6 @@ nmethod::nmethod(
14191421
int compile_id,
14201422
int entry_bci,
14211423
address immutable_data,
1422-
address mutable_data,
14231424
CodeOffsets* offsets,
14241425
int orig_pc_offset,
14251426
DebugInformationRecorder* debug_info,
@@ -1438,7 +1439,7 @@ nmethod::nmethod(
14381439
#endif
14391440
)
14401441
: CodeBlob("nmethod", CodeBlobKind::Nmethod, code_buffer, nmethod_size, sizeof(nmethod),
1441-
offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, true),
1442+
offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, mutable_data_size),
14421443
_deoptimization_generation(0),
14431444
_gc_epoch(CodeCache::gc_epoch()),
14441445
_method(method),
@@ -1514,9 +1515,9 @@ nmethod::nmethod(
15141515
CHECKED_CAST(_jvmci_data_offset, uint16_t, _metadata_offset + metadata_size);
15151516
jvmci_data_size = align_up(compiler->is_jvmci() ? jvmci_data->size() : 0, oopSize);
15161517
#endif
1517-
assert(mutable_data_size == reloc_size + oop_size + metadata_size + jvmci_data_size,
1518+
assert(_mutable_data_size == reloc_size + oop_size + metadata_size + jvmci_data_size,
15181519
"wrong mutable data size: %d != %d + %d + %d + %d",
1519-
mutable_data_size, reloc_size, oop_size, metadata_size, jvmci_data_size);
1520+
_mutable_data_size, reloc_size, oop_size, metadata_size, jvmci_data_size);
15201521
assert(nmethod_size == code_end() - header_begin(), "wrong nmethod size: %d != %d",
15211522
nmethod_size, (int)(code_end() - header_begin()));
15221523

@@ -1528,14 +1529,6 @@ nmethod::nmethod(
15281529
// We need unique not null address
15291530
_immutable_data = blob_end();
15301531
}
1531-
_mutable_data_size = mutable_data_size;
1532-
if (mutable_data_size > 0) {
1533-
assert(mutable_data != nullptr, "required");
1534-
_mutable_data = mutable_data;
1535-
} else {
1536-
// We need unique not null address
1537-
_mutable_data = blob_end();
1538-
}
15391532
CHECKED_CAST(_nul_chk_table_offset, uint16_t, (align_up((int)dependencies->size_in_bytes(), oopSize)));
15401533
CHECKED_CAST(_handler_table_offset, uint16_t, (_nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize)));
15411534
_scopes_pcs_offset = _handler_table_offset + align_up(handler_table->size_in_bytes(), oopSize);

src/hotspot/share/code/nmethod.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ class nmethod : public CodeBlob {
303303
int frame_size,
304304
ByteSize basic_lock_owner_sp_offset, /* synchronized natives only */
305305
ByteSize basic_lock_sp_offset, /* synchronized natives only */
306-
OopMapSet* oop_maps);
306+
OopMapSet* oop_maps,
307+
int mutable_data_size);
307308

308309
// For normal JIT compiled code
309310
nmethod(Method* method,
@@ -314,7 +315,6 @@ class nmethod : public CodeBlob {
314315
int compile_id,
315316
int entry_bci,
316317
address immutable_data,
317-
address mutable_data,
318318
CodeOffsets* offsets,
319319
int orig_pc_offset,
320320
DebugInformationRecorder *recorder,
@@ -526,7 +526,7 @@ class nmethod : public CodeBlob {
526526
address insts_begin () const { return code_begin() ; }
527527
address insts_end () const { return header_begin() + _stub_offset ; }
528528
address stub_begin () const { return header_begin() + _stub_offset ; }
529-
address stub_end () const { return data_begin() ; }
529+
address stub_end () const { return code_end() ; }
530530
address exception_begin () const { return header_begin() + _exception_offset ; }
531531
address deopt_handler_begin () const { return header_begin() + _deopt_handler_offset ; }
532532
address deopt_mh_handler_begin() const { return header_begin() + _deopt_mh_handler_offset ; }

src/hotspot/share/runtime/vmStructs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@
556556
nonstatic_field(CodeBlob, _content_offset, int) \
557557
nonstatic_field(CodeBlob, _code_offset, int) \
558558
nonstatic_field(CodeBlob, _frame_complete_offset, int16_t) \
559-
nonstatic_field(CodeBlob, _data_offset, int) \
559+
nonstatic_field(CodeBlob, _code_end_offset, int) \
560560
nonstatic_field(CodeBlob, _frame_size, int) \
561561
nonstatic_field(CodeBlob, _oop_maps, ImmutableOopMapSet*) \
562562
nonstatic_field(CodeBlob, _caller_must_gc_arguments, bool) \

0 commit comments

Comments
 (0)