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