# HG changeset patch # User vlivanov # Date 1559817963 -10800 # Node ID 36cb654a690f8965e9072fe2cc208fe9e3924303 # Parent 3c905e67e3807c16afc546f869777203f7c019a5 8225141: Better handling of classes in error state in fast class initialization checks Reviewed-by: dlong, dholmes diff -r 3c905e67e380 -r 36cb654a690f src/hotspot/share/oops/instanceKlass.cpp --- a/src/hotspot/share/oops/instanceKlass.cpp Thu Jun 06 13:46:01 2019 +0300 +++ b/src/hotspot/share/oops/instanceKlass.cpp Thu Jun 06 13:46:03 2019 +0300 @@ -438,6 +438,8 @@ _static_field_size(parser.static_field_size()), _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())), _itable_len(parser.itable_size()), + _init_thread(NULL), + _init_state(allocated), _reference_type(parser.reference_type()) { set_vtable_length(parser.vtable_size()); @@ -1071,11 +1073,13 @@ Handle h_init_lock(THREAD, init_lock()); if (h_init_lock() != NULL) { ObjectLocker ol(h_init_lock, THREAD); + set_init_thread(NULL); // reset _init_thread before changing _init_state set_init_state(state); fence_and_clear_init_lock(); ol.notify_all(CHECK); } else { assert(h_init_lock() != NULL, "The initialization state should never be set twice"); + set_init_thread(NULL); // reset _init_thread before changing _init_state set_init_state(state); } } @@ -3710,6 +3714,7 @@ : (_init_state < state); assert(good_state || state == allocated, "illegal state transition"); #endif + assert(_init_thread == NULL, "should be cleared before state change"); _init_state = (u1)state; } diff -r 3c905e67e380 -r 36cb654a690f src/hotspot/share/oops/instanceKlass.hpp --- a/src/hotspot/share/oops/instanceKlass.hpp Thu Jun 06 13:46:01 2019 +0300 +++ b/src/hotspot/share/oops/instanceKlass.hpp Thu Jun 06 13:46:03 2019 +0300 @@ -247,7 +247,7 @@ u2 _misc_flags; u2 _minor_version; // minor version number of class file u2 _major_version; // major version number of class file - Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) + Thread* _init_thread; // Pointer to current thread doing initialization (to handle recursive initialization) OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily) JNIid* _jni_ids; // First JNI identifier for static fields in this class jmethodID* volatile _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none