Skip to content

Commit 352a7a9

Browse files
xmas92TheRealMDoerr
authored andcommitted
8347564: ZGC: Crash in DependencyContext::clean_unloading_dependents
Backport-of: 14136f8b1106137317393bc2ab0a2db0d212f8d8
1 parent ba481f0 commit 352a7a9

File tree

13 files changed

+25
-160
lines changed

13 files changed

+25
-160
lines changed

src/hotspot/share/classfile/javaClasses.cpp

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4674,28 +4674,31 @@ int java_lang_invoke_MethodType::rtype_slot_count(oop mt) {
46744674
// Support for java_lang_invoke_CallSite
46754675

46764676
int java_lang_invoke_CallSite::_target_offset;
4677-
int java_lang_invoke_CallSite::_context_offset;
4677+
int java_lang_invoke_CallSite::_vmdependencies_offset;
4678+
int java_lang_invoke_CallSite::_last_cleanup_offset;
46784679

46794680
#define CALLSITE_FIELDS_DO(macro) \
46804681
macro(_target_offset, k, "target", java_lang_invoke_MethodHandle_signature, false); \
4681-
macro(_context_offset, k, "context", java_lang_invoke_MethodHandleNatives_CallSiteContext_signature, false)
46824682

46834683
void java_lang_invoke_CallSite::compute_offsets() {
46844684
InstanceKlass* k = vmClasses::CallSite_klass();
46854685
CALLSITE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
4686+
CALLSITE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
46864687
}
46874688

46884689
#if INCLUDE_CDS
46894690
void java_lang_invoke_CallSite::serialize_offsets(SerializeClosure* f) {
46904691
CALLSITE_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
4692+
CALLSITE_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET);
46914693
}
46924694
#endif
46934695

4694-
oop java_lang_invoke_CallSite::context_no_keepalive(oop call_site) {
4696+
DependencyContext java_lang_invoke_CallSite::vmdependencies(oop call_site) {
46954697
assert(java_lang_invoke_CallSite::is_instance(call_site), "");
4696-
4697-
oop dep_oop = call_site->obj_field_access<AS_NO_KEEPALIVE>(_context_offset);
4698-
return dep_oop;
4698+
nmethodBucket* volatile* vmdeps_addr = call_site->field_addr<nmethodBucket* volatile>(_vmdependencies_offset);
4699+
volatile uint64_t* last_cleanup_addr = call_site->field_addr<volatile uint64_t>(_last_cleanup_offset);
4700+
DependencyContext dep_ctx(vmdeps_addr, last_cleanup_addr);
4701+
return dep_ctx;
46994702
}
47004703

47014704
// Support for java_lang_invoke_ConstantCallSite
@@ -4716,30 +4719,6 @@ void java_lang_invoke_ConstantCallSite::serialize_offsets(SerializeClosure* f) {
47164719
}
47174720
#endif
47184721

4719-
// Support for java_lang_invoke_MethodHandleNatives_CallSiteContext
4720-
4721-
int java_lang_invoke_MethodHandleNatives_CallSiteContext::_vmdependencies_offset;
4722-
int java_lang_invoke_MethodHandleNatives_CallSiteContext::_last_cleanup_offset;
4723-
4724-
void java_lang_invoke_MethodHandleNatives_CallSiteContext::compute_offsets() {
4725-
InstanceKlass* k = vmClasses::Context_klass();
4726-
CALLSITECONTEXT_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
4727-
}
4728-
4729-
#if INCLUDE_CDS
4730-
void java_lang_invoke_MethodHandleNatives_CallSiteContext::serialize_offsets(SerializeClosure* f) {
4731-
CALLSITECONTEXT_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET);
4732-
}
4733-
#endif
4734-
4735-
DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) {
4736-
assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
4737-
nmethodBucket* volatile* vmdeps_addr = call_site->field_addr<nmethodBucket* volatile>(_vmdependencies_offset);
4738-
volatile uint64_t* last_cleanup_addr = call_site->field_addr<volatile uint64_t>(_last_cleanup_offset);
4739-
DependencyContext dep_ctx(vmdeps_addr, last_cleanup_addr);
4740-
return dep_ctx;
4741-
}
4742-
47434722
// Support for java_lang_ClassLoader
47444723

47454724
int java_lang_ClassLoader::_loader_data_offset;
@@ -5389,7 +5368,6 @@ void java_lang_InternalError::serialize_offsets(SerializeClosure* f) {
53895368
f(java_lang_invoke_MethodType) \
53905369
f(java_lang_invoke_CallSite) \
53915370
f(java_lang_invoke_ConstantCallSite) \
5392-
f(java_lang_invoke_MethodHandleNatives_CallSiteContext) \
53935371
f(java_lang_reflect_AccessibleObject) \
53945372
f(java_lang_reflect_Method) \
53955373
f(java_lang_reflect_Constructor) \
@@ -5455,8 +5433,7 @@ bool JavaClasses::is_supported_for_archiving(oop obj) {
54555433
if (!CDSConfig::is_dumping_invokedynamic()) {
54565434
// These are supported by CDS only when CDSConfig::is_dumping_invokedynamic() is enabled.
54575435
if (klass == vmClasses::ResolvedMethodName_klass() ||
5458-
klass == vmClasses::MemberName_klass() ||
5459-
klass == vmClasses::Context_klass()) {
5436+
klass == vmClasses::MemberName_klass()) {
54605437
return false;
54615438
}
54625439
}

src/hotspot/share/classfile/javaClasses.hpp

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

14101410

14111411
// Interface to java.lang.invoke.CallSite objects
1412+
#define CALLSITE_INJECTED_FIELDS(macro) \
1413+
macro(java_lang_invoke_CallSite, vmdependencies, intptr_signature, false) \
1414+
macro(java_lang_invoke_CallSite, last_cleanup, long_signature, false)
14121415

14131416
class java_lang_invoke_CallSite: AllStatic {
14141417
friend class JavaClasses;
14151418

14161419
private:
14171420
static int _target_offset;
1418-
static int _context_offset;
1421+
static int _vmdependencies_offset;
1422+
static int _last_cleanup_offset;
14191423

14201424
static void compute_offsets();
14211425

@@ -1426,7 +1430,7 @@ class java_lang_invoke_CallSite: AllStatic {
14261430
static void set_target( oop site, oop target);
14271431
static void set_target_volatile( oop site, oop target);
14281432

1429-
static oop context_no_keepalive(oop site);
1433+
static DependencyContext vmdependencies(oop call_site);
14301434

14311435
// Testers
14321436
static bool is_subclass(Klass* klass) {
@@ -1436,7 +1440,6 @@ class java_lang_invoke_CallSite: AllStatic {
14361440

14371441
// Accessors for code generation:
14381442
static int target_offset() { CHECK_INIT(_target_offset); }
1439-
static int context_offset() { CHECK_INIT(_context_offset); }
14401443
};
14411444

14421445
// Interface to java.lang.invoke.ConstantCallSite objects
@@ -1461,35 +1464,6 @@ class java_lang_invoke_ConstantCallSite: AllStatic {
14611464
static bool is_instance(oop obj);
14621465
};
14631466

1464-
// Interface to java.lang.invoke.MethodHandleNatives$CallSiteContext objects
1465-
1466-
#define CALLSITECONTEXT_INJECTED_FIELDS(macro) \
1467-
macro(java_lang_invoke_MethodHandleNatives_CallSiteContext, vmdependencies, intptr_signature, false) \
1468-
macro(java_lang_invoke_MethodHandleNatives_CallSiteContext, last_cleanup, long_signature, false)
1469-
1470-
class DependencyContext;
1471-
1472-
class java_lang_invoke_MethodHandleNatives_CallSiteContext : AllStatic {
1473-
friend class JavaClasses;
1474-
1475-
private:
1476-
static int _vmdependencies_offset;
1477-
static int _last_cleanup_offset;
1478-
1479-
static void compute_offsets();
1480-
1481-
public:
1482-
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
1483-
// Accessors
1484-
static DependencyContext vmdependencies(oop context);
1485-
1486-
// Testers
1487-
static bool is_subclass(Klass* klass) {
1488-
return klass->is_subclass_of(vmClasses::Context_klass());
1489-
}
1490-
static bool is_instance(oop obj);
1491-
};
1492-
14931467
// Interface to java.lang.ClassLoader objects
14941468

14951469
#define CLASSLOADER_INJECTED_FIELDS(macro) \

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

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

266-
inline bool java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(oop obj) {
267-
return obj != nullptr && is_subclass(obj->klass());
268-
}
269-
270266
inline bool java_lang_invoke_MemberName::is_instance(oop obj) {
271267
return obj != nullptr && obj->klass() == vmClasses::MemberName_klass();
272268
}

src/hotspot/share/classfile/javaClassesImpl.hpp

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

src/hotspot/share/classfile/vmClassMacros.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@
123123
do_klass(ABIDescriptor_klass, jdk_internal_foreign_abi_ABIDescriptor ) \
124124
do_klass(VMStorage_klass, jdk_internal_foreign_abi_VMStorage ) \
125125
do_klass(CallConv_klass, jdk_internal_foreign_abi_CallConv ) \
126-
do_klass(Context_klass, java_lang_invoke_MethodHandleNatives_CallSiteContext ) \
127126
do_klass(ConstantCallSite_klass, java_lang_invoke_ConstantCallSite ) \
128127
do_klass(MutableCallSite_klass, java_lang_invoke_MutableCallSite ) \
129128
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
@@ -326,11 +326,9 @@ class SerializeClosure;
326326
template(java_lang_invoke_MemberName, "java/lang/invoke/MemberName") \
327327
template(java_lang_invoke_ResolvedMethodName, "java/lang/invoke/ResolvedMethodName") \
328328
template(java_lang_invoke_MethodHandleNatives, "java/lang/invoke/MethodHandleNatives") \
329-
template(java_lang_invoke_MethodHandleNatives_CallSiteContext, "java/lang/invoke/MethodHandleNatives$CallSiteContext") \
330329
template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \
331330
template(java_lang_invoke_InjectedProfile_signature, "Ljava/lang/invoke/InjectedProfile;") \
332331
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
333-
template(java_lang_invoke_MethodHandleNatives_CallSiteContext_signature, "Ljava/lang/invoke/MethodHandleNatives$CallSiteContext;") \
334332
/* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \
335333
template(findMethodHandleType_name, "findMethodHandleType") \
336334
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
bool DependencyContext::is_empty() {
231213
return dependencies() == nullptr;

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
@@ -932,19 +932,12 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
932932
void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) {
933933
assert_locked_or_safepoint(CodeCache_lock);
934934

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

945939
void MethodHandles::clean_dependency_context(oop call_site) {
946-
oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
947-
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
940+
DependencyContext deps = java_lang_invoke_CallSite::vmdependencies(call_site);
948941
deps.clean_unloading_dependents();
949942
}
950943

@@ -956,8 +949,7 @@ void MethodHandles::mark_dependent_nmethods(DeoptimizationScope* deopt_scope, Ha
956949
NoSafepointVerifier nsv;
957950
MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag);
958951

959-
oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site());
960-
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
952+
DependencyContext deps = java_lang_invoke_CallSite::vmdependencies(call_site());
961953
deps.mark_dependent_nmethods(deopt_scope, changes);
962954
}
963955
}
@@ -1322,23 +1314,6 @@ JVM_ENTRY(void, MHN_copyOutBootstrapArguments(JNIEnv* env, jobject igcls,
13221314
}
13231315
JVM_END
13241316

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

13901364
#define CC (char*) /*cast a literal from (const char*)*/
13911365
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
@@ -1401,7 +1375,6 @@ static JNINativeMethod MHN_methods[] = {
14011375
{CC "setCallSiteTargetNormal", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetNormal)},
14021376
{CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetVolatile)},
14031377
{CC "copyOutBootstrapArguments", CC "(" CLS "[III[" OBJ "IZ" OBJ ")V", FN_PTR(MHN_copyOutBootstrapArguments)},
1404-
{CC "clearCallSiteContext", CC "(" CTX ")V", FN_PTR(MHN_clearCallSiteContext)},
14051378
{CC "staticFieldOffset", CC "(" MEM ")J", FN_PTR(MHN_staticFieldOffset)},
14061379
{CC "staticFieldBase", CC "(" MEM ")" OBJ, FN_PTR(MHN_staticFieldBase)},
14071380
{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)