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