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