30
30
import java .util .Set ;
31
31
import java .util .concurrent .ConcurrentHashMap ;
32
32
import java .util .concurrent .ConcurrentMap ;
33
- import java .util .concurrent .atomic .AtomicBoolean ;
33
+ import java .util .concurrent .atomic .AtomicIntegerFieldUpdater ;
34
34
import java .util .concurrent .atomic .AtomicReferenceFieldUpdater ;
35
35
36
36
import org .graalvm .compiler .debug .GraalError ;
@@ -58,6 +58,24 @@ public abstract class AnalysisField extends AnalysisElement implements ResolvedJ
58
58
private static final AtomicReferenceFieldUpdater <AnalysisField , Object > OBSERVERS_UPDATER = //
59
59
AtomicReferenceFieldUpdater .newUpdater (AnalysisField .class , Object .class , "observers" );
60
60
61
+ private static final AtomicIntegerFieldUpdater <AnalysisField > isAccessedUpdater = AtomicIntegerFieldUpdater
62
+ .newUpdater (AnalysisField .class , "isAccessed" );
63
+
64
+ private static final AtomicIntegerFieldUpdater <AnalysisField > isReadUpdater = AtomicIntegerFieldUpdater
65
+ .newUpdater (AnalysisField .class , "isRead" );
66
+
67
+ private static final AtomicIntegerFieldUpdater <AnalysisField > isWrittenUpdater = AtomicIntegerFieldUpdater
68
+ .newUpdater (AnalysisField .class , "isWritten" );
69
+
70
+ private static final AtomicIntegerFieldUpdater <AnalysisField > isFoldedUpdater = AtomicIntegerFieldUpdater
71
+ .newUpdater (AnalysisField .class , "isFolded" );
72
+
73
+ private static final AtomicIntegerFieldUpdater <AnalysisField > isUnsafeAccessedUpdater = AtomicIntegerFieldUpdater
74
+ .newUpdater (AnalysisField .class , "isUnsafeAccessed" );
75
+
76
+ private static final AtomicIntegerFieldUpdater <AnalysisField > unsafeFrozenTypeStateUpdater = AtomicIntegerFieldUpdater
77
+ .newUpdater (AnalysisField .class , "unsafeFrozenTypeState" );
78
+
61
79
private final int id ;
62
80
63
81
public final ResolvedJavaField wrapped ;
@@ -74,15 +92,15 @@ public abstract class AnalysisField extends AnalysisElement implements ResolvedJ
74
92
*/
75
93
private ContextInsensitiveFieldTypeFlow instanceFieldFlow ;
76
94
77
- private AtomicBoolean isAccessed = new AtomicBoolean () ;
78
- private AtomicBoolean isRead = new AtomicBoolean () ;
79
- private AtomicBoolean isWritten = new AtomicBoolean () ;
80
- private AtomicBoolean isFolded = new AtomicBoolean () ;
95
+ @ SuppressWarnings ( "unused" ) private volatile int isAccessed ;
96
+ @ SuppressWarnings ( "unused" ) private volatile int isRead ;
97
+ @ SuppressWarnings ( "unused" ) private volatile int isWritten ;
98
+ @ SuppressWarnings ( "unused" ) private volatile int isFolded ;
81
99
82
100
private boolean isJNIAccessed ;
83
101
private boolean isUsedInComparison ;
84
- private AtomicBoolean isUnsafeAccessed ;
85
- private AtomicBoolean unsafeFrozenTypeState ;
102
+ @ SuppressWarnings ( "unused" ) private volatile int isUnsafeAccessed ;
103
+ @ SuppressWarnings ( "unused" ) private volatile int unsafeFrozenTypeState ;
86
104
@ SuppressWarnings ("unused" ) private volatile Object observers ;
87
105
88
106
/**
@@ -106,8 +124,6 @@ public AnalysisField(AnalysisUniverse universe, ResolvedJavaField wrappedField)
106
124
assert !wrappedField .isInternal ();
107
125
108
126
this .position = -1 ;
109
- this .isUnsafeAccessed = new AtomicBoolean ();
110
- this .unsafeFrozenTypeState = new AtomicBoolean ();
111
127
112
128
this .wrapped = wrappedField ;
113
129
this .id = universe .nextFieldId .getAndIncrement ();
@@ -153,30 +169,30 @@ private static AnalysisType getDeclaredType(AnalysisUniverse universe, ResolvedJ
153
169
}
154
170
155
171
public void copyAccessInfos (AnalysisField other ) {
156
- this . isAccessed = new AtomicBoolean ( other .isAccessed . get () );
157
- this . isUnsafeAccessed = other .isUnsafeAccessed ;
172
+ isAccessedUpdater . set ( this , other .isAccessed );
173
+ isUnsafeAccessedUpdater . set ( this , other .isUnsafeAccessed ) ;
158
174
this .canBeNull = other .canBeNull ;
159
- this . isWritten = new AtomicBoolean ( other .isWritten . get () );
160
- this . isFolded = new AtomicBoolean ( other .isFolded . get () );
161
- this . isRead = new AtomicBoolean ( other .isRead . get () );
175
+ isWrittenUpdater . set ( this , other .isWritten );
176
+ isFoldedUpdater . set ( this , other .isFolded );
177
+ isReadUpdater . set ( this , other .isRead );
162
178
notifyUpdateAccessInfo ();
163
179
}
164
180
165
181
public void intersectAccessInfos (AnalysisField other ) {
166
- this . isAccessed = new AtomicBoolean (this .isAccessed . get () && other .isAccessed . get () );
182
+ isAccessedUpdater . set (this , this .isAccessed & other .isAccessed );
167
183
this .canBeNull = this .canBeNull && other .canBeNull ;
168
- this . isWritten = new AtomicBoolean (this .isWritten . get () && other .isWritten . get () );
169
- this . isFolded = new AtomicBoolean (this .isFolded . get () && other .isFolded . get () );
170
- this . isRead = new AtomicBoolean (this .isRead . get () && other .isRead . get () );
184
+ isWrittenUpdater . set (this , this .isWritten & other .isWritten );
185
+ isFoldedUpdater . set (this , this .isFolded & other .isFolded );
186
+ isReadUpdater . set (this , this .isRead & other .isRead );
171
187
notifyUpdateAccessInfo ();
172
188
}
173
189
174
190
public void clearAccessInfos () {
175
- this . isAccessed . set (false );
191
+ isAccessedUpdater . set (this , 0 );
176
192
this .canBeNull = true ;
177
- this . isWritten . set (false );
178
- this . isFolded . set (false );
179
- this . isRead . set (false );
193
+ isWrittenUpdater . set (this , 0 );
194
+ isFoldedUpdater . set (this , 0 );
195
+ isReadUpdater . set (this , 0 );
180
196
notifyUpdateAccessInfo ();
181
197
}
182
198
@@ -239,7 +255,7 @@ public void cleanupAfterAnalysis() {
239
255
}
240
256
241
257
public boolean registerAsAccessed () {
242
- boolean firstAttempt = AtomicUtils .atomicMark (isAccessed );
258
+ boolean firstAttempt = AtomicUtils .atomicMark (this , isAccessedUpdater );
243
259
notifyUpdateAccessInfo ();
244
260
if (firstAttempt ) {
245
261
onReachable ();
@@ -250,7 +266,7 @@ public boolean registerAsAccessed() {
250
266
}
251
267
252
268
public boolean registerAsRead (MethodTypeFlow method ) {
253
- boolean firstAttempt = AtomicUtils .atomicMark (isRead );
269
+ boolean firstAttempt = AtomicUtils .atomicMark (this , isReadUpdater );
254
270
notifyUpdateAccessInfo ();
255
271
if (readBy != null && method != null ) {
256
272
readBy .put (method , Boolean .TRUE );
@@ -270,7 +286,7 @@ public boolean registerAsRead(MethodTypeFlow method) {
270
286
* for an unsafe accessed field.
271
287
*/
272
288
public boolean registerAsWritten (MethodTypeFlow method ) {
273
- boolean firstAttempt = AtomicUtils .atomicMark (isWritten );
289
+ boolean firstAttempt = AtomicUtils .atomicMark (this , isWrittenUpdater );
274
290
notifyUpdateAccessInfo ();
275
291
if (writtenBy != null && method != null ) {
276
292
writtenBy .put (method , Boolean .TRUE );
@@ -285,7 +301,7 @@ public boolean registerAsWritten(MethodTypeFlow method) {
285
301
}
286
302
287
303
public void markFolded () {
288
- if (AtomicUtils .atomicMark (isFolded )) {
304
+ if (AtomicUtils .atomicMark (this , isFoldedUpdater )) {
289
305
getDeclaringClass ().registerAsReachable ();
290
306
onReachable ();
291
307
}
@@ -305,9 +321,9 @@ public void registerAsUnsafeAccessed(UnsafePartitionKind partitionKind) {
305
321
* only register fields as unsafe accessed with their declaring type once.
306
322
*/
307
323
308
- if (! isUnsafeAccessed .getAndSet (true ) ) {
324
+ if (isUnsafeAccessedUpdater .getAndSet (this , 1 ) != 1 ) {
309
325
/*
310
- * The atomic boolean ensures that the field is registered as unsafe accessed with its
326
+ * The atomic updater ensures that the field is registered as unsafe accessed with its
311
327
* declaring class only once. However, at the end of this call the registration might
312
328
* still be in progress. The first thread that calls this methods enters the if and
313
329
* starts the registration, the next threads return right away, while the registration
@@ -329,7 +345,7 @@ public void registerAsUnsafeAccessed(UnsafePartitionKind partitionKind) {
329
345
}
330
346
331
347
public boolean isUnsafeAccessed () {
332
- return isUnsafeAccessed . get ( );
348
+ return AtomicUtils . isSet ( this , isUnsafeAccessedUpdater );
333
349
}
334
350
335
351
public void registerAsJNIAccessed () {
@@ -341,11 +357,11 @@ public boolean isJNIAccessed() {
341
357
}
342
358
343
359
public void setUnsafeFrozenTypeState (boolean value ) {
344
- unsafeFrozenTypeState . getAndSet ( value );
360
+ unsafeFrozenTypeStateUpdater . set ( this , value ? 1 : 0 );
345
361
}
346
362
347
363
public boolean hasUnsafeFrozenTypeState () {
348
- return unsafeFrozenTypeState . get ( );
364
+ return AtomicUtils . isSet ( this , unsafeFrozenTypeStateUpdater );
349
365
}
350
366
351
367
public Set <MethodTypeFlow > getReadBy () {
@@ -376,24 +392,26 @@ public Set<MethodTypeFlow> getWrittenBy() {
376
392
* DirectByteBuffer remains reachable.
377
393
*/
378
394
public boolean isAccessed () {
379
- return isAccessed .get () || isRead .get () || (isWritten .get () && (Modifier .isVolatile (getModifiers ()) || getStorageKind () == JavaKind .Object ));
395
+ return AtomicUtils .isSet (this , isAccessedUpdater ) || AtomicUtils .isSet (this , isReadUpdater ) ||
396
+ (AtomicUtils .isSet (this , isWrittenUpdater ) && (Modifier .isVolatile (getModifiers ()) || getStorageKind () == JavaKind .Object ));
380
397
}
381
398
382
399
public boolean isRead () {
383
- return isAccessed . get ( ) || isRead . get ( );
400
+ return AtomicUtils . isSet ( this , isAccessedUpdater ) || AtomicUtils . isSet ( this , isReadUpdater );
384
401
}
385
402
386
403
public boolean isWritten () {
387
- return isAccessed . get ( ) || isWritten . get ( );
404
+ return AtomicUtils . isSet ( this , isAccessedUpdater ) || AtomicUtils . isSet ( this , isWrittenUpdater );
388
405
}
389
406
390
407
public boolean isFolded () {
391
- return isFolded . get ( );
408
+ return AtomicUtils . isSet ( this , isFoldedUpdater );
392
409
}
393
410
394
411
@ Override
395
412
public boolean isReachable () {
396
- return isAccessed .get () || isRead .get () || isWritten .get () || isFolded .get ();
413
+ return AtomicUtils .isSet (this , isAccessedUpdater ) || AtomicUtils .isSet (this , isReadUpdater ) ||
414
+ AtomicUtils .isSet (this , isWrittenUpdater ) || AtomicUtils .isSet (this , isFoldedUpdater );
397
415
}
398
416
399
417
@ Override
0 commit comments