Skip to content

Commit 841eae6

Browse files
committed
8269542: JDWP: EnableCollection support is no longer spec compliant after JDK-8255987
8258071: Fix for JDK-8255987 can be subverted with ObjectReference.EnableCollection Reviewed-by: dholmes, pliden
1 parent 76fe03f commit 841eae6

File tree

2 files changed

+48
-30
lines changed

2 files changed

+48
-30
lines changed

src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2022, 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
@@ -82,22 +82,30 @@ newSeqNum(void)
8282
return gdata->nextSeqNum++;
8383
}
8484

85+
/* Returns true if this is a strong reference, meaning that either or both of
86+
isPinAll and isCommonPin are true. */
87+
static jboolean
88+
isStrong(RefNode* node)
89+
{
90+
return node->isPinAll || node->isCommonPin;
91+
}
92+
8593
/* Create a fresh RefNode structure, create a weak ref and tag the object */
8694
static RefNode *
8795
createNode(JNIEnv *env, jobject ref)
8896
{
8997
RefNode *node;
9098
jobject strongOrWeakRef;
9199
jvmtiError error;
92-
jboolean pin = gdata->pinAllCount != 0;
100+
jboolean pinAll = gdata->pinAllCount != 0;
93101

94102
/* Could allocate RefNode's in blocks, not sure it would help much */
95103
node = (RefNode*)jvmtiAllocate((int)sizeof(RefNode));
96104
if (node == NULL) {
97105
return NULL;
98106
}
99107

100-
if (pin) {
108+
if (pinAll) {
101109
/* Create strong reference to make sure we have a reference */
102110
strongOrWeakRef = JNI_FUNC_PTR(env,NewGlobalRef)(env, ref);
103111
} else {
@@ -116,7 +124,7 @@ createNode(JNIEnv *env, jobject ref)
116124
error = JVMTI_FUNC_PTR(gdata->jvmti, SetTag)
117125
(gdata->jvmti, strongOrWeakRef, ptr_to_jlong(node));
118126
if ( error != JVMTI_ERROR_NONE ) {
119-
if (pin) {
127+
if (pinAll) {
120128
JNI_FUNC_PTR(env,DeleteGlobalRef)(env, strongOrWeakRef);
121129
} else {
122130
JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, strongOrWeakRef);
@@ -128,7 +136,8 @@ createNode(JNIEnv *env, jobject ref)
128136
/* Fill in RefNode */
129137
node->ref = strongOrWeakRef;
130138
node->count = 1;
131-
node->strongCount = pin ? 1 : 0;
139+
node->isPinAll = pinAll;
140+
node->isCommonPin = JNI_FALSE;
132141
node->seqNum = newSeqNum();
133142

134143
/* Count RefNode's created */
@@ -146,7 +155,7 @@ deleteNode(JNIEnv *env, RefNode *node)
146155
/* Clear tag */
147156
(void)JVMTI_FUNC_PTR(gdata->jvmti,SetTag)
148157
(gdata->jvmti, node->ref, NULL_OBJECT_ID);
149-
if (node->strongCount != 0) {
158+
if (isStrong(node)) {
150159
JNI_FUNC_PTR(env,DeleteGlobalRef)(env, node->ref);
151160
} else {
152161
JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, node->ref);
@@ -158,9 +167,9 @@ deleteNode(JNIEnv *env, RefNode *node)
158167

159168
/* Change a RefNode to have a strong reference */
160169
static jobject
161-
strengthenNode(JNIEnv *env, RefNode *node)
170+
strengthenNode(JNIEnv *env, RefNode *node, jboolean isPinAll)
162171
{
163-
if (node->strongCount == 0) {
172+
if (!isStrong(node)) {
164173
jobject strongRef;
165174

166175
strongRef = JNI_FUNC_PTR(env,NewGlobalRef)(env, node->ref);
@@ -176,20 +185,27 @@ strengthenNode(JNIEnv *env, RefNode *node)
176185
if (strongRef != NULL) {
177186
JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, node->ref);
178187
node->ref = strongRef;
179-
node->strongCount = 1;
188+
} else {
189+
return NULL;
180190
}
181-
return strongRef;
191+
}
192+
if (isPinAll) {
193+
node->isPinAll = JNI_TRUE;
182194
} else {
183-
node->strongCount++;
184-
return node->ref;
195+
node->isCommonPin = JNI_TRUE;
185196
}
197+
return node->ref;
186198
}
187199

188200
/* Change a RefNode to have a weak reference */
189201
static jweak
190-
weakenNode(JNIEnv *env, RefNode *node)
202+
weakenNode(JNIEnv *env, RefNode *node, jboolean isUnpinAll)
191203
{
192-
if (node->strongCount == 1) {
204+
jboolean willStillBeStrong = (node->isPinAll && !isUnpinAll) || (node->isCommonPin && isUnpinAll);
205+
206+
// If the node is strong, but the reason(s) for it being strong
207+
// will no longer exist, then weaken it.
208+
if (isStrong(node) && !willStillBeStrong) {
193209
jweak weakRef;
194210

195211
weakRef = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, node->ref);
@@ -200,16 +216,18 @@ weakenNode(JNIEnv *env, RefNode *node)
200216

201217
if (weakRef != NULL) {
202218
JNI_FUNC_PTR(env,DeleteGlobalRef)(env, node->ref);
203-
node->ref = weakRef;
204-
node->strongCount = 0;
219+
node->ref = weakRef;
220+
} else {
221+
return NULL;
205222
}
206-
return weakRef;
223+
}
224+
225+
if (isUnpinAll) {
226+
node->isPinAll = JNI_FALSE;
207227
} else {
208-
if (node->strongCount > 0) {
209-
node->strongCount--;
210-
}
211-
return node->ref;
228+
node->isCommonPin = JNI_FALSE;
212229
}
230+
return node->ref;
213231
}
214232

215233
/*
@@ -470,7 +488,7 @@ commonRef_idToRef(JNIEnv *env, jlong id)
470488

471489
node = findNodeByID(env, id);
472490
if (node != NULL) {
473-
if (node->strongCount != 0) {
491+
if (isStrong(node)) {
474492
saveGlobalRef(env, node->ref, &ref);
475493
} else {
476494
jobject lref;
@@ -522,7 +540,7 @@ commonRef_pin(jlong id)
522540
} else {
523541
jobject strongRef;
524542

525-
strongRef = strengthenNode(env, node);
543+
strongRef = strengthenNode(env, node, JNI_FALSE /* isPinAll */);
526544
if (strongRef == NULL) {
527545
/*
528546
* Referent has been collected, clean up now.
@@ -551,7 +569,7 @@ commonRef_unpin(jlong id)
551569
if (node != NULL) {
552570
jweak weakRef;
553571

554-
weakRef = weakenNode(env, node);
572+
weakRef = weakenNode(env, node, JNI_FALSE /* isUnpinAll */);
555573
if (weakRef == NULL) {
556574
error = AGENT_ERROR_OUT_OF_MEMORY;
557575
}
@@ -585,7 +603,7 @@ commonRef_pinAll()
585603
while (node != NULL) {
586604
jobject strongRef;
587605

588-
strongRef = strengthenNode(env, node);
606+
strongRef = strengthenNode(env, node, JNI_TRUE /* isPinAll */);
589607

590608
/* Has the object been collected? */
591609
if (strongRef == NULL) {
@@ -628,7 +646,7 @@ commonRef_unpinAll()
628646
for (node = gdata->objectsByID[i]; node != NULL; node = node->next) {
629647
jweak weakRef;
630648

631-
weakRef = weakenNode(env, node);
649+
weakRef = weakenNode(env, node, JNI_TRUE /* isUnpinAll */);
632650
if (weakRef == NULL) {
633651
EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"NewWeakGlobalRef");
634652
}
@@ -676,8 +694,7 @@ commonRef_compact(void)
676694
prev = NULL;
677695
while (node != NULL) {
678696
/* Has the object been collected? */
679-
if ( (node->strongCount == 0) &&
680-
isSameObject(env, node->ref, NULL)) {
697+
if (!isStrong(node) && isSameObject(env, node->ref, NULL)) {
681698
RefNode *freed;
682699

683700
/* Detach from the ID list */

src/jdk.jdwp.agent/share/native/libjdwp/util.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2022, 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
@@ -65,7 +65,8 @@ typedef struct RefNode {
6565
jobject ref; /* could be strong or weak */
6666
struct RefNode *next; /* next RefNode* in bucket chain */
6767
jint count; /* count of references */
68-
unsigned strongCount; /* count of strong reference */
68+
jboolean isPinAll; /* true if this is a strong reference due to a commonRef_pinAll() */
69+
jboolean isCommonPin; /* true if this is a strong reference due to a commonRef_pin() */
6970
} RefNode;
7071

7172
/* Value of a NULL ID */

0 commit comments

Comments
 (0)