Skip to content

Commit 3c54e03

Browse files
committed
8251945: SIGSEGV in PackageEntry::purge_qualified_exports()
Reviewed-by: adinn
1 parent cbe9c1b commit 3c54e03

File tree

12 files changed

+253
-39
lines changed

12 files changed

+253
-39
lines changed

src/hotspot/share/classfile/classLoaderData.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1041,22 +1041,24 @@ bool ClassLoaderDataGraph::_metaspace_oom = false;
10411041
// Add a new class loader data node to the list. Assign the newly created
10421042
// ClassLoaderData into the java/lang/ClassLoader object as a hidden field
10431043
ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_anonymous) {
1044-
NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the
1045-
// ClassLoaderData in the graph since the CLD
1046-
// contains oops in _handles that must be walked.
1047-
1048-
ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous);
1044+
ClassLoaderData* cld;
10491045

10501046
if (!is_anonymous) {
1051-
// First, Atomically set it
1052-
ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
1053-
if (old != NULL) {
1054-
delete cld;
1055-
// Returns the data.
1056-
return old;
1047+
MutexLocker ml(ClassLoaderDataGraph_lock);
1048+
cld = java_lang_ClassLoader::loader_data_raw(loader());
1049+
if (cld != NULL) {
1050+
return cld;
10571051
}
1052+
cld = new ClassLoaderData(loader, is_anonymous);
1053+
java_lang_ClassLoader::release_set_loader_data(loader(), cld);
1054+
} else {
1055+
cld = new ClassLoaderData(loader, is_anonymous);
10581056
}
10591057

1058+
NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the
1059+
// ClassLoaderData in the graph since the CLD
1060+
// contains oops in _handles that must be walked.
1061+
10601062
// We won the race, and therefore the task of adding the data to the list of
10611063
// class loader data
10621064
ClassLoaderData** list_head = &_head;

src/hotspot/share/classfile/classLoaderData.inline.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,7 @@ inline ClassLoaderData* ClassLoaderData::class_loader_data_or_null(oop loader) {
4545
if (loader == NULL) {
4646
return ClassLoaderData::the_null_class_loader_data();
4747
}
48-
return java_lang_ClassLoader::loader_data(loader);
48+
return java_lang_ClassLoader::loader_data_acquire(loader);
4949
}
5050

5151
inline ClassLoaderData* ClassLoaderData::class_loader_data(oop loader) {
@@ -59,7 +59,7 @@ inline ClassLoaderData *ClassLoaderDataGraph::find_or_create(Handle loader) {
5959
guarantee(loader() != NULL && oopDesc::is_oop(loader()), "Loader must be oop");
6060
// Gets the class loader data out of the java/lang/ClassLoader object, if non-null
6161
// it's already in the loader_data, so no need to add
62-
ClassLoaderData* loader_data= java_lang_ClassLoader::loader_data(loader());
62+
ClassLoaderData* loader_data= java_lang_ClassLoader::loader_data_acquire(loader());
6363
if (loader_data) {
6464
return loader_data;
6565
}

src/hotspot/share/classfile/classLoaderStats.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -139,7 +139,7 @@ void ClassLoaderStatsClosure::print() {
139139

140140

141141
void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
142-
while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) {
142+
while (cl != NULL && java_lang_ClassLoader::loader_data_acquire(cl) == NULL) {
143143
// This classloader has not loaded any classes
144144
ClassLoaderStats** cls_ptr = _stats->get(cl);
145145
if (cls_ptr == NULL) {

src/hotspot/share/classfile/javaClasses.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -4020,14 +4020,20 @@ int java_lang_ClassLoader::name_offset = -1;
40204020
int java_lang_ClassLoader::nameAndId_offset = -1;
40214021
int java_lang_ClassLoader::unnamedModule_offset = -1;
40224022

4023-
ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
4023+
ClassLoaderData* java_lang_ClassLoader::loader_data_acquire(oop loader) {
40244024
assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
4025-
return HeapAccess<>::load_at(loader, _loader_data_offset);
4025+
return HeapAccess<MO_ACQUIRE>::load_at(loader, _loader_data_offset);
40264026
}
40274027

4028-
ClassLoaderData* java_lang_ClassLoader::cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data) {
4028+
ClassLoaderData* java_lang_ClassLoader::loader_data_raw(oop loader) {
40294029
assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
4030-
return HeapAccess<>::atomic_cmpxchg_at(new_data, loader, _loader_data_offset, expected_data);
4030+
return RawAccess<>::load_at(loader, _loader_data_offset);
4031+
}
4032+
4033+
void java_lang_ClassLoader::release_set_loader_data(oop loader, ClassLoaderData* new_data) {
4034+
assert(loader != NULL, "loader must not be NULL");
4035+
assert(oopDesc::is_oop(loader), "loader must be oop");
4036+
HeapAccess<MO_RELEASE>::store_at(loader, _loader_data_offset, new_data);
40314037
}
40324038

40334039
#define CLASSLOADER_FIELDS_DO(macro) \

src/hotspot/share/classfile/javaClasses.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1320,8 +1320,9 @@ class java_lang_ClassLoader : AllStatic {
13201320
static void compute_offsets();
13211321
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
13221322

1323-
static ClassLoaderData* loader_data(oop loader);
1324-
static ClassLoaderData* cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data);
1323+
static ClassLoaderData* loader_data_acquire(oop loader);
1324+
static ClassLoaderData* loader_data_raw(oop loader);
1325+
static void release_set_loader_data(oop loader, ClassLoaderData* new_data);
13251326

13261327
static oop parent(oop loader);
13271328
static oop name(oop loader);

src/hotspot/share/gc/parallel/psCompactionManager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -183,7 +183,7 @@ void InstanceMirrorKlass::oop_pc_follow_contents(oop obj, ParCompactionManager*
183183
void InstanceClassLoaderKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
184184
InstanceKlass::oop_pc_follow_contents(obj, cm);
185185

186-
ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
186+
ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data_acquire(obj);
187187
if (loader_data != NULL) {
188188
cm->follow_class_loader(loader_data);
189189
}

src/hotspot/share/jfr/periodic/jfrPeriodic.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -468,9 +468,9 @@ class JfrClassLoaderStatsClosure : public ClassLoaderStatsClosure {
468468

469469
bool do_entry(oop const& key, ClassLoaderStats* const& cls) {
470470
const ClassLoaderData* this_cld = cls->_class_loader != NULL ?
471-
java_lang_ClassLoader::loader_data(cls->_class_loader) : (ClassLoaderData*)NULL;
471+
java_lang_ClassLoader::loader_data_acquire(cls->_class_loader) : (ClassLoaderData*)NULL;
472472
const ClassLoaderData* parent_cld = cls->_parent != NULL ?
473-
java_lang_ClassLoader::loader_data(cls->_parent) : (ClassLoaderData*)NULL;
473+
java_lang_ClassLoader::loader_data_acquire(cls->_parent) : (ClassLoaderData*)NULL;
474474
EventClassLoaderStatistics event;
475475
event.set_classLoader(this_cld);
476476
event.set_parentClassLoader(parent_cld);

src/hotspot/share/oops/instanceClassLoaderKlass.inline.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@ inline void InstanceClassLoaderKlass::oop_oop_iterate(oop obj, OopClosureType* c
3939
InstanceKlass::oop_oop_iterate<T>(obj, closure);
4040

4141
if (Devirtualizer::do_metadata(closure)) {
42-
ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);
42+
ClassLoaderData* cld = java_lang_ClassLoader::loader_data_acquire(obj);
4343
// cld can be null if we have a non-registered class loader.
4444
if (cld != NULL) {
4545
Devirtualizer::do_cld(closure, cld);
@@ -61,7 +61,7 @@ inline void InstanceClassLoaderKlass::oop_oop_iterate_bounded(oop obj, OopClosur
6161

6262
if (Devirtualizer::do_metadata(closure)) {
6363
if (mr.contains(obj)) {
64-
ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);
64+
ClassLoaderData* cld = java_lang_ClassLoader::loader_data_acquire(obj);
6565
// cld can be null if we have a non-registered class loader.
6666
if (cld != NULL) {
6767
Devirtualizer::do_cld(closure, cld);

src/hotspot/share/prims/whitebox.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1550,7 +1550,7 @@ WB_ENTRY(jlong, WB_AllocateMetaspace(JNIEnv* env, jobject wb, jobject class_load
15501550

15511551
oop class_loader_oop = JNIHandles::resolve(class_loader);
15521552
ClassLoaderData* cld = class_loader_oop != NULL
1553-
? java_lang_ClassLoader::loader_data(class_loader_oop)
1553+
? java_lang_ClassLoader::loader_data_acquire(class_loader_oop)
15541554
: ClassLoaderData::the_null_class_loader_data();
15551555

15561556
void* metadata = MetadataFactory::new_array<u1>(cld, WhiteBox::array_bytes_to_length((size_t)size), thread);
@@ -1561,7 +1561,7 @@ WB_END
15611561
WB_ENTRY(void, WB_FreeMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong addr, jlong size))
15621562
oop class_loader_oop = JNIHandles::resolve(class_loader);
15631563
ClassLoaderData* cld = class_loader_oop != NULL
1564-
? java_lang_ClassLoader::loader_data(class_loader_oop)
1564+
? java_lang_ClassLoader::loader_data_acquire(class_loader_oop)
15651565
: ClassLoaderData::the_null_class_loader_data();
15661566

15671567
MetadataFactory::free_array(cld, (Array<u1>*)(uintptr_t)addr);

src/hotspot/share/runtime/mutexLocker.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -148,6 +148,7 @@ Mutex* UnsafeJlong_lock = NULL;
148148
Monitor* CodeHeapStateAnalytics_lock = NULL;
149149

150150
Mutex* MetaspaceExpand_lock = NULL;
151+
Mutex* ClassLoaderDataGraph_lock = NULL;
151152
Mutex* ThreadIdTableCreate_lock = NULL;
152153
Monitor* ThreadsSMRDelete_lock = NULL;
153154
Mutex* SharedDecoder_lock = NULL;
@@ -239,6 +240,7 @@ void mutex_init() {
239240
def(OopMapCacheAlloc_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for oop_map_cache allocation.
240241

241242
def(MetaspaceExpand_lock , PaddedMutex , leaf-1, true, Monitor::_safepoint_check_never);
243+
def(ClassLoaderDataGraph_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_always);
242244

243245
def(Patching_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never); // used for safepointing and code patching.
244246
def(Service_lock , PaddedMonitor, special, true, Monitor::_safepoint_check_never); // used for service thread operations

0 commit comments

Comments
 (0)