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