@@ -1056,8 +1056,10 @@ class BoxCacheBase : public CHeapObj<mtCompiler> {
1056
1056
char * klass_name_str = klass_name->as_C_string ();
1057
1057
InstanceKlass* ik = SystemDictionary::find_instance_klass (thread, klass_name, Handle (), Handle ());
1058
1058
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
+ }
1061
1063
return ik;
1062
1064
}
1063
1065
};
@@ -1070,11 +1072,17 @@ template<typename PrimitiveType, typename CacheType, typename BoxType> class Box
1070
1072
static BoxCache<PrimitiveType, CacheType, BoxType> *_singleton;
1071
1073
BoxCache (Thread* thread) {
1072
1074
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
+ }
1078
1086
}
1079
1087
~BoxCache () {
1080
1088
JNIHandles::destroy_global (_cache);
@@ -1096,7 +1104,11 @@ template<typename PrimitiveType, typename CacheType, typename BoxType> class Box
1096
1104
}
1097
1105
return nullptr ;
1098
1106
}
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
+ }
1100
1112
// Have to cast to avoid little/big-endian problems.
1101
1113
if (sizeof (PrimitiveType) > sizeof (jint)) {
1102
1114
jlong value = (jlong)raw_value;
@@ -1126,8 +1138,13 @@ class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> {
1126
1138
static BooleanBoxCache *_singleton;
1127
1139
BooleanBoxCache (Thread *thread) {
1128
1140
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
+ }
1131
1148
}
1132
1149
~BooleanBoxCache () {
1133
1150
JNIHandles::destroy_global (_true_cache);
@@ -1143,7 +1160,11 @@ class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> {
1143
1160
}
1144
1161
return _singleton;
1145
1162
}
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
+ }
1147
1168
// Have to cast to avoid little/big-endian problems.
1148
1169
jboolean value = (jboolean)*((jint*)&raw_value);
1149
1170
return lookup (value);
@@ -1158,18 +1179,18 @@ class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> {
1158
1179
1159
1180
BooleanBoxCache* BooleanBoxCache::_singleton = nullptr ;
1160
1181
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) {
1162
1183
Klass* k = java_lang_Class::as_Klass (bv->klass ()->as_ConstantOopReadValue ()->value ()());
1163
1184
BasicType box_type = vmClasses::box_klass_type (k);
1164
1185
if (box_type != T_OBJECT) {
1165
1186
StackValue* value = StackValue::create_stack_value (fr, reg_map, bv->field_at (box_type == T_LONG ? 1 : 0 ));
1166
1187
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 );
1173
1194
default :;
1174
1195
}
1175
1196
}
@@ -1193,21 +1214,26 @@ bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, RegisterMap*
1193
1214
Klass* k = java_lang_Class::as_Klass (sv->klass ()->as_ConstantOopReadValue ()->value ()());
1194
1215
oop obj = nullptr ;
1195
1216
1217
+ bool cache_init_error = false ;
1196
1218
if (k->is_instance_klass ()) {
1197
1219
#if INCLUDE_JVMCI
1198
1220
CompiledMethod* cm = fr->cb ()->as_compiled_method_or_null ();
1199
1221
if (cm->is_compiled_by_jvmci () && sv->is_auto_box ()) {
1200
1222
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);
1202
1224
if (obj != nullptr ) {
1203
1225
// Set the flag to indicate the box came from a cache, so that we can skip the field reassignment for it.
1204
1226
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 ;
1205
1231
}
1206
1232
}
1207
1233
#endif // INCLUDE_JVMCI
1208
1234
1209
1235
InstanceKlass* ik = InstanceKlass::cast (k);
1210
- if (obj == nullptr ) {
1236
+ if (obj == nullptr && !cache_init_error ) {
1211
1237
#ifdef COMPILER2
1212
1238
if (EnableVectorSupport && VectorSupport::is_vector (ik)) {
1213
1239
obj = VectorSupport::allocate_vector (ik, fr, reg_map, sv, THREAD);
@@ -1233,7 +1259,7 @@ bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, RegisterMap*
1233
1259
}
1234
1260
1235
1261
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" );
1237
1263
CLEAR_PENDING_EXCEPTION;
1238
1264
sv->set_value (obj);
1239
1265
}
0 commit comments