Skip to content

Commit e3eb089

Browse files
author
Vladimir Kozlov
committed
8357175: Failure to generate or load AOT code should be handled gracefully
Reviewed-by: iveresov, asmehra
1 parent 470ffee commit e3eb089

2 files changed

Lines changed: 84 additions & 89 deletions

File tree

src/hotspot/share/code/aotCodeCache.cpp

Lines changed: 78 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ uint AOTCodeCache::max_aot_code_size() {
125125
return _max_aot_code_size;
126126
}
127127

128+
// This method is called during universe_init()
129+
// and does final AOT state and flags settings.
128130
void AOTCodeCache::initialize() {
129131
#if defined(ZERO) || !(defined(AMD64) || defined(AARCH64))
130132
log_info(aot, codecache, init)("AOT Code Cache is not supported on this platform.");
@@ -197,38 +199,48 @@ void AOTCodeCache::initialize() {
197199
#endif // defined(AMD64) || defined(AARCH64)
198200
}
199201

202+
static AOTCodeCache* opened_cache = nullptr; // Use this until we verify the cache
203+
AOTCodeCache* AOTCodeCache::_cache = nullptr;
204+
205+
// This method is called after universe_init()
206+
// when all GC settings are finalized.
200207
void AOTCodeCache::init2() {
201-
if (!is_on()) {
208+
if (opened_cache == nullptr) {
202209
return;
203210
}
204-
if (!verify_vm_config()) {
205-
close();
211+
if (!opened_cache->verify_config()) {
212+
delete opened_cache;
213+
opened_cache = nullptr;
206214
report_load_failure();
215+
return;
207216
}
208217

209218
// initialize the table of external routines so we can save
210219
// generated code blobs that reference them
211-
init_extrs_table();
212-
init_early_stubs_table();
213-
}
220+
AOTCodeAddressTable* table = opened_cache->_table;
221+
assert(table != nullptr, "should be initialized already");
222+
table->init_extrs();
223+
table->init_early_stubs();
214224

215-
AOTCodeCache* AOTCodeCache::_cache = nullptr;
225+
// Now cache and address table are ready for AOT code generation
226+
_cache = opened_cache;
227+
}
216228

217229
bool AOTCodeCache::open_cache(bool is_dumping, bool is_using) {
218-
AOTCodeCache* cache = new AOTCodeCache(is_dumping, is_using);
219-
if (cache->failed()) {
220-
delete cache;
221-
_cache = nullptr;
230+
opened_cache = new AOTCodeCache(is_dumping, is_using);
231+
if (opened_cache->failed()) {
232+
delete opened_cache;
233+
opened_cache = nullptr;
222234
return false;
223235
}
224-
_cache = cache;
225236
return true;
226237
}
227238

228239
void AOTCodeCache::close() {
229240
if (is_on()) {
230241
delete _cache; // Free memory
231242
_cache = nullptr;
243+
opened_cache = nullptr;
232244
}
233245
}
234246

@@ -276,7 +288,7 @@ AOTCodeCache::AOTCodeCache(bool is_dumping, bool is_using) :
276288
log_debug(aot, codecache, init)("Mapped %u bytes at address " INTPTR_FORMAT " at AOT Code Cache", _load_size, p2i(_load_buffer));
277289

278290
_load_header = (Header*)addr(0);
279-
if (!_load_header->verify_config(_load_size)) {
291+
if (!_load_header->verify(_load_size)) {
280292
set_failed();
281293
return;
282294
}
@@ -300,20 +312,6 @@ AOTCodeCache::AOTCodeCache(bool is_dumping, bool is_using) :
300312
_table = new AOTCodeAddressTable();
301313
}
302314

303-
void AOTCodeCache::init_extrs_table() {
304-
AOTCodeAddressTable* table = addr_table();
305-
if (table != nullptr) {
306-
table->init_extrs();
307-
}
308-
}
309-
310-
void AOTCodeCache::init_early_stubs_table() {
311-
AOTCodeAddressTable* table = addr_table();
312-
if (table != nullptr) {
313-
table->init_early_stubs();
314-
}
315-
}
316-
317315
void AOTCodeCache::init_shared_blobs_table() {
318316
AOTCodeAddressTable* table = addr_table();
319317
if (table != nullptr) {
@@ -381,11 +379,11 @@ void AOTCodeCache::Config::record() {
381379
_compressedOopBase = CompressedOops::base();
382380
_compressedKlassShift = CompressedKlassPointers::shift();
383381
_contendedPaddingWidth = ContendedPaddingWidth;
384-
_objectAlignment = ObjectAlignmentInBytes;
385382
_gc = (uint)Universe::heap()->kind();
386383
}
387384

388385
bool AOTCodeCache::Config::verify() const {
386+
// First checks affect all cached AOT code
389387
#ifdef ASSERT
390388
if ((_flags & debugVM) == 0) {
391389
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created by product VM, it can't be used by debug VM");
@@ -404,47 +402,24 @@ bool AOTCodeCache::Config::verify() const {
404402
return false;
405403
}
406404

407-
if (((_flags & compressedOops) != 0) != UseCompressedOops) {
408-
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with UseCompressedOops = %s", UseCompressedOops ? "false" : "true");
409-
return false;
410-
}
411405
if (((_flags & compressedClassPointers) != 0) != UseCompressedClassPointers) {
412406
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with UseCompressedClassPointers = %s", UseCompressedClassPointers ? "false" : "true");
413407
return false;
414408
}
415-
416-
if (((_flags & systemClassAssertions) != 0) != JavaAssertions::systemClassDefault()) {
417-
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with JavaAssertions::systemClassDefault() = %s", JavaAssertions::systemClassDefault() ? "disabled" : "enabled");
418-
return false;
419-
}
420-
if (((_flags & userClassAssertions) != 0) != JavaAssertions::userClassDefault()) {
421-
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with JavaAssertions::userClassDefault() = %s", JavaAssertions::userClassDefault() ? "disabled" : "enabled");
409+
if (_compressedKlassShift != (uint)CompressedKlassPointers::shift()) {
410+
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with CompressedKlassPointers::shift() = %d vs current %d", _compressedKlassShift, CompressedKlassPointers::shift());
422411
return false;
423412
}
424413

425-
if (((_flags & enableContendedPadding) != 0) != EnableContended) {
426-
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with EnableContended = %s", EnableContended ? "false" : "true");
427-
return false;
428-
}
429-
if (((_flags & restrictContendedPadding) != 0) != RestrictContended) {
430-
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with RestrictContended = %s", RestrictContended ? "false" : "true");
431-
return false;
414+
// The following checks do not affect AOT adapters caching
415+
416+
if (((_flags & compressedOops) != 0) != UseCompressedOops) {
417+
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with UseCompressedOops = %s", UseCompressedOops ? "false" : "true");
418+
AOTStubCaching = false;
432419
}
433420
if (_compressedOopShift != (uint)CompressedOops::shift()) {
434421
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with different CompressedOops::shift(): %d vs current %d", _compressedOopShift, CompressedOops::shift());
435-
return false;
436-
}
437-
if (_compressedKlassShift != (uint)CompressedKlassPointers::shift()) {
438-
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with CompressedKlassPointers::shift() = %d vs current %d", _compressedKlassShift, CompressedKlassPointers::shift());
439-
return false;
440-
}
441-
if (_contendedPaddingWidth != (uint)ContendedPaddingWidth) {
442-
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with ContendedPaddingWidth = %d vs current %d", _contendedPaddingWidth, ContendedPaddingWidth);
443-
return false;
444-
}
445-
if (_objectAlignment != (uint)ObjectAlignmentInBytes) {
446-
log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with ObjectAlignmentInBytes = %d vs current %d", _objectAlignment, ObjectAlignmentInBytes);
447-
return false;
422+
AOTStubCaching = false;
448423
}
449424

450425
// This should be the last check as it only disables AOTStubCaching
@@ -456,7 +431,7 @@ bool AOTCodeCache::Config::verify() const {
456431
return true;
457432
}
458433

459-
bool AOTCodeCache::Header::verify_config(uint load_size) const {
434+
bool AOTCodeCache::Header::verify(uint load_size) const {
460435
if (_version != AOT_CODE_VERSION) {
461436
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);
462437
return false;
@@ -857,6 +832,10 @@ bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind
857832
#endif /* PRODUCT */
858833

859834
if (!cache->write_relocations(blob)) {
835+
if (!cache->failed()) {
836+
// We may miss an address in AOT table - skip this code blob.
837+
cache->set_write_position(entry_position);
838+
}
860839
return false;
861840
}
862841

@@ -985,6 +964,10 @@ CodeBlob* AOTCodeReader::compile_code_blob(const char* name, int entry_offset_co
985964

986965
// ------------ process code and data --------------
987966

967+
// Can't use -1. It is valid value for jump to iteself destination
968+
// used by static call stub: see NativeJump::jump_destination().
969+
#define BAD_ADDRESS_ID -2
970+
988971
bool AOTCodeCache::write_relocations(CodeBlob& code_blob) {
989972
GrowableArray<uint> reloc_data;
990973
RelocIterator iter(&code_blob);
@@ -1001,16 +984,24 @@ bool AOTCodeCache::write_relocations(CodeBlob& code_blob) {
1001984
if (dest == r->addr()) { // possible call via trampoline on Aarch64
1002985
dest = (address)-1; // do nothing in this case when loading this relocation
1003986
}
1004-
reloc_data.at_put(idx, _table->id_for_address(dest, iter, &code_blob));
987+
int id = _table->id_for_address(dest, iter, &code_blob);
988+
if (id == BAD_ADDRESS_ID) {
989+
return false;
990+
}
991+
reloc_data.at_put(idx, id);
1005992
break;
1006993
}
1007994
case relocInfo::runtime_call_w_cp_type:
1008-
fatal("runtime_call_w_cp_type unimplemented");
1009-
break;
995+
log_debug(aot, codecache, reloc)("runtime_call_w_cp_type relocation is not implemented");
996+
return false;
1010997
case relocInfo::external_word_type: {
1011998
// Record offset of runtime target
1012999
address target = ((external_word_Relocation*)iter.reloc())->target();
1013-
reloc_data.at_put(idx, _table->id_for_address(target, iter, &code_blob));
1000+
int id = _table->id_for_address(target, iter, &code_blob);
1001+
if (id == BAD_ADDRESS_ID) {
1002+
return false;
1003+
}
1004+
reloc_data.at_put(idx, id);
10141005
break;
10151006
}
10161007
case relocInfo::internal_word_type:
@@ -1020,7 +1011,8 @@ bool AOTCodeCache::write_relocations(CodeBlob& code_blob) {
10201011
case relocInfo::post_call_nop_type:
10211012
break;
10221013
default:
1023-
fatal("relocation %d unimplemented", (int)iter.type());
1014+
log_debug(aot, codecache, reloc)("relocation %d unimplemented", (int)iter.type());
1015+
return false;
10241016
break;
10251017
}
10261018
if (log.is_enabled()) {
@@ -1069,7 +1061,8 @@ void AOTCodeReader::fix_relocations(CodeBlob* code_blob) {
10691061
break;
10701062
}
10711063
case relocInfo::runtime_call_w_cp_type:
1072-
fatal("runtime_call_w_cp_type unimplemented");
1064+
// this relocation should not be in cache (see write_relocations)
1065+
assert(false, "runtime_call_w_cp_type relocation is not implemented");
10731066
break;
10741067
case relocInfo::external_word_type: {
10751068
address target = _cache->address_for_id(reloc_data[j]);
@@ -1095,7 +1088,7 @@ void AOTCodeReader::fix_relocations(CodeBlob* code_blob) {
10951088
case relocInfo::post_call_nop_type:
10961089
break;
10971090
default:
1098-
fatal("relocation %d unimplemented", (int)iter.type());
1091+
assert(false,"relocation %d unimplemented", (int)iter.type());
10991092
break;
11001093
}
11011094
if (log.is_enabled()) {
@@ -1397,9 +1390,13 @@ void AOTCodeAddressTable::init_shared_blobs() {
13971390
if (_complete || initializing_shared_blobs) return; // Done already
13981391
initializing_shared_blobs = true;
13991392
address* blobs_addr = NEW_C_HEAP_ARRAY(address, _blobs_max, mtCode);
1393+
1394+
// Divide _shared_blobs_addr array to chunks because they could be initialized in parrallel
14001395
_shared_blobs_addr = blobs_addr;
14011396
_C1_blobs_addr = _shared_blobs_addr + _shared_blobs_max;
1402-
_shared_blobs_length = _C1_blobs_length = 0;
1397+
1398+
_shared_blobs_length = 0;
1399+
_C1_blobs_length = 0;
14031400

14041401
// clear the address table
14051402
memset(blobs_addr, 0, sizeof(address)* _blobs_max);
@@ -1556,7 +1553,7 @@ const char* AOTCodeAddressTable::add_C_string(const char* str) {
15561553
}
15571554
return dup;
15581555
} else {
1559-
fatal("Number of C strings >= MAX_STR_COUNT");
1556+
assert(false, "Number of C strings >= MAX_STR_COUNT");
15601557
}
15611558
}
15621559
return str;
@@ -1595,13 +1592,11 @@ static int search_address(address addr, address* table, uint length) {
15951592
return i;
15961593
}
15971594
}
1598-
return -1;
1595+
return BAD_ADDRESS_ID;
15991596
}
16001597

16011598
address AOTCodeAddressTable::address_for_id(int idx) {
1602-
if (!_extrs_complete) {
1603-
fatal("AOT Code Cache VM runtime addresses table is not complete");
1604-
}
1599+
assert(_extrs_complete, "AOT Code Cache VM runtime addresses table is not complete");
16051600
if (idx == -1) {
16061601
return (address)-1;
16071602
}
@@ -1612,6 +1607,7 @@ address AOTCodeAddressTable::address_for_id(int idx) {
16121607
}
16131608
if (idx < 0) {
16141609
fatal("Incorrect id %d for AOT Code Cache addresses table", id);
1610+
return nullptr;
16151611
}
16161612
// no need to compare unsigned id against 0
16171613
if (/* id >= _extrs_base && */ id < _extrs_length) {
@@ -1634,9 +1630,7 @@ address AOTCodeAddressTable::address_for_id(int idx) {
16341630
}
16351631

16361632
int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeBlob* code_blob) {
1637-
if (!_extrs_complete) {
1638-
fatal("AOT Code Cache VM runtime addresses table is not complete");
1639-
}
1633+
assert(_extrs_complete, "AOT Code Cache VM runtime addresses table is not complete");
16401634
int id = -1;
16411635
if (addr == (address)-1) { // Static call stub has jump to itself
16421636
return id;
@@ -1655,7 +1649,7 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB
16551649
desc = StubCodeDesc::desc_for(addr + frame::pc_return_offset);
16561650
}
16571651
const char* sub_name = (desc != nullptr) ? desc->name() : "<unknown>";
1658-
fatal("Address " INTPTR_FORMAT " for Stub:%s is missing in AOT Code Cache addresses table", p2i(addr), sub_name);
1652+
assert(false, "Address " INTPTR_FORMAT " for Stub:%s is missing in AOT Code Cache addresses table", p2i(addr), sub_name);
16591653
} else {
16601654
return id + _stubs_base;
16611655
}
@@ -1666,7 +1660,7 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB
16661660
int id_base = _shared_blobs_base;
16671661
id = search_address(addr, _shared_blobs_addr, _blobs_max);
16681662
if (id < 0) {
1669-
fatal("Address " INTPTR_FORMAT " for Blob:%s is missing in AOT Code Cache addresses table", p2i(addr), cb->name());
1663+
assert(false, "Address " INTPTR_FORMAT " for Blob:%s is missing in AOT Code Cache addresses table", p2i(addr), cb->name());
16701664
} else {
16711665
return id_base + id;
16721666
}
@@ -1687,16 +1681,20 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB
16871681
assert(dist > (uint)(_all_max + MAX_STR_COUNT), "change encoding of distance");
16881682
return dist;
16891683
}
1684+
#ifdef ASSERT
16901685
reloc.print_current_on(tty);
16911686
code_blob->print_on(tty);
16921687
code_blob->print_code_on(tty);
1693-
fatal("Address " INTPTR_FORMAT " for runtime target '%s+%d' is missing in AOT Code Cache addresses table", p2i(addr), func_name, offset);
1688+
assert(false, "Address " INTPTR_FORMAT " for runtime target '%s+%d' is missing in AOT Code Cache addresses table", p2i(addr), func_name, offset);
1689+
#endif
16941690
} else {
1691+
#ifdef ASSERT
16951692
reloc.print_current_on(tty);
16961693
code_blob->print_on(tty);
16971694
code_blob->print_code_on(tty);
16981695
os::find(addr, tty);
1699-
fatal("Address " INTPTR_FORMAT " for <unknown>/('%s') is missing in AOT Code Cache addresses table", p2i(addr), (const char*)addr);
1696+
assert(false, "Address " INTPTR_FORMAT " for <unknown>/('%s') is missing in AOT Code Cache addresses table", p2i(addr), (const char*)addr);
1697+
#endif
17001698
}
17011699
} else {
17021700
return _extrs_base + id;

0 commit comments

Comments
 (0)