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