Merge
authorlana
Thu, 17 Dec 2015 20:26:31 -0800
changeset 34739 b813502229af
parent 34589 d00ad2d9049a (current diff)
parent 34738 6a2c8f68a2c2 (diff)
child 34740 e6f9bacfb9a4
Merge
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java	Thu Dec 17 20:26:31 2015 -0800
@@ -59,6 +59,8 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SETTER_PREFIX;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_OBJECT;
@@ -291,6 +293,13 @@
             mi.push(memInfo.getArity());
             mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, SCRIPTFUNCTION_SETARITY_DESC);
         }
+
+        String doc = memInfo.getDocumentation();
+        if (doc != null) {
+            mi.dup();
+            mi.loadLiteral(memInfo.getDocumentation());
+            mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATION, SCRIPTFUNCTION_SETDOCUMENTATION_DESC);
+        }
     }
 
     static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Thu Dec 17 20:26:31 2015 -0800
@@ -42,6 +42,8 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC4;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
@@ -159,6 +161,13 @@
                 mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY,
                         SCRIPTFUNCTION_SETARITY_DESC);
             }
+            final String doc = constructor.getDocumentation();
+            if (doc != null) {
+                mi.loadThis();
+                mi.loadLiteral(doc);
+                mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATION,
+                        SCRIPTFUNCTION_SETDOCUMENTATION_DESC);
+            }
         }
         mi.returnVoid();
         mi.computeMaxs();
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Thu Dec 17 20:26:31 2015 -0800
@@ -85,6 +85,8 @@
     private MemberInfo.Kind kind;
     // script property name
     private String name;
+    // documentation for this member
+    private String documentation;
     // script property attributes
     private int attributes;
     // name of the java member
@@ -137,6 +139,20 @@
     }
 
     /**
+     * @return the documentation
+     */
+    public String getDocumentation() {
+        return documentation;
+    }
+
+    /**
+     * @param doc the documentation to set
+     */
+    public void setDocumentation(final String doc) {
+        this.documentation = doc;
+    }
+
+    /**
      * Tag something as specialized constructor or not
      * @param isSpecializedConstructor boolean, true if specialized constructor
      */
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java	Thu Dec 17 20:26:31 2015 -0800
@@ -206,6 +206,7 @@
                         // These could be "null" if values are not supplied,
                         // in which case we have to use the default values.
                         private String  name;
+                        private String  documentation;
                         private Integer attributes;
                         private Integer arity;
                         private Where   where;
@@ -222,6 +223,13 @@
                                     name = null;
                                 }
                                 break;
+                            case "documentation":
+                                this.documentation = (String)annotationValue;
+                                if (documentation.isEmpty()) {
+                                    documentation = null;
+                                }
+
+                                break;
                             case "attributes":
                                 this.attributes = (Integer)annotationValue;
                                 break;
@@ -270,6 +278,8 @@
                             } else {
                                 memInfo.setName(name == null ? methodName : name);
                             }
+
+                            memInfo.setDocumentation(documentation);
                             memInfo.setAttributes(attributes == null ? MemberInfo.DEFAULT_ATTRIBUTES : attributes);
 
                             memInfo.setArity((arity == null)? MemberInfo.DEFAULT_ARITY : arity);
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Thu Dec 17 20:26:31 2015 -0800
@@ -118,6 +118,8 @@
     static final String SCRIPTFUNCTION_TYPE = TYPE_SCRIPTFUNCTION.getInternalName();
     static final String SCRIPTFUNCTION_SETARITY = "setArity";
     static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
+    static final String SCRIPTFUNCTION_SETDOCUMENTATION = "setDocumentation";
+    static final String SCRIPTFUNCTION_SETDOCUMENTATION_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING);
     static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype";
     static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
     static final String SCRIPTFUNCTION_CREATEBUILTIN = "createBuiltin";
--- a/nashorn/make/build-benchmark.xml	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/make/build-benchmark.xml	Thu Dec 17 20:26:31 2015 -0800
@@ -314,7 +314,7 @@
           classpath="${run.test.classpath}"
           fork="true"
           dir=".">
-      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${boot.class.path}"/>
       <jvmarg line="${run.test.jvmargs.octane} -Xms${run.test.xms} -Xmx${run.test.xmx}"/>
       <!-- pass on all properties prefixed with 'nashorn' to the runtime -->
       <syspropertyset>
@@ -387,7 +387,7 @@
           classpath="${run.test.classpath}"
           fork="true"
           dir=".">
-      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${boot.class.path}"/>
       <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/>
       <arg value="-timezone=PST"/>
       <arg value="--class-cache-size=50"/>
--- a/nashorn/make/build.xml	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/make/build.xml	Thu Dec 17 20:26:31 2015 -0800
@@ -48,12 +48,12 @@
     <condition property="git.executable" value="/usr/local/bin/git" else="git">
       <available file="/usr/local/bin/git"/>
     </condition>
-    <!-- check if testng.jar is avaiable, and download it if it isn't -->
+    <!-- check if testng.jar is available, and download it if it isn't -->
     <available property="testng.already.present" file="${file.reference.testng.jar}"/>
     <antcall target="get-testng"/>
     <available property="testng.available" file="${file.reference.testng.jar}"/>
 
-    <!-- check if asmtools-6.0.jar is avaiable, and download it if it isn't -->
+    <!-- check if asmtools-6.0.jar is available, and download it if it isn't -->
     <!--
     <available property="asmtools.already.present" file="${file.reference.asmtools.jar}"/>
     <antcall target="get-asmtools"/>
@@ -84,6 +84,12 @@
     <condition property="jfr.options" value="${run.test.jvmargs.jfr}" else="">
       <istrue value="${jfr}"/>
     </condition>
+
+    <condition property="test-sys-prop-no-security.os.not.windows">
+      <not>
+        <os family="windows"/>
+      </not>
+    </condition>
   </target>
 
   <!-- check minimum ant version required to be 1.8.4 -->
@@ -408,6 +414,13 @@
     permission java.util.PropertyPermission "nashorn.test.*", "read";
 };
 
+grant codeBase "file:/${basedir}/test/script/basic/apply_to_call/*" {
+    permission java.io.FilePermission "${basedir}/test/script/-", "read";
+    permission java.io.FilePermission "$${user.dir}", "read";
+    permission java.util.PropertyPermission "user.dir", "read";
+    permission java.util.PropertyPermission "nashorn.test.*", "read";
+};
+
 grant codeBase "file:/${basedir}/test/script/basic/parser/*" {
     permission java.io.FilePermission "${basedir}/test/script/-", "read";
     permission java.io.FilePermission "$${user.dir}", "read";
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java	Thu Dec 17 20:26:31 2015 -0800
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.tools.jjs;
 
+import java.awt.event.ActionListener;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -34,21 +35,24 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.function.Function;
 import jdk.internal.jline.NoInterruptUnixTerminal;
 import jdk.internal.jline.Terminal;
 import jdk.internal.jline.TerminalFactory;
 import jdk.internal.jline.TerminalFactory.Flavor;
 import jdk.internal.jline.WindowsTerminal;
 import jdk.internal.jline.console.ConsoleReader;
+import jdk.internal.jline.console.KeyMap;
 import jdk.internal.jline.console.completer.Completer;
 import jdk.internal.jline.console.history.FileHistory;
 
 class Console implements AutoCloseable {
+    private static final String DOCUMENTATION_SHORTCUT = "\033\133\132"; //Shift-TAB
     private final ConsoleReader in;
     private final FileHistory history;
 
     Console(final InputStream cmdin, final PrintStream cmdout, final File historyFile,
-            final Completer completer) throws IOException {
+            final Completer completer, final Function<String, String> docHelper) throws IOException {
         TerminalFactory.registerFlavor(Flavor.WINDOWS, isCygwin()? JJSUnixTerminal::new : JJSWindowsTerminal::new);
         TerminalFactory.registerFlavor(Flavor.UNIX, JJSUnixTerminal::new);
         in = new ConsoleReader(cmdin, cmdout);
@@ -58,6 +62,7 @@
         in.setHistory(history = new FileHistory(historyFile));
         in.addCompleter(completer);
         Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory));
+        bind(DOCUMENTATION_SHORTCUT, (ActionListener)evt -> showDocumentation(docHelper));
     }
 
     String readLine(final String prompt) throws IOException {
@@ -138,4 +143,34 @@
     private static boolean isCygwin() {
         return System.getenv("SHELL") != null;
     }
+
+    private void bind(String shortcut, Object action) {
+        KeyMap km = in.getKeys();
+        for (int i = 0; i < shortcut.length(); i++) {
+            final Object value = km.getBound(Character.toString(shortcut.charAt(i)));
+            if (value instanceof KeyMap) {
+                km = (KeyMap) value;
+            } else {
+                km.bind(shortcut.substring(i), action);
+            }
+        }
+    }
+
+    private void showDocumentation(final Function<String, String> docHelper) {
+        final String buffer = in.getCursorBuffer().buffer.toString();
+        final int cursor = in.getCursorBuffer().cursor;
+        final String doc = docHelper.apply(buffer.substring(0, cursor));
+        try {
+            if (doc != null) {
+                in.println();
+                in.println(doc);
+                in.redrawLine();
+                in.flush();
+            } else {
+                in.beep();
+            }
+        } catch (IOException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java	Thu Dec 17 20:26:31 2015 -0800
@@ -25,6 +25,9 @@
 
 package jdk.nashorn.tools.jjs;
 
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.awt.Desktop;
 import java.awt.GraphicsEnvironment;
 import java.io.BufferedReader;
 import java.io.File;
@@ -33,15 +36,21 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
+import java.net.URI;
+import java.util.concurrent.Callable;
 import java.util.function.Consumer;
+import java.util.function.Function;
 import jdk.internal.jline.console.completer.Completer;
 import jdk.internal.jline.console.UserInterruptException;
 import jdk.nashorn.api.scripting.NashornException;
 import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.objects.NativeJava;
 import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.NativeJavaPackage;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.tools.Shell;
 
@@ -109,7 +118,32 @@
         final PropertiesHelper propsHelper = new PropertiesHelper(env._classpath);
         final NashornCompleter completer = new NashornCompleter(context, global, this, propsHelper);
 
-        try (final Console in = new Console(System.in, System.out, HIST_FILE, completer)) {
+        try (final Console in = new Console(System.in, System.out, HIST_FILE, completer,
+                str -> {
+                    try {
+                        final Object res = context.eval(global, str, global, "<shell>");
+                        if (res != null && res != UNDEFINED) {
+                            // Special case Java types: show the javadoc for the class.
+                            if (NativeJava.isType(UNDEFINED, res)) {
+                                final String typeName = NativeJava.typeName(UNDEFINED, res).toString();
+                                final String url = typeName.replace('.', '/').replace('$', '.') + ".html";
+                                openBrowserForJavadoc(url);
+                            } else if (res instanceof NativeJavaPackage) {
+                                final String pkgName = ((NativeJavaPackage)res).getName();
+                                final String url = pkgName.replace('.', '/') + "/package-summary.html";
+                                openBrowserForJavadoc(url);
+                            } else if (res instanceof ScriptFunction) {
+                                return ((ScriptFunction)res).getDocumentation();
+                            }
+
+                            // FIXME: better than toString for other cases?
+                            return JSType.toString(res);
+                        }
+                     } catch (Exception ignored) {
+                     }
+                     return null;
+                })) {
+
             if (globalChanged) {
                 Context.setGlobal(global);
             }
@@ -164,7 +198,7 @@
 
                 try {
                     final Object res = context.eval(global, source, global, "<shell>");
-                    if (res != ScriptRuntime.UNDEFINED) {
+                    if (res != UNDEFINED) {
                         err.println(toString(res, global));
                     }
                 } catch (final Exception exp) {
@@ -218,7 +252,7 @@
             final PrintWriter err, final boolean doe) {
         try {
             final Object res = context.eval(global, source, global, "<shell>");
-            if (res != ScriptRuntime.UNDEFINED) {
+            if (res != UNDEFINED) {
                 err.println(JSType.toString(res));
             }
         } catch (final Exception e) {
@@ -228,4 +262,15 @@
             }
         }
     }
+
+    // FIXME: needs to be changed to use javase 9 docs later
+    private static String JAVADOC_BASE = "http://download.java.net/jdk9/docs/api/";
+
+    private static void openBrowserForJavadoc(String relativeUrl) {
+        try {
+            final URI uri = new URI(JAVADOC_BASE + relativeUrl);
+            Desktop.getDesktop().browse(uri);
+        } catch (Exception ignored) {
+        }
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java	Thu Dec 17 20:26:31 2015 -0800
@@ -31,6 +31,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.WeakHashMap;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.NativeJavaPackage;
@@ -136,6 +137,42 @@
         return props;
     }
 
+    // This method creates a regex Pattern to use to do CamelCase
+    // matching. The pattern is derived from user supplied string
+    // containing one or more upper case characters in it.
+    private static Pattern makeCamelCasePattern(final String str) {
+        assert !str.isEmpty();
+
+        final char[] chars = str.toCharArray();
+        final StringBuilder buf = new StringBuilder();
+        boolean seenUpperCase = false;
+
+        // Skip first char for case check. Even if it is upper case,
+        // we do not want to put lower case matching pattern before
+        // the first letter!
+        buf.append(chars[0]);
+
+        for (int idx = 1; idx < chars.length; idx++) {
+            final char ch = chars[idx];
+            if (ch >= 'A' && ch <= 'Z') {
+                seenUpperCase = true;
+                buf.append("[^A-Z]*");
+            }
+            buf.append(ch);
+        }
+
+        if (seenUpperCase) {
+            // match anything at the end!
+            buf.append(".*");
+            try {
+                return Pattern.compile(buf.toString());
+            } catch (Exception exp) {
+            }
+        }
+
+        return null;
+    }
+
     /**
      * Returns the list of properties of the given object that start with the given prefix.
      *
@@ -145,8 +182,21 @@
      */
     List<String> getProperties(final Object obj, final String prefix) {
         assert prefix != null && !prefix.isEmpty();
-        return getProperties(obj).stream()
+        List<String> allProps = getProperties(obj);
+        List<String> props = allProps.stream()
                    .filter(s -> s.startsWith(prefix))
                    .collect(Collectors.toList());
+
+        // If no match, try CamelCase completion..
+        if (props.isEmpty()) {
+            final Pattern pat = makeCamelCasePattern(prefix);
+            if (pat != null) {
+                return allProps.stream()
+                    .filter(s -> pat.matcher(s).matches())
+                    .collect(Collectors.toList());
+            }
+        }
+
+        return props;
     }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Dec 17 20:26:31 2015 -0800
@@ -188,8 +188,6 @@
 
     private static final Call ENSURE_INT = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
             "ensureInt", int.class, Object.class, int.class);
-    private static final Call ENSURE_LONG = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
-            "ensureLong", long.class, Object.class, int.class);
     private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
             "ensureNumber", double.class, Object.class, int.class);
 
@@ -1726,7 +1724,7 @@
         enterStatement(expressionStatement);
 
         loadAndDiscard(expressionStatement.getExpression());
-        assert method.getStackSize() == 0;
+        assert method.getStackSize() == 0 : "stack not empty in " + expressionStatement;
 
         return false;
     }
@@ -2241,7 +2239,7 @@
      * @param arrayType        the type of the array, e.g. ARRAY_NUMBER or ARRAY_OBJECT
      */
     private void loadArray(final ArrayLiteralNode arrayLiteralNode, final ArrayType arrayType) {
-        assert arrayType == Type.INT_ARRAY || arrayType == Type.LONG_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY;
+        assert arrayType == Type.INT_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY;
 
         final Expression[]     nodes    = arrayLiteralNode.getValue();
         final Object           presets  = arrayLiteralNode.getPresets();
@@ -2389,20 +2387,9 @@
                 method.convert(Type.OBJECT);
             } else if(!resultBounds.canBeNarrowerThan(Type.NUMBER)) {
                 method.load(((Integer)value).doubleValue());
-            } else if(!resultBounds.canBeNarrowerThan(Type.LONG)) {
-                method.load(((Integer)value).longValue());
             } else {
                 method.load((Integer)value);
             }
-        } else if (value instanceof Long) {
-            if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) {
-                method.load((Long)value);
-                method.convert(Type.OBJECT);
-            } else if(!resultBounds.canBeNarrowerThan(Type.NUMBER)) {
-                method.load(((Long)value).doubleValue());
-            } else {
-                method.load((Long)value);
-            }
         } else if (value instanceof Double) {
             if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) {
                 method.load((Double)value);
@@ -3650,8 +3637,6 @@
             private void loadMinusOne() {
                 if (type.isInteger()) {
                     method.load(isIncrement ? 1 : -1);
-                } else if (type.isLong()) {
-                    method.load(isIncrement ? 1L : -1L);
                 } else {
                     method.load(isIncrement ? 1.0 : -1.0);
                 }
@@ -4033,23 +4018,66 @@
     }
 
     private void loadASSIGN_SHR(final BinaryNode binaryNode) {
-        new BinarySelfAssignment(binaryNode) {
+        new SelfModifyingStore<BinaryNode>(binaryNode, binaryNode.lhs()) {
             @Override
-            protected void op() {
-                doSHR();
-            }
-
+            protected void evaluate() {
+                new OptimisticOperation(assignNode, new TypeBounds(Type.INT, Type.NUMBER)) {
+                    @Override
+                    void loadStack() {
+                        assert assignNode.getWidestOperandType() == Type.INT;
+                        if (isRhsZero(binaryNode)) {
+                            loadExpressionAsType(binaryNode.lhs(), Type.INT);
+                        } else {
+                            loadBinaryOperands(binaryNode.lhs(), binaryNode.rhs(), TypeBounds.INT, true, false);
+                            method.shr();
+                        }
+                    }
+
+                    @Override
+                    void consumeStack() {
+                        if (isOptimistic(binaryNode)) {
+                            toUint32Optimistic(binaryNode.getProgramPoint());
+                        } else {
+                            toUint32Double();
+                        }
+                    }
+                }.emit(getOptimisticIgnoreCountForSelfModifyingExpression(binaryNode.lhs()));
+                method.convert(assignNode.getType());
+            }
         }.store();
     }
 
-    private void doSHR() {
-        // TODO: make SHR optimistic
-        method.shr();
-        toUint();
-    }
-
-    private void toUint() {
-        JSType.TO_UINT32_I.invoke(method);
+    private void doSHR(final BinaryNode binaryNode) {
+        new OptimisticOperation(binaryNode, new TypeBounds(Type.INT, Type.NUMBER)) {
+            @Override
+            void loadStack() {
+                if (isRhsZero(binaryNode)) {
+                    loadExpressionAsType(binaryNode.lhs(), Type.INT);
+                } else {
+                    loadBinaryOperands(binaryNode);
+                    method.shr();
+                }
+            }
+
+            @Override
+            void consumeStack() {
+                if (isOptimistic(binaryNode)) {
+                    toUint32Optimistic(binaryNode.getProgramPoint());
+                } else {
+                    toUint32Double();
+                }
+            }
+        }.emit();
+
+    }
+
+    private void toUint32Optimistic(final int programPoint) {
+        method.load(programPoint);
+        JSType.TO_UINT32_OPTIMISTIC.invoke(method);
+    }
+
+    private void toUint32Double() {
+        JSType.TO_UINT32_DOUBLE.invoke(method);
     }
 
     private void loadASSIGN_SUB(final BinaryNode binaryNode) {
@@ -4087,7 +4115,7 @@
                             // Non-optimistic, non-FP subtraction or multiplication. Allow them to overflow.
                             operandBounds = new TypeBounds(Type.narrowest(node.getWidestOperandType(),
                                     numericBounds.widest), Type.NUMBER);
-                            forceConversionSeparation = node.getWidestOperationType().narrowerThan(numericBounds.widest);
+                            forceConversionSeparation = true;
                         }
                     }
                     loadBinaryOperands(node.lhs(), node.rhs(), operandBounds, false, forceConversionSeparation);
@@ -4189,14 +4217,7 @@
     }
 
     private void loadSHR(final BinaryNode binaryNode) {
-        // Optimize x >>> 0 to (uint)x
-        if (isRhsZero(binaryNode)) {
-            loadExpressionAsType(binaryNode.lhs(), Type.INT);
-            toUint();
-        } else {
-            loadBinaryOperands(binaryNode);
-            doSHR();
-        }
+        doSHR(binaryNode);
     }
 
     private void loadSUB(final BinaryNode binaryNode, final TypeBounds resultBounds) {
@@ -4467,6 +4488,7 @@
                         }
                     } else {
                         final Type storeType = assignNode.getType();
+                        assert storeType != Type.LONG;
                         if (symbol.hasSlotFor(storeType)) {
                             // Only emit a convert for a store known to be live; converts for dead stores can
                             // give us an unnecessary ClassCastException.
@@ -4851,8 +4873,6 @@
                     method.load(optimistic.getProgramPoint());
                     if(optimisticType.isInteger()) {
                         method.invoke(ENSURE_INT);
-                    } else if(optimisticType.isLong()) {
-                        method.invoke(ENSURE_LONG);
                     } else if(optimisticType.isNumber()) {
                         method.invoke(ENSURE_NUMBER);
                     } else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Thu Dec 17 20:26:31 2015 -0800
@@ -167,8 +167,7 @@
         assert fieldName.equals(getFieldName(fieldIndex, PRIMITIVE_FIELD_TYPE)) || fieldType.isObject() :    key + " object keys must store to L*-fields";
         assert fieldName.equals(getFieldName(fieldIndex, Type.OBJECT))          || fieldType.isPrimitive() : key + " primitive keys must store to J*-fields";
 
-        loadTuple(method, tuple);
-
+        loadTuple(method, tuple, true);
         method.putField(fieldClass, fieldName, fieldDesc);
     }
 
@@ -180,11 +179,7 @@
      * @param tuple  Tuple to store.
      */
     private void putSlot(final MethodEmitter method, final long index, final MapTuple<T> tuple) {
-        if (JSType.isRepresentableAsInt(index)) {
-            method.load((int)index);
-        } else {
-            method.load(index);
-        }
+        loadIndex(method, index);
         loadTuple(method, tuple, false); //we don't pack array like objects
         method.dynamicSetIndex(callSiteFlags);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java	Thu Dec 17 20:26:31 2015 -0800
@@ -307,9 +307,7 @@
             final Type widest = Type.widest(lhs.getType(), rhs.getType());
 
             boolean isInteger = widest.isInteger();
-            boolean isLong    = widest.isLong();
-
-            double value;
+            final double value;
 
             switch (parent.tokenType()) {
             case DIV:
@@ -336,7 +334,8 @@
                 value = lhs.getNumber() - rhs.getNumber();
                 break;
             case SHR:
-                return LiteralNode.newInstance(token, finish, JSType.toUint32(lhs.getInt32() >>> rhs.getInt32()));
+                final long result = JSType.toUint32(lhs.getInt32() >>> rhs.getInt32());
+                return LiteralNode.newInstance(token, finish, JSType.isRepresentableAsInt(result) ? (int) result : (double) result);
             case SAR:
                 return LiteralNode.newInstance(token, finish, lhs.getInt32() >> rhs.getInt32());
             case SHL:
@@ -368,12 +367,9 @@
             }
 
             isInteger &= JSType.isStrictlyRepresentableAsInt(value);
-            isLong    &= JSType.isStrictlyRepresentableAsLong(value);
 
             if (isInteger) {
                 return LiteralNode.newInstance(token, finish, (int)value);
-            } else if (isLong) {
-                return LiteralNode.newInstance(token, finish, (long)value);
             }
 
             return LiteralNode.newInstance(token, finish, value);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Thu Dec 17 20:26:31 2015 -0800
@@ -131,7 +131,6 @@
         UNDEFINED(Type.UNDEFINED),
         BOOLEAN(Type.BOOLEAN),
         INT(Type.INT),
-        LONG(Type.LONG),
         DOUBLE(Type.NUMBER),
         OBJECT(Type.OBJECT);
 
@@ -272,12 +271,9 @@
     }
 
     private static class SymbolConversions {
-        private static final byte I2L = 1 << 0;
-        private static final byte I2D = 1 << 1;
-        private static final byte I2O = 1 << 2;
-        private static final byte L2D = 1 << 3;
-        private static final byte L2O = 1 << 4;
-        private static final byte D2O = 1 << 5;
+        private static final byte I2D = 1 << 0;
+        private static final byte I2O = 1 << 1;
+        private static final byte D2O = 1 << 2;
 
         private byte conversions;
 
@@ -288,9 +284,6 @@
             case INT:
             case BOOLEAN:
                 switch (to) {
-                case LONG:
-                    recordConversion(I2L);
-                    return;
                 case DOUBLE:
                     recordConversion(I2D);
                     return;
@@ -301,18 +294,6 @@
                     illegalConversion(from, to);
                     return;
                 }
-            case LONG:
-                switch (to) {
-                case DOUBLE:
-                    recordConversion(L2D);
-                    return;
-                case OBJECT:
-                    recordConversion(L2O);
-                    return;
-                default:
-                    illegalConversion(from, to);
-                    return;
-                }
             case DOUBLE:
                 if(to == LvarType.OBJECT) {
                     recordConversion(D2O);
@@ -340,26 +321,15 @@
                 if(hasConversion(D2O)) {
                     symbol.setHasSlotFor(Type.NUMBER);
                 }
-                if(hasConversion(L2O)) {
-                    symbol.setHasSlotFor(Type.LONG);
-                }
                 if(hasConversion(I2O)) {
                     symbol.setHasSlotFor(Type.INT);
                 }
             }
             if(symbol.hasSlotFor(Type.NUMBER)) {
-                if(hasConversion(L2D)) {
-                    symbol.setHasSlotFor(Type.LONG);
-                }
                 if(hasConversion(I2D)) {
                     symbol.setHasSlotFor(Type.INT);
                 }
             }
-            if(symbol.hasSlotFor(Type.LONG)) {
-                if(hasConversion(I2L)) {
-                    symbol.setHasSlotFor(Type.INT);
-                }
-            }
         }
     }
 
@@ -378,7 +348,7 @@
         if(lvarType != null) {
             return lvarType;
         }
-        assert type.isObject();
+        assert type.isObject() : "Unsupported primitive type: " + type;
         return LvarType.OBJECT;
     }
     private static LvarType widestLvarType(final LvarType t1, final LvarType t2) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java	Thu Dec 17 20:26:31 2015 -0800
@@ -544,7 +544,6 @@
         } else {
             assert false : type + " cannot be packed!";
         }
-        //all others are nops, objects aren't packed
     }
 
     /**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Thu Dec 17 20:26:31 2015 -0800
@@ -41,7 +41,6 @@
 import static jdk.nashorn.internal.runtime.JSType.GET_UNDEFINED;
 import static jdk.nashorn.internal.runtime.JSType.TYPE_DOUBLE_INDEX;
 import static jdk.nashorn.internal.runtime.JSType.TYPE_INT_INDEX;
-import static jdk.nashorn.internal.runtime.JSType.TYPE_LONG_INDEX;
 import static jdk.nashorn.internal.runtime.JSType.TYPE_OBJECT_INDEX;
 import static jdk.nashorn.internal.runtime.JSType.TYPE_UNDEFINED_INDEX;
 import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
@@ -535,8 +534,6 @@
         switch (getAccessorTypeIndex(forType)) {
         case TYPE_INT_INDEX:
             return MH.explicitCastArguments(primitiveGetter, primitiveGetter.type().changeReturnType(int.class));
-        case TYPE_LONG_INDEX:
-            return primitiveGetter;
         case TYPE_DOUBLE_INDEX:
             return MH.filterReturnValue(primitiveGetter, UNPACK_DOUBLE);
         case TYPE_OBJECT_INDEX:
@@ -623,7 +620,7 @@
         }
 
         assert !isOptimistic;
-            //freely coerce the result to whatever you asked for, this is e.g. Object->int for a & b
+        // freely coerce the result to whatever you asked for, this is e.g. Object->int for a & b
         final MethodHandle tgetter = getterForType(forType, primitiveGetter, objectGetter);
         if (fti == TYPE_OBJECT_INDEX) {
             if (fti != ti) {
@@ -638,22 +635,10 @@
         case TYPE_INT_INDEX: {
             return MH.asType(tgetter, tgetterType.changeReturnType(type));
         }
-        case TYPE_LONG_INDEX:
-            switch (ti) {
-            case TYPE_INT_INDEX:
-                //get int while an int, truncating cast of long value
-                return MH.filterReturnValue(tgetter, JSType.TO_INT32_L.methodHandle);
-            case TYPE_LONG_INDEX:
-                return primitiveGetter;
-            default:
-                return MH.asType(tgetter, tgetterType.changeReturnType(type));
-            }
         case TYPE_DOUBLE_INDEX:
             switch (ti) {
             case TYPE_INT_INDEX:
                 return MH.filterReturnValue(tgetter, JSType.TO_INT32_D.methodHandle);
-            case TYPE_LONG_INDEX:
-                return MH.explicitCastArguments(tgetter, tgetterType.changeReturnType(type));
             case TYPE_DOUBLE_INDEX:
                 assert tgetterType.returnType() == double.class;
                 return tgetter;
@@ -734,12 +719,9 @@
 
         switch (fti) {
         case TYPE_INT_INDEX:
-        case TYPE_LONG_INDEX:
             switch (ti) {
             case TYPE_INT_INDEX:
                 return MH.asType(primitiveSetter, pmt.changeParameterType(1, int.class));
-            case TYPE_LONG_INDEX:
-                return primitiveSetter;
             case TYPE_DOUBLE_INDEX:
                 return MH.filterArguments(primitiveSetter, 1, PACK_DOUBLE);
             default:
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectCreator.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectCreator.java	Thu Dec 17 20:26:31 2015 -0800
@@ -29,6 +29,7 @@
 
 import java.util.List;
 import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptObject;
 
@@ -156,15 +157,15 @@
 
     MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple, final boolean pack) {
         loadValue(tuple.value, tuple.type);
-        if (pack && codegen.useDualFields() && tuple.isPrimitive()) {
+        if (!codegen.useDualFields() || !tuple.isPrimitive()) {
+            method.convert(Type.OBJECT);
+        } else if (pack) {
             method.pack();
-        } else {
-            method.convert(Type.OBJECT);
         }
         return method;
     }
 
-    MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple) {
-        return loadTuple(method, tuple, true);
+    MethodEmitter loadIndex(final MethodEmitter method, final long index) {
+        return JSType.isRepresentableAsInt(index) ? method.load((int) index) : method.load((double) index);
     }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Thu Dec 17 20:26:31 2015 -0800
@@ -109,8 +109,6 @@
                         //avoid blowing up the array if we can
                         if (constantValue instanceof Integer) {
                             arrayData = arrayData.set(index, ((Integer)constantValue).intValue(), false);
-                        } else if (constantValue instanceof Long) {
-                            arrayData = arrayData.set(index, ((Long)constantValue).longValue(), false);
                         } else if (constantValue instanceof Double) {
                             arrayData = arrayData.set(index, ((Double)constantValue).doubleValue(), false);
                         } else {
@@ -169,13 +167,13 @@
                 final int index = ArrayIndex.getArrayIndex(tuple.key);
                 assert ArrayIndex.isValidArrayIndex(index);
                 method.dup();
-                method.load(ArrayIndex.toLongIndex(index));
-                loadTuple(method, tuple);
+                loadIndex(method, ArrayIndex.toLongIndex(index));
+                loadTuple(method, tuple, false);
                 method.dynamicSetIndex(callSiteFlags);
             } else {
                 assert property.getKey() instanceof String; // symbol keys not yet supported in object literals
                 method.dup();
-                loadTuple(method, tuple);
+                loadTuple(method, tuple, false);
                 method.dynamicSet((String) property.getKey(), codegen.getCallSiteFlags(), false);
             }
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java	Thu Dec 17 20:26:31 2015 -0800
@@ -239,7 +239,7 @@
                             // currently deoptimize all the way to Object.
                             return Type.OBJECT;
                         }
-                        assert returnType == Type.INT || returnType == Type.LONG || returnType == Type.NUMBER || returnType == Type.OBJECT;
+                        assert returnType == Type.INT || returnType == Type.NUMBER || returnType == Type.OBJECT;
                         return returnType;
                     }
                 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/IntType.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/IntType.java	Thu Dec 17 20:26:31 2015 -0800
@@ -72,7 +72,7 @@
 
     @Override
     public Type nextWider() {
-        return LONG;
+        return NUMBER;
     }
 
     @Override
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/LongType.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/LongType.java	Thu Dec 17 20:26:31 2015 -0800
@@ -28,20 +28,11 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.L2D;
 import static jdk.internal.org.objectweb.asm.Opcodes.L2I;
 import static jdk.internal.org.objectweb.asm.Opcodes.LADD;
-import static jdk.internal.org.objectweb.asm.Opcodes.LAND;
-import static jdk.internal.org.objectweb.asm.Opcodes.LCMP;
 import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_0;
 import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_1;
 import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD;
-import static jdk.internal.org.objectweb.asm.Opcodes.LMUL;
-import static jdk.internal.org.objectweb.asm.Opcodes.LOR;
 import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN;
-import static jdk.internal.org.objectweb.asm.Opcodes.LSHL;
-import static jdk.internal.org.objectweb.asm.Opcodes.LSHR;
 import static jdk.internal.org.objectweb.asm.Opcodes.LSTORE;
-import static jdk.internal.org.objectweb.asm.Opcodes.LSUB;
-import static jdk.internal.org.objectweb.asm.Opcodes.LUSHR;
-import static jdk.internal.org.objectweb.asm.Opcodes.LXOR;
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
 import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_LONG;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
@@ -53,7 +44,7 @@
 /**
  * Type class: LONG
  */
-class LongType extends BitwiseType {
+class LongType extends Type {
     private static final long serialVersionUID = 1L;
 
     private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Long.class, "valueOf", Long.class, long.class);
@@ -82,12 +73,6 @@
     }
 
     @Override
-    public Type cmp(final MethodVisitor method) {
-        method.visitInsn(LCMP);
-        return INT;
-    }
-
-    @Override
     public Type load(final MethodVisitor method, final int slot) {
         assert slot != -1;
         method.visitVarInsn(LLOAD, slot);
@@ -149,88 +134,6 @@
     }
 
     @Override
-    public Type sub(final MethodVisitor method, final int programPoint) {
-        if(programPoint == INVALID_PROGRAM_POINT) {
-            method.visitInsn(LSUB);
-        } else {
-            method.visitInvokeDynamicInsn("lsub", "(JJ)J", MATHBOOTSTRAP, programPoint);
-        }
-        return LONG;
-    }
-
-    @Override
-    public Type mul(final MethodVisitor method, final int programPoint) {
-        if(programPoint == INVALID_PROGRAM_POINT) {
-            method.visitInsn(LMUL);
-        } else {
-            method.visitInvokeDynamicInsn("lmul", "(JJ)J", MATHBOOTSTRAP, programPoint);
-        }
-        return LONG;
-    }
-
-    @Override
-    public Type div(final MethodVisitor method, final int programPoint) {
-        if (programPoint == INVALID_PROGRAM_POINT) {
-            JSType.DIV_ZERO_LONG.invoke(method);
-        } else {
-            method.visitInvokeDynamicInsn("ldiv", "(JJ)J", MATHBOOTSTRAP, programPoint);
-        }
-        return LONG;
-    }
-
-    @Override
-    public Type rem(final MethodVisitor method, final int programPoint) {
-        if (programPoint == INVALID_PROGRAM_POINT) {
-            JSType.REM_ZERO_LONG.invoke(method);
-        } else {
-            method.visitInvokeDynamicInsn("lrem", "(JJ)J", MATHBOOTSTRAP, programPoint);
-        }
-        return LONG;
-    }
-
-    @Override
-    public Type shr(final MethodVisitor method) {
-        method.visitInsn(LUSHR);
-        return LONG;
-    }
-
-    @Override
-    public Type sar(final MethodVisitor method) {
-        method.visitInsn(LSHR);
-        return LONG;
-    }
-
-    @Override
-    public Type shl(final MethodVisitor method) {
-        method.visitInsn(LSHL);
-        return LONG;
-    }
-
-    @Override
-    public Type and(final MethodVisitor method) {
-        method.visitInsn(LAND);
-        return LONG;
-    }
-
-    @Override
-    public Type or(final MethodVisitor method) {
-        method.visitInsn(LOR);
-        return LONG;
-    }
-
-    @Override
-    public Type xor(final MethodVisitor method) {
-        method.visitInsn(LXOR);
-        return LONG;
-    }
-
-    @Override
-    public Type neg(final MethodVisitor method, final int programPoint) {
-        method.visitInvokeDynamicInsn("lneg", "(J)J", MATHBOOTSTRAP, programPoint);
-        return LONG;
-    }
-
-    @Override
     public void _return(final MethodVisitor method) {
         method.visitInsn(LRETURN);
     }
@@ -246,9 +149,4 @@
         method.visitInsn(LCONST_0);
         return LONG;
     }
-
-    @Override
-    public Type cmp(final MethodVisitor method, final boolean isCmpG) {
-        return cmp(method);
-    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/Type.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/Type.java	Thu Dec 17 20:26:31 2015 -0800
@@ -914,7 +914,7 @@
     /**
      * This is the long singleton, used for all long types
      */
-    public static final BitwiseType LONG = putInCache(new LongType());
+    public static final Type LONG = putInCache(new LongType());
 
     /**
      * A string singleton
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BinaryNode.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BinaryNode.java	Thu Dec 17 20:26:31 2015 -0800
@@ -70,7 +70,9 @@
                 TokenType.ASSIGN_DIV,
                 TokenType.ASSIGN_MOD,
                 TokenType.ASSIGN_MUL,
-                TokenType.ASSIGN_SUB
+                TokenType.ASSIGN_SUB,
+                TokenType.SHR,
+                TokenType.ASSIGN_SHR
             })));
 
     /**
@@ -196,9 +198,7 @@
                 return Type.CHARSEQUENCE;
             }
             final Type widestOperandType = Type.widest(undefinedToNumber(booleanToInt(lhsType)), undefinedToNumber(booleanToInt(rhsType)));
-            if(widestOperandType == Type.INT) {
-                return Type.LONG;
-            } else if (widestOperandType.isNumeric()) {
+            if (widestOperandType.isNumeric()) {
                 return Type.NUMBER;
             }
             // We pretty much can't know what it will be statically. Must presume OBJECT conservatively, as we can end
@@ -210,7 +210,7 @@
         }
         case SHR:
         case ASSIGN_SHR:
-            return Type.LONG;
+            return Type.NUMBER;
         case ASSIGN_SAR:
         case ASSIGN_SHL:
         case BIT_AND:
@@ -239,10 +239,6 @@
             if(lhsType == Type.BOOLEAN && rhsType == Type.BOOLEAN) {
                 return Type.INT;
             }
-            final Type widestOperandType = Type.widest(booleanToInt(lhsType), booleanToInt(rhsType));
-            if(widestOperandType == Type.INT) {
-                return Type.LONG;
-            }
             return Type.NUMBER;
         }
         case VOID: {
@@ -565,6 +561,9 @@
         if(type == null) {
             return widest;
         }
+        if (tokenType() == TokenType.ASSIGN_SHR || tokenType() == TokenType.SHR) {
+            return type;
+        }
         return Type.narrowest(widest, Type.widest(type, Type.widest(lhs.getType(), rhs.getType())));
     }
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LiteralNode.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LiteralNode.java	Thu Dec 17 20:26:31 2015 -0800
@@ -386,8 +386,6 @@
         private static Type numberGetType(final Number number) {
             if (number instanceof Integer) {
                 return Type.INT;
-            } else if (number instanceof Long) {
-                return Type.LONG;
             } else if (number instanceof Double) {
                 return Type.NUMBER;
             } else {
@@ -418,6 +416,7 @@
      * @return the new literal node
      */
     public static LiteralNode<Number> newInstance(final long token, final int finish, final Number value) {
+        assert !(value instanceof Long);
         return new NumberLiteralNode(token, finish, value);
     }
 
@@ -776,8 +775,6 @@
                 assert !elementType.isUnknown();
                 if (elementType.isInteger()) {
                     return presetIntArray(value, postsets);
-                } else if (elementType.isLong()) {
-                    return presetLongArray(value, postsets);
                 } else if (elementType.isNumeric()) {
                     return presetDoubleArray(value, postsets);
                 } else {
@@ -847,8 +844,6 @@
         private static ArrayType getArrayType(final Type elementType) {
             if (elementType.isInteger()) {
                 return Type.INT_ARRAY;
-            } else if (elementType.isLong()) {
-                return Type.LONG_ARRAY;
             } else if (elementType.isNumeric()) {
                 return Type.NUMBER_ARRAY;
             } else {
@@ -883,8 +878,6 @@
         private boolean presetsMatchElementType() {
             if (elementType == Type.INT) {
                 return presets instanceof int[];
-            } else if (elementType == Type.LONG) {
-                return presets instanceof long[];
             } else if (elementType == Type.NUMBER) {
                 return presets instanceof double[];
             } else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Symbol.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Symbol.java	Thu Dec 17 20:26:31 2015 -0800
@@ -82,14 +82,12 @@
     public static final int HAS_SLOT                = 1 << 10;
     /** Is this symbol known to store an int value ? */
     public static final int HAS_INT_VALUE           = 1 << 11;
-    /** Is this symbol known to store a long value ? */
-    public static final int HAS_LONG_VALUE          = 1 << 12;
     /** Is this symbol known to store a double value ? */
-    public static final int HAS_DOUBLE_VALUE        = 1 << 13;
+    public static final int HAS_DOUBLE_VALUE        = 1 << 12;
     /** Is this symbol known to store an object value ? */
-    public static final int HAS_OBJECT_VALUE        = 1 << 14;
+    public static final int HAS_OBJECT_VALUE        = 1 << 13;
     /** Is this symbol seen a declaration? Used for block scoped LET and CONST symbols only. */
-    public static final int HAS_BEEN_DECLARED       = 1 << 15;
+    public static final int HAS_BEEN_DECLARED       = 1 << 14;
 
     /** Null or name identifying symbol. */
     private final String name;
@@ -256,7 +254,6 @@
      */
     public int slotCount() {
         return ((flags & HAS_INT_VALUE)    == 0 ? 0 : 1) +
-               ((flags & HAS_LONG_VALUE)   == 0 ? 0 : 2) +
                ((flags & HAS_DOUBLE_VALUE) == 0 ? 0 : 2) +
                ((flags & HAS_OBJECT_VALUE) == 0 ? 0 : 1);
     }
@@ -278,7 +275,6 @@
                 append("slot=").
                 append(firstSlot).append(' ');
             if((flags & HAS_INT_VALUE) != 0) { sb.append('I'); }
-            if((flags & HAS_LONG_VALUE) != 0) { sb.append('J'); }
             if((flags & HAS_DOUBLE_VALUE) != 0) { sb.append('D'); }
             if((flags & HAS_OBJECT_VALUE) != 0) { sb.append('O'); }
             sb.append(')');
@@ -573,11 +569,6 @@
             return typeSlot;
         }
         typeSlot += ((flags & HAS_INT_VALUE) == 0 ? 0 : 1);
-        if(type.isLong()) {
-            assert (flags & HAS_LONG_VALUE) != 0;
-            return typeSlot;
-        }
-        typeSlot += ((flags & HAS_LONG_VALUE) == 0 ? 0 : 2);
         if(type.isNumber()) {
             assert (flags & HAS_DOUBLE_VALUE) != 0;
             return typeSlot;
@@ -595,8 +586,6 @@
     public boolean hasSlotFor(final Type type) {
         if(type.isBoolean() || type.isInteger()) {
             return (flags & HAS_INT_VALUE) != 0;
-        } else if(type.isLong()) {
-            return (flags & HAS_LONG_VALUE) != 0;
         } else if(type.isNumber()) {
             return (flags & HAS_DOUBLE_VALUE) != 0;
         }
@@ -611,8 +600,6 @@
     public void setHasSlotFor(final Type type) {
         if(type.isBoolean() || type.isInteger()) {
             setFlag(HAS_INT_VALUE);
-        } else if(type.isLong()) {
-            setFlag(HAS_LONG_VALUE);
         } else if(type.isNumber()) {
             setFlag(HAS_DOUBLE_VALUE);
         } else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/debug/NashornTextifier.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/debug/NashornTextifier.java	Thu Dec 17 20:26:31 2015 -0800
@@ -25,9 +25,6 @@
 
 package jdk.nashorn.internal.ir.debug;
 
-import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT;
-import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.FLAGS_MASK;
-
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -502,6 +499,7 @@
 
         appendOpcode(sb, Opcodes.INVOKEDYNAMIC).append(' ');
         final boolean isNashornBootstrap = isNashornBootstrap(bsm);
+        final boolean isNashornMathBootstrap = isNashornMathBootstrap(bsm);
         if (isNashornBootstrap) {
             sb.append(NashornCallSiteDescriptor.getOperationName((Integer)bsmArgs[0]));
             final String decodedName = NameCodec.decode(name);
@@ -529,12 +527,9 @@
                 } else if (cst instanceof Handle) {
                     appendHandle(sb, (Handle)cst);
                 } else if (cst instanceof Integer && isNashornBootstrap) {
-                    final int c = (Integer)cst;
-                    final int pp = c >> CALLSITE_PROGRAM_POINT_SHIFT;
-                    if (pp != 0) {
-                        sb.append(" pp=").append(pp);
-                    }
-                    sb.append(NashornCallSiteDescriptor.toString(c & FLAGS_MASK));
+                    NashornCallSiteDescriptor.appendFlags((Integer) cst, sb);
+                } else if (cst instanceof Integer && isNashornMathBootstrap) {
+                    sb.append(" pp=").append(cst);
                 } else {
                     sb.append(cst);
                 }
@@ -551,6 +546,10 @@
         return "bootstrap".equals(bsm.getName()) && BOOTSTRAP_CLASS_NAME.equals(bsm.getOwner());
     }
 
+    private static boolean isNashornMathBootstrap(final Handle bsm) {
+        return "mathBootstrap".equals(bsm.getName()) && BOOTSTRAP_CLASS_NAME.equals(bsm.getOwner());
+    }
+
     private static boolean noFallThru(final int opcode) {
         switch (opcode) {
         case Opcodes.GOTO:
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Thu Dec 17 20:26:31 2015 -0800
@@ -1106,8 +1106,6 @@
             return new NativeArray(ArrayData.allocate((Object[])obj), this);
         } else if (obj instanceof double[]) { // extension
             return new NativeArray(ArrayData.allocate((double[])obj), this);
-        } else if (obj instanceof long[]) {
-            return new NativeArray(ArrayData.allocate((long[])obj), this);
         } else if (obj instanceof int[]) {
             return new NativeArray(ArrayData.allocate((int[]) obj), this);
         } else if (obj instanceof ArrayData) {
@@ -1994,16 +1992,6 @@
     }
 
     /**
-     * Allocate a new long array.
-     *
-     * @param initial number values.
-     * @return the new array
-     */
-    public static NativeArray allocate(final long[] initial) {
-        return new NativeArray(ArrayData.allocate(initial));
-    }
-
-    /**
      * Allocate a new integer array.
      *
      * @param initial number values.
@@ -2291,7 +2279,6 @@
                     new Specialization[] {
                     new Specialization(GlobalFunctions.PARSEINT_Z),
                     new Specialization(GlobalFunctions.PARSEINT_I),
-                    new Specialization(GlobalFunctions.PARSEINT_J),
                     new Specialization(GlobalFunctions.PARSEINT_OI),
                     new Specialization(GlobalFunctions.PARSEINT_O) });
         this.parseFloat = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArguments.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArguments.java	Thu Dec 17 20:26:31 2015 -0800
@@ -128,12 +128,6 @@
     }
 
     @Override
-    public boolean delete(final long key, final boolean strict) {
-        final int index = ArrayIndex.getArrayIndex(key);
-        return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
-    }
-
-    @Override
     public boolean delete(final double key, final boolean strict) {
         final int index = ArrayIndex.getArrayIndex(key);
         return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java	Thu Dec 17 20:26:31 2015 -0800
@@ -100,20 +100,38 @@
     }
 
     NativeArray(final long length) {
-        // TODO assert valid index in long before casting
-        this(ArrayData.allocate((int)length));
+        this(ArrayData.allocate(length));
     }
 
     NativeArray(final int[] array) {
         this(ArrayData.allocate(array));
     }
 
-    NativeArray(final long[] array) {
+    NativeArray(final double[] array) {
         this(ArrayData.allocate(array));
     }
 
-    NativeArray(final double[] array) {
-        this(ArrayData.allocate(array));
+    NativeArray(final long[] array) {
+        this(ArrayData.allocate(array.length));
+
+        ArrayData arrayData = this.getArray();
+        Class<?> widest = int.class;
+
+        for (int index = 0; index < array.length; index++) {
+            final long value = array[index];
+
+            if (widest == int.class && JSType.isRepresentableAsInt(value)) {
+                arrayData = arrayData.set(index, (int) value, false);
+            } else if (widest != Object.class && JSType.isRepresentableAsDouble(value)) {
+                arrayData = arrayData.set(index, (double) value, false);
+                widest = double.class;
+            } else {
+                arrayData = arrayData.set(index, (Object) value, false);
+                widest = Object.class;
+            }
+        }
+
+        this.setArray(arrayData);
     }
 
     NativeArray(final Object[] array) {
@@ -179,7 +197,7 @@
                 @Override
                 public MethodHandle call() {
                     return Bootstrap.createDynamicCallInvoker(rtype, Object.class, Object.class, Object.class,
-                        long.class, Object.class);
+                        double.class, Object.class);
                 }
             });
     }
@@ -210,7 +228,7 @@
                     @Override
                     public MethodHandle call() {
                         return Bootstrap.createDynamicCallInvoker(Object.class, Object.class,
-                             Undefined.class, Object.class, Object.class, long.class, Object.class);
+                             Undefined.class, Object.class, Object.class, double.class, Object.class);
                     }
                 });
     }
@@ -246,8 +264,9 @@
 
     @Override
     public Object getLength() {
-        final long length = JSType.toUint32(getArray().length());
-        if (length < Integer.MAX_VALUE) {
+        final long length = getArray().length();
+        assert length >= 0L;
+        if (length <= Integer.MAX_VALUE) {
             return (int)length;
         }
         return length;
@@ -445,7 +464,13 @@
     @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
     public static Object length(final Object self) {
         if (isArray(self)) {
-            return JSType.toUint32(((ScriptObject) self).getArray().length());
+            final long length = ((ScriptObject) self).getArray().length();
+            assert length >= 0L;
+            // Cast to the narrowest supported numeric type to help optimistic type calculator
+            if (length <= Integer.MAX_VALUE) {
+                return (int) length;
+            }
+            return (double) length;
         }
 
         return 0;
@@ -1553,7 +1578,7 @@
             private final MethodHandle everyInvoker = getEVERY_CALLBACK_INVOKER();
 
             @Override
-            protected boolean forEach(final Object val, final long i) throws Throwable {
+            protected boolean forEach(final Object val, final double i) throws Throwable {
                 return result = (boolean)everyInvoker.invokeExact(callbackfn, thisArg, val, i, self);
             }
         }.apply();
@@ -1573,7 +1598,7 @@
             private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER();
 
             @Override
-            protected boolean forEach(final Object val, final long i) throws Throwable {
+            protected boolean forEach(final Object val, final double i) throws Throwable {
                 return !(result = (boolean)someInvoker.invokeExact(callbackfn, thisArg, val, i, self));
             }
         }.apply();
@@ -1593,7 +1618,7 @@
             private final MethodHandle forEachInvoker = getFOREACH_CALLBACK_INVOKER();
 
             @Override
-            protected boolean forEach(final Object val, final long i) throws Throwable {
+            protected boolean forEach(final Object val, final double i) throws Throwable {
                 forEachInvoker.invokeExact(callbackfn, thisArg, val, i, self);
                 return true;
             }
@@ -1614,7 +1639,7 @@
             private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER();
 
             @Override
-            protected boolean forEach(final Object val, final long i) throws Throwable {
+            protected boolean forEach(final Object val, final double i) throws Throwable {
                 final Object r = mapInvoker.invokeExact(callbackfn, thisArg, val, i, self);
                 result.defineOwnProperty(ArrayIndex.getArrayIndex(index), r);
                 return true;
@@ -1644,7 +1669,7 @@
             private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER();
 
             @Override
-            protected boolean forEach(final Object val, final long i) throws Throwable {
+            protected boolean forEach(final Object val, final double i) throws Throwable {
                 if ((boolean)filterInvoker.invokeExact(callbackfn, thisArg, val, i, self)) {
                     result.defineOwnProperty(ArrayIndex.getArrayIndex(to++), val);
                 }
@@ -1676,7 +1701,7 @@
             private final MethodHandle reduceInvoker = getREDUCE_CALLBACK_INVOKER();
 
             @Override
-            protected boolean forEach(final Object val, final long i) throws Throwable {
+            protected boolean forEach(final Object val, final double i) throws Throwable {
                 // TODO: why can't I declare the second arg as Undefined.class?
                 result = reduceInvoker.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self);
                 return true;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java	Thu Dec 17 20:26:31 2015 -0800
@@ -124,7 +124,7 @@
 
         @Override
         public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
-            if (returnType == int.class || returnType == long.class) {
+            if (returnType == int.class) {
                 return null;
             }
             return getContinuousElementGetter(getClass(), GET_ELEM, returnType, programPoint);
@@ -136,11 +136,6 @@
         }
 
         @Override
-        public long getLong(final int index) {
-            return (long)getDouble(index);
-        }
-
-        @Override
         public double getDouble(final int index) {
             return getElem(index);
         }
@@ -166,11 +161,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return set(index, (double)value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             setElem(index, value);
             return this;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java	Thu Dec 17 20:26:31 2015 -0800
@@ -124,7 +124,7 @@
 
         @Override
         public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
-            if (returnType == int.class || returnType == long.class) {
+            if (returnType == int.class) {
                 return null;
             }
             return getContinuousElementGetter(getClass(), GET_ELEM, returnType, programPoint);
@@ -136,11 +136,6 @@
         }
 
         @Override
-        public long getLong(final int index) {
-            return (long)getDouble(index);
-        }
-
-        @Override
         public double getDouble(final int index) {
             return getElem(index);
         }
@@ -166,11 +161,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return set(index, (double)value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             setElem(index, value);
             return this;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFunction.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFunction.java	Thu Dec 17 20:26:31 2015 -0800
@@ -97,7 +97,6 @@
     @Function(attributes = Attribute.NOT_ENUMERABLE)
     public static Object apply(final Object self, final Object thiz, final Object array) {
         checkCallable(self);
-
         final Object[] args = toApplyArgs(array);
 
         if (self instanceof ScriptFunction) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java	Thu Dec 17 20:26:31 2015 -0800
@@ -134,16 +134,6 @@
         }
 
         @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);
         }
@@ -170,11 +160,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return set(index, (int)value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             return set(index, (int)value, strict);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java	Thu Dec 17 20:26:31 2015 -0800
@@ -133,16 +133,6 @@
         }
 
         @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);
         }
@@ -169,11 +159,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return set(index, (int)value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             return set(index, (int)value, strict);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java	Thu Dec 17 20:26:31 2015 -0800
@@ -132,16 +132,6 @@
         }
 
         @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);
         }
@@ -168,11 +158,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return set(index, (int)value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             return set(index, (int)value, strict);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java	Thu Dec 17 20:26:31 2015 -0800
@@ -185,36 +185,11 @@
     }
 
     @Override
-    public int getInt(final long key, final int programPoint) {
-        return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
-    }
-
-    @Override
     public int getInt(final int key, final int programPoint) {
         return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
     }
 
     @Override
-    public long getLong(final Object key, final int programPoint) {
-        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
-    }
-
-    @Override
-    public long getLong(final double key, final int programPoint) {
-        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
-    }
-
-    @Override
-    public long getLong(final long key, final int programPoint) {
-        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
-    }
-
-    @Override
-    public long getLong(final int key, final int programPoint) {
-        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
-    }
-
-    @Override
     public double getDouble(final Object key, final int programPoint) {
         return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
     }
@@ -225,11 +200,6 @@
     }
 
     @Override
-    public double getDouble(final long key, final int programPoint) {
-        return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
-    }
-
-    @Override
     public double getDouble(final int key, final int programPoint) {
         return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
     }
@@ -245,11 +215,6 @@
     }
 
     @Override
-    public Object get(final long key) {
-        return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
-    }
-
-    @Override
     public Object get(final int key) {
         return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
     }
@@ -264,15 +229,6 @@
     }
 
     @Override
-    public void set(final Object key, final long value, final int flags) {
-        if (overrides && super.hasOwnProperty(key)) {
-            super.set(key, value, flags);
-        } else {
-            callAdaptee(__put__, key, value, flags);
-        }
-    }
-
-    @Override
     public void set(final Object key, final double value, final int flags) {
         if (overrides && super.hasOwnProperty(key)) {
             super.set(key, value, flags);
@@ -300,15 +256,6 @@
     }
 
     @Override
-    public void set(final double key, final long value, final int flags) {
-        if (overrides && super.hasOwnProperty(key)) {
-            super.set(key, value, flags);
-        } else {
-            callAdaptee(__put__, key, value, flags);
-        }
-    }
-
-    @Override
     public void set(final double key, final double value, final int flags) {
         if (overrides && super.hasOwnProperty(key)) {
             super.set(key, value, flags);
@@ -327,42 +274,6 @@
     }
 
     @Override
-    public void set(final long key, final int value, final int flags) {
-        if (overrides && super.hasOwnProperty(key)) {
-            super.set(key, value, flags);
-        } else {
-            callAdaptee(__put__, key, value, flags);
-        }
-    }
-
-    @Override
-    public void set(final long key, final long value, final int flags) {
-        if (overrides && super.hasOwnProperty(key)) {
-            super.set(key, value, flags);
-        } else {
-            callAdaptee(__put__, key, value, flags);
-        }
-    }
-
-    @Override
-    public void set(final long key, final double value, final int flags) {
-        if (overrides && super.hasOwnProperty(key)) {
-            super.set(key, value, flags);
-        } else {
-            callAdaptee(__put__, key, value, flags);
-        }
-    }
-
-    @Override
-    public void set(final long key, final Object value, final int flags) {
-        if (overrides && super.hasOwnProperty(key)) {
-            super.set(key, value, flags);
-        } else {
-            callAdaptee(__put__, key, value, flags);
-        }
-    }
-
-    @Override
     public void set(final int key, final int value, final int flags) {
         if (overrides && super.hasOwnProperty(key)) {
             super.set(key, value, flags);
@@ -372,15 +283,6 @@
     }
 
     @Override
-    public void set(final int key, final long value, final int flags) {
-        if (overrides && super.hasOwnProperty(key)) {
-            super.set(key, value, flags);
-        } else {
-            callAdaptee(__put__, key, value, flags);
-        }
-    }
-
-    @Override
     public void set(final int key, final double value, final int flags) {
         if (overrides && super.hasOwnProperty(key)) {
             super.set(key, value, flags);
@@ -417,15 +319,6 @@
     }
 
     @Override
-    public boolean has(final long key) {
-        if (overrides && super.hasOwnProperty(key)) {
-            return true;
-        }
-
-        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
-    }
-
-    @Override
     public boolean has(final double key) {
         if (overrides && super.hasOwnProperty(key)) {
             return true;
@@ -444,15 +337,6 @@
     }
 
     @Override
-    public boolean delete(final long key, final boolean strict) {
-        if (overrides && super.hasOwnProperty(key)) {
-            return super.delete(key, strict);
-        }
-
-        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
-    }
-
-    @Override
     public boolean delete(final double key, final boolean strict) {
         if (overrides && super.hasOwnProperty(key)) {
             return super.delete(key, strict);
@@ -669,10 +553,6 @@
         return JSType.toNumberMaybeOptimistic(callAdaptee(name, args), programPoint);
     }
 
-    private long callAdapteeLong(final int programPoint, final String name, final Object... args) {
-        return JSType.toLongMaybeOptimistic(callAdaptee(name, args), programPoint);
-    }
-
     private int callAdapteeInt(final int programPoint, final String name, final Object... args) {
         return JSType.toInt32MaybeOptimistic(callAdaptee(name, args), programPoint);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeNumber.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeNumber.java	Thu Dec 17 20:26:31 2015 -0800
@@ -33,8 +33,6 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
-import java.math.RoundingMode;
-import java.text.NumberFormat;
 import java.util.Locale;
 import jdk.dynalink.linker.GuardedInvocation;
 import jdk.dynalink.linker.LinkRequest;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java	Thu Dec 17 20:26:31 2015 -0800
@@ -148,7 +148,8 @@
      * @param buf external buffer - should be a nio ByteBuffer
      * @return the 'obj' object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "sets ByteBuffer to hold indexed data (nashorn extension)")
     public static ScriptObject setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
         Global.checkObject(obj);
         final ScriptObject sobj = (ScriptObject)obj;
@@ -168,7 +169,8 @@
      * @param  obj object to get prototype from
      * @return the prototype of an object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "returns the prototype of the specified object")
     public static Object getPrototypeOf(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).getProto();
@@ -195,7 +197,8 @@
      * @param  proto prototype object to be used
      * @return object whose prototype is set
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "sets the prototype of the given object (ES6)")
     public static Object setPrototypeOf(final Object self, final Object obj, final Object proto) {
         if (obj instanceof ScriptObject) {
             ((ScriptObject)obj).setPrototypeOf(proto);
@@ -216,7 +219,8 @@
      * @param prop  property descriptor
      * @return property descriptor
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "returns a property descriptor for an own property (not inherited property)")
     public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) {
         if (obj instanceof ScriptObject) {
             final String       key  = JSType.toString(prop);
@@ -240,7 +244,8 @@
      * @param obj  object to query for property names
      * @return array of property names
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "returns an array of all properties (enumerable or not) found directly on the given object")
     public static ScriptObject getOwnPropertyNames(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
@@ -258,7 +263,8 @@
      * @param obj  object to query for property names
      * @return array of property names
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "returns an array of all symbol properties found directly on the given object (ES6)")
     public static ScriptObject getOwnPropertySymbols(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return new NativeArray(((ScriptObject)obj).getOwnSymbols(true));
@@ -276,7 +282,8 @@
      * @param props properties to define
      * @return object created
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "creates a new object with the specified prototype object and properties")
     public static ScriptObject create(final Object self, final Object proto, final Object props) {
         if (proto != null) {
             Global.checkObject(proto);
@@ -302,7 +309,8 @@
      * @param attr attributes for property descriptor
      * @return object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "adds an own property and/or update the attributes of an existing own property of an object")
     public static ScriptObject defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
         final ScriptObject sobj = Global.checkObject(obj);
         sobj.defineOwnProperty(JSType.toPropertyKey(prop), attr, true);
@@ -317,7 +325,8 @@
      * @param props properties
      * @return object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "defines new or modifies existing properties directly on the given object")
     public static ScriptObject defineProperties(final Object self, final Object obj, final Object props) {
         final ScriptObject sobj     = Global.checkObject(obj);
         final Object       propsObj = Global.toObject(props);
@@ -339,7 +348,8 @@
      * @param obj  object to seal
      * @return sealed object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "prevents new properties from being added to the given object and marks existing properties as non-configurable")
     public static Object seal(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).seal();
@@ -358,7 +368,8 @@
      * @param obj object to freeze
      * @return frozen object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "prevents new properties from being added to the given object and prevents existing properties from being removed or re-configured")
     public static Object freeze(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).freeze();
@@ -376,7 +387,8 @@
      * @param obj  object, for which to set the internal extensible property to false
      * @return object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "prevents new properties from ever being added to the given object")
     public static Object preventExtensions(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).preventExtensions();
@@ -394,7 +406,8 @@
      * @param obj check whether an object is sealed
      * @return true if sealed, false otherwise
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "tells if an object is sealed or not")
     public static boolean isSealed(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).isSealed();
@@ -412,7 +425,8 @@
      * @param obj check whether an object
      * @return true if object is frozen, false otherwise
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "tells if an object is fronzen or not")
     public static boolean isFrozen(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).isFrozen();
@@ -430,7 +444,8 @@
      * @param obj check whether an object is extensible
      * @return true if object is extensible, false otherwise
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "tells if an object is extensible or not")
     public static boolean isExtensible(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).isExtensible();
@@ -448,7 +463,8 @@
      * @param obj  object from which to extract keys
      * @return array of keys in object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "returns an array of the given object's own enumerable properties")
     public static ScriptObject keys(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             final ScriptObject sobj = (ScriptObject)obj;
@@ -471,7 +487,7 @@
      * @param value  value of object to be instantiated
      * @return the new NativeObject
      */
-    @Constructor
+    @Constructor(documentation = "creates a new script object or converts given value as a script object")
     public static Object construct(final boolean newObj, final Object self, final Object value) {
         final JSType type = JSType.ofNoFunction(value);
 
@@ -505,7 +521,8 @@
      * @param self self reference
      * @return ToString of object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    @Function(attributes = Attribute.NOT_ENUMERABLE,
+        documentation = "returns a string representing of this object")
     public static String toString(final Object self) {
         return ScriptRuntime.builtinObjectToString(self);
     }
@@ -558,7 +575,8 @@
      * @param v property to check for
      * @return true if property exists in object
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    @Function(attributes = Attribute.NOT_ENUMERABLE,
+        documentation = "tells whether this object has the specified property or not")
     public static boolean hasOwnProperty(final Object self, final Object v) {
         // Convert ScriptObjects to primitive with String.class hint
         // but no need to convert other primitives to string.
@@ -575,7 +593,8 @@
      * @param v v prototype object to check against
      * @return true if object is prototype of v
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    @Function(attributes = Attribute.NOT_ENUMERABLE,
+        documentation = "tests for this object in another object's prototype chain")
     public static boolean isPrototypeOf(final Object self, final Object v) {
         if (!(v instanceof ScriptObject)) {
             return false;
@@ -601,7 +620,8 @@
      * @param v property to check if enumerable
      * @return true if property is enumerable
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    @Function(attributes = Attribute.NOT_ENUMERABLE,
+        documentation = "tells whether the given property is enumerable or not")
     public static boolean propertyIsEnumerable(final Object self, final Object v) {
         final String str = JSType.toString(v);
         final Object obj = Global.toObject(self);
@@ -676,7 +696,8 @@
      * @param source the source object whose properties are bound to the target
      * @return the target object after property binding
      */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
+        documentation = "binds the source object's properties to the target object (nashorn extension)")
     public static Object bindProperties(final Object self, final Object target, final Object source) {
         // target object has to be a ScriptObject
         final ScriptObject targetObj = Global.checkObject(target);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java	Thu Dec 17 20:26:31 2015 -0800
@@ -210,14 +210,6 @@
     }
 
     @Override
-    public Object get(final long key) {
-        if (key >= 0 && key < value.length()) {
-            return String.valueOf(value.charAt((int)key));
-        }
-        return super.get(key);
-    }
-
-    @Override
     public Object get(final int key) {
         if (key >= 0 && key < value.length()) {
             return String.valueOf(value.charAt(key));
@@ -236,36 +228,11 @@
     }
 
     @Override
-    public int getInt(final long key, final int programPoint) {
-        return JSType.toInt32MaybeOptimistic(get(key), programPoint);
-    }
-
-    @Override
     public int getInt(final int key, final int programPoint) {
         return JSType.toInt32MaybeOptimistic(get(key), programPoint);
     }
 
     @Override
-    public long getLong(final Object key, final int programPoint) {
-        return JSType.toLongMaybeOptimistic(get(key), programPoint);
-    }
-
-    @Override
-    public long getLong(final double key, final int programPoint) {
-        return JSType.toLongMaybeOptimistic(get(key), programPoint);
-    }
-
-    @Override
-    public long getLong(final long key, final int programPoint) {
-        return JSType.toLongMaybeOptimistic(get(key), programPoint);
-    }
-
-    @Override
-    public long getLong(final int key, final int programPoint) {
-        return JSType.toLongMaybeOptimistic(get(key), programPoint);
-    }
-
-    @Override
     public double getDouble(final Object key, final int programPoint) {
         return JSType.toNumberMaybeOptimistic(get(key), programPoint);
     }
@@ -276,11 +243,6 @@
     }
 
     @Override
-    public double getDouble(final long key, final int programPoint) {
-        return JSType.toNumberMaybeOptimistic(get(key), programPoint);
-    }
-
-    @Override
     public double getDouble(final int key, final int programPoint) {
         return JSType.toNumberMaybeOptimistic(get(key), programPoint);
     }
@@ -298,12 +260,6 @@
     }
 
     @Override
-    public boolean has(final long key) {
-        final int index = ArrayIndex.getArrayIndex(key);
-        return isValidStringIndex(index) || super.has(key);
-    }
-
-    @Override
     public boolean has(final double key) {
         final int index = ArrayIndex.getArrayIndex(key);
         return isValidStringIndex(index) || super.has(key);
@@ -322,12 +278,6 @@
     }
 
     @Override
-    public boolean hasOwnProperty(final long key) {
-        final int index = ArrayIndex.getArrayIndex(key);
-        return isValidStringIndex(index) || super.hasOwnProperty(key);
-    }
-
-    @Override
     public boolean hasOwnProperty(final double key) {
         final int index = ArrayIndex.getArrayIndex(key);
         return isValidStringIndex(index) || super.hasOwnProperty(key);
@@ -339,12 +289,6 @@
     }
 
     @Override
-    public boolean delete(final long key, final boolean strict) {
-        final int index = ArrayIndex.getArrayIndex(key);
-        return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
-    }
-
-    @Override
     public boolean delete(final double key, final boolean strict) {
         final int index = ArrayIndex.getArrayIndex(key);
         return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java	Thu Dec 17 20:26:31 2015 -0800
@@ -138,16 +138,6 @@
         }
 
         @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);
         }
@@ -174,11 +164,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return set(index, (int)value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             return set(index, (int)value, strict);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java	Thu Dec 17 20:26:31 2015 -0800
@@ -32,6 +32,7 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.IntBuffer;
+import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -41,6 +42,7 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
 
@@ -78,7 +80,7 @@
 
     private static final class Uint32ArrayData extends TypedArrayData<IntBuffer> {
 
-        private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint32ArrayData.class, "getElem", long.class, int.class).methodHandle();
+        private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint32ArrayData.class, "getElem", double.class, int.class).methodHandle();
         private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint32ArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
 
         private Uint32ArrayData(final IntBuffer nb, final int start, final int end) {
@@ -103,14 +105,18 @@
             return getContinuousElementGetter(getClass(), GET_ELEM, returnType, programPoint);
         }
 
-        private long getElem(final int index) {
+        private int getRawElem(final int index) {
             try {
-                return JSType.toUint32(nb.get(index));
+                return nb.get(index);
             } catch (final IndexOutOfBoundsException e) {
                 throw new ClassCastException(); //force relink - this works for unoptimistic too
             }
         }
 
+        private double getElem(final int index) {
+            return JSType.toUint32(getRawElem(index));
+        }
+
         private void setElem(final int index, final int elem) {
             try {
                 if (index < nb.limit()) {
@@ -128,42 +134,37 @@
 
         @Override
         public Class<?> getElementType() {
-            return long.class;
+            return double.class;
         }
 
         @Override
         public Class<?> getBoxedElementType() {
-            return Integer.class;
+            return Double.class;
         }
 
         @Override
         public int getInt(final int index) {
-            return (int)getLong(index);
+            return getRawElem(index);
         }
 
         @Override
-        public long getLong(final int index) {
+        public int getIntOptimistic(final int index, final int programPoint) {
+            return JSType.toUint32Optimistic(getRawElem(index), programPoint);
+        }
+
+        @Override
+        public double getDouble(final int index) {
             return getElem(index);
         }
 
         @Override
-        public long getLongOptimistic(final int index, final int programPoint) {
+        public double getDoubleOptimistic(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);
+            return getElem(index);
         }
 
         @Override
@@ -178,11 +179,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return set(index, (int)value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             return set(index, (int)value, strict);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java	Thu Dec 17 20:26:31 2015 -0800
@@ -138,16 +138,6 @@
         }
 
         @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);
         }
@@ -174,11 +164,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return set(index, (int)value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             return set(index, (int)value, strict);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Thu Dec 17 20:26:31 2015 -0800
@@ -168,16 +168,6 @@
         }
 
         @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);
         }
@@ -204,11 +194,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return set(index, (int)value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             return set(index, rint(value), strict);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/annotations/Constructor.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/annotations/Constructor.java	Thu Dec 17 20:26:31 2015 -0800
@@ -48,4 +48,9 @@
      *         arity.
      */
     public int arity() default -2;
+
+    /**
+     * @return the documentation string for this constructor.
+     */
+    public String documentation() default "";
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/annotations/Function.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/annotations/Function.java	Thu Dec 17 20:26:31 2015 -0800
@@ -60,4 +60,9 @@
      * @return where this function lives.
      */
     public Where where() default Where.PROTOTYPE;
+
+    /**
+     * @return return the documentation string for this function.
+     */
+    public String documentation() default "";
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/JSONParser.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/JSONParser.java	Thu Dec 17 20:26:31 2015 -0800
@@ -293,8 +293,6 @@
     private static Class<?> getType(final Object value) {
         if (value instanceof Integer) {
             return int.class;
-        } else if (value instanceof Long) {
-            return long.class;
         } else if (value instanceof Double) {
             return double.class;
         } else {
@@ -477,8 +475,6 @@
         final double d = Double.parseDouble(source.substring(start, pos));
         if (JSType.isRepresentableAsInt(d)) {
             return (int) d;
-        } else if (JSType.isRepresentableAsLong(d)) {
-            return (long) d;
         }
         return d;
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Lexer.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Lexer.java	Thu Dec 17 20:26:31 2015 -0800
@@ -1131,11 +1131,7 @@
      */
     private static Number valueOf(final String valueString, final int radix) throws NumberFormatException {
         try {
-            final long value = Long.parseLong(valueString, radix);
-            if(value >= MIN_INT_L && value <= MAX_INT_L) {
-                return (int)value;
-            }
-            return value;
+            return Integer.parseInt(valueString, radix);
         } catch (final NumberFormatException e) {
             if (radix == 10) {
                 return Double.valueOf(valueString);
@@ -1782,8 +1778,6 @@
             //yet we don't want e.g. 1e6 to be a double unnecessarily
             if (JSType.isStrictlyRepresentableAsInt(value)) {
                 return (int)value;
-            } else if (JSType.isStrictlyRepresentableAsLong(value)) {
-                return (long)value;
             }
             return value;
         case STRING:
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java	Thu Dec 17 20:26:31 2015 -0800
@@ -221,7 +221,7 @@
 
         assert setterType == null || setterType == getterType;
 
-        if (getterType == int.class || getterType == long.class) {
+        if (getterType == int.class) {
             primitiveGetter = MH.asType(getter, Lookup.GET_PRIMITIVE_TYPE);
             primitiveSetter = setter == null ? null : MH.asType(setter, Lookup.SET_PRIMITIVE_TYPE);
         } else if (getterType == double.class) {
@@ -400,17 +400,6 @@
         }
      }
 
-    @Override
-    public long getLongValue(final ScriptObject self, final ScriptObject owner) {
-        try {
-            return (long)getGetter(long.class).invokeExact((Object)self);
-        } catch (final Error | RuntimeException e) {
-            throw e;
-        } catch (final Throwable e) {
-            throw new RuntimeException(e);
-        }
-    }
-
      @Override
      public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
         try {
@@ -453,21 +442,6 @@
      * @param self  owner
      * @param value value
      */
-    protected final void invokeSetter(final ScriptObject self, final long value) {
-        try {
-            getSetter(long.class, self.getMap()).invokeExact((Object)self, value);
-        } catch (final Error | RuntimeException e) {
-            throw e;
-        } catch (final Throwable e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Invoke setter for this property with a value
-     * @param self  owner
-     * @param value value
-     */
     protected final void invokeSetter(final ScriptObject self, final double value) {
         try {
             getSetter(double.class, self.getMap()).invokeExact((Object)self, value);
@@ -500,12 +474,6 @@
     }
 
     @Override
-    public void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict)  {
-        assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
-        invokeSetter(self, value);
-    }
-
-    @Override
     public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict)  {
         assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
         invokeSetter(self, value);
@@ -533,7 +501,6 @@
         final int i = getAccessorTypeIndex(type);
 
         assert type == int.class ||
-                type == long.class ||
                 type == double.class ||
                 type == Object.class :
                 "invalid getter type " + type + " for " + getKey();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/DebuggerSupport.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/DebuggerSupport.java	Thu Dec 17 20:26:31 2015 -0800
@@ -239,7 +239,7 @@
 
         if (ScriptObject.isArray(object)) {
             sb.append('[');
-            final long length = object.getLong("length", INVALID_PROGRAM_POINT);
+            final long length = (long) object.getDouble("length", INVALID_PROGRAM_POINT);
 
             for (long i = 0; i < length; i++) {
                 if (object.has(i)) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java	Thu Dec 17 20:26:31 2015 -0800
@@ -44,36 +44,11 @@
     }
 
     @Override
-    public int getInt(final long key, final int programPoint) {
-        return getInt(JSType.toObject(key), programPoint);
-    }
-
-    @Override
     public int getInt(final int key, final int programPoint) {
         return getInt(JSType.toObject(key), programPoint);
     }
 
     @Override
-    public long getLong(final Object key, final int programPoint) {
-        return JSType.toLong(get(key));
-    }
-
-    @Override
-    public long getLong(final double key, final int programPoint) {
-        return getLong(JSType.toObject(key), programPoint);
-    }
-
-    @Override
-    public long getLong(final long key, final int programPoint) {
-        return getLong(JSType.toObject(key), programPoint);
-    }
-
-    @Override
-    public long getLong(final int key, final int programPoint) {
-        return getLong(JSType.toObject(key), programPoint);
-    }
-
-    @Override
     public double getDouble(final Object key, final int programPoint) {
         return JSType.toNumber(get(key));
     }
@@ -84,11 +59,6 @@
     }
 
     @Override
-    public double getDouble(final long key, final int programPoint) {
-        return getDouble(JSType.toObject(key), programPoint);
-    }
-
-    @Override
     public double getDouble(final int key, final int programPoint) {
         return getDouble(JSType.toObject(key), programPoint);
     }
@@ -102,11 +72,6 @@
     }
 
     @Override
-    public Object get(final long key) {
-        return get(JSType.toObject(key));
-    }
-
-    @Override
     public Object get(final int key) {
         return get(JSType.toObject(key));
     }
@@ -117,11 +82,6 @@
     }
 
     @Override
-    public void set(final double key, final long value, final int flags) {
-        set(JSType.toObject(key), JSType.toObject(value), flags);
-    }
-
-    @Override
     public void set(final double key, final double value, final int flags) {
         set(JSType.toObject(key), JSType.toObject(value), flags);
     }
@@ -132,36 +92,11 @@
     }
 
     @Override
-    public void set(final long key, final int value, final int flags) {
-        set(JSType.toObject(key), JSType.toObject(value), flags);
-    }
-
-    @Override
-    public void set(final long key, final long value, final int flags) {
-        set(JSType.toObject(key), JSType.toObject(value), flags);
-    }
-
-    @Override
-    public void set(final long key, final double value, final int flags) {
-        set(JSType.toObject(key), JSType.toObject(value), flags);
-    }
-
-    @Override
-    public void set(final long key, final Object value, final int flags) {
-        set(JSType.toObject(key), value, flags);
-    }
-
-    @Override
     public void set(final int key, final int value, final int flags) {
         set(JSType.toObject(key), JSType.toObject(value), flags);
     }
 
     @Override
-    public void set(final int key, final long value, final int flags) {
-        set(JSType.toObject(key), JSType.toObject(value), flags);
-    }
-
-    @Override
     public void set(final int key, final double value, final int flags) {
         set(JSType.toObject(key), JSType.toObject(value), flags);
     }
@@ -177,11 +112,6 @@
     }
 
     @Override
-    public void set(final Object key, final long value, final int flags) {
-        set(key, JSType.toObject(value), flags);
-    }
-
-    @Override
     public void set(final Object key, final double value, final int flags) {
         set(key, JSType.toObject(value), flags);
     }
@@ -198,11 +128,6 @@
     }
 
     @Override
-    public boolean has(final long key) {
-        return has(JSType.toObject(key));
-    }
-
-    @Override
     public boolean has(final double key) {
         return has(JSType.toObject(key));
     }
@@ -213,11 +138,6 @@
     }
 
     @Override
-    public boolean hasOwnProperty(final long key) {
-        return hasOwnProperty(JSType.toObject(key));
-    }
-
-    @Override
     public boolean hasOwnProperty(final double key) {
         return hasOwnProperty(JSType.toObject(key));
     }
@@ -231,11 +151,6 @@
     }
 
     @Override
-    public boolean delete(final long key, final boolean strict) {
-        return delete(JSType.toObject(key), strict);
-    }
-
-    @Override
     public boolean delete(final double key, final boolean strict) {
         return delete(JSType.toObject(key), strict);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Thu Dec 17 20:26:31 2015 -0800
@@ -89,11 +89,16 @@
     }
 
     @Override
-    CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
+    CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden, boolean linkLogicOkay) {
         assert isValidCallSite(callSiteType) : callSiteType;
 
         CompiledFunction best = null;
         for (final CompiledFunction candidate: code) {
+            if (!linkLogicOkay && candidate.hasLinkLogic()) {
+                // Skip! Version with no link logic is desired, but this one has link logic!
+                continue;
+            }
+
             if (!forbidden.contains(candidate) && candidate.betterThanFinal(best, callSiteType)) {
                 best = candidate;
             }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FindProperty.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FindProperty.java	Thu Dec 17 20:26:31 2015 -0800
@@ -218,13 +218,6 @@
      * Get the property value from self as object.
      * @return the property value
      */
-    public long getLongValue() {
-        return property.getLongValue(getGetterReceiver(), getOwner());
-    }
-    /**
-     * Get the property value from self as object.
-     * @return the property value
-     */
     public double getDoubleValue() {
         return property.getDoubleValue(getGetterReceiver(), getOwner());
     }
@@ -252,16 +245,6 @@
      * @param value the new value
      * @param strict strict flag
      */
-    public void setValue(final long value, final boolean strict) {
-        property.setValue(getSetterReceiver(), getOwner(), value, strict);
-    }
-
-    /**
-     * Set the property value in self.
-     *
-     * @param value the new value
-     * @param strict strict flag
-     */
     public void setValue(final double value, final boolean strict) {
         property.setValue(getSetterReceiver(), getOwner(), value, strict);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/GlobalFunctions.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/GlobalFunctions.java	Thu Dec 17 20:26:31 2015 -0800
@@ -48,9 +48,6 @@
     /** ParseInt - identity for ints */
     public static final MethodHandle PARSEINT_I = MH.dropArguments(MH.identity(int.class), 0, Object.class);
 
-    /** ParseInt - identity for longs */
-    public static final MethodHandle PARSEINT_J = MH.dropArguments(MH.identity(long.class), 0, Object.class);
-
     /** Methodhandle (specialized) to implementation of ECMA 15.1.2.2, parseInt */
     public static final MethodHandle PARSEINT_O = findOwnMH("parseInt", double.class, Object.class, Object.class);
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java	Thu Dec 17 20:26:31 2015 -0800
@@ -119,14 +119,14 @@
     public static final Call TO_INT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, double.class);
 
     /** JavaScript compliant conversion function from int to uint32 */
-    public static final Call TO_UINT32_I = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, int.class);
+    public static final Call TO_UINT32_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Optimistic", int.class, int.class, int.class);
+
+    /** JavaScript compliant conversion function from int to uint32 */
+    public static final Call TO_UINT32_DOUBLE = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Double", double.class, int.class);
 
     /** JavaScript compliant conversion function from Object to uint32 */
     public static final Call TO_UINT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, Object.class);
 
-    /** JavaScript compliant conversion function from Object to long with type check */
-    public static final Call TO_LONG_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toLongOptimistic", long.class, Object.class, int.class);
-
     /** JavaScript compliant conversion function from number to uint32 */
     public static final Call TO_UINT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, double.class);
 
@@ -172,36 +172,6 @@
     /** Negate exact exact wrapper for potentially overflowing integer operations */
     public static final Call NEGATE_EXACT         = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", int.class, int.class, int.class);
 
-    /** Add exact wrapper for potentially overflowing long operations */
-    public static final Call ADD_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "addExact", long.class, long.class, long.class, int.class);
-
-    /** Sub exact wrapper for potentially overflowing long operations */
-    public static final Call SUB_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "subExact", long.class, long.class, long.class, int.class);
-
-    /** Multiply exact wrapper for potentially overflowing long operations */
-    public static final Call MUL_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "mulExact", long.class, long.class, long.class, int.class);
-
-    /** Div exact wrapper for potentially integer division that turns into float point */
-    public static final Call DIV_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", long.class, long.class, long.class, int.class);
-
-    /** Div zero wrapper for long division that handles (0/0) &gt;&gt;&gt; 0 == 0 */
-    public static final Call DIV_ZERO_LONG        = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", long.class, long.class, long.class);
-
-    /** Mod zero wrapper for long division that handles (0%0) &gt;&gt;&gt; 0 == 0 */
-    public static final Call REM_ZERO_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", long.class, long.class, long.class);
-
-    /** Mod exact wrapper for potentially integer remainders that turns into float point */
-    public static final Call REM_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "remExact", long.class, long.class, long.class, int.class);
-
-    /** Decrement exact wrapper for potentially overflowing long operations */
-    public static final Call DECREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "decrementExact",  long.class, long.class, int.class);
-
-    /** Increment exact wrapper for potentially overflowing long operations */
-    public static final Call INCREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact",  long.class, long.class, int.class);
-
-    /** Negate exact exact wrapper for potentially overflowing long operations */
-    public static final Call NEGATE_EXACT_LONG    = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact",     long.class, long.class, int.class);
-
     /** Method handle to convert a JS Object to a Java array. */
     public static final Call TO_JAVA_ARRAY = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArray", Object.class, Object.class, Class.class);
 
@@ -215,7 +185,6 @@
     private static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
             Arrays.asList(
                 Type.INT,
-                Type.LONG,
                 Type.NUMBER,
                 Type.OBJECT));
 
@@ -223,17 +192,14 @@
     public static final int TYPE_UNDEFINED_INDEX = -1;
     /** table index for integer type - hard coded so it can be used in switches at compile time */
     public static final int TYPE_INT_INDEX    = 0; //getAccessorTypeIndex(int.class);
-    /** table index for long type - hard coded so it can be used in switches at compile time */
-    public static final int TYPE_LONG_INDEX   = 1; //getAccessorTypeIndex(long.class);
     /** table index for double type - hard coded so it can be used in switches at compile time */
-    public static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class);
+    public static final int TYPE_DOUBLE_INDEX = 1; //getAccessorTypeIndex(double.class);
     /** table index for object type - hard coded so it can be used in switches at compile time */
-    public static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class);
+    public static final int TYPE_OBJECT_INDEX = 2; //getAccessorTypeIndex(Object.class);
 
     /** object conversion quickies with JS semantics - used for return value and parameter filter */
     public static final List<MethodHandle> CONVERT_OBJECT = toUnmodifiableList(
         JSType.TO_INT32.methodHandle(),
-        JSType.TO_UINT32.methodHandle(),
         JSType.TO_NUMBER.methodHandle(),
         null
     );
@@ -244,7 +210,6 @@
      */
     public static final List<MethodHandle> CONVERT_OBJECT_OPTIMISTIC = toUnmodifiableList(
         JSType.TO_INT32_OPTIMISTIC.methodHandle(),
-        JSType.TO_LONG_OPTIMISTIC.methodHandle(),
         JSType.TO_NUMBER_OPTIMISTIC.methodHandle(),
         null
     );
@@ -256,13 +221,16 @@
     /** The value of Undefined cast to a double */
     public static final double UNDEFINED_DOUBLE = Double.NaN;
 
+    // Minimum and maximum range between which every long value can be precisely represented as a double.
+    private static final long MAX_PRECISE_DOUBLE = 1L << 53;
+    private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE;
+
     /**
      * Method handles for getters that return undefined coerced
      * to the appropriate type
      */
     public static final List<MethodHandle> GET_UNDEFINED = toUnmodifiableList(
         MH.constant(int.class, UNDEFINED_INT),
-        MH.constant(long.class, UNDEFINED_LONG),
         MH.constant(double.class, UNDEFINED_DOUBLE),
         MH.constant(Object.class, Undefined.getUndefined())
     );
@@ -428,7 +396,7 @@
 
     /**
      * Returns true if double number can be represented as a long. Note that it returns true for negative
-     * zero. If you need to exclude negative zero, use {@link #isStrictlyRepresentableAsLong(double)}.
+     * zero.
      *
      * @param number a double to inspect
      * @return true for long representable doubles
@@ -438,29 +406,12 @@
     }
 
     /**
-     * Returns true if double number can be represented as a long. Note that it returns false for negative
-     * zero. If you don't need to distinguish negative zero, use {@link #isRepresentableAsLong(double)}.
-     *
-     * @param number a double to inspect
-     *
-     * @return true for long representable doubles
+     * Returns true if long number can be represented as double without loss of precision.
+     * @param number a long number
+     * @return true if the double representation does not lose precision
      */
-    public static boolean isStrictlyRepresentableAsLong(final double number) {
-        return isRepresentableAsLong(number) && isNotNegativeZero(number);
-    }
-
-    /**
-     * Returns true if Object can be represented as a long
-     *
-     * @param obj an object to inspect
-     *
-     * @return true for long representable objects
-     */
-    public static boolean isRepresentableAsLong(final Object obj) {
-        if (obj instanceof Number) {
-            return isRepresentableAsLong(((Number)obj).doubleValue());
-        }
-        return false;
+    public static boolean isRepresentableAsDouble(final long number) {
+        return MAX_PRECISE_DOUBLE >= number && number >= MIN_PRECISE_DOUBLE;
     }
 
     /**
@@ -650,22 +601,6 @@
     }
 
     /**
-     * Check whether a string is representable as a JavaScript number
-     *
-     * @param str  a string
-     *
-     * @return     true if string can be represented as a number
-     */
-    public static boolean isNumber(final String str) {
-        try {
-            Double.parseDouble(str);
-            return true;
-        } catch (final NumberFormatException e) {
-            return false;
-        }
-    }
-
-    /**
      * Returns true if object represents a primitive JavaScript string value.
      * @param obj the object
      * @return true if the object represents a primitive JavaScript string value.
@@ -1033,35 +968,6 @@
     }
 
     /**
-     * Optimistic long conversion - throws UnwarrantedOptimismException if double or Object
-     *
-     * @param obj           object to convert
-     * @param programPoint  program point
-     * @return long
-     */
-    public static long toLongOptimistic(final Object obj, final int programPoint) {
-        if (obj != null) {
-            final Class<?> clz = obj.getClass();
-            if (clz == Long.class || clz == Integer.class) {
-                return ((Number)obj).longValue();
-            }
-        }
-        throw new UnwarrantedOptimismException(obj, programPoint);
-    }
-
-    /**
-     * Object to int conversion that delegates to either {@link #toLong(Object)} or to
-     * {@link #toLongOptimistic(Object, int)} depending on whether the program point is valid or not.
-     * @param obj the object to convert
-     * @param programPoint the program point; can be invalid.
-     * @return the value converted to long
-     * @throws UnwarrantedOptimismException if the value can't be represented as long and the program point is valid.
-     */
-    public static long toLongMaybeOptimistic(final Object obj, final int programPoint) {
-        return UnwarrantedOptimismException.isValid(programPoint) ? toLongOptimistic(obj, programPoint) : toLong(obj);
-    }
-
-    /**
      * JavaScript compliant Object to int32 conversion
      * See ECMA 9.5 ToInt32
      *
@@ -1098,10 +1004,6 @@
         return UnwarrantedOptimismException.isValid(programPoint) ? toInt32Optimistic(obj, programPoint) : toInt32(obj);
     }
 
-    // Minimum and maximum range between which every long value can be precisely represented as a double.
-    private static final long MAX_PRECISE_DOUBLE = 1L << 53;
-    private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE;
-
     /**
      * JavaScript compliant long to int32 conversion
      *
@@ -1154,6 +1056,29 @@
     }
 
     /**
+     * Optimistic JavaScript compliant int to uint32 conversion
+     * @param num an int
+     * @param pp the program point
+     * @return the uint32 value if it can be represented by an int
+     * @throws UnwarrantedOptimismException if uint32 value cannot be represented by an int
+     */
+    public static int toUint32Optimistic(final int num, final int pp) {
+        if (num >= 0) {
+            return num;
+        }
+        throw new UnwarrantedOptimismException(toUint32Double(num), pp, Type.NUMBER);
+    }
+
+    /**
+     * JavaScript compliant int to uint32 conversion with double return type
+     * @param num an int
+     * @return the uint32 value as double
+     */
+    public static double toUint32Double(final int num) {
+        return (double) toUint32(num);
+    }
+
+    /**
      * JavaScript compliant Object to uint16 conversion
      * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer)
      *
@@ -1484,26 +1409,6 @@
         try {
             return Math.addExact(x, y);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x + (long)y, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for addExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long addExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.addExact(x, y);
-        } catch (final ArithmeticException e) {
             throw new UnwarrantedOptimismException((double)x + (double)y, programPoint);
         }
     }
@@ -1524,26 +1429,6 @@
         try {
             return Math.subtractExact(x, y);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x - (long)y, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for subExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long subExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.subtractExact(x, y);
-        } catch (final ArithmeticException e) {
             throw new UnwarrantedOptimismException((double)x - (double)y, programPoint);
         }
     }
@@ -1564,26 +1449,6 @@
         try {
             return Math.multiplyExact(x, y);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x * (long)y, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for mulExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long mulExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.multiplyExact(x, y);
-        } catch (final ArithmeticException e) {
             throw new UnwarrantedOptimismException((double)x * (double)y, programPoint);
         }
     }
@@ -1655,71 +1520,6 @@
     }
 
     /**
-     * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
-     * long.
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if the result of the division can't be represented as long.
-     */
-    public static long divExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        final long res;
-        try {
-            res = x / y;
-        } catch (final ArithmeticException e) {
-            assert y == 0L; // Only div by zero anticipated
-            throw new UnwarrantedOptimismException(x > 0L ? Double.POSITIVE_INFINITY : x < 0L ? Double.NEGATIVE_INFINITY : Double.NaN, programPoint);
-        }
-        final long rem = x % y;
-        if (rem == 0L) {
-            return res;
-        }
-        throw new UnwarrantedOptimismException((double)x / (double)y, programPoint);
-    }
-
-    /**
-     * Implements long division but allows {@code x / 0} to be represented as 0. Useful when division of two longs
-     * is coerced to long.
-     * @param x the dividend
-     * @param y the divisor
-     * @return the result
-     */
-    public static long divZero(final long x, final long y) {
-        return y == 0L ? 0L : x / y;
-    }
-
-    /**
-     * Implements long remainder but allows {@code x % 0} to be represented as 0. Useful when remainder of two longs
-     * is coerced to long.
-     * @param x the dividend
-     * @param y the divisor
-     * @return the remainder
-     */
-    public static long remZero(final long x, final long y) {
-        return y == 0L ? 0L : x % y;
-    }
-
-    /**
-     * Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int.
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if the modulo can't be represented as int.
-     */
-    public static long remExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return x % y;
-        } catch (final ArithmeticException e) {
-            assert y == 0L; // Only mod by zero anticipated
-            throw new UnwarrantedOptimismException(Double.NaN, programPoint);
-        }
-    }
-
-    /**
      * Wrapper for decrementExact
      *
      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
@@ -1734,26 +1534,7 @@
         try {
             return Math.decrementExact(x);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x - 1, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for decrementExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x number to negate
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long decrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.decrementExact(x);
-        } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((double)x - 1L, programPoint);
+            throw new UnwarrantedOptimismException((double)x - 1, programPoint);
         }
     }
 
@@ -1772,26 +1553,7 @@
         try {
             return Math.incrementExact(x);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x + 1, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for incrementExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x the number to increment
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long incrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.incrementExact(x);
-        } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((double)x + 1L, programPoint);
+            throw new UnwarrantedOptimismException((double)x + 1, programPoint);
         }
     }
 
@@ -1813,28 +1575,6 @@
             }
             return Math.negateExact(x);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException(-(long)x, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for negateExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x the number to negate
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long negateExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            if (x == 0L) {
-                throw new UnwarrantedOptimismException(-0.0, programPoint);
-            }
-            return Math.negateExact(x);
-        } catch (final ArithmeticException e) {
             throw new UnwarrantedOptimismException(-(double)x, programPoint);
         }
     }
@@ -1866,8 +1606,6 @@
             return TYPE_UNDEFINED_INDEX;
         } else if (type == int.class) {
             return TYPE_INT_INDEX;
-        } else if (type == long.class) {
-            return TYPE_LONG_INDEX;
         } else if (type == double.class) {
             return TYPE_DOUBLE_INDEX;
         } else if (!type.isPrimitive()) {
@@ -1972,8 +1710,6 @@
     public static Class<?> getBoxedClass(final Class<?> clazz) {
         if (clazz == int.class) {
             return Integer.class;
-        } else if (clazz == long.class) {
-            return Long.class;
         } else if (clazz == double.class) {
             return Double.class;
         }
@@ -1991,8 +1727,6 @@
         if (o != null) {
             if (o.getClass() == Integer.class) {
                 return MH.constant(int.class, ((Integer)o));
-            } else if (o.getClass() == Long.class) {
-                return MH.constant(long.class, ((Long)o));
             } else if (o.getClass() == Double.class) {
                 return MH.constant(double.class, ((Double)o));
             }
@@ -2010,8 +1744,6 @@
             return Object.class;
         } else if (o.getClass() == Integer.class) {
             return int.class;
-        } else if (o.getClass() == Long.class) {
-            return long.class;
         } else if (o.getClass() == Double.class) {
             return double.class;
         } else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java	Thu Dec 17 20:26:31 2015 -0800
@@ -43,52 +43,42 @@
  */
 public final class OptimisticReturnFilters {
     private static final MethodHandle[] ENSURE_INT;
-    private static final MethodHandle[] ENSURE_LONG;
     private static final MethodHandle[] ENSURE_NUMBER;
 
+    // These extend the type index constants in JSType
+    private static final int VOID_TYPE_INDEX;
     private static final int BOOLEAN_TYPE_INDEX;
     private static final int CHAR_TYPE_INDEX;
+    private static final int LONG_TYPE_INDEX;
     private static final int FLOAT_TYPE_INDEX;
-    private static final int VOID_TYPE_INDEX;
 
     static {
         final MethodHandle INT_DOUBLE = findOwnMH("ensureInt", int.class, double.class, int.class);
         ENSURE_INT = new MethodHandle[] {
                 null,
-                findOwnMH("ensureInt", int.class, long.class, int.class),
                 INT_DOUBLE,
                 findOwnMH("ensureInt", int.class, Object.class, int.class),
                 findOwnMH("ensureInt", int.class, int.class),
                 findOwnMH("ensureInt", int.class, boolean.class, int.class),
                 findOwnMH("ensureInt", int.class, char.class, int.class),
+                findOwnMH("ensureInt", int.class, long.class, int.class),
                 INT_DOUBLE.asType(INT_DOUBLE.type().changeParameterType(0, float.class)),
         };
 
-        VOID_TYPE_INDEX = ENSURE_INT.length - 4;
-        BOOLEAN_TYPE_INDEX = ENSURE_INT.length - 3;
-        CHAR_TYPE_INDEX = ENSURE_INT.length - 2;
+        VOID_TYPE_INDEX = ENSURE_INT.length - 5;
+        BOOLEAN_TYPE_INDEX = ENSURE_INT.length - 4;
+        CHAR_TYPE_INDEX = ENSURE_INT.length - 3;
+        LONG_TYPE_INDEX = ENSURE_INT.length - 2;
         FLOAT_TYPE_INDEX = ENSURE_INT.length - 1;
 
-        final MethodHandle LONG_DOUBLE = findOwnMH("ensureLong", long.class, double.class, int.class);
-        ENSURE_LONG = new MethodHandle[] {
-                null,
-                null,
-                LONG_DOUBLE,
-                findOwnMH("ensureLong", long.class, Object.class, int.class),
-                ENSURE_INT[VOID_TYPE_INDEX].asType(ENSURE_INT[VOID_TYPE_INDEX].type().changeReturnType(long.class)),
-                ENSURE_INT[BOOLEAN_TYPE_INDEX].asType(ENSURE_INT[BOOLEAN_TYPE_INDEX].type().changeReturnType(long.class)),
-                ENSURE_INT[CHAR_TYPE_INDEX].asType(ENSURE_INT[CHAR_TYPE_INDEX].type().changeReturnType(long.class)),
-                LONG_DOUBLE.asType(LONG_DOUBLE.type().changeParameterType(0, float.class)),
-            };
-
         ENSURE_NUMBER = new MethodHandle[] {
                 null,
                 null,
-                null,
                 findOwnMH("ensureNumber", double.class, Object.class, int.class),
                 ENSURE_INT[VOID_TYPE_INDEX].asType(ENSURE_INT[VOID_TYPE_INDEX].type().changeReturnType(double.class)),
                 ENSURE_INT[BOOLEAN_TYPE_INDEX].asType(ENSURE_INT[BOOLEAN_TYPE_INDEX].type().changeReturnType(double.class)),
                 ENSURE_INT[CHAR_TYPE_INDEX].asType(ENSURE_INT[CHAR_TYPE_INDEX].type().changeReturnType(double.class)),
+                findOwnMH("ensureNumber", double.class, long.class, int.class),
                 null
         };
     }
@@ -136,8 +126,6 @@
         final int provableTypeIndex = getProvableTypeIndex(provable);
         if (actual == int.class) {
             guard = ENSURE_INT[provableTypeIndex];
-        } else if (actual == long.class) {
-            guard = ENSURE_LONG[provableTypeIndex];
         } else if (actual == double.class) {
             guard = ENSURE_NUMBER[provableTypeIndex];
         } else {
@@ -167,6 +155,8 @@
             return 0; // never needs a guard, as it's assignable to int
         } else if(provable == char.class) {
             return CHAR_TYPE_INDEX;
+        } else if(provable == long.class) {
+            return LONG_TYPE_INDEX;
         } else if(provable == float.class) {
             return FLOAT_TYPE_INDEX;
         }
@@ -179,7 +169,7 @@
         if (JSType.isRepresentableAsInt(arg)) {
             return (int)arg;
         }
-        throw new UnwarrantedOptimismException(arg, programPoint);
+        throw UnwarrantedOptimismException.createNarrowest(arg, programPoint);
     }
 
     @SuppressWarnings("unused")
@@ -187,7 +177,7 @@
         if (JSType.isStrictlyRepresentableAsInt(arg)) {
             return (int)arg;
         }
-        throw new UnwarrantedOptimismException(arg, programPoint);
+        throw new UnwarrantedOptimismException(arg, programPoint, Type.NUMBER);
     }
 
     /**
@@ -210,7 +200,7 @@
                 return (int)d;
             }
         }
-        throw new UnwarrantedOptimismException(arg, programPoint);
+        throw UnwarrantedOptimismException.createNarrowest(arg, programPoint);
     }
 
     private static boolean isPrimitiveNumberWrapper(final Object obj) {
@@ -238,51 +228,30 @@
         throw new UnwarrantedOptimismException(ScriptRuntime.UNDEFINED, programPoint, Type.OBJECT);
     }
 
-    private static long ensureLong(final double arg, final int programPoint) {
-        if (JSType.isStrictlyRepresentableAsLong(arg)) {
-            return (long)arg;
+
+    @SuppressWarnings("unused")
+    private static double ensureNumber(final long arg, final int programPoint) {
+        if (JSType.isRepresentableAsDouble(arg)) {
+            return (double) arg;
         }
-        throw new UnwarrantedOptimismException(arg, programPoint);
+        throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT);
     }
 
     /**
-     * Returns the argument value as a long. If the argument is not a wrapper for a primitive numeric type
-     * with a value that can be exactly represented as a long, throw an {@link UnwarrantedOptimismException}.
-     * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_LONG}.
-     * @param arg the original argument.
-     * @param programPoint the program point used in the exception
-     * @return the value of the argument as a long.
-     * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with
-     * a value that can be exactly represented as a long
-     */
-    public static long ensureLong(final Object arg, final int programPoint) {
-        if (arg != null) {
-            final Class<?> c = arg.getClass();
-            if (c == Long.class) {
-                // Must check for Long separately, as Long.doubleValue() isn't precise.
-                return ((Long)arg);
-            } else if (c == Integer.class || c == Double.class || c == Float.class || c == Short.class ||
-                    c == Byte.class) {
-                return ensureLong(((Number)arg).doubleValue(), programPoint);
-            }
-        }
-        throw new UnwarrantedOptimismException(arg, programPoint);
-    }
-
-    /**
-     * Returns the argument value as a double. If the argument is not a a wrapper for a primitive numeric type
-     * throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code
-     * can use it. See {code CodeGenerator.ENSURE_NUMBER}.
+     * Returns the argument value as a double. If the argument is not a wrapper for a primitive numeric type
+     * that can be represented as double throw an {@link UnwarrantedOptimismException}.
+     * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_NUMBER}.
      * @param arg the original argument.
      * @param programPoint the program point used in the exception
      * @return the value of the argument as a double.
      * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type.
      */
     public static double ensureNumber(final Object arg, final int programPoint) {
-        if (isPrimitiveNumberWrapper(arg)) {
-            return ((Number)arg).doubleValue();
+        if (isPrimitiveNumberWrapper(arg)
+                && (arg.getClass() != Long.class || JSType.isRepresentableAsDouble((Long) arg))) {
+            return ((Number) arg).doubleValue();
         }
-        throw new UnwarrantedOptimismException(arg, programPoint);
+        throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT);
     }
 
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java	Thu Dec 17 20:26:31 2015 -0800
@@ -450,16 +450,6 @@
      * @param owner the owner of the property
      * @return  the property value
      */
-    public abstract long getLongValue(final ScriptObject self, final ScriptObject owner);
-
-    /**
-     * get the Object value of this property from {@code owner}. This allows to bypass creation of the
-     * getter MethodHandle for spill and user accessor properties.
-     *
-     * @param self the this object
-     * @param owner the owner of the property
-     * @return  the property value
-     */
     public abstract double getDoubleValue(final ScriptObject self, final ScriptObject owner);
 
     /**
@@ -492,17 +482,6 @@
      * @param value the new property value
      * @param strict is this a strict setter?
      */
-    public abstract void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict);
-
-    /**
-     * Set the value of this property in {@code owner}. This allows to bypass creation of the
-     * setter MethodHandle for spill and user accessor properties.
-     *
-     * @param self the this object
-     * @param owner the owner object
-     * @param value the new property value
-     * @param strict is this a strict setter?
-     */
     public abstract void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict);
 
     /**
@@ -593,8 +572,6 @@
             return "undef";
         } else if (type == int.class) {
             return "i";
-        } else if (type == long.class) {
-            return "j";
         } else if (type == double.class) {
             return "d";
         } else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyAccess.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyAccess.java	Thu Dec 17 20:26:31 2015 -0800
@@ -57,49 +57,9 @@
      * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
      * @return the value
      */
-    public int getInt(long key, int programPoint);
-
-    /**
-     * Get the value for a given key and return it as an int
-     * @param key the key
-     * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
-     * @return the value
-     */
     public int getInt(int key, int programPoint);
 
     /**
-     * Get the value for a given key and return it as a long
-     * @param key the key
-     * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
-     * @return the value
-     */
-    public long getLong(Object key, int programPoint);
-
-    /**
-     * Get the value for a given key and return it as a long
-     * @param key the key
-     * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
-     * @return the value
-     */
-    public long getLong(double key, int programPoint);
-
-    /**
-     * Get the value for a given key and return it as a long
-     * @param key the key
-     * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
-     * @return the value
-     */
-    public long getLong(long key, int programPoint);
-
-    /**
-     * Get the value for a given key and return it as a long
-     * @param key the key
-     * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
-     * @return the value
-     */
-    public long getLong(int key, int programPoint);
-
-    /**
      * Get the value for a given key and return it as a double
      * @param key the key
      * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
@@ -121,14 +81,6 @@
      * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
      * @return the value
      */
-    public double getDouble(long key, int programPoint);
-
-    /**
-     * Get the value for a given key and return it as a double
-     * @param key the key
-     * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
-     * @return the value
-     */
     public double getDouble(int key, int programPoint);
 
     /**
@@ -150,13 +102,6 @@
      * @param key the key
      * @return the value
      */
-    public Object get(long key);
-
-    /**
-     * Get the value for a given key and return it as an Object
-     * @param key the key
-     * @return the value
-     */
     public Object get(int key);
 
     /**
@@ -173,14 +118,6 @@
      * @param value   the value
      * @param flags   call site flags
      */
-    public void set(Object key, long value, int flags);
-
-    /**
-     * Set the value of a given key
-     * @param key     the key
-     * @param value   the value
-     * @param flags   call site flags
-     */
     public void set(Object key, double value, int flags);
 
     /**
@@ -205,14 +142,6 @@
      * @param value   the value
      * @param flags   call site flags
      */
-    public void set(double key, long value, int flags);
-
-    /**
-     * Set the value of a given key
-     * @param key     the key
-     * @param value   the value
-     * @param flags   call site flags
-     */
     public void set(double key, double value, int flags);
 
     /**
@@ -229,38 +158,6 @@
      * @param value   the value
      * @param flags   call site flags
      */
-    public void set(long key, int value, int flags);
-
-    /**
-     * Set the value of a given key
-     * @param key     the key
-     * @param value   the value
-     * @param flags   call site flags
-     */
-    public void set(long key, long value, int flags);
-
-    /**
-     * Set the value of a given key
-     * @param key     the key
-     * @param value   the value
-     * @param flags   call site flags
-     */
-    public void set(long key, double value, int flags);
-
-    /**
-     * Set the value of a given key
-     * @param key     the key
-     * @param value   the value
-     * @param flags   call site flags
-     */
-    public void set(long key, Object value, int flags);
-
-    /**
-     * Set the value of a given key
-     * @param key     the key
-     * @param value   the value
-     * @param flags   call site flags
-     */
     public void set(int key, int value, int flags);
 
     /**
@@ -269,14 +166,6 @@
      * @param value   the value
      * @param flags   call site flags
      */
-    public void set(int key, long value, int flags);
-
-    /**
-     * Set the value of a given key
-     * @param key     the key
-     * @param value   the value
-     * @param flags   call site flags
-     */
     public void set(int key, double value, int flags);
 
     /**
@@ -306,13 +195,6 @@
      * @param key the key
      * @return true if key exists
      */
-    public boolean has(long key);
-
-    /**
-     * Check if the given key exists anywhere in the proto chain
-     * @param key the key
-     * @return true if key exists
-     */
     public boolean has(double key);
 
     /**
@@ -334,13 +216,6 @@
      * @param key the key
      * @return true if key exists
      */
-    public boolean hasOwnProperty(long key);
-
-    /**
-     * Check if the given key exists directly in the implementor
-     * @param key the key
-     * @return true if key exists
-     */
     public boolean hasOwnProperty(double key);
 
     /**
@@ -357,14 +232,6 @@
      * @param strict are we in strict mode
      * @return true if deletion succeeded, false otherwise
      */
-    public boolean delete(long key, boolean strict);
-
-    /**
-     * Delete a property with the given key from the implementor
-     * @param key    the key
-     * @param strict are we in strict mode
-     * @return true if deletion succeeded, false otherwise
-     */
     public boolean delete(double key, boolean strict);
 
     /**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Thu Dec 17 20:26:31 2015 -0800
@@ -886,7 +886,7 @@
     }
 
     @Override
-    synchronized CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
+    synchronized CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden, final boolean linkLogicOkay) {
         assert isValidCallSite(callSiteType) : callSiteType;
 
         CompiledFunction existingBest = pickFunction(callSiteType, false);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java	Thu Dec 17 20:26:31 2015 -0800
@@ -646,6 +646,24 @@
     }
 
     /**
+     * Get the documentation for this function
+     *
+     * @return the documentation
+     */
+    public final String getDocumentation() {
+        return data.getDocumentation();
+    }
+
+    /**
+     * Set the documentation for this function
+     *
+     * @param doc documentation String for this function
+     */
+    public final void setDocumentation(final String doc) {
+        data.setDocumentation(doc);
+    }
+
+    /**
      * Get the name for this function
      *
      * @return the name
@@ -954,6 +972,13 @@
             }
         }
 
+        // Is this an unstable callsite which was earlier apply-to-call optimized?
+        // If so, earlier apply2call would have exploded arguments. We have to convert
+        // that as an array again!
+        if (isUnstable && NashornCallSiteDescriptor.isApplyToCall(desc)) {
+            boundHandle = MH.asCollector(boundHandle, Object[].class, type.parameterCount() - 2);
+        }
+
         boundHandle = pairArguments(boundHandle, type);
 
         if (bestInvoker.getSwitchPoints() != null) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Thu Dec 17 20:26:31 2015 -0800
@@ -70,6 +70,9 @@
     // value, the function might still be capable of receiving variable number of arguments, see isVariableArity.
     private int arity;
 
+    // this may be null, if not available
+    private String documentation;
+
     /**
      * A pair of method handles used for generic invoker and constructor. Field is volatile as it can be initialized by
      * multiple threads concurrently, but we still tolerate a race condition in it as all values stored into it are
@@ -118,6 +121,10 @@
         return arity;
     }
 
+    final String getDocumentation() {
+        return documentation != null? documentation : toSource();
+    }
+
     final boolean isVariableArity() {
         return (flags & IS_VARIABLE_ARITY) != 0;
     }
@@ -137,6 +144,15 @@
         this.arity = arity;
     }
 
+    /**
+     * Used from nasgen generated code.
+     *
+     * @param doc documentation for this function
+     */
+    void setDocumentation(final String doc) {
+        this.documentation = doc;
+    }
+
     CompiledFunction bind(final CompiledFunction originalInv, final ScriptFunction fn, final Object self, final Object[] args) {
         final MethodHandle boundInvoker = bindInvokeHandle(originalInv.createComposableInvoker(), fn, self, args);
 
@@ -357,9 +373,23 @@
      * @param runtimeScope the runtime scope. It can be used to evaluate types of scoped variables to guide the
      * optimistic compilation, should the call to this method trigger code compilation. Can be null if current runtime
      * scope is not known, but that might cause compilation of code that will need more deoptimization passes.
+     * @param linkLogicOkay is a CompiledFunction with a LinkLogic acceptable?
      * @return the best function for the specified call site type.
      */
-    abstract CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden);
+    abstract CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden, final boolean linkLogicOkay);
+
+    /**
+     * Returns the best function for the specified call site type.
+     * @param callSiteType The call site type. Call site types are expected to have the form
+     * {@code (callee, this[, args...])}.
+     * @param runtimeScope the runtime scope. It can be used to evaluate types of scoped variables to guide the
+     * optimistic compilation, should the call to this method trigger code compilation. Can be null if current runtime
+     * scope is not known, but that might cause compilation of code that will need more deoptimization passes.
+     * @return the best function for the specified call site type.
+     */
+    final CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
+        return getBest(callSiteType, runtimeScope, forbidden, true);
+    }
 
     boolean isValidCallSite(final MethodType callSiteType) {
         return callSiteType.parameterCount() >= 2  && // Must have at least (callee, this)
@@ -367,7 +397,7 @@
     }
 
     CompiledFunction getGeneric(final ScriptObject runtimeScope) {
-        return getBest(getGenericType(), runtimeScope, CompiledFunction.NO_FUNCTIONS);
+        return getBest(getGenericType(), runtimeScope, CompiledFunction.NO_FUNCTIONS, false);
     }
 
     /**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Dec 17 20:26:31 2015 -0800
@@ -33,7 +33,6 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_DOUBLE;
 import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_INT;
-import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_LONG;
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE;
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE;
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.GET;
@@ -188,7 +187,6 @@
 
     static final MethodHandle[] SET_SLOW = new MethodHandle[] {
         findOwnMH_V("set", void.class, Object.class, int.class, int.class),
-        findOwnMH_V("set", void.class, Object.class, long.class, int.class),
         findOwnMH_V("set", void.class, Object.class, double.class, int.class),
         findOwnMH_V("set", void.class, Object.class, Object.class, int.class)
     };
@@ -1087,21 +1085,6 @@
         return UNDEFINED_INT;
     }
 
-    private static long getLongValue(final FindProperty find, final int programPoint) {
-        final MethodHandle getter = find.getGetter(long.class, programPoint, null);
-        if (getter != null) {
-            try {
-                return (long)getter.invokeExact((Object)find.getGetterReceiver());
-            } catch (final Error|RuntimeException e) {
-                throw e;
-            } catch (final Throwable e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        return UNDEFINED_LONG;
-    }
-
     private static double getDoubleValue(final FindProperty find, final int programPoint) {
         final MethodHandle getter = find.getGetter(double.class, programPoint, null);
         if (getter != null) {
@@ -2804,18 +2787,6 @@
     }
 
     @Override
-    public int getInt(final long key, final int programPoint) {
-        final int       index = getArrayIndex(key);
-        final ArrayData array = getArray();
-
-        if (array.has(index)) {
-            return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index);
-        }
-
-        return getInt(index, JSType.toString(key), programPoint);
-    }
-
-    @Override
     public int getInt(final int key, final int programPoint) {
         final int       index = getArrayIndex(key);
         final ArrayData array = getArray();
@@ -2827,88 +2798,6 @@
         return getInt(index, JSType.toString(key), programPoint);
     }
 
-    private long getLong(final int index, final Object key, final int programPoint) {
-        if (isValidArrayIndex(index)) {
-            for (ScriptObject object = this; ; ) {
-                if (object.getMap().containsArrayKeys()) {
-                    final FindProperty find = object.findProperty(key, false, this);
-                    if (find != null) {
-                        return getLongValue(find, programPoint);
-                    }
-                }
-
-                if ((object = object.getProto()) == null) {
-                    break;
-                }
-
-                final ArrayData array = object.getArray();
-
-                if (array.has(index)) {
-                    return isValid(programPoint) ?
-                        array.getLongOptimistic(index, programPoint) :
-                        array.getLong(index);
-                }
-            }
-        } else {
-            final FindProperty find = findProperty(key, true);
-
-            if (find != null) {
-                return getLongValue(find, programPoint);
-            }
-        }
-
-        return JSType.toLong(invokeNoSuchProperty(key, false, programPoint));
-    }
-
-    @Override
-    public long getLong(final Object key, final int programPoint) {
-        final Object    primitiveKey = JSType.toPrimitive(key, String.class);
-        final int       index        = getArrayIndex(primitiveKey);
-        final ArrayData array        = getArray();
-
-        if (array.has(index)) {
-            return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
-        }
-
-        return getLong(index, JSType.toPropertyKey(primitiveKey), programPoint);
-    }
-
-    @Override
-    public long getLong(final double key, final int programPoint) {
-        final int       index = getArrayIndex(key);
-        final ArrayData array = getArray();
-
-        if (array.has(index)) {
-            return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
-        }
-
-        return getLong(index, JSType.toString(key), programPoint);
-    }
-
-    @Override
-    public long getLong(final long key, final int programPoint) {
-        final int       index = getArrayIndex(key);
-        final ArrayData array = getArray();
-
-        if (array.has(index)) {
-            return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
-        }
-
-        return getLong(index, JSType.toString(key), programPoint);
-    }
-
-    @Override
-    public long getLong(final int key, final int programPoint) {
-        final int       index = getArrayIndex(key);
-        final ArrayData array = getArray();
-
-        if (array.has(index)) {
-            return isValid(programPoint) ? array.getLongOptimistic(key, programPoint) : array.getLong(key);
-        }
-
-        return getLong(index, JSType.toString(key), programPoint);
-    }
-
     private double getDouble(final int index, final Object key, final int programPoint) {
         if (isValidArrayIndex(index)) {
             for (ScriptObject object = this; ; ) {
@@ -2968,18 +2857,6 @@
     }
 
     @Override
-    public double getDouble(final long key, final int programPoint) {
-        final int       index = getArrayIndex(key);
-        final ArrayData array = getArray();
-
-        if (array.has(index)) {
-            return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index);
-        }
-
-        return getDouble(index, JSType.toString(key), programPoint);
-    }
-
-    @Override
     public double getDouble(final int key, final int programPoint) {
         final int       index = getArrayIndex(key);
         final ArrayData array = getArray();
@@ -3049,18 +2926,6 @@
     }
 
     @Override
-    public Object get(final long key) {
-        final int index = getArrayIndex(key);
-        final ArrayData array = getArray();
-
-        if (array.has(index)) {
-            return array.getObject(index);
-        }
-
-        return get(index, JSType.toString(key));
-    }
-
-    @Override
     public Object get(final int key) {
         final int index = getArrayIndex(key);
         final ArrayData array = getArray();
@@ -3143,15 +3008,6 @@
         }
     }
 
-    private void doesNotHave(final int index, final long value, final int callSiteFlags) {
-        final long oldLength = getArray().length();
-        final long longIndex = ArrayIndex.toLongIndex(index);
-        if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
-            final boolean strict = isStrictFlag(callSiteFlags);
-            setArray(getArray().set(index, value, strict).safeDelete(oldLength, longIndex - 1, strict));
-        }
-    }
-
     private void doesNotHave(final int index, final double value, final int callSiteFlags) {
         final long oldLength = getArray().length();
         final long longIndex = ArrayIndex.toLongIndex(index);
@@ -3258,26 +3114,6 @@
     }
 
     @Override
-    public void set(final Object key, final long value, final int callSiteFlags) {
-        final Object primitiveKey = JSType.toPrimitive(key, String.class);
-        final int    index        = getArrayIndex(primitiveKey);
-
-        if (isValidArrayIndex(index)) {
-            final ArrayData data = getArray();
-            if (data.has(index)) {
-                setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
-            } else {
-                doesNotHave(index, value, callSiteFlags);
-            }
-
-            return;
-        }
-
-        final Object propName = JSType.toPropertyKey(primitiveKey);
-        setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
-    }
-
-    @Override
     public void set(final Object key, final double value, final int callSiteFlags) {
         final Object primitiveKey = JSType.toPrimitive(key, String.class);
         final int    index        = getArrayIndex(primitiveKey);
@@ -3337,25 +3173,6 @@
     }
 
     @Override
-    public void set(final double key, final long value, final int callSiteFlags) {
-        final int index = getArrayIndex(key);
-
-        if (isValidArrayIndex(index)) {
-            final ArrayData data = getArray();
-            if (data.has(index)) {
-                setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
-            } else {
-                doesNotHave(index, value, callSiteFlags);
-            }
-
-            return;
-        }
-
-        final String propName = JSType.toString(key);
-        setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
-    }
-
-    @Override
     public void set(final double key, final double value, final int callSiteFlags) {
         final int index = getArrayIndex(key);
 
@@ -3394,82 +3211,6 @@
     }
 
     @Override
-    public void set(final long key, final int value, final int callSiteFlags) {
-        final int index = getArrayIndex(key);
-
-        if (isValidArrayIndex(index)) {
-            final ArrayData data = getArray();
-            if (data.has(index)) {
-                setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
-            } else {
-                doesNotHave(index, value, callSiteFlags);
-            }
-
-            return;
-        }
-
-        final String propName = JSType.toString(key);
-        setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
-    }
-
-    @Override
-    public void set(final long key, final long value, final int callSiteFlags) {
-        final int index = getArrayIndex(key);
-
-        if (isValidArrayIndex(index)) {
-            final ArrayData data = getArray();
-            if (data.has(index)) {
-                setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
-            } else {
-                doesNotHave(index, value, callSiteFlags);
-            }
-
-            return;
-        }
-
-        final String propName = JSType.toString(key);
-        setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
-    }
-
-    @Override
-    public void set(final long key, final double value, final int callSiteFlags) {
-        final int index = getArrayIndex(key);
-
-        if (isValidArrayIndex(index)) {
-            final ArrayData data = getArray();
-            if (data.has(index)) {
-                setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
-            } else {
-                doesNotHave(index, value, callSiteFlags);
-            }
-
-            return;
-        }
-
-        final String propName = JSType.toString(key);
-        setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
-    }
-
-    @Override
-    public void set(final long key, final Object value, final int callSiteFlags) {
-        final int index = getArrayIndex(key);
-
-        if (isValidArrayIndex(index)) {
-            final ArrayData data = getArray();
-            if (data.has(index)) {
-                setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
-            } else {
-                doesNotHave(index, value, callSiteFlags);
-            }
-
-            return;
-        }
-
-        final String propName = JSType.toString(key);
-        setObject(findProperty(propName, true), callSiteFlags, propName, value);
-    }
-
-    @Override
     public void set(final int key, final int value, final int callSiteFlags) {
         final int index = getArrayIndex(key);
         if (isValidArrayIndex(index)) {
@@ -3487,25 +3228,6 @@
     }
 
     @Override
-    public void set(final int key, final long value, final int callSiteFlags) {
-        final int index = getArrayIndex(key);
-
-        if (isValidArrayIndex(index)) {
-            final ArrayData data = getArray();
-            if (data.has(index)) {
-                setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
-            } else {
-                doesNotHave(index, value, callSiteFlags);
-            }
-
-            return;
-        }
-
-        final String propName = JSType.toString(key);
-        setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
-    }
-
-    @Override
     public void set(final int key, final double value, final int callSiteFlags) {
         final int index = getArrayIndex(key);
 
@@ -3557,12 +3279,6 @@
     }
 
     @Override
-    public boolean has(final long key) {
-        final int index = getArrayIndex(key);
-        return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true);
-    }
-
-    @Override
     public boolean has(final int key) {
         final int index = getArrayIndex(key);
         return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true);
@@ -3595,12 +3311,6 @@
     }
 
     @Override
-    public boolean hasOwnProperty(final long key) {
-        final int index = getArrayIndex(key);
-        return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false);
-    }
-
-    @Override
     public boolean hasOwnProperty(final double key) {
         final int index = getArrayIndex(key);
         return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false);
@@ -3626,22 +3336,6 @@
     }
 
     @Override
-    public boolean delete(final long key, final boolean strict) {
-        final int index = getArrayIndex(key);
-        final ArrayData array = getArray();
-
-        if (array.has(index)) {
-            if (array.canDelete(index, strict)) {
-                setArray(array.delete(index));
-                return true;
-            }
-            return false;
-        }
-
-        return deleteObject(JSType.toObject(key), strict);
-    }
-
-    @Override
     public boolean delete(final double key, final boolean strict) {
         final int index = getArrayIndex(key);
         final ArrayData array = getArray();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Thu Dec 17 20:26:31 2015 -0800
@@ -278,9 +278,8 @@
      * @param str a {@link String} to tokenize.
      * @return a {@link List} of {@link String}s representing the tokens that
      * constitute the string.
-     * @throws IOException in case {@link StreamTokenizer#nextToken()} raises it.
      */
-    public static List<String> tokenizeString(final String str) throws IOException {
+    public static List<String> tokenizeString(final String str) {
         final StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(str));
         tokenizer.resetSyntax();
         tokenizer.wordChars(0, 255);
@@ -290,7 +289,7 @@
         tokenizer.quoteChar('\'');
         final List<String> tokenList = new ArrayList<>();
         final StringBuilder toAppend = new StringBuilder();
-        while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
+        while (nextToken(tokenizer) != StreamTokenizer.TT_EOF) {
             final String s = tokenizer.sval;
             // The tokenizer understands about honoring quoted strings and recognizes
             // them as one token that possibly contains multiple space-separated words.
@@ -309,4 +308,12 @@
         }
         return tokenList;
     }
+
+    private static int nextToken(final StreamTokenizer tokenizer) {
+        try {
+            return tokenizer.nextToken();
+        } catch (final IOException ioe) {
+            return StreamTokenizer.TT_EOF;
+        }
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/UnwarrantedOptimismException.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/UnwarrantedOptimismException.java	Thu Dec 17 20:26:31 2015 -0800
@@ -49,7 +49,10 @@
     private final Type   returnType;
 
     /**
-     * Constructor
+     * Constructor without explicit return type. The return type is determined statically from the class of
+     * the return value, and only canonical internal number representations are recognized. Use
+     * {@link #createNarrowest} if you want to handle float and long values as numbers instead of objects.
+     *
      * @param returnValue actual return value from the too narrow operation
      * @param programPoint program point where unwarranted optimism was detected
      */
@@ -58,7 +61,7 @@
     }
 
     /**
-     * Check if a program point is valid
+     * Check if a program point is valid.
      * @param programPoint the program point
      * @return true if valid
      */
@@ -70,8 +73,6 @@
     private static Type getReturnType(final Object v) {
         if (v instanceof Double) {
             return Type.NUMBER;
-        } else if (v instanceof Long) {
-            return Type.LONG;
         }
         assert !(v instanceof Integer) : v + " is an int"; // Can't have an unwarranted optimism exception with int
         return Type.OBJECT;
@@ -97,6 +98,22 @@
     }
 
     /**
+     * Create an {@code UnwarrantedOptimismException} with the given return value and program point, narrowing
+     * the type to {@code number} if the value is a float or a long that can be represented as double.
+     *
+     * @param returnValue the return value
+     * @param programPoint the program point
+     * @return the exception
+     */
+    public static UnwarrantedOptimismException createNarrowest(final Object returnValue, final int programPoint) {
+        if (returnValue instanceof Float
+                || (returnValue instanceof Long && JSType.isRepresentableAsDouble((Long) returnValue))) {
+            return new UnwarrantedOptimismException(((Number) returnValue).doubleValue(), programPoint, Type.NUMBER);
+        }
+        return new UnwarrantedOptimismException(returnValue, programPoint);
+    }
+
+    /**
      * Get the return value. This is a destructive readout, after the method is invoked the return value is null'd out.
      * @return return value
      */
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Thu Dec 17 20:26:31 2015 -0800
@@ -71,13 +71,11 @@
     /** Getter method handle */
     private final static MethodHandle INVOKE_OBJECT_GETTER = findOwnMH_S("invokeObjectGetter", Object.class, Accessors.class, MethodHandle.class, Object.class);
     private final static MethodHandle INVOKE_INT_GETTER  = findOwnMH_S("invokeIntGetter", int.class, Accessors.class, MethodHandle.class, int.class, Object.class);
-    private final static MethodHandle INVOKE_LONG_GETTER  = findOwnMH_S("invokeLongGetter", long.class, Accessors.class, MethodHandle.class, int.class, Object.class);
     private final static MethodHandle INVOKE_NUMBER_GETTER  = findOwnMH_S("invokeNumberGetter", double.class, Accessors.class, MethodHandle.class, int.class, Object.class);
 
     /** Setter method handle */
     private final static MethodHandle INVOKE_OBJECT_SETTER = findOwnMH_S("invokeObjectSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, Object.class);
     private final static MethodHandle INVOKE_INT_SETTER = findOwnMH_S("invokeIntSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, int.class);
-    private final static MethodHandle INVOKE_LONG_SETTER = findOwnMH_S("invokeLongSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, long.class);
     private final static MethodHandle INVOKE_NUMBER_SETTER = findOwnMH_S("invokeNumberSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, double.class);
 
     private static final Object OBJECT_GETTER_INVOKER_KEY = new Object();
@@ -188,11 +186,6 @@
     }
 
     @Override
-    public long getLongValue(final ScriptObject self, final ScriptObject owner) {
-        return (long)getObjectValue(self, owner);
-    }
-
-    @Override
     public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
         return (double)getObjectValue(self, owner);
     }
@@ -214,11 +207,6 @@
     }
 
     @Override
-    public void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict) {
-        setValue(self, owner, (Object) value, strict);
-    }
-
-    @Override
     public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict) {
         setValue(self, owner, (Object) value, strict);
     }
@@ -244,8 +232,6 @@
     public MethodHandle getOptimisticGetter(final Class<?> type, final int programPoint) {
         if (type == int.class) {
             return INVOKE_INT_GETTER;
-        } else if (type == long.class) {
-            return INVOKE_LONG_GETTER;
         } else if (type == double.class) {
             return INVOKE_NUMBER_GETTER;
         } else {
@@ -269,8 +255,6 @@
     public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
         if (type == int.class) {
             return INVOKE_INT_SETTER;
-        } else if (type == long.class) {
-            return INVOKE_LONG_SETTER;
         } else if (type == double.class) {
             return INVOKE_NUMBER_SETTER;
         } else {
@@ -320,16 +304,6 @@
     }
 
     @SuppressWarnings("unused")
-    private static long invokeLongGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
-        final Object func = gs.getter;
-        if (func instanceof ScriptFunction) {
-            return (long) invoker.invokeExact(func, self);
-        }
-
-        throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
-    }
-
-    @SuppressWarnings("unused")
     private static double invokeNumberGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
         final Object func = gs.getter;
         if (func instanceof ScriptFunction) {
@@ -360,16 +334,6 @@
     }
 
     @SuppressWarnings("unused")
-    private static void invokeLongSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final long value) throws Throwable {
-        final Object func = gs.setter;
-        if (func instanceof ScriptFunction) {
-            invoker.invokeExact(func, self, value);
-        } else if (name != null) {
-            throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
-        }
-    }
-
-    @SuppressWarnings("unused")
     private static void invokeNumberSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final double value) throws Throwable {
         final Object func = gs.setter;
         if (func instanceof ScriptFunction) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Thu Dec 17 20:26:31 2015 -0800
@@ -52,9 +52,6 @@
     /** Minimum chunk size for underlying arrays */
     protected static final int CHUNK_SIZE = 32;
 
-    /** Mask for getting a chunk */
-    protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
-
     /** Untouched data - still link callsites as IntArrayData, but expands to
      *  a proper ArrayData when we try to write to it */
     public static final ArrayData EMPTY_ARRAY = new UntouchedArrayData();
@@ -164,11 +161,6 @@
         }
 
         @Override
-        public ArrayData set(final int index, final long value, final boolean strict) {
-            return toRealArrayData(index).set(index, value, strict);
-        }
-
-        @Override
         public ArrayData set(final int index, final double value, final boolean strict) {
             return toRealArrayData(index).set(index, value, strict);
         }
@@ -179,11 +171,6 @@
         }
 
         @Override
-        public long getLong(final int index) {
-            throw new ArrayIndexOutOfBoundsException(index); //empty
-        }
-
-        @Override
         public double getDouble(final int index) {
             throw new ArrayIndexOutOfBoundsException(index); //empty
         }
@@ -288,13 +275,13 @@
      * @param length the initial length
      * @return ArrayData
      */
-    public static ArrayData allocate(final int length) {
-        if (length == 0) {
+    public static ArrayData allocate(final long length) {
+        if (length == 0L) {
             return new IntArrayData();
         } else if (length >= SparseArrayData.MAX_DENSE_LENGTH) {
             return new SparseArrayData(EMPTY_ARRAY, length);
         } else {
-            return new DeletedRangeArrayFilter(new IntArrayData(length), 0, length - 1);
+            return new DeletedRangeArrayFilter(new IntArrayData((int) length), 0, length - 1);
         }
     }
 
@@ -309,8 +296,6 @@
 
         if (clazz == int[].class) {
             return new IntArrayData((int[])array, ((int[])array).length);
-        } else if (clazz == long[].class) {
-            return new LongArrayData((long[])array, ((long[])array).length);
         } else if (clazz == double[].class) {
             return new NumberArrayData((double[])array, ((double[])array).length);
         } else {
@@ -334,16 +319,6 @@
      * @param array the array to use for initial elements
      * @return the ArrayData
      */
-    public static ArrayData allocate(final long[] array) {
-        return new LongArrayData(array, array.length);
-    }
-
-    /**
-     * Allocate an ArrayData wrapping a given array
-     *
-     * @param array the array to use for initial elements
-     * @return the ArrayData
-     */
     public static ArrayData allocate(final double[] array) {
         return new NumberArrayData(array, array.length);
     }
@@ -537,16 +512,6 @@
     public abstract ArrayData set(final int index, final int value, final boolean strict);
 
     /**
-     * Set a long value at a given index
-     *
-     * @param index the index
-     * @param value the value
-     * @param strict are we in strict mode
-     * @return new array data (or same)
-     */
-    public abstract ArrayData set(final int index, final long value, final boolean strict);
-
-    /**
      * Set an double value at a given index
      *
      * @param index the index
@@ -609,26 +574,6 @@
     }
 
     /**
-     * Get a long value from a given index
-     *
-     * @param index the index
-     * @return the value
-     */
-    public abstract long getLong(final int index);
-
-    /**
-     * Get optimistic long - default is that it's impossible. Overridden
-     * by arrays that actually represents longs or narrower
-     *
-     * @param index        the index
-     * @param programPoint program point
-     * @return the value
-     */
-    public long getLongOptimistic(final int index, final int programPoint) {
-        throw new UnwarrantedOptimismException(getObject(index), programPoint, getOptimisticType());
-    }
-
-    /**
      * Get a double value from a given index
      *
      * @param index the index
@@ -821,12 +766,8 @@
                 return Object.class;
             }
             final Class<?> itemClass = item.getClass();
-            if (itemClass == Long.class) {
+            if (itemClass == Double.class || itemClass == Float.class || itemClass == Long.class) {
                 if (widest == Integer.class) {
-                    widest = Long.class;
-                }
-            } else if (itemClass == Double.class || itemClass == Float.class) {
-                if (widest == Integer.class || widest == Long.class) {
                     widest = Double.class;
                 }
             } else if (itemClass != Integer.class && itemClass != Short.class && itemClass != Byte.class) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java	Thu Dec 17 20:26:31 2015 -0800
@@ -109,13 +109,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        underlying = underlying.set(index, value, strict);
-        setLength(underlying.length());
-        return this;
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         underlying = underlying.set(index, value, strict);
         setLength(underlying.length());
@@ -150,16 +143,6 @@
     }
 
     @Override
-    public long getLong(final int index) {
-        return underlying.getLong(index);
-    }
-
-    @Override
-    public long getLongOptimistic(final int index, final int programPoint) {
-        return underlying.getLongOptimistic(index, programPoint);
-    }
-
-    @Override
     public double getDouble(final int index) {
         return underlying.getDouble(index);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ByteBufferArrayData.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ByteBufferArrayData.java	Thu Dec 17 20:26:31 2015 -0800
@@ -122,12 +122,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        buf.put(index, (byte)value);
-        return this;
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         buf.put(index, (byte)value);
         return this;
@@ -139,11 +133,6 @@
     }
 
     @Override
-    public long getLong(final int index) {
-        return 0x0ff & buf.get(index);
-    }
-
-    @Override
     public double getDouble(final int index) {
         return 0x0ff & buf.get(index);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java	Thu Dec 17 20:26:31 2015 -0800
@@ -120,12 +120,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        deleted.clear(ArrayIndex.toLongIndex(index));
-        return super.set(index, value, strict);
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         deleted.clear(ArrayIndex.toLongIndex(index));
         return super.set(index, value, strict);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java	Thu Dec 17 20:26:31 2015 -0800
@@ -163,24 +163,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        final long longIndex = ArrayIndex.toLongIndex(index);
-        if (longIndex < lo || longIndex > hi) {
-            return super.set(index, value, strict);
-        } else if (longIndex > lo && longIndex < hi) {
-            return getDeletedArrayFilter().set(index, value, strict);
-        }
-        if (longIndex == lo) {
-            lo++;
-        } else {
-            assert longIndex == hi;
-            hi--;
-        }
-
-        return isEmpty() ? getUnderlying().set(index, value, strict) : super.set(index, value, strict);
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         final long longIndex = ArrayIndex.toLongIndex(index);
         if (longIndex < lo || longIndex > hi) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java	Thu Dec 17 20:26:31 2015 -0800
@@ -57,14 +57,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        if (strict) {
-            throw typeError("cant.set.property", Integer.toString(index), "frozen array");
-        }
-        return this;
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         if (strict) {
             throw typeError("cant.set.property", Integer.toString(index), "frozen array");
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Thu Dec 17 20:26:31 2015 -0800
@@ -156,22 +156,6 @@
         return darray;
     }
 
-    private long[] toLongArray() {
-        assert length() <= array.length : "length exceeds internal array size";
-        final int len = (int)length();
-        final long[] larray = new long[array.length];
-
-        for (int index = 0; index < len; index++) {
-            larray[index] = array[index];
-        }
-
-        return larray;
-    }
-
-    private LongArrayData convertToLong() {
-        return new LongArrayData(toLongArray(), (int)length());
-    }
-
     private NumberArrayData convertToDouble() {
         return new NumberArrayData(toDoubleArray(), (int)length());
     }
@@ -184,8 +168,6 @@
     public ArrayData convert(final Class<?> type) {
         if (type == Integer.class || type == Byte.class || type == Short.class) {
             return this;
-        } else if (type == Long.class) {
-            return convertToLong();
         } else if (type == Double.class || type == Float.class) {
             return convertToDouble();
         } else {
@@ -253,17 +235,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        if (JSType.isRepresentableAsInt(value)) {
-            array[index] = JSType.toInt32(value);
-            setLength(Math.max(index + 1, length()));
-            return this;
-        }
-
-        return convert(Long.class).set(index, value, strict);
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         if (JSType.isRepresentableAsInt(value)) {
             array[index] = (int)(long)value;
@@ -285,16 +256,6 @@
     }
 
     @Override
-    public long getLong(final int index) {
-        return array[index];
-    }
-
-    @Override
-    public long getLongOptimistic(final int index, final int programPoint) {
-        return array[index];
-    }
-
-    @Override
     public double getDouble(final int index) {
         return array[index];
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IteratorAction.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IteratorAction.java	Thu Dec 17 20:26:31 2015 -0800
@@ -130,6 +130,6 @@
      *
      * @throws Throwable if invocation throws an exception/error
      */
-    protected abstract boolean forEach(final Object val, final long i) throws Throwable;
+    protected abstract boolean forEach(final Object val, final double i) throws Throwable;
 
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LengthNotWritableFilter.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LengthNotWritableFilter.java	Thu Dec 17 20:26:31 2015 -0800
@@ -91,22 +91,6 @@
     }
 
     @Override
-    public long getLong(final int index) {
-        if (index >= length()) {
-            return JSType.toLong(get(index));
-        }
-        return underlying.getLong(index);
-    }
-
-    @Override
-    public long getLongOptimistic(final int index, final int programPoint) {
-        if (index >= length()) {
-            return JSType.toLongOptimistic(get(index), programPoint);
-        }
-        return underlying.getLongOptimistic(index, programPoint);
-    }
-
-    @Override
     public double getDouble(final int index) {
         if (index >= length()) {
             return JSType.toNumber(get(index));
@@ -149,15 +133,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        if (checkAdd(index, value)) {
-            return this;
-        }
-        underlying = underlying.set(index, value, strict);
-        return this;
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         if (checkAdd(index, value)) {
             return this;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java	Wed Jul 05 21:08:30 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,406 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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.internal.runtime.arrays;
-
-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.runtime.JSType;
-import jdk.nashorn.internal.runtime.ScriptRuntime;
-
-/**
- * Implementation of {@link ArrayData} as soon as a long has been
- * written to the array
- */
-final class LongArrayData extends ContinuousArrayData implements IntOrLongElements {
-    /**
-     * The wrapped array
-     */
-    private long[] array;
-
-    /**
-     * Constructor
-     * @param array an int array
-     * @param length a length, not necessarily array.length
-     */
-    LongArrayData(final long array[], final int length) {
-        super(length);
-        assert array.length >= length;
-        this.array = array;
-    }
-
-    @Override
-    public final Class<?> getElementType() {
-        return long.class;
-    }
-
-    @Override
-    public final Class<?> getBoxedElementType() {
-        return Long.class;
-    }
-
-    @Override
-    public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
-        return otherData instanceof IntElements ? this : otherData;
-    }
-
-    @Override
-    public final int getElementWeight() {
-        return 2;
-    }
-
-    @Override
-    public LongArrayData copy() {
-        return new LongArrayData(array.clone(), (int)length());
-    }
-
-    @Override
-    public Object[] asObjectArray() {
-        return toObjectArray(true);
-    }
-
-    private Object[] toObjectArray(final boolean trim) {
-        assert length() <= array.length : "length exceeds internal array size";
-        final int len = (int)length();
-        final Object[] oarray = new Object[trim ? len : array.length];
-
-        for (int index = 0; index < len; index++) {
-            oarray[index] = array[index];
-        }
-
-        return oarray;
-    }
-
-    @Override
-    public Object asArrayOfType(final Class<?> componentType) {
-        if (componentType == long.class) {
-            final int len = (int)length();
-            return array.length == len ? array.clone() : Arrays.copyOf(array, len);
-        }
-        return super.asArrayOfType(componentType);
-    }
-
-    private double[] toDoubleArray() {
-        assert length() <= array.length : "length exceeds internal array size";
-        final int len = (int)length();
-        final double[] darray = new double[array.length];
-
-        for (int index = 0; index < len; index++) {
-            darray[index] = array[index];
-        }
-
-        return darray;
-    }
-
-    @Override
-    public ContinuousArrayData convert(final Class<?> type) {
-        if (type == Integer.class || type == Long.class || type == Byte.class || type == Short.class) {
-            return this;
-        }
-        final int len = (int)length();
-        if (type == Double.class || type == Float.class) {
-            return new NumberArrayData(toDoubleArray(), len);
-        }
-        return new ObjectArrayData(toObjectArray(false), len);
-    }
-
-    @Override
-    public void shiftLeft(final int by) {
-        System.arraycopy(array, by, array, 0, array.length - by);
-    }
-
-    @Override
-    public ArrayData shiftRight(final int by) {
-        final ArrayData newData = ensure(by + length() - 1);
-        if (newData != this) {
-            newData.shiftRight(by);
-            return newData;
-        }
-        System.arraycopy(array, 0, array, by, array.length - by);
-
-        return this;
-    }
-
-    @Override
-    public ArrayData ensure(final long safeIndex) {
-        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
-            return new SparseArrayData(this, safeIndex + 1);
-        }
-        final int alen = array.length;
-        if (safeIndex >= alen) {
-            final int newLength = ArrayData.nextSize((int)safeIndex);
-            array = Arrays.copyOf(array, newLength);
-        }
-        if (safeIndex >= length()) {
-            setLength(safeIndex + 1);
-        }
-        return this;
-    }
-
-    @Override
-    public ArrayData shrink(final long newLength) {
-        Arrays.fill(array, (int)newLength, array.length, 0L);
-        return this;
-    }
-
-    @Override
-    public ArrayData set(final int index, final Object value, final boolean strict) {
-        if (value instanceof Long || value instanceof Integer ||
-            value instanceof Byte || value instanceof Short) {
-            return set(index, ((Number)value).longValue(), strict);
-        } else if (value == ScriptRuntime.UNDEFINED) {
-            return new UndefinedArrayFilter(this).set(index, value, strict);
-        }
-
-        final ArrayData newData = convert(value == null ? Object.class : value.getClass());
-        return newData.set(index, value, strict);
-    }
-
-    @Override
-    public ArrayData set(final int index, final int value, final boolean strict) {
-        array[index] = value;
-        setLength(Math.max(index + 1, length()));
-        return this;
-    }
-
-    @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        array[index] = value;
-        setLength(Math.max(index + 1, length()));
-        return this;
-    }
-
-    @Override
-    public ArrayData set(final int index, final double value, final boolean strict) {
-        if (JSType.isRepresentableAsLong(value)) {
-            array[index] = (long)value;
-            setLength(Math.max(index + 1, length()));
-            return this;
-        }
-        return convert(Double.class).set(index, value, strict);
-    }
-
-    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();
-
-    @SuppressWarnings("unused")
-    private long getElem(final int index) {
-        if (has(index)) {
-            return array[index];
-        }
-        throw new ClassCastException();
-    }
-
-    @SuppressWarnings("unused")
-    private void setElem(final int index, final long elem) {
-        if (hasRoomFor(index)) {
-            array[index] = elem;
-            return;
-        }
-        throw new ClassCastException();
-    }
-
-    @Override
-    public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
-        if (returnType == int.class) {
-            return null;
-        }
-        return getContinuousElementGetter(HAS_GET_ELEM, returnType, programPoint);
-    }
-
-    @Override
-    public MethodHandle getElementSetter(final Class<?> elementType) {
-        return elementType == int.class || elementType == long.class ? getContinuousElementSetter(MH.asType(SET_ELEM, SET_ELEM.type().changeParameterType(2, elementType)), elementType) : null;
-    }
-
-    @Override
-    public int getInt(final int index) {
-        return JSType.toInt32(array[index]);
-    }
-
-    @Override
-    public long getLong(final int index) {
-        return array[index];
-    }
-
-    @Override
-    public long getLongOptimistic(final int index, final int programPoint) {
-        return array[index];
-    }
-
-    @Override
-    public double getDouble(final int index) {
-        return array[index];
-    }
-
-    @Override
-    public double getDoubleOptimistic(final int index, final int programPoint) {
-        return array[index];
-    }
-
-    @Override
-    public Object getObject(final int index) {
-        return array[index];
-    }
-
-    @Override
-    public boolean has(final int index) {
-        return 0 <= index && index < length();
-    }
-
-    @Override
-    public ArrayData delete(final int index) {
-        return new DeletedRangeArrayFilter(this, index, index);
-    }
-
-    @Override
-    public ArrayData delete(final long fromIndex, final long toIndex) {
-        return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
-    }
-
-    @Override
-    public Object pop() {
-        final int len = (int)length();
-        if (len == 0) {
-            return ScriptRuntime.UNDEFINED;
-        }
-
-        final int newLength = len - 1;
-        final long elem = array[newLength];
-        array[newLength] = 0;
-        setLength(newLength);
-
-        return elem;
-    }
-
-    @Override
-    public ArrayData slice(final long from, final long to) {
-        final long start     = from < 0 ? from + length() : from;
-        final long newLength = to - start;
-        return new LongArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
-    }
-
-    @Override
-    public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
-        final long oldLength = length();
-        final long newLength = oldLength - removed + added;
-        if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
-            throw new UnsupportedOperationException();
-        }
-        final ArrayData returnValue = removed == 0 ?
-                EMPTY_ARRAY : new LongArrayData(Arrays.copyOfRange(array, start, start + removed), removed);
-
-        if (newLength != oldLength) {
-            final long[] newArray;
-
-            if (newLength > array.length) {
-                newArray = new long[ArrayData.nextSize((int)newLength)];
-                System.arraycopy(array, 0, newArray, 0, start);
-            } else {
-                newArray = array;
-            }
-
-            System.arraycopy(array, start + removed, newArray, start + added, (int)(oldLength - start - removed));
-            array = newArray;
-            setLength(newLength);
-        }
-
-        return returnValue;
-    }
-
-    @Override
-    public long fastPush(final int arg) {
-        return fastPush((long)arg);
-    }
-
-    @Override
-    public long fastPush(final long arg) {
-        final int len = (int)length();
-        if (len == array.length) {
-            array = Arrays.copyOf(array, nextSize(len));
-        }
-        array[len] = arg;
-        return increaseLength();
-    }
-
-    @Override
-    public long fastPopLong() {
-        if (length() == 0) {
-            throw new ClassCastException(); //undefined result
-        }
-        final int newLength = (int)decreaseLength();
-        final long elem = array[newLength];
-        array[newLength] = 0;
-        return elem;
-    }
-
-    @Override
-    public double fastPopDouble() {
-        return fastPopLong();
-   }
-
-    @Override
-    public Object fastPopObject() {
-        return fastPopLong();
-    }
-
-    @Override
-    public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
-        final int   otherLength = (int)otherData.length();
-        final int   thisLength  = (int)length();
-        assert otherLength > 0 && thisLength > 0;
-
-        final long[] otherArray  = ((LongArrayData)otherData).array;
-        final int    newLength   = otherLength + thisLength;
-        final long[] newArray   = new long[ArrayData.alignUp(newLength)];
-
-        System.arraycopy(array, 0, newArray, 0, thisLength);
-        System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
-
-        return new LongArrayData(newArray, newLength);
-    }
-
-    @Override
-    public String toString() {
-        assert length() <= array.length : length() + " > " + array.length;
-
-        final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).
-                append(": [");
-        final int len = (int)length();
-        for (int i = 0; i < len; i++) {
-            sb.append(array[i]).append('L'); //make sure L suffix is on elements, to discriminate this from IntArrayData.toString()
-            if (i + 1 < len) {
-                sb.append(", ");
-            }
-        }
-        sb.append(']');
-
-        return sb.toString();
-    }
-}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NonExtensibleArrayFilter.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NonExtensibleArrayFilter.java	Thu Dec 17 20:26:31 2015 -0800
@@ -51,14 +51,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        if (has(index)) {
-            return underlying.set(index, value, strict);
-        }
-        return extensionCheck(strict, index);
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         if (has(index)) {
             return underlying.set(index, value, strict);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Thu Dec 17 20:26:31 2015 -0800
@@ -179,13 +179,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        array[index] = value;
-        setLength(Math.max(index + 1, length()));
-        return this;
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         array[index] = value;
         setLength(Math.max(index + 1, length()));
@@ -214,7 +207,7 @@
 
     @Override
     public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
-        if (returnType == int.class || returnType == long.class) {
+        if (returnType == int.class) {
             return null;
         }
         return getContinuousElementGetter(HAS_GET_ELEM, returnType, programPoint);
@@ -231,11 +224,6 @@
     }
 
     @Override
-    public long getLong(final int index) {
-        return (long)array[index];
-    }
-
-    @Override
     public double getDouble(final int index) {
         return array[index];
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java	Thu Dec 17 20:26:31 2015 -0800
@@ -150,13 +150,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        array[index] = value;
-        setLength(Math.max(index + 1, length()));
-        return this;
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         array[index] = value;
         setLength(Math.max(index + 1, length()));
@@ -216,11 +209,6 @@
     }
 
     @Override
-    public long getLong(final int index) {
-        return JSType.toLong(array[index]);
-    }
-
-    @Override
     public double getDouble(final int index) {
         return JSType.toNumber(array[index]);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java	Thu Dec 17 20:26:31 2015 -0800
@@ -195,21 +195,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long 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);
-            setLength(Math.max(underlying.length(), length()));
-        } else {
-            final Long longIndex = indexToKey(index);
-            sparseMap.put(longIndex, value);
-            setLength(Math.max(longIndex + 1, length()));
-        }
-        return this;
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         if (index >= 0 && index < maxDenseLength) {
             final long oldLength = underlying.length();
@@ -258,22 +243,6 @@
     }
 
     @Override
-    public long getLong(final int index) {
-        if (index >= 0 && index < maxDenseLength) {
-            return underlying.getLong(index);
-        }
-        return JSType.toLong(sparseMap.get(indexToKey(index)));
-    }
-
-    @Override
-    public long getLongOptimistic(final int index, final int programPoint) {
-        if (index >= 0 && index < maxDenseLength) {
-            return underlying.getLongOptimistic(index, programPoint);
-        }
-        return JSType.toLongOptimistic(sparseMap.get(indexToKey(index)), programPoint);
-    }
-
-    @Override
     public double getDouble(final int index) {
         if (index >= 0 && index < maxDenseLength) {
             return underlying.getDouble(index);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java	Thu Dec 17 20:26:31 2015 -0800
@@ -128,13 +128,6 @@
     }
 
     @Override
-    public ArrayData set(final int index, final long value, final boolean strict) {
-        undefined.clear(index);
-
-        return super.set(index, value, strict);
-    }
-
-    @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         undefined.clear(index);
 
@@ -160,24 +153,6 @@
     }
 
     @Override
-    public long getLong(final int index) {
-        if (undefined.isSet(index)) {
-            return 0L;
-        }
-
-        return super.getLong(index);
-    }
-
-    @Override
-    public long getLongOptimistic(final int index, final int programPoint) {
-        if (undefined.isSet(index)) {
-            throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
-        }
-
-        return super.getLongOptimistic(index, programPoint);
-    }
-
-    @Override
     public double getDouble(final int index) {
         if (undefined.isSet(index)) {
             return Double.NaN;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Thu Dec 17 20:26:31 2015 -0800
@@ -201,7 +201,7 @@
      *
      * @return callsite for a math intrinsic node
      */
-    public static CallSite mathBootstrap(final MethodHandles.Lookup lookup, final String name, final MethodType type, final int programPoint) {
+    public static CallSite mathBootstrap(final Lookup lookup, final String name, final MethodType type, final int programPoint) {
         final MethodHandle mh;
         switch (name) {
         case "iadd":
@@ -222,24 +222,6 @@
         case "ineg":
             mh = JSType.NEGATE_EXACT.methodHandle();
             break;
-        case "ladd":
-            mh = JSType.ADD_EXACT_LONG.methodHandle();
-            break;
-        case "lsub":
-            mh = JSType.SUB_EXACT_LONG.methodHandle();
-            break;
-        case "lmul":
-            mh = JSType.MUL_EXACT_LONG.methodHandle();
-            break;
-        case "ldiv":
-            mh = JSType.DIV_EXACT_LONG.methodHandle();
-            break;
-        case "lrem":
-            mh = JSType.REM_EXACT_LONG.methodHandle();
-            break;
-        case "lneg":
-            mh = JSType.NEGATE_EXACT_LONG.methodHandle();
-            break;
         default:
             throw new AssertionError("unsupported math intrinsic");
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java	Thu Dec 17 20:26:31 2015 -0800
@@ -48,19 +48,8 @@
  * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects.
  */
 final class BrowserJSObjectLinker implements TypeBasedGuardingDynamicLinker {
-    private static ClassLoader extLoader;
-    static {
-        extLoader = BrowserJSObjectLinker.class.getClassLoader();
-        // in case nashorn is loaded as bootstrap!
-        if (extLoader == null) {
-            extLoader = ClassLoader.getSystemClassLoader().getParent();
-        }
-    }
-
     private static final String JSOBJECT_CLASS = "netscape.javascript.JSObject";
-    // not final because this is lazily initialized
-    // when we hit a subclass for the first time.
-    private static volatile Class<?> jsObjectClass;
+    private static final Class<?> jsObjectClass = findBrowserJSObjectClass();
     private final NashornBeansLinker nashornBeansLinker;
 
     BrowserJSObjectLinker(final NashornBeansLinker nashornBeansLinker) {
@@ -73,22 +62,7 @@
     }
 
     static boolean canLinkTypeStatic(final Class<?> type) {
-        if (jsObjectClass != null && jsObjectClass.isAssignableFrom(type)) {
-            return true;
-        }
-
-        // check if this class is a subclass of JSObject
-        Class<?> clazz = type;
-        while (clazz != null) {
-            if (clazz.getClassLoader() == extLoader &&
-                clazz.getName().equals(JSOBJECT_CLASS)) {
-                jsObjectClass = clazz;
-                return true;
-            }
-            clazz = clazz.getSuperclass();
-        }
-
-        return false;
+        return jsObjectClass != null && jsObjectClass.isAssignableFrom(type);
     }
 
     private static void checkJSObjectClass() {
@@ -101,13 +75,10 @@
         final CallSiteDescriptor desc = request.getCallSiteDescriptor();
         checkJSObjectClass();
 
-        GuardedInvocation inv;
-        if (jsObjectClass.isInstance(self)) {
-            inv = lookup(desc, request, linkerServices);
-            inv = inv.replaceMethods(linkerServices.filterInternalObjects(inv.getInvocation()), inv.getGuard());
-        } else {
-            throw new AssertionError(); // Should never reach here.
-        }
+        assert jsObjectClass.isInstance(self);
+
+        GuardedInvocation inv = lookup(desc, request, linkerServices);
+        inv = inv.replaceMethods(linkerServices.filterInternalObjects(inv.getInvocation()), inv.getGuard());
 
         return Bootstrap.asTypeSafeReturn(inv, linkerServices, desc);
     }
@@ -122,7 +93,7 @@
 
         final StandardOperation op = NashornCallSiteDescriptor.getFirstStandardOperation(desc);
         if (op == null) {
-            return null;
+            return inv;
         }
         final String name = NashornCallSiteDescriptor.getOperand(desc);
         switch (op) {
@@ -236,4 +207,18 @@
             return MH.findVirtual(MethodHandles.publicLookup(), jsObjectClass, name, MH.type(rtype, types));
         }
     }
+
+    private static Class<?> findBrowserJSObjectClass() {
+        ClassLoader extLoader;
+        extLoader = BrowserJSObjectLinker.class.getClassLoader();
+        // in case nashorn is loaded as bootstrap!
+        if (extLoader == null) {
+            extLoader = ClassLoader.getSystemClassLoader().getParent();
+        }
+        try {
+            return Class.forName(JSOBJECT_CLASS, false, extLoader);
+        } catch (final ClassNotFoundException e) {
+            return null;
+        }
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Thu Dec 17 20:26:31 2015 -0800
@@ -141,8 +141,9 @@
     }
 
     /**
-     * Main part of the implementation of {@link GuardingTypeConverterFactory#convertToType(Class, Class)} that doesn't
-     * care about adapting the method signature; that's done by the invoking method. Returns conversion from Object to String/number/boolean (JS primitive types).
+     * Main part of the implementation of {@link GuardingTypeConverterFactory#convertToType} that doesn't
+     * care about adapting the method signature; that's done by the invoking method. Returns conversion
+     * from Object to String/number/boolean (JS primitive types).
      * @param sourceType the source type
      * @param targetType the target type
      * @return a guarded invocation that converts from the source type to the target type.
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Thu Dec 17 20:26:31 2015 -0800
@@ -174,28 +174,31 @@
      * Function used by {@link NashornTextifier} to represent call site flags in
      * human readable form
      * @param flags call site flags
-     * @return human readable form of this callsite descriptor
+     * @param sb the string builder
      */
-    public static String toString(final int flags) {
-        final StringBuilder sb = new StringBuilder();
+    public static void appendFlags(final int flags, final StringBuilder sb) {
+        final int pp = flags >> CALLSITE_PROGRAM_POINT_SHIFT;
+        if (pp != 0) {
+            sb.append(" pp=").append(pp);
+        }
         if ((flags & CALLSITE_SCOPE) != 0) {
             if ((flags & CALLSITE_FAST_SCOPE) != 0) {
-                sb.append("fastscope ");
+                sb.append(" fastscope");
             } else {
-                assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope";
-                sb.append("scope ");
+                sb.append(" scope");
             }
             if ((flags & CALLSITE_DECLARE) != 0) {
-                sb.append("declare ");
+                sb.append(" declare");
             }
+        } else {
+            assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope";
         }
         if ((flags & CALLSITE_APPLY_TO_CALL) != 0) {
-            sb.append("apply2call ");
+            sb.append(" apply2call");
         }
         if ((flags & CALLSITE_STRICT) != 0) {
-            sb.append("strict ");
+            sb.append(" strict");
         }
-        return sb.length() == 0 ? "" : " " + sb.toString().trim();
     }
 
     /**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java	Thu Dec 17 20:26:31 2015 -0800
@@ -25,23 +25,6 @@
 
 package jdk.nashorn.tools;
 
-import static jdk.nashorn.internal.runtime.Source.sourceFor;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.*;
-import java.util.stream.Collectors;
-
 import jdk.nashorn.api.scripting.NashornException;
 import jdk.nashorn.internal.codegen.Compiler;
 import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
@@ -60,10 +43,32 @@
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.ScriptingFunctions;
 import jdk.nashorn.internal.runtime.Symbol;
 import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
 import jdk.nashorn.internal.runtime.options.Options;
 
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import static jdk.nashorn.internal.runtime.Source.sourceFor;
+
 /**
  * Command line Shell for processing JavaScript files.
  */
@@ -203,8 +208,7 @@
         // parse options
         if (args != null) {
             try {
-                // FIXME: preprocessArgs does not yet work fine
-                final String[] prepArgs = args; // preprocessArgs(args);
+                final String[] prepArgs = preprocessArgs(args);
                 options.process(prepArgs);
             } catch (final IllegalArgumentException e) {
                 werr.println(bundle.getString("shell.usage"));
@@ -236,35 +240,53 @@
     }
 
     /**
-     * Preprocess the command line arguments passed in by the shell. This checks, for each of the arguments, whether it
-     * can be a file name, and if so, whether the file exists. If the file exists and begins with a shebang line, and
-     * the arguments on that line are a prefix of {@code args} with the file removed, it is assumed that a script file
-     * being executed via shebang was found, and it is moved to the appropriate position in the argument list. The first
-     * such match is used.
+     * Preprocess the command line arguments passed in by the shell. This method checks, for the first non-option
+     * argument, whether the file denoted by it begins with a shebang line. If so, it is assumed that execution in
+     * shebang mode is intended. The consequence of this is that the identified script file will be treated as the
+     * <em>only</em> script file, and all subsequent arguments will be regarded as arguments to the script.
      * <p>
-     * This method canonicalizes the command line arguments to the form {@code <options> <scripts> -- <arguments>},
-     * where the last of the {@code scripts} is the one being run in shebang fashion.
+     * This method canonicalizes the command line arguments to the form {@code <options> <script> -- <arguments>} if a
+     * shebang script is identified. On platforms that pass shebang arguments as single strings, the shebang arguments
+     * will be broken down into single arguments; whitespace is used as separator.
+     * <p>
+     * Shebang mode is entered regardless of whether the script is actually run directly from the shell, or indirectly
+     * via the {@code jjs} executable. It is the user's / script author's responsibility to ensure that the arguments
+     * given on the shebang line do not lead to a malformed argument sequence. In particular, the shebang arguments
+     * should not contain any whitespace for purposes other than separating arguments, as the different platforms deal
+     * with whitespace in different and incompatible ways.
      * <p>
      * @implNote Example:<ul>
-     * <li>Shebang line in {@code script.js}: {@code #!/path/to/jjs --language=es6 other.js -- arg1}</li>
+     * <li>Shebang line in {@code script.js}: {@code #!/path/to/jjs --language=es6}</li>
      * <li>Command line: {@code ./script.js arg2}</li>
-     * <li>{@code args} array passed to Nashorn: {@code --language=es6,other.js,--,arg1,./script.js,arg2}</li>
-     * <li>Required canonicalized arguments array: {@code --language=es6,other.js,./script.js,--,arg1,arg2}</li>
+     * <li>{@code args} array passed to Nashorn: {@code --language=es6,./script.js,arg}</li>
+     * <li>Required canonicalized arguments array: {@code --language=es6,./script.js,--,arg2}</li>
      * </ul>
      *
      * @param args the command line arguments as passed into Nashorn.
-     * @return a properly ordered argument list
+     * @return the passed and possibly canonicalized argument list
      */
     private static String[] preprocessArgs(final String[] args) {
-        final List<String> largs = new ArrayList<>();
-        Collections.addAll(largs, args);
-        final List<String> pa = new ArrayList<>();
-        String scriptFile = null;
-        boolean found = false;
-        for (int i = 0; i < args.length; ++i) {
-            final String a = args[i];
-            final Path p = Paths.get(a);
-            if (!found && (!a.startsWith("-") || a.length() == 1) && Files.exists(p)) {
+        if (args.length == 0) {
+            return args;
+        }
+
+        final List<String> processedArgs = new ArrayList<>();
+        processedArgs.addAll(Arrays.asList(args));
+
+        // Nashorn supports passing multiple shebang arguments. On platforms that pass anything following the
+        // shebang interpreter notice as one argument, the first element of the argument array needs to be special-cased
+        // as it might actually contain several arguments. Mac OS X splits shebang arguments, other platforms don't.
+        // This special handling is also only necessary if the first argument actually starts with an option.
+        if (args[0].startsWith("-") && !System.getProperty("os.name", "generic").startsWith("Mac OS X")) {
+            processedArgs.addAll(0, ScriptingFunctions.tokenizeString(processedArgs.remove(0)));
+        }
+
+        int shebangFilePos = -1; // -1 signifies "none found"
+        // identify a shebang file and its position in the arguments array (if any)
+        for (int i = 0; i < processedArgs.size(); ++i) {
+            final String a = processedArgs.get(i);
+            if (!a.startsWith("-")) {
+                final Path p = Paths.get(a);
                 String l = "";
                 try (final BufferedReader r = Files.newBufferedReader(p)) {
                     l = r.readLine();
@@ -272,35 +294,18 @@
                     // ignore
                 }
                 if (l.startsWith("#!")) {
-                    List<String> shebangArgs = Arrays.asList(l.split(" "));
-                    shebangArgs = shebangArgs.subList(1, shebangArgs.size()); // remove #! part
-                    final int ssize = shebangArgs.size();
-                    final List<String> filteredArgs = largs.stream().filter(x -> !x.equals(a)).collect(Collectors.toList());
-                    if (filteredArgs.size() >= ssize && shebangArgs.equals(filteredArgs.subList(0, ssize))) {
-                        scriptFile = a;
-                        found = true;
-                        continue;
-                    }
+                    shebangFilePos = i;
                 }
+                // We're only checking the first non-option argument. If it's not a shebang file, we're in normal
+                // execution mode.
+                break;
             }
-            pa.add(a);
         }
-        if (scriptFile != null) {
-            // Insert the found script file name either before a -- argument, or at the end of the options list, before
-            // any other arguments, with an extra --.
-            int argidx = pa.indexOf("--");
-            if (argidx == -1) {
-                for (String s : pa) {
-                    ++argidx;
-                    if (s.charAt(0) != '-') {
-                        pa.add(argidx, "--");
-                        break;
-                    }
-                }
-            }
-            pa.add(argidx, scriptFile);
+        if (shebangFilePos != -1) {
+            // Insert the argument separator after the shebang script file.
+            processedArgs.add(shebangFilePos + 1, "--");
         }
-        return pa.stream().toArray(String[]::new);
+        return processedArgs.stream().toArray(String[]::new);
     }
 
     /**
--- a/nashorn/test/script/basic/JDK-8062799.js	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/test/script/basic/JDK-8062799.js	Thu Dec 17 20:26:31 2015 -0800
@@ -33,67 +33,46 @@
     
     var b = true;
     var i = 1;
-    var l = 4294967296;
     var d = 2.1;
     var o = "foo";
 
     print(inspect(b || b, "b || b"));
     print(inspect(b || i, "b || i"));
-    print(inspect(b || l, "b || l"));
     print(inspect(b || d, "b || d"));
     print(inspect(b || o, "b || o"));
         
     print(inspect(i || b, "i || b"));
     print(inspect(i || i, "i || i"));
-    print(inspect(i || l, "i || l"));
     print(inspect(i || d, "i || d"));
     print(inspect(i || o, "i || o"));
 
-    print(inspect(l || b, "l || b"));
-    print(inspect(l || i, "l || i"));
-    print(inspect(l || l, "l || l"));
-    print(inspect(l || d, "l || d"));
-    print(inspect(l || o, "l || o"));
-
     print(inspect(d || b, "d || b"));
     print(inspect(d || i, "d || i"));
-    print(inspect(d || l, "d || l"));
     print(inspect(d || d, "d || d"));
     print(inspect(d || o, "d || o"));
 
     print(inspect(o || b, "o || b"));
     print(inspect(o || i, "o || i"));
-    print(inspect(o || l, "o || l"));
     print(inspect(o || d, "o || d"));
     print(inspect(o || o, "o || o"));
 
     print(inspect(b && b, "b && b"));
     print(inspect(b && i, "b && i"));
-    print(inspect(b && l, "b && l"));
     print(inspect(b && d, "b && d"));
     print(inspect(b && o, "b && o"));
         
     print(inspect(i && b, "i && b"));
     print(inspect(i && i, "i && i"));
-    print(inspect(i && l, "i && l"));
     print(inspect(i && d, "i && d"));
     print(inspect(i && o, "i && o"));
 
-    print(inspect(l && b, "l && b"));
-    print(inspect(l && i, "l && i"));
-    print(inspect(l && l, "l && l"));
-    print(inspect(l && d, "l && d"));
-    print(inspect(l && o, "l && o"));
-
     print(inspect(d && b, "d && b"));
     print(inspect(d && i, "d && i"));
-    print(inspect(d && l, "d && l"));
     print(inspect(d && d, "d && d"));
     print(inspect(d && o, "d && o"));
 
     print(inspect(o && b, "o && b"));
     print(inspect(o && i, "o && i"));
-    print(inspect(o && l, "o && l"));
     print(inspect(o && d, "o && d"));
     print(inspect(o && o, "o && o"));
 })();
--- a/nashorn/test/script/basic/JDK-8062799.js.EXPECTED	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/test/script/basic/JDK-8062799.js.EXPECTED	Thu Dec 17 20:26:31 2015 -0800
@@ -1,50 +1,32 @@
 b || b: boolean
 b || i: boolean
-b || l: boolean
 b || d: boolean
 b || o: boolean
 i || b: int
 i || i: int
-i || l: long
 i || d: double
 i || o: int
-l || b: long
-l || i: long
-l || l: long
-l || d: double
-l || o: long
 d || b: double
 d || i: double
-d || l: double
 d || d: double
 d || o: double
 o || b: object
 o || i: object
-o || l: object
 o || d: object
 o || o: object
 b && b: boolean
 b && i: int
-b && l: long
 b && d: double
 b && o: object
 i && b: boolean
 i && i: int
-i && l: long
 i && d: double
 i && o: object
-l && b: boolean
-l && i: long
-l && l: long
-l && d: double
-l && o: object
 d && b: boolean
 d && i: double
-d && l: double
 d && d: double
 d && o: object
 o && b: boolean
 o && i: int
-o && l: long
 o && d: double
 o && o: object
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8144020.js	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, 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-8144020: Remove long as an internal numeric type
+ *
+ * @test
+ * @run
+ */
+
+var LongProvider = Java.type("jdk.nashorn.test.models.LongProvider");
+var Long = Java.type("java.lang.Long");
+var LongClass = Long.class;
+var Integer = Java.type("java.lang.Integer");
+var Double = Java.type("java.lang.Double");
+
+var INT      = "3";
+var DOUBLE   = "5.5";
+var MAX_LONG = "9223372036854775807";
+var MIN_LONG = "-9223372036854775808";
+var BIG_LONG = "281474976710655"; // can be represented as double
+var NEG_LONG = "-281474976710656"; // can be represented as double
+var SMALL_LONG = "13";
+
+// Make sure we can pass longs from and to Java without losing precision
+LongProvider.checkLong(LongProvider.getLong(MAX_LONG), MAX_LONG);
+LongProvider.checkLong(LongProvider.getLong(MIN_LONG), MIN_LONG);
+LongProvider.checkLong(LongProvider.getLong(BIG_LONG), BIG_LONG);
+LongProvider.checkLong(LongProvider.getLong(NEG_LONG), NEG_LONG);
+LongProvider.checkLong(LongProvider.getLong(SMALL_LONG), SMALL_LONG);
+
+// a polymorphic function that can return various number types
+function getNumber(str) {
+    switch (str) {
+        case INT:    return +INT;
+        case DOUBLE: return +DOUBLE;
+        default:     return Long.parseLong(str);
+    }
+}
+
+function compareValue(n, str) {
+    switch (str) {
+        case INT:    return Integer.compare(n, Integer.parseInt(str) == 0);
+        case DOUBLE: return Double.compare(n, Double.parseDouble(str) == 0);
+        default:     return Long.compare(n, Long.parseLong(str) == 0);
+    }
+}
+
+// Call a a function with a sequence of values. The purpose of this is that we can handle
+// longs without losing precision in the presence of optimistic deoptimization, cached callsites, etc.
+function testSequence(fn, values) {
+    for (var i in values) {
+        fn(values[i]);
+    }
+}
+
+// We need to use "fresh" (unlinked and un-deoptimized) functions for each of the test runs.
+testSequence(function(str) {
+    var n = getNumber(str);
+    Assert.assertTrue(compareValue(n, str));
+}, [INT, BIG_LONG, MIN_LONG]);
+
+testSequence(function(str) {
+    var n = getNumber(str);
+    Assert.assertTrue(compareValue(n, str));
+}, [INT, MAX_LONG]);
+
+testSequence(function(str) {
+    var n = getNumber(str);
+    Assert.assertTrue(compareValue(n, str));
+}, [INT, DOUBLE, NEG_LONG]);
+
+testSequence(function(str) {
+    var n = getNumber(str);
+    Assert.assertTrue(compareValue(n, str));
+}, [DOUBLE, MAX_LONG]);
+
+testSequence(function(str) {
+    var n = getNumber(str);
+    Assert.assertTrue(compareValue(n, str));
+}, [DOUBLE, SMALL_LONG, MAX_LONG]);
+
+testSequence(function(str) {
+    var n = getNumber(str);
+    Assert.assertTrue(compareValue(n, str));
+}, [INT, DOUBLE, NEG_LONG, MAX_LONG]);
+
+testSequence(function(str) {
+    var n = getNumber(str);
+    Assert.assertTrue(compareValue(n, str));
+}, [DOUBLE, MAX_LONG, DOUBLE, INT]);
+
+// Make sure long arrays make it through Java.from and Java.to without losing precision
+var longArrayType = Java.type("long[]");
+for (var i = 0; i < 3; i++) {
+    LongProvider.checkLongArray(Java.to(Java.from(LongProvider.getLongArray(i)), longArrayType), i);
+}
+
+l = Long.parseLong(BIG_LONG);
+Assert.assertTrue(l >>> 8 === 0xffffff);
+Assert.assertTrue(l << 8 === -0x100);
+Assert.assertTrue(l + 1 === 0x1000000000000);
+Assert.assertTrue(l - 1 === 0xfffffffffffe);
+
+Assert.assertEquals(LongProvider.getLong(MAX_LONG).getClass(), LongClass);
+Assert.assertEquals(LongProvider.getLong(MIN_LONG).getClass(), LongClass);
--- a/nashorn/test/script/basic/JDK-8144131.js	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/test/script/basic/JDK-8144131.js	Thu Dec 17 20:26:31 2015 -0800
@@ -30,12 +30,9 @@
 
 var doubleArray = [97912312397.234, -182374983434.56];
 var doubleArrayResults = [-871935411, -1986357002];
-var longArray = [0x7fffffff8c102ebc, -0x7fffffffe9dfec18];
-var longArrayResults = [-1945096192, 371201024];
 
-// Make sure arrays use double and long array data
+// Make sure array uses double array data
 Assert.assertEquals(doubleArray[0].getClass(), java.lang.Double.class);
-Assert.assertEquals(longArray[0].getClass(), java.lang.Long.class);
 
 function testBinaryOp(array, index, expected) {
     Assert.assertEquals(array[index] & 0xffffffff, expected);
@@ -44,7 +41,4 @@
 for (var i = 0; i < doubleArray.length; i++) {
     testBinaryOp(doubleArray, i, doubleArrayResults[i]);
 }
-for (var i = 0; i < longArray.length; i++) {
-    testBinaryOp(longArray, i, longArrayResults[i]);
-}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8145550.js	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, 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-8141537: Megamorphic invoke should use CompiledFunction variants without any LinkLogic
+ *
+ * @test
+ * @option --unstable-relink-threshold=1
+ * @run
+ */
+
+load(__DIR__ + "NASHORN-421.js")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/apply_to_call/JDK-8145669.js	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,32 @@
+/* 
+ * Copyright (c) 2015, 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-8145669: apply2call optimized callsite fails after becoming megamorphic
+ *
+ * @test
+ * @option --unstable-relink-threshold=1
+ * @run
+ */
+
+load(__DIR__ + "apply_to_call2.js");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/apply_to_call/JDK-8145669.js.EXPECTED	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,8 @@
+start
+4711
+23
+17
+Overwriting call now
+1
+2
+3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/apply_to_call/JDK-8145669_2.js	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, 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-8145669: apply2call optimized callsite fails after becoming megamorphic
+ *
+ * @test
+ * @option --unstable-relink-threshold=1
+ * @run
+ */
+
+load(__DIR__ + "apply_to_call_varargs.js");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/apply_to_call/JDK-8145669_2.js.EXPECTED	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,66 @@
+[red=0, green=255, blue=255]
+undefined
+[red=1, green=255, blue=255]
+undefined
+[red=2, green=255, blue=255]
+undefined
+[red=3, green=255, blue=255]
+undefined
+[red=4, green=255, blue=255]
+undefined
+[red=5, green=255, blue=255]
+undefined
+[red=6, green=255, blue=255]
+undefined
+[red=7, green=255, blue=255]
+undefined
+[red=8, green=255, blue=255]
+undefined
+[red=9, green=255, blue=255]
+undefined
+[red=10, green=255, blue=255]
+undefined
+[red=11, green=255, blue=255]
+undefined
+[red=12, green=255, blue=255]
+undefined
+[red=13, green=255, blue=255]
+undefined
+[red=14, green=255, blue=255]
+undefined
+[red=15, green=255, blue=255]
+undefined
+Swapping out call
+[red=0, green=255, blue=255]
+undefined
+[red=1, green=255, blue=255]
+undefined
+[red=2, green=255, blue=255]
+undefined
+[red=3, green=255, blue=255]
+undefined
+[red=4, green=255, blue=255]
+undefined
+[red=5, green=255, blue=255]
+undefined
+[red=6, green=255, blue=255]
+undefined
+[red=7, green=255, blue=255]
+undefined
+[red=8, green=255, blue=255]
+undefined
+[red=9, green=255, blue=255]
+undefined
+[red=10, green=255, blue=255]
+undefined
+[red=11, green=255, blue=255]
+undefined
+[red=12, green=255, blue=255]
+undefined
+[red=13, green=255, blue=255]
+undefined
+[red=14, green=255, blue=255]
+undefined
+[red=15, green=255, blue=255]
+undefined
+All done!
--- a/nashorn/test/script/nosecurity/JDK-8067215.js	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/test/script/nosecurity/JDK-8067215.js	Thu Dec 17 20:26:31 2015 -0800
@@ -32,7 +32,6 @@
 
 var intType    = Java.type("int");
 var doubleType = Java.type("double");
-var longType   = Java.type("long");
 var objectType = Java.type("java.lang.Object");
 
 var Context = Java.type("jdk.nashorn.internal.runtime.Context");
@@ -58,7 +57,6 @@
         }
         if (prop.getType() != getExpectedType(obj[key])) {
             throw new Error("Wrong property type: " + prop.getType() + " // " + getExpectedType(obj[key]));
-
         }
     }
 }
@@ -67,14 +65,8 @@
     if (!dualFields) {
         return objectType.class;
     }
-    if (JSType.isRepresentableAsInt(value)) {
-        return intType.class;
-    }
-    if (JSType.isRepresentableAsLong(value)) {
-        return longType.class;
-    }
-    if (JSType.isNumber(value)) {
-        return doubleType.class;
+    if (typeof value === "number") {
+        return JSType.isRepresentableAsInt(value) ? intType.class : doubleType.class;
     }
     return objectType.class;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/nosecurity/JDK-8144221.js	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/**
+ * Test that shebang handling works properly.
+ *
+ * @test
+ * @runif os.not.windows
+ * @option -scripting
+ * @run
+ */
+
+// The test generates three different JavaScript source files. The first two
+// are generated at the beginning of the test and do not change.
+// * a.js
+//   print("A: " + arguments)
+// * b.js
+//   #!<path_to_jjs> -lalelu -- ignore
+//   print("B: " + arguments)
+//
+// The third file, shebang.js, is generated differently for each particular
+// test case, containing different shebang lines and one statement:
+// * shebang.js
+//   #!<path_to_jjs> <shebang_line>
+//   print("S: " + arguments)
+//
+// The path_to_jjs is extracted from the environment based on JAVA_HOME, so the
+// latter must be set properly.
+//
+// Each shebang.js is run four times, in all possible combinations of values
+// from the following two axes:
+// * without passing any arguments, and passing the arguments 'a.js' and
+//   '"hello world"' (the latter being a quoted string);
+// * run via jjs, and via direct shell execution (using shebang).
+
+var pseudosheb  = "#!${jjs} -lalelu -- ignore",
+    System      = Java.type('java.lang.System'),
+    Paths       = Java.type('java.nio.file.Paths'),
+    Files       = Java.type('java.nio.file.Files'),
+    Opt         = Java.type('java.nio.file.StandardOpenOption'),
+    Arrays      = Java.type('java.util.Arrays')
+
+var sep      = Java.type('java.io.File').separator,
+    win      = System.getProperty("os.name").startsWith("Windows"),
+    jjsName  = "jjs" + (win ? ".exe" : ""),
+    javaHome = System.getProperty("java.home")
+
+var jjs = javaHome + "/../bin/".replace(/\//g, sep) + jjsName
+if (!Files.exists(Paths.get(jjs))) {
+    jjs = javaHome + "/bin/".replace(/\//g, sep) + jjsName
+}
+
+// Create and cwd to a temporary directory.
+
+var tmpdir = Files.createTempDirectory(null),
+    tmp    = tmpdir.toAbsolutePath().toString(),
+    curpwd = $ENV.PWD
+
+$ENV.PWD = tmp
+
+// Test cases. Each case is documented with the expected output for the four
+// different executions.
+
+var shebs = [
+        // No arguments on the shebang line.
+        // noargs jjs/shebang -> no output but "S" prefix
+        // args jjs/shebang   -> output the arguments with "S" prefix
+        "",
+        // One interpreter argument.
+        // noargs jjs/shebang -> no output but "S" prefix
+        // args jjs/shebang   -> output the arguments with "S" prefix
+        "--language=es6",
+        // Two interpreter arguments.
+        // noargs jjs/shebang -> no output but "S" prefix
+        // args jjs/shebang   -> output the arguments with "S" prefix
+        "--language=es6 -scripting",
+        // One interpreter argument and a JavaScript file without shebang.
+        // (For shebang execution, this is a pathological example, as the
+        // JavaScript file passed as a shebang argument will be analyzed and
+        // shebang mode will not be entered.)
+        // noargs jjs     -> no output but "S" prefix
+        // args jjs       -> output the arguments with "S" prefix
+        // noargs shebang -> no output but "A" and "S" prefixes
+        // args shebang   -> output "A", "S", and "A" prefixes, then the error
+        //                   message:
+        //                   "java.io.IOException: hello world is not a file"
+        "-scripting a.js",
+        // One interpreter argument and a JavaScript file with shebang. (This
+        // is another pathological example, as it will force shebang mode,
+        // leading to all subsequent arguments, including shebang.js, being
+        // treated as arguments to the script b.js.)
+        // noargs jjs     -> no output but the "S" prefix
+        // args jjs       -> output the arguments with "S" prefix
+        // noargs shebang -> output shebang.js with "B" prefix
+        // args shebang   -> output shebang.js and the arguments with "B"
+        //                   prefix
+        "-scripting b.js"
+    ]
+
+function write(file, lines) {
+    Files.write(Paths.get(tmp, file), Arrays.asList(lines), Opt.CREATE, Opt.WRITE)
+}
+
+function insn(name) {
+    return "print('${name}:' + arguments)"
+}
+
+function run(viajjs, name, arg1, arg2) {
+    var prefix = viajjs ? "${jjs} -scripting " : ''
+    $EXEC("${prefix}./shebang.js ${arg1} ${arg2}")
+    print("* ${name} via ${viajjs ? 'jjs' : 'shebang'}")
+    print($OUT.trim())
+    print($ERR.trim())
+}
+
+write('a.js', insn('A'))
+write('b.js', [pseudosheb, insn('B')])
+
+shebs.forEach(function(sheb) {
+    var shebang = "#!${jjs} ${sheb}"
+    print("<<< ${sheb} >>>")
+    write('shebang.js', [shebang, insn('S')])
+    $EXEC('chmod +x shebang.js')
+    run(false, 'noargs', '', '')
+    run(true, 'noargs', '', '')
+    run(false, 'withargs', 'a.js', '"hello world"')
+    run(true, 'withargs', 'a.js', '"hello world"')
+    $EXEC('rm shebang.js')
+})
+
+// Cleanup.
+
+$EXEC('rm a.js b.js')
+$ENV.PWD = curpwd
+Files.delete(tmpdir)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/nosecurity/JDK-8144221.js.EXPECTED	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,68 @@
+<<<  >>>
+* noargs via shebang
+S:
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+S:a.js,hello world
+
+* withargs via jjs
+S:a.js,hello world
+
+<<< --language=es6 >>>
+* noargs via shebang
+S:
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+S:a.js,hello world
+
+* withargs via jjs
+S:a.js,hello world
+
+<<< --language=es6 -scripting >>>
+* noargs via shebang
+S:
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+S:a.js,hello world
+
+* withargs via jjs
+S:a.js,hello world
+
+<<< -scripting a.js >>>
+* noargs via shebang
+A:
+S:
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+A:
+S:
+A:
+java.io.IOException: hello world is not a file
+* withargs via jjs
+S:a.js,hello world
+
+<<< -scripting b.js >>>
+* noargs via shebang
+B:./shebang.js
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+B:./shebang.js,a.js,hello world
+
+* withargs via jjs
+S:a.js,hello world
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/nosecurity/os-not-windows.js	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/**
+ * Test that we're not running on Windows. The test actually checks if the os.not.windows property is set and processed
+ * by runif correctly.
+ *
+ * @test
+ * @runif os.not.windows
+ * @run
+ */
+
+var os = java.lang.System.getProperty("os.name")
+
+if (os.startsWith("Windows")) {
+    throw "This test should not be run on Windows."
+}
--- a/nashorn/test/src/jdk/nashorn/api/javaaccess/test/NumberAccessTest.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/test/NumberAccessTest.java	Thu Dec 17 20:26:31 2015 -0800
@@ -143,7 +143,7 @@
     @Test
     public void accessStaticFinalFieldLong() throws ScriptException {
         e.eval("var psf_long = SharedObject.publicStaticFinalLong;");
-        assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long"));
+        assertEquals(SharedObject.publicStaticFinalLong, ((Number) e.get("psf_long")).longValue());
         e.eval("SharedObject.publicStaticFinalLong = 120;");
         assertEquals(8333333333333L, SharedObject.publicStaticFinalLong);
     }
--- a/nashorn/test/src/jdk/nashorn/api/javaaccess/test/NumberBoxingTest.java	Wed Jul 05 21:08:30 2017 +0200
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/test/NumberBoxingTest.java	Thu Dec 17 20:26:31 2015 -0800
@@ -70,7 +70,7 @@
     @Test
     public void accessFieldLongBoxing() throws ScriptException {
         e.eval("var p_long = o.publicLongBox;");
-        assertEquals(o.publicLongBox, e.get("p_long"));
+        assertEquals(o.publicLongBox.longValue(), ((Number) e.get("p_long")).longValue());
         e.eval("o.publicLongBox = 12;");
         assertEquals(Long.valueOf(12), o.publicLongBox);
     }
@@ -78,7 +78,7 @@
     @Test
     public void accessStaticFieldLongBoxing() throws ScriptException {
         e.eval("var ps_long = SharedObject.publicStaticLongBox;");
-        assertEquals(SharedObject.publicStaticLongBox, e.get("ps_long"));
+        assertEquals(SharedObject.publicStaticLongBox.longValue(), ((Number) e.get("ps_long")).longValue());
         e.eval("SharedObject.publicStaticLongBox = 120;");
         assertEquals(120L, SharedObject.publicStaticLongBox.longValue());
     }
@@ -86,7 +86,7 @@
     @Test
     public void accessFinalFieldLongBoxing() throws ScriptException {
         e.eval("var pf_long = o.publicFinalLongBox;");
-        assertEquals(o.publicFinalLongBox, e.get("pf_long"));
+        assertEquals(o.publicFinalLongBox.longValue(), ((Number) e.get("pf_long")).longValue());
         e.eval("o.publicFinalLongBox = 120;");
         assertEquals(Long.valueOf(9377333334L), o.publicFinalLongBox);
     }
@@ -94,7 +94,7 @@
     @Test
     public void accessStaticFinalFieldLongBoxing() throws ScriptException {
         e.eval("var psf_long = SharedObject.publicStaticFinalLong;");
-        assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long"));
+        assertEquals(SharedObject.publicStaticFinalLong, ((Number) e.get("psf_long")).longValue());
         e.eval("SharedObject.publicStaticFinalLong = 120;");
         assertEquals(8333333333333L, SharedObject.publicStaticFinalLong);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/test/models/LongProvider.java	Thu Dec 17 20:26:31 2015 -0800
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, 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.Arrays;
+
+/**
+ * A class that returns and receives longs.
+ */
+@SuppressWarnings("javadoc")
+public class LongProvider {
+
+    final static long[][] arrays = {
+            {1L, 2L, 3L},
+            {1L, 1L << 30, 1L << 50, 4L},
+            {1L, Long.MAX_VALUE, Long.MIN_VALUE, 4L}
+    };
+
+    public static long getLong(final String str) {
+        final long l = Long.parseLong(str);
+        checkLong(l, str);
+        return l;
+    }
+
+    public static long[] getLongArray(final int n) {
+        return arrays[n];
+    }
+
+    public static void checkLong(final long value, final String str) {
+        if (!Long.toString(value).equals(str)) {
+            throw new RuntimeException("Wrong value. Expected " + str + ", got " + value);
+        }
+    }
+
+    public static void checkLongArray(final long[] array, final int n) {
+        if (!Arrays.equals(array, arrays[n])) {
+            throw new RuntimeException("Arrays don't match: " + Arrays.toString(array) + ", " + Arrays.toString(arrays[n]));
+        }
+    }
+}