Projects
openEuler:24.03:SP1:Everything
openjdk-1.8.0
_service:tar_scm:8143408-Crash-during-InstanceK...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:8143408-Crash-during-InstanceKlass-unloading-when-cl.patch of Package openjdk-1.8.0
Date: Sat, 30 Mar 2024 07:13:14 +0000 Subject: 8143408: Crash during InstanceKlass unloading when clearing dependency context --- .../src/share/vm/code/dependencyContext.cpp | 40 ++++++++++--------- .../src/share/vm/code/dependencyContext.hpp | 4 ++ hotspot/src/share/vm/oops/instanceKlass.cpp | 16 +++++--- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/hotspot/src/share/vm/code/dependencyContext.cpp b/hotspot/src/share/vm/code/dependencyContext.cpp index 5c0af1e3..6cb0c330 100644 --- a/hotspot/src/share/vm/code/dependencyContext.cpp +++ b/hotspot/src/share/vm/code/dependencyContext.cpp @@ -218,6 +218,18 @@ int DependencyContext::remove_all_dependents() { return marked; } +void DependencyContext::wipe() { + assert_locked_or_safepoint(CodeCache_lock); + nmethodBucket* b = dependencies(); + set_dependencies(NULL); + set_has_stale_entries(false); + while (b != NULL) { + nmethodBucket* next = b->next(); + delete b; + b = next; + } +} + #ifndef PRODUCT void DependencyContext::print_dependent_nmethods(bool verbose) { int idx = 0; @@ -271,28 +283,31 @@ class TestDependencyContext { intptr_t _dependency_context; + DependencyContext dependencies() { + DependencyContext depContext(&_dependency_context); + return depContext; + } + TestDependencyContext() : _dependency_context(DependencyContext::EMPTY) { CodeCache_lock->lock_without_safepoint_check(); - DependencyContext depContext(&_dependency_context); - _nmethods[0] = reinterpret_cast<nmethod*>(0x8 * 0); _nmethods[1] = reinterpret_cast<nmethod*>(0x8 * 1); _nmethods[2] = reinterpret_cast<nmethod*>(0x8 * 2); - depContext.add_dependent_nmethod(_nmethods[2]); - depContext.add_dependent_nmethod(_nmethods[1]); - depContext.add_dependent_nmethod(_nmethods[0]); + dependencies().add_dependent_nmethod(_nmethods[2]); + dependencies().add_dependent_nmethod(_nmethods[1]); + dependencies().add_dependent_nmethod(_nmethods[0]); } ~TestDependencyContext() { - wipe(); + dependencies().wipe(); CodeCache_lock->unlock(); } static void testRemoveDependentNmethod(int id, bool delete_immediately) { TestDependencyContext c; - DependencyContext depContext(&c._dependency_context); + DependencyContext depContext = c.dependencies(); assert(!has_stale_entries(depContext), "check"); nmethod* nm = c._nmethods[id]; @@ -327,17 +342,6 @@ class TestDependencyContext { return ctx.has_stale_entries(); } - void wipe() { - DependencyContext ctx(&_dependency_context); - nmethodBucket* b = ctx.dependencies(); - ctx.set_dependencies(NULL); - ctx.set_has_stale_entries(false); - while (b != NULL) { - nmethodBucket* next = b->next(); - delete b; - b = next; - } - } }; void TestDependencyContext_test() { diff --git a/hotspot/src/share/vm/code/dependencyContext.hpp b/hotspot/src/share/vm/code/dependencyContext.hpp index 533112b8..414ce0c0 100644 --- a/hotspot/src/share/vm/code/dependencyContext.hpp +++ b/hotspot/src/share/vm/code/dependencyContext.hpp @@ -143,6 +143,10 @@ class DependencyContext : public StackObj { void expunge_stale_entries(); + // Unsafe deallocation of nmethodBuckets. Used in IK::release_C_heap_structures + // to clean up the context possibly containing live entries pointing to unloaded nmethods. + void wipe(); + #ifndef PRODUCT void print_dependent_nmethods(bool verbose); bool is_dependent_nmethod(nmethod* nm); diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 1bff1309..df44e531 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -2628,12 +2628,16 @@ void InstanceKlass::release_C_heap_structures() { } } - // release dependencies - { - DependencyContext ctx(&_dep_context); - int marked = ctx.remove_all_dependents(); - assert(marked == 0, "all dependencies should be already invalidated"); - } + // Release dependencies. + // It is desirable to use DC::remove_all_dependents() here, but, unfortunately, + // it is not safe (see JDK-8143408). The problem is that the klass dependency + // context can contain live dependencies, since there's a race between nmethod & + // klass unloading. If the klass is dead when nmethod unloading happens, relevant + // dependencies aren't removed from the context associated with the class (see + // nmethod::flush_dependencies). It ends up during klass unloading as seemingly + // live dependencies pointing to unloaded nmethods and causes a crash in + // DC::remove_all_dependents() when it touches unloaded nmethod. + dependencies().wipe(); // Deallocate breakpoint records if (breakpoints() != 0x0) { -- 2.17.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2