Skip to content

Commit 245d53c

Browse files
committed
8347564: ZGC: Crash in DependencyContext::clean_unloading_dependents
Reviewed-by: rrich Backport-of: 14136f8b1106137317393bc2ab0a2db0d212f8d8
1 parent a1b0dea commit 245d53c

File tree

13 files changed

+24
-159
lines changed

13 files changed

+24
-159
lines changed

src/hotspot/share/classfile/javaClasses.cpp

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4435,28 +4435,31 @@ int java_lang_invoke_MethodType::rtype_slot_count(oop mt) {
44354435
// Support for java_lang_invoke_CallSite
44364436

44374437
int java_lang_invoke_CallSite::_target_offset;
4438-
int java_lang_invoke_CallSite::_context_offset;
4438+
int java_lang_invoke_CallSite::_vmdependencies_offset;
4439+
int java_lang_invoke_CallSite::_last_cleanup_offset;
44394440

44404441
#define CALLSITE_FIELDS_DO(macro) \
44414442
macro(_target_offset, k, "target", java_lang_invoke_MethodHandle_signature, false); \
4442-
macro(_context_offset, k, "context", java_lang_invoke_MethodHandleNatives_CallSiteContext_signature, false)
44434443

44444444
void java_lang_invoke_CallSite::compute_offsets() {
44454445
InstanceKlass* k = vmClasses::CallSite_klass();
44464446
CALLSITE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
4447+
CALLSITE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
44474448
}
44484449

44494450
#if INCLUDE_CDS
44504451
void java_lang_invoke_CallSite::serialize_offsets(SerializeClosure* f) {
44514452
CALLSITE_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
4453+
CALLSITE_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET);
44524454
}
44534455
#endif
44544456

4455-
oop java_lang_invoke_CallSite::context_no_keepalive(oop call_site) {
4457+
DependencyContext java_lang_invoke_CallSite::vmdependencies(oop call_site) {
44564458
assert(java_lang_invoke_CallSite::is_instance(call_site), "");
4457-
4458-
oop dep_oop = call_site->obj_field_access<AS_NO_KEEPALIVE>(_context_offset);
4459-
return dep_oop;
4459+
nmethodBucket* volatile* vmdeps_addr = call_site->field_addr<nmethodBucket* volatile>(_vmdependencies_offset);
4460+
volatile uint64_t* last_cleanup_addr = call_site->field_addr<volatile uint64_t>(_last_cleanup_offset);
4461+
DependencyContext dep_ctx(vmdeps_addr, last_cleanup_addr);
4462+
return dep_ctx;
44604463
}
44614464

44624465
// Support for java_lang_invoke_ConstantCallSite
@@ -4477,30 +4480,6 @@ void java_lang_invoke_ConstantCallSite::serialize_offsets(SerializeClosure* f) {
44774480
}
44784481
#endif
44794482

4480-
// Support for java_lang_invoke_MethodHandleNatives_CallSiteContext
4481-
4482-
int java_lang_invoke_MethodHandleNatives_CallSiteContext::_vmdependencies_offset;
4483-
int java_lang_invoke_MethodHandleNatives_CallSiteContext::_last_cleanup_offset;
4484-
4485-
void java_lang_invoke_MethodHandleNatives_CallSiteContext::compute_offsets() {
4486-
InstanceKlass* k = vmClasses::Context_klass();
4487-
CALLSITECONTEXT_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
4488-
}
4489-
4490-
#if INCLUDE_CDS
4491-
void java_lang_invoke_MethodHandleNatives_CallSiteContext::serialize_offsets(SerializeClosure* f) {
4492-
CALLSITECONTEXT_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET);
4493-
}
4494-
#endif
4495-
4496-
DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) {
4497-
assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
4498-
nmethodBucket* volatile* vmdeps_addr = call_site->field_addr<nmethodBucket* volatile>(_vmdependencies_offset);
4499-
volatile uint64_t* last_cleanup_addr = call_site->field_addr<volatile uint64_t>(_last_cleanup_offset);
4500-
DependencyContext dep_ctx(vmdeps_addr, last_cleanup_addr);
4501-
return dep_ctx;
4502-
}
4503-
45044483
// Support for java_security_AccessControlContext
45054484

45064485
int java_security_AccessControlContext::_context_offset;
@@ -5242,7 +5221,6 @@ void java_lang_InternalError::serialize_offsets(SerializeClosure* f) {
52425221
f(java_lang_invoke_MethodType) \
52435222
f(java_lang_invoke_CallSite) \
52445223
f(java_lang_invoke_ConstantCallSite) \
5245-
f(java_lang_invoke_MethodHandleNatives_CallSiteContext) \
52465224
f(java_security_AccessControlContext) \
52475225
f(java_lang_reflect_AccessibleObject) \
52485226
f(java_lang_reflect_Method) \
@@ -5316,7 +5294,6 @@ bool JavaClasses::is_supported_for_archiving(oop obj) {
53165294
// constant pool entries, so excluding them shouldn't affect the archiving of static fields.
53175295
klass == vmClasses::ResolvedMethodName_klass() ||
53185296
klass == vmClasses::MemberName_klass() ||
5319-
klass == vmClasses::Context_klass() ||
53205297
// It's problematic to archive Reference objects. One of the reasons is that
53215298
// Reference::discovered may pull in unwanted objects (see JDK-8284336)
53225299
klass->is_subclass_of(vmClasses::Reference_klass())) {

src/hotspot/share/classfile/javaClasses.hpp

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,13 +1368,17 @@ class java_lang_invoke_MethodType: AllStatic {
13681368

13691369

13701370
// Interface to java.lang.invoke.CallSite objects
1371+
#define CALLSITE_INJECTED_FIELDS(macro) \
1372+
macro(java_lang_invoke_CallSite, vmdependencies, intptr_signature, false) \
1373+
macro(java_lang_invoke_CallSite, last_cleanup, long_signature, false)
13711374

13721375
class java_lang_invoke_CallSite: AllStatic {
13731376
friend class JavaClasses;
13741377

13751378
private:
13761379
static int _target_offset;
1377-
static int _context_offset;
1380+
static int _vmdependencies_offset;
1381+
static int _last_cleanup_offset;
13781382

13791383
static void compute_offsets();
13801384

@@ -1385,7 +1389,7 @@ class java_lang_invoke_CallSite: AllStatic {
13851389
static void set_target( oop site, oop target);
13861390
static void set_target_volatile( oop site, oop target);
13871391

1388-
static oop context_no_keepalive(oop site);
1392+
static DependencyContext vmdependencies(oop call_site);
13891393

13901394
// Testers
13911395
static bool is_subclass(Klass* klass) {
@@ -1395,7 +1399,6 @@ class java_lang_invoke_CallSite: AllStatic {
13951399

13961400
// Accessors for code generation:
13971401
static int target_offset() { CHECK_INIT(_target_offset); }
1398-
static int context_offset() { CHECK_INIT(_context_offset); }
13991402
};
14001403

14011404
// Interface to java.lang.invoke.ConstantCallSite objects
@@ -1420,35 +1423,6 @@ class java_lang_invoke_ConstantCallSite: AllStatic {
14201423
static bool is_instance(oop obj);
14211424
};
14221425

1423-
// Interface to java.lang.invoke.MethodHandleNatives$CallSiteContext objects
1424-
1425-
#define CALLSITECONTEXT_INJECTED_FIELDS(macro) \
1426-
macro(java_lang_invoke_MethodHandleNatives_CallSiteContext, vmdependencies, intptr_signature, false) \
1427-
macro(java_lang_invoke_MethodHandleNatives_CallSiteContext, last_cleanup, long_signature, false)
1428-
1429-
class DependencyContext;
1430-
1431-
class java_lang_invoke_MethodHandleNatives_CallSiteContext : AllStatic {
1432-
friend class JavaClasses;
1433-
1434-
private:
1435-
static int _vmdependencies_offset;
1436-
static int _last_cleanup_offset;
1437-
1438-
static void compute_offsets();
1439-
1440-
public:
1441-
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
1442-
// Accessors
1443-
static DependencyContext vmdependencies(oop context);
1444-
1445-
// Testers
1446-
static bool is_subclass(Klass* klass) {
1447-
return klass->is_subclass_of(vmClasses::Context_klass());
1448-
}
1449-
static bool is_instance(oop obj);
1450-
};
1451-
14521426
// Interface to java.security.AccessControlContext objects
14531427

14541428
class java_security_AccessControlContext: AllStatic {

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,6 @@ inline bool java_lang_invoke_ConstantCallSite::is_instance(oop obj) {
259259
return obj != nullptr && is_subclass(obj->klass());
260260
}
261261

262-
inline bool java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(oop obj) {
263-
return obj != nullptr && is_subclass(obj->klass());
264-
}
265-
266262
inline bool java_lang_invoke_MemberName::is_instance(oop obj) {
267263
return obj != nullptr && obj->klass() == vmClasses::MemberName_klass();
268264
}

src/hotspot/share/classfile/javaClassesImpl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
CLASSLOADER_INJECTED_FIELDS(macro) \
3636
RESOLVEDMETHOD_INJECTED_FIELDS(macro) \
3737
MEMBERNAME_INJECTED_FIELDS(macro) \
38-
CALLSITECONTEXT_INJECTED_FIELDS(macro) \
38+
CALLSITE_INJECTED_FIELDS(macro) \
3939
STACKFRAMEINFO_INJECTED_FIELDS(macro) \
4040
MODULE_INJECTED_FIELDS(macro) \
4141
THREAD_INJECTED_FIELDS(macro) \

src/hotspot/share/classfile/vmClassMacros.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@
129129
do_klass(ABIDescriptor_klass, jdk_internal_foreign_abi_ABIDescriptor ) \
130130
do_klass(VMStorage_klass, jdk_internal_foreign_abi_VMStorage ) \
131131
do_klass(CallConv_klass, jdk_internal_foreign_abi_CallConv ) \
132-
do_klass(Context_klass, java_lang_invoke_MethodHandleNatives_CallSiteContext ) \
133132
do_klass(ConstantCallSite_klass, java_lang_invoke_ConstantCallSite ) \
134133
do_klass(MutableCallSite_klass, java_lang_invoke_MutableCallSite ) \
135134
do_klass(VolatileCallSite_klass, java_lang_invoke_VolatileCallSite ) \

src/hotspot/share/classfile/vmSymbols.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,11 +341,9 @@
341341
template(java_lang_invoke_MemberName, "java/lang/invoke/MemberName") \
342342
template(java_lang_invoke_ResolvedMethodName, "java/lang/invoke/ResolvedMethodName") \
343343
template(java_lang_invoke_MethodHandleNatives, "java/lang/invoke/MethodHandleNatives") \
344-
template(java_lang_invoke_MethodHandleNatives_CallSiteContext, "java/lang/invoke/MethodHandleNatives$CallSiteContext") \
345344
template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \
346345
template(java_lang_invoke_InjectedProfile_signature, "Ljava/lang/invoke/InjectedProfile;") \
347346
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
348-
template(java_lang_invoke_MethodHandleNatives_CallSiteContext_signature, "Ljava/lang/invoke/MethodHandleNatives$CallSiteContext;") \
349347
/* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \
350348
template(findMethodHandleType_name, "findMethodHandleType") \
351349
template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \

src/hotspot/share/code/dependencyContext.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,6 @@ void DependencyContext::clean_unloading_dependents() {
168168
}
169169
}
170170

171-
nmethodBucket* DependencyContext::release_and_get_next_not_unloading(nmethodBucket* b) {
172-
nmethodBucket* next = b->next_not_unloading();
173-
release(b);
174-
return next;
175-
}
176-
177171
//
178172
// Invalidate all dependencies in the context
179173
void DependencyContext::remove_all_dependents() {
@@ -214,18 +208,6 @@ void DependencyContext::remove_all_dependents() {
214208
set_dependencies(nullptr);
215209
}
216210

217-
void DependencyContext::remove_and_mark_for_deoptimization_all_dependents(DeoptimizationScope* deopt_scope) {
218-
nmethodBucket* b = dependencies_not_unloading();
219-
set_dependencies(nullptr);
220-
while (b != nullptr) {
221-
nmethod* nm = b->get_nmethod();
222-
// Also count already (concurrently) marked nmethods to make sure
223-
// deoptimization is triggered before execution in this thread continues.
224-
deopt_scope->mark(nm);
225-
b = release_and_get_next_not_unloading(b);
226-
}
227-
}
228-
229211
#ifndef PRODUCT
230212
void DependencyContext::print_dependent_nmethods(bool verbose) {
231213
int idx = 0;

src/hotspot/share/code/dependencyContext.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class nmethodBucket: public CHeapObj<mtClass> {
6363
//
6464
// Utility class to manipulate nmethod dependency context.
6565
// Dependency context can be attached either to an InstanceKlass (_dep_context field)
66-
// or CallSiteContext oop for call_site_target dependencies (see javaClasses.hpp).
66+
// or CallSite oop for call_site_target dependencies (see javaClasses.hpp).
6767
// DependencyContext class operates on some location which holds a nmethodBucket* value
6868
// and uint64_t integer recording the safepoint counter at the last cleanup.
6969
//
@@ -92,7 +92,6 @@ class DependencyContext : public StackObj {
9292
#ifdef ASSERT
9393
// Safepoints are forbidden during DC lifetime. GC can invalidate
9494
// _dependency_context_addr if it relocates the holder
95-
// (e.g. CallSiteContext Java object).
9695
SafepointStateTracker _safepoint_tracker;
9796

9897
DependencyContext(nmethodBucket* volatile* bucket_addr, volatile uint64_t* last_cleanup_addr)
@@ -114,9 +113,7 @@ class DependencyContext : public StackObj {
114113
void mark_dependent_nmethods(DeoptimizationScope* deopt_scope, DepChange& changes);
115114
void add_dependent_nmethod(nmethod* nm);
116115
void remove_all_dependents();
117-
void remove_and_mark_for_deoptimization_all_dependents(DeoptimizationScope* deopt_scope);
118116
void clean_unloading_dependents();
119-
static nmethodBucket* release_and_get_next_not_unloading(nmethodBucket* b);
120117
static void purge_dependency_contexts();
121118
static void release(nmethodBucket* b);
122119
static void cleaning_start();

src/hotspot/share/prims/methodHandles.cpp

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -934,19 +934,12 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
934934
void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) {
935935
assert_locked_or_safepoint(CodeCache_lock);
936936

937-
oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
938-
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
939-
// Try to purge stale entries on updates.
940-
// Since GC doesn't clean dependency contexts rooted at CallSiteContext objects,
941-
// in order to avoid memory leak, stale entries are purged whenever a dependency list
942-
// is changed (both on addition and removal). Though memory reclamation is delayed,
943-
// it avoids indefinite memory usage growth.
937+
DependencyContext deps = java_lang_invoke_CallSite::vmdependencies(call_site);
944938
deps.add_dependent_nmethod(nm);
945939
}
946940

947941
void MethodHandles::clean_dependency_context(oop call_site) {
948-
oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
949-
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
942+
DependencyContext deps = java_lang_invoke_CallSite::vmdependencies(call_site);
950943
deps.clean_unloading_dependents();
951944
}
952945

@@ -958,8 +951,7 @@ void MethodHandles::mark_dependent_nmethods(DeoptimizationScope* deopt_scope, Ha
958951
NoSafepointVerifier nsv;
959952
MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag);
960953

961-
oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site());
962-
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
954+
DependencyContext deps = java_lang_invoke_CallSite::vmdependencies(call_site());
963955
deps.mark_dependent_nmethods(deopt_scope, changes);
964956
}
965957
}
@@ -1323,23 +1315,6 @@ JVM_ENTRY(void, MHN_copyOutBootstrapArguments(JNIEnv* env, jobject igcls,
13231315
}
13241316
JVM_END
13251317

1326-
// It is called by a Cleaner object which ensures that dropped CallSites properly
1327-
// deallocate their dependency information.
1328-
JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1329-
Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1330-
DeoptimizationScope deopt_scope;
1331-
{
1332-
NoSafepointVerifier nsv;
1333-
MutexLocker ml(THREAD, CodeCache_lock, Mutex::_no_safepoint_check_flag);
1334-
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
1335-
deps.remove_and_mark_for_deoptimization_all_dependents(&deopt_scope);
1336-
// This is assumed to be an 'atomic' operation by verification.
1337-
// So keep it under lock for now.
1338-
deopt_scope.deoptimize_marked();
1339-
}
1340-
}
1341-
JVM_END
1342-
13431318
/**
13441319
* Throws a java/lang/UnsupportedOperationException unconditionally.
13451320
* This is required by the specification of MethodHandle.invoke if
@@ -1374,7 +1349,6 @@ JVM_END
13741349
#define MT JLINV "MethodType;"
13751350
#define MH JLINV "MethodHandle;"
13761351
#define MEM JLINV "MemberName;"
1377-
#define CTX JLINV "MethodHandleNatives$CallSiteContext;"
13781352

13791353
#define CC (char*) /*cast a literal from (const char*)*/
13801354
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
@@ -1390,7 +1364,6 @@ static JNINativeMethod MHN_methods[] = {
13901364
{CC "setCallSiteTargetNormal", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetNormal)},
13911365
{CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetVolatile)},
13921366
{CC "copyOutBootstrapArguments", CC "(" CLS "[III[" OBJ "IZ" OBJ ")V", FN_PTR(MHN_copyOutBootstrapArguments)},
1393-
{CC "clearCallSiteContext", CC "(" CTX ")V", FN_PTR(MHN_clearCallSiteContext)},
13941367
{CC "staticFieldOffset", CC "(" MEM ")J", FN_PTR(MHN_staticFieldOffset)},
13951368
{CC "staticFieldBase", CC "(" MEM ")" OBJ, FN_PTR(MHN_staticFieldBase)},
13961369
{CC "getMemberVMInfo", CC "(" MEM ")" OBJ, FN_PTR(MHN_getMemberVMInfo)}

src/java.base/share/classes/java/lang/invoke/CallSite.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,6 @@ abstract sealed class CallSite permits ConstantCallSite, MutableCallSite, Volati
138138
UNSAFE.storeStoreFence(); // barrier between target and isFrozen updates
139139
}
140140

141-
/**
142-
* {@code CallSite} dependency context.
143-
* JVM uses CallSite.context to store nmethod dependencies on the call site target.
144-
*/
145-
private final MethodHandleNatives.CallSiteContext context = MethodHandleNatives.CallSiteContext.make(this);
146-
147141
/**
148142
* Returns the type of this call site's target.
149143
* Although targets may change, any call site's type is permanent, and can never change to an unequal type.

0 commit comments

Comments
 (0)