mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-3459: Fix race condition in ClassLoaderDataGraph::classes_do
InstanceKlass in ClassLoaderData can be uninitialized when ClassLoaderDataGraph::classes_do is called. Using ClassLoaderDataGraph::dictionary_classes_do is safe but problem is still persisting with anonymous classes.
This commit is contained in:
committed by
Vitaly Provodin
parent
9861d1cadf
commit
97e5abd8a1
@@ -361,6 +361,16 @@ void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::anonymous_or_hidden_classes_do(KlassClosure* klass_closure) {
|
||||
Thread* thread = Thread::current();
|
||||
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
|
||||
if (cld->has_class_mirror_holder()) {
|
||||
Handle holder(thread, cld->holder_phantom());
|
||||
cld->classes_do(klass_closure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
|
||||
ClassLoaderDataGraphIterator iter;
|
||||
while (ClassLoaderData* cld = iter.get_next()) {
|
||||
|
||||
@@ -78,6 +78,10 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
// for redefinition. These classes are removed during the next class unloading.
|
||||
// Walking the ClassLoaderDataGraph also includes hidden classes.
|
||||
static void classes_do(KlassClosure* klass_closure);
|
||||
|
||||
// Enhanced class redefinition
|
||||
static void anonymous_or_hidden_classes_do(KlassClosure* klass_closure);
|
||||
|
||||
static void classes_do(void f(Klass* const));
|
||||
static void methods_do(void f(Method*));
|
||||
static void modules_do(void f(ModuleEntry*));
|
||||
|
||||
@@ -2164,9 +2164,19 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
|
||||
|
||||
{
|
||||
MutexLocker mcld(ClassLoaderDataGraph_lock);
|
||||
ClassLoaderDataGraph::classes_do(&closure);
|
||||
|
||||
// 0. we can't use ClassLoaderDataGraph::classes_do since classes can be uninitialized in cld,
|
||||
// fully initialized class is in system dictionary
|
||||
// ClassLoaderDataGraph::classes_do(&closure);
|
||||
|
||||
// 1. Scan over dictionaries
|
||||
ClassLoaderDataGraph::dictionary_classes_do(&closure);
|
||||
|
||||
// 2. Anonymous or hidden class is not in dictionary, we have to iterate anonymous cld directly, but there is race cond...
|
||||
// TODO: review ... anonymous class is added to cld before InstanceKlass initialization,
|
||||
// find out how to check if the InstanceKlass is initialized
|
||||
ClassLoaderDataGraph::anonymous_or_hidden_classes_do(&closure);
|
||||
}
|
||||
//ClassLoaderDataGraph::dictionary_classes_do(&closure);
|
||||
|
||||
log_trace(redefine, class, load)("%d classes affected", _affected_klasses->length());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user