src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template
changeset 49788 5375d426822a
parent 47216 71c04702a3d5
child 52914 4fa75d8ad418
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Fri Jan 19 11:24:39 2018 -0800
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Mon Jan 22 13:27:28 2018 -0800
@@ -592,6 +592,28 @@
             return accessMode.at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
         }
 
+#if[Object]
+        @ForceInline
+        static Object runtimeTypeCheck(Array handle, Object[] oarray, Object value) {
+            if (handle.arrayType == oarray.getClass()) {
+                // Fast path: static array type same as argument array type
+                return handle.componentType.cast(value);
+            } else {
+                // Slow path: check value against argument array component type
+                return reflectiveTypeCheck(oarray, value);
+            }
+        }
+
+        @ForceInline
+        static Object reflectiveTypeCheck(Object[] oarray, Object value) {
+            try {
+                return oarray.getClass().getComponentType().cast(value);
+            } catch (ClassCastException e) {
+                throw new ArrayStoreException();
+            }
+        }
+#end[Object]
+
         @ForceInline
         static $type$ get(Array handle, Object oarray, int index) {
 #if[Object]
@@ -632,7 +654,7 @@
 #end[Object]
             UNSAFE.put$Type$Volatile(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -655,7 +677,7 @@
 #end[Object]
             UNSAFE.put$Type$Opaque(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -678,7 +700,7 @@
 #end[Object]
             UNSAFE.put$Type$Release(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 #if[CAS]
 
@@ -692,7 +714,7 @@
             return UNSAFE.compareAndSet$Type$(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -705,7 +727,7 @@
             return UNSAFE.compareAndExchange$Type$(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -718,7 +740,7 @@
             return UNSAFE.compareAndExchange$Type$Acquire(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -731,7 +753,7 @@
             return UNSAFE.compareAndExchange$Type$Release(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -744,7 +766,7 @@
             return UNSAFE.weakCompareAndSet$Type$Plain(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -757,7 +779,7 @@
             return UNSAFE.weakCompareAndSet$Type$(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -770,7 +792,7 @@
             return UNSAFE.weakCompareAndSet$Type$Acquire(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -783,7 +805,7 @@
             return UNSAFE.weakCompareAndSet$Type$Release(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -795,7 +817,7 @@
 #end[Object]
             return UNSAFE.getAndSet$Type$(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -807,7 +829,7 @@
 #end[Object]
             return UNSAFE.getAndSet$Type$Acquire(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -819,7 +841,7 @@
 #end[Object]
             return UNSAFE.getAndSet$Type$Release(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 #end[CAS]
 #if[AtomicAdd]