1 /* 2 * Copyright (c) 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 #include "cds/aotCacheAccess.hpp" 26 #include "cds/cds_globals.hpp" 27 #include "cds/cdsConfig.hpp" 28 #include "cds/heapShared.hpp" 29 #include "cds/metaspaceShared.hpp" 30 #include "classfile/javaAssertions.hpp" 31 #include "code/aotCodeCache.hpp" 32 #include "code/codeCache.hpp" 33 #include "gc/shared/gcConfig.hpp" 34 #include "logging/logStream.hpp" 35 #include "memory/memoryReserver.hpp" 36 #include "runtime/flags/flagSetting.hpp" 37 #include "runtime/globals_extension.hpp" 38 #include "runtime/java.hpp" 39 #include "runtime/mutexLocker.hpp" 40 #include "runtime/os.inline.hpp" 41 #include "runtime/sharedRuntime.hpp" 42 #include "runtime/stubRoutines.hpp" 43 #ifdef COMPILER2 44 #include "opto/runtime.hpp" 45 #endif 46 #if INCLUDE_G1GC 47 #include "gc/g1/g1BarrierSetRuntime.hpp" 48 #endif 49 #if INCLUDE_ZGC 50 #include "gc/z/zBarrierSetRuntime.hpp" 51 #endif 52 53 #include <sys/stat.h> 54 #include <errno.h> 55 56 static void report_load_failure() { 57 if (AbortVMOnAOTCodeFailure) { 58 vm_exit_during_initialization("Unable to use AOT Code Cache.", nullptr); 59 } 60 log_info(aot, codecache, init)("Unable to use AOT Code Cache."); 61 AOTAdapterCaching = false; 62 } 63 64 static void report_store_failure() { 65 if (AbortVMOnAOTCodeFailure) { 66 tty->print_cr("Unable to create AOT Code Cache."); 67 vm_abort(false); 68 } 69 log_info(aot, codecache, exit)("Unable to create AOT Code Cache."); 70 AOTAdapterCaching = false; 71 } 72 73 bool AOTCodeCache::is_dumping_adapters() { 74 return AOTAdapterCaching && is_on_for_dump(); 75 } 76 77 bool AOTCodeCache::is_using_adapters() { 78 return AOTAdapterCaching && is_on_for_use(); 79 } 80 81 static uint _max_aot_code_size = 0; 82 uint AOTCodeCache::max_aot_code_size() { 83 return _max_aot_code_size; 84 } 85 86 void AOTCodeCache::initialize() { 87 if (FLAG_IS_DEFAULT(AOTCache)) { 88 log_info(aot, codecache, init)("AOT Code Cache is not used: AOTCache is not specified."); 89 return; // AOTCache must be specified to dump and use AOT code 90 } 91 92 bool is_dumping = false; 93 bool is_using = false; 94 if (CDSConfig::is_dumping_final_static_archive() && CDSConfig::is_dumping_aot_linked_classes()) { 95 FLAG_SET_ERGO_IF_DEFAULT(AOTAdapterCaching, true); 96 is_dumping = true; 97 } else if (CDSConfig::is_using_archive() && CDSConfig::is_using_aot_linked_classes()) { 98 FLAG_SET_ERGO_IF_DEFAULT(AOTAdapterCaching, true); 99 is_using = true; 100 } else { 101 log_info(aot, codecache, init)("AOT Code Cache is not used: AOT Class Linking is not used."); 102 return; // nothing to do 103 } 104 if (!AOTAdapterCaching) { 105 return; // AOT code caching disabled on command line 106 } 107 _max_aot_code_size = AOTCodeMaxSize; 108 if (!FLAG_IS_DEFAULT(AOTCodeMaxSize)) { 109 if (!is_aligned(AOTCodeMaxSize, os::vm_allocation_granularity())) { 110 _max_aot_code_size = align_up(AOTCodeMaxSize, os::vm_allocation_granularity()); 111 log_debug(aot,codecache,init)("Max AOT Code Cache size is aligned up to %uK", (int)(max_aot_code_size()/K)); 112 } 113 } 114 size_t aot_code_size = is_using ? AOTCacheAccess::get_aot_code_region_size() : 0; 115 if (is_using && aot_code_size == 0) { 116 log_info(aot, codecache, init)("AOT Code Cache is empty"); 117 return; 118 } 119 if (!open_cache(is_dumping, is_using)) { 120 if (is_using) { 121 report_load_failure(); 122 } else { 123 report_store_failure(); 124 } 125 return; 126 } 127 if (is_dumping) { 128 FLAG_SET_DEFAULT(ForceUnreachable, true); 129 } 130 FLAG_SET_DEFAULT(DelayCompilerStubsGeneration, false); 131 } 132 133 void AOTCodeCache::init2() { 134 if (!is_on()) { 135 return; 136 } 137 if (!verify_vm_config()) { 138 close(); 139 report_load_failure(); 140 } 141 // initialize the table of external routines so we can save 142 // generated code blobs that reference them 143 init_extrs_table(); 144 } 145 146 AOTCodeCache* AOTCodeCache::_cache = nullptr; 147 148 bool AOTCodeCache::open_cache(bool is_dumping, bool is_using) { 149 AOTCodeCache* cache = new AOTCodeCache(is_dumping, is_using); 150 if (cache->failed()) { 151 delete cache; 152 _cache = nullptr; 153 return false; 154 } 155 _cache = cache; 156 return true; 157 } 158 159 void AOTCodeCache::close() { 160 if (is_on()) { 161 delete _cache; // Free memory 162 _cache = nullptr; 163 } 164 } 165 166 #define DATA_ALIGNMENT HeapWordSize 167 168 AOTCodeCache::AOTCodeCache(bool is_dumping, bool is_using) : 169 _load_header(nullptr), 170 _load_buffer(nullptr), 171 _store_buffer(nullptr), 172 _C_store_buffer(nullptr), 173 _write_position(0), 174 _load_size(0), 175 _store_size(0), 176 _for_use(is_using), 177 _for_dump(is_dumping), 178 _closing(false), 179 _failed(false), 180 _lookup_failed(false), 181 _table(nullptr), 182 _load_entries(nullptr), 183 _search_entries(nullptr), 184 _store_entries(nullptr), 185 _C_strings_buf(nullptr), 186 _store_entries_cnt(0) 187 { 188 // Read header at the begining of cache 189 if (_for_use) { 190 // Read cache 191 size_t load_size = AOTCacheAccess::get_aot_code_region_size(); 192 ReservedSpace rs = MemoryReserver::reserve(load_size, mtCode); 193 if (!rs.is_reserved()) { 194 log_warning(aot, codecache, init)("Failed to reserved %u bytes of memory for mapping AOT code region into AOT Code Cache", (uint)load_size); 195 set_failed(); 196 return; 197 } 198 if (!AOTCacheAccess::map_aot_code_region(rs)) { 199 log_warning(aot, codecache, init)("Failed to read/mmap cached code region into AOT Code Cache"); 200 set_failed(); 201 return; 202 } 203 204 _load_size = (uint)load_size; 205 _load_buffer = (char*)rs.base(); 206 assert(is_aligned(_load_buffer, DATA_ALIGNMENT), "load_buffer is not aligned"); 207 log_debug(aot, codecache, init)("Mapped %u bytes at address " INTPTR_FORMAT " at AOT Code Cache", _load_size, p2i(_load_buffer)); 208 209 _load_header = (Header*)addr(0); 210 if (!_load_header->verify_config(_load_size)) { 211 set_failed(); 212 return; 213 } 214 log_info (aot, codecache, init)("Loaded %u AOT code entries from AOT Code Cache", _load_header->entries_count()); 215 log_debug(aot, codecache, init)(" Adapters: total=%u", _load_header->adapters_count()); 216 log_debug(aot, codecache, init)(" All Blobs: total=%u", _load_header->blobs_count()); 217 log_debug(aot, codecache, init)(" AOT code cache size: %u bytes", _load_header->cache_size()); 218 219 // Read strings 220 load_strings(); 221 } 222 if (_for_dump) { 223 _C_store_buffer = NEW_C_HEAP_ARRAY(char, max_aot_code_size() + DATA_ALIGNMENT, mtCode); 224 _store_buffer = align_up(_C_store_buffer, DATA_ALIGNMENT); 225 // Entries allocated at the end of buffer in reverse (as on stack). 226 _store_entries = (AOTCodeEntry*)align_up(_C_store_buffer + max_aot_code_size(), DATA_ALIGNMENT); 227 log_debug(aot, codecache, init)("Allocated store buffer at address " INTPTR_FORMAT " of size %u", p2i(_store_buffer), max_aot_code_size()); 228 } 229 _table = new AOTCodeAddressTable(); 230 } 231 232 void AOTCodeCache::init_extrs_table() { 233 AOTCodeAddressTable* table = addr_table(); 234 if (table != nullptr) { 235 table->init_extrs(); 236 } 237 } 238 239 void AOTCodeCache::init_shared_blobs_table() { 240 AOTCodeAddressTable* table = addr_table(); 241 if (table != nullptr) { 242 table->init_shared_blobs(); 243 } 244 } 245 246 AOTCodeCache::~AOTCodeCache() { 247 if (_closing) { 248 return; // Already closed 249 } 250 // Stop any further access to cache. 251 _closing = true; 252 253 MutexLocker ml(Compile_lock); 254 if (for_dump()) { // Finalize cache 255 finish_write(); 256 } 257 _load_buffer = nullptr; 258 if (_C_store_buffer != nullptr) { 259 FREE_C_HEAP_ARRAY(char, _C_store_buffer); 260 _C_store_buffer = nullptr; 261 _store_buffer = nullptr; 262 } 263 if (_table != nullptr) { 264 delete _table; 265 _table = nullptr; 266 } 267 } 268 269 void AOTCodeCache::Config::record() { 270 _flags = 0; 271 #ifdef ASSERT 272 _flags |= debugVM; 273 #endif 274 if (UseCompressedOops) { 275 _flags |= compressedOops; 276 } 277 if (UseCompressedClassPointers) { 278 _flags |= compressedClassPointers; 279 } 280 if (UseTLAB) { 281 _flags |= useTLAB; 282 } 283 if (JavaAssertions::systemClassDefault()) { 284 _flags |= systemClassAssertions; 285 } 286 if (JavaAssertions::userClassDefault()) { 287 _flags |= userClassAssertions; 288 } 289 if (EnableContended) { 290 _flags |= enableContendedPadding; 291 } 292 if (RestrictContended) { 293 _flags |= restrictContendedPadding; 294 } 295 _compressedOopShift = CompressedOops::shift(); 296 _compressedKlassShift = CompressedKlassPointers::shift(); 297 _contendedPaddingWidth = ContendedPaddingWidth; 298 _objectAlignment = ObjectAlignmentInBytes; 299 _gc = (uint)Universe::heap()->kind(); 300 } 301 302 bool AOTCodeCache::Config::verify() const { 303 #ifdef ASSERT 304 if ((_flags & debugVM) == 0) { 305 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created by product VM, it can't be used by debug VM"); 306 return false; 307 } 308 #else 309 if ((_flags & debugVM) != 0) { 310 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created by debug VM, it can't be used by product VM"); 311 return false; 312 } 313 #endif 314 315 CollectedHeap::Name aot_gc = (CollectedHeap::Name)_gc; 316 if (aot_gc != Universe::heap()->kind()) { 317 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with different GC: %s vs current %s", GCConfig::hs_err_name(aot_gc), GCConfig::hs_err_name()); 318 return false; 319 } 320 321 if (((_flags & compressedOops) != 0) != UseCompressedOops) { 322 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with UseCompressedOops = %s", UseCompressedOops ? "false" : "true"); 323 return false; 324 } 325 if (((_flags & compressedClassPointers) != 0) != UseCompressedClassPointers) { 326 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with UseCompressedClassPointers = %s", UseCompressedClassPointers ? "false" : "true"); 327 return false; 328 } 329 330 if (((_flags & systemClassAssertions) != 0) != JavaAssertions::systemClassDefault()) { 331 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with JavaAssertions::systemClassDefault() = %s", JavaAssertions::systemClassDefault() ? "disabled" : "enabled"); 332 return false; 333 } 334 if (((_flags & userClassAssertions) != 0) != JavaAssertions::userClassDefault()) { 335 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with JavaAssertions::userClassDefault() = %s", JavaAssertions::userClassDefault() ? "disabled" : "enabled"); 336 return false; 337 } 338 339 if (((_flags & enableContendedPadding) != 0) != EnableContended) { 340 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with EnableContended = %s", EnableContended ? "false" : "true"); 341 return false; 342 } 343 if (((_flags & restrictContendedPadding) != 0) != RestrictContended) { 344 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with RestrictContended = %s", RestrictContended ? "false" : "true"); 345 return false; 346 } 347 if (_compressedOopShift != (uint)CompressedOops::shift()) { 348 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with CompressedOops::shift() = %d vs current %d", _compressedOopShift, CompressedOops::shift()); 349 return false; 350 } 351 if (_compressedKlassShift != (uint)CompressedKlassPointers::shift()) { 352 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with CompressedKlassPointers::shift() = %d vs current %d", _compressedKlassShift, CompressedKlassPointers::shift()); 353 return false; 354 } 355 if (_contendedPaddingWidth != (uint)ContendedPaddingWidth) { 356 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with ContendedPaddingWidth = %d vs current %d", _contendedPaddingWidth, ContendedPaddingWidth); 357 return false; 358 } 359 if (_objectAlignment != (uint)ObjectAlignmentInBytes) { 360 log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with ObjectAlignmentInBytes = %d vs current %d", _objectAlignment, ObjectAlignmentInBytes); 361 return false; 362 } 363 return true; 364 } 365 366 bool AOTCodeCache::Header::verify_config(uint load_size) const { 367 if (_version != AOT_CODE_VERSION) { 368 log_debug(aot, codecache, init)("AOT Code Cache disabled: different AOT Code version %d vs %d recorded in AOT Code header", AOT_CODE_VERSION, _version); 369 return false; 370 } 371 if (load_size < _cache_size) { 372 log_debug(aot, codecache, init)("AOT Code Cache disabled: AOT Code Cache size %d < %d recorded in AOT Code header", load_size, _cache_size); 373 return false; 374 } 375 return true; 376 } 377 378 AOTCodeCache* AOTCodeCache::open_for_use() { 379 if (AOTCodeCache::is_on_for_use()) { 380 return AOTCodeCache::cache(); 381 } 382 return nullptr; 383 } 384 385 AOTCodeCache* AOTCodeCache::open_for_dump() { 386 if (AOTCodeCache::is_on_for_dump()) { 387 AOTCodeCache* cache = AOTCodeCache::cache(); 388 cache->clear_lookup_failed(); // Reset bit 389 return cache; 390 } 391 return nullptr; 392 } 393 394 void copy_bytes(const char* from, address to, uint size) { 395 assert(size > 0, "sanity"); 396 bool by_words = true; 397 if ((size > 2 * HeapWordSize) && (((intptr_t)from | (intptr_t)to) & (HeapWordSize - 1)) == 0) { 398 // Use wordwise copies if possible: 399 Copy::disjoint_words((HeapWord*)from, 400 (HeapWord*)to, 401 ((size_t)size + HeapWordSize-1) / HeapWordSize); 402 } else { 403 by_words = false; 404 Copy::conjoint_jbytes(from, to, (size_t)size); 405 } 406 log_trace(aot, codecache)("Copied %d bytes as %s from " INTPTR_FORMAT " to " INTPTR_FORMAT, size, (by_words ? "HeapWord" : "bytes"), p2i(from), p2i(to)); 407 } 408 409 AOTCodeReader::AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry) { 410 _cache = cache; 411 _entry = entry; 412 _load_buffer = cache->cache_buffer(); 413 _read_position = 0; 414 _lookup_failed = false; 415 } 416 417 void AOTCodeReader::set_read_position(uint pos) { 418 if (pos == _read_position) { 419 return; 420 } 421 assert(pos < _cache->load_size(), "offset:%d >= file size:%d", pos, _cache->load_size()); 422 _read_position = pos; 423 } 424 425 bool AOTCodeCache::set_write_position(uint pos) { 426 if (pos == _write_position) { 427 return true; 428 } 429 if (_store_size < _write_position) { 430 _store_size = _write_position; // Adjust during write 431 } 432 assert(pos < _store_size, "offset:%d >= file size:%d", pos, _store_size); 433 _write_position = pos; 434 return true; 435 } 436 437 static char align_buffer[256] = { 0 }; 438 439 bool AOTCodeCache::align_write() { 440 // We are not executing code from cache - we copy it by bytes first. 441 // No need for big alignment (or at all). 442 uint padding = DATA_ALIGNMENT - (_write_position & (DATA_ALIGNMENT - 1)); 443 if (padding == DATA_ALIGNMENT) { 444 return true; 445 } 446 uint n = write_bytes((const void*)&align_buffer, padding); 447 if (n != padding) { 448 return false; 449 } 450 log_trace(aot, codecache)("Adjust write alignment in AOT Code Cache"); 451 return true; 452 } 453 454 // Check to see if AOT code cache has required space to store "nbytes" of data 455 address AOTCodeCache::reserve_bytes(uint nbytes) { 456 assert(for_dump(), "Code Cache file is not created"); 457 uint new_position = _write_position + nbytes; 458 if (new_position >= (uint)((char*)_store_entries - _store_buffer)) { 459 log_warning(aot,codecache)("Failed to ensure %d bytes at offset %d in AOT Code Cache. Increase AOTCodeMaxSize.", 460 nbytes, _write_position); 461 set_failed(); 462 report_store_failure(); 463 return nullptr; 464 } 465 address buffer = (address)(_store_buffer + _write_position); 466 log_trace(aot, codecache)("Reserved %d bytes at offset %d in AOT Code Cache", nbytes, _write_position); 467 _write_position += nbytes; 468 if (_store_size < _write_position) { 469 _store_size = _write_position; 470 } 471 return buffer; 472 } 473 474 uint AOTCodeCache::write_bytes(const void* buffer, uint nbytes) { 475 assert(for_dump(), "Code Cache file is not created"); 476 if (nbytes == 0) { 477 return 0; 478 } 479 uint new_position = _write_position + nbytes; 480 if (new_position >= (uint)((char*)_store_entries - _store_buffer)) { 481 log_warning(aot, codecache)("Failed to write %d bytes at offset %d to AOT Code Cache. Increase AOTCodeMaxSize.", 482 nbytes, _write_position); 483 set_failed(); 484 report_store_failure(); 485 return 0; 486 } 487 copy_bytes((const char* )buffer, (address)(_store_buffer + _write_position), nbytes); 488 log_trace(aot, codecache)("Wrote %d bytes at offset %d to AOT Code Cache", nbytes, _write_position); 489 _write_position += nbytes; 490 if (_store_size < _write_position) { 491 _store_size = _write_position; 492 } 493 return nbytes; 494 } 495 496 void* AOTCodeEntry::operator new(size_t x, AOTCodeCache* cache) { 497 return (void*)(cache->add_entry()); 498 } 499 500 static bool check_entry(AOTCodeEntry::Kind kind, uint id, AOTCodeEntry* entry) { 501 if (entry->kind() == kind) { 502 assert(entry->id() == id, "sanity"); 503 return true; // Found 504 } 505 return false; 506 } 507 508 AOTCodeEntry* AOTCodeCache::find_entry(AOTCodeEntry::Kind kind, uint id) { 509 assert(_for_use, "sanity"); 510 uint count = _load_header->entries_count(); 511 if (_load_entries == nullptr) { 512 // Read it 513 _search_entries = (uint*)addr(_load_header->entries_offset()); // [id, index] 514 _load_entries = (AOTCodeEntry*)(_search_entries + 2 * count); 515 log_debug(aot, codecache, init)("Read %d entries table at offset %d from AOT Code Cache", count, _load_header->entries_offset()); 516 } 517 // Binary search 518 int l = 0; 519 int h = count - 1; 520 while (l <= h) { 521 int mid = (l + h) >> 1; 522 int ix = mid * 2; 523 uint is = _search_entries[ix]; 524 if (is == id) { 525 int index = _search_entries[ix + 1]; 526 AOTCodeEntry* entry = &(_load_entries[index]); 527 if (check_entry(kind, id, entry)) { 528 return entry; // Found 529 } 530 break; // Not found match 531 } else if (is < id) { 532 l = mid + 1; 533 } else { 534 h = mid - 1; 535 } 536 } 537 return nullptr; 538 } 539 540 extern "C" { 541 static int uint_cmp(const void *i, const void *j) { 542 uint a = *(uint *)i; 543 uint b = *(uint *)j; 544 return a > b ? 1 : a < b ? -1 : 0; 545 } 546 } 547 548 bool AOTCodeCache::finish_write() { 549 if (!align_write()) { 550 return false; 551 } 552 uint strings_offset = _write_position; 553 int strings_count = store_strings(); 554 if (strings_count < 0) { 555 return false; 556 } 557 if (!align_write()) { 558 return false; 559 } 560 uint strings_size = _write_position - strings_offset; 561 562 uint entries_count = 0; // Number of entrant (useful) code entries 563 uint entries_offset = _write_position; 564 565 uint store_count = _store_entries_cnt; 566 if (store_count > 0) { 567 uint header_size = (uint)align_up(sizeof(AOTCodeCache::Header), DATA_ALIGNMENT); 568 uint code_count = store_count; 569 uint search_count = code_count * 2; 570 uint search_size = search_count * sizeof(uint); 571 uint entries_size = (uint)align_up(code_count * sizeof(AOTCodeEntry), DATA_ALIGNMENT); // In bytes 572 // _write_position includes size of code and strings 573 uint code_alignment = code_count * DATA_ALIGNMENT; // We align_up code size when storing it. 574 uint total_size = header_size + _write_position + code_alignment + search_size + entries_size; 575 assert(total_size < max_aot_code_size(), "AOT Code size (" UINT32_FORMAT " bytes) is greater than AOTCodeMaxSize(" UINT32_FORMAT " bytes).", total_size, max_aot_code_size()); 576 577 // Create ordered search table for entries [id, index]; 578 uint* search = NEW_C_HEAP_ARRAY(uint, search_count, mtCode); 579 // Allocate in AOT Cache buffer 580 char* buffer = (char *)AOTCacheAccess::allocate_aot_code_region(total_size + DATA_ALIGNMENT); 581 char* start = align_up(buffer, DATA_ALIGNMENT); 582 char* current = start + header_size; // Skip header 583 584 AOTCodeEntry* entries_address = _store_entries; // Pointer to latest entry 585 uint adapters_count = 0; 586 uint blobs_count = 0; 587 uint max_size = 0; 588 // AOTCodeEntry entries were allocated in reverse in store buffer. 589 // Process them in reverse order to cache first code first. 590 for (int i = store_count - 1; i >= 0; i--) { 591 entries_address[i].set_next(nullptr); // clear pointers before storing data 592 uint size = align_up(entries_address[i].size(), DATA_ALIGNMENT); 593 if (size > max_size) { 594 max_size = size; 595 } 596 copy_bytes((_store_buffer + entries_address[i].offset()), (address)current, size); 597 entries_address[i].set_offset(current - start); // New offset 598 current += size; 599 uint n = write_bytes(&(entries_address[i]), sizeof(AOTCodeEntry)); 600 if (n != sizeof(AOTCodeEntry)) { 601 FREE_C_HEAP_ARRAY(uint, search); 602 return false; 603 } 604 search[entries_count*2 + 0] = entries_address[i].id(); 605 search[entries_count*2 + 1] = entries_count; 606 entries_count++; 607 AOTCodeEntry::Kind kind = entries_address[i].kind(); 608 if (kind == AOTCodeEntry::Adapter) { 609 adapters_count++; 610 } else if (kind == AOTCodeEntry::Blob) { 611 blobs_count++; 612 } 613 } 614 if (entries_count == 0) { 615 log_info(aot, codecache, exit)("AOT Code Cache was not created: no entires"); 616 FREE_C_HEAP_ARRAY(uint, search); 617 return true; // Nothing to write 618 } 619 assert(entries_count <= store_count, "%d > %d", entries_count, store_count); 620 // Write strings 621 if (strings_count > 0) { 622 copy_bytes((_store_buffer + strings_offset), (address)current, strings_size); 623 strings_offset = (current - start); // New offset 624 current += strings_size; 625 } 626 627 uint new_entries_offset = (current - start); // New offset 628 // Sort and store search table 629 qsort(search, entries_count, 2*sizeof(uint), uint_cmp); 630 search_size = 2 * entries_count * sizeof(uint); 631 copy_bytes((const char*)search, (address)current, search_size); 632 FREE_C_HEAP_ARRAY(uint, search); 633 current += search_size; 634 635 // Write entries 636 entries_size = entries_count * sizeof(AOTCodeEntry); // New size 637 copy_bytes((_store_buffer + entries_offset), (address)current, entries_size); 638 current += entries_size; 639 uint size = (current - start); 640 assert(size <= total_size, "%d > %d", size , total_size); 641 642 log_debug(aot, codecache, exit)(" Adapters: total=%u", adapters_count); 643 log_debug(aot, codecache, exit)(" All Blobs: total=%u", blobs_count); 644 log_debug(aot, codecache, exit)(" AOT code cache size: %u bytes, max entry's size: %u bytes", size, max_size); 645 646 // Finalize header 647 AOTCodeCache::Header* header = (AOTCodeCache::Header*)start; 648 header->init(size, (uint)strings_count, strings_offset, 649 entries_count, new_entries_offset, 650 adapters_count, blobs_count); 651 652 log_info(aot, codecache, exit)("Wrote %d AOT code entries to AOT Code Cache", entries_count); 653 } 654 return true; 655 } 656 657 //------------------Store/Load AOT code ---------------------- 658 659 bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind, uint id, const char* name, int entry_offset_count, int* entry_offsets) { 660 AOTCodeCache* cache = open_for_dump(); 661 if (cache == nullptr) { 662 return false; 663 } 664 assert(AOTCodeEntry::is_valid_entry_kind(entry_kind), "invalid entry_kind %d", entry_kind); 665 666 if ((entry_kind == AOTCodeEntry::Adapter) && !AOTAdapterCaching) { 667 return false; 668 } 669 log_debug(aot, codecache, stubs)("Writing blob '%s' to AOT Code Cache", name); 670 671 #ifdef ASSERT 672 LogStreamHandle(Trace, aot, codecache, stubs) log; 673 if (log.is_enabled()) { 674 FlagSetting fs(PrintRelocations, true); 675 blob.print_on(&log); 676 } 677 #endif 678 // we need to take a lock to prevent race between compiler threads generating AOT code 679 // and the main thread generating adapter 680 MutexLocker ml(Compile_lock); 681 if (!cache->align_write()) { 682 return false; 683 } 684 uint entry_position = cache->_write_position; 685 686 // Write name 687 uint name_offset = cache->_write_position - entry_position; 688 uint name_size = (uint)strlen(name) + 1; // Includes '/0' 689 uint n = cache->write_bytes(name, name_size); 690 if (n != name_size) { 691 return false; 692 } 693 694 // Write CodeBlob 695 if (!cache->align_write()) { 696 return false; 697 } 698 uint blob_offset = cache->_write_position - entry_position; 699 address archive_buffer = cache->reserve_bytes(blob.size()); 700 if (archive_buffer == nullptr) { 701 return false; 702 } 703 CodeBlob::archive_blob(&blob, archive_buffer); 704 705 uint reloc_data_size = blob.relocation_size(); 706 n = cache->write_bytes((address)blob.relocation_begin(), reloc_data_size); 707 if (n != reloc_data_size) { 708 return false; 709 } 710 711 bool has_oop_maps = false; 712 if (blob.oop_maps() != nullptr) { 713 if (!cache->write_oop_map_set(blob)) { 714 return false; 715 } 716 has_oop_maps = true; 717 } 718 719 if (!cache->write_relocations(blob)) { 720 return false; 721 } 722 723 // Write entries offsets 724 n = cache->write_bytes(&entry_offset_count, sizeof(int)); 725 if (n != sizeof(int)) { 726 return false; 727 } 728 for (int i = 0; i < entry_offset_count; i++) { 729 uint32_t off = (uint32_t)entry_offsets[i]; 730 n = cache->write_bytes(&off, sizeof(uint32_t)); 731 if (n != sizeof(uint32_t)) { 732 return false; 733 } 734 } 735 uint entry_size = cache->_write_position - entry_position; 736 AOTCodeEntry* entry = new(cache) AOTCodeEntry(entry_kind, id, 737 entry_position, entry_size, name_offset, name_size, 738 blob_offset, has_oop_maps, blob.content_begin()); 739 log_debug(aot, codecache, stubs)("Wrote code blob '%s(id=%d)' to AOT Code Cache", name, id); 740 return true; 741 } 742 743 CodeBlob* AOTCodeCache::load_code_blob(AOTCodeEntry::Kind entry_kind, uint id, const char* name, int entry_offset_count, int* entry_offsets) { 744 AOTCodeCache* cache = open_for_use(); 745 if (cache == nullptr) { 746 return nullptr; 747 } 748 assert(AOTCodeEntry::is_valid_entry_kind(entry_kind), "invalid entry_kind %d", entry_kind); 749 750 if ((entry_kind == AOTCodeEntry::Adapter) && !AOTAdapterCaching) { 751 return nullptr; 752 } 753 log_debug(aot, codecache, stubs)("Reading blob '%s' from AOT Code Cache", name); 754 755 AOTCodeEntry* entry = cache->find_entry(entry_kind, id); 756 if (entry == nullptr) { 757 return nullptr; 758 } 759 AOTCodeReader reader(cache, entry); 760 return reader.compile_code_blob(name, entry_offset_count, entry_offsets); 761 } 762 763 CodeBlob* AOTCodeReader::compile_code_blob(const char* name, int entry_offset_count, int* entry_offsets) { 764 uint entry_position = _entry->offset(); 765 766 // Read name 767 uint name_offset = entry_position + _entry->name_offset(); 768 uint name_size = _entry->name_size(); // Includes '/0' 769 const char* stored_name = addr(name_offset); 770 771 if (strncmp(stored_name, name, (name_size - 1)) != 0) { 772 log_warning(aot, codecache, stubs)("Saved blob's name '%s' is different from the expected name '%s'", 773 stored_name, name); 774 ((AOTCodeCache*)_cache)->set_failed(); 775 report_load_failure(); 776 return nullptr; 777 } 778 779 // Read archived code blob 780 uint offset = entry_position + _entry->blob_offset(); 781 CodeBlob* archived_blob = (CodeBlob*)addr(offset); 782 offset += archived_blob->size(); 783 784 address reloc_data = (address)addr(offset); 785 offset += archived_blob->relocation_size(); 786 set_read_position(offset); 787 788 ImmutableOopMapSet* oop_maps = nullptr; 789 if (_entry->has_oop_maps()) { 790 oop_maps = read_oop_map_set(); 791 } 792 793 CodeBlob* code_blob = CodeBlob::create(archived_blob, stored_name, reloc_data, oop_maps); 794 if (code_blob == nullptr) { // no space left in CodeCache 795 return nullptr; 796 } 797 798 fix_relocations(code_blob); 799 800 // Read entries offsets 801 offset = read_position(); 802 int stored_count = *(int*)addr(offset); 803 assert(stored_count == entry_offset_count, "entry offset count mismatch, count in AOT code cache=%d, expected=%d", stored_count, entry_offset_count); 804 offset += sizeof(int); 805 set_read_position(offset); 806 for (int i = 0; i < stored_count; i++) { 807 uint32_t off = *(uint32_t*)addr(offset); 808 offset += sizeof(uint32_t); 809 const char* entry_name = (_entry->kind() == AOTCodeEntry::Adapter) ? AdapterHandlerEntry::entry_name(i) : ""; 810 log_trace(aot, codecache, stubs)("Reading adapter '%s:%s' (0x%x) offset: 0x%x from AOT Code Cache", 811 stored_name, entry_name, _entry->id(), off); 812 entry_offsets[i] = off; 813 } 814 815 log_debug(aot, codecache, stubs)("Read blob '%s' from AOT Code Cache", name); 816 #ifdef ASSERT 817 LogStreamHandle(Trace, aot, codecache, stubs) log; 818 if (log.is_enabled()) { 819 FlagSetting fs(PrintRelocations, true); 820 code_blob->print_on(&log); 821 } 822 #endif 823 return code_blob; 824 } 825 826 // ------------ process code and data -------------- 827 828 bool AOTCodeCache::write_relocations(CodeBlob& code_blob) { 829 GrowableArray<uint> reloc_data; 830 RelocIterator iter(&code_blob); 831 LogStreamHandle(Trace, aot, codecache, reloc) log; 832 while (iter.next()) { 833 int idx = reloc_data.append(0); // default value 834 switch (iter.type()) { 835 case relocInfo::none: 836 break; 837 case relocInfo::runtime_call_type: { 838 // Record offset of runtime destination 839 CallRelocation* r = (CallRelocation*)iter.reloc(); 840 address dest = r->destination(); 841 if (dest == r->addr()) { // possible call via trampoline on Aarch64 842 dest = (address)-1; // do nothing in this case when loading this relocation 843 } 844 reloc_data.at_put(idx, _table->id_for_address(dest, iter, &code_blob)); 845 break; 846 } 847 case relocInfo::runtime_call_w_cp_type: 848 fatal("runtime_call_w_cp_type unimplemented"); 849 break; 850 case relocInfo::external_word_type: { 851 // Record offset of runtime target 852 address target = ((external_word_Relocation*)iter.reloc())->target(); 853 reloc_data.at_put(idx, _table->id_for_address(target, iter, &code_blob)); 854 break; 855 } 856 case relocInfo::internal_word_type: 857 break; 858 case relocInfo::section_word_type: 859 break; 860 default: 861 fatal("relocation %d unimplemented", (int)iter.type()); 862 break; 863 } 864 if (log.is_enabled()) { 865 iter.print_current_on(&log); 866 } 867 } 868 869 // Write additional relocation data: uint per relocation 870 // Write the count first 871 int count = reloc_data.length(); 872 write_bytes(&count, sizeof(int)); 873 for (GrowableArrayIterator<uint> iter = reloc_data.begin(); 874 iter != reloc_data.end(); ++iter) { 875 uint value = *iter; 876 int n = write_bytes(&value, sizeof(uint)); 877 if (n != sizeof(uint)) { 878 return false; 879 } 880 } 881 return true; 882 } 883 884 void AOTCodeReader::fix_relocations(CodeBlob* code_blob) { 885 LogStreamHandle(Trace, aot, reloc) log; 886 uint offset = read_position(); 887 int count = *(int*)addr(offset); 888 offset += sizeof(int); 889 if (log.is_enabled()) { 890 log.print_cr("======== extra relocations count=%d", count); 891 } 892 uint* reloc_data = (uint*)addr(offset); 893 offset += (count * sizeof(uint)); 894 set_read_position(offset); 895 896 RelocIterator iter(code_blob); 897 int j = 0; 898 while (iter.next()) { 899 switch (iter.type()) { 900 case relocInfo::none: 901 break; 902 case relocInfo::runtime_call_type: { 903 address dest = _cache->address_for_id(reloc_data[j]); 904 if (dest != (address)-1) { 905 ((CallRelocation*)iter.reloc())->set_destination(dest); 906 } 907 break; 908 } 909 case relocInfo::runtime_call_w_cp_type: 910 fatal("runtime_call_w_cp_type unimplemented"); 911 break; 912 case relocInfo::external_word_type: { 913 address target = _cache->address_for_id(reloc_data[j]); 914 // Add external address to global table 915 int index = ExternalsRecorder::find_index(target); 916 // Update index in relocation 917 Relocation::add_jint(iter.data(), index); 918 external_word_Relocation* reloc = (external_word_Relocation*)iter.reloc(); 919 assert(reloc->target() == target, "sanity"); 920 reloc->set_value(target); // Patch address in the code 921 break; 922 } 923 case relocInfo::internal_word_type: { 924 internal_word_Relocation* r = (internal_word_Relocation*)iter.reloc(); 925 r->fix_relocation_after_aot_load(aot_code_entry()->dumptime_content_start_addr(), code_blob->content_begin()); 926 break; 927 } 928 case relocInfo::section_word_type: { 929 section_word_Relocation* r = (section_word_Relocation*)iter.reloc(); 930 r->fix_relocation_after_aot_load(aot_code_entry()->dumptime_content_start_addr(), code_blob->content_begin()); 931 break; 932 } 933 default: 934 fatal("relocation %d unimplemented", (int)iter.type()); 935 break; 936 } 937 if (log.is_enabled()) { 938 iter.print_current_on(&log); 939 } 940 j++; 941 } 942 assert(j == count, "sanity"); 943 } 944 945 bool AOTCodeCache::write_oop_map_set(CodeBlob& cb) { 946 ImmutableOopMapSet* oopmaps = cb.oop_maps(); 947 int oopmaps_size = oopmaps->nr_of_bytes(); 948 if (!write_bytes(&oopmaps_size, sizeof(int))) { 949 return false; 950 } 951 uint n = write_bytes(oopmaps, oopmaps->nr_of_bytes()); 952 if (n != (uint)oopmaps->nr_of_bytes()) { 953 return false; 954 } 955 return true; 956 } 957 958 ImmutableOopMapSet* AOTCodeReader::read_oop_map_set() { 959 uint offset = read_position(); 960 int size = *(int *)addr(offset); 961 offset += sizeof(int); 962 ImmutableOopMapSet* oopmaps = (ImmutableOopMapSet *)addr(offset); 963 offset += size; 964 set_read_position(offset); 965 return oopmaps; 966 } 967 968 //======================= AOTCodeAddressTable =============== 969 970 // address table ids for generated routines, external addresses and C 971 // string addresses are partitioned into positive integer ranges 972 // defined by the following positive base and max values 973 // i.e. [_extrs_base, _extrs_base + _extrs_max -1], 974 // [_blobs_base, _blobs_base + _blobs_max -1], 975 // ... 976 // [_c_str_base, _c_str_base + _c_str_max -1], 977 #define _extrs_max 10 978 #define _blobs_max 10 979 #define _all_max 20 980 981 #define _extrs_base 0 982 #define _blobs_base (_extrs_base + _extrs_max) 983 #define _blobs_end (_blobs_base + _blobs_max) 984 985 #if (_blobs_end > _all_max) 986 #error AOTCodeAddress table ranges need adjusting 987 #endif 988 989 #define SET_ADDRESS(type, addr) \ 990 { \ 991 type##_addr[type##_length++] = (address) (addr); \ 992 assert(type##_length <= type##_max, "increase size"); \ 993 } 994 995 static bool initializing_extrs = false; 996 997 void AOTCodeAddressTable::init_extrs() { 998 if (_extrs_complete || initializing_extrs) return; // Done already 999 initializing_extrs = true; 1000 _extrs_addr = NEW_C_HEAP_ARRAY(address, _extrs_max, mtCode); 1001 1002 _extrs_length = 0; 1003 1004 // Recored addresses of VM runtime methods 1005 SET_ADDRESS(_extrs, SharedRuntime::fixup_callers_callsite); 1006 SET_ADDRESS(_extrs, SharedRuntime::handle_wrong_method); 1007 SET_ADDRESS(_extrs, SharedRuntime::handle_wrong_method_abstract); 1008 SET_ADDRESS(_extrs, SharedRuntime::handle_wrong_method_ic_miss); 1009 #if INCLUDE_G1GC 1010 SET_ADDRESS(_extrs, G1BarrierSetRuntime::write_ref_field_post_entry); 1011 SET_ADDRESS(_extrs, G1BarrierSetRuntime::write_ref_field_pre_entry); 1012 #endif 1013 #if INCLUDE_ZGC 1014 SET_ADDRESS(_extrs, ZBarrierSetRuntime::load_barrier_on_phantom_oop_field_preloaded_addr()); 1015 #if defined(AMD64) 1016 SET_ADDRESS(_extrs, &ZPointerLoadShift); 1017 #endif 1018 #endif 1019 #ifdef COMPILER2 1020 SET_ADDRESS(_extrs, OptoRuntime::handle_exception_C); 1021 #endif 1022 #ifndef ZERO 1023 #if defined(AMD64) || defined(AARCH64) || defined(RISCV64) 1024 SET_ADDRESS(_extrs, MacroAssembler::debug64); 1025 #endif 1026 #endif // ZERO 1027 1028 _extrs_complete = true; 1029 log_debug(aot, codecache, init)("External addresses recorded"); 1030 } 1031 1032 static bool initializing_shared_blobs = false; 1033 1034 void AOTCodeAddressTable::init_shared_blobs() { 1035 if (_complete || initializing_shared_blobs) return; // Done already 1036 initializing_shared_blobs = true; 1037 _blobs_addr = NEW_C_HEAP_ARRAY(address, _blobs_max, mtCode); 1038 1039 _blobs_length = 0; // for shared blobs 1040 1041 // Recored addresses of generated code blobs 1042 SET_ADDRESS(_blobs, SharedRuntime::get_handle_wrong_method_stub()); 1043 SET_ADDRESS(_blobs, SharedRuntime::get_ic_miss_stub()); 1044 1045 _shared_blobs_complete = true; 1046 log_debug(aot, codecache, init)("Early shared blobs recorded"); 1047 _complete = true; 1048 } 1049 1050 #undef SET_ADDRESS 1051 1052 AOTCodeAddressTable::~AOTCodeAddressTable() { 1053 if (_extrs_addr != nullptr) { 1054 FREE_C_HEAP_ARRAY(address, _extrs_addr); 1055 } 1056 if (_blobs_addr != nullptr) { 1057 FREE_C_HEAP_ARRAY(address, _blobs_addr); 1058 } 1059 } 1060 1061 #ifdef PRODUCT 1062 #define MAX_STR_COUNT 200 1063 #else 1064 #define MAX_STR_COUNT 500 1065 #endif 1066 #define _c_str_max MAX_STR_COUNT 1067 #define _c_str_base _all_max 1068 1069 static const char* _C_strings_in[MAX_STR_COUNT] = {nullptr}; // Incoming strings 1070 static const char* _C_strings[MAX_STR_COUNT] = {nullptr}; // Our duplicates 1071 static int _C_strings_count = 0; 1072 static int _C_strings_s[MAX_STR_COUNT] = {0}; 1073 static int _C_strings_id[MAX_STR_COUNT] = {0}; 1074 static int _C_strings_used = 0; 1075 1076 void AOTCodeCache::load_strings() { 1077 uint strings_count = _load_header->strings_count(); 1078 if (strings_count == 0) { 1079 return; 1080 } 1081 uint strings_offset = _load_header->strings_offset(); 1082 uint* string_lengths = (uint*)addr(strings_offset); 1083 strings_offset += (strings_count * sizeof(uint)); 1084 uint strings_size = _load_header->entries_offset() - strings_offset; 1085 // We have to keep cached strings longer than _cache buffer 1086 // because they are refernced from compiled code which may 1087 // still be executed on VM exit after _cache is freed. 1088 char* p = NEW_C_HEAP_ARRAY(char, strings_size+1, mtCode); 1089 memcpy(p, addr(strings_offset), strings_size); 1090 _C_strings_buf = p; 1091 assert(strings_count <= MAX_STR_COUNT, "sanity"); 1092 for (uint i = 0; i < strings_count; i++) { 1093 _C_strings[i] = p; 1094 uint len = string_lengths[i]; 1095 _C_strings_s[i] = i; 1096 _C_strings_id[i] = i; 1097 p += len; 1098 } 1099 assert((uint)(p - _C_strings_buf) <= strings_size, "(" INTPTR_FORMAT " - " INTPTR_FORMAT ") = %d > %d ", p2i(p), p2i(_C_strings_buf), (uint)(p - _C_strings_buf), strings_size); 1100 _C_strings_count = strings_count; 1101 _C_strings_used = strings_count; 1102 log_debug(aot, codecache, init)(" Loaded %d C strings of total length %d at offset %d from AOT Code Cache", _C_strings_count, strings_size, strings_offset); 1103 } 1104 1105 int AOTCodeCache::store_strings() { 1106 if (_C_strings_used > 0) { 1107 uint offset = _write_position; 1108 uint length = 0; 1109 uint* lengths = (uint *)reserve_bytes(sizeof(uint) * _C_strings_used); 1110 if (lengths == nullptr) { 1111 return -1; 1112 } 1113 for (int i = 0; i < _C_strings_used; i++) { 1114 const char* str = _C_strings[_C_strings_s[i]]; 1115 uint len = (uint)strlen(str) + 1; 1116 length += len; 1117 assert(len < 1000, "big string: %s", str); 1118 lengths[i] = len; 1119 uint n = write_bytes(str, len); 1120 if (n != len) { 1121 return -1; 1122 } 1123 } 1124 log_debug(aot, codecache, exit)(" Wrote %d C strings of total length %d at offset %d to AOT Code Cache", 1125 _C_strings_used, length, offset); 1126 } 1127 return _C_strings_used; 1128 } 1129 1130 const char* AOTCodeCache::add_C_string(const char* str) { 1131 if (is_on_for_dump() && str != nullptr) { 1132 return _cache->_table->add_C_string(str); 1133 } 1134 return str; 1135 } 1136 1137 const char* AOTCodeAddressTable::add_C_string(const char* str) { 1138 if (_extrs_complete) { 1139 LogStreamHandle(Trace, aot, codecache, stringtable) log; // ctor outside lock 1140 MutexLocker ml(AOTCodeCStrings_lock, Mutex::_no_safepoint_check_flag); 1141 // Check previous strings address 1142 for (int i = 0; i < _C_strings_count; i++) { 1143 if (_C_strings_in[i] == str) { 1144 return _C_strings[i]; // Found previous one - return our duplicate 1145 } else if (strcmp(_C_strings[i], str) == 0) { 1146 return _C_strings[i]; 1147 } 1148 } 1149 // Add new one 1150 if (_C_strings_count < MAX_STR_COUNT) { 1151 // Passed in string can be freed and used space become inaccessible. 1152 // Keep original address but duplicate string for future compare. 1153 _C_strings_id[_C_strings_count] = -1; // Init 1154 _C_strings_in[_C_strings_count] = str; 1155 const char* dup = os::strdup(str); 1156 _C_strings[_C_strings_count++] = dup; 1157 if (log.is_enabled()) { 1158 log.print_cr("add_C_string: [%d] " INTPTR_FORMAT " '%s'", _C_strings_count, p2i(dup), dup); 1159 } 1160 return dup; 1161 } else { 1162 fatal("Number of C strings >= MAX_STR_COUNT"); 1163 } 1164 } 1165 return str; 1166 } 1167 1168 int AOTCodeAddressTable::id_for_C_string(address str) { 1169 if (str == nullptr) { 1170 return -1; 1171 } 1172 MutexLocker ml(AOTCodeCStrings_lock, Mutex::_no_safepoint_check_flag); 1173 for (int i = 0; i < _C_strings_count; i++) { 1174 if (_C_strings[i] == (const char*)str) { // found 1175 int id = _C_strings_id[i]; 1176 if (id >= 0) { 1177 assert(id < _C_strings_used, "%d >= %d", id , _C_strings_used); 1178 return id; // Found recorded 1179 } 1180 // Not found in recorded, add new 1181 id = _C_strings_used++; 1182 _C_strings_s[id] = i; 1183 _C_strings_id[i] = id; 1184 return id; 1185 } 1186 } 1187 return -1; 1188 } 1189 1190 address AOTCodeAddressTable::address_for_C_string(int idx) { 1191 assert(idx < _C_strings_count, "sanity"); 1192 return (address)_C_strings[idx]; 1193 } 1194 1195 static int search_address(address addr, address* table, uint length) { 1196 for (int i = 0; i < (int)length; i++) { 1197 if (table[i] == addr) { 1198 return i; 1199 } 1200 } 1201 return -1; 1202 } 1203 1204 address AOTCodeAddressTable::address_for_id(int idx) { 1205 if (!_extrs_complete) { 1206 fatal("AOT Code Cache VM runtime addresses table is not complete"); 1207 } 1208 if (idx == -1) { 1209 return (address)-1; 1210 } 1211 uint id = (uint)idx; 1212 // special case for symbols based relative to os::init 1213 if (id > (_c_str_base + _c_str_max)) { 1214 return (address)os::init + idx; 1215 } 1216 if (idx < 0) { 1217 fatal("Incorrect id %d for AOT Code Cache addresses table", id); 1218 } 1219 // no need to compare unsigned id against 0 1220 if (/* id >= _extrs_base && */ id < _extrs_length) { 1221 return _extrs_addr[id - _extrs_base]; 1222 } 1223 if (id >= _blobs_base && id < _blobs_base + _blobs_length) { 1224 return _blobs_addr[id - _blobs_base]; 1225 } 1226 if (id >= _c_str_base && id < (_c_str_base + (uint)_C_strings_count)) { 1227 return address_for_C_string(id - _c_str_base); 1228 } 1229 fatal("Incorrect id %d for AOT Code Cache addresses table", id); 1230 return nullptr; 1231 } 1232 1233 int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeBlob* code_blob) { 1234 if (!_extrs_complete) { 1235 fatal("AOT Code Cache VM runtime addresses table is not complete"); 1236 } 1237 int id = -1; 1238 if (addr == (address)-1) { // Static call stub has jump to itself 1239 return id; 1240 } 1241 // Seach for C string 1242 id = id_for_C_string(addr); 1243 if (id >= 0) { 1244 return id + _c_str_base; 1245 } 1246 if (StubRoutines::contains(addr)) { 1247 // Search in stubs 1248 StubCodeDesc* desc = StubCodeDesc::desc_for(addr); 1249 if (desc == nullptr) { 1250 desc = StubCodeDesc::desc_for(addr + frame::pc_return_offset); 1251 } 1252 const char* sub_name = (desc != nullptr) ? desc->name() : "<unknown>"; 1253 fatal("Address " INTPTR_FORMAT " for Stub:%s is missing in AOT Code Cache addresses table", p2i(addr), sub_name); 1254 } else { 1255 CodeBlob* cb = CodeCache::find_blob(addr); 1256 if (cb != nullptr) { 1257 // Search in code blobs 1258 int id_base = _blobs_base; 1259 id = search_address(addr, _blobs_addr, _blobs_length); 1260 if (id < 0) { 1261 fatal("Address " INTPTR_FORMAT " for Blob:%s is missing in AOT Code Cache addresses table", p2i(addr), cb->name()); 1262 } else { 1263 return id_base + id; 1264 } 1265 } else { 1266 // Search in runtime functions 1267 id = search_address(addr, _extrs_addr, _extrs_length); 1268 if (id < 0) { 1269 ResourceMark rm; 1270 const int buflen = 1024; 1271 char* func_name = NEW_RESOURCE_ARRAY(char, buflen); 1272 int offset = 0; 1273 if (os::dll_address_to_function_name(addr, func_name, buflen, &offset)) { 1274 if (offset > 0) { 1275 // Could be address of C string 1276 uint dist = (uint)pointer_delta(addr, (address)os::init, 1); 1277 log_debug(aot, codecache)("Address " INTPTR_FORMAT " (offset %d) for runtime target '%s' is missing in AOT Code Cache addresses table", 1278 p2i(addr), dist, (const char*)addr); 1279 assert(dist > (uint)(_all_max + MAX_STR_COUNT), "change encoding of distance"); 1280 return dist; 1281 } 1282 reloc.print_current_on(tty); 1283 code_blob->print_on(tty); 1284 code_blob->print_code_on(tty); 1285 fatal("Address " INTPTR_FORMAT " for runtime target '%s+%d' is missing in AOT Code Cache addresses table", p2i(addr), func_name, offset); 1286 } else { 1287 reloc.print_current_on(tty); 1288 code_blob->print_on(tty); 1289 code_blob->print_code_on(tty); 1290 os::find(addr, tty); 1291 fatal("Address " INTPTR_FORMAT " for <unknown>/('%s') is missing in AOT Code Cache addresses table", p2i(addr), (const char*)addr); 1292 } 1293 } else { 1294 return _extrs_base + id; 1295 } 1296 } 1297 } 1298 return id; 1299 } 1300 1301 void AOTCodeCache::print_on(outputStream* st) { 1302 AOTCodeCache* cache = open_for_use(); 1303 if (cache != nullptr) { 1304 uint count = cache->_load_header->entries_count(); 1305 uint* search_entries = (uint*)cache->addr(cache->_load_header->entries_offset()); // [id, index] 1306 AOTCodeEntry* load_entries = (AOTCodeEntry*)(search_entries + 2 * count); 1307 1308 for (uint i = 0; i < count; i++) { 1309 // Use search_entries[] to order ouput 1310 int index = search_entries[2*i + 1]; 1311 AOTCodeEntry* entry = &(load_entries[index]); 1312 1313 uint entry_position = entry->offset(); 1314 uint name_offset = entry->name_offset() + entry_position; 1315 const char* saved_name = cache->addr(name_offset); 1316 1317 st->print_cr("%4u: entry_idx:%4u Kind:%u Id:%u size=%u '%s'", 1318 i, index, entry->kind(), entry->id(), entry->size(), saved_name); 1319 } 1320 } else { 1321 st->print_cr("failed to map code cache"); 1322 } 1323 } 1324