@@ -1056,8 +1056,10 @@ class BoxCacheBase : public CHeapObj<mtCompiler> {
10561056 char * klass_name_str = klass_name->as_C_string ();
10571057 InstanceKlass* ik = SystemDictionary::find_instance_klass (thread, klass_name, Handle (), Handle ());
10581058 guarantee (ik != nullptr , " %s must be loaded" , klass_name_str);
1059- guarantee (ik->is_initialized (), " %s must be initialized" , klass_name_str);
1060- CacheType::compute_offsets (ik);
1059+ if (!ik->is_in_error_state ()) {
1060+ guarantee (ik->is_initialized (), " %s must be initialized" , klass_name_str);
1061+ CacheType::compute_offsets (ik);
1062+ }
10611063 return ik;
10621064 }
10631065};
@@ -1070,11 +1072,17 @@ template<typename PrimitiveType, typename CacheType, typename BoxType> class Box
10701072 static BoxCache<PrimitiveType, CacheType, BoxType> *_singleton;
10711073 BoxCache (Thread* thread) {
10721074 InstanceKlass* ik = BoxCacheBase<CacheType>::find_cache_klass (thread, CacheType::symbol ());
1073- objArrayOop cache = CacheType::cache (ik);
1074- assert (cache->length () > 0 , " Empty cache" );
1075- _low = BoxType::value (cache->obj_at (0 ));
1076- _high = _low + cache->length () - 1 ;
1077- _cache = JNIHandles::make_global (Handle (thread, cache));
1075+ if (ik->is_in_error_state ()) {
1076+ _low = 1 ;
1077+ _high = 0 ;
1078+ _cache = nullptr ;
1079+ } else {
1080+ objArrayOop cache = CacheType::cache (ik);
1081+ assert (cache->length () > 0 , " Empty cache" );
1082+ _low = BoxType::value (cache->obj_at (0 ));
1083+ _high = _low + cache->length () - 1 ;
1084+ _cache = JNIHandles::make_global (Handle (thread, cache));
1085+ }
10781086 }
10791087 ~BoxCache () {
10801088 JNIHandles::destroy_global (_cache);
@@ -1096,7 +1104,11 @@ template<typename PrimitiveType, typename CacheType, typename BoxType> class Box
10961104 }
10971105 return nullptr ;
10981106 }
1099- oop lookup_raw (intptr_t raw_value) {
1107+ oop lookup_raw (intptr_t raw_value, bool & cache_init_error) {
1108+ if (_cache == nullptr ) {
1109+ cache_init_error = true ;
1110+ return nullptr ;
1111+ }
11001112 // Have to cast to avoid little/big-endian problems.
11011113 if (sizeof (PrimitiveType) > sizeof (jint)) {
11021114 jlong value = (jlong)raw_value;
@@ -1126,8 +1138,13 @@ class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> {
11261138 static BooleanBoxCache *_singleton;
11271139 BooleanBoxCache (Thread *thread) {
11281140 InstanceKlass* ik = find_cache_klass (thread, java_lang_Boolean::symbol ());
1129- _true_cache = JNIHandles::make_global (Handle (thread, java_lang_Boolean::get_TRUE (ik)));
1130- _false_cache = JNIHandles::make_global (Handle (thread, java_lang_Boolean::get_FALSE (ik)));
1141+ if (ik->is_in_error_state ()) {
1142+ _true_cache = nullptr ;
1143+ _false_cache = nullptr ;
1144+ } else {
1145+ _true_cache = JNIHandles::make_global (Handle (thread, java_lang_Boolean::get_TRUE (ik)));
1146+ _false_cache = JNIHandles::make_global (Handle (thread, java_lang_Boolean::get_FALSE (ik)));
1147+ }
11311148 }
11321149 ~BooleanBoxCache () {
11331150 JNIHandles::destroy_global (_true_cache);
@@ -1143,7 +1160,11 @@ class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> {
11431160 }
11441161 return _singleton;
11451162 }
1146- oop lookup_raw (intptr_t raw_value) {
1163+ oop lookup_raw (intptr_t raw_value, bool & cache_in_error) {
1164+ if (_true_cache == nullptr ) {
1165+ cache_in_error = true ;
1166+ return nullptr ;
1167+ }
11471168 // Have to cast to avoid little/big-endian problems.
11481169 jboolean value = (jboolean)*((jint*)&raw_value);
11491170 return lookup (value);
@@ -1158,18 +1179,18 @@ class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> {
11581179
11591180BooleanBoxCache* BooleanBoxCache::_singleton = nullptr ;
11601181
1161- oop Deoptimization::get_cached_box (AutoBoxObjectValue* bv, frame* fr, RegisterMap* reg_map, TRAPS) {
1182+ oop Deoptimization::get_cached_box (AutoBoxObjectValue* bv, frame* fr, RegisterMap* reg_map, bool & cache_init_error, TRAPS) {
11621183 Klass* k = java_lang_Class::as_Klass (bv->klass ()->as_ConstantOopReadValue ()->value ()());
11631184 BasicType box_type = vmClasses::box_klass_type (k);
11641185 if (box_type != T_OBJECT) {
11651186 StackValue* value = StackValue::create_stack_value (fr, reg_map, bv->field_at (box_type == T_LONG ? 1 : 0 ));
11661187 switch (box_type) {
1167- case T_INT: return IntegerBoxCache::singleton (THREAD)->lookup_raw (value->get_int ());
1168- case T_CHAR: return CharacterBoxCache::singleton (THREAD)->lookup_raw (value->get_int ());
1169- case T_SHORT: return ShortBoxCache::singleton (THREAD)->lookup_raw (value->get_int ());
1170- case T_BYTE: return ByteBoxCache::singleton (THREAD)->lookup_raw (value->get_int ());
1171- case T_BOOLEAN: return BooleanBoxCache::singleton (THREAD)->lookup_raw (value->get_int ());
1172- case T_LONG: return LongBoxCache::singleton (THREAD)->lookup_raw (value->get_int ());
1188+ case T_INT: return IntegerBoxCache::singleton (THREAD)->lookup_raw (value->get_int (), cache_init_error );
1189+ case T_CHAR: return CharacterBoxCache::singleton (THREAD)->lookup_raw (value->get_int (), cache_init_error );
1190+ case T_SHORT: return ShortBoxCache::singleton (THREAD)->lookup_raw (value->get_int (), cache_init_error );
1191+ case T_BYTE: return ByteBoxCache::singleton (THREAD)->lookup_raw (value->get_int (), cache_init_error );
1192+ case T_BOOLEAN: return BooleanBoxCache::singleton (THREAD)->lookup_raw (value->get_int (), cache_init_error );
1193+ case T_LONG: return LongBoxCache::singleton (THREAD)->lookup_raw (value->get_int (), cache_init_error );
11731194 default :;
11741195 }
11751196 }
@@ -1193,21 +1214,26 @@ bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, RegisterMap*
11931214 Klass* k = java_lang_Class::as_Klass (sv->klass ()->as_ConstantOopReadValue ()->value ()());
11941215 oop obj = nullptr ;
11951216
1217+ bool cache_init_error = false ;
11961218 if (k->is_instance_klass ()) {
11971219#if INCLUDE_JVMCI
11981220 CompiledMethod* cm = fr->cb ()->as_compiled_method_or_null ();
11991221 if (cm->is_compiled_by_jvmci () && sv->is_auto_box ()) {
12001222 AutoBoxObjectValue* abv = (AutoBoxObjectValue*) sv;
1201- obj = get_cached_box (abv, fr, reg_map, THREAD);
1223+ obj = get_cached_box (abv, fr, reg_map, cache_init_error, THREAD);
12021224 if (obj != nullptr ) {
12031225 // Set the flag to indicate the box came from a cache, so that we can skip the field reassignment for it.
12041226 abv->set_cached (true );
1227+ } else if (cache_init_error) {
1228+ // Results in an OOME which is valid (as opposed to a class initialization error)
1229+ // and is fine for the rare case a cache initialization failing.
1230+ failures = true ;
12051231 }
12061232 }
12071233#endif // INCLUDE_JVMCI
12081234
12091235 InstanceKlass* ik = InstanceKlass::cast (k);
1210- if (obj == nullptr ) {
1236+ if (obj == nullptr && !cache_init_error ) {
12111237#ifdef COMPILER2
12121238 if (EnableVectorSupport && VectorSupport::is_vector (ik)) {
12131239 obj = VectorSupport::allocate_vector (ik, fr, reg_map, sv, THREAD);
@@ -1233,7 +1259,7 @@ bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, RegisterMap*
12331259 }
12341260
12351261 assert (sv->value ().is_null (), " redundant reallocation" );
1236- assert (obj != nullptr || HAS_PENDING_EXCEPTION, " allocation should succeed or we should get an exception" );
1262+ assert (obj != nullptr || HAS_PENDING_EXCEPTION || cache_init_error , " allocation should succeed or we should get an exception" );
12371263 CLEAR_PENDING_EXCEPTION;
12381264 sv->set_value (obj);
12391265 }
0 commit comments