1
1
/*
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.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
@@ -82,22 +82,30 @@ newSeqNum(void)
82
82
return gdata -> nextSeqNum ++ ;
83
83
}
84
84
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
+
85
93
/* Create a fresh RefNode structure, create a weak ref and tag the object */
86
94
static RefNode *
87
95
createNode (JNIEnv * env , jobject ref )
88
96
{
89
97
RefNode * node ;
90
98
jobject strongOrWeakRef ;
91
99
jvmtiError error ;
92
- jboolean pin = gdata -> pinAllCount != 0 ;
100
+ jboolean pinAll = gdata -> pinAllCount != 0 ;
93
101
94
102
/* Could allocate RefNode's in blocks, not sure it would help much */
95
103
node = (RefNode * )jvmtiAllocate ((int )sizeof (RefNode ));
96
104
if (node == NULL ) {
97
105
return NULL ;
98
106
}
99
107
100
- if (pin ) {
108
+ if (pinAll ) {
101
109
/* Create strong reference to make sure we have a reference */
102
110
strongOrWeakRef = JNI_FUNC_PTR (env ,NewGlobalRef )(env , ref );
103
111
} else {
@@ -116,7 +124,7 @@ createNode(JNIEnv *env, jobject ref)
116
124
error = JVMTI_FUNC_PTR (gdata -> jvmti , SetTag )
117
125
(gdata -> jvmti , strongOrWeakRef , ptr_to_jlong (node ));
118
126
if ( error != JVMTI_ERROR_NONE ) {
119
- if (pin ) {
127
+ if (pinAll ) {
120
128
JNI_FUNC_PTR (env ,DeleteGlobalRef )(env , strongOrWeakRef );
121
129
} else {
122
130
JNI_FUNC_PTR (env ,DeleteWeakGlobalRef )(env , strongOrWeakRef );
@@ -128,7 +136,8 @@ createNode(JNIEnv *env, jobject ref)
128
136
/* Fill in RefNode */
129
137
node -> ref = strongOrWeakRef ;
130
138
node -> count = 1 ;
131
- node -> strongCount = pin ? 1 : 0 ;
139
+ node -> isPinAll = pinAll ;
140
+ node -> isCommonPin = JNI_FALSE ;
132
141
node -> seqNum = newSeqNum ();
133
142
134
143
/* Count RefNode's created */
@@ -146,7 +155,7 @@ deleteNode(JNIEnv *env, RefNode *node)
146
155
/* Clear tag */
147
156
(void )JVMTI_FUNC_PTR (gdata -> jvmti ,SetTag )
148
157
(gdata -> jvmti , node -> ref , NULL_OBJECT_ID );
149
- if (node -> strongCount != 0 ) {
158
+ if (isStrong ( node ) ) {
150
159
JNI_FUNC_PTR (env ,DeleteGlobalRef )(env , node -> ref );
151
160
} else {
152
161
JNI_FUNC_PTR (env ,DeleteWeakGlobalRef )(env , node -> ref );
@@ -158,9 +167,9 @@ deleteNode(JNIEnv *env, RefNode *node)
158
167
159
168
/* Change a RefNode to have a strong reference */
160
169
static jobject
161
- strengthenNode (JNIEnv * env , RefNode * node )
170
+ strengthenNode (JNIEnv * env , RefNode * node , jboolean isPinAll )
162
171
{
163
- if (node -> strongCount == 0 ) {
172
+ if (! isStrong ( node ) ) {
164
173
jobject strongRef ;
165
174
166
175
strongRef = JNI_FUNC_PTR (env ,NewGlobalRef )(env , node -> ref );
@@ -176,20 +185,27 @@ strengthenNode(JNIEnv *env, RefNode *node)
176
185
if (strongRef != NULL ) {
177
186
JNI_FUNC_PTR (env ,DeleteWeakGlobalRef )(env , node -> ref );
178
187
node -> ref = strongRef ;
179
- node -> strongCount = 1 ;
188
+ } else {
189
+ return NULL ;
180
190
}
181
- return strongRef ;
191
+ }
192
+ if (isPinAll ) {
193
+ node -> isPinAll = JNI_TRUE ;
182
194
} else {
183
- node -> strongCount ++ ;
184
- return node -> ref ;
195
+ node -> isCommonPin = JNI_TRUE ;
185
196
}
197
+ return node -> ref ;
186
198
}
187
199
188
200
/* Change a RefNode to have a weak reference */
189
201
static jweak
190
- weakenNode (JNIEnv * env , RefNode * node )
202
+ weakenNode (JNIEnv * env , RefNode * node , jboolean isUnpinAll )
191
203
{
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 ) {
193
209
jweak weakRef ;
194
210
195
211
weakRef = JNI_FUNC_PTR (env ,NewWeakGlobalRef )(env , node -> ref );
@@ -200,16 +216,18 @@ weakenNode(JNIEnv *env, RefNode *node)
200
216
201
217
if (weakRef != NULL ) {
202
218
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 ;
205
222
}
206
- return weakRef ;
223
+ }
224
+
225
+ if (isUnpinAll ) {
226
+ node -> isPinAll = JNI_FALSE ;
207
227
} else {
208
- if (node -> strongCount > 0 ) {
209
- node -> strongCount -- ;
210
- }
211
- return node -> ref ;
228
+ node -> isCommonPin = JNI_FALSE ;
212
229
}
230
+ return node -> ref ;
213
231
}
214
232
215
233
/*
@@ -470,7 +488,7 @@ commonRef_idToRef(JNIEnv *env, jlong id)
470
488
471
489
node = findNodeByID (env , id );
472
490
if (node != NULL ) {
473
- if (node -> strongCount != 0 ) {
491
+ if (isStrong ( node ) ) {
474
492
saveGlobalRef (env , node -> ref , & ref );
475
493
} else {
476
494
jobject lref ;
@@ -522,7 +540,7 @@ commonRef_pin(jlong id)
522
540
} else {
523
541
jobject strongRef ;
524
542
525
- strongRef = strengthenNode (env , node );
543
+ strongRef = strengthenNode (env , node , JNI_FALSE /* isPinAll */ );
526
544
if (strongRef == NULL ) {
527
545
/*
528
546
* Referent has been collected, clean up now.
@@ -551,7 +569,7 @@ commonRef_unpin(jlong id)
551
569
if (node != NULL ) {
552
570
jweak weakRef ;
553
571
554
- weakRef = weakenNode (env , node );
572
+ weakRef = weakenNode (env , node , JNI_FALSE /* isUnpinAll */ );
555
573
if (weakRef == NULL ) {
556
574
error = AGENT_ERROR_OUT_OF_MEMORY ;
557
575
}
@@ -585,7 +603,7 @@ commonRef_pinAll()
585
603
while (node != NULL ) {
586
604
jobject strongRef ;
587
605
588
- strongRef = strengthenNode (env , node );
606
+ strongRef = strengthenNode (env , node , JNI_TRUE /* isPinAll */ );
589
607
590
608
/* Has the object been collected? */
591
609
if (strongRef == NULL ) {
@@ -628,7 +646,7 @@ commonRef_unpinAll()
628
646
for (node = gdata -> objectsByID [i ]; node != NULL ; node = node -> next ) {
629
647
jweak weakRef ;
630
648
631
- weakRef = weakenNode (env , node );
649
+ weakRef = weakenNode (env , node , JNI_TRUE /* isUnpinAll */ );
632
650
if (weakRef == NULL ) {
633
651
EXIT_ERROR (AGENT_ERROR_NULL_POINTER ,"NewWeakGlobalRef" );
634
652
}
@@ -676,8 +694,7 @@ commonRef_compact(void)
676
694
prev = NULL ;
677
695
while (node != NULL ) {
678
696
/* 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 )) {
681
698
RefNode * freed ;
682
699
683
700
/* Detach from the ID list */
0 commit comments