1
25 package java.lang.invoke;
26
27 import jdk.internal.util.Preconditions;
28 import jdk.internal.vm.annotation.ForceInline;
29
30 import java.util.Objects;
31
32 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
33
34
35
36 final class VarHandleObjects {
37
38 static class FieldInstanceReadOnly extends VarHandle {
39 final long fieldOffset;
40 final Class<?> receiverType;
41 final Class<?> fieldType;
42
43 FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset, Class<?> fieldType) {
44 this(receiverType, fieldOffset, fieldType, FieldInstanceReadOnly.FORM);
45 }
46
47 protected FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset, Class<?> fieldType,
48 VarForm form) {
49 super(form);
50 this.fieldOffset = fieldOffset;
51 this.receiverType = receiverType;
52 this.fieldType = fieldType;
53 }
54
55 @Override
56 final MethodType accessModeTypeUncached(AccessMode accessMode) {
57 return accessMode.at.accessModeType(receiverType, fieldType);
58 }
59
60 @ForceInline
61 static Object get(FieldInstanceReadOnly handle, Object holder) {
62 return UNSAFE.getObject(Objects.requireNonNull(handle.receiverType.cast(holder)),
63 handle.fieldOffset);
64 }
65
66 @ForceInline
67 static Object getVolatile(FieldInstanceReadOnly handle, Object holder) {
68 return UNSAFE.getObjectVolatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
69 handle.fieldOffset);
70 }
71
72 @ForceInline
73 static Object getOpaque(FieldInstanceReadOnly handle, Object holder) {
74 return UNSAFE.getObjectOpaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
75 handle.fieldOffset);
76 }
77
78 @ForceInline
79 static Object getAcquire(FieldInstanceReadOnly handle, Object holder) {
80 return UNSAFE.getObjectAcquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
81 handle.fieldOffset);
82 }
83
84 static final VarForm FORM = new VarForm(FieldInstanceReadOnly.class, Object.class, Object.class);
85 }
86
87 static final class FieldInstanceReadWrite extends FieldInstanceReadOnly {
88
89 FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset, Class<?> fieldType) {
90 super(receiverType, fieldOffset, fieldType, FieldInstanceReadWrite.FORM);
91 }
92
93 @ForceInline
94 static void set(FieldInstanceReadWrite handle, Object holder, Object value) {
95 UNSAFE.putObject(Objects.requireNonNull(handle.receiverType.cast(holder)),
96 handle.fieldOffset,
97 handle.fieldType.cast(value));
98 }
99
100 @ForceInline
101 static void setVolatile(FieldInstanceReadWrite handle, Object holder, Object value) {
102 UNSAFE.putObjectVolatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
103 handle.fieldOffset,
104 handle.fieldType.cast(value));
105 }
106
107 @ForceInline
108 static void setOpaque(FieldInstanceReadWrite handle, Object holder, Object value) {
109 UNSAFE.putObjectOpaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
110 handle.fieldOffset,
111 handle.fieldType.cast(value));
112 }
113
114 @ForceInline
115 static void setRelease(FieldInstanceReadWrite handle, Object holder, Object value) {
116 UNSAFE.putObjectRelease(Objects.requireNonNull(handle.receiverType.cast(holder)),
117 handle.fieldOffset,
118 handle.fieldType.cast(value));
119 }
120
121 @ForceInline
122 static boolean compareAndSet(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
123 return UNSAFE.compareAndSetObject(Objects.requireNonNull(handle.receiverType.cast(holder)),
124 handle.fieldOffset,
125 handle.fieldType.cast(expected),
126 handle.fieldType.cast(value));
127 }
128
129 @ForceInline
130 static Object compareAndExchange(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
131 return UNSAFE.compareAndExchangeObject(Objects.requireNonNull(handle.receiverType.cast(holder)),
132 handle.fieldOffset,
133 handle.fieldType.cast(expected),
134 handle.fieldType.cast(value));
135 }
136
137 @ForceInline
138 static Object compareAndExchangeAcquire(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
139 return UNSAFE.compareAndExchangeObjectAcquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
140 handle.fieldOffset,
141 handle.fieldType.cast(expected),
142 handle.fieldType.cast(value));
143 }
144
145 @ForceInline
146 static Object compareAndExchangeRelease(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
147 return UNSAFE.compareAndExchangeObjectRelease(Objects.requireNonNull(handle.receiverType.cast(holder)),
148 handle.fieldOffset,
149 handle.fieldType.cast(expected),
150 handle.fieldType.cast(value));
151 }
152
153 @ForceInline
154 static boolean weakCompareAndSetPlain(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
155 return UNSAFE.weakCompareAndSetObjectPlain(Objects.requireNonNull(handle.receiverType.cast(holder)),
156 handle.fieldOffset,
157 handle.fieldType.cast(expected),
158 handle.fieldType.cast(value));
159 }
160
161 @ForceInline
162 static boolean weakCompareAndSet(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
163 return UNSAFE.weakCompareAndSetObject(Objects.requireNonNull(handle.receiverType.cast(holder)),
164 handle.fieldOffset,
165 handle.fieldType.cast(expected),
166 handle.fieldType.cast(value));
167 }
168
169 @ForceInline
170 static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
171 return UNSAFE.weakCompareAndSetObjectAcquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
172 handle.fieldOffset,
173 handle.fieldType.cast(expected),
174 handle.fieldType.cast(value));
175 }
176
177 @ForceInline
178 static boolean weakCompareAndSetRelease(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
179 return UNSAFE.weakCompareAndSetObjectRelease(Objects.requireNonNull(handle.receiverType.cast(holder)),
180 handle.fieldOffset,
181 handle.fieldType.cast(expected),
182 handle.fieldType.cast(value));
183 }
184
185 @ForceInline
186 static Object getAndSet(FieldInstanceReadWrite handle, Object holder, Object value) {
187 return UNSAFE.getAndSetObject(Objects.requireNonNull(handle.receiverType.cast(holder)),
188 handle.fieldOffset,
189 handle.fieldType.cast(value));
190 }
191
192 @ForceInline
193 static Object getAndSetAcquire(FieldInstanceReadWrite handle, Object holder, Object value) {
194 return UNSAFE.getAndSetObjectAcquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
195 handle.fieldOffset,
196 handle.fieldType.cast(value));
197 }
198
199 @ForceInline
200 static Object getAndSetRelease(FieldInstanceReadWrite handle, Object holder, Object value) {
201 return UNSAFE.getAndSetObjectRelease(Objects.requireNonNull(handle.receiverType.cast(holder)),
202 handle.fieldOffset,
203 handle.fieldType.cast(value));
204 }
205
206 static final VarForm FORM = new VarForm(FieldInstanceReadWrite.class, Object.class, Object.class);
207 }
208
209
210 static class FieldStaticReadOnly extends VarHandle {
211 final Object base;
212 final long fieldOffset;
213 final Class<?> fieldType;
214
215 FieldStaticReadOnly(Object base, long fieldOffset, Class<?> fieldType) {
216 this(base, fieldOffset, fieldType, FieldStaticReadOnly.FORM);
217 }
218
219 protected FieldStaticReadOnly(Object base, long fieldOffset, Class<?> fieldType,
220 VarForm form) {
221 super(form);
222 this.base = base;
223 this.fieldOffset = fieldOffset;
224 this.fieldType = fieldType;
225 }
226
227 @Override
228 final MethodType accessModeTypeUncached(AccessMode accessMode) {
229 return accessMode.at.accessModeType(null, fieldType);
230 }
231
232 @ForceInline
233 static Object get(FieldStaticReadOnly handle) {
234 return UNSAFE.getObject(handle.base,
235 handle.fieldOffset);
236 }
237
238 @ForceInline
239 static Object getVolatile(FieldStaticReadOnly handle) {
240 return UNSAFE.getObjectVolatile(handle.base,
241 handle.fieldOffset);
242 }
243
244 @ForceInline
245 static Object getOpaque(FieldStaticReadOnly handle) {
246 return UNSAFE.getObjectOpaque(handle.base,
247 handle.fieldOffset);
248 }
249
250 @ForceInline
251 static Object getAcquire(FieldStaticReadOnly handle) {
252 return UNSAFE.getObjectAcquire(handle.base,
253 handle.fieldOffset);
254 }
255
256 static final VarForm FORM = new VarForm(FieldStaticReadOnly.class, null, Object.class);
257 }
258
259 static final class FieldStaticReadWrite extends FieldStaticReadOnly {
260
261 FieldStaticReadWrite(Object base, long fieldOffset, Class<?> fieldType) {
262 super(base, fieldOffset, fieldType, FieldStaticReadWrite.FORM);
263 }
264
265 @ForceInline
266 static void set(FieldStaticReadWrite handle, Object value) {
267 UNSAFE.putObject(handle.base,
268 handle.fieldOffset,
269 handle.fieldType.cast(value));
270 }
271
272 @ForceInline
273 static void setVolatile(FieldStaticReadWrite handle, Object value) {
274 UNSAFE.putObjectVolatile(handle.base,
275 handle.fieldOffset,
276 handle.fieldType.cast(value));
277 }
278
279 @ForceInline
280 static void setOpaque(FieldStaticReadWrite handle, Object value) {
281 UNSAFE.putObjectOpaque(handle.base,
282 handle.fieldOffset,
283 handle.fieldType.cast(value));
284 }
285
286 @ForceInline
287 static void setRelease(FieldStaticReadWrite handle, Object value) {
288 UNSAFE.putObjectRelease(handle.base,
289 handle.fieldOffset,
290 handle.fieldType.cast(value));
291 }
292
293 @ForceInline
294 static boolean compareAndSet(FieldStaticReadWrite handle, Object expected, Object value) {
295 return UNSAFE.compareAndSetObject(handle.base,
296 handle.fieldOffset,
297 handle.fieldType.cast(expected),
298 handle.fieldType.cast(value));
299 }
300
301
302 @ForceInline
303 static Object compareAndExchange(FieldStaticReadWrite handle, Object expected, Object value) {
304 return UNSAFE.compareAndExchangeObject(handle.base,
305 handle.fieldOffset,
306 handle.fieldType.cast(expected),
307 handle.fieldType.cast(value));
308 }
309
310 @ForceInline
311 static Object compareAndExchangeAcquire(FieldStaticReadWrite handle, Object expected, Object value) {
312 return UNSAFE.compareAndExchangeObjectAcquire(handle.base,
313 handle.fieldOffset,
314 handle.fieldType.cast(expected),
315 handle.fieldType.cast(value));
316 }
317
318 @ForceInline
319 static Object compareAndExchangeRelease(FieldStaticReadWrite handle, Object expected, Object value) {
320 return UNSAFE.compareAndExchangeObjectRelease(handle.base,
321 handle.fieldOffset,
322 handle.fieldType.cast(expected),
323 handle.fieldType.cast(value));
324 }
325
326 @ForceInline
327 static boolean weakCompareAndSetPlain(FieldStaticReadWrite handle, Object expected, Object value) {
328 return UNSAFE.weakCompareAndSetObjectPlain(handle.base,
329 handle.fieldOffset,
330 handle.fieldType.cast(expected),
331 handle.fieldType.cast(value));
332 }
333
334 @ForceInline
335 static boolean weakCompareAndSet(FieldStaticReadWrite handle, Object expected, Object value) {
336 return UNSAFE.weakCompareAndSetObject(handle.base,
337 handle.fieldOffset,
338 handle.fieldType.cast(expected),
339 handle.fieldType.cast(value));
340 }
341
342 @ForceInline
343 static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, Object expected, Object value) {
344 return UNSAFE.weakCompareAndSetObjectAcquire(handle.base,
345 handle.fieldOffset,
346 handle.fieldType.cast(expected),
347 handle.fieldType.cast(value));
348 }
349
350 @ForceInline
351 static boolean weakCompareAndSetRelease(FieldStaticReadWrite handle, Object expected, Object value) {
352 return UNSAFE.weakCompareAndSetObjectRelease(handle.base,
353 handle.fieldOffset,
354 handle.fieldType.cast(expected),
355 handle.fieldType.cast(value));
356 }
357
358 @ForceInline
359 static Object getAndSet(FieldStaticReadWrite handle, Object value) {
360 return UNSAFE.getAndSetObject(handle.base,
361 handle.fieldOffset,
362 handle.fieldType.cast(value));
363 }
364
365 @ForceInline
366 static Object getAndSetAcquire(FieldStaticReadWrite handle, Object value) {
367 return UNSAFE.getAndSetObjectAcquire(handle.base,
368 handle.fieldOffset,
369 handle.fieldType.cast(value));
370 }
371
372 @ForceInline
373 static Object getAndSetRelease(FieldStaticReadWrite handle, Object value) {
374 return UNSAFE.getAndSetObjectRelease(handle.base,
375 handle.fieldOffset,
376 handle.fieldType.cast(value));
377 }
378
379 static final VarForm FORM = new VarForm(FieldStaticReadWrite.class, null, Object.class);
380 }
381
382
383 static final class Array extends VarHandle {
384 final int abase;
385 final int ashift;
386 final Class<?> arrayType;
387 final Class<?> componentType;
388
389 Array(int abase, int ashift, Class<?> arrayType) {
390 super(Array.FORM);
391 this.abase = abase;
392 this.ashift = ashift;
393 this.arrayType = arrayType;
394 this.componentType = arrayType.getComponentType();
395 }
396
397 @Override
398 final MethodType accessModeTypeUncached(AccessMode accessMode) {
399 return accessMode.at.accessModeType(arrayType, arrayType.getComponentType(), int.class);
400 }
401
402 @ForceInline
403 static Object runtimeTypeCheck(Array handle, Object[] oarray, Object value) {
404 if (handle.arrayType == oarray.getClass()) {
405
406 return handle.componentType.cast(value);
407 } else {
408
409 return reflectiveTypeCheck(oarray, value);
410 }
411 }
412
413 @ForceInline
414 static Object reflectiveTypeCheck(Object[] oarray, Object value) {
415 try {
416 return oarray.getClass().getComponentType().cast(value);
417 } catch (ClassCastException e) {
418 throw new ArrayStoreException();
419 }
420 }
421
422 @ForceInline
423 static Object get(Array handle, Object oarray, int index) {
424 Object[] array = (Object[]) handle.arrayType.cast(oarray);
425 return array[index];
426 }
427
428 @ForceInline
429 static void set(Array handle, Object oarray, int index, Object value) {
430 Object[] array = (Object[]) handle.arrayType.cast(oarray);
431 array[index] = handle.componentType.cast(value);
432 }
433
434 @ForceInline
435 static Object getVolatile(Array handle, Object oarray, int index) {
436 Object[] array = (Object[]) handle.arrayType.cast(oarray);
437 return UNSAFE.getObjectVolatile(array,
438 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
439 }
440
441 @ForceInline
442 static void setVolatile(Array handle, Object oarray, int index, Object value) {
443 Object[] array = (Object[]) handle.arrayType.cast(oarray);
444 UNSAFE.putObjectVolatile(array,
445 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
446 runtimeTypeCheck(handle, array, value));
447 }
448
449 @ForceInline
450 static Object getOpaque(Array handle, Object oarray, int index) {
451 Object[] array = (Object[]) handle.arrayType.cast(oarray);
452 return UNSAFE.getObjectOpaque(array,
453 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
454 }
455
456 @ForceInline
457 static void setOpaque(Array handle, Object oarray, int index, Object value) {
458 Object[] array = (Object[]) handle.arrayType.cast(oarray);
459 UNSAFE.putObjectOpaque(array,
460 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
461 runtimeTypeCheck(handle, array, value));
462 }
463
464 @ForceInline
465 static Object getAcquire(Array handle, Object oarray, int index) {
466 Object[] array = (Object[]) handle.arrayType.cast(oarray);
467 return UNSAFE.getObjectAcquire(array,
468 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
469 }
470
471 @ForceInline
472 static void setRelease(Array handle, Object oarray, int index, Object value) {
473 Object[] array = (Object[]) handle.arrayType.cast(oarray);
474 UNSAFE.putObjectRelease(array,
475 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
476 runtimeTypeCheck(handle, array, value));
477 }
478
479 @ForceInline
480 static boolean compareAndSet(Array handle, Object oarray, int index, Object expected, Object value) {
481 Object[] array = (Object[]) handle.arrayType.cast(oarray);
482 return UNSAFE.compareAndSetObject(array,
483 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
484 handle.componentType.cast(expected),
485 runtimeTypeCheck(handle, array, value));
486 }
487
488 @ForceInline
489 static Object compareAndExchange(Array handle, Object oarray, int index, Object expected, Object value) {
490 Object[] array = (Object[]) handle.arrayType.cast(oarray);
491 return UNSAFE.compareAndExchangeObject(array,
492 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
493 handle.componentType.cast(expected),
494 runtimeTypeCheck(handle, array, value));
495 }
496
497 @ForceInline
498 static Object compareAndExchangeAcquire(Array handle, Object oarray, int index, Object expected, Object value) {
499 Object[] array = (Object[]) handle.arrayType.cast(oarray);
500 return UNSAFE.compareAndExchangeObjectAcquire(array,
501 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
502 handle.componentType.cast(expected),
503 runtimeTypeCheck(handle, array, value));
504 }
505
506 @ForceInline
507 static Object compareAndExchangeRelease(Array handle, Object oarray, int index, Object expected, Object value) {
508 Object[] array = (Object[]) handle.arrayType.cast(oarray);
509 return UNSAFE.compareAndExchangeObjectRelease(array,
510 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
511 handle.componentType.cast(expected),
512 runtimeTypeCheck(handle, array, value));
513 }
514
515 @ForceInline
516 static boolean weakCompareAndSetPlain(Array handle, Object oarray, int index, Object expected, Object value) {
517 Object[] array = (Object[]) handle.arrayType.cast(oarray);
518 return UNSAFE.weakCompareAndSetObjectPlain(array,
519 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
520 handle.componentType.cast(expected),
521 runtimeTypeCheck(handle, array, value));
522 }
523
524 @ForceInline
525 static boolean weakCompareAndSet(Array handle, Object oarray, int index, Object expected, Object value) {
526 Object[] array = (Object[]) handle.arrayType.cast(oarray);
527 return UNSAFE.weakCompareAndSetObject(array,
528 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
529 handle.componentType.cast(expected),
530 runtimeTypeCheck(handle, array, value));
531 }
532
533 @ForceInline
534 static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, Object expected, Object value) {
535 Object[] array = (Object[]) handle.arrayType.cast(oarray);
536 return UNSAFE.weakCompareAndSetObjectAcquire(array,
537 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
538 handle.componentType.cast(expected),
539 runtimeTypeCheck(handle, array, value));
540 }
541
542 @ForceInline
543 static boolean weakCompareAndSetRelease(Array handle, Object oarray, int index, Object expected, Object value) {
544 Object[] array = (Object[]) handle.arrayType.cast(oarray);
545 return UNSAFE.weakCompareAndSetObjectRelease(array,
546 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
547 handle.componentType.cast(expected),
548 runtimeTypeCheck(handle, array, value));
549 }
550
551 @ForceInline
552 static Object getAndSet(Array handle, Object oarray, int index, Object value) {
553 Object[] array = (Object[]) handle.arrayType.cast(oarray);
554 return UNSAFE.getAndSetObject(array,
555 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
556 runtimeTypeCheck(handle, array, value));
557 }
558
559 @ForceInline
560 static Object getAndSetAcquire(Array handle, Object oarray, int index, Object value) {
561 Object[] array = (Object[]) handle.arrayType.cast(oarray);
562 return UNSAFE.getAndSetObjectAcquire(array,
563 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
564 runtimeTypeCheck(handle, array, value));
565 }
566
567 @ForceInline
568 static Object getAndSetRelease(Array handle, Object oarray, int index, Object value) {
569 Object[] array = (Object[]) handle.arrayType.cast(oarray);
570 return UNSAFE.getAndSetObjectRelease(array,
571 (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
572 runtimeTypeCheck(handle, array, value));
573 }
574
575 static final VarForm FORM = new VarForm(Array.class, Object[].class, Object.class, int.class);
576 }
577 }
578