1 /*
2 * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_CODE_AOTCODECACHE_HPP
26 #define SHARE_CODE_AOTCODECACHE_HPP
27
28 /*
29 * AOT Code Cache collects code from Code Cache and corresponding metadata
30 * during application training run.
31 * In following "production" runs this code and data can be loaded into
32 * Code Cache skipping its generation.
33 */
34
35 class CodeBuffer;
36 class RelocIterator;
37 class AOTCodeCache;
38 class AdapterBlob;
39 class ExceptionBlob;
40 class ImmutableOopMapSet;
41
42 enum class vmIntrinsicID : int;
43 enum CompLevel : signed char;
44
45 // Descriptor of AOT Code Cache's entry
46 class AOTCodeEntry {
47 public:
48 enum Kind {
49 None = 0,
50 Adapter = 1,
51 Blob = 2
52 };
53
54 private:
55 AOTCodeEntry* _next;
56 Kind _kind;
57 uint _id; // Adapter's id, vmIntrinsic::ID for stub or name's hash for nmethod
58 uint _offset; // Offset to entry
59 uint _size; // Entry size
60 uint _name_offset; // Code blob name
61 uint _name_size;
62 uint _blob_offset; // Start of code in cache
63 bool _has_oop_maps;
64 address _dumptime_content_start_addr; // CodeBlob::content_begin() at dump time; used for applying relocations
65
66 public:
67 AOTCodeEntry(Kind kind, uint id,
68 uint offset, uint size,
69 uint name_offset, uint name_size,
70 uint blob_offset, bool has_oop_maps,
71 address dumptime_content_start_addr) {
72 _next = nullptr;
73 _kind = kind;
74 _id = id;
75 _offset = offset;
76 _size = size;
77 _name_offset = name_offset;
78 _name_size = name_size;
79 _blob_offset = blob_offset;
80 _has_oop_maps = has_oop_maps;
81 _dumptime_content_start_addr = dumptime_content_start_addr;
82 }
83 void* operator new(size_t x, AOTCodeCache* cache);
84 // Delete is a NOP
85 void operator delete( void *ptr ) {}
86
87 AOTCodeEntry* next() const { return _next; }
88 void set_next(AOTCodeEntry* next) { _next = next; }
89
90 Kind kind() const { return _kind; }
91 uint id() const { return _id; }
92
93 uint offset() const { return _offset; }
94 void set_offset(uint off) { _offset = off; }
95
96 uint size() const { return _size; }
97 uint name_offset() const { return _name_offset; }
98 uint name_size() const { return _name_size; }
99 uint blob_offset() const { return _blob_offset; }
100 bool has_oop_maps() const { return _has_oop_maps; }
101 address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }
102
103 static bool is_valid_entry_kind(Kind kind) { return kind == Adapter || kind == Blob; }
104 };
105
106 // Addresses of stubs, blobs and runtime finctions called from compiled code.
107 class AOTCodeAddressTable : public CHeapObj<mtCode> {
108 private:
109 address* _extrs_addr;
110 address* _blobs_addr;
111 uint _extrs_length;
112 uint _blobs_length;
113
114 bool _extrs_complete;
115 bool _shared_blobs_complete;
116 bool _complete;
117
118 public:
119 AOTCodeAddressTable() :
120 _extrs_addr(nullptr),
121 _blobs_addr(nullptr),
122 _extrs_length(0),
123 _blobs_length(0),
124 _extrs_complete(false),
125 _shared_blobs_complete(false),
126 _complete(false)
127 { }
128 ~AOTCodeAddressTable();
129 void init_extrs();
130 void init_shared_blobs();
131 const char* add_C_string(const char* str);
132 int id_for_C_string(address str);
133 address address_for_C_string(int idx);
134 int id_for_address(address addr, RelocIterator iter, CodeBlob* code_blob);
135 address address_for_id(int id);
136 };
137
138 class AOTCodeCache : public CHeapObj<mtCode> {
139
140 // Classes used to describe AOT code cache.
141 protected:
142 class Config {
143 uint _compressedOopShift;
144 uint _compressedKlassShift;
145 uint _contendedPaddingWidth;
146 uint _objectAlignment;
147 uint _gc;
148 enum Flags {
149 none = 0,
150 debugVM = 1,
151 compressedOops = 2,
152 compressedClassPointers = 4,
153 useTLAB = 8,
154 systemClassAssertions = 16,
155 userClassAssertions = 32,
156 enableContendedPadding = 64,
157 restrictContendedPadding = 128
158 };
159 uint _flags;
160
161 public:
162 void record();
163 bool verify() const;
164 };
165
166 class Header : public CHeapObj<mtCode> {
167 private:
168 enum {
169 AOT_CODE_VERSION = 1
170 };
171 uint _version; // AOT code version (should match when reading code cache)
172 uint _cache_size; // cache size in bytes
173 uint _strings_count; // number of recorded C strings
174 uint _strings_offset; // offset to recorded C strings
175 uint _entries_count; // number of recorded entries
176 uint _entries_offset; // offset of AOTCodeEntry array describing entries
177 uint _adapters_count;
178 uint _blobs_count;
179 Config _config;
180
181 public:
182 void init(uint cache_size,
183 uint strings_count, uint strings_offset,
184 uint entries_count, uint entries_offset,
185 uint adapters_count, uint blobs_count) {
186 _version = AOT_CODE_VERSION;
187 _cache_size = cache_size;
188 _strings_count = strings_count;
189 _strings_offset = strings_offset;
190 _entries_count = entries_count;
191 _entries_offset = entries_offset;
192 _adapters_count = adapters_count;
193 _blobs_count = blobs_count;
194
195 _config.record();
196 }
197
198
199 uint cache_size() const { return _cache_size; }
200 uint strings_count() const { return _strings_count; }
201 uint strings_offset() const { return _strings_offset; }
202 uint entries_count() const { return _entries_count; }
203 uint entries_offset() const { return _entries_offset; }
204 uint adapters_count() const { return _adapters_count; }
205 uint blobs_count() const { return _blobs_count; }
206
207 bool verify_config(uint load_size) const;
208 bool verify_vm_config() const { // Called after Universe initialized
209 return _config.verify();
210 }
211 };
212
213 // Continue with AOTCodeCache class definition.
214 private:
215 Header* _load_header;
216 char* _load_buffer; // Aligned buffer for loading cached code
217 char* _store_buffer; // Aligned buffer for storing cached code
218 char* _C_store_buffer; // Original unaligned buffer
219
220 uint _write_position; // Position in _store_buffer
221 uint _load_size; // Used when reading cache
222 uint _store_size; // Used when writing cache
223 bool _for_use; // AOT cache is open for using AOT code
224 bool _for_dump; // AOT cache is open for dumping AOT code
225 bool _closing; // Closing cache file
226 bool _failed; // Failed read/write to/from cache (cache is broken?)
227 bool _lookup_failed; // Failed to lookup for info (skip only this code load)
228
229 AOTCodeAddressTable* _table;
230
231 AOTCodeEntry* _load_entries; // Used when reading cache
232 uint* _search_entries; // sorted by ID table [id, index]
233 AOTCodeEntry* _store_entries; // Used when writing cache
234 const char* _C_strings_buf; // Loaded buffer for _C_strings[] table
235 uint _store_entries_cnt;
236
237 static AOTCodeCache* open_for_use();
238 static AOTCodeCache* open_for_dump();
239
240 bool set_write_position(uint pos);
241 bool align_write();
242 address reserve_bytes(uint nbytes);
243 uint write_bytes(const void* buffer, uint nbytes);
244 const char* addr(uint offset) const { return _load_buffer + offset; }
245 static AOTCodeAddressTable* addr_table() {
246 return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
247 }
248
249 void set_lookup_failed() { _lookup_failed = true; }
250 void clear_lookup_failed() { _lookup_failed = false; }
251 bool lookup_failed() const { return _lookup_failed; }
252
253 public:
254 AOTCodeCache(bool is_dumping, bool is_using);
255 ~AOTCodeCache();
256
257 const char* cache_buffer() const { return _load_buffer; }
258 bool failed() const { return _failed; }
259 void set_failed() { _failed = true; }
260
261 static uint max_aot_code_size();
262
263 uint load_size() const { return _load_size; }
264 uint write_position() const { return _write_position; }
265
266 void load_strings();
267 int store_strings();
268
269 static void init_extrs_table() NOT_CDS_RETURN;
270 static void init_shared_blobs_table() NOT_CDS_RETURN;
271
272 address address_for_id(int id) const { return _table->address_for_id(id); }
273
274 bool for_use() const { return _for_use && !_failed; }
275 bool for_dump() const { return _for_dump && !_failed; }
276
277 bool closing() const { return _closing; }
278
279 AOTCodeEntry* add_entry() {
280 _store_entries_cnt++;
281 _store_entries -= 1;
282 return _store_entries;
283 }
284
285 AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id);
286
287 bool finish_write();
288
289 bool write_relocations(CodeBlob& code_blob);
290 bool write_oop_map_set(CodeBlob& cb);
291
292 static bool store_code_blob(CodeBlob& blob,
293 AOTCodeEntry::Kind entry_kind,
294 uint id, const char* name,
295 int entry_offset_count,
296 int* entry_offsets) NOT_CDS_RETURN_(false);
297
298 static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
299 uint id, const char* name,
300 int entry_offset_count,
301 int* entry_offsets) NOT_CDS_RETURN_(nullptr);
302
303 static uint store_entries_cnt() {
304 if (is_on_for_dump()) {
305 return cache()->_store_entries_cnt;
306 }
307 return -1;
308 }
309
310 // Static access
311
312 private:
313 static AOTCodeCache* _cache;
314
315 static bool open_cache(bool is_dumping, bool is_using);
316 static bool verify_vm_config() {
317 if (is_on_for_use()) {
318 return _cache->_load_header->verify_vm_config();
319 }
320 return true;
321 }
322 public:
323 static AOTCodeCache* cache() { return _cache; }
324 static void initialize() NOT_CDS_RETURN;
325 static void init2() NOT_CDS_RETURN;
326 static void close() NOT_CDS_RETURN;
327 static bool is_on() CDS_ONLY({ return _cache != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
328 static bool is_on_for_use() { return is_on() && _cache->for_use(); }
329 static bool is_on_for_dump() { return is_on() && _cache->for_dump(); }
330
331 static bool is_dumping_adapters() NOT_CDS_RETURN_(false);
332 static bool is_using_adapters() NOT_CDS_RETURN_(false);
333
334 static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
335
336 static void print_on(outputStream* st) NOT_CDS_RETURN;
337 };
338
339 // Concurent AOT code reader
340 class AOTCodeReader {
341 private:
342 const AOTCodeCache* _cache;
343 const AOTCodeEntry* _entry;
344 const char* _load_buffer; // Loaded cached code buffer
345 uint _read_position; // Position in _load_buffer
346 uint read_position() const { return _read_position; }
347 void set_read_position(uint pos);
348 const char* addr(uint offset) const { return _load_buffer + offset; }
349
350 bool _lookup_failed; // Failed to lookup for info (skip only this code load)
351 void set_lookup_failed() { _lookup_failed = true; }
352 void clear_lookup_failed() { _lookup_failed = false; }
353 bool lookup_failed() const { return _lookup_failed; }
354
355 AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
356 public:
357 AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry);
358
359 CodeBlob* compile_code_blob(const char* name, int entry_offset_count, int* entry_offsets);
360
361 ImmutableOopMapSet* read_oop_map_set();
362
363 void fix_relocations(CodeBlob* code_blob);
364 };
365 #endif // SHARE_CODE_AOTCODECACH_HPP
|
1 /*
2 * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_CODE_AOTCODECACHE_HPP
26 #define SHARE_CODE_AOTCODECACHE_HPP
27
28 #include "compiler/compilerDefinitions.hpp"
29 #include "memory/allocation.hpp"
30 #include "nmt/memTag.hpp"
31 #include "oops/oopsHierarchy.hpp"
32 #include "utilities/exceptions.hpp"
33
34 /*
35 * AOT Code Cache collects code from Code Cache and corresponding metadata
36 * during application training run.
37 * In following "production" runs this code and data can me loaded into
38 * Code Cache skipping its generation.
39 * Additionaly special compiled code "preload" is generated with class initialization
40 * barriers which can be called on first Java method invocation.
41 */
42
43 class AbstractCompiler;
44 class AOTCodeCache;
45 class ciConstant;
46 class ciEnv;
47 class ciMethod;
48 class CodeBuffer;
49 class CodeBlob;
50 class CodeOffsets;
51 class CompileTask;
52 class DebugInformationRecorder;
53 class Dependencies;
54 class ExceptionTable;
55 class ExceptionHandlerTable;
56 template<typename E>
57 class GrowableArray;
58 class ImmutableOopMapSet;
59 class ImplicitExceptionTable;
60 class JavaThread;
61 class Klass;
62 class methodHandle;
63 class Metadata;
64 class Method;
65 class nmethod;
66 class OopMapSet;
67 class OopRecorder;
68 class outputStream;
69 class RelocIterator;
70 class StubCodeGenerator;
71
72 enum class vmIntrinsicID : int;
73
74 #define DO_AOTCODEENTRY_KIND(Fn) \
75 Fn(None) \
76 Fn(Adapter) \
77 Fn(Stub) \
78 Fn(Blob) \
79 Fn(Code) \
80
81 // Code Cache's entry contain information from CodeBuffer
82 class AOTCodeEntry {
83 public:
84 enum Kind : s1 {
85 #define DECL_KIND_ENUM(kind) kind,
86 DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
87 #undef DECL_KIND_ENUM
88 Kind_count
89 };
90
91 private:
92 AOTCodeEntry* _next;
93 Method* _method;
94 Kind _kind;
95 uint _id; // Adapter's id, vmIntrinsic::ID for stub or name's hash for nmethod
96
97 uint _offset; // Offset to entry
98 uint _size; // Entry size
99 uint _name_offset; // Method's or intrinsic name
100 uint _name_size;
101 uint _code_offset; // Start of code in cache
102 uint _code_size; // Total size of all code sections
103 uint _reloc_offset;// Relocations
104 uint _reloc_size; // Max size of relocations per code section
105 uint _num_inlined_bytecodes;
106
107 uint _comp_level; // compilation level
108 uint _comp_id; // compilation id
109 uint _decompile; // Decompile count for this nmethod
110 bool _has_oop_maps;
111 bool _has_clinit_barriers; // Generated code has class init checks
112 bool _for_preload; // Code can be used for preload
113 bool _loaded; // Code was loaded
114 bool _not_entrant; // Deoptimized
115 bool _load_fail; // Failed to load due to some klass state
116 bool _ignore_decompile; // ignore decompile counter if compilation is done
117 // during "assembly" phase without running application
118 address _dumptime_content_start_addr;
119 public:
120 AOTCodeEntry(uint offset, uint size, uint name_offset, uint name_size,
121 uint code_offset, uint code_size,
122 uint reloc_offset, uint reloc_size,
123 Kind kind, uint id,
124 address dumptime_content_start_addr = nullptr,
125 uint comp_level = 0,
126 uint comp_id = 0, uint decomp = 0,
127 bool has_clinit_barriers = false,
128 bool for_preload = false,
129 bool ignore_decompile = false) {
130 _next = nullptr;
131 _method = nullptr;
132 _kind = kind;
133 _id = id;
134
135 _offset = offset;
136 _size = size;
137 _name_offset = name_offset;
138 _name_size = name_size;
139 _code_offset = code_offset;
140 _code_size = code_size;
141 _reloc_offset = reloc_offset;
142 _reloc_size = reloc_size;
143
144 _dumptime_content_start_addr = dumptime_content_start_addr;
145 _num_inlined_bytecodes = 0;
146
147 _comp_level = comp_level;
148 _comp_id = comp_id;
149 _decompile = decomp;
150 _has_oop_maps = false; // unused here
151 _has_clinit_barriers = has_clinit_barriers;
152 _for_preload = for_preload;
153 _loaded = false;
154 _not_entrant = false;
155 _load_fail = false;
156 _ignore_decompile = ignore_decompile;
157 }
158
159 AOTCodeEntry(Kind kind, uint id,
160 uint offset, uint size,
161 uint name_offset, uint name_size,
162 uint blob_offset, bool has_oop_maps,
163 address dumptime_content_start_addr) {
164 _next = nullptr;
165 _method = nullptr;
166 _kind = kind;
167 _id = id;
168 _offset = offset;
169 _size = size;
170 _name_offset = name_offset;
171 _name_size = name_size;
172 _code_offset = blob_offset;
173 _code_size = 0;
174 _reloc_offset = 0;
175 _reloc_size = 0;
176
177 _dumptime_content_start_addr = dumptime_content_start_addr;
178 _num_inlined_bytecodes = 0;
179
180 _comp_level = 0;
181 _comp_id = 0;
182 _decompile = 0;
183 _has_oop_maps = has_oop_maps;
184 _has_clinit_barriers = false;
185 _for_preload = false;
186 _loaded = false;
187 _not_entrant = false;
188 _load_fail = false;
189 _ignore_decompile = true;
190 }
191
192 void* operator new(size_t x, AOTCodeCache* cache);
193 // Delete is a NOP
194 void operator delete( void *ptr ) {}
195
196 bool is_adapter() { return _kind == Adapter; }
197 bool is_stub() { return _kind == Stub; }
198 bool is_blob() { return _kind == Blob; }
199 bool is_code() { return _kind == Code; }
200
201 AOTCodeEntry* next() const { return _next; }
202 void set_next(AOTCodeEntry* next) { _next = next; }
203
204 Method* method() const { return _method; }
205 void set_method(Method* method) { _method = method; }
206 void update_method_for_writing();
207
208 Kind kind() const { return _kind; }
209 uint id() const { return _id; }
210
211 uint offset() const { return _offset; }
212 void set_offset(uint off) { _offset = off; }
213
214 uint size() const { return _size; }
215 uint name_offset() const { return _name_offset; }
216 uint name_size() const { return _name_size; }
217 uint code_offset() const { return _code_offset; }
218 uint code_size() const { return _code_size; }
219 uint reloc_offset() const { return _reloc_offset; }
220 uint reloc_size() const { return _reloc_size; }
221
222 address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }
223
224 uint num_inlined_bytecodes() const { return _num_inlined_bytecodes; }
225 void set_inlined_bytecodes(int bytes) { _num_inlined_bytecodes = bytes; }
226
227 uint comp_level() const { return _comp_level; }
228 uint comp_id() const { return _comp_id; }
229
230 uint decompile() const { return _decompile; }
231 bool has_clinit_barriers() const { return _has_clinit_barriers; }
232 bool for_preload() const { return _for_preload; }
233 bool is_loaded() const { return _loaded; }
234 void set_loaded() { _loaded = true; }
235 bool ignore_decompile() const { return _ignore_decompile; }
236
237 bool not_entrant() const { return _not_entrant; }
238 void set_not_entrant() { _not_entrant = true; }
239 void set_entrant() { _not_entrant = false; }
240
241 bool load_fail() const { return _load_fail; }
242 void set_load_fail() { _load_fail = true; }
243
244 void print(outputStream* st) const;
245 uint blob_offset() const { return _code_offset; }
246 bool has_oop_maps() const { return _has_oop_maps; }
247
248 static bool is_valid_entry_kind(Kind kind) { return kind == Adapter || kind == Blob; }
249 };
250
251 // Addresses of stubs, blobs and runtime finctions called from compiled code.
252 class AOTCodeAddressTable : public CHeapObj<mtCode> {
253 private:
254 address* _extrs_addr;
255 address* _stubs_addr;
256 address* _blobs_addr;
257 address* _C1_blobs_addr;
258 address* _C2_blobs_addr;
259 uint _extrs_length;
260 uint _stubs_length;
261 uint _blobs_length;
262 uint _C1_blobs_length;
263 uint _C2_blobs_length;
264
265 bool _extrs_complete;
266 bool _early_stubs_complete;
267 bool _shared_blobs_complete;
268 bool _complete;
269 bool _opto_complete;
270 bool _c1_complete;
271
272 public:
273 AOTCodeAddressTable() {
274 _extrs_addr = nullptr;
275 _stubs_addr = nullptr;
276 _blobs_addr = nullptr;
277 _extrs_complete = false;
278 _early_stubs_complete = false;
279 _shared_blobs_complete = false;
280 _complete = false;
281 _opto_complete = false;
282 _c1_complete = false;
283 }
284 ~AOTCodeAddressTable();
285 void init_extrs();
286 void init_early_stubs();
287 void init_shared_blobs();
288 void init_stubs();
289 void init_opto();
290 void init_c1();
291 const char* add_C_string(const char* str);
292 int id_for_C_string(address str);
293 address address_for_C_string(int idx);
294 int id_for_address(address addr, RelocIterator iter, CodeBuffer* buffer, CodeBlob* blob = nullptr);
295 address address_for_id(int id);
296 bool opto_complete() const { return _opto_complete; }
297 bool c1_complete() const { return _c1_complete; }
298 };
299
300 struct AOTCodeSection {
301 public:
302 address _origin_address;
303 uint _size;
304 uint _offset;
305 };
306
307 enum class DataKind: int {
308 No_Data = -1,
309 Null = 0,
310 Klass = 1,
311 Method = 2,
312 String = 3,
313 Primitive = 4, // primitive Class object
314 SysLoader = 5, // java_system_loader
315 PlaLoader = 6, // java_platform_loader
316 MethodCnts= 7,
317 Klass_Shared = 8,
318 Method_Shared = 9,
319 String_Shared = 10,
320 MH_Oop_Shared = 11
321 };
322
323 class AOTCodeCache : public CHeapObj<mtCode> {
324
325 // Classes used to describe AOT code cache.
326 protected:
327 class Config {
328 uint _compressedOopShift;
329 uint _compressedKlassShift;
330 uint _contendedPaddingWidth;
331 uint _objectAlignment;
332 uint _gc;
333 enum Flags {
334 none = 0,
335 metadataPointers = 1,
336 debugVM = 2,
337 compressedOops = 4,
338 compressedClassPointers = 8,
339 useTLAB = 16,
340 systemClassAssertions = 32,
341 userClassAssertions = 64,
342 enableContendedPadding = 128,
343 restrictContendedPadding = 256,
344 };
345 uint _flags;
346
347 public:
348 void record(bool use_meta_ptrs);
349 bool verify() const;
350
351 bool has_meta_ptrs() const { return (_flags & metadataPointers) != 0; }
352 };
353
354 class Header : public CHeapObj<mtCode> {
355 private:
356 // Here should be version and other verification fields
357 enum {
358 AOT_CODE_VERSION = 1
359 };
360 uint _version; // AOT code version (should match when reading code cache)
361 uint _cache_size; // cache size in bytes
362 uint _strings_count; // number of recorded C strings
363 uint _strings_offset; // offset to recorded C strings
364 uint _entries_count; // number of recorded entries in cache
365 uint _entries_offset; // offset of AOTCodeEntry array describing entries
366 uint _preload_entries_count; // entries for pre-loading code
367 uint _preload_entries_offset;
368 uint _adapters_count;
369 uint _blobs_count;
370 uint _stubs_count;
371 Config _config;
372
373 public:
374 void init(uint cache_size,
375 uint strings_count, uint strings_offset,
376 uint entries_count, uint entries_offset,
377 uint preload_entries_count, uint preload_entries_offset,
378 uint adapters_count, uint blobs_count, uint stubs_count,
379 bool use_meta_ptrs) {
380 _version = AOT_CODE_VERSION;
381 _cache_size = cache_size;
382 _strings_count = strings_count;
383 _strings_offset = strings_offset;
384 _entries_count = entries_count;
385 _entries_offset = entries_offset;
386 _preload_entries_count = preload_entries_count;
387 _preload_entries_offset = preload_entries_offset;
388 _adapters_count = adapters_count;
389 _blobs_count = blobs_count;
390 _stubs_count = stubs_count;
391
392 _config.record(use_meta_ptrs);
393 }
394
395 uint cache_size() const { return _cache_size; }
396 uint strings_count() const { return _strings_count; }
397 uint strings_offset() const { return _strings_offset; }
398 uint entries_count() const { return _entries_count; }
399 uint entries_offset() const { return _entries_offset; }
400 uint preload_entries_count() const { return _preload_entries_count; }
401 uint preload_entries_offset() const { return _preload_entries_offset; }
402 uint adapters_count() const { return _adapters_count; }
403 uint blobs_count() const { return _blobs_count; }
404 uint stubs_count() const { return _stubs_count; }
405 uint nmethods_count() const { return _entries_count - _stubs_count - _blobs_count - _adapters_count; }
406 bool has_meta_ptrs() const { return _config.has_meta_ptrs(); }
407
408 bool verify_config(uint load_size) const;
409 bool verify_vm_config() const { // Called after Universe initialized
410 return _config.verify();
411 }
412 };
413
414 // Continue with AOTCodeCache class definition.
415 private:
416 Header* _load_header;
417 char* _load_buffer; // Aligned buffer for loading cached code
418 char* _store_buffer; // Aligned buffer for storing cached code
419 char* _C_store_buffer; // Original unaligned buffer
420
421 uint _write_position; // Position in _store_buffer
422 uint _load_size; // Used when reading cache
423 uint _store_size; // Used when writing cache
424 bool _for_use; // AOT cache is open for using AOT code
425 bool _for_dump; // AOT cache is open for dumping AOT code
426 bool _closing; // Closing cache file
427 bool _failed; // Failed read/write to/from cache (cache is broken?)
428 bool _lookup_failed; // Failed to lookup for info (skip only this code load)
429
430 bool _for_preload; // Code for preload
431 bool _gen_preload_code; // Generate pre-loading code
432 bool _has_clinit_barriers; // Code with clinit barriers
433
434 bool _use_meta_ptrs; // Store metadata pointers
435
436 AOTCodeAddressTable* _table;
437
438 AOTCodeEntry* _load_entries; // Used when reading cache
439 uint* _search_entries; // sorted by ID table [id, index]
440 AOTCodeEntry* _store_entries; // Used when writing cache
441 const char* _C_strings_buf; // Loaded buffer for _C_strings[] table
442 uint _store_entries_cnt;
443
444 uint _compile_id;
445 uint _comp_level;
446 uint compile_id() const { return _compile_id; }
447 uint comp_level() const { return _comp_level; }
448
449 static AOTCodeCache* open_for_use();
450 static AOTCodeCache* open_for_dump();
451
452 bool set_write_position(uint pos);
453 bool align_write();
454
455 address reserve_bytes(uint nbytes);
456 uint write_bytes(const void* buffer, uint nbytes);
457 const char* addr(uint offset) const { return _load_buffer + offset; }
458 static AOTCodeAddressTable* addr_table() {
459 return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
460 }
461
462 void set_lookup_failed() { _lookup_failed = true; }
463 void clear_lookup_failed() { _lookup_failed = false; }
464 bool lookup_failed() const { return _lookup_failed; }
465
466 AOTCodeEntry* write_nmethod(nmethod* nm, bool for_preload);
467
468 // States:
469 // S >= 0: allow new readers, S readers are currently active
470 // S < 0: no new readers are allowed; (-S-1) readers are currently active
471 // (special case: S = -1 means no readers are active, and would never be active again)
472 static volatile int _nmethod_readers;
473
474 static void wait_for_no_nmethod_readers();
475
476 class ReadingMark {
477 private:
478 bool _failed;
479 public:
480 ReadingMark();
481 ~ReadingMark();
482 bool failed() {
483 return _failed;
484 }
485 };
486
487 public:
488 AOTCodeCache(bool is_dumping, bool is_using);
489 ~AOTCodeCache();
490
491 const char* cache_buffer() const { return _load_buffer; }
492 bool failed() const { return _failed; }
493 void set_failed() { _failed = true; }
494
495 static bool is_address_in_aot_cache(address p) NOT_CDS_RETURN_(false);
496 static uint max_aot_code_size();
497
498 uint load_size() const { return _load_size; }
499 uint write_position() const { return _write_position; }
500
501 void load_strings();
502 int store_strings();
503
504 static void init_extrs_table() NOT_CDS_RETURN;
505 static void init_early_stubs_table() NOT_CDS_RETURN;
506 static void init_shared_blobs_table() NOT_CDS_RETURN;
507 static void init_stubs_table() NOT_CDS_RETURN;
508 static void init_opto_table() NOT_CDS_RETURN;
509 static void init_c1_table() NOT_CDS_RETURN;
510
511 address address_for_id(int id) const { return _table->address_for_id(id); }
512
513 bool for_use() const { return _for_use && !_failed; }
514 bool for_dump() const { return _for_dump && !_failed; }
515
516 bool closing() const { return _closing; }
517 bool use_meta_ptrs() const { return _use_meta_ptrs; }
518 bool gen_preload_code() const { return _gen_preload_code; }
519
520 AOTCodeEntry* add_entry() {
521 _store_entries_cnt++;
522 _store_entries -= 1;
523 return _store_entries;
524 }
525 void preload_startup_code(TRAPS);
526
527 AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id, uint comp_level = 0, uint decomp = 0);
528 void invalidate_entry(AOTCodeEntry* entry);
529
530 bool finish_write();
531
532 void log_stats_on_exit();
533
534 static bool load_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
535 static bool store_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
536
537 bool write_klass(Klass* klass);
538 bool write_method(Method* method);
539
540 bool write_relocations(CodeBlob& code_blob);
541 bool write_debug_info(DebugInformationRecorder* recorder);
542
543 bool write_oop_map_set(CodeBlob& cb);
544 bool write_nmethod_reloc_immediates(GrowableArray<Handle>& oop_list, GrowableArray<Metadata*>& metadata_list);
545 bool write_nmethod_loadtime_relocations(JavaThread* thread, nmethod* nm, GrowableArray<Handle>& oop_list, GrowableArray<Metadata*>& metadata_list);
546
547 jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
548 Metadata* read_metadata(const methodHandle& comp_method);
549 bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
550 bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
551
552 bool write_oop(jobject& jo);
553 bool write_oop(oop obj);
554 bool write_oops(OopRecorder* oop_recorder);
555 bool write_metadata(Metadata* m);
556 bool write_metadata(OopRecorder* oop_recorder);
557 bool write_oops(nmethod* nm);
558 bool write_metadata(nmethod* nm);
559
560 static bool store_code_blob(CodeBlob& blob,
561 AOTCodeEntry::Kind entry_kind,
562 uint id, const char* name,
563 int entry_offset_count = 0,
564 int* entry_offsets = nullptr) NOT_CDS_RETURN_(false);
565
566 static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
567 uint id, const char* name,
568 int entry_offset_count = 0,
569 int* entry_offsets = nullptr) NOT_CDS_RETURN_(nullptr);
570
571 static bool load_nmethod(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler, CompLevel comp_level) NOT_CDS_RETURN_(false);
572 static AOTCodeEntry* store_nmethod(nmethod* nm, AbstractCompiler* compiler, bool for_preload) NOT_CDS_RETURN_(nullptr);
573
574 static uint store_entries_cnt() {
575 if (is_on_for_dump()) {
576 return cache()->_store_entries_cnt;
577 }
578 return -1;
579 }
580
581 // Static access
582
583 private:
584 static AOTCodeCache* _cache;
585
586 static bool open_cache(bool is_dumping, bool is_using);
587 static bool verify_vm_config() {
588 if (is_on_for_use()) {
589 return _cache->_load_header->verify_vm_config();
590 }
591 return true;
592 }
593 public:
594 static AOTCodeCache* cache() { return _cache; }
595 static void initialize() NOT_CDS_RETURN;
596 static void init2() NOT_CDS_RETURN;
597 static void close() NOT_CDS_RETURN;
598 static bool is_on() CDS_ONLY({ return _cache != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
599 static bool is_C3_on() NOT_CDS_RETURN_(false);
600 static bool is_code_load_thread_on() NOT_CDS_RETURN_(false);
601 static bool is_on_for_use() CDS_ONLY({ return is_on() && _cache->for_use(); }) NOT_CDS_RETURN_(false);
602 static bool is_on_for_dump() CDS_ONLY({ return is_on() && _cache->for_dump(); }) NOT_CDS_RETURN_(false);
603 static bool is_dumping_code() NOT_CDS_RETURN_(false);
604 static bool is_dumping_stub() NOT_CDS_RETURN_(false);
605 static bool is_dumping_adapter() NOT_CDS_RETURN_(false);
606 static bool is_using_code() NOT_CDS_RETURN_(false);
607 static bool is_using_stub() NOT_CDS_RETURN_(false);
608 static bool is_using_adapter() NOT_CDS_RETURN_(false);
609 static void enable_caching() NOT_CDS_RETURN;
610 static void disable_caching() NOT_CDS_RETURN;
611 static bool is_caching_enabled() NOT_CDS_RETURN_(false);
612
613 static bool gen_preload_code(ciMethod* m, int entry_bci) NOT_CDS_RETURN_(false);
614 static bool allow_const_field(ciConstant& value) NOT_CDS_RETURN_(false);
615 static void invalidate(AOTCodeEntry* entry) NOT_CDS_RETURN;
616 static bool is_loaded(AOTCodeEntry* entry);
617 static AOTCodeEntry* find_code_entry(const methodHandle& method, uint comp_level);
618 static void preload_code(JavaThread* thread) NOT_CDS_RETURN;
619
620 template<typename Function>
621 static void iterate(Function function) { // lambda enabled API
622 AOTCodeCache* cache = open_for_use();
623 if (cache != nullptr) {
624 ReadingMark rdmk;
625 if (rdmk.failed()) {
626 // Cache is closed, cannot touch anything.
627 return;
628 }
629
630 uint count = cache->_load_header->entries_count();
631 uint* search_entries = (uint*)cache->addr(cache->_load_header->entries_offset()); // [id, index]
632 AOTCodeEntry* load_entries = (AOTCodeEntry*)(search_entries + 2 * count);
633
634 for (uint i = 0; i < count; i++) {
635 int index = search_entries[2*i + 1];
636 AOTCodeEntry* entry = &(load_entries[index]);
637 function(entry);
638 }
639 }
640 }
641
642 static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
643
644 static void print_on(outputStream* st) NOT_CDS_RETURN;
645 static void print_statistics_on(outputStream* st) NOT_CDS_RETURN;
646 static void print_timers_on(outputStream* st) NOT_CDS_RETURN;
647 static void print_unused_entries_on(outputStream* st) NOT_CDS_RETURN;
648 };
649
650 // Concurent AOT code reader
651 class AOTCodeReader {
652 private:
653 const AOTCodeCache* _cache;
654 const AOTCodeEntry* _entry;
655 const char* _load_buffer; // Loaded cached code buffer
656 uint _read_position; // Position in _load_buffer
657 uint read_position() const { return _read_position; }
658 void set_read_position(uint pos);
659 const char* addr(uint offset) const { return _load_buffer + offset; }
660
661 uint _compile_id;
662 uint _comp_level;
663 uint compile_id() const { return _compile_id; }
664 uint comp_level() const { return _comp_level; }
665
666 bool _preload; // Preloading code before method execution
667 bool _lookup_failed; // Failed to lookup for info (skip only this code load)
668 void set_lookup_failed() { _lookup_failed = true; }
669 void clear_lookup_failed() { _lookup_failed = false; }
670 bool lookup_failed() const { return _lookup_failed; }
671
672 public:
673 AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry, CompileTask* task);
674
675 AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
676
677 // convenience method to convert offset in AOTCodeEntry data to its address
678 bool compile_nmethod(ciEnv* env, ciMethod* target, AbstractCompiler* compiler);
679 bool compile_blob(CodeBuffer* buffer, int* pc_offset);
680
681 CodeBlob* compile_code_blob(const char* name, int entry_offset_count, int* entry_offsets);
682
683 Klass* read_klass(const methodHandle& comp_method, bool shared);
684 Method* read_method(const methodHandle& comp_method, bool shared);
685
686 DebugInformationRecorder* read_debug_info(OopRecorder* oop_recorder);
687
688 oop read_oop(JavaThread* thread, const methodHandle& comp_method);
689 Metadata* read_metadata(const methodHandle& comp_method);
690 bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
691 bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
692
693 bool read_oop_metadata_list(JavaThread* thread, ciMethod* target, GrowableArray<Handle> &oop_list, GrowableArray<Metadata*> &metadata_list, OopRecorder* oop_recorder);
694 void apply_relocations(nmethod* nm, GrowableArray<Handle> &oop_list, GrowableArray<Metadata*> &metadata_list) NOT_CDS_RETURN;
695
696 ImmutableOopMapSet* read_oop_map_set();
697
698 void fix_relocations(CodeBlob* code_blob);
699
700 void print_on(outputStream* st);
701 };
702
703 // +1 for preload code
704 const int AOTCompLevel_count = CompLevel_count + 1; // 6 levels indexed from 0 to 5
705
706 struct AOTCodeStats {
707 private:
708 struct {
709 uint _kind_cnt[AOTCodeEntry::Kind_count];
710 uint _nmethod_cnt[AOTCompLevel_count];
711 uint _clinit_barriers_cnt;
712 } ccstats; // ccstats = cached code stats
713
714 void check_kind(uint kind) { assert(kind >= AOTCodeEntry::None && kind < AOTCodeEntry::Kind_count, "Invalid AOTCodeEntry kind %d", kind); }
715 void check_complevel(uint lvl) { assert(lvl >= CompLevel_none && lvl < AOTCompLevel_count, "Invalid compilation level %d", lvl); }
716
717 public:
718 void inc_entry_cnt(uint kind) { check_kind(kind); ccstats._kind_cnt[kind] += 1; }
719 void inc_nmethod_cnt(uint lvl) { check_complevel(lvl); ccstats._nmethod_cnt[lvl] += 1; }
720 void inc_preload_cnt() { ccstats._nmethod_cnt[AOTCompLevel_count-1] += 1; }
721 void inc_clinit_barriers_cnt() { ccstats._clinit_barriers_cnt += 1; }
722
723 void collect_entry_stats(AOTCodeEntry* entry) {
724 inc_entry_cnt(entry->kind());
725 if (entry->is_code()) {
726 entry->for_preload() ? inc_nmethod_cnt(AOTCompLevel_count-1)
727 : inc_nmethod_cnt(entry->comp_level());
728 if (entry->has_clinit_barriers()) {
729 inc_clinit_barriers_cnt();
730 }
731 }
732 }
733
734 uint entry_count(uint kind) { check_kind(kind); return ccstats._kind_cnt[kind]; }
735 uint nmethod_count(uint lvl) { check_complevel(lvl); return ccstats._nmethod_cnt[lvl]; }
736 uint preload_count() { return ccstats._nmethod_cnt[AOTCompLevel_count-1]; }
737 uint clinit_barriers_count() { return ccstats._clinit_barriers_cnt; }
738
739 uint total_count() {
740 uint total = 0;
741 for (int kind = AOTCodeEntry::None; kind < AOTCodeEntry::Kind_count; kind++) {
742 total += ccstats._kind_cnt[kind];
743 }
744 return total;
745 }
746
747 static AOTCodeStats add_aot_code_stats(AOTCodeStats stats1, AOTCodeStats stats2);
748
749 // Runtime stats of the AOT code
750 private:
751 struct {
752 struct {
753 uint _loaded_cnt;
754 uint _invalidated_cnt;
755 uint _load_failed_cnt;
756 } _entry_kinds[AOTCodeEntry::Kind_count],
757 _nmethods[AOTCompLevel_count];
758 } rs; // rs = runtime stats
759
760 public:
761 void inc_entry_loaded_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._loaded_cnt += 1; }
762 void inc_entry_invalidated_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._invalidated_cnt += 1; }
763 void inc_entry_load_failed_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._load_failed_cnt += 1; }
764
765 void inc_nmethod_loaded_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._loaded_cnt += 1; }
766 void inc_nmethod_invalidated_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._invalidated_cnt += 1; }
767 void inc_nmethod_load_failed_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._load_failed_cnt += 1; }
768
769 uint entry_loaded_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._loaded_cnt; }
770 uint entry_invalidated_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._invalidated_cnt; }
771 uint entry_load_failed_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._load_failed_cnt; }
772
773 uint nmethod_loaded_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._loaded_cnt; }
774 uint nmethod_invalidated_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._invalidated_cnt; }
775 uint nmethod_load_failed_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._load_failed_cnt; }
776
777 void inc_loaded_cnt(AOTCodeEntry* entry) {
778 inc_entry_loaded_cnt(entry->kind());
779 if (entry->is_code()) {
780 entry->for_preload() ? inc_nmethod_loaded_cnt(AOTCompLevel_count-1)
781 : inc_nmethod_loaded_cnt(entry->comp_level());
782 }
783 }
784
785 void inc_invalidated_cnt(AOTCodeEntry* entry) {
786 inc_entry_invalidated_cnt(entry->kind());
787 if (entry->is_code()) {
788 entry->for_preload() ? inc_nmethod_invalidated_cnt(AOTCompLevel_count-1)
789 : inc_nmethod_invalidated_cnt(entry->comp_level());
790 }
791 }
792
793 void inc_load_failed_cnt(AOTCodeEntry* entry) {
794 inc_entry_load_failed_cnt(entry->kind());
795 if (entry->is_code()) {
796 entry->for_preload() ? inc_nmethod_load_failed_cnt(AOTCompLevel_count-1)
797 : inc_nmethod_load_failed_cnt(entry->comp_level());
798 }
799 }
800
801 void collect_entry_runtime_stats(AOTCodeEntry* entry) {
802 if (entry->is_loaded()) {
803 inc_loaded_cnt(entry);
804 }
805 if (entry->not_entrant()) {
806 inc_invalidated_cnt(entry);
807 }
808 if (entry->load_fail()) {
809 inc_load_failed_cnt(entry);
810 }
811 }
812
813 void collect_all_stats(AOTCodeEntry* entry) {
814 collect_entry_stats(entry);
815 collect_entry_runtime_stats(entry);
816 }
817
818 AOTCodeStats() {
819 memset(this, 0, sizeof(AOTCodeStats));
820 }
821 };
822
823 // code cache internal runtime constants area used by AOT code
824 class AOTRuntimeConstants {
825 friend class AOTCodeCache;
826 private:
827 uint _grain_shift;
828 uint _card_shift;
829 static address _field_addresses_list[];
830 static AOTRuntimeConstants _aot_runtime_constants;
831 // private constructor for unique singleton
832 AOTRuntimeConstants() { }
833 // private for use by friend class AOTCodeCache
834 static void initialize_from_runtime();
835 public:
836 #if INCLUDE_CDS
837 static bool contains(address adr) {
838 address base = (address)&_aot_runtime_constants;
839 address hi = base + sizeof(AOTRuntimeConstants);
840 return (base <= adr && adr < hi);
841 }
842 static address grain_shift_address() { return (address)&_aot_runtime_constants._grain_shift; }
843 static address card_shift_address() { return (address)&_aot_runtime_constants._card_shift; }
844 static address* field_addresses_list() {
845 return _field_addresses_list;
846 }
847 #else
848 static bool contains(address adr) { return false; }
849 static address grain_shift_address() { return nullptr; }
850 static address card_shift_address() { return nullptr; }
851 static address* field_addresses_list() { return nullptr; }
852 #endif
853 };
854
855 #endif // SHARE_CODE_AOTCODECACHE_HPP
|