Skip to content

Commit e012685

Browse files
author
Doug Simon
committed
8305066: [JVMCI] guarantee(ik->is_initialized()) failed: java/lang/Long$LongCache must be initialized
Reviewed-by: never, iveresov
1 parent fe42312 commit e012685

File tree

4 files changed

+49
-32
lines changed

4 files changed

+49
-32
lines changed

src/hotspot/share/runtime/deoptimization.cpp

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

11591180
BooleanBoxCache* 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
}

src/hotspot/share/runtime/deoptimization.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ class Deoptimization : AllStatic {
185185

186186
#if INCLUDE_JVMCI
187187
static address deoptimize_for_missing_exception_handler(CompiledMethod* cm);
188-
static oop get_cached_box(AutoBoxObjectValue* bv, frame* fr, RegisterMap* reg_map, TRAPS);
188+
static oop get_cached_box(AutoBoxObjectValue* bv, frame* fr, RegisterMap* reg_map, bool& cache_init_error, TRAPS);
189189
#endif
190190

191191
private:

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public static VirtualObject get(ResolvedJavaType type, int id) {
7474
* @param id a unique id that identifies the object within the debug information for one
7575
* position in the compiled code.
7676
* @param isAutoBox a flag that tells the runtime that the object may be a boxed primitive and
77-
* that it possibly needs to be obtained for the box cache instead of creating a new
77+
* that it possibly needs to be obtained from the box cache instead of creating a new
7878
* instance.
7979
* @return a new {@link VirtualObject} instance.
8080
*/

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,6 @@ public static HotSpotJVMCIRuntime runtime() {
192192
// initialized.
193193
JVMCI.getRuntime();
194194
}
195-
// Make sure all the primitive box caches are populated (required to properly
196-
// materialize boxed primitives
197-
// during deoptimization).
198-
Boolean.valueOf(false);
199-
Byte.valueOf((byte) 0);
200-
Short.valueOf((short) 0);
201-
Character.valueOf((char) 0);
202-
Integer.valueOf(0);
203-
Long.valueOf(0);
204195
}
205196
}
206197
return result;

0 commit comments

Comments
 (0)