8215575: C2 crash: assert(get_instanceKlass()->is_loaded()) failed: must be at least loaded
Summary: Set InstanceKlass::loaded before adding classes to the subklass list, which can be read concurrently by the compiler.
Reviewed-by: dholmes, eosterlund
--- a/src/hotspot/share/classfile/systemDictionary.cpp Wed Jan 09 08:07:23 2019 -0500
+++ b/src/hotspot/share/classfile/systemDictionary.cpp Wed Jan 09 07:52:45 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1788,14 +1788,17 @@
assert(k != NULL, "just checking");
assert_locked_or_safepoint(Compile_lock);
- // Link into hierachy. Make sure the vtables are initialized before linking into
+ k->set_init_state(InstanceKlass::loaded);
+ // make sure init_state store is already done.
+ // The compiler reads the hierarchy outside of the Compile_lock.
+ // Access ordering is used to add to hierarchy.
+
+ // Link into hierachy.
k->append_to_sibling_list(); // add to superklass/sibling list
k->process_interfaces(THREAD); // handle all "implements" declarations
- k->set_init_state(InstanceKlass::loaded);
+
// Now flush all code that depended on old class hierarchy.
// Note: must be done *after* linking k into the hierarchy (was bug 12/9/97)
- // Also, first reinitialize vtable because it may have gotten out of synch
- // while the new class wasn't connected to the class hierarchy.
CodeCache::flush_dependents_on(k);
}
--- a/src/hotspot/share/oops/instanceKlass.cpp Wed Jan 09 08:07:23 2019 -0500
+++ b/src/hotspot/share/oops/instanceKlass.cpp Wed Jan 09 07:52:45 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3662,14 +3662,14 @@
}
}
+void InstanceKlass::set_init_state(ClassState state) {
#ifdef ASSERT
-void InstanceKlass::set_init_state(ClassState state) {
bool good_state = is_shared() ? (_init_state <= state)
: (_init_state < state);
assert(good_state || state == allocated, "illegal state transition");
+#endif
_init_state = (u1)state;
}
-#endif
#if INCLUDE_JVMTI
--- a/src/hotspot/share/oops/instanceKlass.hpp Wed Jan 09 08:07:23 2019 -0500
+++ b/src/hotspot/share/oops/instanceKlass.hpp Wed Jan 09 07:52:45 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1242,11 +1242,7 @@
private:
// initialization state
-#ifdef ASSERT
void set_init_state(ClassState state);
-#else
- void set_init_state(ClassState state) { _init_state = (u1)state; }
-#endif
void set_rewritten() { _misc_flags |= _misc_rewritten; }
void set_init_thread(Thread *thread) { _init_thread = thread; }