8060242: Compile-time expression evaluator was not seeing into ArrayBufferViews
authorattila
Wed, 15 Oct 2014 15:57:46 +0200
changeset 27104 bc8ce3f84b84
parent 27103 7a1a7ab2879c
child 27105 ef61cca021aa
8060242: Compile-time expression evaluator was not seeing into ArrayBufferViews Reviewed-by: hannesw, lagergren, sundar
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java	Wed Oct 15 15:57:46 2014 +0200
@@ -35,6 +35,7 @@
 import jdk.nashorn.internal.ir.IdentNode;
 import jdk.nashorn.internal.ir.IndexNode;
 import jdk.nashorn.internal.ir.Optimistic;
+import jdk.nashorn.internal.objects.ArrayBufferView;
 import jdk.nashorn.internal.objects.NativeArray;
 import jdk.nashorn.internal.runtime.FindProperty;
 import jdk.nashorn.internal.runtime.JSType;
@@ -204,16 +205,14 @@
         if (expr instanceof IndexNode) {
             final IndexNode indexNode = (IndexNode)expr;
             final Object    base = evaluateSafely(indexNode.getBase());
-            if(!(base instanceof NativeArray)) {
-                // We only know how to deal with NativeArray. TODO: maybe manage buffers too
-                return null;
+            if(base instanceof NativeArray || base instanceof ArrayBufferView) {
+                // NOTE: optimistic array getters throw UnwarrantedOptimismException based on the type of their underlying
+                // array storage, not based on values of individual elements. Thus, a LongArrayData will throw UOE for every
+                // optimistic int linkage attempt, even if the long value being returned in the first invocation would be
+                // representable as int. That way, we can presume that the array's optimistic type is the most optimistic
+                // type for which an element getter has a chance of executing successfully.
+                return ((ScriptObject)base).getArray().getOptimisticType();
             }
-            // NOTE: optimistic array getters throw UnwarrantedOptimismException based on the type of their underlying
-            // array storage, not based on values of individual elements. Thus, a LongArrayData will throw UOE for every
-            // optimistic int linkage attempt, even if the long value being returned in the first invocation would be
-            // representable as int. That way, we can presume that the array's optimistic type is the most optimistic
-            // type for which an element getter has a chance of executing successfully.
-            return ((NativeArray)base).getArray().getOptimisticType();
         }
 
         return null;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java	Wed Oct 15 15:57:46 2014 +0200
@@ -31,7 +31,6 @@
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
@@ -46,7 +45,7 @@
 import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
 
 @ScriptClass("ArrayBufferView")
-abstract class ArrayBufferView extends ScriptObject {
+public abstract class ArrayBufferView extends ScriptObject {
     private final NativeArrayBuffer buffer;
     private final int byteOffset;
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -141,6 +142,11 @@
         }
 
         @Override
+        public double getDoubleOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public Object getObject(final int index) {
             return getDouble(index);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -141,6 +142,11 @@
         }
 
         @Override
+        public double getDoubleOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public Object getObject(final int index) {
             return getDouble(index);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -124,16 +125,31 @@
         }
 
         @Override
+        public int getIntOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public long getLong(final int index) {
             return getInt(index);
         }
 
         @Override
+        public long getLongOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public double getDouble(final int index) {
             return getInt(index);
         }
 
         @Override
+        public double getDoubleOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public Object getObject(final int index) {
             return getInt(index);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -122,16 +123,31 @@
         }
 
         @Override
+        public int getIntOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public long getLong(final int index) {
             return getInt(index);
         }
 
         @Override
+        public long getLongOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public double getDouble(final int index) {
             return getInt(index);
         }
 
         @Override
+        public double getDoubleOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public Object getObject(final int index) {
             return getInt(index);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -122,16 +123,31 @@
         }
 
         @Override
+        public int getIntOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public long getLong(final int index) {
             return getInt(index);
         }
 
         @Override
+        public long getLongOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public double getDouble(final int index) {
             return getInt(index);
         }
 
         @Override
+        public double getDoubleOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public Object getObject(final int index) {
             return getInt(index);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -128,16 +129,31 @@
         }
 
         @Override
+        public int getIntOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public long getLong(final int index) {
             return getInt(index);
         }
 
         @Override
+        public long getLongOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public double getDouble(final int index) {
             return getInt(index);
         }
 
         @Override
+        public double getDoubleOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public Object getObject(final int index) {
             return getInt(index);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -128,7 +129,7 @@
 
         @Override
         public Class<?> getElementType() {
-            return int.class;
+            return long.class;
         }
 
         @Override
@@ -142,11 +143,21 @@
         }
 
         @Override
+        public long getLongOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public double getDouble(final int index) {
             return getLong(index);
         }
 
         @Override
+        public double getDoubleOptimistic(final int index, final int programPoint) {
+            return getLong(index);
+        }
+
+        @Override
         public Object getObject(final int index) {
             return getLong(index);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -128,16 +129,31 @@
         }
 
         @Override
+        public int getIntOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public long getLong(final int index) {
             return getInt(index);
         }
 
         @Override
+        public long getLongOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public double getDouble(final int index) {
             return getInt(index);
         }
 
         @Override
+        public double getDoubleOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public Object getObject(final int index) {
             return getInt(index);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Wed Oct 15 15:57:46 2014 +0200
@@ -28,6 +28,7 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -158,16 +159,31 @@
         }
 
         @Override
+        public int getIntOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public long getLong(final int index) {
             return getInt(index);
         }
 
         @Override
+        public long getLongOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public double getDouble(final int index) {
             return getInt(index);
         }
 
         @Override
+        public double getDoubleOptimistic(final int index, final int programPoint) {
+            return getElem(index);
+        }
+
+        @Override
         public Object getObject(final int index) {
             return getInt(index);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java	Wed Oct 15 15:57:46 2014 +0200
@@ -30,6 +30,7 @@
 import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
@@ -37,6 +38,7 @@
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
@@ -120,6 +122,11 @@
      */
     public abstract Class<?> getElementType();
 
+    @Override
+    public Type getOptimisticType() {
+        return Type.typeFor(getElementType());
+    }
+
     /**
      * Look up a continuous array element getter
      * @param get          getter, sometimes combined with a has check that throws CCE on failure for relink
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,10 +26,10 @@
 package jdk.nashorn.internal.runtime.arrays;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
-import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 
@@ -257,11 +257,6 @@
     }
 
     @Override
-    public Type getOptimisticType() {
-        return Type.INT;
-    }
-
-    @Override
     public int getInt(final int index) {
         return array[index];
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java	Wed Oct 15 15:57:46 2014 +0200
@@ -27,10 +27,10 @@
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
-import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 
@@ -186,11 +186,6 @@
         return convert(Double.class).set(index, value, strict);
     }
 
-    @Override
-    public Type getOptimisticType() {
-        return Type.LONG;
-    }
-
     private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), LongArrayData.class, "getElem", long.class, int.class).methodHandle();
     private static final MethodHandle SET_ELEM     = specialCall(MethodHandles.lookup(), LongArrayData.class, "setElem", void.class, int.class, long.class).methodHandle();
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Wed Oct 15 15:57:46 2014 +0200
@@ -28,10 +28,10 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
-import jdk.nashorn.internal.codegen.types.Type;
 
 /**
  * Implementation of {@link ArrayData} as soon as a double has been
@@ -166,11 +166,6 @@
         return this;
     }
 
-    @Override
-    public Type getOptimisticType() {
-        return Type.NUMBER;
-    }
-
     private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), NumberArrayData.class, "getElem", double.class, int.class).methodHandle();
     private static final MethodHandle SET_ELEM     = specialCall(MethodHandles.lookup(), NumberArrayData.class, "setElem", void.class, int.class, double.class).methodHandle();
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java	Tue Oct 14 16:11:07 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java	Wed Oct 15 15:57:46 2014 +0200
@@ -26,10 +26,10 @@
 package jdk.nashorn.internal.runtime.arrays;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
-import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 
@@ -160,11 +160,6 @@
         return this;
     }
 
-    @Override
-    public Type getOptimisticType() {
-        return Type.OBJECT;
-    }
-
     private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), ObjectArrayData.class, "getElem", Object.class, int.class).methodHandle();
     private static final MethodHandle SET_ELEM     = specialCall(MethodHandles.lookup(), ObjectArrayData.class, "setElem", void.class, int.class, Object.class).methodHandle();