changeset 2461:9958f5d65581 jdk8u152-b16-aarch32-171102

Merge
author snazarki
date Thu, 02 Nov 2017 16:18:25 +0300
parents 8f5e86a9d221 (current diff) d0841bfdb637 (diff)
children 698b15415d2a
files .hgtags
diffstat 33 files changed, 742 insertions(+), 147 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Nov 02 16:02:48 2017 +0300
+++ b/.hgtags	Thu Nov 02 16:18:25 2017 +0300
@@ -712,3 +712,30 @@
 f41afee891a32a88224317737b1eecbd735e7fd7 jdk8u151-b10
 a05eabdec5bb0133d6a8d0cf22f11c6e2a0d6b5d jdk8u151-b11
 1a6fa4dcb1ea4221950019ef75f83335bc8a05c3 jdk8u151-b12-aarch32-171102
+dee0a16b2c50b99b0a232821861edc153f4f4937 jdk8u151-b12
+18eb73eb84c5395b3efcafa43ce224565eca02b3 jdk8u122-b00
+9e615ea961fe5732813ed7b273606e7337ea2234 jdk8u122-b01
+2f0b11882cb7ddb10e35682ab9e8343919a71c54 jdk8u122-b02
+df2a2824284f97c5edb9b9c2e6d18bb4ff838199 jdk8u122-b03
+df2a2824284f97c5edb9b9c2e6d18bb4ff838199 jdk8u122-b03
+0000000000000000000000000000000000000000 jdk8u122-b03
+0000000000000000000000000000000000000000 jdk8u122-b03
+12650d23a8fd1b27a0d28c6a276fdecf01805294 jdk8u122-b03
+3c3b4e793e7c6255a840844db077ef466940035c jdk8u122-b04
+30dc0c72f3d0aff34b6d421208b18f384d05d761 jdk8u132-b00
+91d33aea2714e63796eeab0e63e38c9d2568c00c jdk8u152-b00
+50dac2fd8689dbb820d887ce3919708d5d042891 jdk8u152-b01
+01bbd310156db7a75a46a7320d1f49beff844472 jdk8u152-b02
+2a01d94fea9a86b4038a93622f62b0986083f67e jdk8u152-b03
+9dce75561a92f096d822ebb7eb76810f191fe522 jdk8u152-b04
+cdb7d9454d254e95c73d6dc77077ab2c198e2ad6 jdk8u152-b05
+2be667f12b54fc5b57b147f60851ee63ff02e5fa jdk8u152-b06
+a44dcdfa00bee9261012f10bd3f06bea1fec4340 jdk8u152-b07
+d0a8151a276c362a6e17068d9aa8ed583309d46e jdk8u152-b08
+37e94d764d7b98e3676e54f2ad346d721fdde113 jdk8u152-b09
+b4f39fda3c39d41a33c9996555ddfd3200895756 jdk8u152-b10
+52485a7a9fc54a620a8a0568626087faf2bd63f9 jdk8u152-b11
+7d9cb98c7f071a7c0f6d430c6ec8116c8db34655 jdk8u152-b12
+293cf1e0a22791a96fe8e07f85af40f4dca64d1f jdk8u152-b13
+6025f8527d42706d171201f0a912c760d4d0c037 jdk8u152-b14
+a61136aa725ab8bb4721e8bb48aa827b49530978 jdk8u152-b15
--- a/ASSEMBLY_EXCEPTION	Thu Nov 02 16:02:48 2017 +0300
+++ b/ASSEMBLY_EXCEPTION	Thu Nov 02 16:18:25 2017 +0300
@@ -1,27 +1,27 @@
 
 OPENJDK ASSEMBLY EXCEPTION
 
-The OpenJDK source code made available by Sun at openjdk.java.net and
-openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the
-GNU General Public License <http://www.gnu.org/copyleft/gpl.html> version 2
+The OpenJDK source code made available by Oracle America, Inc. (Oracle) at
+openjdk.java.net ("OpenJDK Code") is distributed under the terms of the GNU
+General Public License <http://www.gnu.org/copyleft/gpl.html> version 2
 only ("GPL2"), with the following clarification and special exception.
 
     Linking this OpenJDK Code statically or dynamically with other code
     is making a combined work based on this library.  Thus, the terms
     and conditions of GPL2 cover the whole combination.
 
-    As a special exception, Sun gives you permission to link this
-    OpenJDK Code with certain code licensed by Sun as indicated at
+    As a special exception, Oracle gives you permission to link this
+    OpenJDK Code with certain code licensed by Oracle as indicated at
     http://openjdk.java.net/legal/exception-modules-2007-05-08.html
     ("Designated Exception Modules") to produce an executable,
     regardless of the license terms of the Designated Exception Modules,
     and to copy and distribute the resulting executable under GPL2,
     provided that the Designated Exception Modules continue to be
-    governed by the licenses under which they were offered by Sun.
+    governed by the licenses under which they were offered by Oracle.
 
-As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to
-build an executable that includes those portions of necessary code that Sun
-could not provide under GPL2 (or that Sun has provided under GPL2 with the
-Classpath exception).  If you modify or add to the OpenJDK code, that new
-GPL2 code may still be combined with Designated Exception Modules if the
-new code is made subject to this exception by its copyright holder.
+As such, it allows licensees and sublicensees of Oracle's GPL2 OpenJDK Code
+to build an executable that includes those portions of necessary code that
+Oracle could not provide under GPL2 (or that Oracle has provided under GPL2
+with the Classpath exception).  If you modify or add to the OpenJDK code,
+that new GPL2 code may still be combined with Designated Exception Modules
+if the new code is made subject to this exception by its copyright holder.
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Nov 02 16:18:25 2017 +0300
@@ -2454,11 +2454,6 @@
                     }
 
                     @Override
-                    public boolean enterObjectNode(final ObjectNode objectNode) {
-                        return false;
-                    }
-
-                    @Override
                     public boolean enterDefault(final Node node) {
                         if (contains) {
                             return false;
@@ -2526,7 +2521,8 @@
             oc = new FieldObjectCreator<Expression>(this, tuples) {
                 @Override
                 protected void loadValue(final Expression node, final Type type) {
-                    loadExpressionAsType(node, type);
+                    // Use generic type in order to avoid conversion between object types
+                    loadExpressionAsType(node, Type.generic(type));
                 }};
         }
 
@@ -2542,10 +2538,7 @@
         //handler
         if (restOfProperty) {
             final ContinuationInfo ci = getContinuationInfo();
-            // Can be set at most once for a single rest-of method
-            assert ci.getObjectLiteralMap() == null;
-            ci.setObjectLiteralMap(oc.getMap());
-            ci.setObjectLiteralStackDepth(method.getStackSize());
+            ci.setObjectLiteralMap(method.getStackSize(), oc.getMap());
         }
 
         method.dup();
@@ -4023,7 +4016,7 @@
                     void loadStack() {
                         assert assignNode.getWidestOperandType() == Type.INT;
                         if (isRhsZero(binaryNode)) {
-                            loadExpressionAsType(binaryNode.lhs(), Type.INT);
+                            loadExpression(binaryNode.lhs(), TypeBounds.INT, true);
                         } else {
                             loadBinaryOperands(binaryNode.lhs(), binaryNode.rhs(), TypeBounds.INT, true, false);
                             method.shr();
@@ -5259,10 +5252,8 @@
         private Type[] stackTypes;
         // If non-null, this node should perform the requisite type conversion
         private Type returnValueType;
-        // If we are in the middle of an object literal initialization, we need to update the map
-        private PropertyMap objectLiteralMap;
-        // Object literal stack depth for object literal - not necessarily top if property is a tree
-        private int objectLiteralStackDepth = -1;
+        // If we are in the middle of an object literal initialization, we need to update the property maps
+        private Map<Integer, PropertyMap> objectLiteralMaps;
         // The line number at the continuation point
         private int lineNumber;
         // The active catch label, in case the continuation point is in a try/catch block
@@ -5314,20 +5305,15 @@
             this.returnValueType = returnValueType;
         }
 
-        int getObjectLiteralStackDepth() {
-            return objectLiteralStackDepth;
-        }
-
-        void setObjectLiteralStackDepth(final int objectLiteralStackDepth) {
-            this.objectLiteralStackDepth = objectLiteralStackDepth;
-        }
-
-        PropertyMap getObjectLiteralMap() {
-            return objectLiteralMap;
-        }
-
-        void setObjectLiteralMap(final PropertyMap objectLiteralMap) {
-            this.objectLiteralMap = objectLiteralMap;
+        void setObjectLiteralMap(final int objectLiteralStackDepth, final PropertyMap objectLiteralMap) {
+            if (objectLiteralMaps == null) {
+                objectLiteralMaps = new HashMap<>();
+            }
+            objectLiteralMaps.put(objectLiteralStackDepth, objectLiteralMap);
+        }
+
+        PropertyMap getObjectLiteralMap(final int stackDepth) {
+            return objectLiteralMaps == null ? null : objectLiteralMaps.get(stackDepth);
         }
 
         @Override
@@ -5417,10 +5403,9 @@
         final int[]   stackStoreSpec = ci.getStackStoreSpec();
         final Type[]  stackTypes     = ci.getStackTypes();
         final boolean isStackEmpty   = stackStoreSpec.length == 0;
-        boolean replacedObjectLiteralMap = false;
+        int replacedObjectLiteralMaps = 0;
         if(!isStackEmpty) {
             // Load arguments on the stack
-            final int objectLiteralStackDepth = ci.getObjectLiteralStackDepth();
             for(int i = 0; i < stackStoreSpec.length; ++i) {
                 final int slot = stackStoreSpec[i];
                 method.load(lvarTypes.get(slot), slot);
@@ -5428,18 +5413,18 @@
                 // stack: s0=object literal being initialized
                 // change map of s0 so that the property we are initializing when we failed
                 // is now ci.returnValueType
-                if (i == objectLiteralStackDepth) {
+                final PropertyMap map = ci.getObjectLiteralMap(i);
+                if (map != null) {
                     method.dup();
-                    assert ci.getObjectLiteralMap() != null;
                     assert ScriptObject.class.isAssignableFrom(method.peekType().getTypeClass()) : method.peekType().getTypeClass() + " is not a script object";
-                    loadConstant(ci.getObjectLiteralMap());
+                    loadConstant(map);
                     method.invoke(ScriptObject.SET_MAP);
-                    replacedObjectLiteralMap = true;
+                    replacedObjectLiteralMaps++;
                 }
             }
         }
-        // Must have emitted the code for replacing the map of an object literal if we have a set object literal stack depth
-        assert ci.getObjectLiteralStackDepth() == -1 || replacedObjectLiteralMap;
+        // Must have emitted the code for replacing all object literal maps
+        assert ci.objectLiteralMaps == null || ci.objectLiteralMaps.size() == replacedObjectLiteralMaps;
         // Load RewriteException back.
         method.load(rewriteExceptionType, lvarCount);
         // Get rid of the stored reference
--- a/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Thu Nov 02 16:18:25 2017 +0300
@@ -33,6 +33,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Deque;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.Iterator;
@@ -122,9 +123,9 @@
         private final List<JumpOrigin> origins = new LinkedList<>();
         private Map<Symbol, LvarType> types = Collections.emptyMap();
 
-        void addOrigin(final JoinPredecessor originNode, final Map<Symbol, LvarType> originTypes) {
+        void addOrigin(final JoinPredecessor originNode, final Map<Symbol, LvarType> originTypes, final LocalVariableTypesCalculator calc) {
             origins.add(new JumpOrigin(originNode, originTypes));
-            this.types = getUnionTypes(this.types, originTypes);
+            this.types = calc.getUnionTypes(this.types, originTypes);
         }
     }
     private enum LvarType {
@@ -185,12 +186,15 @@
     }
 
     @SuppressWarnings("unchecked")
-    private static IdentityHashMap<Symbol, LvarType> cloneMap(final Map<Symbol, LvarType> map) {
-        return (IdentityHashMap<Symbol, LvarType>)((IdentityHashMap<?,?>)map).clone();
+    private static HashMap<Symbol, LvarType> cloneMap(final Map<Symbol, LvarType> map) {
+        return (HashMap<Symbol, LvarType>)((HashMap<?,?>)map).clone();
     }
 
     private LocalVariableConversion createConversion(final Symbol symbol, final LvarType branchLvarType,
             final Map<Symbol, LvarType> joinLvarTypes, final LocalVariableConversion next) {
+        if (invalidatedSymbols.contains(symbol)) {
+            return next;
+        }
         final LvarType targetType = joinLvarTypes.get(symbol);
         assert targetType != null;
         if(targetType == branchLvarType) {
@@ -208,7 +212,7 @@
         return new LocalVariableConversion(symbol, branchLvarType.type, targetType.type, next);
     }
 
-    private static Map<Symbol, LvarType> getUnionTypes(final Map<Symbol, LvarType> types1, final Map<Symbol, LvarType> types2) {
+    private Map<Symbol, LvarType> getUnionTypes(final Map<Symbol, LvarType> types1, final Map<Symbol, LvarType> types2) {
         if(types1 == types2 || types1.isEmpty()) {
             return types2;
         } else if(types2.isEmpty()) {
@@ -261,6 +265,11 @@
             final LvarType type2 = types2.get(symbol);
             union.put(symbol, widestLvarType(type1,  type2));
         }
+        // If the two sets of symbols differ, there's a good chance that some of
+        // symbols only appearing in one of the sets are lexically invalidated,
+        // so we remove them from further consideration.
+        // This is not strictly necessary, just a working set size optimization.
+        union.keySet().removeAll(invalidatedSymbols);
         return union;
     }
 
@@ -359,8 +368,6 @@
         if(t1.ordinal() < LvarType.INT.ordinal() || t2.ordinal() < LvarType.INT.ordinal()) {
             return LvarType.OBJECT;
         }
-        // NOTE: we allow "widening" of long to double even though it can lose precision. ECMAScript doesn't have an
-        // Int64 type anyway, so this loss of precision is actually more conformant to the specification...
         return LvarType.values()[Math.max(t1.ordinal(), t2.ordinal())];
     }
     private final Compiler compiler;
@@ -368,7 +375,10 @@
     // Local variable type mapping at the currently evaluated point. No map instance is ever modified; setLvarType() always
     // allocates a new map. Immutability of maps allows for cheap snapshots by just keeping the reference to the current
     // value.
-    private Map<Symbol, LvarType> localVariableTypes = new IdentityHashMap<>();
+    private Map<Symbol, LvarType> localVariableTypes = Collections.emptyMap();
+    // Set of symbols whose lexical scope has already ended.
+    private final Set<Symbol> invalidatedSymbols = new HashSet<>();
+
     // Stack for evaluated expression types.
     private final Deque<LvarType> typeStack = new ArrayDeque<>();
 
@@ -464,9 +474,19 @@
 
     @Override
     public boolean enterBlock(final Block block) {
+        boolean cloned = false;
         for(final Symbol symbol: block.getSymbols()) {
-            if(symbol.isBytecodeLocal() && getLocalVariableTypeOrNull(symbol) == null) {
-                setType(symbol, LvarType.UNDEFINED);
+            if(symbol.isBytecodeLocal()) {
+                if (getLocalVariableTypeOrNull(symbol) == null) {
+                    if (!cloned) {
+                        cloneOrNewLocalVariableTypes();
+                        cloned = true;
+                    }
+                    localVariableTypes.put(symbol, LvarType.UNDEFINED);
+                }
+                // In case we're repeating analysis of a lexical scope (e.g. it's in a loop),
+                // make sure all symbols lexically scoped by the block become valid again.
+                invalidatedSymbols.remove(symbol);
             }
         }
         return true;
@@ -1046,15 +1066,11 @@
             // throw an exception.
             reachable = true;
             catchBody.accept(this);
-            final Symbol exceptionSymbol = exception.getSymbol();
             if(reachable) {
-                localVariableTypes = cloneMap(localVariableTypes);
-                localVariableTypes.remove(exceptionSymbol);
                 jumpToLabel(catchBody, endLabel);
                 canExit = true;
             }
-            localVariableTypes = cloneMap(afterConditionTypes);
-            localVariableTypes.remove(exceptionSymbol);
+            localVariableTypes = afterConditionTypes;
         }
         // NOTE: if we had one or more conditional catch blocks with no unconditional catch block following them, then
         // there will be an unconditional rethrow, so the join point can never be reached from the last
@@ -1204,7 +1220,7 @@
     }
 
     private void jumpToLabel(final JoinPredecessor jumpOrigin, final Label label, final Map<Symbol, LvarType> types) {
-        getOrCreateJumpTarget(label).addOrigin(jumpOrigin, types);
+        getOrCreateJumpTarget(label).addOrigin(jumpOrigin, types, this);
     }
 
     @Override
@@ -1226,16 +1242,18 @@
 
         boolean cloned = false;
         for(final Symbol symbol: block.getSymbols()) {
-            // Undefine the symbol outside the block
-            if(localVariableTypes.containsKey(symbol)) {
-                if(!cloned) {
-                    localVariableTypes = cloneMap(localVariableTypes);
-                    cloned = true;
+            if(symbol.hasSlot()) {
+                // Invalidate the symbol when its defining block ends
+                if (symbol.isBytecodeLocal()) {
+                    if(localVariableTypes.containsKey(symbol)) {
+                        if(!cloned) {
+                            localVariableTypes = cloneMap(localVariableTypes);
+                            cloned = true;
+                        }
+                    }
+                    invalidateSymbol(symbol);
                 }
-                localVariableTypes.remove(symbol);
-            }
 
-            if(symbol.hasSlot()) {
                 final SymbolConversions conversions = symbolConversions.get(symbol);
                 if(conversions != null) {
                     // Potentially make some currently dead types live if they're needed as a source of a type
@@ -1605,10 +1623,19 @@
         }
         assert symbol.hasSlot();
         assert !symbol.isGlobal();
-        localVariableTypes = localVariableTypes.isEmpty() ? new IdentityHashMap<Symbol, LvarType>() : cloneMap(localVariableTypes);
+        cloneOrNewLocalVariableTypes();
         localVariableTypes.put(symbol, type);
     }
 
+    private void cloneOrNewLocalVariableTypes() {
+        localVariableTypes = localVariableTypes.isEmpty() ? new HashMap<Symbol, LvarType>() : cloneMap(localVariableTypes);
+    }
+
+    private void invalidateSymbol(final Symbol symbol) {
+        localVariableTypes.remove(symbol);
+        invalidatedSymbols.add(symbol);
+    }
+
     /**
      * Set a flag in the symbol marking it as needing to be able to store a value of a particular type. Every symbol for
      * a local variable will be assigned between 1 and 6 local variable slots for storing all types it is known to need
--- a/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Thu Nov 02 16:18:25 2017 +0300
@@ -188,7 +188,8 @@
 
     @Override
     protected void loadValue(final Expression expr, final Type type) {
-        codegen.loadExpressionAsType(expr, type);
+        // Use generic type in order to avoid conversion between object types
+        codegen.loadExpressionAsType(expr, Type.generic(type));
     }
 
     @Override
--- a/src/jdk/nashorn/internal/codegen/WeighNodes.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/codegen/WeighNodes.java	Thu Nov 02 16:18:25 2017 +0300
@@ -77,6 +77,7 @@
     static final long CALL_WEIGHT      = 10;
     static final long CATCH_WEIGHT     = 10;
     static final long COMPARE_WEIGHT   =  6;
+    static final long CONST_WEIGHT     =  2;
     static final long CONTINUE_WEIGHT  =  1;
     static final long IF_WEIGHT        =  2;
     static final long LITERAL_WEIGHT   = 10;
@@ -185,7 +186,7 @@
 
     @Override
     public Node leaveIdentNode(final IdentNode identNode) {
-        weight += ACCESS_WEIGHT + identNode.getName().length() * 2;
+        weight += ACCESS_WEIGHT;
         return identNode;
     }
 
@@ -210,6 +211,11 @@
     @SuppressWarnings("rawtypes")
     @Override
     public boolean enterLiteralNode(final LiteralNode literalNode) {
+        if (literalNode instanceof LiteralNode.PrimitiveLiteralNode) {
+            weight += CONST_WEIGHT;
+            return false;
+        }
+
         weight += LITERAL_WEIGHT;
 
         if (literalNode instanceof ArrayLiteralNode) {
--- a/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java	Thu Nov 02 16:18:25 2017 +0300
@@ -397,7 +397,7 @@
 
     @Override
     public boolean enterVarNode(final VarNode varNode) {
-        sb.append("var ");
+        sb.append(varNode.isConst() ? "const " : varNode.isLet() ? "let " : "var ");
         varNode.getName().toString(sb, printTypes);
         printLocalVariableConversion(varNode.getName());
         final Node init = varNode.getInit();
--- a/src/jdk/nashorn/internal/objects/NativeDataView.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/objects/NativeDataView.java	Thu Nov 02 16:18:25 2017 +0300
@@ -416,7 +416,7 @@
      * @return 32-bit unsigned int value at the byteOffset
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static long getUint32(final Object self, final Object byteOffset, final Object littleEndian) {
+    public static double getUint32(final Object self, final Object byteOffset, final Object littleEndian) {
         try {
             return 0xFFFFFFFFL & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset));
         } catch (final IllegalArgumentException iae) {
@@ -432,7 +432,7 @@
      * @return 32-bit unsigned int value at the byteOffset
      */
     @SpecializedFunction
-    public static long getUint32(final Object self, final int byteOffset) {
+    public static double getUint32(final Object self, final int byteOffset) {
         try {
             return JSType.toUint32(getBuffer(self, false).getInt(JSType.toInt32(byteOffset)));
         } catch (final IllegalArgumentException iae) {
@@ -449,7 +449,7 @@
      * @return 32-bit unsigned int value at the byteOffset
      */
     @SpecializedFunction
-    public static long getUint32(final Object self, final int byteOffset, final boolean littleEndian) {
+    public static double getUint32(final Object self, final int byteOffset, final boolean littleEndian) {
         try {
             return JSType.toUint32(getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset)));
         } catch (final IllegalArgumentException iae) {
@@ -837,9 +837,9 @@
      * @return undefined
      */
     @SpecializedFunction
-    public static Object setUint32(final Object self, final int byteOffset, final long value) {
+    public static Object setUint32(final Object self, final int byteOffset, final double value) {
         try {
-            getBuffer(self, false).putInt(byteOffset, (int)value);
+            getBuffer(self, false).putInt(byteOffset, (int) JSType.toUint32(value));
             return UNDEFINED;
         } catch (final IllegalArgumentException iae) {
             throw rangeError(iae, "dataview.offset");
@@ -856,9 +856,9 @@
      * @return undefined
      */
     @SpecializedFunction
-    public static Object setUint32(final Object self, final int byteOffset, final long value, final boolean littleEndian) {
+    public static Object setUint32(final Object self, final int byteOffset, final double value, final boolean littleEndian) {
         try {
-            getBuffer(self, littleEndian).putInt(byteOffset, (int)value);
+            getBuffer(self, littleEndian).putInt(byteOffset, (int) JSType.toUint32(value));
             return UNDEFINED;
         } catch (final IllegalArgumentException iae) {
             throw rangeError(iae, "dataview.offset");
--- a/src/jdk/nashorn/internal/runtime/JSType.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/JSType.java	Thu Nov 02 16:18:25 2017 +0300
@@ -457,6 +457,8 @@
             return toPrimitive((ScriptObject)obj, hint);
         } else if (isPrimitive(obj)) {
             return obj;
+        } else if (hint == Number.class && obj instanceof Number) {
+            return ((Number) obj).doubleValue();
         } else if (obj instanceof JSObject) {
             return toPrimitive((JSObject)obj, hint);
         } else if (obj instanceof StaticClass) {
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Thu Nov 02 16:18:25 2017 +0300
@@ -107,14 +107,13 @@
 
         @Override
         public ArrayData ensure(final long safeIndex) {
-            if (safeIndex > 0L) {
-                if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
-                    return new SparseArrayData(this, safeIndex + 1);
-                }
-                //known to fit in int
-                return toRealArrayData((int)safeIndex);
-           }
-           return this;
+            assert safeIndex >= 0L;
+            if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
+                return new SparseArrayData(this, safeIndex + 1);
+            }
+            //known to fit in int
+            return toRealArrayData((int)safeIndex);
+
         }
 
         @Override
@@ -133,8 +132,8 @@
         }
 
         @Override
-        public void shiftLeft(final int by) {
-            //nop, always empty or we wouldn't be of this class
+        public ArrayData shiftLeft(final int by) {
+            return this; //nop, always empty or we wouldn't be of this class
         }
 
         @Override
@@ -451,13 +450,13 @@
     /**
      * Shift the array data left
      *
-     * TODO: explore start at an index and not at zero, to make these operations
-     * even faster. Offset everything from the index. Costs memory but is probably
-     * worth it
+     * TODO: This is used for Array.prototype.shift() which only shifts by 1,
+     * so we might consider dropping the offset parameter.
      *
      * @param by offset to shift
+     * @return New arraydata (or same)
      */
-    public abstract void shiftLeft(final int by);
+    public abstract ArrayData shiftLeft(final int by);
 
     /**
      * Shift the array right
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java	Thu Nov 02 16:18:25 2017 +0300
@@ -68,9 +68,10 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
+    public ArrayData shiftLeft(final int by) {
         underlying.shiftLeft(by);
         setLength(underlying.length());
+        return this;
     }
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/arrays/ByteBufferArrayData.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/ByteBufferArrayData.java	Thu Nov 02 16:18:25 2017 +0300
@@ -82,7 +82,7 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
+    public ArrayData shiftLeft(final int by) {
         throw unsupported("shiftLeft");
     }
 
--- a/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java	Thu Nov 02 16:18:25 2017 +0300
@@ -76,9 +76,10 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
+    public ArrayData shiftLeft(final int by) {
         super.shiftLeft(by);
         deleted.shiftLeft(by, length());
+        return this;
     }
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java	Thu Nov 02 16:18:25 2017 +0300
@@ -101,10 +101,12 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
+    public ArrayData shiftLeft(final int by) {
         super.shiftLeft(by);
         lo = Math.max(0, lo - by);
         hi = Math.max(-1, hi - by);
+
+        return isEmpty() ? getUnderlying() : this;
     }
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Thu Nov 02 16:18:25 2017 +0300
@@ -176,8 +176,15 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
-        System.arraycopy(array, by, array, 0, array.length - by);
+    public ArrayData shiftLeft(final int by) {
+        if (by >= length()) {
+            shrink(0);
+        } else {
+            System.arraycopy(array, by, array, 0, array.length - by);
+        }
+        setLength(Math.max(0, length() - by));
+
+        return this;
     }
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Thu Nov 02 16:18:25 2017 +0300
@@ -121,8 +121,14 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
-        System.arraycopy(array, by, array, 0, array.length - by);
+    public ArrayData shiftLeft(final int by) {
+        if (by >= length()) {
+            shrink(0);
+        } else {
+            System.arraycopy(array, by, array, 0, array.length - by);
+        }
+        setLength(Math.max(0, length() - by));
+        return this;
     }
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java	Thu Nov 02 16:18:25 2017 +0300
@@ -98,8 +98,14 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
-        System.arraycopy(array, by, array, 0, array.length - by);
+    public ArrayData shiftLeft(final int by) {
+        if (by >= length()) {
+            shrink(0);
+        } else {
+            System.arraycopy(array, by, array, 0, array.length - by);
+        }
+        setLength(Math.max(0, length() - by));
+        return this;
     }
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java	Thu Nov 02 16:18:25 2017 +0300
@@ -36,7 +36,8 @@
  * Handle arrays where the index is very large.
  */
 class SparseArrayData extends ArrayData {
-    static final int MAX_DENSE_LENGTH = 1024 * 1024;
+    /** Maximum size for dense arrays */
+    static final int MAX_DENSE_LENGTH = 128 * 1024;
 
     /** Underlying array. */
     private ArrayData underlying;
@@ -51,11 +52,11 @@
         this(underlying, length, new TreeMap<Long, Object>());
     }
 
-    SparseArrayData(final ArrayData underlying, final long length, final TreeMap<Long, Object> sparseMap) {
+    private SparseArrayData(final ArrayData underlying, final long length, final TreeMap<Long, Object> sparseMap) {
         super(length);
         assert underlying.length() <= length;
         this.underlying = underlying;
-        this.maxDenseLength = Math.max(MAX_DENSE_LENGTH, underlying.length());
+        this.maxDenseLength = underlying.length();
         this.sparseMap = sparseMap;
     }
 
@@ -89,38 +90,49 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
-        underlying.shiftLeft(by);
+    public ArrayData shiftLeft(final int by) {
+        underlying = underlying.shiftLeft(by);
 
         final TreeMap<Long, Object> newSparseMap = new TreeMap<>();
 
         for (final Map.Entry<Long, Object> entry : sparseMap.entrySet()) {
             final long newIndex = entry.getKey().longValue() - by;
-            if (newIndex < maxDenseLength) {
-                underlying = underlying.set((int) newIndex, entry.getValue(), false);
-            } else if (newIndex >= 0) {
-                newSparseMap.put(Long.valueOf(newIndex), entry.getValue());
+            if (newIndex >= 0) {
+                if (newIndex < maxDenseLength) {
+                    final long oldLength = underlying.length();
+                    underlying = underlying.ensure(newIndex)
+                            .set((int) newIndex, entry.getValue(), false)
+                            .safeDelete(oldLength, newIndex - 1, false);
+                } else {
+                    newSparseMap.put(Long.valueOf(newIndex), entry.getValue());
+                }
             }
         }
 
         sparseMap = newSparseMap;
         setLength(Math.max(length() - by, 0));
+
+        return sparseMap.isEmpty() ? underlying : this;
     }
 
     @Override
     public ArrayData shiftRight(final int by) {
         final TreeMap<Long, Object> newSparseMap = new TreeMap<>();
+        // Move elements from underlying to sparse map if necessary
         final long len = underlying.length();
         if (len + by > maxDenseLength) {
-            for (long i = maxDenseLength - by; i < len; i++) {
+            // Length of underlying array after shrinking, before right-shifting
+            final long tempLength = Math.max(0, maxDenseLength - by);
+            for (long i = tempLength; i < len; i++) {
                 if (underlying.has((int) i)) {
                     newSparseMap.put(Long.valueOf(i + by), underlying.getObject((int) i));
                 }
             }
-            underlying = underlying.shrink((int) (maxDenseLength - by));
+            underlying = underlying.shrink((int) tempLength);
+            underlying.setLength(tempLength);
         }
 
-        underlying.shiftRight(by);
+        underlying = underlying.shiftRight(by);
 
         for (final Map.Entry<Long, Object> entry : sparseMap.entrySet()) {
             final long newIndex = entry.getKey().longValue() + by;
@@ -135,14 +147,6 @@
 
     @Override
     public ArrayData ensure(final long safeIndex) {
-        // Usually #ensure only needs to be called if safeIndex is greater or equal current length.
-        // SparseArrayData is an exception as an index smaller than our current length may still
-        // exceed the underlying ArrayData's capacity. Because of this, SparseArrayData invokes
-        // its ensure method internally in various places where other ArrayData subclasses don't,
-        // making it safe for outside uses to only call ensure(safeIndex) if safeIndex >= length.
-        if (safeIndex < maxDenseLength && underlying.length() <= safeIndex) {
-            underlying = underlying.ensure(safeIndex);
-        }
         if (safeIndex >= length()) {
             setLength(safeIndex + 1);
         }
@@ -167,8 +171,7 @@
     public ArrayData set(final int index, final Object value, final boolean strict) {
         if (index >= 0 && index < maxDenseLength) {
             final long oldLength = underlying.length();
-            ensure(index);
-            underlying = underlying.set(index, value, strict).safeDelete(oldLength, index - 1, strict);
+            underlying = underlying.ensure(index).set(index, value, strict).safeDelete(oldLength, index - 1, strict);
             setLength(Math.max(underlying.length(), length()));
         } else {
             final Long longIndex = indexToKey(index);
@@ -183,8 +186,7 @@
     public ArrayData set(final int index, final int value, final boolean strict) {
         if (index >= 0 && index < maxDenseLength) {
             final long oldLength = underlying.length();
-            ensure(index);
-            underlying = underlying.set(index, value, strict).safeDelete(oldLength, index - 1, strict);
+            underlying = underlying.ensure(index).set(index, value, strict).safeDelete(oldLength, index - 1, strict);
             setLength(Math.max(underlying.length(), length()));
         } else {
             final Long longIndex = indexToKey(index);
@@ -198,8 +200,7 @@
     public ArrayData set(final int index, final double value, final boolean strict) {
         if (index >= 0 && index < maxDenseLength) {
             final long oldLength = underlying.length();
-            ensure(index);
-            underlying = underlying.set(index, value, strict).safeDelete(oldLength, index - 1, strict);
+            underlying = underlying.ensure(index).set(index, value, strict).safeDelete(oldLength, index - 1, strict);
             setLength(Math.max(underlying.length(), length()));
         } else {
             final Long longIndex = indexToKey(index);
--- a/src/jdk/nashorn/internal/runtime/arrays/TypedArrayData.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/TypedArrayData.java	Thu Nov 02 16:18:25 2017 +0300
@@ -98,7 +98,7 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
+    public ArrayData shiftLeft(final int by) {
         throw new UnsupportedOperationException();
     }
 
--- a/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java	Thu Nov 02 16:18:25 2017 +0300
@@ -77,9 +77,10 @@
     }
 
     @Override
-    public void shiftLeft(final int by) {
+    public ArrayData shiftLeft(final int by) {
         super.shiftLeft(by);
         undefined.shiftLeft(by, length());
+        return this;
     }
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Thu Nov 02 16:18:25 2017 +0300
@@ -39,9 +39,13 @@
 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
 import jdk.nashorn.api.scripting.JSObject;
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
 import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
+import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.objects.Global;
 
 /**
  * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well
@@ -141,9 +145,9 @@
     }
 
     private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc) {
-        MethodHandle mh = JSOBJECT_CALL;
+        MethodHandle mh = NashornCallSiteDescriptor.isScope(desc)? JSOBJECT_SCOPE_CALL : JSOBJECT_CALL;
         if (NashornCallSiteDescriptor.isApplyToCall(desc)) {
-            mh = MH.insertArguments(JSOBJECT_CALL_TO_APPLY, 0, JSOBJECT_CALL);
+            mh = MH.insertArguments(JSOBJECT_CALL_TO_APPLY, 0, mh);
         }
         final MethodType type = desc.getMethodType();
         mh = type.parameterType(type.parameterCount() - 1) == Object[].class ?
@@ -171,6 +175,8 @@
             final int index = getIndex((Number)key);
             if (index > -1) {
                 return ((JSObject)jsobj).getSlot(index);
+            } else {
+                return ((JSObject)jsobj).getMember(JSType.toString(key));
             }
         } else if (isString(key)) {
             final String name = key.toString();
@@ -188,7 +194,12 @@
         if (key instanceof Integer) {
             ((JSObject)jsobj).setSlot((Integer)key, value);
         } else if (key instanceof Number) {
-            ((JSObject)jsobj).setSlot(getIndex((Number)key), value);
+            final int index = getIndex((Number)key);
+            if (index > -1) {
+                ((JSObject)jsobj).setSlot(index, value);
+            } else {
+                ((JSObject)jsobj).setMember(JSType.toString(key), value);
+            }
         } else if (isString(key)) {
             ((JSObject)jsobj).setMember(key.toString(), value);
         }
@@ -214,6 +225,19 @@
         }
     }
 
+    // This is used when a JSObject is called as scope call to do undefined -> Global this translation.
+    @SuppressWarnings("unused")
+    private static Object jsObjectScopeCall(final JSObject jsObj, final Object thiz, final Object[] args) {
+        final Object modifiedThiz;
+        if (thiz == ScriptRuntime.UNDEFINED && !jsObj.isStrictFunction()) {
+            final Global global = Context.getGlobal();
+            modifiedThiz = ScriptObjectMirror.wrap(global, global);
+        } else {
+            modifiedThiz = thiz;
+        }
+        return jsObj.call(modifiedThiz, args);
+    }
+
     private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
 
     // method handles of the current class
@@ -225,6 +249,7 @@
     private static final MethodHandle JSOBJECT_GETMEMBER     = findJSObjectMH_V("getMember", Object.class, String.class);
     private static final MethodHandle JSOBJECT_SETMEMBER     = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class);
     private static final MethodHandle JSOBJECT_CALL          = findJSObjectMH_V("call", Object.class, Object.class, Object[].class);
+    private static final MethodHandle JSOBJECT_SCOPE_CALL    = findOwnMH_S("jsObjectScopeCall", Object.class, JSObject.class, Object.class, Object[].class);
     private static final MethodHandle JSOBJECT_CALL_TO_APPLY = findOwnMH_S("callToApply", Object.class, MethodHandle.class, JSObject.class, Object.class, Object[].class);
     private static final MethodHandle JSOBJECT_NEW           = findJSObjectMH_V("newObject", Object.class, Object[].class);
 
--- a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Thu Nov 02 16:18:25 2017 +0300
@@ -251,15 +251,15 @@
     @Override
     public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
         if(sourceType == NativeArray.class) {
-            // Prefer lists, as they're less costly to create than arrays.
-            if(isList(targetType1)) {
-                if(!isList(targetType2)) {
+            // Prefer those types we can convert to with just a wrapper (cheaper than Java array creation).
+            if(isArrayPreferredTarget(targetType1)) {
+                if(!isArrayPreferredTarget(targetType2)) {
                     return Comparison.TYPE_1_BETTER;
                 }
-            } else if(isList(targetType2)) {
+            } else if(isArrayPreferredTarget(targetType2)) {
                 return Comparison.TYPE_2_BETTER;
             }
-            // Then prefer arrays
+            // Then prefer Java arrays
             if(targetType1.isArray()) {
                 if(!targetType2.isArray()) {
                     return Comparison.TYPE_1_BETTER;
@@ -281,8 +281,8 @@
         return Comparison.INDETERMINATE;
     }
 
-    private static boolean isList(final Class<?> clazz) {
-        return clazz == List.class || clazz == Deque.class;
+    private static boolean isArrayPreferredTarget(final Class<?> clazz) {
+        return clazz == List.class || clazz == Collection.class || clazz == Queue.class || clazz == Deque.class;
     }
 
     private static final MethodHandle IS_SCRIPT_OBJECT = Guards.isInstance(ScriptObject.class, MH.type(Boolean.TYPE, Object.class));
--- a/test/script/basic/JDK-8030182_2.js	Thu Nov 02 16:02:48 2017 +0300
+++ b/test/script/basic/JDK-8030182_2.js	Thu Nov 02 16:18:25 2017 +0300
@@ -31,7 +31,7 @@
 var str = "";
 
 // large code to force splitting
-for (i = 0; i < 1000; ++i)
+for (i = 0; i < 2000; ++i)
     str +="o = new Object()\n";
 
 str +="g()";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8163945.js	Thu Nov 02 16:18:25 2017 +0300
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8163945: Honor Number type hint in toPrimitive on Numbers
+ *
+ * @test
+ * @run
+ */
+
+function assertLessThan(a, b) {
+    Assert.assertTrue(a < b);
+    Assert.assertTrue(a <= b);
+    Assert.assertFalse(a >= b);
+    Assert.assertFalse(a > b);
+}
+
+assertLessThan(new java.lang.Long(2), new java.lang.Long(10));
+assertLessThan(new java.lang.Long(2), 10);
+assertLessThan(2, new java.lang.Long(10));
+
+assertLessThan(new java.math.BigInteger(2), new java.math.BigInteger(10));
+assertLessThan(new java.math.BigInteger(2), 10);
+assertLessThan(2, new java.math.BigInteger(10));
+
+assertLessThan(new java.util.concurrent.atomic.AtomicInteger(2), new java.util.concurrent.atomic.AtomicInteger(10));
+assertLessThan(new java.util.concurrent.atomic.AtomicInteger(2), 10);
+assertLessThan(2, new java.util.concurrent.atomic.AtomicInteger(10));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8166902.js	Thu Nov 02 16:18:25 2017 +0300
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8166902: Nested object literal property maps not reset in optimistic recompilation
+ *
+ * @test
+ * @run
+ */
+
+var o = {
+    a: "A",
+    b: "B"
+};
+
+var m = {
+    x: { z: o.a },
+    y: o.b
+};
+
+Assert.assertEquals(m.x.z, "A");
+Assert.assertEquals(m.y, "B");
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8170594.js	Thu Nov 02 16:18:25 2017 +0300
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8170594: >>>=0 generates invalid bytecode for BaseNode LHS
+ *
+ * @test
+ * @run
+ */
+
+var obj1 = {x: "100"};
+(function (o, p) {
+ if (p) {
+   o.x >>>= 0;
+ }
+})(obj1, true)
+Assert.assertTrue(obj1.x === 100)
+
+var obj2 = ["100"];
+(function (o, p) {
+ if (p) {
+   o[0] >>>= 0;
+ }
+})(obj2, true)
+Assert.assertTrue(obj2[0] === 100)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8171219.js	Thu Nov 02 16:18:25 2017 +0300
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8171219: Missing checks in sparse array shift() implementation
+ *
+ * @test
+ * @run
+ */
+
+var a = [];
+a[1048577] = 1;
+a.shift();
+a[1] = 2;
+a.shift();
+var ka = Object.keys(a);
+Assert.assertTrue(ka.length === 2);
+Assert.assertTrue(ka[0] === '0');
+Assert.assertTrue(ka[1] === '1048575');
+Assert.assertTrue(a.length === 1048576);
+Assert.assertTrue(a[0] === 2);
+Assert.assertTrue(a[1048575] = 1);
+
+var b = [];
+b[1048577] = 1;
+b.unshift(2);
+b.shift();
+b[1] = 3;
+b.shift();
+var kb = Object.keys(b);
+Assert.assertTrue(kb.length === 2);
+Assert.assertTrue(kb[0] === '0');
+Assert.assertTrue(kb[1] === '1048576');
+Assert.assertTrue(b.length === 1048577);
+Assert.assertTrue(b[0] === 3);
+Assert.assertTrue(b[1048576] = 1);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8171849.js	Thu Nov 02 16:18:25 2017 +0300
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8171849: Collection and Queue conversions not prioritized for Arrays
+ *
+ * @test
+ * @run
+ */
+
+var acp = new (Java.type("jdk.nashorn.test.models.ArrayConversionPreferences"))
+
+var a = [1, "", {}]
+
+Assert.assertTrue(acp.testCollectionOverMap(a))
+Assert.assertTrue(acp.testCollectionOverArray(a))
+Assert.assertTrue(acp.testListOverMap(a))
+Assert.assertTrue(acp.testListOverArray(a))
+Assert.assertTrue(acp.testListOverCollection(a))
+Assert.assertTrue(acp.testQueueOverMap(a))
+Assert.assertTrue(acp.testQueueOverArray(a))
+Assert.assertTrue(acp.testQueueOverCollection(a))
+Assert.assertTrue(acp.testDequeOverMap(a))
+Assert.assertTrue(acp.testDequeOverArray(a))
+Assert.assertTrue(acp.testDequeOverCollection(a))
+Assert.assertTrue(acp.testDequeOverQueue(a))
+Assert.assertTrue(acp.testArrayOverMap(a))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8176511.js	Thu Nov 02 16:18:25 2017 +0300
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8176511: JSObject property access is broken for numeric keys outside the int range
+ *
+ * @test
+ * @run
+ */
+
+
+var reassignWithNewGlobal = loadWithNewGlobal({
+    script: '(function (o, i) { o[i] = o[i]; })', name: 'internal.js'
+
+});
+
+function test(i) {
+    var o = {};
+    o[i] = true;
+    var before = JSON.stringify(o);
+    reassignWithNewGlobal(o, i);
+    var after = JSON.stringify(o);
+    Assert.assertEquals(before, after);
+}
+
+test(-2147483649);
+test(-2147483648);
+test(2147483647);
+test(2147483648);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8181191.js	Thu Nov 02 16:18:25 2017 +0300
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8181191: getUint32 returning Long
+ *
+ * @test
+ * @run
+ */
+
+
+function uint32(x) {
+    var buffer = new ArrayBuffer(16);
+    var dataview = new DataView(buffer);
+    dataview.setUint32(0, x);
+    return dataview.getUint32(0);
+}
+
+Assert.assertTrue(typeof uint32(0x7f) === 'number');
+Assert.assertTrue(typeof uint32(0x80) === 'number');
+Assert.assertTrue(typeof uint32(0xffffffff) === 'number');
+Assert.assertTrue(typeof uint32(0x100000000) === 'number');
+
+Assert.assertTrue(uint32(0x7f) === 0x7f);
+Assert.assertTrue(uint32(0x80) === 0x80);
+Assert.assertTrue(uint32(0xffffffff) === 0xffffffff);
+Assert.assertTrue(uint32(0x100000000) === 0x0);
+
+Assert.assertTrue(uint32(0x7f) === uint32(0x7f));
+Assert.assertTrue(uint32(0x80) === uint32(0x80));
+Assert.assertTrue(uint32(0xffffffff) === uint32(0xffffffff));
+Assert.assertTrue(uint32(0x100000000) === uint32(0x100000000));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/es6/JDK-8168373.js	Thu Nov 02 16:18:25 2017 +0300
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8168373: don't emit conversions for symbols outside their lexical scope
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+function p() { return false } // "predicate"
+function r(x) { return x } // "read"
+
+(function() {
+  try { // Try creates control flow edges from assignments into catch blocks.
+    // Lexically scoped, never read int variable (undefined at catch block) but still with a cf edge into catch block.
+    // Since it's never read, it's not written either (Nashorn optimizes some dead writes).
+    let x = 0; 
+    if (p()) { throw {}; } // We need `p()` so this block doesn't get optimized away, for possibility of a `throw` 
+    x = 0.0; // change the type of x to double
+    r(x); // read x otherwise it's optimized away
+  } catch (e) {} // under the bug, "throw" will try to widen unwritten int x to double for here and cause a verifier error
+})()
--- a/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java	Thu Nov 02 16:02:48 2017 +0300
+++ b/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java	Thu Nov 02 16:18:25 2017 +0300
@@ -41,6 +41,7 @@
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
+import jdk.nashorn.api.scripting.AbstractJSObject;
 import jdk.nashorn.api.scripting.JSObject;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
 import org.testng.annotations.Test;
@@ -386,4 +387,41 @@
         assertTrue(func.isFunction());
         assertEquals(func.call(e.eval("this"), "hello"), "hello world");
     }
+
+    // @bug 8170565: JSObject call() is passed undefined for the argument 'thiz'
+    @Test
+    public void jsObjectThisTest() throws Exception {
+        final ScriptEngineManager engineManager = new ScriptEngineManager();
+        final ScriptEngine e = engineManager.getEngineByName("nashorn");
+        e.put("func", new AbstractJSObject() {
+            @Override
+            public boolean isFunction() { return true; }
+
+            @Override
+            public Object call(Object thiz, Object...args) {
+                return thiz;
+            }
+        });
+
+        assertTrue((boolean)e.eval("func() === this"));
+
+        // check that there is no blind undefined->Global translation!
+        assertTrue((boolean)e.eval("typeof(Function.prototype.call.call(func, undefined)) == 'undefined'"));
+
+        // make sure that strict functions don't get translated this for scope calls!
+        e.put("sfunc", new AbstractJSObject() {
+            @Override
+            public boolean isFunction() { return true; }
+
+            @Override
+            public boolean isStrictFunction() { return true; }
+
+            @Override
+            public Object call(Object thiz, Object...args) {
+                return thiz;
+            }
+        });
+
+        assertTrue((boolean)e.eval("typeof sfunc() == 'undefined'"));
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/src/jdk/nashorn/test/models/ArrayConversionPreferences.java	Thu Nov 02 16:18:25 2017 +0300
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.test.models;
+
+import java.util.Collection;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+
+public class ArrayConversionPreferences {
+    public boolean testCollectionOverMap(final Collection x) { return true; }
+    public boolean testCollectionOverMap(final Map x) { return false; }
+
+    public boolean testCollectionOverArray(final Collection x) { return true; }
+    public boolean testCollectionOverArray(final Object[] x) { return false; }
+
+    public boolean testListOverMap(final List x) { return true; }
+    public boolean testListOverMap(final Map x) { return false; }
+
+    public boolean testListOverArray(final List x) { return true; }
+    public boolean testListOverArray(final Object[] x) { return false; }
+
+    public boolean testListOverCollection(final List x) { return true; }
+    public boolean testListOverCollection(final Collection x) { return false; }
+
+    public boolean testQueueOverMap(final Queue x) { return true; }
+    public boolean testQueueOverMap(final Map x) { return false; }
+
+    public boolean testQueueOverArray(final Queue x) { return true; }
+    public boolean testQueueOverArray(final Object[] x) { return false; }
+
+    public boolean testQueueOverCollection(final Queue x) { return true; }
+    public boolean testQueueOverCollection(final Collection x) { return false; }
+
+    public boolean testDequeOverMap(final Deque x) { return true; }
+    public boolean testDequeOverMap(final Map x) { return false; }
+
+    public boolean testDequeOverArray(final Deque x) { return true; }
+    public boolean testDequeOverArray(final Object[] x) { return false; }
+
+    public boolean testDequeOverCollection(final Deque x) { return true; }
+    public boolean testDequeOverCollection(final Collection x) { return false; }
+
+    public boolean testDequeOverQueue(final Deque x) { return true; }
+    public boolean testDequeOverQueue(final Queue x) { return false; }
+
+    public boolean testArrayOverMap(final Object[] x) { return true; }
+    public boolean testArrayOverMap(final Map x) { return false; }
+}
+