1 /* 2 * Copyright (c) 2019, 2026, 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/aotCompressedPointers.hpp" 26 #include "cds/aotLogging.hpp" 27 #include "cds/aotMetaspace.hpp" 28 #include "cds/archiveBuilder.hpp" 29 #include "cds/archiveUtils.hpp" 30 #include "cds/cdsConfig.hpp" 31 #include "cds/classListParser.hpp" 32 #include "cds/classListWriter.hpp" 33 #include "cds/dumpAllocStats.hpp" 34 #include "cds/dynamicArchive.hpp" 35 #include "cds/filemap.hpp" 36 #include "cds/heapShared.hpp" 37 #include "cds/lambdaProxyClassDictionary.hpp" 38 #include "classfile/classLoader.hpp" 39 #include "classfile/systemDictionaryShared.hpp" 40 #include "classfile/vmClasses.hpp" 41 #include "interpreter/bootstrapInfo.hpp" 42 #include "memory/metaspaceUtils.hpp" 43 #include "memory/resourceArea.hpp" 44 #include "oops/compressedOops.inline.hpp" 45 #include "oops/klass.inline.hpp" 46 #include "runtime/arguments.hpp" 47 #include "utilities/bitMap.inline.hpp" 48 #include "utilities/debug.hpp" 49 #include "utilities/formatBuffer.hpp" 50 #include "utilities/globalDefinitions.hpp" 51 #include "utilities/rbTree.inline.hpp" 52 #include "utilities/spinYield.hpp" 53 54 CHeapBitMap* ArchivePtrMarker::_ptrmap = nullptr; 55 CHeapBitMap* ArchivePtrMarker::_rw_ptrmap = nullptr; 56 CHeapBitMap* ArchivePtrMarker::_ro_ptrmap = nullptr; 57 CHeapBitMap* ArchivePtrMarker::_ac_ptrmap = nullptr; 58 VirtualSpace* ArchivePtrMarker::_vs; 59 60 bool ArchivePtrMarker::_compacted; 61 62 void ArchivePtrMarker::initialize(CHeapBitMap* ptrmap, VirtualSpace* vs) { 63 assert(_ptrmap == nullptr, "initialize only once"); 64 assert(_rw_ptrmap == nullptr, "initialize only once"); 65 assert(_ro_ptrmap == nullptr, "initialize only once"); 66 assert(_ac_ptrmap == nullptr, "initialize only once"); 67 _vs = vs; 68 _compacted = false; 69 _ptrmap = ptrmap; 70 71 // Use this as initial guesstimate. We should need less space in the 72 // archive, but if we're wrong the bitmap will be expanded automatically. 73 size_t estimated_archive_size = MetaspaceGC::capacity_until_GC(); 74 // But set it smaller in debug builds so we always test the expansion code. 75 // (Default archive is about 12MB). 76 DEBUG_ONLY(estimated_archive_size = 6 * M); 77 78 // We need one bit per pointer in the archive. 79 _ptrmap->initialize(estimated_archive_size / sizeof(intptr_t)); 80 } 81 82 void ArchivePtrMarker::initialize_rw_ro_ac_maps(CHeapBitMap* rw_ptrmap, CHeapBitMap* ro_ptrmap, CHeapBitMap* ac_ptrmap) { 83 address* buff_bottom = (address*)ArchiveBuilder::current()->buffer_bottom(); 84 address* rw_bottom = (address*)ArchiveBuilder::current()->rw_region()->base(); 85 address* ro_bottom = (address*)ArchiveBuilder::current()->ro_region()->base(); 86 address* ac_bottom = (address*)ArchiveBuilder::current()->ac_region()->base(); 87 88 // The bit in _ptrmap that cover the very first word in the rw/ro/ac regions. 89 size_t rw_start = rw_bottom - buff_bottom; 90 size_t ro_start = ro_bottom - buff_bottom; 91 size_t ac_start = ac_bottom - buff_bottom; 92 93 // The number of bits used by the rw/ro ptrmaps. We might have lots of zero 94 // bits at the bottom and top of rw/ro ptrmaps, but these zeros will be 95 // removed by FileMapInfo::write_bitmap_region(). 96 size_t rw_size = ArchiveBuilder::current()->rw_region()->used() / sizeof(address); 97 size_t ro_size = ArchiveBuilder::current()->ro_region()->used() / sizeof(address); 98 size_t ac_size = ArchiveBuilder::current()->ac_region()->used() / sizeof(address); 99 100 // The last (exclusive) bit in _ptrmap that covers the rw/ro regions. 101 // Note: _ptrmap is dynamically expanded only when an actual pointer is written, so 102 // it may not be as large as we want. 103 size_t rw_end = MIN2<size_t>(rw_start + rw_size, _ptrmap->size()); 104 size_t ro_end = MIN2<size_t>(ro_start + ro_size, _ptrmap->size()); 105 size_t ac_end = MIN2<size_t>(ac_start + ac_size, _ptrmap->size()); 106 107 rw_ptrmap->initialize(rw_size); 108 ro_ptrmap->initialize(ro_size); 109 ac_ptrmap->initialize(ac_size); 110 111 for (size_t rw_bit = rw_start; rw_bit < rw_end; rw_bit++) { 112 rw_ptrmap->at_put(rw_bit - rw_start, _ptrmap->at(rw_bit)); 113 } 114 115 for(size_t ro_bit = ro_start; ro_bit < ro_end; ro_bit++) { 116 ro_ptrmap->at_put(ro_bit - ro_start, _ptrmap->at(ro_bit)); 117 } 118 119 for (size_t ac_bit = ac_start; ac_bit < ac_end; ac_bit++) { 120 ac_ptrmap->at_put(ac_bit - ac_start, _ptrmap->at(ac_bit)); 121 } 122 123 _rw_ptrmap = rw_ptrmap; 124 _ro_ptrmap = ro_ptrmap; 125 _ac_ptrmap = ac_ptrmap; 126 } 127 128 void ArchivePtrMarker::mark_pointer(address* ptr_loc) { 129 assert(_ptrmap != nullptr, "not initialized"); 130 assert(!_compacted, "cannot mark anymore"); 131 132 if (ptr_base() <= ptr_loc && ptr_loc < ptr_end()) { 133 address value = *ptr_loc; 134 if (value != nullptr) { 135 // We don't want any pointer that points to very bottom of the AOT metaspace, otherwise 136 // when AOTMetaspace::default_base_address()==0, we can't distinguish between a pointer 137 // to nothing (null) vs a pointer to an objects that happens to be at the very bottom 138 // of the AOT metaspace. 139 // 140 // This should never happen because the protection zone prevents any valid objects from 141 // being allocated at the bottom of the AOT metaspace. 142 assert(AOTMetaspace::protection_zone_size() > 0, "must be"); 143 assert(ArchiveBuilder::current()->any_to_offset(value) > 0, "cannot point to bottom of AOT metaspace"); 144 145 assert(uintx(ptr_loc) % sizeof(intptr_t) == 0, "pointers must be stored in aligned addresses"); 146 size_t idx = ptr_loc - ptr_base(); 147 if (_ptrmap->size() <= idx) { 148 _ptrmap->resize((idx + 1) * 2); 149 } 150 assert(idx < _ptrmap->size(), "must be"); 151 _ptrmap->set_bit(idx); 152 } 153 } 154 } 155 156 void ArchivePtrMarker::clear_pointer(address* ptr_loc) { 157 assert(_ptrmap != nullptr, "not initialized"); 158 assert(!_compacted, "cannot clear anymore"); 159 160 assert(ptr_base() <= ptr_loc && ptr_loc < ptr_end(), "must be"); 161 assert(uintx(ptr_loc) % sizeof(intptr_t) == 0, "pointers must be stored in aligned addresses"); 162 size_t idx = ptr_loc - ptr_base(); 163 assert(idx < _ptrmap->size(), "cannot clear pointers that have not been marked"); 164 _ptrmap->clear_bit(idx); 165 } 166 167 class ArchivePtrBitmapCleaner: public BitMapClosure { 168 CHeapBitMap* _ptrmap; 169 address* _ptr_base; 170 address _relocatable_base; 171 address _relocatable_end; 172 size_t _max_non_null_offset; 173 174 public: 175 ArchivePtrBitmapCleaner(CHeapBitMap* ptrmap, address* ptr_base, address relocatable_base, address relocatable_end) : 176 _ptrmap(ptrmap), _ptr_base(ptr_base), 177 _relocatable_base(relocatable_base), _relocatable_end(relocatable_end), _max_non_null_offset(0) {} 178 179 bool do_bit(size_t offset) { 180 address* ptr_loc = _ptr_base + offset; 181 address ptr_value = *ptr_loc; 182 if (ptr_value != nullptr) { 183 assert(_relocatable_base <= ptr_value && ptr_value < _relocatable_end, "do not point to arbitrary locations!"); 184 if (_max_non_null_offset < offset) { 185 _max_non_null_offset = offset; 186 } 187 } else { 188 _ptrmap->clear_bit(offset); 189 DEBUG_ONLY(log_trace(aot, reloc)("Clearing pointer [" PTR_FORMAT "] -> null @ %9zu", p2i(ptr_loc), offset)); 190 } 191 192 return true; 193 } 194 195 size_t max_non_null_offset() const { return _max_non_null_offset; } 196 }; 197 198 void ArchivePtrMarker::compact(address relocatable_base, address relocatable_end) { 199 assert(!_compacted, "cannot compact again"); 200 ArchivePtrBitmapCleaner cleaner(_ptrmap, ptr_base(), relocatable_base, relocatable_end); 201 _ptrmap->iterate(&cleaner); 202 compact(cleaner.max_non_null_offset()); 203 } 204 205 void ArchivePtrMarker::compact(size_t max_non_null_offset) { 206 assert(!_compacted, "cannot compact again"); 207 _ptrmap->resize(max_non_null_offset + 1); 208 _compacted = true; 209 } 210 211 char* DumpRegion::expand_top_to(char* newtop) { 212 assert(is_allocatable(), "must be initialized and not packed"); 213 assert(newtop >= _top, "must not grow backwards"); 214 if (newtop > _end) { 215 ArchiveBuilder::current()->report_out_of_space(_name, newtop - _top); 216 ShouldNotReachHere(); 217 } 218 219 commit_to(newtop); 220 _top = newtop; 221 222 if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(_base)) { 223 uintx delta = ArchiveBuilder::current()->buffer_to_offset((address)(newtop-1)); 224 if (delta > AOTCompressedPointers::MaxMetadataOffsetBytes) { 225 // This is just a sanity check and should not appear in any real world usage. This 226 // happens only if you allocate more than 2GB of shared objects and would require 227 // millions of shared classes. 228 aot_log_error(aot)("Out of memory in the %s: Please reduce the number of shared classes.", CDSConfig::type_of_archive_being_written()); 229 AOTMetaspace::unrecoverable_writing_error(); 230 } 231 } 232 233 return _top; 234 } 235 236 void DumpRegion::commit_to(char* newtop) { 237 assert(CDSConfig::is_dumping_archive(), "sanity"); 238 char* base = _rs->base(); 239 size_t need_committed_size = newtop - base; 240 size_t has_committed_size = _vs->committed_size(); 241 if (need_committed_size < has_committed_size) { 242 return; 243 } 244 245 size_t min_bytes = need_committed_size - has_committed_size; 246 size_t preferred_bytes = 1 * M; 247 size_t uncommitted = _vs->reserved_size() - has_committed_size; 248 249 size_t commit = MAX2(min_bytes, preferred_bytes); 250 commit = MIN2(commit, uncommitted); 251 assert(commit <= uncommitted, "sanity"); 252 253 if (!_vs->expand_by(commit, false)) { 254 aot_log_error(aot)("Failed to expand shared space to %zu bytes", 255 need_committed_size); 256 AOTMetaspace::unrecoverable_writing_error(); 257 } 258 259 const char* which; 260 if (_rs->base() == (char*)AOTMetaspace::symbol_rs_base()) { 261 which = "symbol"; 262 } else { 263 which = "shared"; 264 } 265 log_debug(aot)("Expanding %s spaces by %7zu bytes [total %9zu bytes ending at %p]", 266 which, commit, _vs->actual_committed_size(), _vs->high()); 267 } 268 269 // Basic allocation. Any alignment gaps will be wasted. 270 char* DumpRegion::allocate(size_t num_bytes, size_t alignment) { 271 // Always align to at least minimum alignment 272 alignment = MAX2(SharedSpaceObjectAlignment, alignment); 273 char* p = (char*)align_up(_top, alignment); 274 char* newtop = p + align_up(num_bytes, SharedSpaceObjectAlignment); 275 expand_top_to(newtop); 276 memset(p, 0, newtop - p); 277 return p; 278 } 279 280 class DumpRegion::AllocGap { 281 size_t _gap_bytes; // size of this gap in bytes 282 char* _gap_bottom; // must be SharedSpaceObjectAlignment aligned 283 public: 284 size_t gap_bytes() const { return _gap_bytes; } 285 char* gap_bottom() const { return _gap_bottom; } 286 287 AllocGap(size_t bytes, char* bottom) : _gap_bytes(bytes), _gap_bottom(bottom) { 288 precond(is_aligned(gap_bytes(), SharedSpaceObjectAlignment)); 289 precond(is_aligned(gap_bottom(), SharedSpaceObjectAlignment)); 290 } 291 }; 292 293 struct DumpRegion::AllocGapCmp { 294 static RBTreeOrdering cmp(AllocGap a, AllocGap b) { 295 RBTreeOrdering order = rbtree_primitive_cmp(a.gap_bytes(), b.gap_bytes()); 296 if (order == RBTreeOrdering::EQ) { 297 order = rbtree_primitive_cmp(a.gap_bottom(), b.gap_bottom()); 298 } 299 return order; 300 } 301 }; 302 303 struct Empty {}; 304 using AllocGapNode = RBNode<DumpRegion::AllocGap, Empty>; 305 306 class DumpRegion::AllocGapTree : public RBTreeCHeap<AllocGap, Empty, AllocGapCmp, mtClassShared> { 307 public: 308 size_t add_gap(char* gap_bottom, char* gap_top) { 309 precond(gap_bottom < gap_top); 310 size_t gap_bytes = pointer_delta(gap_top, gap_bottom, 1); 311 precond(gap_bytes > 0); 312 313 _total_gap_bytes += gap_bytes; 314 315 AllocGap gap(gap_bytes, gap_bottom); // constructor checks alignment 316 AllocGapNode* node = allocate_node(gap, Empty{}); 317 insert(gap, node); 318 319 log_trace(aot, alloc)("adding a gap of %zu bytes @ %p (total = %zu) in %zu blocks", gap_bytes, gap_bottom, _total_gap_bytes, size()); 320 return gap_bytes; 321 } 322 323 char* allocate_from_gap(size_t num_bytes) { 324 // The gaps are sorted in ascending order of their sizes. When two gaps have the same 325 // size, the one with a lower gap_bottom comes first. 326 // 327 // Find the first gap that's big enough, with the lowest gap_bottom. 328 AllocGap target(num_bytes, nullptr); 329 AllocGapNode* node = closest_ge(target); 330 if (node == nullptr) { 331 return nullptr; // Didn't find any usable gap. 332 } 333 334 size_t gap_bytes = node->key().gap_bytes(); 335 char* gap_bottom = node->key().gap_bottom(); 336 char* result = gap_bottom; 337 precond(is_aligned(result, SharedSpaceObjectAlignment)); 338 339 remove(node); 340 341 precond(_total_gap_bytes >= num_bytes); 342 _total_gap_bytes -= num_bytes; 343 _total_gap_bytes_used += num_bytes; 344 _total_gap_allocs++; 345 DEBUG_ONLY(node = nullptr); // Don't use it anymore! 346 347 precond(gap_bytes >= num_bytes); 348 if (gap_bytes > num_bytes) { 349 gap_bytes -= num_bytes; 350 gap_bottom += num_bytes; 351 352 AllocGap gap(gap_bytes, gap_bottom); // constructor checks alignment 353 AllocGapNode* new_node = allocate_node(gap, Empty{}); 354 insert(gap, new_node); 355 } 356 log_trace(aot, alloc)("%zu bytes @ %p in a gap of %zu bytes (used gaps %zu times, remain gap = %zu bytes in %zu blocks)", 357 num_bytes, result, gap_bytes, _total_gap_allocs, _total_gap_bytes, size()); 358 return result; 359 } 360 }; 361 362 size_t DumpRegion::_total_gap_bytes = 0; 363 size_t DumpRegion::_total_gap_bytes_used = 0; 364 size_t DumpRegion::_total_gap_allocs = 0; 365 DumpRegion::AllocGapTree DumpRegion::_gap_tree; 366 367 // Alignment gaps happen only for the RW space. Collect the gaps into the _gap_tree so they can be 368 // used for future small object allocation. 369 char* DumpRegion::allocate_metaspace_obj(size_t num_bytes, address src, MetaspaceClosureType type, bool read_only, DumpAllocStats* stats) { 370 num_bytes = align_up(num_bytes, SharedSpaceObjectAlignment); 371 size_t alignment = SharedSpaceObjectAlignment; // alignment for the dest pointer 372 bool is_class = (type == MetaspaceClosureType::ClassType); 373 bool is_instance_class = is_class && ((Klass*)src)->is_instance_klass(); 374 375 #ifdef _LP64 376 // More strict alignments needed for UseCompressedClassPointers 377 if (is_class && UseCompressedClassPointers) { 378 size_t klass_alignment = checked_cast<size_t>(nth_bit(ArchiveBuilder::precomputed_narrow_klass_shift())); 379 alignment = MAX2(alignment, klass_alignment); 380 precond(is_aligned(alignment, SharedSpaceObjectAlignment)); 381 } 382 #endif 383 384 if (alignment == SharedSpaceObjectAlignment && type != MetaspaceClosureType::SymbolType) { 385 // The addresses of Symbols must be in the same order as they are in ArchiveBuilder::SourceObjList. 386 // If we put them in gaps, their order will change. 387 // 388 // We have enough small objects that all gaps are usually filled. 389 char* p = _gap_tree.allocate_from_gap(num_bytes); 390 if (p != nullptr) { 391 // Already memset to 0 when adding the gap 392 stats->record(type, checked_cast<int>(num_bytes), /*read_only=*/false); // all gaps are from RW space (for classes) 393 return p; 394 } 395 } 396 397 // Reserve space for a pointer directly in front of the buffered InstanceKlass, so 398 // we can do a quick lookup from InstanceKlass* -> RunTimeClassInfo* 399 // without building another hashtable. See RunTimeClassInfo::get_for() 400 // in systemDictionaryShared.cpp. 401 const size_t RuntimeClassInfoPtrSize = is_instance_class ? sizeof(address) : 0; 402 403 if (is_class && !is_aligned(top() + RuntimeClassInfoPtrSize, alignment)) { 404 // We need to add a gap to align the buffered Klass. Save the gap for future small allocations. 405 assert(read_only == false, "only gaps in RW region are reusable"); 406 char* gap_bottom = top(); 407 char* gap_top = align_up(gap_bottom + RuntimeClassInfoPtrSize, alignment) - RuntimeClassInfoPtrSize; 408 size_t gap_bytes = _gap_tree.add_gap(gap_bottom, gap_top); 409 allocate(gap_bytes); 410 } 411 412 char* oldtop = top(); 413 if (is_instance_class) { 414 SystemDictionaryShared::validate_before_archiving((InstanceKlass*)src); 415 allocate(RuntimeClassInfoPtrSize); 416 } 417 418 precond(is_aligned(top(), alignment)); 419 char* result = allocate(num_bytes); 420 log_trace(aot, alloc)("%zu bytes @ %p", num_bytes, result); 421 stats->record(type, pointer_delta_as_int(top(), oldtop), read_only); // includes RuntimeClassInfoPtrSize for classes 422 423 return result; 424 } 425 426 // Usually we have no gaps left. 427 void DumpRegion::report_gaps(DumpAllocStats* stats) { 428 _gap_tree.visit_in_order([&](const AllocGapNode* node) { 429 stats->record_gap(checked_cast<int>(node->key().gap_bytes())); 430 return true; 431 }); 432 if (_gap_tree.size() > 0) { 433 log_warning(aot)("Unexpected %zu gaps (%zu bytes) for Klass alignment", 434 _gap_tree.size(), _total_gap_bytes); 435 } 436 if (_total_gap_allocs > 0) { 437 log_info(aot)("Allocated %zu objects of %zu bytes in gaps (remain = %zu bytes)", 438 _total_gap_allocs, _total_gap_bytes_used, _total_gap_bytes); 439 } 440 } 441 442 void DumpRegion::append_intptr_t(intptr_t n, bool need_to_mark) { 443 assert(is_aligned(_top, sizeof(intptr_t)), "bad alignment"); 444 intptr_t *p = (intptr_t*)_top; 445 char* newtop = _top + sizeof(intptr_t); 446 expand_top_to(newtop); 447 *p = n; 448 if (need_to_mark) { 449 ArchivePtrMarker::mark_pointer(p); 450 } 451 } 452 453 void DumpRegion::print(size_t total_bytes) const { 454 char* base = used() > 0 ? ArchiveBuilder::current()->to_requested(_base) : nullptr; 455 log_debug(aot)("%s space: %9zu [ %4.1f%% of total] out of %9zu bytes [%5.1f%% used] at " INTPTR_FORMAT, 456 _name, used(), percent_of(used(), total_bytes), reserved(), percent_of(used(), reserved()), 457 p2i(base)); 458 } 459 460 void DumpRegion::print_out_of_space_msg(const char* failing_region, size_t needed_bytes) { 461 aot_log_error(aot)("[%-8s] " PTR_FORMAT " - " PTR_FORMAT " capacity =%9d, allocated =%9d", 462 _name, p2i(_base), p2i(_top), int(_end - _base), int(_top - _base)); 463 if (strcmp(_name, failing_region) == 0) { 464 aot_log_error(aot)(" required = %d", int(needed_bytes)); 465 } 466 } 467 468 void DumpRegion::init(ReservedSpace* rs, VirtualSpace* vs) { 469 _rs = rs; 470 _vs = vs; 471 // Start with 0 committed bytes. The memory will be committed as needed. 472 if (!_vs->initialize(*_rs, 0)) { 473 fatal("Unable to allocate memory for shared space"); 474 } 475 _base = _top = _rs->base(); 476 _end = _rs->end(); 477 } 478 479 void DumpRegion::pack(DumpRegion* next) { 480 if (!is_packed()) { 481 _end = (char*)align_up(_top, AOTMetaspace::core_region_alignment()); 482 _is_packed = true; 483 } 484 if (next != nullptr) { 485 next->_rs = _rs; 486 next->_vs = _vs; 487 next->_base = next->_top = this->_end; 488 next->_end = _rs->end(); 489 } 490 } 491 492 void WriteClosure::do_ptr(void** p) { 493 address ptr = *(address*)p; 494 AOTCompressedPointers::narrowPtr narrowp = AOTCompressedPointers::encode(ptr); 495 _dump_region->append_intptr_t(checked_cast<intptr_t>(narrowp), false); 496 } 497 498 void ReadClosure::do_ptr(void** p) { 499 assert(*p == nullptr, "initializing previous initialized pointer."); 500 u4 narrowp = checked_cast<u4>(nextPtr()); 501 *p = AOTCompressedPointers::decode<void*>(cast_from_u4(narrowp), _base_address); 502 } 503 504 void ReadClosure::do_u4(u4* p) { 505 intptr_t obj = nextPtr(); 506 *p = (u4)(uintx(obj)); 507 } 508 509 void ReadClosure::do_int(int* p) { 510 intptr_t obj = nextPtr(); 511 *p = (int)(intx(obj)); 512 } 513 514 void ReadClosure::do_bool(bool* p) { 515 intptr_t obj = nextPtr(); 516 *p = (bool)(uintx(obj)); 517 } 518 519 void ReadClosure::do_tag(int tag) { 520 int old_tag; 521 old_tag = (int)(intptr_t)nextPtr(); 522 // do_int(&old_tag); 523 assert(tag == old_tag, "tag doesn't match (%d, expected %d)", old_tag, tag); 524 FileMapInfo::assert_mark(tag == old_tag); 525 } 526 527 void ArchiveUtils::log_to_classlist(BootstrapInfo* bootstrap_specifier, TRAPS) { 528 if (ClassListWriter::is_enabled()) { 529 if (LambdaProxyClassDictionary::is_supported_invokedynamic(bootstrap_specifier)) { 530 const constantPoolHandle& pool = bootstrap_specifier->pool(); 531 if (SystemDictionaryShared::is_builtin_loader(pool->pool_holder()->class_loader_data())) { 532 // Currently lambda proxy classes are supported only for the built-in loaders. 533 ResourceMark rm(THREAD); 534 int pool_index = bootstrap_specifier->bss_index(); 535 ClassListWriter w; 536 w.stream()->print("%s %s", ClassListParser::lambda_proxy_tag(), pool->pool_holder()->name()->as_C_string()); 537 CDSIndyInfo cii; 538 ClassListParser::populate_cds_indy_info(pool, pool_index, &cii, CHECK); 539 GrowableArray<const char*>* indy_items = cii.items(); 540 for (int i = 0; i < indy_items->length(); i++) { 541 w.stream()->print(" %s", indy_items->at(i)); 542 } 543 w.stream()->cr(); 544 } 545 } 546 } 547 } 548 549 550 // "boot", "platform", "app" or nullptr 551 const char* ArchiveUtils::builtin_loader_name_or_null(oop loader) { 552 if (loader == nullptr) { 553 return "boot"; 554 } else if (loader == SystemDictionary::java_platform_loader()) { 555 return "platform"; 556 } else if (loader == SystemDictionary::java_system_loader()) { 557 return "app"; 558 } else { 559 return nullptr; 560 } 561 } 562 563 // "boot", "platform", "app". Asserts if not a built-in-loader 564 const char* ArchiveUtils::builtin_loader_name(oop loader) { 565 const char* name = builtin_loader_name_or_null(loader); 566 assert(name != nullptr, "must be a built-in loader"); 567 return name; 568 } 569 570 bool ArchiveUtils::builtin_loader_from_type(const char* loader_type, oop* value_ret) { 571 if (strcmp(loader_type, "boot") == 0) { 572 *value_ret = nullptr; 573 return true; 574 } else if (strcmp(loader_type, "platform") == 0) { 575 *value_ret = SystemDictionary::java_platform_loader(); 576 return true; 577 } else if (strcmp(loader_type, "app") == 0) { 578 *value_ret = SystemDictionary::java_system_loader(); 579 return true; 580 } else { 581 DEBUG_ONLY(*value_ret = cast_to_oop((void*)badOopVal)); 582 return false; 583 } 584 } 585 586 oop ArchiveUtils::builtin_loader_from_type(int loader_type) { 587 if (loader_type == ClassLoader::BOOT_LOADER) { 588 return nullptr; 589 } else if (loader_type == ClassLoader::PLATFORM_LOADER) { 590 return SystemDictionary::java_platform_loader(); 591 } else if (loader_type == ClassLoader::APP_LOADER) { 592 return SystemDictionary::java_system_loader(); 593 } else { 594 ShouldNotReachHere(); 595 return nullptr; 596 } 597 } 598 599 bool ArchiveUtils::has_aot_initialized_mirror(InstanceKlass* src_ik) { 600 if (!ArchiveBuilder::current()->has_been_archived(src_ik)) { 601 return false; 602 } 603 return ArchiveBuilder::current()->get_buffered_addr(src_ik)->has_aot_initialized_mirror(); 604 } 605 606 size_t HeapRootSegments::size_in_bytes(size_t seg_idx) { 607 assert(seg_idx < _count, "In range"); 608 return objArrayOopDesc::object_size(size_in_elems(seg_idx)) * HeapWordSize; 609 } 610 611 int HeapRootSegments::size_in_elems(size_t seg_idx) { 612 assert(seg_idx < _count, "In range"); 613 if (seg_idx != _count - 1) { 614 return _max_size_in_elems; 615 } else { 616 // Last slice, leftover 617 return _roots_count % _max_size_in_elems; 618 } 619 } 620 621 size_t HeapRootSegments::segment_offset(size_t seg_idx) { 622 assert(seg_idx < _count, "In range"); 623 return _base_offset + seg_idx * _max_size_in_bytes; 624 } 625 626 ArchiveWorkers::ArchiveWorkers() : 627 _end_semaphore(0), 628 _num_workers(max_workers()), 629 _started_workers(0), 630 _finish_tokens(0), 631 _state(UNUSED), 632 _task(nullptr) {} 633 634 ArchiveWorkers::~ArchiveWorkers() { 635 assert(AtomicAccess::load(&_state) != WORKING, "Should not be working"); 636 } 637 638 int ArchiveWorkers::max_workers() { 639 // The pool is used for short-lived bursty tasks. We do not want to spend 640 // too much time creating and waking up threads unnecessarily. Plus, we do 641 // not want to overwhelm large machines. This is why we want to be very 642 // conservative about the number of workers actually needed. 643 return MAX2(0, log2i_graceful(os::active_processor_count())); 644 } 645 646 bool ArchiveWorkers::is_parallel() { 647 return _num_workers > 0; 648 } 649 650 void ArchiveWorkers::start_worker_if_needed() { 651 while (true) { 652 int cur = AtomicAccess::load(&_started_workers); 653 if (cur >= _num_workers) { 654 return; 655 } 656 if (AtomicAccess::cmpxchg(&_started_workers, cur, cur + 1, memory_order_relaxed) == cur) { 657 new ArchiveWorkerThread(this); 658 return; 659 } 660 } 661 } 662 663 void ArchiveWorkers::run_task(ArchiveWorkerTask* task) { 664 assert(AtomicAccess::load(&_state) == UNUSED, "Should be unused yet"); 665 assert(AtomicAccess::load(&_task) == nullptr, "Should not have running tasks"); 666 AtomicAccess::store(&_state, WORKING); 667 668 if (is_parallel()) { 669 run_task_multi(task); 670 } else { 671 run_task_single(task); 672 } 673 674 assert(AtomicAccess::load(&_state) == WORKING, "Should be working"); 675 AtomicAccess::store(&_state, SHUTDOWN); 676 } 677 678 void ArchiveWorkers::run_task_single(ArchiveWorkerTask* task) { 679 // Single thread needs no chunking. 680 task->configure_max_chunks(1); 681 682 // Execute the task ourselves, as there are no workers. 683 task->work(0, 1); 684 } 685 686 void ArchiveWorkers::run_task_multi(ArchiveWorkerTask* task) { 687 // Multiple threads can work with multiple chunks. 688 task->configure_max_chunks(_num_workers * CHUNKS_PER_WORKER); 689 690 // Set up the run and publish the task. Issue one additional finish token 691 // to cover the semaphore shutdown path, see below. 692 AtomicAccess::store(&_finish_tokens, _num_workers + 1); 693 AtomicAccess::release_store(&_task, task); 694 695 // Kick off pool startup by starting a single worker, and proceed 696 // immediately to executing the task locally. 697 start_worker_if_needed(); 698 699 // Execute the task ourselves, while workers are catching up. 700 // This allows us to hide parts of task handoff latency. 701 task->run(); 702 703 // Done executing task locally, wait for any remaining workers to complete. 704 // Once all workers report, we can proceed to termination. To do this safely, 705 // we need to make sure every worker has left. A spin-wait alone would suffice, 706 // but we do not want to burn cycles on it. A semaphore alone would not be safe, 707 // since workers can still be inside it as we proceed from wait here. So we block 708 // on semaphore first, and then spin-wait for all workers to terminate. 709 _end_semaphore.wait(); 710 SpinYield spin; 711 while (AtomicAccess::load(&_finish_tokens) != 0) { 712 spin.wait(); 713 } 714 715 OrderAccess::fence(); 716 717 assert(AtomicAccess::load(&_finish_tokens) == 0, "All tokens are consumed"); 718 } 719 720 void ArchiveWorkers::run_as_worker() { 721 assert(is_parallel(), "Should be in parallel mode"); 722 723 ArchiveWorkerTask* task = AtomicAccess::load_acquire(&_task); 724 task->run(); 725 726 // All work done in threads should be visible to caller. 727 OrderAccess::fence(); 728 729 // Signal the pool the work is complete, and we are exiting. 730 // Worker cannot do anything else with the pool after this. 731 if (AtomicAccess::sub(&_finish_tokens, 1, memory_order_relaxed) == 1) { 732 // Last worker leaving. Notify the pool it can unblock to spin-wait. 733 // Then consume the last token and leave. 734 _end_semaphore.signal(); 735 int last = AtomicAccess::sub(&_finish_tokens, 1, memory_order_relaxed); 736 assert(last == 0, "Should be"); 737 } 738 } 739 740 void ArchiveWorkerTask::run() { 741 while (true) { 742 int chunk = AtomicAccess::load(&_chunk); 743 if (chunk >= _max_chunks) { 744 return; 745 } 746 if (AtomicAccess::cmpxchg(&_chunk, chunk, chunk + 1, memory_order_relaxed) == chunk) { 747 assert(0 <= chunk && chunk < _max_chunks, "Sanity"); 748 work(chunk, _max_chunks); 749 } 750 } 751 } 752 753 void ArchiveWorkerTask::configure_max_chunks(int max_chunks) { 754 if (_max_chunks == 0) { 755 _max_chunks = max_chunks; 756 } 757 } 758 759 ArchiveWorkerThread::ArchiveWorkerThread(ArchiveWorkers* pool) : NamedThread(), _pool(pool) { 760 set_name("ArchiveWorkerThread"); 761 if (os::create_thread(this, os::os_thread)) { 762 os::start_thread(this); 763 } else { 764 vm_exit_during_initialization("Unable to create archive worker", 765 os::native_thread_creation_failed_msg()); 766 } 767 } 768 769 void ArchiveWorkerThread::run() { 770 // Avalanche startup: each worker starts two others. 771 _pool->start_worker_if_needed(); 772 _pool->start_worker_if_needed(); 773 774 // Set ourselves up. 775 os::set_priority(this, NearMaxPriority); 776 777 // Work. 778 _pool->run_as_worker(); 779 } 780 781 void ArchiveWorkerThread::post_run() { 782 this->NamedThread::post_run(); 783 delete this; 784 } --- EOF ---