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