Merge

Thu, 24 Sep 2015 10:09:56 -0700

author
asaha
date
Thu, 24 Sep 2015 10:09:56 -0700
changeset 1630
a82fc95737d1
parent 1629
1eda0618f55d
parent 1541
e4a553f79ebd
child 1634
718b32884775

Merge

src/jdk/nashorn/internal/codegen/AstSerializer.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/PrototypeObject.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java file | annotate | diff | comparison | revisions
     1.1 --- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java	Thu Sep 24 10:00:42 2015 -0700
     1.2 +++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java	Thu Sep 24 10:09:56 2015 -0700
     1.3 @@ -54,10 +54,9 @@
     1.4  import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP;
     1.5  import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC;
     1.6  import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
     1.7 -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION;
     1.8 -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC;
     1.9 -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC;
    1.10 -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE;
    1.11 +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN;
    1.12 +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_DESC;
    1.13 +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC;
    1.14  import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
    1.15  import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
    1.16  import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
    1.17 @@ -282,9 +281,9 @@
    1.18          assert specs != null;
    1.19          if (!specs.isEmpty()) {
    1.20              mi.memberInfoArray(className, specs);
    1.21 -            mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC);
    1.22 +            mi.invokeStatic(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_CREATEBUILTIN, SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC);
    1.23          } else {
    1.24 -            mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC);
    1.25 +            mi.invokeStatic(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_CREATEBUILTIN, SCRIPTFUNCTION_CREATEBUILTIN_DESC);
    1.26          }
    1.27  
    1.28          if (arityFound) {
     2.1 --- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Thu Sep 24 10:00:42 2015 -0700
     2.2 +++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Thu Sep 24 10:09:56 2015 -0700
     2.3 @@ -38,9 +38,8 @@
     2.4  import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR;
     2.5  import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC;
     2.6  import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
     2.7 -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC3;
     2.8 -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC4;
     2.9 -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE;
    2.10 +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC3;
    2.11 +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC4;
    2.12  import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
    2.13  import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
    2.14  import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE;
    2.15 @@ -55,7 +54,7 @@
    2.16  import jdk.internal.org.objectweb.asm.Handle;
    2.17  
    2.18  /**
    2.19 - * This class generates constructor class for a @ClassInfo annotated class.
    2.20 + * This class generates constructor class for a @ScriptClass annotated class.
    2.21   *
    2.22   */
    2.23  public class ConstructorGenerator extends ClassGenerator {
    2.24 @@ -75,8 +74,8 @@
    2.25      }
    2.26  
    2.27      byte[] getClassBytes() {
    2.28 -        // new class extensing from ScriptObject
    2.29 -        final String superClass = (constructor != null)? SCRIPTFUNCTIONIMPL_TYPE : SCRIPTOBJECT_TYPE;
    2.30 +        // new class extending from ScriptObject
    2.31 +        final String superClass = (constructor != null)? SCRIPTFUNCTION_TYPE : SCRIPTOBJECT_TYPE;
    2.32          cw.visit(V1_7, ACC_FINAL, className, null, superClass, null);
    2.33          if (memberCount > 0) {
    2.34              // add fields
    2.35 @@ -182,8 +181,8 @@
    2.36              loadMap(mi);
    2.37          } else {
    2.38              // call Function.<init>
    2.39 -            superClass = SCRIPTFUNCTIONIMPL_TYPE;
    2.40 -            superDesc = (memberCount > 0) ? SCRIPTFUNCTIONIMPL_INIT_DESC4 : SCRIPTFUNCTIONIMPL_INIT_DESC3;
    2.41 +            superClass = SCRIPTFUNCTION_TYPE;
    2.42 +            superDesc = (memberCount > 0) ? SCRIPTFUNCTION_INIT_DESC4 : SCRIPTFUNCTION_INIT_DESC3;
    2.43              mi.loadLiteral(constructor.getName());
    2.44              mi.visitLdcInsn(new Handle(H_INVOKESTATIC, scriptClassInfo.getJavaName(), constructor.getJavaName(), constructor.getJavaDesc()));
    2.45              loadMap(mi);
     3.1 --- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Thu Sep 24 10:00:42 2015 -0700
     3.2 +++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Thu Sep 24 10:09:56 2015 -0700
     3.3 @@ -161,7 +161,7 @@
     3.4      }
     3.5  
     3.6      /**
     3.7 -     * Tag something as optimitic builtin or not
     3.8 +     * Tag something as optimistic builtin or not
     3.9       * @param isOptimistic boolean, true if builtin constructor
    3.10       */
    3.11      public void setIsOptimistic(final boolean isOptimistic) {
    3.12 @@ -178,7 +178,7 @@
    3.13      }
    3.14  
    3.15      /**
    3.16 -     * Set thre SpecializedFunction link logic class for specializations, i.e. optimistic
    3.17 +     * Set the SpecializedFunction link logic class for specializations, i.e. optimistic
    3.18       * builtins
    3.19       * @param linkLogicClass link logic class
    3.20       */
     4.1 --- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java	Thu Sep 24 10:00:42 2015 -0700
     4.2 +++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java	Thu Sep 24 10:09:56 2015 -0700
     4.3 @@ -42,7 +42,7 @@
     4.4  import java.io.IOException;
     4.5  
     4.6  /**
     4.7 - * This class generates prototype class for a @ClassInfo annotated class.
     4.8 + * This class generates prototype class for a @ScriptClass annotated class.
     4.9   *
    4.10   */
    4.11  public class PrototypeGenerator extends ClassGenerator {
    4.12 @@ -57,7 +57,7 @@
    4.13      }
    4.14  
    4.15      byte[] getClassBytes() {
    4.16 -        // new class extensing from ScriptObject
    4.17 +        // new class extending from ScriptObject
    4.18          cw.visit(V1_7, ACC_FINAL | ACC_SUPER, className, null, PROTOTYPEOBJECT_TYPE, null);
    4.19          if (memberCount > 0) {
    4.20              // add fields
    4.21 @@ -155,7 +155,7 @@
    4.22       */
    4.23      public static void main(final String[] args) throws IOException {
    4.24          if (args.length != 1) {
    4.25 -            System.err.println("Usage: " + ConstructorGenerator.class.getName() + " <class>");
    4.26 +            System.err.println("Usage: " + PrototypeGenerator.class.getName() + " <class>");
    4.27              System.exit(1);
    4.28          }
    4.29  
     5.1 --- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java	Thu Sep 24 10:00:42 2015 -0700
     5.2 +++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java	Thu Sep 24 10:09:56 2015 -0700
     5.3 @@ -48,7 +48,7 @@
     5.4   *
     5.5   */
     5.6  public final class ScriptClassInfo {
     5.7 -    // descriptots for various annotations
     5.8 +    // descriptors for various annotations
     5.9      static final String SCRIPT_CLASS_ANNO_DESC  = Type.getDescriptor(ScriptClass.class);
    5.10      static final String CONSTRUCTOR_ANNO_DESC   = Type.getDescriptor(Constructor.class);
    5.11      static final String FUNCTION_ANNO_DESC      = Type.getDescriptor(Function.class);
    5.12 @@ -140,7 +140,7 @@
    5.13      }
    5.14  
    5.15      boolean isPrototypeNeeded() {
    5.16 -        // Prototype class generation is needed if we have atleast one
    5.17 +        // Prototype class generation is needed if we have at least one
    5.18          // prototype property or @Constructor defined in the class.
    5.19          for (final MemberInfo memInfo : members) {
    5.20              if (memInfo.getWhere() == Where.PROTOTYPE || memInfo.isConstructor()) {
     6.1 --- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java	Thu Sep 24 10:00:42 2015 -0700
     6.2 +++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java	Thu Sep 24 10:09:56 2015 -0700
     6.3 @@ -118,7 +118,7 @@
     6.4                      addScriptMember(memInfo);
     6.5  
     6.6                      return new AnnotationVisitor(Opcodes.ASM4, delegateAV) {
     6.7 -                        // These could be "null" if values are not suppiled,
     6.8 +                        // These could be "null" if values are not supplied,
     6.9                          // in which case we have to use the default values.
    6.10                          private String  name;
    6.11                          private Integer attributes;
    6.12 @@ -194,7 +194,7 @@
    6.13  
    6.14                      final MemberInfo memInfo = new MemberInfo();
    6.15  
    6.16 -                    //annokind == e.g. GETTER or SPECIALIZED_FUNCTION
    6.17 +                    // annoKind == GETTER or SPECIALIZED_FUNCTION
    6.18                      memInfo.setKind(annoKind);
    6.19                      memInfo.setJavaName(methodName);
    6.20                      memInfo.setJavaDesc(methodDesc);
    6.21 @@ -203,7 +203,7 @@
    6.22                      addScriptMember(memInfo);
    6.23  
    6.24                      return new AnnotationVisitor(Opcodes.ASM4, delegateAV) {
    6.25 -                        // These could be "null" if values are not suppiled,
    6.26 +                        // These could be "null" if values are not supplied,
    6.27                          // in which case we have to use the default values.
    6.28                          private String  name;
    6.29                          private Integer attributes;
     7.1 --- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java	Thu Sep 24 10:00:42 2015 -0700
     7.2 +++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java	Thu Sep 24 10:09:56 2015 -0700
     7.3 @@ -65,7 +65,6 @@
     7.4   * 2) add "Map" type static field named "$map".
     7.5   * 3) add static initializer block to initialize map.
     7.6   */
     7.7 -
     7.8  public class ScriptClassInstrumentor extends ClassVisitor {
     7.9      private final ScriptClassInfo scriptClassInfo;
    7.10      private final int memberCount;
    7.11 @@ -267,7 +266,7 @@
    7.12       */
    7.13      public static void main(final String[] args) throws IOException {
    7.14          if (args.length != 1) {
    7.15 -            System.err.println("Usage: " + ScriptClassInfoCollector.class.getName() + " <class>");
    7.16 +            System.err.println("Usage: " + ScriptClassInstrumentor.class.getName() + " <class>");
    7.17              System.exit(1);
    7.18          }
    7.19  
     8.1 --- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Thu Sep 24 10:00:42 2015 -0700
     8.2 +++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Thu Sep 24 10:09:56 2015 -0700
     8.3 @@ -31,10 +31,9 @@
     8.4  import java.util.Collections;
     8.5  import java.util.List;
     8.6  import jdk.internal.org.objectweb.asm.Type;
     8.7 -import jdk.nashorn.internal.objects.PrototypeObject;
     8.8 -import jdk.nashorn.internal.objects.ScriptFunctionImpl;
     8.9  import jdk.nashorn.internal.runtime.AccessorProperty;
    8.10  import jdk.nashorn.internal.runtime.PropertyMap;
    8.11 +import jdk.nashorn.internal.runtime.PrototypeObject;
    8.12  import jdk.nashorn.internal.runtime.ScriptFunction;
    8.13  import jdk.nashorn.internal.runtime.ScriptObject;
    8.14  import jdk.nashorn.internal.runtime.Specialization;
    8.15 @@ -88,7 +87,6 @@
    8.16      static final Type TYPE_PROPERTYMAP        = Type.getType(PropertyMap.class);
    8.17      static final Type TYPE_PROTOTYPEOBJECT    = Type.getType(PrototypeObject.class);
    8.18      static final Type TYPE_SCRIPTFUNCTION     = Type.getType(ScriptFunction.class);
    8.19 -    static final Type TYPE_SCRIPTFUNCTIONIMPL = Type.getType(ScriptFunctionImpl.class);
    8.20      static final Type TYPE_SCRIPTOBJECT       = Type.getType(ScriptObject.class);
    8.21  
    8.22      static final String PROTOTYPE_SUFFIX = "$Prototype";
    8.23 @@ -122,17 +120,14 @@
    8.24      static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
    8.25      static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype";
    8.26      static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
    8.27 -
    8.28 -    // ScriptFunctionImpl
    8.29 -    static final String SCRIPTFUNCTIONIMPL_TYPE = TYPE_SCRIPTFUNCTIONIMPL.getInternalName();
    8.30 -    static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION = "makeFunction";
    8.31 -    static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC =
    8.32 +    static final String SCRIPTFUNCTION_CREATEBUILTIN = "createBuiltin";
    8.33 +    static final String SCRIPTFUNCTION_CREATEBUILTIN_DESC =
    8.34          Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE);
    8.35 -    static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC =
    8.36 +    static final String SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC =
    8.37          Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
    8.38 -    static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 =
    8.39 +    static final String SCRIPTFUNCTION_INIT_DESC3 =
    8.40          Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
    8.41 -    static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 =
    8.42 +    static final String SCRIPTFUNCTION_INIT_DESC4 =
    8.43          Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_SPECIALIZATION_ARRAY);
    8.44  
    8.45      // ScriptObject
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/samples/exceptionswallow.js	Thu Sep 24 10:09:56 2015 -0700
     9.3 @@ -0,0 +1,136 @@
     9.4 +#// Usage: jjs exceptionswallow.js -- <directory>
     9.5 +
     9.6 +/*
     9.7 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
     9.8 + *
     9.9 + * Redistribution and use in source and binary forms, with or without
    9.10 + * modification, are permitted provided that the following conditions
    9.11 + * are met:
    9.12 + *
    9.13 + *   - Redistributions of source code must retain the above copyright
    9.14 + *     notice, this list of conditions and the following disclaimer.
    9.15 + *
    9.16 + *   - Redistributions in binary form must reproduce the above copyright
    9.17 + *     notice, this list of conditions and the following disclaimer in the
    9.18 + *     documentation and/or other materials provided with the distribution.
    9.19 + *
    9.20 + *   - Neither the name of Oracle nor the names of its
    9.21 + *     contributors may be used to endorse or promote products derived
    9.22 + *     from this software without specific prior written permission.
    9.23 + *
    9.24 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
    9.25 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    9.26 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    9.27 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    9.28 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    9.29 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    9.30 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    9.31 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    9.32 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    9.33 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    9.34 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    9.35 + */
    9.36 +
    9.37 +// This example demonstrates Java subclassing by Java.extend
    9.38 +// and javac Compiler and Tree API. This example looks for
    9.39 +// empty catch blocks ("exception swallow") and reports those.
    9.40 +
    9.41 +if (arguments.length == 0) {
    9.42 +    print("Usage: jjs exceptionswallow.js -- <directory>");
    9.43 +    exit(1);
    9.44 +}
    9.45 + 
    9.46 +// Java types used
    9.47 +var File = Java.type("java.io.File");
    9.48 +var Files = Java.type("java.nio.file.Files");
    9.49 +var StringArray = Java.type("java.lang.String[]");
    9.50 +var ToolProvider = Java.type("javax.tools.ToolProvider");
    9.51 +var Tree = Java.type("com.sun.source.tree.Tree");
    9.52 +var EmptyStatementTree = Java.type("com.sun.source.tree.EmptyStatementTree");
    9.53 +var Trees = Java.type("com.sun.source.util.Trees");
    9.54 +var TreeScanner = Java.type("com.sun.source.util.TreeScanner");
    9.55 +
    9.56 +// printEmptyCatch
    9.57 +
    9.58 +function printEmptyCatch() {
    9.59 +    // get the system compiler tool
    9.60 +    var compiler = ToolProvider.systemJavaCompiler;
    9.61 +    // get standard file manager
    9.62 +    var fileMgr = compiler.getStandardFileManager(null, null, null);
    9.63 +    // Using Java.to convert script array (arguments) to a Java String[]
    9.64 +    var compUnits = fileMgr.getJavaFileObjects(
    9.65 +        Java.to(arguments, StringArray));
    9.66 +    // create a new compilation task
    9.67 +    var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
    9.68 +
    9.69 +    // SourcePositions object to get positions of AST nodes
    9.70 +    var sourcePositions = Trees.instance(task).sourcePositions;
    9.71 +
    9.72 +    // subclass SimpleTreeVisitor - to print empty catch
    9.73 +    var EmptyCatchFinder = Java.extend(TreeScanner);
    9.74 +   
    9.75 +    function hasOnlyEmptyStats(stats) {
    9.76 +        var itr = stats.iterator();
    9.77 +        while (itr.hasNext()) {
    9.78 +            if (! (itr.next() instanceof EmptyStatementTree)) {
    9.79 +                return false;
    9.80 +            }
    9.81 +        }
    9.82 +
    9.83 +        return true;
    9.84 +    }
    9.85 + 
    9.86 +    var visitor = new EmptyCatchFinder() {
    9.87 +        // current CompilationUnitTree
    9.88 +        compUnit: null,
    9.89 +        // current LineMap (pos -> line, column)
    9.90 +        lineMap: null,
    9.91 +        // current compilation unit's file name
    9.92 +        fileName: null,
    9.93 +
    9.94 +        // overrides of TreeScanner methods
    9.95 +
    9.96 +        visitCompilationUnit: function(node, p) {
    9.97 +            // capture info about current Compilation unit
    9.98 +            this.compUnit = node;
    9.99 +            this.lineMap = node.lineMap;
   9.100 +            this.fileName = node.sourceFile.name;
   9.101 +
   9.102 +            // Using Java.super API to call super class method here
   9.103 +            return Java.super(visitor).visitCompilationUnit(node, p);
   9.104 +        },
   9.105 +
   9.106 +        visitCatch: function (node, p) {
   9.107 +            var stats = node.block.statements;
   9.108 +            if (stats.empty || hasOnlyEmptyStats(stats)) {
   9.109 +                // print information on this empty catch
   9.110 +                var pos = sourcePositions.getStartPosition(this.compUnit, node);
   9.111 +                var line = this.lineMap.getLineNumber(pos);
   9.112 +                var col = this.lineMap.getColumnNumber(pos);
   9.113 +                print("Exception swallow" + " @ " + this.fileName + ":" + line + ":" + col);
   9.114 +                // print(node);
   9.115 +            }
   9.116 +        }
   9.117 +    }
   9.118 + 
   9.119 +    for each (var cu in task.parse()) {
   9.120 +        cu.accept(visitor, null);
   9.121 +    }
   9.122 +}
   9.123 + 
   9.124 +// for each ".java" file in directory (recursively) and check it!
   9.125 +function main(dir) {
   9.126 +    Files.walk(dir.toPath()).
   9.127 +      forEach(function(p) {
   9.128 +        var name = p.toFile().absolutePath;
   9.129 +        if (name.endsWith(".java")) {
   9.130 +            try {
   9.131 +                printEmptyCatch(p.toFile().getAbsolutePath());
   9.132 +            } catch (e) {
   9.133 +                print(e);
   9.134 +            }
   9.135 +        }
   9.136 +      });
   9.137 +}
   9.138 + 
   9.139 +main(new File(arguments[0]));
    10.1 --- a/samples/find_nonfinals2.js	Thu Sep 24 10:00:42 2015 -0700
    10.2 +++ b/samples/find_nonfinals2.js	Thu Sep 24 10:09:56 2015 -0700
    10.3 @@ -43,7 +43,6 @@
    10.4  // Java types used
    10.5  var File = Java.type("java.io.File");
    10.6  var Files = Java.type("java.nio.file.Files");
    10.7 -var FileVisitOption = Java.type("java.nio.file.FileVisitOption");
    10.8  var StringArray = Java.type("java.lang.String[]");
    10.9  var ToolProvider = Java.type("javax.tools.ToolProvider");
   10.10  var Tree = Java.type("com.sun.source.tree.Tree");
   10.11 @@ -106,7 +105,7 @@
   10.12  // for each ".java" file in directory (recursively).
   10.13  function main(dir) {
   10.14      var totalCount = 0;
   10.15 -    Files.walk(dir.toPath(), FileVisitOption.FOLLOW_LINKS).
   10.16 +    Files.walk(dir.toPath()).
   10.17        forEach(function(p) {
   10.18          var name = p.toFile().absolutePath;
   10.19          if (name.endsWith(".java")) {
    11.1 --- a/samples/javafoovars.js	Thu Sep 24 10:00:42 2015 -0700
    11.2 +++ b/samples/javafoovars.js	Thu Sep 24 10:09:56 2015 -0700
    11.3 @@ -42,7 +42,6 @@
    11.4  // Java types used
    11.5  var File = Java.type("java.io.File");
    11.6  var Files = Java.type("java.nio.file.Files");
    11.7 -var FileVisitOption = Java.type("java.nio.file.FileVisitOption");
    11.8  var StringArray = Java.type("java.lang.String[]");
    11.9  var ToolProvider = Java.type("javax.tools.ToolProvider");
   11.10  var Tree = Java.type("com.sun.source.tree.Tree");
   11.11 @@ -81,7 +80,7 @@
   11.12  // for each ".java" file in directory (recursively) count "foo".
   11.13  function main(dir) {
   11.14      var totalCount = 0;
   11.15 -    Files.walk(dir.toPath(), FileVisitOption.FOLLOW_LINKS).
   11.16 +    Files.walk(dir.toPath()).
   11.17        forEach(function(p) {
   11.18          var name = p.toFile().absolutePath;
   11.19          if (name.endsWith(".java")) {
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/samples/resourcetrysuggester.js	Thu Sep 24 10:09:56 2015 -0700
    12.3 @@ -0,0 +1,156 @@
    12.4 +#// Usage: jjs resourcetrysuggester.js -- <directory>
    12.5 +
    12.6 +/*
    12.7 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
    12.8 + *
    12.9 + * Redistribution and use in source and binary forms, with or without
   12.10 + * modification, are permitted provided that the following conditions
   12.11 + * are met:
   12.12 + *
   12.13 + *   - Redistributions of source code must retain the above copyright
   12.14 + *     notice, this list of conditions and the following disclaimer.
   12.15 + *
   12.16 + *   - Redistributions in binary form must reproduce the above copyright
   12.17 + *     notice, this list of conditions and the following disclaimer in the
   12.18 + *     documentation and/or other materials provided with the distribution.
   12.19 + *
   12.20 + *   - Neither the name of Oracle nor the names of its
   12.21 + *     contributors may be used to endorse or promote products derived
   12.22 + *     from this software without specific prior written permission.
   12.23 + *
   12.24 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   12.25 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   12.26 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   12.27 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   12.28 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   12.29 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   12.30 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   12.31 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   12.32 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   12.33 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   12.34 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   12.35 + */
   12.36 +
   12.37 +// This example demonstrates Java subclassing by Java.extend
   12.38 +// and javac Compiler and Tree API. This example looks for
   12.39 +// finally clauses with "close" call and suggests "resource try"!
   12.40 +
   12.41 +if (arguments.length == 0) {
   12.42 +    print("Usage: jjs resourcetrysuggester.js -- <directory>");
   12.43 +    exit(1);
   12.44 +}
   12.45 + 
   12.46 +// Java types used
   12.47 +var ExpressionStatementTree = Java.type("com.sun.source.tree.ExpressionStatementTree");
   12.48 +var File = Java.type("java.io.File");
   12.49 +var Files = Java.type("java.nio.file.Files");
   12.50 +var MemberSelectTree = Java.type("com.sun.source.tree.MemberSelectTree");
   12.51 +var MethodInvocationTree = Java.type("com.sun.source.tree.MethodInvocationTree");
   12.52 +var StringArray = Java.type("java.lang.String[]");
   12.53 +var ToolProvider = Java.type("javax.tools.ToolProvider");
   12.54 +var Tree = Java.type("com.sun.source.tree.Tree");
   12.55 +var Trees = Java.type("com.sun.source.util.Trees");
   12.56 +var TreeScanner = Java.type("com.sun.source.util.TreeScanner");
   12.57 +
   12.58 +// resourceTrySuggestions
   12.59 +
   12.60 +function resourceTrySuggestions() {
   12.61 +    // get the system compiler tool
   12.62 +    var compiler = ToolProvider.systemJavaCompiler;
   12.63 +    // get standard file manager
   12.64 +    var fileMgr = compiler.getStandardFileManager(null, null, null);
   12.65 +    // Using Java.to convert script array (arguments) to a Java String[]
   12.66 +    var compUnits = fileMgr.getJavaFileObjects(
   12.67 +        Java.to(arguments, StringArray));
   12.68 +    // create a new compilation task
   12.69 +    var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
   12.70 +
   12.71 +    // SourcePositions object to get positions of AST nodes
   12.72 +    var sourcePositions = Trees.instance(task).sourcePositions;
   12.73 +
   12.74 +    // subclass SimpleTreeVisitor - to print resource try suggestions
   12.75 +    var ResourceTrySuggester = Java.extend(TreeScanner);
   12.76 +   
   12.77 +    function hasOnlyEmptyStats(stats) {
   12.78 +        var itr = stats.iterator();
   12.79 +        while (itr.hasNext()) {
   12.80 +            if (! (itr.next() instanceof EmptyStatementTree)) {
   12.81 +                return false;
   12.82 +            }
   12.83 +        }
   12.84 +
   12.85 +        return true;
   12.86 +    }
   12.87 +
   12.88 +    // does the given statement list has an expression statement which
   12.89 +    // calls "close" method (don't worry about types - just crude one will do)
   12.90 +    function hasCloseCall(stats) {
   12.91 +        var itr = stats.iterator();
   12.92 +        while (itr.hasNext()) {
   12.93 +            var stat = itr.next();
   12.94 +            if (stat instanceof ExpressionStatementTree) {
   12.95 +                var expr = stat.expression;
   12.96 +                if (expr instanceof MethodInvocationTree) {
   12.97 +                    var method = expr.methodSelect;
   12.98 +                    if (method instanceof MemberSelectTree) {
   12.99 +                        return method.identifier.toString().equals("close");
  12.100 +                    }
  12.101 +                }
  12.102 +            }
  12.103 +        }
  12.104 +        return false;
  12.105 +    }
  12.106 + 
  12.107 +    var visitor = new ResourceTrySuggester() {
  12.108 +        // current CompilationUnitTree
  12.109 +        compUnit: null,
  12.110 +        // current LineMap (pos -> line, column)
  12.111 +        lineMap: null,
  12.112 +        // current compilation unit's file name
  12.113 +        fileName: null,
  12.114 +
  12.115 +        // overrides of TreeScanner methods
  12.116 +
  12.117 +        visitCompilationUnit: function(node, p) {
  12.118 +            // capture info about current Compilation unit
  12.119 +            this.compUnit = node;
  12.120 +            this.lineMap = node.lineMap;
  12.121 +            this.fileName = node.sourceFile.name;
  12.122 +
  12.123 +            // Using Java.super API to call super class method here
  12.124 +            return Java.super(visitor).visitCompilationUnit(node, p);
  12.125 +        },
  12.126 +
  12.127 +        visitTry: function (node, p) {
  12.128 +            var finallyBlk = node.finallyBlock;
  12.129 +            if (finallyBlk != null && hasCloseCall(finallyBlk.statements)) {
  12.130 +                var pos = sourcePositions.getStartPosition(this.compUnit, node);
  12.131 +                var line = this.lineMap.getLineNumber(pos);
  12.132 +                var col = this.lineMap.getColumnNumber(pos);
  12.133 +                print("Consider resource try statement " + " @ " + this.fileName + ":" + line + ":" + col);
  12.134 +                // print(node);
  12.135 +            }
  12.136 +        }
  12.137 +    }
  12.138 + 
  12.139 +    for each (var cu in task.parse()) {
  12.140 +        cu.accept(visitor, null);
  12.141 +    }
  12.142 +}
  12.143 + 
  12.144 +// for each ".java" file in directory (recursively) and check it!
  12.145 +function main(dir) {
  12.146 +    Files.walk(dir.toPath()).
  12.147 +      forEach(function(p) {
  12.148 +        var name = p.toFile().absolutePath;
  12.149 +        if (name.endsWith(".java")) {
  12.150 +            try {
  12.151 +                resourceTrySuggestions(p.toFile().getAbsolutePath());
  12.152 +            } catch (e) {
  12.153 +                print(e);
  12.154 +            }
  12.155 +        }
  12.156 +      });
  12.157 +}
  12.158 + 
  12.159 +main(new File(arguments[0]));
    13.1 --- a/samples/zipfs.js	Thu Sep 24 10:00:42 2015 -0700
    13.2 +++ b/samples/zipfs.js	Thu Sep 24 10:09:56 2015 -0700
    13.3 @@ -36,13 +36,12 @@
    13.4  
    13.5  var Files = Java.type("java.nio.file.Files")
    13.6  var FileSystems = Java.type("java.nio.file.FileSystems")
    13.7 -var FileVisitOption = Java.type("java.nio.file.FileVisitOption")
    13.8  var Paths = Java.type("java.nio.file.Paths")
    13.9  
   13.10  var zipfile = Paths.get(arguments[0])
   13.11  var fs = FileSystems.newFileSystem(zipfile, null)
   13.12  var root = fs.rootDirectories[0]
   13.13 -Files.walk(root, FileVisitOption.FOLLOW_LINKS).forEach(
   13.14 +Files.walk(root).forEach(
   13.15     function(p) (print(p), print(Files.readAttributes(p, "zip:*")))
   13.16  )
   13.17  fs.close()
    14.1 --- a/src/jdk/internal/dynalink/DynamicLinker.java	Thu Sep 24 10:00:42 2015 -0700
    14.2 +++ b/src/jdk/internal/dynalink/DynamicLinker.java	Thu Sep 24 10:09:56 2015 -0700
    14.3 @@ -117,7 +117,7 @@
    14.4   *         return factory.createLinker();
    14.5   *     }
    14.6   *
    14.7 - *     public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
    14.8 + *     public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) {
    14.9   *         return dynamicLinker.link(new MonomorphicCallSite(CallSiteDescriptorFactory.create(lookup, name, type)));
   14.10   *     }
   14.11   * }
    15.1 --- a/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java	Thu Sep 24 10:00:42 2015 -0700
    15.2 +++ b/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java	Thu Sep 24 10:09:56 2015 -0700
    15.3 @@ -107,7 +107,7 @@
    15.4      private final AccessibleObject target;
    15.5      private final MethodType type;
    15.6  
    15.7 -    public CallerSensitiveDynamicMethod(final AccessibleObject target) {
    15.8 +    CallerSensitiveDynamicMethod(final AccessibleObject target) {
    15.9          super(getName(target));
   15.10          this.target = target;
   15.11          this.type = getMethodType(target);
   15.12 @@ -115,8 +115,9 @@
   15.13  
   15.14      private static String getName(final AccessibleObject target) {
   15.15          final Member m = (Member)target;
   15.16 -        return getMethodNameWithSignature(getMethodType(target), getClassAndMethodName(m.getDeclaringClass(),
   15.17 -                m.getName()));
   15.18 +        final boolean constructor = m instanceof Constructor;
   15.19 +        return getMethodNameWithSignature(getMethodType(target), constructor ? m.getName() :
   15.20 +            getClassAndMethodName(m.getDeclaringClass(), m.getName()), !constructor);
   15.21      }
   15.22  
   15.23      @Override
    16.1 --- a/src/jdk/internal/dynalink/beans/FacetIntrospector.java	Thu Sep 24 10:00:42 2015 -0700
    16.2 +++ b/src/jdk/internal/dynalink/beans/FacetIntrospector.java	Thu Sep 24 10:09:56 2015 -0700
    16.3 @@ -152,7 +152,7 @@
    16.4      boolean isAccessible(final Member m) {
    16.5          final Class<?> declaring = m.getDeclaringClass();
    16.6          // (declaring == clazz) is just an optimization - we're calling this only from code that operates on a
    16.7 -        // non-restriced class, so if the declaring class is identical to the class being inspected, then forego
    16.8 +        // non-restricted class, so if the declaring class is identical to the class being inspected, then forego
    16.9          // a potentially expensive restricted-package check.
   16.10          return declaring == clazz || !CheckRestrictedPackage.isRestrictedClass(declaring);
   16.11      }
    17.1 --- a/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java	Thu Sep 24 10:00:42 2015 -0700
    17.2 +++ b/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java	Thu Sep 24 10:09:56 2015 -0700
    17.3 @@ -86,7 +86,9 @@
    17.4  import java.lang.invoke.MethodHandle;
    17.5  import java.lang.invoke.MethodHandles;
    17.6  import java.lang.invoke.MethodType;
    17.7 +import java.text.Collator;
    17.8  import java.util.ArrayList;
    17.9 +import java.util.Collections;
   17.10  import java.util.Iterator;
   17.11  import java.util.LinkedList;
   17.12  import java.util.List;
   17.13 @@ -242,6 +244,35 @@
   17.14          return methods.getFirst().isConstructor();
   17.15      }
   17.16  
   17.17 +    @Override
   17.18 +    public String toString() {
   17.19 +        // First gather the names and sort them. This makes it consistent and easier to read.
   17.20 +        final List<String> names = new ArrayList<>(methods.size());
   17.21 +        int len = 0;
   17.22 +        for (final SingleDynamicMethod m: methods) {
   17.23 +            final String name = m.getName();
   17.24 +            len += name.length();
   17.25 +            names.add(name);
   17.26 +        }
   17.27 +        // Case insensitive sorting, so e.g. "Object" doesn't come before "boolean".
   17.28 +        final Collator collator = Collator.getInstance();
   17.29 +        collator.setStrength(Collator.SECONDARY);
   17.30 +        Collections.sort(names, collator);
   17.31 +
   17.32 +        final String className = getClass().getName();
   17.33 +        // Class name length + length of signatures + 2 chars/per signature for indentation and newline +
   17.34 +        // 3 for brackets and initial newline
   17.35 +        final int totalLength = className.length() + len + 2 * names.size() + 3;
   17.36 +        final StringBuilder b = new StringBuilder(totalLength);
   17.37 +        b.append('[').append(className).append('\n');
   17.38 +        for(final String name: names) {
   17.39 +            b.append(' ').append(name).append('\n');
   17.40 +        }
   17.41 +        b.append(']');
   17.42 +        assert b.length() == totalLength;
   17.43 +        return b.toString();
   17.44 +    };
   17.45 +
   17.46      ClassLoader getClassLoader() {
   17.47          return classLoader;
   17.48      }
    18.1 --- a/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java	Thu Sep 24 10:00:42 2015 -0700
    18.2 +++ b/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java	Thu Sep 24 10:09:56 2015 -0700
    18.3 @@ -122,13 +122,13 @@
    18.4       * @param constructor does this represent a constructor?
    18.5       */
    18.6      SimpleDynamicMethod(final MethodHandle target, final Class<?> clazz, final String name, final boolean constructor) {
    18.7 -        super(getName(target, clazz, name));
    18.8 +        super(getName(target, clazz, name, constructor));
    18.9          this.target = target;
   18.10          this.constructor = constructor;
   18.11      }
   18.12  
   18.13 -    private static String getName(final MethodHandle target, final Class<?> clazz, final String name) {
   18.14 -        return getMethodNameWithSignature(target.type(), getClassAndMethodName(clazz, name));
   18.15 +    private static String getName(final MethodHandle target, final Class<?> clazz, final String name, final boolean constructor) {
   18.16 +        return getMethodNameWithSignature(target.type(), constructor ? name : getClassAndMethodName(clazz, name), !constructor);
   18.17      }
   18.18  
   18.19      @Override
    19.1 --- a/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java	Thu Sep 24 10:00:42 2015 -0700
    19.2 +++ b/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java	Thu Sep 24 10:09:56 2015 -0700
    19.3 @@ -98,7 +98,6 @@
    19.4   * target method to a call site type (including mapping variable arity methods to a call site signature with different
    19.5   * arity).
    19.6   * @author Attila Szegedi
    19.7 - * @version $Id: $
    19.8   */
    19.9  abstract class SingleDynamicMethod extends DynamicMethod {
   19.10  
   19.11 @@ -143,14 +142,18 @@
   19.12          return getMethodType().parameterList().equals(method.getMethodType().parameterList());
   19.13      }
   19.14  
   19.15 -    static String getMethodNameWithSignature(final MethodType type, final String methodName) {
   19.16 +    static String getMethodNameWithSignature(final MethodType type, final String methodName, final boolean withReturnType) {
   19.17          final String typeStr = type.toString();
   19.18          final int retTypeIndex = typeStr.lastIndexOf(')') + 1;
   19.19          int secondParamIndex = typeStr.indexOf(',') + 1;
   19.20          if(secondParamIndex == 0) {
   19.21              secondParamIndex = retTypeIndex - 1;
   19.22          }
   19.23 -        return typeStr.substring(retTypeIndex) + " " + methodName + "(" + typeStr.substring(secondParamIndex, retTypeIndex);
   19.24 +        final StringBuilder b = new StringBuilder();
   19.25 +        if (withReturnType) {
   19.26 +            b.append(typeStr, retTypeIndex, typeStr.length()).append(' ');
   19.27 +        }
   19.28 +        return b.append(methodName).append('(').append(typeStr, secondParamIndex, retTypeIndex).toString();
   19.29      }
   19.30  
   19.31      /**
    20.1 --- a/src/jdk/internal/dynalink/linker/GuardedInvocation.java	Thu Sep 24 10:00:42 2015 -0700
    20.2 +++ b/src/jdk/internal/dynalink/linker/GuardedInvocation.java	Thu Sep 24 10:09:56 2015 -0700
    20.3 @@ -353,7 +353,7 @@
    20.4  
    20.5      /**
    20.6       * Applies argument filters to both the invocation and the guard (if there is one).
    20.7 -     * @param pos the position of the first argumen being filtered
    20.8 +     * @param pos the position of the first argument being filtered
    20.9       * @param filters the argument filters
   20.10       * @return a filtered invocation
   20.11       */
    21.1 --- a/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java	Thu Sep 24 10:00:42 2015 -0700
    21.2 +++ b/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java	Thu Sep 24 10:09:56 2015 -0700
    21.3 @@ -110,7 +110,7 @@
    21.4  
    21.5      /**
    21.6       * Check if invocation is cacheable
    21.7 -     * @return true if cachable, false otherwise
    21.8 +     * @return true if cacheable, false otherwise
    21.9       */
   21.10      public boolean isCacheable() {
   21.11          return cacheable;
    22.1 --- a/src/jdk/nashorn/api/scripting/AbstractJSObject.java	Thu Sep 24 10:00:42 2015 -0700
    22.2 +++ b/src/jdk/nashorn/api/scripting/AbstractJSObject.java	Thu Sep 24 10:09:56 2015 -0700
    22.3 @@ -182,7 +182,7 @@
    22.4      /**
    22.5       * Checking whether the given object is an instance of 'this' object.
    22.6       *
    22.7 -     * @param instance instace to check
    22.8 +     * @param instance instance to check
    22.9       * @return true if the given 'instance' is an instance of this 'function' object
   22.10       */
   22.11      @Override
    23.1 --- a/src/jdk/nashorn/api/scripting/JSObject.java	Thu Sep 24 10:00:42 2015 -0700
    23.2 +++ b/src/jdk/nashorn/api/scripting/JSObject.java	Thu Sep 24 10:09:56 2015 -0700
    23.3 @@ -141,7 +141,7 @@
    23.4      /**
    23.5       * Checking whether the given object is an instance of 'this' object.
    23.6       *
    23.7 -     * @param instance instace to check
    23.8 +     * @param instance instance to check
    23.9       * @return true if the given 'instance' is an instance of this 'function' object
   23.10       */
   23.11      public boolean isInstance(final Object instance);
    24.1 --- a/src/jdk/nashorn/api/scripting/NashornException.java	Thu Sep 24 10:00:42 2015 -0700
    24.2 +++ b/src/jdk/nashorn/api/scripting/NashornException.java	Thu Sep 24 10:09:56 2015 -0700
    24.3 @@ -51,6 +51,8 @@
    24.4      private String fileName;
    24.5      // script line number
    24.6      private int line;
    24.7 +    // are the line and fileName unknown?
    24.8 +    private boolean lineAndFileNameUnknown;
    24.9      // script column number
   24.10      private int column;
   24.11      // underlying ECMA error object - lazily initialized
   24.12 @@ -92,27 +94,10 @@
   24.13       */
   24.14      protected NashornException(final String msg, final Throwable cause) {
   24.15          super(msg, cause == null ? null : cause);
   24.16 -        // This is not so pretty - but it gets the job done. Note that the stack
   24.17 -        // trace has been already filled by "fillInStackTrace" call from
   24.18 -        // Throwable
   24.19 -        // constructor and so we don't pay additional cost for it.
   24.20 -
   24.21          // Hard luck - no column number info
   24.22          this.column = -1;
   24.23 -
   24.24 -        // Find the first JavaScript frame by walking and set file, line from it
   24.25 -        // Usually, we should be able to find it in just few frames depth.
   24.26 -        for (final StackTraceElement ste : getStackTrace()) {
   24.27 -            if (ECMAErrors.isScriptFrame(ste)) {
   24.28 -                // Whatever here is compiled from JavaScript code
   24.29 -                this.fileName = ste.getFileName();
   24.30 -                this.line = ste.getLineNumber();
   24.31 -                return;
   24.32 -            }
   24.33 -        }
   24.34 -
   24.35 -        this.fileName = null;
   24.36 -        this.line = 0;
   24.37 +        // We can retrieve the line number and file name from the stack trace if needed
   24.38 +        this.lineAndFileNameUnknown = true;
   24.39      }
   24.40  
   24.41      /**
   24.42 @@ -121,6 +106,7 @@
   24.43       * @return the file name
   24.44       */
   24.45      public final String getFileName() {
   24.46 +        ensureLineAndFileName();
   24.47          return fileName;
   24.48      }
   24.49  
   24.50 @@ -131,6 +117,7 @@
   24.51       */
   24.52      public final void setFileName(final String fileName) {
   24.53          this.fileName = fileName;
   24.54 +        lineAndFileNameUnknown = false;
   24.55      }
   24.56  
   24.57      /**
   24.58 @@ -139,6 +126,7 @@
   24.59       * @return the line number
   24.60       */
   24.61      public final int getLineNumber() {
   24.62 +        ensureLineAndFileName();
   24.63          return line;
   24.64      }
   24.65  
   24.66 @@ -148,6 +136,7 @@
   24.67       * @param line the line number
   24.68       */
   24.69      public final void setLineNumber(final int line) {
   24.70 +        lineAndFileNameUnknown = false;
   24.71          this.line = line;
   24.72      }
   24.73  
   24.74 @@ -274,4 +263,19 @@
   24.75      public void setEcmaError(final Object ecmaError) {
   24.76          this.ecmaError = ecmaError;
   24.77      }
   24.78 +
   24.79 +    private void ensureLineAndFileName() {
   24.80 +        if (lineAndFileNameUnknown) {
   24.81 +            for (final StackTraceElement ste : getStackTrace()) {
   24.82 +                if (ECMAErrors.isScriptFrame(ste)) {
   24.83 +                    // Whatever here is compiled from JavaScript code
   24.84 +                    fileName = ste.getFileName();
   24.85 +                    line = ste.getLineNumber();
   24.86 +                    return;
   24.87 +                }
   24.88 +            }
   24.89 +
   24.90 +            lineAndFileNameUnknown = false;
   24.91 +        }
   24.92 +    }
   24.93  }
    25.1 --- a/src/jdk/nashorn/api/scripting/ScriptUtils.java	Thu Sep 24 10:00:42 2015 -0700
    25.2 +++ b/src/jdk/nashorn/api/scripting/ScriptUtils.java	Thu Sep 24 10:09:56 2015 -0700
    25.3 @@ -79,7 +79,7 @@
    25.4       * @return a synchronizing wrapper function
    25.5       */
    25.6      public static Object makeSynchronizedFunction(final ScriptFunction func, final Object sync) {
    25.7 -        return func.makeSynchronizedFunction(unwrap(sync));
    25.8 +        return func.createSynchronized(unwrap(sync));
    25.9      }
   25.10  
   25.11      /**
    26.1 --- a/src/jdk/nashorn/api/scripting/URLReader.java	Thu Sep 24 10:00:42 2015 -0700
    26.2 +++ b/src/jdk/nashorn/api/scripting/URLReader.java	Thu Sep 24 10:09:56 2015 -0700
    26.3 @@ -103,7 +103,7 @@
    26.4      /**
    26.5       * Charset used by this reader
    26.6       *
    26.7 -     * @return the Chartset used to convert bytes to chars
    26.8 +     * @return the Charset used to convert bytes to chars
    26.9       */
   26.10      public Charset getCharset() {
   26.11          return cs;
    27.1 --- a/src/jdk/nashorn/internal/codegen/ApplySpecialization.java	Thu Sep 24 10:00:42 2015 -0700
    27.2 +++ b/src/jdk/nashorn/internal/codegen/ApplySpecialization.java	Thu Sep 24 10:09:56 2015 -0700
    27.3 @@ -40,7 +40,6 @@
    27.4  import jdk.nashorn.internal.ir.CallNode;
    27.5  import jdk.nashorn.internal.ir.Expression;
    27.6  import jdk.nashorn.internal.ir.FunctionNode;
    27.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    27.8  import jdk.nashorn.internal.ir.IdentNode;
    27.9  import jdk.nashorn.internal.ir.LexicalContext;
   27.10  import jdk.nashorn.internal.ir.Node;
   27.11 @@ -298,7 +297,28 @@
   27.12  
   27.13      @Override
   27.14      public boolean enterFunctionNode(final FunctionNode functionNode) {
   27.15 -        if (!USE_APPLY2CALL) {
   27.16 +        // Cheap tests first
   27.17 +        if (!(
   27.18 +                // is the transform globally enabled?
   27.19 +                USE_APPLY2CALL
   27.20 +
   27.21 +                // Are we compiling lazily? We can't known the number and types of the actual parameters at
   27.22 +                // the caller when compiling eagerly, so this only works with on-demand compilation.
   27.23 +                && compiler.isOnDemandCompilation()
   27.24 +
   27.25 +                // Does the function even reference the "arguments" identifier (without redefining it)? If not,
   27.26 +                // it trivially can't have an expression of form "f.apply(self, arguments)" that this transform
   27.27 +                // is targeting.
   27.28 +                && functionNode.needsArguments()
   27.29 +
   27.30 +                // Does the function have eval? If so, it can arbitrarily modify arguments so we can't touch it.
   27.31 +                && !functionNode.hasEval()
   27.32 +
   27.33 +                // Finally, does the function declare any parameters explicitly? We don't support that. It could
   27.34 +                // be done, but has some complications. Therefore only a function with no explicit parameters
   27.35 +                // is considered.
   27.36 +                && functionNode.getNumOfParams() == 0))
   27.37 +        {
   27.38              return false;
   27.39          }
   27.40  
   27.41 @@ -308,18 +328,6 @@
   27.42              return false;
   27.43          }
   27.44  
   27.45 -        if (!compiler.isOnDemandCompilation()) {
   27.46 -            return false;
   27.47 -        }
   27.48 -
   27.49 -        if (functionNode.getNumOfParams() != 0) {
   27.50 -            return false;
   27.51 -        }
   27.52 -
   27.53 -        if (functionNode.hasEval()) {
   27.54 -            return false;
   27.55 -        }
   27.56 -
   27.57          if (!hasApplies(functionNode)) {
   27.58              return false;
   27.59          }
   27.60 @@ -375,7 +383,7 @@
   27.61          callSiteTypes.pop();
   27.62          explodedArguments.pop();
   27.63  
   27.64 -        return newFunctionNode.setState(lc, CompilationState.BUILTINS_TRANSFORMED);
   27.65 +        return newFunctionNode;
   27.66      }
   27.67  
   27.68      private static boolean isApply(final CallNode callNode) {
    28.1 --- a/src/jdk/nashorn/internal/codegen/AssignSymbols.java	Thu Sep 24 10:00:42 2015 -0700
    28.2 +++ b/src/jdk/nashorn/internal/codegen/AssignSymbols.java	Thu Sep 24 10:09:56 2015 -0700
    28.3 @@ -65,7 +65,6 @@
    28.4  import jdk.nashorn.internal.ir.Expression;
    28.5  import jdk.nashorn.internal.ir.ForNode;
    28.6  import jdk.nashorn.internal.ir.FunctionNode;
    28.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    28.8  import jdk.nashorn.internal.ir.IdentNode;
    28.9  import jdk.nashorn.internal.ir.IndexNode;
   28.10  import jdk.nashorn.internal.ir.LexicalContext;
   28.11 @@ -149,12 +148,14 @@
   28.12      private final Deque<Set<String>> thisProperties = new ArrayDeque<>();
   28.13      private final Map<String, Symbol> globalSymbols = new HashMap<>(); //reuse the same global symbol
   28.14      private final Compiler compiler;
   28.15 +    private final boolean isOnDemand;
   28.16  
   28.17      public AssignSymbols(final Compiler compiler) {
   28.18          super(new LexicalContext());
   28.19          this.compiler = compiler;
   28.20          this.log   = initLogger(compiler.getContext());
   28.21          this.debug = log.isEnabled();
   28.22 +        this.isOnDemand = compiler.isOnDemandCompilation();
   28.23      }
   28.24  
   28.25      @Override
   28.26 @@ -242,7 +243,7 @@
   28.27  
   28.28      /**
   28.29       * Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically
   28.30 -     * used to create assignmnent of {@code :callee} to the function name symbol in self-referential function
   28.31 +     * used to create assignment of {@code :callee} to the function name symbol in self-referential function
   28.32       * expressions as well as for assignment of {@code :arguments} to {@code arguments}.
   28.33       *
   28.34       * @param name the ident node identifying the variable to initialize
   28.35 @@ -390,7 +391,7 @@
   28.36  
   28.37              // Create and add to appropriate block.
   28.38              symbol = createSymbol(name, flags);
   28.39 -            symbolBlock.putSymbol(lc, symbol);
   28.40 +            symbolBlock.putSymbol(symbol);
   28.41  
   28.42              if ((flags & IS_SCOPE) == 0) {
   28.43                  // Initial assumption; symbol can lose its slot later
   28.44 @@ -440,7 +441,7 @@
   28.45          start(block);
   28.46  
   28.47          if (lc.isFunctionBody()) {
   28.48 -            block.clearSymbols();
   28.49 +            assert !block.hasSymbols();
   28.50              final FunctionNode fn = lc.getCurrentFunction();
   28.51              if (isUnparsedFunction(fn)) {
   28.52                  // It's a skipped nested function. Just mark the symbols being used by it as being in use.
   28.53 @@ -459,7 +460,7 @@
   28.54      }
   28.55  
   28.56      private boolean isUnparsedFunction(final FunctionNode fn) {
   28.57 -        return compiler.isOnDemandCompilation() && fn != lc.getOutermostFunction();
   28.58 +        return isOnDemand && fn != lc.getOutermostFunction();
   28.59      }
   28.60  
   28.61      @Override
   28.62 @@ -747,28 +748,6 @@
   28.63          }
   28.64      }
   28.65  
   28.66 -    @Override
   28.67 -    public Node leaveBlock(final Block block) {
   28.68 -        // It's not necessary to guard the marking of symbols as locals with this "if" condition for
   28.69 -        // correctness, it's just an optimization -- runtime type calculation is not used when the compilation
   28.70 -        // is not an on-demand optimistic compilation, so we can skip locals marking then.
   28.71 -        if (compiler.useOptimisticTypes() && compiler.isOnDemandCompilation()) {
   28.72 -            // OTOH, we must not declare symbols from nested functions to be locals. As we're doing on-demand
   28.73 -            // compilation, and we're skipping parsing the function bodies for nested functions, this
   28.74 -            // basically only means their parameters. It'd be enough to mistakenly declare to be a local a
   28.75 -            // symbol in the outer function named the same as one of the parameters, though.
   28.76 -            if (lc.getFunction(block) == lc.getOutermostFunction()) {
   28.77 -                for (final Symbol symbol: block.getSymbols()) {
   28.78 -                    if (!symbol.isScope()) {
   28.79 -                        assert symbol.isVar() || symbol.isParam();
   28.80 -                        compiler.declareLocalSymbol(symbol.getName());
   28.81 -                    }
   28.82 -                }
   28.83 -            }
   28.84 -        }
   28.85 -        return block;
   28.86 -    }
   28.87 -
   28.88      private Node leaveDELETE(final UnaryNode unaryNode) {
   28.89          final FunctionNode currentFunctionNode = lc.getCurrentFunction();
   28.90          final boolean      strictMode          = currentFunctionNode.isStrict();
   28.91 @@ -786,9 +765,9 @@
   28.92  
   28.93              if (symbol.isThis()) {
   28.94                  // Can't delete "this", ignore and return true
   28.95 -                return LiteralNode.newInstance(unaryNode, true).accept(this);
   28.96 +                return LiteralNode.newInstance(unaryNode, true);
   28.97              }
   28.98 -            final Expression literalNode = (Expression)LiteralNode.newInstance(unaryNode, name).accept(this);
   28.99 +            final Expression literalNode = LiteralNode.newInstance(unaryNode, name);
  28.100              final boolean failDelete = strictMode || (!symbol.isScope() && (symbol.isParam() || (symbol.isVar() && !symbol.isProgramLevel())));
  28.101  
  28.102              if (!failDelete) {
  28.103 @@ -799,7 +778,7 @@
  28.104  
  28.105              if (failDelete) {
  28.106                  request = Request.FAIL_DELETE;
  28.107 -            } else if (symbol.isGlobal() && !symbol.isFunctionDeclaration()) {
  28.108 +            } else if ((symbol.isGlobal() && !symbol.isFunctionDeclaration()) || symbol.isProgramLevel()) {
  28.109                  request = Request.SLOW_DELETE;
  28.110              }
  28.111          } else if (rhs instanceof AccessNode) {
  28.112 @@ -807,7 +786,7 @@
  28.113              final String     property = ((AccessNode)rhs).getProperty();
  28.114  
  28.115              args.add(base);
  28.116 -            args.add((Expression)LiteralNode.newInstance(unaryNode, property).accept(this));
  28.117 +            args.add(LiteralNode.newInstance(unaryNode, property));
  28.118              args.add(strictFlagNode);
  28.119  
  28.120          } else if (rhs instanceof IndexNode) {
  28.121 @@ -820,15 +799,15 @@
  28.122              args.add(strictFlagNode);
  28.123  
  28.124          } else {
  28.125 -            return LiteralNode.newInstance(unaryNode, true).accept(this);
  28.126 +            return LiteralNode.newInstance(unaryNode, true);
  28.127          }
  28.128 -        return new RuntimeNode(unaryNode, request, args).accept(this);
  28.129 +        return new RuntimeNode(unaryNode, request, args);
  28.130      }
  28.131  
  28.132      @Override
  28.133      public Node leaveForNode(final ForNode forNode) {
  28.134          if (forNode.isForIn()) {
  28.135 -            forNode.setIterator(newObjectInternal(ITERATOR_PREFIX)); //NASHORN-73
  28.136 +            return forNode.setIterator(lc, newObjectInternal(ITERATOR_PREFIX)); //NASHORN-73
  28.137          }
  28.138  
  28.139          return end(forNode);
  28.140 @@ -848,7 +827,7 @@
  28.141                         lc.applyTopFlags(functionNode))))
  28.142                         .setThisProperties(lc, thisProperties.pop().size()));
  28.143          }
  28.144 -        return finalizedFunction.setState(lc, CompilationState.SYMBOLS_ASSIGNED);
  28.145 +        return finalizedFunction;
  28.146      }
  28.147  
  28.148      @Override
  28.149 @@ -904,19 +883,18 @@
  28.150      public Node leaveSwitchNode(final SwitchNode switchNode) {
  28.151          // We only need a symbol for the tag if it's not an integer switch node
  28.152          if(!switchNode.isUniqueInteger()) {
  28.153 -            switchNode.setTag(newObjectInternal(SWITCH_TAG_PREFIX));
  28.154 +            return switchNode.setTag(lc, newObjectInternal(SWITCH_TAG_PREFIX));
  28.155          }
  28.156          return switchNode;
  28.157      }
  28.158  
  28.159      @Override
  28.160      public Node leaveTryNode(final TryNode tryNode) {
  28.161 -        tryNode.setException(exceptionSymbol());
  28.162          assert tryNode.getFinallyBody() == null;
  28.163  
  28.164          end(tryNode);
  28.165  
  28.166 -        return tryNode;
  28.167 +        return tryNode.setException(lc, exceptionSymbol());
  28.168      }
  28.169  
  28.170      private Node leaveTYPEOF(final UnaryNode unaryNode) {
  28.171 @@ -925,13 +903,13 @@
  28.172          final List<Expression> args = new ArrayList<>();
  28.173          if (rhs instanceof IdentNode && !isParamOrVar((IdentNode)rhs)) {
  28.174              args.add(compilerConstantIdentifier(SCOPE));
  28.175 -            args.add((Expression)LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null
  28.176 +            args.add(LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName())); //null
  28.177          } else {
  28.178              args.add(rhs);
  28.179 -            args.add((Expression)LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this'
  28.180 +            args.add(LiteralNode.newInstance(unaryNode)); //null, do not reuse token of identifier rhs, it can be e.g. 'this'
  28.181          }
  28.182  
  28.183 -        final Node runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args).accept(this);
  28.184 +        final Node runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args);
  28.185  
  28.186          end(unaryNode);
  28.187  
  28.188 @@ -939,7 +917,7 @@
  28.189      }
  28.190  
  28.191      private FunctionNode markProgramBlock(final FunctionNode functionNode) {
  28.192 -        if (compiler.isOnDemandCompilation() || !functionNode.isProgram()) {
  28.193 +        if (isOnDemand || !functionNode.isProgram()) {
  28.194              return functionNode;
  28.195          }
  28.196  
    29.1 --- a/src/jdk/nashorn/internal/codegen/AstSerializer.java	Thu Sep 24 10:00:42 2015 -0700
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,73 +0,0 @@
    29.4 -/*
    29.5 - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    29.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    29.7 - *
    29.8 - * This code is free software; you can redistribute it and/or modify it
    29.9 - * under the terms of the GNU General Public License version 2 only, as
   29.10 - * published by the Free Software Foundation.  Oracle designates this
   29.11 - * particular file as subject to the "Classpath" exception as provided
   29.12 - * by Oracle in the LICENSE file that accompanied this code.
   29.13 - *
   29.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   29.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   29.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   29.17 - * version 2 for more details (a copy is included in the LICENSE file that
   29.18 - * accompanied this code).
   29.19 - *
   29.20 - * You should have received a copy of the GNU General Public License version
   29.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   29.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   29.23 - *
   29.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   29.25 - * or visit www.oracle.com if you need additional information or have any
   29.26 - * questions.
   29.27 - */
   29.28 -package jdk.nashorn.internal.codegen;
   29.29 -
   29.30 -import java.io.ByteArrayOutputStream;
   29.31 -import java.io.IOException;
   29.32 -import java.io.ObjectOutputStream;
   29.33 -import java.util.Collections;
   29.34 -import java.util.zip.Deflater;
   29.35 -import java.util.zip.DeflaterOutputStream;
   29.36 -import jdk.nashorn.internal.ir.Block;
   29.37 -import jdk.nashorn.internal.ir.FunctionNode;
   29.38 -import jdk.nashorn.internal.ir.LexicalContext;
   29.39 -import jdk.nashorn.internal.ir.Node;
   29.40 -import jdk.nashorn.internal.ir.Statement;
   29.41 -import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   29.42 -import jdk.nashorn.internal.runtime.options.Options;
   29.43 -
   29.44 -/**
   29.45 - * This static utility class performs serialization of FunctionNode ASTs to a byte array.
   29.46 - * The format is a standard Java serialization stream, deflated.
   29.47 - */
   29.48 -final class AstSerializer {
   29.49 -    // Experimentally, we concluded that compression level 4 gives a good tradeoff between serialization speed
   29.50 -    // and size.
   29.51 -    private static final int COMPRESSION_LEVEL = Options.getIntProperty("nashorn.serialize.compression", 4);
   29.52 -    static byte[] serialize(final FunctionNode fn) {
   29.53 -        final ByteArrayOutputStream out = new ByteArrayOutputStream();
   29.54 -        final Deflater deflater = new Deflater(COMPRESSION_LEVEL);
   29.55 -        try (final ObjectOutputStream oout = new ObjectOutputStream(new DeflaterOutputStream(out, deflater))) {
   29.56 -            oout.writeObject(removeInnerFunctionBodies(fn));
   29.57 -        } catch (final IOException e) {
   29.58 -            throw new AssertionError("Unexpected exception serializing function", e);
   29.59 -        } finally {
   29.60 -            deflater.end();
   29.61 -        }
   29.62 -        return out.toByteArray();
   29.63 -    }
   29.64 -
   29.65 -    private static FunctionNode removeInnerFunctionBodies(final FunctionNode fn) {
   29.66 -        return (FunctionNode)fn.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   29.67 -            @Override
   29.68 -            public Node leaveBlock(final Block block) {
   29.69 -                if (lc.isFunctionBody() && lc.getFunction(block) != lc.getOutermostFunction()) {
   29.70 -                    return block.setStatements(lc, Collections.<Statement>emptyList());
   29.71 -                }
   29.72 -                return super.leaveBlock(block);
   29.73 -            }
   29.74 -        });
   29.75 -    }
   29.76 -}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/src/jdk/nashorn/internal/codegen/CacheAst.java	Thu Sep 24 10:09:56 2015 -0700
    30.3 @@ -0,0 +1,87 @@
    30.4 +/*
    30.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
    30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    30.7 + *
    30.8 + * This code is free software; you can redistribute it and/or modify it
    30.9 + * under the terms of the GNU General Public License version 2 only, as
   30.10 + * published by the Free Software Foundation.  Oracle designates this
   30.11 + * particular file as subject to the "Classpath" exception as provided
   30.12 + * by Oracle in the LICENSE file that accompanied this code.
   30.13 + *
   30.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   30.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   30.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   30.17 + * version 2 for more details (a copy is included in the LICENSE file that
   30.18 + * accompanied this code).
   30.19 + *
   30.20 + * You should have received a copy of the GNU General Public License version
   30.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   30.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   30.23 + *
   30.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   30.25 + * or visit www.oracle.com if you need additional information or have any
   30.26 + * questions.
   30.27 + */
   30.28 +
   30.29 +package jdk.nashorn.internal.codegen;
   30.30 +
   30.31 +import java.util.ArrayDeque;
   30.32 +import java.util.Collections;
   30.33 +import java.util.Deque;
   30.34 +import jdk.nashorn.internal.ir.FunctionNode;
   30.35 +import jdk.nashorn.internal.ir.LexicalContext;
   30.36 +import jdk.nashorn.internal.ir.Node;
   30.37 +import jdk.nashorn.internal.ir.Statement;
   30.38 +import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   30.39 +import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
   30.40 +
   30.41 +class CacheAst extends NodeVisitor<LexicalContext> {
   30.42 +    private final Deque<RecompilableScriptFunctionData> dataStack = new ArrayDeque<>();
   30.43 +
   30.44 +    private final Compiler compiler;
   30.45 +
   30.46 +    CacheAst(final Compiler compiler) {
   30.47 +        super(new LexicalContext());
   30.48 +        this.compiler = compiler;
   30.49 +        assert !compiler.isOnDemandCompilation();
   30.50 +    }
   30.51 +
   30.52 +    @Override
   30.53 +    public boolean enterFunctionNode(final FunctionNode functionNode) {
   30.54 +        final int id = functionNode.getId();
   30.55 +        // It isn't necessary to keep a stack of RecompilableScriptFunctionData, but then we'd need to do a
   30.56 +        // potentially transitive lookup with compiler.getScriptFunctionData(id) for deeper functions; this way
   30.57 +        // we keep it constant time.
   30.58 +        dataStack.push(dataStack.isEmpty() ? compiler.getScriptFunctionData(id) : dataStack.peek().getScriptFunctionData(id));
   30.59 +        return true;
   30.60 +    }
   30.61 +
   30.62 +    @Override
   30.63 +    public Node leaveFunctionNode(final FunctionNode functionNode) {
   30.64 +        final RecompilableScriptFunctionData data = dataStack.pop();
   30.65 +        if (functionNode.isSplit()) {
   30.66 +            // NOTE: cache only split function ASTs from eager pass. Caching non-split functions would require
   30.67 +            // some additional work, namely creating the concept of "uncacheable" function and reworking
   30.68 +            // ApplySpecialization to ensure that functions undergoing apply-to-call transformations are not
   30.69 +            // cacheable as well as recomputing Symbol.useCount when caching the eagerly parsed AST.
   30.70 +            // Recomputing Symbol.useCount would be needed so it will only reflect uses from within the
   30.71 +            // function being cached (and not reflect uses from its own nested functions or functions it is
   30.72 +            // nested in). This is consistent with the count an on-demand recompilation of the function would
   30.73 +            // produce. This is important as the decision to emit shared scope calls is based on this count,
   30.74 +            // and if it is not matched between a previous version of the code and its deoptimizing rest-of
   30.75 +            // compilation, it can result in rest-of not emitting a shared scope call where a previous version
   30.76 +            // of the code (compiled from a cached eager pre-pass seeing higher (global) useCount) would emit
   30.77 +            // it, causing a mismatch in stack shapes between previous code and its rest-of.
   30.78 +            data.setCachedAst(functionNode);
   30.79 +        }
   30.80 +
   30.81 +        if (!dataStack.isEmpty() && ((dataStack.peek().getFunctionFlags() & FunctionNode.IS_SPLIT) != 0)) {
   30.82 +            // Return a function node with no body so that caching outer functions doesn't hold on to nested
   30.83 +            // functions' bodies. Note we're doing this only for functions directly nested inside split
   30.84 +            // functions, since we're only caching the split ones. It is not necessary to limit body removal
   30.85 +            // to just these functions, but it's a cheap way to prevent unnecessary AST mutations.
   30.86 +            return functionNode.setBody(lc, functionNode.getBody().setStatements(null, Collections.<Statement>emptyList()));
   30.87 +        }
   30.88 +        return functionNode;
   30.89 +    }
   30.90 +}
    31.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Sep 24 10:00:42 2015 -0700
    31.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Sep 24 10:09:56 2015 -0700
    31.3 @@ -93,7 +93,6 @@
    31.4  import jdk.nashorn.internal.ir.ExpressionStatement;
    31.5  import jdk.nashorn.internal.ir.ForNode;
    31.6  import jdk.nashorn.internal.ir.FunctionNode;
    31.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    31.8  import jdk.nashorn.internal.ir.GetSplitState;
    31.9  import jdk.nashorn.internal.ir.IdentNode;
   31.10  import jdk.nashorn.internal.ir.IfNode;
   31.11 @@ -132,7 +131,6 @@
   31.12  import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
   31.13  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   31.14  import jdk.nashorn.internal.objects.Global;
   31.15 -import jdk.nashorn.internal.objects.ScriptFunctionImpl;
   31.16  import jdk.nashorn.internal.parser.Lexer.RegexToken;
   31.17  import jdk.nashorn.internal.parser.TokenType;
   31.18  import jdk.nashorn.internal.runtime.Context;
   31.19 @@ -195,9 +193,9 @@
   31.20      private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
   31.21              "ensureNumber", double.class, Object.class, int.class);
   31.22  
   31.23 -    private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
   31.24 +    private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunction.class,
   31.25              "create", ScriptFunction.class, Object[].class, int.class, ScriptObject.class);
   31.26 -    private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
   31.27 +    private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunction.class,
   31.28              "create", ScriptFunction.class, Object[].class, int.class);
   31.29  
   31.30      private static final Call TO_NUMBER_FOR_EQ = CompilerConstants.staticCallNoLookup(JSType.class,
   31.31 @@ -249,7 +247,7 @@
   31.32      private final Set<String> emittedMethods = new HashSet<>();
   31.33  
   31.34      // Function Id -> ContinuationInfo. Used by compilation of rest-of function only.
   31.35 -    private final Map<Integer, ContinuationInfo> fnIdToContinuationInfo = new HashMap<>();
   31.36 +    private ContinuationInfo continuationInfo;
   31.37  
   31.38      private final Deque<Label> scopeEntryLabels = new ArrayDeque<>();
   31.39  
   31.40 @@ -349,11 +347,20 @@
   31.41          final int flags = getScopeCallSiteFlags(symbol);
   31.42          if (isFastScope(symbol)) {
   31.43              // Only generate shared scope getter for fast-scope symbols so we know we can dial in correct scope.
   31.44 -            if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD && !isOptimisticOrRestOf()) {
   31.45 -                method.loadCompilerConstant(SCOPE);
   31.46 -                // As shared scope vars are only used in non-optimistic compilation, we switch from using TypeBounds to
   31.47 +            if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD && !identNode.isOptimistic()) {
   31.48 +                // As shared scope vars are only used with non-optimistic identifiers, we switch from using TypeBounds to
   31.49                  // just a single definitive type, resultBounds.widest.
   31.50 -                loadSharedScopeVar(resultBounds.widest, symbol, flags);
   31.51 +                new OptimisticOperation(identNode, TypeBounds.OBJECT) {
   31.52 +                    @Override
   31.53 +                    void loadStack() {
   31.54 +                        method.loadCompilerConstant(SCOPE);
   31.55 +                    }
   31.56 +
   31.57 +                    @Override
   31.58 +                    void consumeStack() {
   31.59 +                        loadSharedScopeVar(resultBounds.widest, symbol, flags);
   31.60 +                    }
   31.61 +                }.emit();
   31.62              } else {
   31.63                  new LoadFastScopeVar(identNode, resultBounds, flags).emit();
   31.64              }
   31.65 @@ -384,10 +391,6 @@
   31.66          return continuationEntryPoints != null;
   31.67      }
   31.68  
   31.69 -    private boolean isOptimisticOrRestOf() {
   31.70 -        return useOptimisticTypes() || isRestOf();
   31.71 -    }
   31.72 -
   31.73      private boolean isCurrentContinuationEntryPoint(final int programPoint) {
   31.74          return isRestOf() && getCurrentContinuationEntryPoint() == programPoint;
   31.75      }
   31.76 @@ -464,12 +467,8 @@
   31.77      }
   31.78  
   31.79      private MethodEmitter loadSharedScopeVar(final Type valueType, final Symbol symbol, final int flags) {
   31.80 -        assert !isOptimisticOrRestOf();
   31.81 -        if (isFastScope(symbol)) {
   31.82 -            method.load(getScopeProtoDepth(lc.getCurrentBlock(), symbol));
   31.83 -        } else {
   31.84 -            method.load(-1);
   31.85 -        }
   31.86 +        assert isFastScope(symbol);
   31.87 +        method.load(getScopeProtoDepth(lc.getCurrentBlock(), symbol));
   31.88          return lc.getScopeGet(unit, symbol, valueType, flags).generateInvoke(method);
   31.89      }
   31.90  
   31.91 @@ -1494,7 +1493,7 @@
   31.92                      int argsCount;
   31.93                      @Override
   31.94                      void loadStack() {
   31.95 -                        /**
   31.96 +                        /*
   31.97                           * We want to load 'eval' to check if it is indeed global builtin eval.
   31.98                           * If this eval call is inside a 'with' statement, dyn:getMethod|getProp|getElem
   31.99                           * would be generated if ident is a "isFunction". But, that would result in a
  31.100 @@ -1573,7 +1572,7 @@
  31.101                      } else if (useCount <= SharedScopeCall.FAST_SCOPE_CALL_THRESHOLD
  31.102                              || !isFastScope(symbol) && useCount <= SharedScopeCall.SLOW_SCOPE_CALL_THRESHOLD
  31.103                              || CodeGenerator.this.lc.inDynamicScope()
  31.104 -                            || isOptimisticOrRestOf()) {
  31.105 +                            || callNode.isOptimistic()) {
  31.106                          scopeCall(node, flags);
  31.107                      } else {
  31.108                          sharedScopeCall(node, flags);
  31.109 @@ -2070,8 +2069,6 @@
  31.110  
  31.111      @Override
  31.112      public boolean enterFunctionNode(final FunctionNode functionNode) {
  31.113 -        final int fnId = functionNode.getId();
  31.114 -
  31.115          if (skipFunction(functionNode)) {
  31.116              // In case we are not generating code for the function, we must create or retrieve the function object and
  31.117              // load it on the stack here.
  31.118 @@ -2109,9 +2106,9 @@
  31.119              method.begin();
  31.120  
  31.121              if (isRestOf()) {
  31.122 -                final ContinuationInfo ci = new ContinuationInfo();
  31.123 -                fnIdToContinuationInfo.put(fnId, ci);
  31.124 -                method.gotoLoopStart(ci.getHandlerLabel());
  31.125 +                assert continuationInfo == null;
  31.126 +                continuationInfo = new ContinuationInfo();
  31.127 +                method.gotoLoopStart(continuationInfo.getHandlerLabel());
  31.128              }
  31.129          }
  31.130  
  31.131 @@ -2144,7 +2141,7 @@
  31.132                  markOptimistic = false;
  31.133              }
  31.134  
  31.135 -            FunctionNode newFunctionNode = functionNode.setState(lc, CompilationState.BYTECODE_GENERATED);
  31.136 +            FunctionNode newFunctionNode = functionNode;
  31.137              if (markOptimistic) {
  31.138                  newFunctionNode = newFunctionNode.setFlag(lc, FunctionNode.IS_DEOPTIMIZABLE);
  31.139              }
  31.140 @@ -4331,7 +4328,7 @@
  31.141          }
  31.142  
  31.143          private void prologue() {
  31.144 -            /**
  31.145 +            /*
  31.146               * This loads the parts of the target, e.g base and index. they are kept
  31.147               * on the stack throughout the store and used at the end to execute it
  31.148               */
  31.149 @@ -4799,7 +4796,7 @@
  31.150           * conversion has no side effects.
  31.151           * @param name the name of the property being get
  31.152           * @param flags call site flags
  31.153 -         * @param isMethod whether we're preferrably retrieving a function
  31.154 +         * @param isMethod whether we're preferably retrieving a function
  31.155           * @return the current method emitter
  31.156           */
  31.157          MethodEmitter dynamicGet(final String name, final int flags, final boolean isMethod, final boolean isIndex) {
  31.158 @@ -5231,7 +5228,7 @@
  31.159          private Type returnValueType;
  31.160          // If we are in the middle of an object literal initialization, we need to update the map
  31.161          private PropertyMap objectLiteralMap;
  31.162 -        // Object literal stack depth for object literal - not necessarly top if property is a tree
  31.163 +        // Object literal stack depth for object literal - not necessarily top if property is a tree
  31.164          private int objectLiteralStackDepth = -1;
  31.165          // The line number at the continuation point
  31.166          private int lineNumber;
  31.167 @@ -5308,7 +5305,7 @@
  31.168      }
  31.169  
  31.170      private ContinuationInfo getContinuationInfo() {
  31.171 -        return fnIdToContinuationInfo.get(lc.getCurrentFunction().getId());
  31.172 +        return continuationInfo;
  31.173      }
  31.174  
  31.175      private void generateContinuationHandler() {
  31.176 @@ -5396,7 +5393,7 @@
  31.177                  method.load(lvarTypes.get(slot), slot);
  31.178                  method.convert(stackTypes[i]);
  31.179                  // stack: s0=object literal being initialized
  31.180 -                // change map of s0 so that the property we are initilizing when we failed
  31.181 +                // change map of s0 so that the property we are initializing when we failed
  31.182                  // is now ci.returnValueType
  31.183                  if (i == objectLiteralStackDepth) {
  31.184                      method.dup();
    32.1 --- a/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Thu Sep 24 10:00:42 2015 -0700
    32.2 +++ b/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Thu Sep 24 10:09:56 2015 -0700
    32.3 @@ -25,34 +25,21 @@
    32.4  
    32.5  package jdk.nashorn.internal.codegen;
    32.6  
    32.7 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.BUILTINS_TRANSFORMED;
    32.8 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.BYTECODE_GENERATED;
    32.9 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.BYTECODE_INSTALLED;
   32.10 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.CONSTANT_FOLDED;
   32.11 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.INITIALIZED;
   32.12 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.LOCAL_VARIABLE_TYPES_CALCULATED;
   32.13 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.LOWERED;
   32.14 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.OPTIMISTIC_TYPES_ASSIGNED;
   32.15 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.PARSED;
   32.16 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SCOPE_DEPTHS_COMPUTED;
   32.17 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SPLIT;
   32.18 -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SYMBOLS_ASSIGNED;
   32.19  import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
   32.20  
   32.21  import java.io.PrintWriter;
   32.22 -import java.util.EnumSet;
   32.23  import java.util.HashMap;
   32.24  import java.util.LinkedHashMap;
   32.25  import java.util.Map;
   32.26  import java.util.Map.Entry;
   32.27  import java.util.Set;
   32.28 -import jdk.nashorn.internal.AssertsEnabled;
   32.29  import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
   32.30 +import jdk.nashorn.internal.ir.Block;
   32.31  import jdk.nashorn.internal.ir.FunctionNode;
   32.32 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
   32.33  import jdk.nashorn.internal.ir.LexicalContext;
   32.34  import jdk.nashorn.internal.ir.LiteralNode;
   32.35  import jdk.nashorn.internal.ir.Node;
   32.36 +import jdk.nashorn.internal.ir.Symbol;
   32.37  import jdk.nashorn.internal.ir.debug.ASTWriter;
   32.38  import jdk.nashorn.internal.ir.debug.PrintVisitor;
   32.39  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   32.40 @@ -65,15 +52,9 @@
   32.41   * A compilation phase is a step in the processes of turning a JavaScript
   32.42   * FunctionNode into bytecode. It has an optional return value.
   32.43   */
   32.44 -enum CompilationPhase {
   32.45 -    /**
   32.46 -     * Constant folding pass Simple constant folding that will make elementary
   32.47 -     * constructs go away
   32.48 -     */
   32.49 -    CONSTANT_FOLDING_PHASE(
   32.50 -            EnumSet.of(
   32.51 -                INITIALIZED,
   32.52 -                PARSED)) {
   32.53 +abstract class CompilationPhase {
   32.54 +
   32.55 +    private static final class ConstantFoldingPhase extends CompilationPhase {
   32.56          @Override
   32.57          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
   32.58              return transformFunction(fn, new FoldConstants(compiler));
   32.59 @@ -83,20 +64,15 @@
   32.60          public String toString() {
   32.61              return "'Constant Folding'";
   32.62          }
   32.63 -    },
   32.64 +    }
   32.65  
   32.66      /**
   32.67 -     * Lower (Control flow pass) Finalizes the control flow. Clones blocks for
   32.68 -     * finally constructs and similar things. Establishes termination criteria
   32.69 -     * for nodes Guarantee return instructions to method making sure control
   32.70 -     * flow cannot fall off the end. Replacing high level nodes with lower such
   32.71 -     * as runtime nodes where applicable.
   32.72 +     * Constant folding pass Simple constant folding that will make elementary
   32.73 +     * constructs go away
   32.74       */
   32.75 -    LOWERING_PHASE(
   32.76 -            EnumSet.of(
   32.77 -                INITIALIZED,
   32.78 -                PARSED,
   32.79 -                CONSTANT_FOLDED)) {
   32.80 +    static final CompilationPhase CONSTANT_FOLDING_PHASE = new ConstantFoldingPhase();
   32.81 +
   32.82 +    private static final class LoweringPhase extends CompilationPhase {
   32.83          @Override
   32.84          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
   32.85              return transformFunction(fn, new Lower(compiler));
   32.86 @@ -106,42 +82,35 @@
   32.87          public String toString() {
   32.88              return "'Control Flow Lowering'";
   32.89          }
   32.90 -    },
   32.91 +    }
   32.92  
   32.93      /**
   32.94 -     * Phase used only when doing optimistic code generation. It assigns all potentially
   32.95 -     * optimistic ops a program point so that an UnwarrantedException knows from where
   32.96 -     * a guess went wrong when creating the continuation to roll back this execution
   32.97 +     * Lower (Control flow pass) Finalizes the control flow. Clones blocks for
   32.98 +     * finally constructs and similar things. Establishes termination criteria
   32.99 +     * for nodes Guarantee return instructions to method making sure control
  32.100 +     * flow cannot fall off the end. Replacing high level nodes with lower such
  32.101 +     * as runtime nodes where applicable.
  32.102       */
  32.103 -    TRANSFORM_BUILTINS_PHASE(
  32.104 -            EnumSet.of(
  32.105 -                    INITIALIZED,
  32.106 -                    PARSED,
  32.107 -                    CONSTANT_FOLDED,
  32.108 -                    LOWERED)) {
  32.109 -        //we only do this if we have a param type map, otherwise this is not a specialized recompile
  32.110 +    static final CompilationPhase LOWERING_PHASE = new LoweringPhase();
  32.111 +
  32.112 +    private static final class ApplySpecializationPhase extends CompilationPhase {
  32.113          @Override
  32.114          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.115 -            return setStates(transformFunction(fn, new ApplySpecialization(compiler)), BUILTINS_TRANSFORMED);
  32.116 +            return transformFunction(fn, new ApplySpecialization(compiler));
  32.117          }
  32.118  
  32.119          @Override
  32.120          public String toString() {
  32.121              return "'Builtin Replacement'";
  32.122          }
  32.123 -    },
  32.124 +    };
  32.125  
  32.126      /**
  32.127 -     * Splitter Split the AST into several compile units based on a heuristic size calculation.
  32.128 -     * Split IR can lead to scope information being changed.
  32.129 +     * Phase used to transform Function.prototype.apply.
  32.130       */
  32.131 -    SPLITTING_PHASE(
  32.132 -            EnumSet.of(
  32.133 -                    INITIALIZED,
  32.134 -                    PARSED,
  32.135 -                    CONSTANT_FOLDED,
  32.136 -                    LOWERED,
  32.137 -                    BUILTINS_TRANSFORMED)) {
  32.138 +    static final CompilationPhase APPLY_SPECIALIZATION_PHASE = new ApplySpecializationPhase();
  32.139 +
  32.140 +    private static final class SplittingPhase extends CompilationPhase {
  32.141          @Override
  32.142          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.143              final CompileUnit  outermostCompileUnit = compiler.addCompileUnit(0L);
  32.144 @@ -168,16 +137,15 @@
  32.145          public String toString() {
  32.146              return "'Code Splitting'";
  32.147          }
  32.148 -    },
  32.149 +    };
  32.150  
  32.151 -    PROGRAM_POINT_PHASE(
  32.152 -            EnumSet.of(
  32.153 -                    INITIALIZED,
  32.154 -                    PARSED,
  32.155 -                    CONSTANT_FOLDED,
  32.156 -                    LOWERED,
  32.157 -                    BUILTINS_TRANSFORMED,
  32.158 -                    SPLIT)) {
  32.159 +    /**
  32.160 +     * Splitter Split the AST into several compile units based on a heuristic size calculation.
  32.161 +     * Split IR can lead to scope information being changed.
  32.162 +     */
  32.163 +    static final CompilationPhase SPLITTING_PHASE = new SplittingPhase();
  32.164 +
  32.165 +    private static final class ProgramPointPhase extends CompilationPhase {
  32.166          @Override
  32.167          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.168              return transformFunction(fn, new ProgramPoints());
  32.169 @@ -187,43 +155,34 @@
  32.170          public String toString() {
  32.171              return "'Program Point Calculation'";
  32.172          }
  32.173 -    },
  32.174 +    };
  32.175  
  32.176 -    SERIALIZE_SPLIT_PHASE(
  32.177 -            EnumSet.of(
  32.178 -                    INITIALIZED,
  32.179 -                    PARSED,
  32.180 -                    CONSTANT_FOLDED,
  32.181 -                    LOWERED,
  32.182 -                    BUILTINS_TRANSFORMED,
  32.183 -                    SPLIT)) {
  32.184 +    static final CompilationPhase PROGRAM_POINT_PHASE = new ProgramPointPhase();
  32.185 +
  32.186 +    private static final class CacheAstPhase extends CompilationPhase {
  32.187          @Override
  32.188          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.189 -            return transformFunction(fn, new NodeVisitor<LexicalContext>(new LexicalContext()) {
  32.190 -                @Override
  32.191 -                public boolean enterFunctionNode(final FunctionNode functionNode) {
  32.192 -                    if (functionNode.isSplit()) {
  32.193 -                        compiler.serializeAst(functionNode);
  32.194 -                    }
  32.195 -                    return true;
  32.196 -                }
  32.197 -            });
  32.198 +            if (!compiler.isOnDemandCompilation()) {
  32.199 +                // Only do this on initial preprocessing of the source code. For on-demand compilations from
  32.200 +                // source, FindScopeDepths#leaveFunctionNode() calls data.setCachedAst() for the sole function
  32.201 +                // being compiled.
  32.202 +                transformFunction(fn, new CacheAst(compiler));
  32.203 +            }
  32.204 +            // NOTE: we're returning the original fn as we have destructively modified the cached functions by
  32.205 +            // removing their bodies. This step is associating FunctionNode objects with
  32.206 +            // RecompilableScriptFunctionData; it's not really modifying the AST.
  32.207 +            return fn;
  32.208          }
  32.209  
  32.210          @Override
  32.211          public String toString() {
  32.212 -            return "'Serialize Split Functions'";
  32.213 +            return "'Cache ASTs'";
  32.214          }
  32.215 -    },
  32.216 +    };
  32.217  
  32.218 -    SYMBOL_ASSIGNMENT_PHASE(
  32.219 -            EnumSet.of(
  32.220 -                    INITIALIZED,
  32.221 -                    PARSED,
  32.222 -                    CONSTANT_FOLDED,
  32.223 -                    LOWERED,
  32.224 -                    BUILTINS_TRANSFORMED,
  32.225 -                    SPLIT)) {
  32.226 +    static final CompilationPhase CACHE_AST_PHASE = new CacheAstPhase();
  32.227 +
  32.228 +    private static final class SymbolAssignmentPhase extends CompilationPhase {
  32.229          @Override
  32.230          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.231              return transformFunction(fn, new AssignSymbols(compiler));
  32.232 @@ -233,17 +192,11 @@
  32.233          public String toString() {
  32.234              return "'Symbol Assignment'";
  32.235          }
  32.236 -    },
  32.237 +    };
  32.238  
  32.239 -    SCOPE_DEPTH_COMPUTATION_PHASE(
  32.240 -            EnumSet.of(
  32.241 -                    INITIALIZED,
  32.242 -                    PARSED,
  32.243 -                    CONSTANT_FOLDED,
  32.244 -                    LOWERED,
  32.245 -                    BUILTINS_TRANSFORMED,
  32.246 -                    SPLIT,
  32.247 -                    SYMBOLS_ASSIGNED)) {
  32.248 +    static final CompilationPhase SYMBOL_ASSIGNMENT_PHASE = new SymbolAssignmentPhase();
  32.249 +
  32.250 +    private static final class ScopeDepthComputationPhase extends CompilationPhase {
  32.251          @Override
  32.252          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.253              return transformFunction(fn, new FindScopeDepths(compiler));
  32.254 @@ -253,43 +206,66 @@
  32.255          public String toString() {
  32.256              return "'Scope Depth Computation'";
  32.257          }
  32.258 -    },
  32.259 +    };
  32.260  
  32.261 -    OPTIMISTIC_TYPE_ASSIGNMENT_PHASE(
  32.262 -            EnumSet.of(
  32.263 -                    INITIALIZED,
  32.264 -                    PARSED,
  32.265 -                    CONSTANT_FOLDED,
  32.266 -                    LOWERED,
  32.267 -                    BUILTINS_TRANSFORMED,
  32.268 -                    SPLIT,
  32.269 -                    SYMBOLS_ASSIGNED,
  32.270 -                    SCOPE_DEPTHS_COMPUTED)) {
  32.271 +    static final CompilationPhase SCOPE_DEPTH_COMPUTATION_PHASE = new ScopeDepthComputationPhase();
  32.272 +
  32.273 +    private static final class DeclareLocalSymbolsPhase extends CompilationPhase {
  32.274 +        @Override
  32.275 +        FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.276 +            // It's not necessary to guard the marking of symbols as locals with this "if" condition for
  32.277 +            // correctness, it's just an optimization -- runtime type calculation is not used when the compilation
  32.278 +            // is not an on-demand optimistic compilation, so we can skip locals marking then.
  32.279 +            if (compiler.useOptimisticTypes() && compiler.isOnDemandCompilation()) {
  32.280 +                fn.getBody().accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  32.281 +                    @Override
  32.282 +                    public boolean enterFunctionNode(final FunctionNode functionNode) {
  32.283 +                        // OTOH, we must not declare symbols from nested functions to be locals. As we're doing on-demand
  32.284 +                        // compilation, and we're skipping parsing the function bodies for nested functions, this
  32.285 +                        // basically only means their parameters. It'd be enough to mistakenly declare to be a local a
  32.286 +                        // symbol in the outer function named the same as one of the parameters, though.
  32.287 +                        return false;
  32.288 +                    };
  32.289 +                    @Override
  32.290 +                    public boolean enterBlock(final Block block) {
  32.291 +                        for (final Symbol symbol: block.getSymbols()) {
  32.292 +                            if (!symbol.isScope()) {
  32.293 +                                compiler.declareLocalSymbol(symbol.getName());
  32.294 +                            }
  32.295 +                        }
  32.296 +                        return true;
  32.297 +                    };
  32.298 +                });
  32.299 +            }
  32.300 +            return fn;
  32.301 +        }
  32.302 +
  32.303 +        @Override
  32.304 +        public String toString() {
  32.305 +            return "'Local Symbols Declaration'";
  32.306 +        }
  32.307 +    };
  32.308 +
  32.309 +    static final CompilationPhase DECLARE_LOCAL_SYMBOLS_PHASE = new DeclareLocalSymbolsPhase();
  32.310 +
  32.311 +    private static final class OptimisticTypeAssignmentPhase extends CompilationPhase {
  32.312          @Override
  32.313          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.314              if (compiler.useOptimisticTypes()) {
  32.315                  return transformFunction(fn, new OptimisticTypesCalculator(compiler));
  32.316              }
  32.317 -            return setStates(fn, OPTIMISTIC_TYPES_ASSIGNED);
  32.318 +            return fn;
  32.319          }
  32.320  
  32.321          @Override
  32.322          public String toString() {
  32.323              return "'Optimistic Type Assignment'";
  32.324          }
  32.325 -    },
  32.326 +    }
  32.327  
  32.328 -    LOCAL_VARIABLE_TYPE_CALCULATION_PHASE(
  32.329 -            EnumSet.of(
  32.330 -                    INITIALIZED,
  32.331 -                    PARSED,
  32.332 -                    CONSTANT_FOLDED,
  32.333 -                    LOWERED,
  32.334 -                    BUILTINS_TRANSFORMED,
  32.335 -                    SPLIT,
  32.336 -                    SYMBOLS_ASSIGNED,
  32.337 -                    SCOPE_DEPTHS_COMPUTED,
  32.338 -                    OPTIMISTIC_TYPES_ASSIGNED)) {
  32.339 +    static final CompilationPhase OPTIMISTIC_TYPE_ASSIGNMENT_PHASE = new OptimisticTypeAssignmentPhase();
  32.340 +
  32.341 +    private static final class LocalVariableTypeCalculationPhase extends CompilationPhase {
  32.342          @Override
  32.343          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.344              final FunctionNode newFunctionNode = transformFunction(fn, new LocalVariableTypesCalculator(compiler));
  32.345 @@ -314,25 +290,11 @@
  32.346          public String toString() {
  32.347              return "'Local Variable Type Calculation'";
  32.348          }
  32.349 -    },
  32.350 +    };
  32.351  
  32.352 +    static final CompilationPhase LOCAL_VARIABLE_TYPE_CALCULATION_PHASE = new LocalVariableTypeCalculationPhase();
  32.353  
  32.354 -    /**
  32.355 -     * Reuse compile units, if they are already present. We are using the same compiler
  32.356 -     * to recompile stuff
  32.357 -     */
  32.358 -    REUSE_COMPILE_UNITS_PHASE(
  32.359 -            EnumSet.of(
  32.360 -                    INITIALIZED,
  32.361 -                    PARSED,
  32.362 -                    CONSTANT_FOLDED,
  32.363 -                    LOWERED,
  32.364 -                    BUILTINS_TRANSFORMED,
  32.365 -                    SPLIT,
  32.366 -                    SYMBOLS_ASSIGNED,
  32.367 -                    SCOPE_DEPTHS_COMPUTED,
  32.368 -                    OPTIMISTIC_TYPES_ASSIGNED,
  32.369 -                    LOCAL_VARIABLE_TYPES_CALCULATED)) {
  32.370 +    private static final class ReuseCompileUnitsPhase extends CompilationPhase {
  32.371          @Override
  32.372          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.373              assert phases.isRestOfCompilation() : "reuse compile units currently only used for Rest-Of methods";
  32.374 @@ -380,16 +342,15 @@
  32.375          public String toString() {
  32.376              return "'Reuse Compile Units'";
  32.377          }
  32.378 -    },
  32.379 +    }
  32.380  
  32.381 -    REINITIALIZE_SERIALIZED(
  32.382 -            EnumSet.of(
  32.383 -                    INITIALIZED,
  32.384 -                    PARSED,
  32.385 -                    CONSTANT_FOLDED,
  32.386 -                    LOWERED,
  32.387 -                    BUILTINS_TRANSFORMED,
  32.388 -                    SPLIT)) {
  32.389 +    /**
  32.390 +     * Reuse compile units, if they are already present. We are using the same compiler
  32.391 +     * to recompile stuff
  32.392 +     */
  32.393 +    static final CompilationPhase REUSE_COMPILE_UNITS_PHASE = new ReuseCompileUnitsPhase();
  32.394 +
  32.395 +    private static final class ReinitializeCachedPhase extends CompilationPhase {
  32.396          @Override
  32.397          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.398              final Set<CompileUnit> unitSet = CompileUnit.createCompileUnitSet();
  32.399 @@ -430,28 +391,13 @@
  32.400  
  32.401          @Override
  32.402          public String toString() {
  32.403 -            return "'Deserialize'";
  32.404 +            return "'Reinitialize cached'";
  32.405          }
  32.406 -    },
  32.407 +    }
  32.408  
  32.409 -    /**
  32.410 -     * Bytecode generation:
  32.411 -     *
  32.412 -     * Generate the byte code class(es) resulting from the compiled FunctionNode
  32.413 -     */
  32.414 -    BYTECODE_GENERATION_PHASE(
  32.415 -            EnumSet.of(
  32.416 -                    INITIALIZED,
  32.417 -                    PARSED,
  32.418 -                    CONSTANT_FOLDED,
  32.419 -                    LOWERED,
  32.420 -                    BUILTINS_TRANSFORMED,
  32.421 -                    SPLIT,
  32.422 -                    SYMBOLS_ASSIGNED,
  32.423 -                    SCOPE_DEPTHS_COMPUTED,
  32.424 -                    OPTIMISTIC_TYPES_ASSIGNED,
  32.425 -                    LOCAL_VARIABLE_TYPES_CALCULATED)) {
  32.426 +    static final CompilationPhase REINITIALIZE_CACHED = new ReinitializeCachedPhase();
  32.427  
  32.428 +    private static final class BytecodeGenerationPhase extends CompilationPhase {
  32.429          @Override
  32.430          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.431              final ScriptEnvironment senv = compiler.getScriptEnvironment();
  32.432 @@ -469,7 +415,7 @@
  32.433              try {
  32.434                  // Explicitly set BYTECODE_GENERATED here; it can not be set in case of skipping codegen for :program
  32.435                  // in the lazy + optimistic world. See CodeGenerator.skipFunction().
  32.436 -                newFunctionNode = transformFunction(newFunctionNode, codegen).setState(null, BYTECODE_GENERATED);
  32.437 +                newFunctionNode = transformFunction(newFunctionNode, codegen);
  32.438                  codegen.generateScopeCalls();
  32.439              } catch (final VerifyError e) {
  32.440                  if (senv._verify_code || senv._print_code) {
  32.441 @@ -517,22 +463,16 @@
  32.442          public String toString() {
  32.443              return "'Bytecode Generation'";
  32.444          }
  32.445 -    },
  32.446 +    }
  32.447  
  32.448 -     INSTALL_PHASE(
  32.449 -            EnumSet.of(
  32.450 -                    INITIALIZED,
  32.451 -                    PARSED,
  32.452 -                    CONSTANT_FOLDED,
  32.453 -                    LOWERED,
  32.454 -                    BUILTINS_TRANSFORMED,
  32.455 -                    SPLIT,
  32.456 -                    SYMBOLS_ASSIGNED,
  32.457 -                    SCOPE_DEPTHS_COMPUTED,
  32.458 -                    OPTIMISTIC_TYPES_ASSIGNED,
  32.459 -                    LOCAL_VARIABLE_TYPES_CALCULATED,
  32.460 -                    BYTECODE_GENERATED)) {
  32.461 +    /**
  32.462 +     * Bytecode generation:
  32.463 +     *
  32.464 +     * Generate the byte code class(es) resulting from the compiled FunctionNode
  32.465 +     */
  32.466 +    static final CompilationPhase BYTECODE_GENERATION_PHASE = new BytecodeGenerationPhase();
  32.467  
  32.468 +    private static final class InstallPhase extends CompilationPhase {
  32.469          @Override
  32.470          FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
  32.471              final DebugLogger log = compiler.getLogger();
  32.472 @@ -600,18 +540,16 @@
  32.473                  log.fine(sb.toString());
  32.474              }
  32.475  
  32.476 -            return setStates(fn.setRootClass(null, rootClass), BYTECODE_INSTALLED);
  32.477 +            return fn.setRootClass(null, rootClass);
  32.478          }
  32.479  
  32.480          @Override
  32.481          public String toString() {
  32.482              return "'Class Installation'";
  32.483          }
  32.484 +    }
  32.485  
  32.486 -     };
  32.487 -
  32.488 -    /** pre conditions required for function node to which this transform is to be applied */
  32.489 -    private final EnumSet<CompilationState> pre;
  32.490 +    static final CompilationPhase INSTALL_PHASE = new InstallPhase();
  32.491  
  32.492      /** start time of transform - used for timing, see {@link jdk.nashorn.internal.runtime.Timing} */
  32.493      private long startTime;
  32.494 @@ -622,21 +560,7 @@
  32.495      /** boolean that is true upon transform completion */
  32.496      private boolean isFinished;
  32.497  
  32.498 -    private CompilationPhase(final EnumSet<CompilationState> pre) {
  32.499 -        this.pre = pre;
  32.500 -    }
  32.501 -
  32.502 -    private static FunctionNode setStates(final FunctionNode functionNode, final CompilationState state) {
  32.503 -        if (!AssertsEnabled.assertsEnabled()) {
  32.504 -            return functionNode;
  32.505 -        }
  32.506 -        return transformFunction(functionNode, new NodeVisitor<LexicalContext>(new LexicalContext()) {
  32.507 -            @Override
  32.508 -            public Node leaveFunctionNode(final FunctionNode fn) {
  32.509 -                return fn.setState(lc, state);
  32.510 -           }
  32.511 -        });
  32.512 -    }
  32.513 +    private CompilationPhase() {}
  32.514  
  32.515      /**
  32.516       * Start a compilation phase
  32.517 @@ -646,23 +570,7 @@
  32.518       */
  32.519      protected FunctionNode begin(final Compiler compiler, final FunctionNode functionNode) {
  32.520          compiler.getLogger().indent();
  32.521 -
  32.522 -        assert pre != null;
  32.523 -
  32.524 -        if (!functionNode.hasState(pre)) {
  32.525 -            final StringBuilder sb = new StringBuilder("Compilation phase ");
  32.526 -            sb.append(this).
  32.527 -                append(" is not applicable to ").
  32.528 -                append(quote(functionNode.getName())).
  32.529 -                append("\n\tFunctionNode state = ").
  32.530 -                append(functionNode.getState()).
  32.531 -                append("\n\tRequired state     = ").
  32.532 -                append(this.pre);
  32.533 -
  32.534 -            throw new CompilationException(sb.toString());
  32.535 -         }
  32.536 -
  32.537 -         startTime = System.nanoTime();
  32.538 +        startTime = System.nanoTime();
  32.539  
  32.540           return functionNode;
  32.541       }
  32.542 @@ -697,7 +605,7 @@
  32.543      abstract FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode functionNode) throws CompilationException;
  32.544  
  32.545      /**
  32.546 -     * Apply a transform to a function node, returning the transfored function node. If the transform is not
  32.547 +     * Apply a transform to a function node, returning the transformed function node. If the transform is not
  32.548       * applicable, an exception is thrown. Every transform requires the function to have a certain number of
  32.549       * states to operate. It can have more states set, but not fewer. The state list, i.e. the constructor
  32.550       * arguments to any of the CompilationPhase enum entries, is a set of REQUIRED states.
    33.1 --- a/src/jdk/nashorn/internal/codegen/Compiler.java	Thu Sep 24 10:00:42 2015 -0700
    33.2 +++ b/src/jdk/nashorn/internal/codegen/Compiler.java	Thu Sep 24 10:09:56 2015 -0700
    33.3 @@ -160,42 +160,40 @@
    33.4       */
    33.5      private static final int COMPILE_UNIT_NAME_BUFFER_SIZE = 32;
    33.6  
    33.7 -    private final Map<Integer, byte[]> serializedAsts = new HashMap<>();
    33.8 -
    33.9      /**
   33.10       * Compilation phases that a compilation goes through
   33.11       */
   33.12      public static class CompilationPhases implements Iterable<CompilationPhase> {
   33.13  
   33.14          /**
   33.15 -         * Singleton that describes compilation up to the phase where a function can be serialized.
   33.16 +         * Singleton that describes compilation up to the phase where a function can be cached.
   33.17           */
   33.18 -        private final static CompilationPhases COMPILE_UPTO_SERIALIZABLE = new CompilationPhases(
   33.19 +        private final static CompilationPhases COMPILE_UPTO_CACHED = new CompilationPhases(
   33.20                  "Common initial phases",
   33.21                  CompilationPhase.CONSTANT_FOLDING_PHASE,
   33.22                  CompilationPhase.LOWERING_PHASE,
   33.23 -                CompilationPhase.TRANSFORM_BUILTINS_PHASE,
   33.24 +                CompilationPhase.APPLY_SPECIALIZATION_PHASE,
   33.25                  CompilationPhase.SPLITTING_PHASE,
   33.26                  CompilationPhase.PROGRAM_POINT_PHASE,
   33.27 -                CompilationPhase.SERIALIZE_SPLIT_PHASE
   33.28 +                CompilationPhase.SYMBOL_ASSIGNMENT_PHASE,
   33.29 +                CompilationPhase.SCOPE_DEPTH_COMPUTATION_PHASE,
   33.30 +                CompilationPhase.CACHE_AST_PHASE
   33.31                  );
   33.32  
   33.33 -        private final static CompilationPhases COMPILE_SERIALIZABLE_UPTO_BYTECODE = new CompilationPhases(
   33.34 +        private final static CompilationPhases COMPILE_CACHED_UPTO_BYTECODE = new CompilationPhases(
   33.35                  "After common phases, before bytecode generator",
   33.36 -                CompilationPhase.SYMBOL_ASSIGNMENT_PHASE,
   33.37 -                CompilationPhase.SCOPE_DEPTH_COMPUTATION_PHASE,
   33.38                  CompilationPhase.OPTIMISTIC_TYPE_ASSIGNMENT_PHASE,
   33.39                  CompilationPhase.LOCAL_VARIABLE_TYPE_CALCULATION_PHASE
   33.40                  );
   33.41  
   33.42          /**
   33.43 -         * Singleton that describes additional steps to be taken after deserializing, all the way up to (but not
   33.44 -         * including) generating and installing code.
   33.45 +         * Singleton that describes additional steps to be taken after retrieving a cached function, all the
   33.46 +         * way up to (but not including) generating and installing code.
   33.47           */
   33.48 -        public final static CompilationPhases RECOMPILE_SERIALIZED_UPTO_BYTECODE = new CompilationPhases(
   33.49 -                "Recompile serialized function up to bytecode",
   33.50 -                CompilationPhase.REINITIALIZE_SERIALIZED,
   33.51 -                COMPILE_SERIALIZABLE_UPTO_BYTECODE
   33.52 +        public final static CompilationPhases RECOMPILE_CACHED_UPTO_BYTECODE = new CompilationPhases(
   33.53 +                "Recompile cached function up to bytecode",
   33.54 +                CompilationPhase.REINITIALIZE_CACHED,
   33.55 +                COMPILE_CACHED_UPTO_BYTECODE
   33.56                  );
   33.57  
   33.58          /**
   33.59 @@ -211,8 +209,8 @@
   33.60          /** Singleton that describes compilation up to the CodeGenerator, but not actually generating code */
   33.61          public final static CompilationPhases COMPILE_UPTO_BYTECODE = new CompilationPhases(
   33.62                  "Compile upto bytecode",
   33.63 -                COMPILE_UPTO_SERIALIZABLE,
   33.64 -                COMPILE_SERIALIZABLE_UPTO_BYTECODE);
   33.65 +                COMPILE_UPTO_CACHED,
   33.66 +                COMPILE_CACHED_UPTO_BYTECODE);
   33.67  
   33.68          /** Singleton that describes a standard eager compilation, but no installation, for example used by --compile-only */
   33.69          public final static CompilationPhases COMPILE_ALL_NO_INSTALL = new CompilationPhases(
   33.70 @@ -227,9 +225,9 @@
   33.71                  GENERATE_BYTECODE_AND_INSTALL);
   33.72  
   33.73          /** Singleton that describes a full compilation - this includes code installation - from serialized state*/
   33.74 -        public final static CompilationPhases COMPILE_ALL_SERIALIZED = new CompilationPhases(
   33.75 +        public final static CompilationPhases COMPILE_ALL_CACHED = new CompilationPhases(
   33.76                  "Eager compilation from serializaed state",
   33.77 -                RECOMPILE_SERIALIZED_UPTO_BYTECODE,
   33.78 +                RECOMPILE_CACHED_UPTO_BYTECODE,
   33.79                  GENERATE_BYTECODE_AND_INSTALL);
   33.80  
   33.81          /**
   33.82 @@ -248,9 +246,9 @@
   33.83                  GENERATE_BYTECODE_AND_INSTALL_RESTOF);
   33.84  
   33.85          /** Compile from serialized for a rest of method */
   33.86 -        public final static CompilationPhases COMPILE_SERIALIZED_RESTOF = new CompilationPhases(
   33.87 +        public final static CompilationPhases COMPILE_CACHED_RESTOF = new CompilationPhases(
   33.88                  "Compile serialized, rest of",
   33.89 -                RECOMPILE_SERIALIZED_UPTO_BYTECODE,
   33.90 +                RECOMPILE_CACHED_UPTO_BYTECODE,
   33.91                  GENERATE_BYTECODE_AND_INSTALL_RESTOF);
   33.92  
   33.93          private final List<CompilationPhase> phases;
   33.94 @@ -313,7 +311,7 @@
   33.95          }
   33.96  
   33.97          boolean isRestOfCompilation() {
   33.98 -            return this == COMPILE_ALL_RESTOF || this == GENERATE_BYTECODE_AND_INSTALL_RESTOF || this == COMPILE_SERIALIZED_RESTOF;
   33.99 +            return this == COMPILE_ALL_RESTOF || this == GENERATE_BYTECODE_AND_INSTALL_RESTOF || this == COMPILE_CACHED_RESTOF;
  33.100          }
  33.101  
  33.102          String getDesc() {
  33.103 @@ -766,14 +764,6 @@
  33.104          compileUnits.addAll(newUnits);
  33.105      }
  33.106  
  33.107 -    void serializeAst(final FunctionNode fn) {
  33.108 -        serializedAsts.put(fn.getId(), AstSerializer.serialize(fn));
  33.109 -    }
  33.110 -
  33.111 -    byte[] removeSerializedAst(final int fnId) {
  33.112 -        return serializedAsts.remove(fnId);
  33.113 -    }
  33.114 -
  33.115      CompileUnit findUnit(final long weight) {
  33.116          for (final CompileUnit unit : compileUnits) {
  33.117              if (unit.canHold(weight)) {
    34.1 --- a/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Thu Sep 24 10:00:42 2015 -0700
    34.2 +++ b/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Thu Sep 24 10:09:56 2015 -0700
    34.3 @@ -192,7 +192,7 @@
    34.4      private static Set<String> symbolNames;
    34.5  
    34.6      /**
    34.7 -     * Prefix used for internal methods generated in script clases.
    34.8 +     * Prefix used for internal methods generated in script classes.
    34.9       */
   34.10      private static final String INTERNAL_METHOD_PREFIX = ":";
   34.11  
   34.12 @@ -225,7 +225,7 @@
   34.13      }
   34.14  
   34.15      /**
   34.16 -     * Check whether a name is that of a reserved compiler constnat
   34.17 +     * Check whether a name is that of a reserved compiler constant
   34.18       * @param name name
   34.19       * @return true if compiler constant name
   34.20       */
    35.1 --- a/src/jdk/nashorn/internal/codegen/FindScopeDepths.java	Thu Sep 24 10:00:42 2015 -0700
    35.2 +++ b/src/jdk/nashorn/internal/codegen/FindScopeDepths.java	Thu Sep 24 10:09:56 2015 -0700
    35.3 @@ -34,7 +34,6 @@
    35.4  import java.util.Set;
    35.5  import jdk.nashorn.internal.ir.Block;
    35.6  import jdk.nashorn.internal.ir.FunctionNode;
    35.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    35.8  import jdk.nashorn.internal.ir.IdentNode;
    35.9  import jdk.nashorn.internal.ir.LexicalContext;
   35.10  import jdk.nashorn.internal.ir.Node;
   35.11 @@ -182,14 +181,16 @@
   35.12      @Override
   35.13      public Node leaveFunctionNode(final FunctionNode functionNode) {
   35.14          final String name = functionNode.getName();
   35.15 -        FunctionNode newFunctionNode = functionNode.setState(lc, CompilationState.SCOPE_DEPTHS_COMPUTED);
   35.16 -
   35.17 +        FunctionNode newFunctionNode = functionNode;
   35.18          if (compiler.isOnDemandCompilation()) {
   35.19              final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(newFunctionNode.getId());
   35.20              if (data.inDynamicContext()) {
   35.21                  log.fine("Reviving scriptfunction ", quote(name), " as defined in previous (now lost) dynamic scope.");
   35.22                  newFunctionNode = newFunctionNode.setInDynamicContext(lc);
   35.23              }
   35.24 +            if (newFunctionNode == lc.getOutermostFunction() && !newFunctionNode.hasApplyToCallSpecialization()) {
   35.25 +                data.setCachedAst(newFunctionNode);
   35.26 +            }
   35.27              return newFunctionNode;
   35.28          }
   35.29  
   35.30 @@ -210,8 +211,7 @@
   35.31                  ObjectClassGenerator.createAllocationStrategy(newFunctionNode.getThisProperties(), compiler.getContext().useDualFields()),
   35.32                  nestedFunctions,
   35.33                  externalSymbolDepths.get(fnId),
   35.34 -                internalSymbols.get(fnId),
   35.35 -                compiler.removeSerializedAst(fnId));
   35.36 +                internalSymbols.get(fnId));
   35.37  
   35.38          if (lc.getOutermostFunction() != newFunctionNode) {
   35.39              final FunctionNode parentFn = lc.getParentFunction(newFunctionNode);
    36.1 --- a/src/jdk/nashorn/internal/codegen/FoldConstants.java	Thu Sep 24 10:00:42 2015 -0700
    36.2 +++ b/src/jdk/nashorn/internal/codegen/FoldConstants.java	Thu Sep 24 10:09:56 2015 -0700
    36.3 @@ -37,7 +37,6 @@
    36.4  import jdk.nashorn.internal.ir.EmptyNode;
    36.5  import jdk.nashorn.internal.ir.Expression;
    36.6  import jdk.nashorn.internal.ir.FunctionNode;
    36.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    36.8  import jdk.nashorn.internal.ir.IfNode;
    36.9  import jdk.nashorn.internal.ir.LexicalContext;
   36.10  import jdk.nashorn.internal.ir.LiteralNode;
   36.11 @@ -101,7 +100,7 @@
   36.12  
   36.13      @Override
   36.14      public Node leaveFunctionNode(final FunctionNode functionNode) {
   36.15 -        return functionNode.setState(lc, CompilationState.CONSTANT_FOLDED);
   36.16 +        return functionNode;
   36.17      }
   36.18  
   36.19      @Override
    37.1 --- a/src/jdk/nashorn/internal/codegen/Label.java	Thu Sep 24 10:00:42 2015 -0700
    37.2 +++ b/src/jdk/nashorn/internal/codegen/Label.java	Thu Sep 24 10:09:56 2015 -0700
    37.3 @@ -447,7 +447,7 @@
    37.4              undefineLocalVariables(liveLocalCount, true);
    37.5              // Temporaries are promoted
    37.6              firstTemp = liveLocalCount;
    37.7 -            // No trailing undefineds
    37.8 +            // No trailing undefined values
    37.9              localVariableTypes.subList(firstTemp, localVariableTypes.size()).clear();
   37.10              assert symbolBoundary.length() == firstTemp;
   37.11              // Generalize all reference types to Object, and promote boolean to int
   37.12 @@ -497,7 +497,7 @@
   37.13      private transient Label.Stack stack;
   37.14  
   37.15      /** ASM representation of this label */
   37.16 -    private jdk.internal.org.objectweb.asm.Label label;
   37.17 +    private transient jdk.internal.org.objectweb.asm.Label label;
   37.18  
   37.19      /** Id for debugging purposes, remove if footprint becomes unmanageable */
   37.20      private final int id;
    38.1 --- a/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Thu Sep 24 10:00:42 2015 -0700
    38.2 +++ b/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Thu Sep 24 10:09:56 2015 -0700
    38.3 @@ -54,7 +54,6 @@
    38.4  import jdk.nashorn.internal.ir.ExpressionStatement;
    38.5  import jdk.nashorn.internal.ir.ForNode;
    38.6  import jdk.nashorn.internal.ir.FunctionNode;
    38.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    38.8  import jdk.nashorn.internal.ir.GetSplitState;
    38.9  import jdk.nashorn.internal.ir.IdentNode;
   38.10  import jdk.nashorn.internal.ir.IfNode;
   38.11 @@ -1478,7 +1477,6 @@
   38.12          newFunction = newFunction.setReturnType(lc, returnType);
   38.13  
   38.14  
   38.15 -        newFunction = newFunction.setState(lc, CompilationState.LOCAL_VARIABLE_TYPES_CALCULATED);
   38.16          newFunction = newFunction.setParameters(lc, newFunction.visitParameters(applyChangesVisitor));
   38.17          return newFunction;
   38.18      }
    39.1 --- a/src/jdk/nashorn/internal/codegen/Lower.java	Thu Sep 24 10:00:42 2015 -0700
    39.2 +++ b/src/jdk/nashorn/internal/codegen/Lower.java	Thu Sep 24 10:09:56 2015 -0700
    39.3 @@ -51,7 +51,6 @@
    39.4  import jdk.nashorn.internal.ir.ExpressionStatement;
    39.5  import jdk.nashorn.internal.ir.ForNode;
    39.6  import jdk.nashorn.internal.ir.FunctionNode;
    39.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    39.8  import jdk.nashorn.internal.ir.IdentNode;
    39.9  import jdk.nashorn.internal.ir.IfNode;
   39.10  import jdk.nashorn.internal.ir.IndexNode;
   39.11 @@ -266,7 +265,7 @@
   39.12      @Override
   39.13      public Node leaveFunctionNode(final FunctionNode functionNode) {
   39.14          log.info("END FunctionNode: ", functionNode.getName());
   39.15 -        return functionNode.setState(lc, CompilationState.LOWERED);
   39.16 +        return functionNode;
   39.17      }
   39.18  
   39.19      @Override
   39.20 @@ -511,7 +510,7 @@
   39.21          }
   39.22  
   39.23          /*
   39.24 -         * create a new trynode
   39.25 +         * create a new try node
   39.26           *    if we have catches:
   39.27           *
   39.28           *    try            try
   39.29 @@ -522,7 +521,7 @@
   39.30           *                   catchall
   39.31           *                        rethrow
   39.32           *
   39.33 -         *   otheriwse
   39.34 +         *   otherwise
   39.35           *
   39.36           *   try              try
   39.37           *      x               x
    40.1 --- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Thu Sep 24 10:00:42 2015 -0700
    40.2 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Thu Sep 24 10:09:56 2015 -0700
    40.3 @@ -1159,7 +1159,7 @@
    40.4      /**
    40.5       * Pop a value from the stack and store it in a variable denoted by the given symbol. The variable should be either
    40.6       * a local variable, or a function parameter (and not a scoped variable). For local variables, this method will also
    40.7 -     * do the bookeeping of the local variable table as well as mark values in all alternative slots for the symbol as
    40.8 +     * do the bookkeeping of the local variable table as well as mark values in all alternative slots for the symbol as
    40.9       * dead. In this regard it differs from {@link #storeHidden(Type, int)}.
   40.10       *
   40.11       * @param symbol the symbol to store into.
    41.1 --- a/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Thu Sep 24 10:00:42 2015 -0700
    41.2 +++ b/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Thu Sep 24 10:09:56 2015 -0700
    41.3 @@ -786,7 +786,7 @@
    41.4       * @param primitiveSetter   primitive setter for the current type with an element of the current type
    41.5       * @param objectSetter      the object setter
    41.6       *
    41.7 -     * @return method handle that checks if the element to be set is of the currenttype, even though it's boxed
    41.8 +     * @return method handle that checks if the element to be set is of the current type, even though it's boxed
    41.9       *  and instead of using the generic object setter, that would blow up the type and invalidate the map,
   41.10       *  unbox it and call the primitive setter instead
   41.11       */
    42.1 --- a/src/jdk/nashorn/internal/codegen/OptimisticTypesCalculator.java	Thu Sep 24 10:00:42 2015 -0700
    42.2 +++ b/src/jdk/nashorn/internal/codegen/OptimisticTypesCalculator.java	Thu Sep 24 10:09:56 2015 -0700
    42.3 @@ -38,7 +38,6 @@
    42.4  import jdk.nashorn.internal.ir.ExpressionStatement;
    42.5  import jdk.nashorn.internal.ir.ForNode;
    42.6  import jdk.nashorn.internal.ir.FunctionNode;
    42.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    42.8  import jdk.nashorn.internal.ir.IdentNode;
    42.9  import jdk.nashorn.internal.ir.IfNode;
   42.10  import jdk.nashorn.internal.ir.IndexNode;
   42.11 @@ -208,7 +207,7 @@
   42.12      @Override
   42.13      public Node leaveFunctionNode(final FunctionNode functionNode) {
   42.14          neverOptimistic.pop();
   42.15 -        return functionNode.setState(lc, CompilationState.OPTIMISTIC_TYPES_ASSIGNED);
   42.16 +        return functionNode;
   42.17      }
   42.18  
   42.19      @Override
    43.1 --- a/src/jdk/nashorn/internal/codegen/ReplaceCompileUnits.java	Thu Sep 24 10:00:42 2015 -0700
    43.2 +++ b/src/jdk/nashorn/internal/codegen/ReplaceCompileUnits.java	Thu Sep 24 10:09:56 2015 -0700
    43.3 @@ -29,7 +29,6 @@
    43.4  import java.util.List;
    43.5  import jdk.nashorn.internal.ir.CompileUnitHolder;
    43.6  import jdk.nashorn.internal.ir.FunctionNode;
    43.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    43.8  import jdk.nashorn.internal.ir.LexicalContext;
    43.9  import jdk.nashorn.internal.ir.LiteralNode;
   43.10  import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
   43.11 @@ -64,7 +63,7 @@
   43.12  
   43.13      @Override
   43.14      public Node leaveFunctionNode(final FunctionNode node) {
   43.15 -        return node.setCompileUnit(lc, getExistingReplacement(node)).setState(lc, CompilationState.COMPILE_UNITS_REUSED);
   43.16 +        return node.setCompileUnit(lc, getExistingReplacement(node));
   43.17      }
   43.18  
   43.19      @Override
    44.1 --- a/src/jdk/nashorn/internal/codegen/SplitIntoFunctions.java	Thu Sep 24 10:00:42 2015 -0700
    44.2 +++ b/src/jdk/nashorn/internal/codegen/SplitIntoFunctions.java	Thu Sep 24 10:09:56 2015 -0700
    44.3 @@ -175,8 +175,7 @@
    44.4                  FunctionNode.IS_ANONYMOUS | FunctionNode.USES_ANCESTOR_SCOPE | FunctionNode.IS_SPLIT
    44.5          )
    44.6          .setBody(lc, body)
    44.7 -        .setCompileUnit(lc, splitNode.getCompileUnit())
    44.8 -        .copyCompilationState(lc, originalFn);
    44.9 +        .setCompileUnit(lc, splitNode.getCompileUnit());
   44.10  
   44.11          // Call the function:
   44.12          //     either "(function () { ... }).call(this)"
    45.1 --- a/src/jdk/nashorn/internal/codegen/Splitter.java	Thu Sep 24 10:00:42 2015 -0700
    45.2 +++ b/src/jdk/nashorn/internal/codegen/Splitter.java	Thu Sep 24 10:09:56 2015 -0700
    45.3 @@ -33,7 +33,6 @@
    45.4  import java.util.Map;
    45.5  import jdk.nashorn.internal.ir.Block;
    45.6  import jdk.nashorn.internal.ir.FunctionNode;
    45.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    45.8  import jdk.nashorn.internal.ir.LexicalContext;
    45.9  import jdk.nashorn.internal.ir.LiteralNode;
   45.10  import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
   45.11 @@ -158,7 +157,7 @@
   45.12  
   45.13          assert functionNode.getCompileUnit() != null;
   45.14  
   45.15 -        return functionNode.setState(null, CompilationState.SPLIT);
   45.16 +        return functionNode;
   45.17      }
   45.18  
   45.19      private static List<FunctionNode> directChildren(final FunctionNode functionNode) {
    46.1 --- a/src/jdk/nashorn/internal/codegen/types/BytecodeOps.java	Thu Sep 24 10:00:42 2015 -0700
    46.2 +++ b/src/jdk/nashorn/internal/codegen/types/BytecodeOps.java	Thu Sep 24 10:09:56 2015 -0700
    46.3 @@ -36,7 +36,7 @@
    46.4   * The bytecode ops are coupled to a MethodVisitor from ASM for
    46.5   * byte code generation. They know nothing about our MethodGenerator,
    46.6   * which is the abstraction for working with Nashorn JS types
    46.7 - * For exmaple, anything like "two or one slots" for a type, which
    46.8 + * For example, anything like "two or one slots" for a type, which
    46.9   * is represented in bytecode and ASM, is abstracted away in the
   46.10   * MethodGenerator. There you just say "dup" or "store".
   46.11   *
    47.1 --- a/src/jdk/nashorn/internal/ir/Block.java	Thu Sep 24 10:00:42 2015 -0700
    47.2 +++ b/src/jdk/nashorn/internal/ir/Block.java	Thu Sep 24 10:09:56 2015 -0700
    47.3 @@ -130,11 +130,42 @@
    47.4      }
    47.5  
    47.6      /**
    47.7 -     * Clear the symbols in the block.
    47.8 -     * TODO: make this immutable.
    47.9 +     * Returns true if this block defines any symbols.
   47.10 +     * @return true if this block defines any symbols.
   47.11       */
   47.12 -    public void clearSymbols() {
   47.13 -        symbols.clear();
   47.14 +    public boolean hasSymbols() {
   47.15 +        return !symbols.isEmpty();
   47.16 +    }
   47.17 +
   47.18 +    /**
   47.19 +     * Replaces symbols defined in this block with different symbols. Used to ensure symbol tables are
   47.20 +     * immutable upon construction and have copy-on-write semantics. Note that this method only replaces the
   47.21 +     * symbols in the symbol table, it does not act on any contained AST nodes that might reference the symbols.
   47.22 +     * Those should be updated separately as this method is meant to be used as part of such an update pass.
   47.23 +     * @param lc the current lexical context
   47.24 +     * @param replacements the map of symbol replacements
   47.25 +     * @return a new block with replaced symbols, or this block if none of the replacements modified the symbol
   47.26 +     * table.
   47.27 +     */
   47.28 +    public Block replaceSymbols(final LexicalContext lc, final Map<Symbol, Symbol> replacements) {
   47.29 +        if (symbols.isEmpty()) {
   47.30 +            return this;
   47.31 +        }
   47.32 +        final LinkedHashMap<String, Symbol> newSymbols = new LinkedHashMap<>(symbols);
   47.33 +        for (final Map.Entry<String, Symbol> entry: newSymbols.entrySet()) {
   47.34 +            final Symbol newSymbol = replacements.get(entry.getValue());
   47.35 +            assert newSymbol != null : "Missing replacement for " + entry.getKey();
   47.36 +            entry.setValue(newSymbol);
   47.37 +        }
   47.38 +        return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, newSymbols, conversion));
   47.39 +    }
   47.40 +
   47.41 +    /**
   47.42 +     * Returns a copy of this block with a shallow copy of the symbol table.
   47.43 +     * @return a copy of this block with a shallow copy of the symbol table.
   47.44 +     */
   47.45 +    public Block copyWithNewSymbols() {
   47.46 +        return new Block(this, finish, statements, flags, new LinkedHashMap<>(symbols), conversion);
   47.47      }
   47.48  
   47.49      @Override
   47.50 @@ -162,7 +193,7 @@
   47.51       * @return symbol iterator
   47.52       */
   47.53      public List<Symbol> getSymbols() {
   47.54 -        return Collections.unmodifiableList(new ArrayList<>(symbols.values()));
   47.55 +        return symbols.isEmpty() ? Collections.<Symbol>emptyList() : Collections.unmodifiableList(new ArrayList<>(symbols.values()));
   47.56      }
   47.57  
   47.58      /**
   47.59 @@ -326,10 +357,9 @@
   47.60      /**
   47.61       * Add or overwrite an existing symbol in the block
   47.62       *
   47.63 -     * @param lc     get lexical context
   47.64       * @param symbol symbol
   47.65       */
   47.66 -    public void putSymbol(final LexicalContext lc, final Symbol symbol) {
   47.67 +    public void putSymbol(final Symbol symbol) {
   47.68          symbols.put(symbol.getName(), symbol);
   47.69      }
   47.70  
    48.1 --- a/src/jdk/nashorn/internal/ir/BlockLexicalContext.java	Thu Sep 24 10:00:42 2015 -0700
    48.2 +++ b/src/jdk/nashorn/internal/ir/BlockLexicalContext.java	Thu Sep 24 10:09:56 2015 -0700
    48.3 @@ -34,7 +34,7 @@
    48.4   * This is a subclass of lexical context used for filling
    48.5   * blocks (and function nodes) with statements. When popping
    48.6   * a block from the lexical context, any statements that have
    48.7 - * been generated in it are commited to the block. This saves
    48.8 + * been generated in it are committed to the block. This saves
    48.9   * unnecessary object mutations and lexical context replacement
   48.10   */
   48.11  public class BlockLexicalContext extends LexicalContext {
    49.1 --- a/src/jdk/nashorn/internal/ir/ForNode.java	Thu Sep 24 10:00:42 2015 -0700
    49.2 +++ b/src/jdk/nashorn/internal/ir/ForNode.java	Thu Sep 24 10:09:56 2015 -0700
    49.3 @@ -43,7 +43,7 @@
    49.4      private final JoinPredecessorExpression modify;
    49.5  
    49.6      /** Iterator symbol. */
    49.7 -    private Symbol iterator;
    49.8 +    private final Symbol iterator;
    49.9  
   49.10      /** Is this a normal for in loop? */
   49.11      public static final int IS_FOR_IN           = 1 << 0;
   49.12 @@ -70,22 +70,22 @@
   49.13          this.flags  = flags;
   49.14          this.init = null;
   49.15          this.modify = null;
   49.16 +        this.iterator = null;
   49.17      }
   49.18  
   49.19      private ForNode(final ForNode forNode, final Expression init, final JoinPredecessorExpression test,
   49.20 -            final Block body, final JoinPredecessorExpression modify, final int flags, final boolean controlFlowEscapes, final LocalVariableConversion conversion) {
   49.21 +            final Block body, final JoinPredecessorExpression modify, final int flags,
   49.22 +            final boolean controlFlowEscapes, final LocalVariableConversion conversion, final Symbol iterator) {
   49.23          super(forNode, test, body, controlFlowEscapes, conversion);
   49.24          this.init   = init;
   49.25          this.modify = modify;
   49.26          this.flags  = flags;
   49.27 -        // Even if the for node gets cloned in try/finally, the symbol can be shared as only one branch of the finally
   49.28 -        // is executed.
   49.29 -        this.iterator = forNode.iterator;
   49.30 +        this.iterator = iterator;
   49.31      }
   49.32  
   49.33      @Override
   49.34      public Node ensureUniqueLabels(final LexicalContext lc) {
   49.35 -        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
   49.36 +        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion, iterator));
   49.37      }
   49.38  
   49.39      @Override
   49.40 @@ -158,7 +158,7 @@
   49.41          if (this.init == init) {
   49.42              return this;
   49.43          }
   49.44 -        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
   49.45 +        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion, iterator));
   49.46      }
   49.47  
   49.48      /**
   49.49 @@ -206,10 +206,15 @@
   49.50  
   49.51      /**
   49.52       * Assign an iterator symbol to this ForNode. Used for for in and for each constructs
   49.53 +     * @param lc the current lexical context
   49.54       * @param iterator the iterator symbol
   49.55 +     * @return a ForNode with the iterator set
   49.56       */
   49.57 -    public void setIterator(final Symbol iterator) {
   49.58 -        this.iterator = iterator;
   49.59 +    public ForNode setIterator(final LexicalContext lc, final Symbol iterator) {
   49.60 +        if (this.iterator == iterator) {
   49.61 +            return this;
   49.62 +        }
   49.63 +        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion, iterator));
   49.64      }
   49.65  
   49.66      /**
   49.67 @@ -230,7 +235,7 @@
   49.68          if (this.modify == modify) {
   49.69              return this;
   49.70          }
   49.71 -        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
   49.72 +        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion, iterator));
   49.73      }
   49.74  
   49.75      @Override
   49.76 @@ -238,7 +243,7 @@
   49.77          if (this.test == test) {
   49.78              return this;
   49.79          }
   49.80 -        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
   49.81 +        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion, iterator));
   49.82      }
   49.83  
   49.84      @Override
   49.85 @@ -251,7 +256,7 @@
   49.86          if (this.body == body) {
   49.87              return this;
   49.88          }
   49.89 -        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
   49.90 +        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion, iterator));
   49.91      }
   49.92  
   49.93      @Override
   49.94 @@ -259,19 +264,19 @@
   49.95          if (this.controlFlowEscapes == controlFlowEscapes) {
   49.96              return this;
   49.97          }
   49.98 -        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
   49.99 +        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion, iterator));
  49.100      }
  49.101  
  49.102      private ForNode setFlags(final LexicalContext lc, final int flags) {
  49.103          if (this.flags == flags) {
  49.104              return this;
  49.105          }
  49.106 -        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
  49.107 +        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion, iterator));
  49.108      }
  49.109  
  49.110      @Override
  49.111      JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) {
  49.112 -        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
  49.113 +        return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion, iterator));
  49.114      }
  49.115  
  49.116      @Override
    50.1 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java	Thu Sep 24 10:00:42 2015 -0700
    50.2 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java	Thu Sep 24 10:09:56 2015 -0700
    50.3 @@ -33,10 +33,8 @@
    50.4  import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES;
    50.5  
    50.6  import java.util.Collections;
    50.7 -import java.util.EnumSet;
    50.8  import java.util.Iterator;
    50.9  import java.util.List;
   50.10 -import jdk.nashorn.internal.AssertsEnabled;
   50.11  import jdk.nashorn.internal.codegen.CompileUnit;
   50.12  import jdk.nashorn.internal.codegen.Compiler;
   50.13  import jdk.nashorn.internal.codegen.CompilerConstants;
   50.14 @@ -73,40 +71,6 @@
   50.15          SETTER
   50.16      }
   50.17  
   50.18 -    /** Compilation states available */
   50.19 -    public enum CompilationState {
   50.20 -        /** compiler is ready */
   50.21 -        INITIALIZED,
   50.22 -        /** method has been parsed */
   50.23 -        PARSED,
   50.24 -        /** method has been parsed */
   50.25 -        PARSE_ERROR,
   50.26 -        /** constant folding pass */
   50.27 -        CONSTANT_FOLDED,
   50.28 -        /** method has been lowered */
   50.29 -        LOWERED,
   50.30 -        /** program points have been assigned to unique locations */
   50.31 -        PROGRAM_POINTS_ASSIGNED,
   50.32 -        /** any transformations of builtins have taken place, e.g. apply=&gt;call */
   50.33 -        BUILTINS_TRANSFORMED,
   50.34 -        /** method has been split */
   50.35 -        SPLIT,
   50.36 -        /** method has had symbols assigned */
   50.37 -        SYMBOLS_ASSIGNED,
   50.38 -        /** computed scope depths for symbols */
   50.39 -        SCOPE_DEPTHS_COMPUTED,
   50.40 -        /** method has had types calculated*/
   50.41 -        OPTIMISTIC_TYPES_ASSIGNED,
   50.42 -        /** method has had types calculated */
   50.43 -        LOCAL_VARIABLE_TYPES_CALCULATED,
   50.44 -        /** compile units reused (optional) */
   50.45 -        COMPILE_UNITS_REUSED,
   50.46 -        /** method has been emitted to bytecode */
   50.47 -        BYTECODE_GENERATED,
   50.48 -        /** method has been installed */
   50.49 -        BYTECODE_INSTALLED
   50.50 -    }
   50.51 -
   50.52      /** Source of entity. */
   50.53      private transient final Source source;
   50.54  
   50.55 @@ -144,10 +108,6 @@
   50.56      /** Method's namespace. */
   50.57      private transient final Namespace namespace;
   50.58  
   50.59 -    /** Current compilation state */
   50.60 -    @Ignore
   50.61 -    private final EnumSet<CompilationState> compilationState;
   50.62 -
   50.63      /** Number of properties of "this" object assigned in this function */
   50.64      @Ignore
   50.65      private final int thisProperties;
   50.66 @@ -263,6 +223,11 @@
   50.67       */
   50.68      public static final int NEEDS_CALLEE       = 1 << 26;
   50.69  
   50.70 +    /**
   50.71 +     * Is the function node cached?
   50.72 +     */
   50.73 +    public static final int IS_CACHED = 1 << 27;
   50.74 +
   50.75      /** extension callsite flags mask */
   50.76      public static final int EXTENSION_CALLSITE_FLAGS = IS_PRINT_PARSE |
   50.77          IS_PRINT_LOWER_PARSE | IS_PRINT_AST | IS_PRINT_LOWER_AST |
   50.78 @@ -322,7 +287,6 @@
   50.79          this.firstToken       = firstToken;
   50.80          this.lastToken        = token;
   50.81          this.namespace        = namespace;
   50.82 -        this.compilationState = EnumSet.of(CompilationState.INITIALIZED);
   50.83          this.flags            = flags;
   50.84          this.compileUnit      = null;
   50.85          this.body             = null;
   50.86 @@ -339,12 +303,11 @@
   50.87          final String name,
   50.88          final Type returnType,
   50.89          final CompileUnit compileUnit,
   50.90 -        final EnumSet<CompilationState> compilationState,
   50.91          final Block body,
   50.92          final List<IdentNode> parameters,
   50.93          final int thisProperties,
   50.94          final Class<?> rootClass,
   50.95 -        final Source source, Namespace namespace) {
   50.96 +        final Source source, final Namespace namespace) {
   50.97          super(functionNode);
   50.98  
   50.99          this.endParserState    = endParserState;
  50.100 @@ -354,7 +317,6 @@
  50.101          this.returnType       = returnType;
  50.102          this.compileUnit      = compileUnit;
  50.103          this.lastToken        = lastToken;
  50.104 -        this.compilationState = compilationState;
  50.105          this.body             = body;
  50.106          this.parameters       = parameters;
  50.107          this.thisProperties   = thisProperties;
  50.108 @@ -454,7 +416,6 @@
  50.109              name,
  50.110              returnType,
  50.111              compileUnit,
  50.112 -            compilationState,
  50.113              body,
  50.114              parameters,
  50.115              thisProperties,
  50.116 @@ -530,80 +491,6 @@
  50.117      }
  50.118  
  50.119      /**
  50.120 -     * Get the compilation state of this function
  50.121 -     * @return the compilation state
  50.122 -     */
  50.123 -    public EnumSet<CompilationState> getState() {
  50.124 -        return compilationState;
  50.125 -    }
  50.126 -
  50.127 -    /**
  50.128 -     * Check whether this FunctionNode has reached a give CompilationState.
  50.129 -     *
  50.130 -     * @param state the state to check for
  50.131 -     * @return true of the node is in the given state
  50.132 -     */
  50.133 -    public boolean hasState(final EnumSet<CompilationState> state) {
  50.134 -        return !AssertsEnabled.assertsEnabled() || compilationState.containsAll(state);
  50.135 -    }
  50.136 -
  50.137 -    /**
  50.138 -     * Add a state to the total CompilationState of this node, e.g. if
  50.139 -     * FunctionNode has been lowered, the compiler will add
  50.140 -     * {@code CompilationState#LOWERED} to the state vector
  50.141 -     *
  50.142 -     * @param lc lexical context
  50.143 -     * @param state {@link CompilationState} to add
  50.144 -     * @return function node or a new one if state was changed
  50.145 -     */
  50.146 -    public FunctionNode setState(final LexicalContext lc, final CompilationState state) {
  50.147 -        if (!AssertsEnabled.assertsEnabled() || this.compilationState.contains(state)) {
  50.148 -            return this;
  50.149 -        }
  50.150 -        final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState);
  50.151 -        newState.add(state);
  50.152 -        return setCompilationState(lc, newState);
  50.153 -    }
  50.154 -
  50.155 -    /**
  50.156 -     * Copy a compilation state from an original function to this function. Used when creating synthetic
  50.157 -     * function nodes by the splitter.
  50.158 -     *
  50.159 -     * @param lc lexical context
  50.160 -     * @param original the original function node to copy compilation state from
  50.161 -     * @return function node or a new one if state was changed
  50.162 -     */
  50.163 -    public FunctionNode copyCompilationState(final LexicalContext lc, final FunctionNode original) {
  50.164 -        final EnumSet<CompilationState> origState = original.compilationState;
  50.165 -        if (!AssertsEnabled.assertsEnabled() || this.compilationState.containsAll(origState)) {
  50.166 -            return this;
  50.167 -        }
  50.168 -        final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState);
  50.169 -        newState.addAll(origState);
  50.170 -        return setCompilationState(lc, newState);
  50.171 -    }
  50.172 -
  50.173 -    private FunctionNode setCompilationState(final LexicalContext lc, final EnumSet<CompilationState> compilationState) {
  50.174 -        return Node.replaceInLexicalContext(
  50.175 -                lc,
  50.176 -                this,
  50.177 -                new FunctionNode(
  50.178 -                        this,
  50.179 -                        lastToken,
  50.180 -                        endParserState,
  50.181 -                        flags,
  50.182 -                        name,
  50.183 -                        returnType,
  50.184 -                        compileUnit,
  50.185 -                        compilationState,
  50.186 -                        body,
  50.187 -                        parameters,
  50.188 -                        thisProperties,
  50.189 -                        rootClass, source, namespace));
  50.190 -    }
  50.191 -
  50.192 -
  50.193 -    /**
  50.194       * Create a unique name in the namespace of this FunctionNode
  50.195       * @param base prefix for name
  50.196       * @return base if no collision exists, otherwise a name prefix with base
  50.197 @@ -668,7 +555,6 @@
  50.198                          name,
  50.199                          returnType,
  50.200                          compileUnit,
  50.201 -                        compilationState,
  50.202                          body,
  50.203                          parameters,
  50.204                          thisProperties,
  50.205 @@ -748,7 +634,7 @@
  50.206       */
  50.207      public boolean needsCallee() {
  50.208          // NOTE: we only need isSplit() here to ensure that :scope can never drop below slot 2 for splitting array units.
  50.209 -        return needsParentScope() || usesSelfSymbol() || isSplit() || (needsArguments() && !isStrict()) || hasOptimisticApplyToCall();
  50.210 +        return needsParentScope() || usesSelfSymbol() || isSplit() || (needsArguments() && !isStrict()) || hasApplyToCallSpecialization();
  50.211      }
  50.212  
  50.213      /**
  50.214 @@ -765,7 +651,7 @@
  50.215       * Return true if function contains an apply to call transform
  50.216       * @return true if this function has transformed apply to call
  50.217       */
  50.218 -    public boolean hasOptimisticApplyToCall() {
  50.219 +    public boolean hasApplyToCallSpecialization() {
  50.220          return getFlag(HAS_APPLY_TO_CALL_SPECIALIZATION);
  50.221      }
  50.222  
  50.223 @@ -809,7 +695,6 @@
  50.224                          name,
  50.225                          returnType,
  50.226                          compileUnit,
  50.227 -                        compilationState,
  50.228                          body,
  50.229                          parameters,
  50.230                          thisProperties,
  50.231 @@ -905,7 +790,6 @@
  50.232                          name,
  50.233                          returnType,
  50.234                          compileUnit,
  50.235 -                        compilationState,
  50.236                          body,
  50.237                          parameters,
  50.238                          thisProperties,
  50.239 @@ -966,7 +850,6 @@
  50.240                          name,
  50.241                          returnType,
  50.242                          compileUnit,
  50.243 -                        compilationState,
  50.244                          body,
  50.245                          parameters,
  50.246                          thisProperties,
  50.247 @@ -1002,7 +885,6 @@
  50.248                          name,
  50.249                          returnType,
  50.250                          compileUnit,
  50.251 -                        compilationState,
  50.252                          body,
  50.253                          parameters,
  50.254                          thisProperties,
  50.255 @@ -1040,7 +922,6 @@
  50.256                          name,
  50.257                          returnType,
  50.258                          compileUnit,
  50.259 -                        compilationState,
  50.260                          body,
  50.261                          parameters,
  50.262                          thisProperties,
  50.263 @@ -1116,7 +997,6 @@
  50.264                          name,
  50.265                          returnType,
  50.266                          compileUnit,
  50.267 -                        compilationState,
  50.268                          body,
  50.269                          parameters,
  50.270                          thisProperties,
  50.271 @@ -1204,7 +1084,6 @@
  50.272                  name,
  50.273                  type,
  50.274                  compileUnit,
  50.275 -                compilationState,
  50.276                  body,
  50.277                  parameters,
  50.278                  thisProperties,
  50.279 @@ -1221,6 +1100,24 @@
  50.280      }
  50.281  
  50.282      /**
  50.283 +     * Returns true if this function node has been cached.
  50.284 +     * @return true if this function node has been cached.
  50.285 +     */
  50.286 +    public boolean isCached() {
  50.287 +        return getFlag(IS_CACHED);
  50.288 +    }
  50.289 +
  50.290 +    /**
  50.291 +     * Mark this function node as having been cached.
  50.292 +     * @param lc the current lexical context
  50.293 +     * @return a function node equivalent to this one, with the flag set.
  50.294 +     */
  50.295 +    public FunctionNode setCached(final LexicalContext lc) {
  50.296 +        return setFlag(lc, IS_CACHED);
  50.297 +    }
  50.298 +
  50.299 +
  50.300 +    /**
  50.301       * Get the compile unit used to compile this function
  50.302       * @see Compiler
  50.303       * @return the compile unit
  50.304 @@ -1252,7 +1149,6 @@
  50.305                          name,
  50.306                          returnType,
  50.307                          compileUnit,
  50.308 -                        compilationState,
  50.309                          body,
  50.310                          parameters,
  50.311                          thisProperties,
  50.312 @@ -1308,7 +1204,6 @@
  50.313                          name,
  50.314                          returnType,
  50.315                          compileUnit,
  50.316 -                        compilationState,
  50.317                          body,
  50.318                          parameters,
  50.319                          thisProperties,
    51.1 --- a/src/jdk/nashorn/internal/ir/LiteralNode.java	Thu Sep 24 10:00:42 2015 -0700
    51.2 +++ b/src/jdk/nashorn/internal/ir/LiteralNode.java	Thu Sep 24 10:09:56 2015 -0700
    51.3 @@ -430,7 +430,7 @@
    51.4       *
    51.5       * @param token   token
    51.6       * @param finish  finish
    51.7 -     * @param value   undefined value, passed only for polymorphisism discrimination
    51.8 +     * @param value   undefined value, passed only for polymorphism discrimination
    51.9       *
   51.10       * @return the new literal node
   51.11       */
    52.1 --- a/src/jdk/nashorn/internal/ir/RuntimeNode.java	Thu Sep 24 10:00:42 2015 -0700
    52.2 +++ b/src/jdk/nashorn/internal/ir/RuntimeNode.java	Thu Sep 24 10:09:56 2015 -0700
    52.3 @@ -276,7 +276,7 @@
    52.4           *
    52.5           * @param request a request
    52.6           *
    52.7 -         * @return the inverted rquest, or null if not applicable
    52.8 +         * @return the inverted request, or null if not applicable
    52.9           */
   52.10          public static Request invert(final Request request) {
   52.11              switch (request) {
    53.1 --- a/src/jdk/nashorn/internal/ir/SwitchNode.java	Thu Sep 24 10:00:42 2015 -0700
    53.2 +++ b/src/jdk/nashorn/internal/ir/SwitchNode.java	Thu Sep 24 10:09:56 2015 -0700
    53.3 @@ -53,7 +53,7 @@
    53.4      private final boolean uniqueInteger;
    53.5  
    53.6      /** Tag symbol. */
    53.7 -    private Symbol tag;
    53.8 +    private final Symbol tag;
    53.9  
   53.10      /**
   53.11       * Constructor
   53.12 @@ -71,15 +71,16 @@
   53.13          this.cases            = cases;
   53.14          this.defaultCaseIndex = defaultCase == null ? -1 : cases.indexOf(defaultCase);
   53.15          this.uniqueInteger    = false;
   53.16 +        this.tag = null;
   53.17      }
   53.18  
   53.19      private SwitchNode(final SwitchNode switchNode, final Expression expression, final List<CaseNode> cases,
   53.20 -            final int defaultCaseIndex, final LocalVariableConversion conversion, final boolean uniqueInteger) {
   53.21 +            final int defaultCaseIndex, final LocalVariableConversion conversion, final boolean uniqueInteger, final Symbol tag) {
   53.22          super(switchNode, conversion);
   53.23          this.expression       = expression;
   53.24          this.cases            = cases;
   53.25          this.defaultCaseIndex = defaultCaseIndex;
   53.26 -        this.tag              = switchNode.getTag(); //TODO are symbols inherited as references?
   53.27 +        this.tag              = tag;
   53.28          this.uniqueInteger    = uniqueInteger;
   53.29      }
   53.30  
   53.31 @@ -89,7 +90,7 @@
   53.32          for (final CaseNode caseNode : cases) {
   53.33              newCases.add(new CaseNode(caseNode, caseNode.getTest(), caseNode.getBody(), caseNode.getLocalVariableConversion()));
   53.34          }
   53.35 -        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, newCases, defaultCaseIndex, conversion, uniqueInteger));
   53.36 +        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, newCases, defaultCaseIndex, conversion, uniqueInteger, tag));
   53.37      }
   53.38  
   53.39      @Override
   53.40 @@ -157,7 +158,7 @@
   53.41          if (this.cases == cases) {
   53.42              return this;
   53.43          }
   53.44 -        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger));
   53.45 +        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger, tag));
   53.46      }
   53.47  
   53.48      /**
   53.49 @@ -189,7 +190,7 @@
   53.50          if (this.expression == expression) {
   53.51              return this;
   53.52          }
   53.53 -        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger));
   53.54 +        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger, tag));
   53.55      }
   53.56  
   53.57      /**
   53.58 @@ -204,10 +205,15 @@
   53.59      /**
   53.60       * Set the tag symbol for this switch. The tag symbol is where
   53.61       * the switch expression result is stored
   53.62 +     * @param lc lexical context
   53.63       * @param tag a symbol
   53.64 +     * @return a switch node with the symbol set
   53.65       */
   53.66 -    public void setTag(final Symbol tag) {
   53.67 -        this.tag = tag;
   53.68 +    public SwitchNode setTag(final LexicalContext lc, final Symbol tag) {
   53.69 +        if (this.tag == tag) {
   53.70 +            return this;
   53.71 +        }
   53.72 +        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger, tag));
   53.73      }
   53.74  
   53.75      /**
   53.76 @@ -229,12 +235,12 @@
   53.77          if(this.uniqueInteger == uniqueInteger) {
   53.78              return this;
   53.79          }
   53.80 -        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger));
   53.81 +        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger, tag));
   53.82      }
   53.83  
   53.84      @Override
   53.85      JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) {
   53.86 -        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger));
   53.87 +        return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger, tag));
   53.88      }
   53.89  
   53.90  }
    54.1 --- a/src/jdk/nashorn/internal/ir/Symbol.java	Thu Sep 24 10:00:42 2015 -0700
    54.2 +++ b/src/jdk/nashorn/internal/ir/Symbol.java	Thu Sep 24 10:09:56 2015 -0700
    54.3 @@ -25,7 +25,10 @@
    54.4  
    54.5  package jdk.nashorn.internal.ir;
    54.6  
    54.7 +import java.io.IOException;
    54.8 +import java.io.ObjectInputStream;
    54.9  import java.io.PrintWriter;
   54.10 +import java.io.Serializable;
   54.11  import java.util.HashSet;
   54.12  import java.util.Set;
   54.13  import java.util.StringTokenizer;
   54.14 @@ -47,7 +50,9 @@
   54.15   * refer to their location.
   54.16   */
   54.17  
   54.18 -public final class Symbol implements Comparable<Symbol> {
   54.19 +public final class Symbol implements Comparable<Symbol>, Cloneable, Serializable {
   54.20 +    private static final long serialVersionUID = 1L;
   54.21 +
   54.22      /** Is this Global */
   54.23      public static final int IS_GLOBAL   = 1;
   54.24      /** Is this a variable */
   54.25 @@ -94,10 +99,10 @@
   54.26  
   54.27      /** First bytecode method local variable slot for storing the value(s) of this variable. -1 indicates the variable
   54.28       * is not stored in local variable slots or it is not yet known. */
   54.29 -    private int firstSlot = -1;
   54.30 +    private transient int firstSlot = -1;
   54.31  
   54.32      /** Field number in scope or property; array index in varargs when not using arguments object. */
   54.33 -    private int fieldIndex = -1;
   54.34 +    private transient int fieldIndex = -1;
   54.35  
   54.36      /** Number of times this symbol is used in code */
   54.37      private int useCount;
   54.38 @@ -144,6 +149,15 @@
   54.39          }
   54.40      }
   54.41  
   54.42 +    @Override
   54.43 +    public Symbol clone() {
   54.44 +        try {
   54.45 +            return (Symbol)super.clone();
   54.46 +        } catch (final CloneNotSupportedException e) {
   54.47 +            throw new AssertionError(e);
   54.48 +        }
   54.49 +    }
   54.50 +
   54.51      private static String align(final String string, final int max) {
   54.52          final StringBuilder sb = new StringBuilder();
   54.53          sb.append(string.substring(0, Math.min(string.length(), max)));
   54.54 @@ -337,7 +351,7 @@
   54.55       * Flag this symbol as scope as described in {@link Symbol#isScope()}
   54.56       * @return the symbol
   54.57       */
   54.58 -     public Symbol setIsScope() {
   54.59 +    public Symbol setIsScope() {
   54.60          if (!isScope()) {
   54.61              if(shouldTrace()) {
   54.62                  trace("SET IS SCOPE");
   54.63 @@ -609,11 +623,11 @@
   54.64  
   54.65      /**
   54.66       * Increase the symbol's use count by one.
   54.67 -     * @return the symbol
   54.68       */
   54.69 -    public Symbol increaseUseCount() {
   54.70 -        useCount++;
   54.71 -        return this;
   54.72 +    public void increaseUseCount() {
   54.73 +        if (isScope()) { // Avoid dirtying a cache line; we only need the use count for scoped symbols
   54.74 +            useCount++;
   54.75 +        }
   54.76      }
   54.77  
   54.78      /**
   54.79 @@ -669,4 +683,10 @@
   54.80              new Throwable().printStackTrace(Context.getCurrentErr());
   54.81          }
   54.82      }
   54.83 +
   54.84 +    private void readObject(final ObjectInputStream in) throws ClassNotFoundException, IOException {
   54.85 +        in.defaultReadObject();
   54.86 +        firstSlot = -1;
   54.87 +        fieldIndex = -1;
   54.88 +    }
   54.89  }
    55.1 --- a/src/jdk/nashorn/internal/ir/TryNode.java	Thu Sep 24 10:00:42 2015 -0700
    55.2 +++ b/src/jdk/nashorn/internal/ir/TryNode.java	Thu Sep 24 10:09:56 2015 -0700
    55.3 @@ -65,7 +65,7 @@
    55.4      private final List<Block> inlinedFinallies;
    55.5  
    55.6      /** Exception symbol. */
    55.7 -    private Symbol exception;
    55.8 +    private final Symbol exception;
    55.9  
   55.10      private final LocalVariableConversion conversion;
   55.11  
   55.12 @@ -86,22 +86,23 @@
   55.13          this.finallyBody = finallyBody;
   55.14          this.conversion  = null;
   55.15          this.inlinedFinallies = Collections.emptyList();
   55.16 +        this.exception = null;
   55.17      }
   55.18  
   55.19 -    private TryNode(final TryNode tryNode, final Block body, final List<Block> catchBlocks, final Block finallyBody, final LocalVariableConversion conversion, final List<Block> inlinedFinallies) {
   55.20 +    private TryNode(final TryNode tryNode, final Block body, final List<Block> catchBlocks, final Block finallyBody, final LocalVariableConversion conversion, final List<Block> inlinedFinallies, final Symbol exception) {
   55.21          super(tryNode);
   55.22          this.body        = body;
   55.23          this.catchBlocks = catchBlocks;
   55.24          this.finallyBody = finallyBody;
   55.25          this.conversion  = conversion;
   55.26          this.inlinedFinallies = inlinedFinallies;
   55.27 -        this.exception = tryNode.exception;
   55.28 +        this.exception = exception;
   55.29      }
   55.30  
   55.31      @Override
   55.32      public Node ensureUniqueLabels(final LexicalContext lc) {
   55.33          //try nodes are never in lex context
   55.34 -        return new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies);
   55.35 +        return new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies, exception);
   55.36      }
   55.37  
   55.38      @Override
   55.39 @@ -160,7 +161,7 @@
   55.40          if (this.body == body) {
   55.41              return this;
   55.42          }
   55.43 -        return Node.replaceInLexicalContext(lc, this, new TryNode(this,  body, catchBlocks, finallyBody, conversion, inlinedFinallies));
   55.44 +        return Node.replaceInLexicalContext(lc, this, new TryNode(this,  body, catchBlocks, finallyBody, conversion, inlinedFinallies, exception));
   55.45      }
   55.46  
   55.47      /**
   55.48 @@ -197,7 +198,7 @@
   55.49          if (this.catchBlocks == catchBlocks) {
   55.50              return this;
   55.51          }
   55.52 -        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies));
   55.53 +        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies, exception));
   55.54      }
   55.55  
   55.56      /**
   55.57 @@ -209,12 +210,15 @@
   55.58      }
   55.59      /**
   55.60       * Set the exception symbol for this try block
   55.61 +     * @param lc lexical context
   55.62       * @param exception a symbol for the compiler to store the exception in
   55.63       * @return new TryNode or same if unchanged
   55.64       */
   55.65 -    public TryNode setException(final Symbol exception) {
   55.66 -        this.exception = exception;
   55.67 -        return this;
   55.68 +    public TryNode setException(final LexicalContext lc, final Symbol exception) {
   55.69 +        if (this.exception == exception) {
   55.70 +            return this;
   55.71 +        }
   55.72 +        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies, exception));
   55.73      }
   55.74  
   55.75      /**
   55.76 @@ -277,7 +281,7 @@
   55.77          if (this.finallyBody == finallyBody) {
   55.78              return this;
   55.79          }
   55.80 -        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies));
   55.81 +        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies, exception));
   55.82      }
   55.83  
   55.84      /**
   55.85 @@ -293,7 +297,7 @@
   55.86              return this;
   55.87          }
   55.88          assert checkInlinedFinallies(inlinedFinallies);
   55.89 -        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies));
   55.90 +        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies, exception));
   55.91      }
   55.92  
   55.93      private static boolean checkInlinedFinallies(final List<Block> inlinedFinallies) {
   55.94 @@ -314,7 +318,7 @@
   55.95          if(this.conversion == conversion) {
   55.96              return this;
   55.97          }
   55.98 -        return new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies);
   55.99 +        return new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies, exception);
  55.100      }
  55.101  
  55.102      @Override
    56.1 --- a/src/jdk/nashorn/internal/ir/debug/NashornClassReader.java	Thu Sep 24 10:00:42 2015 -0700
    56.2 +++ b/src/jdk/nashorn/internal/ir/debug/NashornClassReader.java	Thu Sep 24 10:09:56 2015 -0700
    56.3 @@ -36,7 +36,7 @@
    56.4  import jdk.nashorn.internal.ir.debug.NashornTextifier.NashornLabel;
    56.5  
    56.6  /**
    56.7 - * Subclass of the ASM classs reader that retains more info, such
    56.8 + * Subclass of the ASM class reader that retains more info, such
    56.9   * as bytecode offsets
   56.10   */
   56.11  public class NashornClassReader extends ClassReader {
    57.1 --- a/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java	Thu Sep 24 10:00:42 2015 -0700
    57.2 +++ b/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java	Thu Sep 24 10:09:56 2015 -0700
    57.3 @@ -193,7 +193,7 @@
    57.4      }
    57.5  
    57.6      /**
    57.7 -     * Get the class histograpm
    57.8 +     * Get the class histogram
    57.9       * @return class histogram element list
   57.10       */
   57.11      public List<ClassHistogramElement> getClassHistogram() {
    58.1 --- a/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Thu Sep 24 10:00:42 2015 -0700
    58.2 +++ b/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Thu Sep 24 10:09:56 2015 -0700
    58.3 @@ -192,7 +192,7 @@
    58.4          /**
    58.5           * Factory method for array data
    58.6           *
    58.7 -         * @param nb    underlying nativebuffer
    58.8 +         * @param nb    underlying native buffer
    58.9           * @param start start element
   58.10           * @param end   end element
   58.11           *
    59.1 --- a/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java	Thu Sep 24 10:00:42 2015 -0700
    59.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.3 @@ -1,51 +0,0 @@
    59.4 -/*
    59.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    59.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    59.7 - *
    59.8 - * This code is free software; you can redistribute it and/or modify it
    59.9 - * under the terms of the GNU General Public License version 2 only, as
   59.10 - * published by the Free Software Foundation.  Oracle designates this
   59.11 - * particular file as subject to the "Classpath" exception as provided
   59.12 - * by Oracle in the LICENSE file that accompanied this code.
   59.13 - *
   59.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   59.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   59.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   59.17 - * version 2 for more details (a copy is included in the LICENSE file that
   59.18 - * accompanied this code).
   59.19 - *
   59.20 - * You should have received a copy of the GNU General Public License version
   59.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   59.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   59.23 - *
   59.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   59.25 - * or visit www.oracle.com if you need additional information or have any
   59.26 - * questions.
   59.27 - */
   59.28 -
   59.29 -package jdk.nashorn.internal.objects;
   59.30 -
   59.31 -import jdk.nashorn.internal.runtime.ScriptFunction;
   59.32 -import jdk.nashorn.internal.runtime.ScriptFunctionData;
   59.33 -import jdk.nashorn.internal.runtime.ScriptObject;
   59.34 -import jdk.nashorn.internal.runtime.ScriptRuntime;
   59.35 -
   59.36 -/**
   59.37 - * A {@code ScriptFunctionImpl} subclass for functions created using {@code Function.prototype.bind}. Such functions
   59.38 - * must track their {@code [[TargetFunction]]} property for purposes of correctly implementing {@code [[HasInstance]]};
   59.39 - * see {@link ScriptFunction#isInstance(ScriptObject)}.
   59.40 - */
   59.41 -final class BoundScriptFunctionImpl extends ScriptFunctionImpl {
   59.42 -    private final ScriptFunction targetFunction;
   59.43 -
   59.44 -    BoundScriptFunctionImpl(final ScriptFunctionData data, final ScriptFunction targetFunction) {
   59.45 -        super(data, Global.instance());
   59.46 -        setPrototype(ScriptRuntime.UNDEFINED);
   59.47 -        this.targetFunction = targetFunction;
   59.48 -    }
   59.49 -
   59.50 -    @Override
   59.51 -    protected ScriptFunction getTargetFunction() {
   59.52 -        return targetFunction;
   59.53 -    }
   59.54 -}
    60.1 --- a/src/jdk/nashorn/internal/objects/Global.java	Thu Sep 24 10:00:42 2015 -0700
    60.2 +++ b/src/jdk/nashorn/internal/objects/Global.java	Thu Sep 24 10:09:56 2015 -0700
    60.3 @@ -1583,7 +1583,11 @@
    60.4          return ScriptFunction.getPrototype(builtinObject);
    60.5      }
    60.6  
    60.7 -    ScriptObject getFunctionPrototype() {
    60.8 +    /**
    60.9 +     * Get the builtin Function prototype.
   60.10 +     * @return the Function.prototype.
   60.11 +     */
   60.12 +    public ScriptObject getFunctionPrototype() {
   60.13          return ScriptFunction.getPrototype(builtinFunction);
   60.14      }
   60.15  
   60.16 @@ -1768,7 +1772,12 @@
   60.17          return ScriptFunction.getPrototype(getBuiltinFloat64Array());
   60.18      }
   60.19  
   60.20 -    ScriptFunction getTypeErrorThrower() {
   60.21 +    /**
   60.22 +     * Return the function that throws TypeError unconditionally. Used as "poison" methods for certain Function properties.
   60.23 +     *
   60.24 +     * @return the TypeError throwing function
   60.25 +     */
   60.26 +    public ScriptFunction getTypeErrorThrower() {
   60.27          return typeErrorThrower;
   60.28      }
   60.29  
   60.30 @@ -2157,7 +2166,7 @@
   60.31  
   60.32          // We want to avoid adding our generic lexical scope switchpoint to global constant invocations,
   60.33          // because those are invalidated per-key in the addBoundProperties method above.
   60.34 -        // We therefor check if the invocation does already have a switchpoint and the property is non-inherited,
   60.35 +        // We therefore check if the invocation does already have a switchpoint and the property is non-inherited,
   60.36          // assuming this only applies to global constants. If other non-inherited properties will
   60.37          // start using switchpoints some time in the future we'll have to revisit this.
   60.38          if (isScope && context.getEnv()._es6 && (invocation.getSwitchPoints() == null || !hasOwnProperty(name))) {
   60.39 @@ -2202,10 +2211,10 @@
   60.40       * Adds jjs shell interactive mode builtin functions to global scope.
   60.41       */
   60.42      public void addShellBuiltins() {
   60.43 -        Object value = ScriptFunctionImpl.makeFunction("input", ShellFunctions.INPUT);
   60.44 +        Object value = ScriptFunction.createBuiltin("input", ShellFunctions.INPUT);
   60.45          addOwnProperty("input", Attribute.NOT_ENUMERABLE, value);
   60.46  
   60.47 -        value = ScriptFunctionImpl.makeFunction("evalinput", ShellFunctions.EVALINPUT);
   60.48 +        value = ScriptFunction.createBuiltin("evalinput", ShellFunctions.EVALINPUT);
   60.49          addOwnProperty("evalinput", Attribute.NOT_ENUMERABLE, value);
   60.50      }
   60.51  
   60.52 @@ -2252,35 +2261,35 @@
   60.53          this.setInitialProto(getObjectPrototype());
   60.54  
   60.55          // initialize global function properties
   60.56 -        this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
   60.57 -
   60.58 -        this.parseInt = ScriptFunctionImpl.makeFunction("parseInt",   GlobalFunctions.PARSEINT,
   60.59 +        this.eval = this.builtinEval = ScriptFunction.createBuiltin("eval", EVAL);
   60.60 +
   60.61 +        this.parseInt = ScriptFunction.createBuiltin("parseInt",   GlobalFunctions.PARSEINT,
   60.62                      new Specialization[] {
   60.63                      new Specialization(GlobalFunctions.PARSEINT_Z),
   60.64                      new Specialization(GlobalFunctions.PARSEINT_I),
   60.65                      new Specialization(GlobalFunctions.PARSEINT_J),
   60.66                      new Specialization(GlobalFunctions.PARSEINT_OI),
   60.67                      new Specialization(GlobalFunctions.PARSEINT_O) });
   60.68 -        this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
   60.69 -        this.isNaN = ScriptFunctionImpl.makeFunction("isNaN",   GlobalFunctions.IS_NAN,
   60.70 +        this.parseFloat = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);
   60.71 +        this.isNaN = ScriptFunction.createBuiltin("isNaN",   GlobalFunctions.IS_NAN,
   60.72                     new Specialization[] {
   60.73                          new Specialization(GlobalFunctions.IS_NAN_I),
   60.74                          new Specialization(GlobalFunctions.IS_NAN_J),
   60.75                          new Specialization(GlobalFunctions.IS_NAN_D) });
   60.76 -        this.parseFloat         = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
   60.77 -        this.isNaN              = ScriptFunctionImpl.makeFunction("isNaN",      GlobalFunctions.IS_NAN);
   60.78 -        this.isFinite           = ScriptFunctionImpl.makeFunction("isFinite",   GlobalFunctions.IS_FINITE);
   60.79 -        this.encodeURI          = ScriptFunctionImpl.makeFunction("encodeURI",  GlobalFunctions.ENCODE_URI);
   60.80 -        this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
   60.81 -        this.decodeURI          = ScriptFunctionImpl.makeFunction("decodeURI",  GlobalFunctions.DECODE_URI);
   60.82 -        this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
   60.83 -        this.escape             = ScriptFunctionImpl.makeFunction("escape",     GlobalFunctions.ESCAPE);
   60.84 -        this.unescape           = ScriptFunctionImpl.makeFunction("unescape",   GlobalFunctions.UNESCAPE);
   60.85 -        this.print              = ScriptFunctionImpl.makeFunction("print",      env._print_no_newline ? PRINT : PRINTLN);
   60.86 -        this.load               = ScriptFunctionImpl.makeFunction("load",       LOAD);
   60.87 -        this.loadWithNewGlobal  = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL);
   60.88 -        this.exit               = ScriptFunctionImpl.makeFunction("exit",       EXIT);
   60.89 -        this.quit               = ScriptFunctionImpl.makeFunction("quit",       EXIT);
   60.90 +        this.parseFloat         = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);
   60.91 +        this.isNaN              = ScriptFunction.createBuiltin("isNaN",      GlobalFunctions.IS_NAN);
   60.92 +        this.isFinite           = ScriptFunction.createBuiltin("isFinite",   GlobalFunctions.IS_FINITE);
   60.93 +        this.encodeURI          = ScriptFunction.createBuiltin("encodeURI",  GlobalFunctions.ENCODE_URI);
   60.94 +        this.encodeURIComponent = ScriptFunction.createBuiltin("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
   60.95 +        this.decodeURI          = ScriptFunction.createBuiltin("decodeURI",  GlobalFunctions.DECODE_URI);
   60.96 +        this.decodeURIComponent = ScriptFunction.createBuiltin("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
   60.97 +        this.escape             = ScriptFunction.createBuiltin("escape",     GlobalFunctions.ESCAPE);
   60.98 +        this.unescape           = ScriptFunction.createBuiltin("unescape",   GlobalFunctions.UNESCAPE);
   60.99 +        this.print              = ScriptFunction.createBuiltin("print",      env._print_no_newline ? PRINT : PRINTLN);
  60.100 +        this.load               = ScriptFunction.createBuiltin("load",       LOAD);
  60.101 +        this.loadWithNewGlobal  = ScriptFunction.createBuiltin("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL);
  60.102 +        this.exit               = ScriptFunction.createBuiltin("exit",       EXIT);
  60.103 +        this.quit               = ScriptFunction.createBuiltin("quit",       EXIT);
  60.104  
  60.105          // built-in constructors
  60.106          this.builtinArray     = initConstructorAndSwitchPoint("Array", ScriptFunction.class);
  60.107 @@ -2360,7 +2369,7 @@
  60.108              // default file name
  60.109              addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null);
  60.110              // __noSuchProperty__ hook for ScriptContext search of missing variables
  60.111 -            final ScriptFunction noSuchProp = ScriptFunctionImpl.makeStrictFunction(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY);
  60.112 +            final ScriptFunction noSuchProp = ScriptFunction.createStrictBuiltin(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY);
  60.113              addOwnProperty(NO_SUCH_PROPERTY_NAME, Attribute.NOT_ENUMERABLE, noSuchProp);
  60.114          }
  60.115      }
  60.116 @@ -2371,17 +2380,17 @@
  60.117          final ScriptObject errorProto = getErrorPrototype();
  60.118  
  60.119          // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
  60.120 -        final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK);
  60.121 -        final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", NativeError.SET_STACK);
  60.122 +        final ScriptFunction getStack = ScriptFunction.createBuiltin("getStack", NativeError.GET_STACK);
  60.123 +        final ScriptFunction setStack = ScriptFunction.createBuiltin("setStack", NativeError.SET_STACK);
  60.124          errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
  60.125 -        final ScriptFunction getLineNumber = ScriptFunctionImpl.makeFunction("getLineNumber", NativeError.GET_LINENUMBER);
  60.126 -        final ScriptFunction setLineNumber = ScriptFunctionImpl.makeFunction("setLineNumber", NativeError.SET_LINENUMBER);
  60.127 +        final ScriptFunction getLineNumber = ScriptFunction.createBuiltin("getLineNumber", NativeError.GET_LINENUMBER);
  60.128 +        final ScriptFunction setLineNumber = ScriptFunction.createBuiltin("setLineNumber", NativeError.SET_LINENUMBER);
  60.129          errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber);
  60.130 -        final ScriptFunction getColumnNumber = ScriptFunctionImpl.makeFunction("getColumnNumber", NativeError.GET_COLUMNNUMBER);
  60.131 -        final ScriptFunction setColumnNumber = ScriptFunctionImpl.makeFunction("setColumnNumber", NativeError.SET_COLUMNNUMBER);
  60.132 +        final ScriptFunction getColumnNumber = ScriptFunction.createBuiltin("getColumnNumber", NativeError.GET_COLUMNNUMBER);
  60.133 +        final ScriptFunction setColumnNumber = ScriptFunction.createBuiltin("setColumnNumber", NativeError.SET_COLUMNNUMBER);
  60.134          errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber);
  60.135 -        final ScriptFunction getFileName = ScriptFunctionImpl.makeFunction("getFileName", NativeError.GET_FILENAME);
  60.136 -        final ScriptFunction setFileName = ScriptFunctionImpl.makeFunction("setFileName", NativeError.SET_FILENAME);
  60.137 +        final ScriptFunction getFileName = ScriptFunction.createBuiltin("getFileName", NativeError.GET_FILENAME);
  60.138 +        final ScriptFunction setFileName = ScriptFunction.createBuiltin("setFileName", NativeError.SET_FILENAME);
  60.139          errorProto.addOwnProperty("fileName", Attribute.NOT_ENUMERABLE, getFileName, setFileName);
  60.140  
  60.141          // ECMA 15.11.4.2 Error.prototype.name
  60.142 @@ -2420,20 +2429,22 @@
  60.143      }
  60.144  
  60.145      private void initScripting(final ScriptEnvironment scriptEnv) {
  60.146 -        Object value;
  60.147 -        value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE);
  60.148 +        ScriptObject value;
  60.149 +        value = ScriptFunction.createBuiltin("readLine", ScriptingFunctions.READLINE);
  60.150          addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);
  60.151  
  60.152 -        value = ScriptFunctionImpl.makeFunction("readFully", ScriptingFunctions.READFULLY);
  60.153 +        value = ScriptFunction.createBuiltin("readFully", ScriptingFunctions.READFULLY);
  60.154          addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value);
  60.155  
  60.156          final String execName = ScriptingFunctions.EXEC_NAME;
  60.157 -        value = ScriptFunctionImpl.makeFunction(execName, ScriptingFunctions.EXEC);
  60.158 +        value = ScriptFunction.createBuiltin(execName, ScriptingFunctions.EXEC);
  60.159 +        value.addOwnProperty(ScriptingFunctions.THROW_ON_ERROR_NAME, Attribute.NOT_ENUMERABLE, false);
  60.160 +
  60.161          addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value);
  60.162  
  60.163          // Nashorn extension: global.echo (scripting-mode-only)
  60.164          // alias for "print"
  60.165 -        value = get("print");
  60.166 +        value = (ScriptObject)get("print");
  60.167          addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value);
  60.168  
  60.169          // Nashorn extension: global.$OPTIONS (scripting-mode-only)
  60.170 @@ -2609,7 +2620,7 @@
  60.171          this.builtinFunction = initConstructor("Function", ScriptFunction.class);
  60.172  
  60.173          // create global anonymous function
  60.174 -        final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction();
  60.175 +        final ScriptFunction anon = ScriptFunction.createAnonymous();
  60.176          // need to copy over members of Function.prototype to anon function
  60.177          anon.addBoundProperties(getFunctionPrototype());
  60.178  
  60.179 @@ -2621,10 +2632,7 @@
  60.180          anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
  60.181  
  60.182          // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
  60.183 -        this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, 0);
  60.184 -        typeErrorThrower.setPrototype(UNDEFINED);
  60.185 -        // Non-constructor built-in functions do not have "prototype" property
  60.186 -        typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
  60.187 +        this.typeErrorThrower = ScriptFunction.createBuiltin("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER);
  60.188          typeErrorThrower.preventExtensions();
  60.189  
  60.190          // now initialize Object
  60.191 @@ -2635,8 +2643,8 @@
  60.192  
  60.193          // ES6 draft compliant __proto__ property of Object.prototype
  60.194          // accessors on Object.prototype for "__proto__"
  60.195 -        final ScriptFunction getProto = ScriptFunctionImpl.makeFunction("getProto", NativeObject.GET__PROTO__);
  60.196 -        final ScriptFunction setProto = ScriptFunctionImpl.makeFunction("setProto", NativeObject.SET__PROTO__);
  60.197 +        final ScriptFunction getProto = ScriptFunction.createBuiltin("getProto", NativeObject.GET__PROTO__);
  60.198 +        final ScriptFunction setProto = ScriptFunction.createBuiltin("setProto", NativeObject.SET__PROTO__);
  60.199          ObjectPrototype.addOwnProperty("__proto__", Attribute.NOT_ENUMERABLE, getProto, setProto);
  60.200  
  60.201          // Function valued properties of Function.prototype were not properly
    61.1 --- a/src/jdk/nashorn/internal/objects/NativeDataView.java	Thu Sep 24 10:00:42 2015 -0700
    61.2 +++ b/src/jdk/nashorn/internal/objects/NativeDataView.java	Thu Sep 24 10:09:56 2015 -0700
    61.3 @@ -22,6 +22,7 @@
    61.4   * or visit www.oracle.com if you need additional information or have any
    61.5   * questions.
    61.6   */
    61.7 +
    61.8  package jdk.nashorn.internal.objects;
    61.9  
   61.10  import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
    62.1 --- a/src/jdk/nashorn/internal/objects/NativeDebug.java	Thu Sep 24 10:00:42 2015 -0700
    62.2 +++ b/src/jdk/nashorn/internal/objects/NativeDebug.java	Thu Sep 24 10:09:56 2015 -0700
    62.3 @@ -26,6 +26,7 @@
    62.4  package jdk.nashorn.internal.objects;
    62.5  
    62.6  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    62.7 +
    62.8  import java.io.PrintWriter;
    62.9  import java.util.LinkedList;
   62.10  import java.util.Objects;
   62.11 @@ -246,7 +247,7 @@
   62.12          final PrintWriter out = Context.getCurrentErr();
   62.13  
   62.14          out.println("ScriptObject count " + ScriptObject.getCount());
   62.15 -        out.println("Scope count " + Scope.getCount());
   62.16 +        out.println("Scope count " + Scope.getScopeCount());
   62.17          out.println("ScriptObject listeners added " + PropertyListeners.getListenersAdded());
   62.18          out.println("ScriptObject listeners removed " + PropertyListeners.getListenersRemoved());
   62.19          out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount());
    63.1 --- a/src/jdk/nashorn/internal/objects/NativeError.java	Thu Sep 24 10:00:42 2015 -0700
    63.2 +++ b/src/jdk/nashorn/internal/objects/NativeError.java	Thu Sep 24 10:09:56 2015 -0700
    63.3 @@ -150,8 +150,8 @@
    63.4          initException(sobj);
    63.5          sobj.delete(STACK, false);
    63.6          if (! sobj.has("stack")) {
    63.7 -            final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", GET_STACK);
    63.8 -            final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", SET_STACK);
    63.9 +            final ScriptFunction getStack = ScriptFunction.createBuiltin("getStack", GET_STACK);
   63.10 +            final ScriptFunction setStack = ScriptFunction.createBuiltin("setStack", SET_STACK);
   63.11              sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
   63.12          }
   63.13          return UNDEFINED;
    64.1 --- a/src/jdk/nashorn/internal/objects/NativeFunction.java	Thu Sep 24 10:00:42 2015 -0700
    64.2 +++ b/src/jdk/nashorn/internal/objects/NativeFunction.java	Thu Sep 24 10:09:56 2015 -0700
    64.3 @@ -108,7 +108,7 @@
    64.4          throw new AssertionError("Should not reach here");
    64.5      }
    64.6  
    64.7 -     /**
    64.8 +    /**
    64.9       * Given an array-like object, converts it into a Java object array suitable for invocation of ScriptRuntime.apply
   64.10       * or for direct invocation of the applied function.
   64.11       * @param array the array-like object. Can be null in which case a zero-length array is created.
    65.1 --- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Thu Sep 24 10:00:42 2015 -0700
    65.2 +++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Thu Sep 24 10:09:56 2015 -0700
    65.3 @@ -621,11 +621,11 @@
    65.4              if (find != null) {
    65.5                  final Object value = find.getObjectValue();
    65.6                  if (value instanceof ScriptFunction) {
    65.7 -                    final ScriptFunctionImpl func = (ScriptFunctionImpl)value;
    65.8 +                    final ScriptFunction func = (ScriptFunction)value;
    65.9                      // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
   65.10                      // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
   65.11                      return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
   65.12 -                            func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
   65.13 +                            func.createBound(this, new Object[] { name })), 0, Object.class),
   65.14                              testJSAdaptor(adaptee, null, null, null),
   65.15                              adaptee.getProtoSwitchPoint(__call__, find.getOwner()));
   65.16                  }
    66.1 --- a/src/jdk/nashorn/internal/objects/NativeJava.java	Thu Sep 24 10:00:42 2015 -0700
    66.2 +++ b/src/jdk/nashorn/internal/objects/NativeJava.java	Thu Sep 24 10:09:56 2015 -0700
    66.3 @@ -93,7 +93,7 @@
    66.4      @Function(name="synchronized", attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
    66.5      public static Object synchronizedFunc(final Object self, final Object func, final Object obj) {
    66.6          if (func instanceof ScriptFunction) {
    66.7 -            return ((ScriptFunction)func).makeSynchronizedFunction(obj);
    66.8 +            return ((ScriptFunction)func).createSynchronized(obj);
    66.9          }
   66.10  
   66.11          throw typeError("not.a.function", ScriptRuntime.safeToString(func));
   66.12 @@ -342,7 +342,8 @@
   66.13      /**
   66.14       * Given a script object and a Java type, converts the script object into the desired Java type. Currently it
   66.15       * performs shallow creation of Java arrays, as well as wrapping of objects in Lists, Dequeues, Queues,
   66.16 -     * and Collections. Example:
   66.17 +     * and Collections. If conversion is not possible or fails for some reason, TypeError is thrown.
   66.18 +     * Example:
   66.19       * <pre>
   66.20       * var anArray = [1, "13", false]
   66.21       * var javaIntArray = Java.to(anArray, "int[]")
   66.22 @@ -386,7 +387,11 @@
   66.23          }
   66.24  
   66.25          if(targetClass.isArray()) {
   66.26 -            return JSType.toJavaArray(obj, targetClass.getComponentType());
   66.27 +            try {
   66.28 +                return JSType.toJavaArray(obj, targetClass.getComponentType());
   66.29 +            } catch (final Exception exp) {
   66.30 +                throw typeError(exp, "java.array.conversion.failed", targetClass.getName());
   66.31 +            }
   66.32          }
   66.33  
   66.34          if (targetClass == List.class || targetClass == Deque.class || targetClass == Queue.class || targetClass == Collection.class) {
    67.1 --- a/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Thu Sep 24 10:00:42 2015 -0700
    67.2 +++ b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Thu Sep 24 10:09:56 2015 -0700
    67.3 @@ -134,7 +134,7 @@
    67.4      }
    67.5  
    67.6      @Override
    67.7 -    protected Object invokeNoSuchProperty(final String name, final int programPoint) {
    67.8 +    protected Object invokeNoSuchProperty(final String name, final boolean isScope, final int programPoint) {
    67.9          final Object retval = createProperty(name);
   67.10          if (isValid(programPoint)) {
   67.11              throw new UnwarrantedOptimismException(retval, programPoint);
    68.1 --- a/src/jdk/nashorn/internal/objects/NativeRegExp.java	Thu Sep 24 10:00:42 2015 -0700
    68.2 +++ b/src/jdk/nashorn/internal/objects/NativeRegExp.java	Thu Sep 24 10:09:56 2015 -0700
    68.3 @@ -728,7 +728,7 @@
    68.4           *
    68.5           * $$ -> $
    68.6           * $& -> the matched substring
    68.7 -         * $` -> the portion of string that preceeds matched substring
    68.8 +         * $` -> the portion of string that precedes matched substring
    68.9           * $' -> the portion of string that follows the matched substring
   68.10           * $n -> the nth capture, where n is [1-9] and $n is NOT followed by a decimal digit
   68.11           * $nn -> the nnth capture, where nn is a two digit decimal number [01-99].
    69.1 --- a/src/jdk/nashorn/internal/objects/PrototypeObject.java	Thu Sep 24 10:00:42 2015 -0700
    69.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.3 @@ -1,115 +0,0 @@
    69.4 -/*
    69.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    69.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    69.7 - *
    69.8 - * This code is free software; you can redistribute it and/or modify it
    69.9 - * under the terms of the GNU General Public License version 2 only, as
   69.10 - * published by the Free Software Foundation.  Oracle designates this
   69.11 - * particular file as subject to the "Classpath" exception as provided
   69.12 - * by Oracle in the LICENSE file that accompanied this code.
   69.13 - *
   69.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   69.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   69.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   69.17 - * version 2 for more details (a copy is included in the LICENSE file that
   69.18 - * accompanied this code).
   69.19 - *
   69.20 - * You should have received a copy of the GNU General Public License version
   69.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   69.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   69.23 - *
   69.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   69.25 - * or visit www.oracle.com if you need additional information or have any
   69.26 - * questions.
   69.27 - */
   69.28 -
   69.29 -package jdk.nashorn.internal.objects;
   69.30 -
   69.31 -import static jdk.nashorn.internal.lookup.Lookup.MH;
   69.32 -import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
   69.33 -
   69.34 -import java.lang.invoke.MethodHandle;
   69.35 -import java.lang.invoke.MethodHandles;
   69.36 -import java.util.ArrayList;
   69.37 -import jdk.nashorn.internal.runtime.AccessorProperty;
   69.38 -import jdk.nashorn.internal.runtime.Property;
   69.39 -import jdk.nashorn.internal.runtime.PropertyMap;
   69.40 -import jdk.nashorn.internal.runtime.ScriptFunction;
   69.41 -import jdk.nashorn.internal.runtime.ScriptObject;
   69.42 -
   69.43 -/**
   69.44 - * Instances of this class serve as "prototype" object for script functions.
   69.45 - * The purpose is to expose "constructor" property from "prototype". Also, nasgen
   69.46 - * generated prototype classes extend from this class.
   69.47 - *
   69.48 - */
   69.49 -public class PrototypeObject extends ScriptObject {
   69.50 -    private static final PropertyMap map$;
   69.51 -
   69.52 -    private Object constructor;
   69.53 -
   69.54 -    private static final MethodHandle GET_CONSTRUCTOR = findOwnMH("getConstructor", Object.class, Object.class);
   69.55 -    private static final MethodHandle SET_CONSTRUCTOR = findOwnMH("setConstructor", void.class, Object.class, Object.class);
   69.56 -
   69.57 -    static {
   69.58 -        final ArrayList<Property> properties = new ArrayList<>(1);
   69.59 -        properties.add(AccessorProperty.create("constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR));
   69.60 -        map$ = PropertyMap.newMap(properties);
   69.61 -    }
   69.62 -
   69.63 -    private PrototypeObject(final Global global, final PropertyMap map) {
   69.64 -        super(global.getObjectPrototype(), map != map$? map.addAll(map$) : map$);
   69.65 -    }
   69.66 -
   69.67 -    PrototypeObject() {
   69.68 -        this(Global.instance(), map$);
   69.69 -    }
   69.70 -
   69.71 -    /**
   69.72 -     * PropertyObject constructor
   69.73 -     *
   69.74 -     * @param map property map
   69.75 -     */
   69.76 -    PrototypeObject(final PropertyMap map) {
   69.77 -        this(Global.instance(), map);
   69.78 -    }
   69.79 -
   69.80 -    PrototypeObject(final ScriptFunction func) {
   69.81 -        this(Global.instance(), map$);
   69.82 -        this.constructor = func;
   69.83 -    }
   69.84 -
   69.85 -    /**
   69.86 -     * Get the constructor for this {@code PrototypeObject}
   69.87 -     * @param self self reference
   69.88 -     * @return constructor, probably, but not necessarily, a {@link ScriptFunction}
   69.89 -     */
   69.90 -    static Object getConstructor(final Object self) {
   69.91 -        return (self instanceof PrototypeObject) ?
   69.92 -            ((PrototypeObject)self).getConstructor() :
   69.93 -            UNDEFINED;
   69.94 -    }
   69.95 -
   69.96 -    /**
   69.97 -     * Reset the constructor for this {@code PrototypeObject}
   69.98 -     * @param self self reference
   69.99 -     * @param constructor constructor, probably, but not necessarily, a {@link ScriptFunction}
  69.100 -     */
  69.101 -    static void setConstructor(final Object self, final Object constructor) {
  69.102 -        if (self instanceof PrototypeObject) {
  69.103 -            ((PrototypeObject)self).setConstructor(constructor);
  69.104 -        }
  69.105 -    }
  69.106 -
  69.107 -    private Object getConstructor() {
  69.108 -        return constructor;
  69.109 -    }
  69.110 -
  69.111 -    private void setConstructor(final Object constructor) {
  69.112 -        this.constructor = constructor;
  69.113 -    }
  69.114 -
  69.115 -    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
  69.116 -        return MH.findStatic(MethodHandles.lookup(), PrototypeObject.class, name, MH.type(rtype, types));
  69.117 -    }
  69.118 -}
    70.1 --- a/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Thu Sep 24 10:00:42 2015 -0700
    70.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.3 @@ -1,313 +0,0 @@
    70.4 -/*
    70.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    70.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    70.7 - *
    70.8 - * This code is free software; you can redistribute it and/or modify it
    70.9 - * under the terms of the GNU General Public License version 2 only, as
   70.10 - * published by the Free Software Foundation.  Oracle designates this
   70.11 - * particular file as subject to the "Classpath" exception as provided
   70.12 - * by Oracle in the LICENSE file that accompanied this code.
   70.13 - *
   70.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   70.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   70.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   70.17 - * version 2 for more details (a copy is included in the LICENSE file that
   70.18 - * accompanied this code).
   70.19 - *
   70.20 - * You should have received a copy of the GNU General Public License version
   70.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   70.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   70.23 - *
   70.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   70.25 - * or visit www.oracle.com if you need additional information or have any
   70.26 - * questions.
   70.27 - */
   70.28 -
   70.29 -package jdk.nashorn.internal.objects;
   70.30 -
   70.31 -import static jdk.nashorn.internal.lookup.Lookup.MH;
   70.32 -import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
   70.33 -
   70.34 -import java.lang.invoke.MethodHandle;
   70.35 -import java.util.ArrayList;
   70.36 -import jdk.nashorn.internal.runtime.AccessorProperty;
   70.37 -import jdk.nashorn.internal.runtime.GlobalFunctions;
   70.38 -import jdk.nashorn.internal.runtime.Property;
   70.39 -import jdk.nashorn.internal.runtime.PropertyMap;
   70.40 -import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
   70.41 -import jdk.nashorn.internal.runtime.ScriptFunction;
   70.42 -import jdk.nashorn.internal.runtime.ScriptFunctionData;
   70.43 -import jdk.nashorn.internal.runtime.ScriptObject;
   70.44 -import jdk.nashorn.internal.runtime.Specialization;
   70.45 -
   70.46 -/**
   70.47 - * Concrete implementation of ScriptFunction. This sets correct map for the
   70.48 - * function objects -- to expose properties like "prototype", "length" etc.
   70.49 - */
   70.50 -public class ScriptFunctionImpl extends ScriptFunction {
   70.51 -
   70.52 -    /** Reference to constructor prototype. */
   70.53 -    private Object prototype;
   70.54 -
   70.55 -    // property map for strict mode functions
   70.56 -    private static final PropertyMap strictmodemap$;
   70.57 -    // property map for bound functions
   70.58 -    private static final PropertyMap boundfunctionmap$;
   70.59 -    // property map for non-strict, non-bound functions.
   70.60 -    private static final PropertyMap map$;
   70.61 -
   70.62 -    // Marker object for lazily initialized prototype object
   70.63 -    private static final Object LAZY_PROTOTYPE = new Object();
   70.64 -
   70.65 -    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs, final Global global) {
   70.66 -        super(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
   70.67 -        init(global);
   70.68 -    }
   70.69 -
   70.70 -    /**
   70.71 -     * Constructor called by Nasgen generated code, no membercount, use the default map.
   70.72 -     * Creates builtin functions only.
   70.73 -     *
   70.74 -     * @param name name of function
   70.75 -     * @param invokeHandle handle for invocation
   70.76 -     * @param specs specialized versions of this method, if available, null otherwise
   70.77 -     */
   70.78 -    ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs) {
   70.79 -        this(name, invokeHandle, specs, Global.instance());
   70.80 -    }
   70.81 -
   70.82 -    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs, final Global global) {
   70.83 -        super(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
   70.84 -        init(global);
   70.85 -    }
   70.86 -
   70.87 -    /**
   70.88 -     * Constructor called by Nasgen generated code, no membercount, use the map passed as argument.
   70.89 -     * Creates builtin functions only.
   70.90 -     *
   70.91 -     * @param name name of function
   70.92 -     * @param invokeHandle handle for invocation
   70.93 -     * @param map initial property map
   70.94 -     * @param specs specialized versions of this method, if available, null otherwise
   70.95 -     */
   70.96 -    ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs) {
   70.97 -        this(name, invokeHandle, map, specs, Global.instance());
   70.98 -    }
   70.99 -
  70.100 -    private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags, final Global global) {
  70.101 -        super(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags);
  70.102 -        init(global);
  70.103 -    }
  70.104 -
  70.105 -    /**
  70.106 -     * Constructor called by Global.newScriptFunction (runtime).
  70.107 -     *
  70.108 -     * @param name name of function
  70.109 -     * @param methodHandle handle for invocation
  70.110 -     * @param scope scope object
  70.111 -     * @param specs specialized versions of this method, if available, null otherwise
  70.112 -     * @param flags {@link ScriptFunctionData} flags
  70.113 -     */
  70.114 -    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags) {
  70.115 -        this(name, methodHandle, scope, specs, flags, Global.instance());
  70.116 -    }
  70.117 -
  70.118 -    private ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope, final Global global) {
  70.119 -        super(data, getMap(data.isStrict()), scope);
  70.120 -        init(global);
  70.121 -    }
  70.122 -
  70.123 -    /**
  70.124 -     * Factory method called by compiler generated code for functions that need parent scope.
  70.125 -     *
  70.126 -     * @param constants the generated class' constant array
  70.127 -     * @param index the index of the {@code RecompilableScriptFunctionData} object in the constants array.
  70.128 -     * @param scope the parent scope object
  70.129 -     * @return a newly created function object
  70.130 -     */
  70.131 -    public static ScriptFunction create(final Object[] constants, final int index, final ScriptObject scope) {
  70.132 -        return new ScriptFunctionImpl((RecompilableScriptFunctionData)constants[index], scope, Global.instance());
  70.133 -    }
  70.134 -
  70.135 -    /**
  70.136 -     * Factory method called by compiler generated code for functions that don't need parent scope.
  70.137 -     *
  70.138 -     * @param constants the generated class' constant array
  70.139 -     * @param index the index of the {@code RecompilableScriptFunctionData} object in the constants array.
  70.140 -     * @return a newly created function object
  70.141 -     */
  70.142 -    public static ScriptFunction create(final Object[] constants, final int index) {
  70.143 -        return create(constants, index, null);
  70.144 -    }
  70.145 -
  70.146 -    /**
  70.147 -     * Only invoked internally from {@link BoundScriptFunctionImpl} constructor.
  70.148 -     * @param data the script function data for the bound function.
  70.149 -     * @param global the global object
  70.150 -     */
  70.151 -    ScriptFunctionImpl(final ScriptFunctionData data, final Global global) {
  70.152 -        super(data, boundfunctionmap$, null);
  70.153 -        init(global);
  70.154 -    }
  70.155 -
  70.156 -    static {
  70.157 -        final ArrayList<Property> properties = new ArrayList<>(3);
  70.158 -        properties.add(AccessorProperty.create("prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE));
  70.159 -        properties.add(AccessorProperty.create("length",  Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null));
  70.160 -        properties.add(AccessorProperty.create("name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null));
  70.161 -        map$ = PropertyMap.newMap(properties);
  70.162 -        strictmodemap$ = createStrictModeMap(map$);
  70.163 -        boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
  70.164 -    }
  70.165 -
  70.166 -    private static PropertyMap createStrictModeMap(final PropertyMap map) {
  70.167 -        final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
  70.168 -        PropertyMap newMap = map;
  70.169 -        // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
  70.170 -        newMap = newMap.addPropertyNoHistory(map.newUserAccessors("arguments", flags));
  70.171 -        newMap = newMap.addPropertyNoHistory(map.newUserAccessors("caller", flags));
  70.172 -        return newMap;
  70.173 -    }
  70.174 -
  70.175 -    private static boolean isStrict(final int flags) {
  70.176 -        return (flags & ScriptFunctionData.IS_STRICT) != 0;
  70.177 -    }
  70.178 -
  70.179 -    // Choose the map based on strict mode!
  70.180 -    private static PropertyMap getMap(final boolean strict) {
  70.181 -        return strict ? strictmodemap$ : map$;
  70.182 -    }
  70.183 -
  70.184 -    private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
  70.185 -        // Bound function map is same as strict function map, but additionally lacks the "prototype" property, see
  70.186 -        // ECMAScript 5.1 section 15.3.4.5
  70.187 -        return strictModeMap.deleteProperty(strictModeMap.findProperty("prototype"));
  70.188 -    }
  70.189 -
  70.190 -    // Instance of this class is used as global anonymous function which
  70.191 -    // serves as Function.prototype object.
  70.192 -    private static class AnonymousFunction extends ScriptFunctionImpl {
  70.193 -        private static final PropertyMap anonmap$ = PropertyMap.newMap();
  70.194 -
  70.195 -        AnonymousFunction() {
  70.196 -            super("", GlobalFunctions.ANONYMOUS, anonmap$, null);
  70.197 -        }
  70.198 -    }
  70.199 -
  70.200 -    static ScriptFunctionImpl newAnonymousFunction() {
  70.201 -        return new AnonymousFunction();
  70.202 -    }
  70.203 -
  70.204 -    private static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs, final int flags) {
  70.205 -        final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, flags);
  70.206 -        func.setPrototype(UNDEFINED);
  70.207 -        // Non-constructor built-in functions do not have "prototype" property
  70.208 -        func.deleteOwnProperty(func.getMap().findProperty("prototype"));
  70.209 -
  70.210 -        return func;
  70.211 -    }
  70.212 -
  70.213 -    /**
  70.214 -     * Factory method for non-constructor built-in functions
  70.215 -     *
  70.216 -     * @param name   function name
  70.217 -     * @param methodHandle handle for invocation
  70.218 -     * @param specs  specialized versions of function if available, null otherwise
  70.219 -     * @return new ScriptFunction
  70.220 -     */
  70.221 -    static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs) {
  70.222 -        return makeFunction(name, methodHandle, specs, ScriptFunctionData.IS_BUILTIN);
  70.223 -    }
  70.224 -
  70.225 -    /**
  70.226 -     * Factory method for non-constructor built-in, strict functions
  70.227 -     *
  70.228 -     * @param name   function name
  70.229 -     * @param methodHandle handle for invocation
  70.230 -     * @return new ScriptFunction
  70.231 -     */
  70.232 -    static ScriptFunction makeStrictFunction(final String name, final MethodHandle methodHandle) {
  70.233 -        return makeFunction(name, methodHandle, null, ScriptFunctionData.IS_BUILTIN | ScriptFunctionData.IS_STRICT );
  70.234 -    }
  70.235 -
  70.236 -    /**
  70.237 -     * Factory method for non-constructor built-in functions
  70.238 -     *
  70.239 -     * @param name   function name
  70.240 -     * @param methodHandle handle for invocation
  70.241 -     * @return new ScriptFunction
  70.242 -     */
  70.243 -    static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle) {
  70.244 -        return makeFunction(name, methodHandle, null);
  70.245 -    }
  70.246 -
  70.247 -    @Override
  70.248 -    public ScriptFunction makeSynchronizedFunction(final Object sync) {
  70.249 -        final MethodHandle mh = MH.insertArguments(ScriptFunction.INVOKE_SYNC, 0, this, sync);
  70.250 -        return makeFunction(getName(), mh);
  70.251 -    }
  70.252 -
  70.253 -    /**
  70.254 -     * Same as {@link ScriptFunction#makeBoundFunction(Object, Object[])}. The only reason we override it is so that we
  70.255 -     * can expose it.
  70.256 -     * @param self the self to bind to this function. Can be null (in which case, null is bound as this).
  70.257 -     * @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments.
  70.258 -     * @return a function with the specified self and parameters bound.
  70.259 -     */
  70.260 -    @Override
  70.261 -    public ScriptFunction makeBoundFunction(final Object self, final Object[] args) {
  70.262 -        return super.makeBoundFunction(self, args);
  70.263 -    }
  70.264 -
  70.265 -    /**
  70.266 -     * This method is used to create a bound function based on this function.
  70.267 -     *
  70.268 -     * @param data the {@code ScriptFunctionData} specifying the functions immutable portion.
  70.269 -     * @return a function initialized from the specified data. Its parent scope will be set to null, therefore the
  70.270 -     * passed in data should not expect a callee.
  70.271 -     */
  70.272 -    @Override
  70.273 -    protected ScriptFunction makeBoundFunction(final ScriptFunctionData data) {
  70.274 -        return new BoundScriptFunctionImpl(data, getTargetFunction());
  70.275 -    }
  70.276 -
  70.277 -    // return Object.prototype - used by "allocate"
  70.278 -    @Override
  70.279 -    protected final ScriptObject getObjectPrototype() {
  70.280 -        return Global.objectPrototype();
  70.281 -    }
  70.282 -
  70.283 -    @Override
  70.284 -    public final Object getPrototype() {
  70.285 -        if (prototype == LAZY_PROTOTYPE) {
  70.286 -            prototype = new PrototypeObject(this);
  70.287 -        }
  70.288 -        return prototype;
  70.289 -    }
  70.290 -
  70.291 -    @Override
  70.292 -    public final void setPrototype(final Object newProto) {
  70.293 -        if (newProto instanceof ScriptObject && newProto != this.prototype && allocatorMap != null) {
  70.294 -            // Replace our current allocator map with one that is associated with the new prototype.
  70.295 -            allocatorMap = allocatorMap.changeProto((ScriptObject)newProto);
  70.296 -        }
  70.297 -        this.prototype = newProto;
  70.298 -    }
  70.299 -
  70.300 -    // Internals below..
  70.301 -    private void init(final Global global) {
  70.302 -        this.setInitialProto(global.getFunctionPrototype());
  70.303 -        this.prototype = LAZY_PROTOTYPE;
  70.304 -
  70.305 -        // We have to fill user accessor functions late as these are stored
  70.306 -        // in this object rather than in the PropertyMap of this object.
  70.307 -        assert objectSpill == null;
  70.308 -        final ScriptFunction typeErrorThrower = global.getTypeErrorThrower();
  70.309 -        if (findProperty("arguments", true) != null) {
  70.310 -            initUserAccessors("arguments", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
  70.311 -        }
  70.312 -        if (findProperty("caller", true) != null) {
  70.313 -            initUserAccessors("caller", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
  70.314 -       }
  70.315 -    }
  70.316 -}
    71.1 --- a/src/jdk/nashorn/internal/parser/Parser.java	Thu Sep 24 10:00:42 2015 -0700
    71.2 +++ b/src/jdk/nashorn/internal/parser/Parser.java	Thu Sep 24 10:09:56 2015 -0700
    71.3 @@ -84,7 +84,6 @@
    71.4  import jdk.nashorn.internal.ir.ExpressionStatement;
    71.5  import jdk.nashorn.internal.ir.ForNode;
    71.6  import jdk.nashorn.internal.ir.FunctionNode;
    71.7 -import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    71.8  import jdk.nashorn.internal.ir.IdentNode;
    71.9  import jdk.nashorn.internal.ir.IfNode;
   71.10  import jdk.nashorn.internal.ir.IndexNode;
   71.11 @@ -513,8 +512,7 @@
   71.12  
   71.13          return lc.pop(functionNode).
   71.14              setBody(lc, newBody).
   71.15 -            setLastToken(lc, lastToken).
   71.16 -            setState(lc, errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED);
   71.17 +            setLastToken(lc, lastToken);
   71.18      }
   71.19  
   71.20      /**
   71.21 @@ -805,7 +803,7 @@
   71.22                                  if (!oldStrictMode && directiveStmts != null) {
   71.23                                      // check that directives preceding this one do not violate strictness
   71.24                                      for (final Node statement : directiveStmts) {
   71.25 -                                        // the get value will force unescape of preceeding
   71.26 +                                        // the get value will force unescape of preceding
   71.27                                          // escaped string directives
   71.28                                          getValue(statement.getToken());
   71.29                                      }
   71.30 @@ -2469,7 +2467,7 @@
   71.31          //         run: function() { println("run"); }
   71.32          //     };
   71.33          //
   71.34 -        // The object literal following the "new Constructor()" expresssion
   71.35 +        // The object literal following the "new Constructor()" expression
   71.36          // is passed as an additional (last) argument to the constructor.
   71.37          if (!env._no_syntax_extensions && type == LBRACE) {
   71.38              arguments.add(objectLiteral());
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/src/jdk/nashorn/internal/runtime/AstSerializer.java	Thu Sep 24 10:09:56 2015 -0700
    72.3 @@ -0,0 +1,55 @@
    72.4 +/*
    72.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    72.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    72.7 + *
    72.8 + * This code is free software; you can redistribute it and/or modify it
    72.9 + * under the terms of the GNU General Public License version 2 only, as
   72.10 + * published by the Free Software Foundation.  Oracle designates this
   72.11 + * particular file as subject to the "Classpath" exception as provided
   72.12 + * by Oracle in the LICENSE file that accompanied this code.
   72.13 + *
   72.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   72.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   72.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   72.17 + * version 2 for more details (a copy is included in the LICENSE file that
   72.18 + * accompanied this code).
   72.19 + *
   72.20 + * You should have received a copy of the GNU General Public License version
   72.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   72.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   72.23 + *
   72.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   72.25 + * or visit www.oracle.com if you need additional information or have any
   72.26 + * questions.
   72.27 + */
   72.28 +package jdk.nashorn.internal.runtime;
   72.29 +
   72.30 +import java.io.ByteArrayOutputStream;
   72.31 +import java.io.IOException;
   72.32 +import java.io.ObjectOutputStream;
   72.33 +import java.util.zip.Deflater;
   72.34 +import java.util.zip.DeflaterOutputStream;
   72.35 +import jdk.nashorn.internal.ir.FunctionNode;
   72.36 +import jdk.nashorn.internal.runtime.options.Options;
   72.37 +
   72.38 +/**
   72.39 + * This static utility class performs serialization of FunctionNode ASTs to a byte array.
   72.40 + * The format is a standard Java serialization stream, deflated.
   72.41 + */
   72.42 +final class AstSerializer {
   72.43 +    // Experimentally, we concluded that compression level 4 gives a good tradeoff between serialization speed
   72.44 +    // and size.
   72.45 +    private static final int COMPRESSION_LEVEL = Options.getIntProperty("nashorn.serialize.compression", 4);
   72.46 +    static byte[] serialize(final FunctionNode fn) {
   72.47 +        final ByteArrayOutputStream out = new ByteArrayOutputStream();
   72.48 +        final Deflater deflater = new Deflater(COMPRESSION_LEVEL);
   72.49 +        try (final ObjectOutputStream oout = new ObjectOutputStream(new DeflaterOutputStream(out, deflater))) {
   72.50 +            oout.writeObject(fn);
   72.51 +        } catch (final IOException e) {
   72.52 +            throw new AssertionError("Unexpected exception serializing function", e);
   72.53 +        } finally {
   72.54 +            deflater.end();
   72.55 +        }
   72.56 +        return out.toByteArray();
   72.57 +    }
   72.58 +}
    73.1 --- a/src/jdk/nashorn/internal/runtime/CompiledFunction.java	Thu Sep 24 10:00:42 2015 -0700
    73.2 +++ b/src/jdk/nashorn/internal/runtime/CompiledFunction.java	Thu Sep 24 10:09:56 2015 -0700
    73.3 @@ -27,6 +27,7 @@
    73.4  import static jdk.nashorn.internal.lookup.Lookup.MH;
    73.5  import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
    73.6  import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
    73.7 +
    73.8  import java.lang.invoke.CallSite;
    73.9  import java.lang.invoke.MethodHandle;
   73.10  import java.lang.invoke.MethodHandles;
   73.11 @@ -101,7 +102,7 @@
   73.12              /*
   73.13               * An optimistic builtin with isOptimistic=true works like any optimistic generated function, i.e. it
   73.14               * can throw unwarranted optimism exceptions. As native functions trivially can't have parts of them
   73.15 -             * regenerated as restof methods, this only works if the methods are atomic/functional in their behavior
   73.16 +             * regenerated as "restOf" methods, this only works if the methods are atomic/functional in their behavior
   73.17               * and doesn't modify state before an UOE can be thrown. If they aren't, we can reexecute a wider version
   73.18               * of the same builtin in a recompilation handler for FinalScriptFunctionData. There are several
   73.19               * candidate methods in Native* that would benefit from this, but I haven't had time to implement any
   73.20 @@ -566,7 +567,7 @@
   73.21              return handle;
   73.22          }
   73.23  
   73.24 -        // Otherwise, we need a new level of indirection; need to introduce a mutable call site that can relink itslef
   73.25 +        // Otherwise, we need a new level of indirection; need to introduce a mutable call site that can relink itself
   73.26          // to the compiled function's changed target whenever the optimistic assumptions are invalidated.
   73.27          final CallSite cs = new MutableCallSite(handle.type());
   73.28          relinkComposableInvoker(cs, this, isConstructor);
   73.29 @@ -820,7 +821,7 @@
   73.30          // isn't available, we'll use the old one bound into the call site.
   73.31          final OptimismInfo effectiveOptInfo = currentOptInfo != null ? currentOptInfo : oldOptInfo;
   73.32          FunctionNode fn = effectiveOptInfo.reparse();
   73.33 -        final boolean serialized = effectiveOptInfo.isSerialized();
   73.34 +        final boolean cached = fn.isCached();
   73.35          final Compiler compiler = effectiveOptInfo.getCompiler(fn, ct, re); //set to non rest-of
   73.36  
   73.37          if (!shouldRecompile) {
   73.38 @@ -828,11 +829,11 @@
   73.39              // recompiled a deoptimized version for an inner invocation.
   73.40              // We still need to do the rest of from the beginning
   73.41              logRecompile("Rest-of compilation [STANDALONE] ", fn, ct, effectiveOptInfo.invalidatedProgramPoints);
   73.42 -            return restOfHandle(effectiveOptInfo, compiler.compile(fn, serialized ? CompilationPhases.COMPILE_SERIALIZED_RESTOF : CompilationPhases.COMPILE_ALL_RESTOF), currentOptInfo != null);
   73.43 +            return restOfHandle(effectiveOptInfo, compiler.compile(fn, cached ? CompilationPhases.COMPILE_CACHED_RESTOF : CompilationPhases.COMPILE_ALL_RESTOF), currentOptInfo != null);
   73.44          }
   73.45  
   73.46          logRecompile("Deoptimizing recompilation (up to bytecode) ", fn, ct, effectiveOptInfo.invalidatedProgramPoints);
   73.47 -        fn = compiler.compile(fn, serialized ? CompilationPhases.RECOMPILE_SERIALIZED_UPTO_BYTECODE : CompilationPhases.COMPILE_UPTO_BYTECODE);
   73.48 +        fn = compiler.compile(fn, cached ? CompilationPhases.RECOMPILE_CACHED_UPTO_BYTECODE : CompilationPhases.COMPILE_UPTO_BYTECODE);
   73.49          log.fine("Reusable IR generated");
   73.50  
   73.51          // compile the rest of the function, and install it
   73.52 @@ -956,10 +957,6 @@
   73.53          FunctionNode reparse() {
   73.54              return data.reparse();
   73.55          }
   73.56 -
   73.57 -        boolean isSerialized() {
   73.58 -            return data.isSerialized();
   73.59 -        }
   73.60      }
   73.61  
   73.62      @SuppressWarnings("unused")
    74.1 --- a/src/jdk/nashorn/internal/runtime/Context.java	Thu Sep 24 10:00:42 2015 -0700
    74.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java	Thu Sep 24 10:09:56 2015 -0700
    74.3 @@ -153,7 +153,7 @@
    74.4       * Currently we are conservative and associate the name of a builtin class with all
    74.5       * its properties, so it's enough to invalidate a property to break all assumptions
    74.6       * about a prototype. This can be changed to a more fine grained approach, but no one
    74.7 -     * ever needs this, given the very rare occurance of swapping out only parts of
    74.8 +     * ever needs this, given the very rare occurrence of swapping out only parts of
    74.9       * a builtin v.s. the entire builtin object
   74.10       */
   74.11      private final Map<String, SwitchPoint> builtinSwitchPoints = new HashMap<>();
   74.12 @@ -1456,7 +1456,7 @@
   74.13       * @param level            log level
   74.14       * @param mh               method handle
   74.15       * @param paramStart       first parameter to print
   74.16 -     * @param printReturnValue should we print the return vaulue?
   74.17 +     * @param printReturnValue should we print the return value?
   74.18       * @param text             debug printout to add
   74.19       *
   74.20       * @return instrumented method handle, or null if logger not enabled
    75.1 --- a/src/jdk/nashorn/internal/runtime/FindProperty.java	Thu Sep 24 10:00:42 2015 -0700
    75.2 +++ b/src/jdk/nashorn/internal/runtime/FindProperty.java	Thu Sep 24 10:09:56 2015 -0700
    75.3 @@ -297,4 +297,3 @@
    75.4      }
    75.5  
    75.6  }
    75.7 -
    76.1 --- a/src/jdk/nashorn/internal/runtime/GlobalConstants.java	Thu Sep 24 10:00:42 2015 -0700
    76.2 +++ b/src/jdk/nashorn/internal/runtime/GlobalConstants.java	Thu Sep 24 10:09:56 2015 -0700
    76.3 @@ -67,7 +67,7 @@
    76.4   *
    76.5   * Thus everything registered as a global constant gets an extra chance. Set once,
    76.6   * reregister the switchpoint. Set twice or more - don't try again forever, or we'd
    76.7 - * just end up relinking our way into megamorphisism.
    76.8 + * just end up relinking our way into megamorphism.
    76.9   *
   76.10   * Also it has to be noted that this kind of linking creates a coupling between a Global
   76.11   * and the call sites in compiled code belonging to the Context. For this reason, the
    77.1 --- a/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Thu Sep 24 10:00:42 2015 -0700
    77.2 +++ b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Thu Sep 24 10:09:56 2015 -0700
    77.3 @@ -187,14 +187,14 @@
    77.4  
    77.5          double result = 0.0;
    77.6          int digit;
    77.7 -        // we should see atleast one valid digit
    77.8 +        // we should see at least one valid digit
    77.9          boolean entered = false;
   77.10          while (idx < length) {
   77.11              digit = fastDigit(str.charAt(idx++), radix);
   77.12              if (digit < 0) {
   77.13                  break;
   77.14              }
   77.15 -            // we have seen atleast one valid digit in the specified radix
   77.16 +            // we have seen at least one valid digit in the specified radix
   77.17              entered = true;
   77.18              result *= radix;
   77.19              result += digit;
    78.1 --- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Thu Sep 24 10:00:42 2015 -0700
    78.2 +++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Thu Sep 24 10:09:56 2015 -0700
    78.3 @@ -26,7 +26,6 @@
    78.4  package jdk.nashorn.internal.runtime;
    78.5  
    78.6  import java.lang.invoke.MethodHandle;
    78.7 -import java.util.Iterator;
    78.8  import java.util.concurrent.Callable;
    78.9  import jdk.nashorn.internal.objects.Global;
   78.10  import jdk.nashorn.internal.parser.JSONParser;
    79.1 --- a/src/jdk/nashorn/internal/runtime/JSType.java	Thu Sep 24 10:00:42 2015 -0700
    79.2 +++ b/src/jdk/nashorn/internal/runtime/JSType.java	Thu Sep 24 10:09:56 2015 -0700
    79.3 @@ -1968,7 +1968,7 @@
    79.4      /**
    79.5       * Get the unboxed (primitive) type for an object
    79.6       * @param o object
    79.7 -     * @return primive type or Object.class if not primitive
    79.8 +     * @return primitive type or Object.class if not primitive
    79.9       */
   79.10      public static Class<?> unboxedFieldType(final Object o) {
   79.11          if (o == null) {
    80.1 --- a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Thu Sep 24 10:00:42 2015 -0700
    80.2 +++ b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Thu Sep 24 10:09:56 2015 -0700
    80.3 @@ -206,7 +206,7 @@
    80.4      }
    80.5  
    80.6      @Override
    80.7 -    protected Object invokeNoSuchProperty(final String key, final int programPoint) {
    80.8 +    protected Object invokeNoSuchProperty(final String key, final boolean isScope, final int programPoint) {
    80.9          final Object retval = createProperty(key);
   80.10          if (isValid(programPoint)) {
   80.11              throw new UnwarrantedOptimismException(retval, programPoint);
    81.1 --- a/src/jdk/nashorn/internal/runtime/ParserException.java	Thu Sep 24 10:00:42 2015 -0700
    81.2 +++ b/src/jdk/nashorn/internal/runtime/ParserException.java	Thu Sep 24 10:09:56 2015 -0700
    81.3 @@ -38,7 +38,7 @@
    81.4      private final Source source;
    81.5      // token responsible for this exception
    81.6      private final long token;
    81.7 -    // if this is traslated as ECMA error, which type should be used?
    81.8 +    // if this is translated as ECMA error, which type should be used?
    81.9      private final JSErrorType errorType;
   81.10  
   81.11      /**
    82.1 --- a/src/jdk/nashorn/internal/runtime/PropertyListeners.java	Thu Sep 24 10:00:42 2015 -0700
    82.2 +++ b/src/jdk/nashorn/internal/runtime/PropertyListeners.java	Thu Sep 24 10:09:56 2015 -0700
    82.3 @@ -28,6 +28,7 @@
    82.4  import java.util.Map;
    82.5  import java.util.Set;
    82.6  import java.util.WeakHashMap;
    82.7 +import java.util.concurrent.atomic.LongAdder;
    82.8  
    82.9  /**
   82.10   * Helper class to manage property listeners and notification.
   82.11 @@ -37,8 +38,15 @@
   82.12      private Map<String, WeakPropertyMapSet> listeners;
   82.13  
   82.14      // These counters are updated in debug mode
   82.15 -    private static int listenersAdded;
   82.16 -    private static int listenersRemoved;
   82.17 +    private static LongAdder listenersAdded;
   82.18 +    private static LongAdder listenersRemoved;
   82.19 +
   82.20 +    static {
   82.21 +        if (Context.DEBUG) {
   82.22 +            listenersAdded = new LongAdder();
   82.23 +            listenersRemoved = new LongAdder();
   82.24 +        }
   82.25 +    }
   82.26  
   82.27      /**
   82.28       * Copy constructor
   82.29 @@ -54,16 +62,16 @@
   82.30       * Return aggregate listeners added to all PropertyListenerManagers
   82.31       * @return the listenersAdded
   82.32       */
   82.33 -    public static int getListenersAdded() {
   82.34 -        return listenersAdded;
   82.35 +    public static long getListenersAdded() {
   82.36 +        return listenersAdded.longValue();
   82.37      }
   82.38  
   82.39      /**
   82.40       * Return aggregate listeners removed from all PropertyListenerManagers
   82.41       * @return the listenersRemoved
   82.42       */
   82.43 -    public static int getListenersRemoved() {
   82.44 -        return listenersRemoved;
   82.45 +    public static long getListenersRemoved() {
   82.46 +        return listenersRemoved.longValue();
   82.47      }
   82.48  
   82.49      /**
   82.50 @@ -122,7 +130,7 @@
   82.51       */
   82.52      synchronized final void addListener(final String key, final PropertyMap propertyMap) {
   82.53          if (Context.DEBUG) {
   82.54 -            listenersAdded++;
   82.55 +            listenersAdded.increment();
   82.56          }
   82.57          if (listeners == null) {
   82.58              listeners = new WeakHashMap<>();
   82.59 @@ -151,6 +159,9 @@
   82.60                      propertyMap.propertyAdded(prop);
   82.61                  }
   82.62                  listeners.remove(prop.getKey());
   82.63 +                if (Context.DEBUG) {
   82.64 +                    listenersRemoved.increment();
   82.65 +                }
   82.66              }
   82.67          }
   82.68      }
   82.69 @@ -168,6 +179,9 @@
   82.70                      propertyMap.propertyDeleted(prop);
   82.71                  }
   82.72                  listeners.remove(prop.getKey());
   82.73 +                if (Context.DEBUG) {
   82.74 +                    listenersRemoved.increment();
   82.75 +                }
   82.76              }
   82.77          }
   82.78      }
   82.79 @@ -187,6 +201,9 @@
   82.80                      propertyMap.propertyModified(oldProp, newProp);
   82.81                  }
   82.82                  listeners.remove(oldProp.getKey());
   82.83 +                if (Context.DEBUG) {
   82.84 +                    listenersRemoved.increment();
   82.85 +                }
   82.86              }
   82.87          }
   82.88      }
    83.1 --- a/src/jdk/nashorn/internal/runtime/PropertyMap.java	Thu Sep 24 10:00:42 2015 -0700
    83.2 +++ b/src/jdk/nashorn/internal/runtime/PropertyMap.java	Thu Sep 24 10:09:56 2015 -0700
    83.3 @@ -42,6 +42,7 @@
    83.4  import java.util.Iterator;
    83.5  import java.util.NoSuchElementException;
    83.6  import java.util.WeakHashMap;
    83.7 +import java.util.concurrent.atomic.LongAdder;
    83.8  import jdk.nashorn.internal.scripts.JO;
    83.9  
   83.10  /**
   83.11 @@ -114,7 +115,7 @@
   83.12          }
   83.13  
   83.14          if (Context.DEBUG) {
   83.15 -            count++;
   83.16 +            count.increment();
   83.17          }
   83.18      }
   83.19  
   83.20 @@ -135,8 +136,8 @@
   83.21          this.freeSlots    = propertyMap.freeSlots;
   83.22  
   83.23          if (Context.DEBUG) {
   83.24 -            count++;
   83.25 -            clonedCount++;
   83.26 +            count.increment();
   83.27 +            clonedCount.increment();
   83.28          }
   83.29      }
   83.30  
   83.31 @@ -328,7 +329,7 @@
   83.32              if (sp != null) {
   83.33                  protoGetSwitches.remove(key);
   83.34                  if (Context.DEBUG) {
   83.35 -                    protoInvalidations++;
   83.36 +                    protoInvalidations.increment();
   83.37                  }
   83.38                  SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
   83.39              }
   83.40 @@ -343,7 +344,7 @@
   83.41              final int size = protoGetSwitches.size();
   83.42              if (size > 0) {
   83.43                  if (Context.DEBUG) {
   83.44 -                    protoInvalidations += size;
   83.45 +                    protoInvalidations.add(size);
   83.46                  }
   83.47                  SwitchPoint.invalidateAll(protoGetSwitches.values().toArray(new SwitchPoint[size]));
   83.48                  protoGetSwitches.clear();
   83.49 @@ -704,7 +705,7 @@
   83.50          }
   83.51  
   83.52          if (Context.DEBUG && cachedMap != null) {
   83.53 -            protoHistoryHit++;
   83.54 +            protoHistoryHit.increment();
   83.55          }
   83.56  
   83.57          return cachedMap;
   83.58 @@ -753,7 +754,7 @@
   83.59  
   83.60              if (historicMap != null) {
   83.61                  if (Context.DEBUG) {
   83.62 -                    historyHit++;
   83.63 +                    historyHit.increment();
   83.64                  }
   83.65  
   83.66                  return historicMap;
   83.67 @@ -901,7 +902,7 @@
   83.68          }
   83.69  
   83.70          if (Context.DEBUG) {
   83.71 -            setProtoNewMapCount++;
   83.72 +            setProtoNewMapCount.increment();
   83.73          }
   83.74  
   83.75          final PropertyMap newMap = new PropertyMap(this);
   83.76 @@ -1021,52 +1022,62 @@
   83.77      }
   83.78  
   83.79      // counters updated only in debug mode
   83.80 -    private static int count;
   83.81 -    private static int clonedCount;
   83.82 -    private static int historyHit;
   83.83 -    private static int protoInvalidations;
   83.84 -    private static int protoHistoryHit;
   83.85 -    private static int setProtoNewMapCount;
   83.86 +    private static LongAdder count;
   83.87 +    private static LongAdder clonedCount;
   83.88 +    private static LongAdder historyHit;
   83.89 +    private static LongAdder protoInvalidations;
   83.90 +    private static LongAdder protoHistoryHit;
   83.91 +    private static LongAdder setProtoNewMapCount;
   83.92 +    static {
   83.93 +        if (Context.DEBUG) {
   83.94 +            count = new LongAdder();
   83.95 +            clonedCount = new LongAdder();
   83.96 +            historyHit = new LongAdder();
   83.97 +            protoInvalidations = new LongAdder();
   83.98 +            protoHistoryHit = new LongAdder();
   83.99 +            setProtoNewMapCount = new LongAdder();
  83.100 +        }
  83.101 +    }
  83.102  
  83.103      /**
  83.104       * @return Total number of maps.
  83.105       */
  83.106 -    public static int getCount() {
  83.107 -        return count;
  83.108 +    public static long getCount() {
  83.109 +        return count.longValue();
  83.110      }
  83.111  
  83.112      /**
  83.113       * @return The number of maps that were cloned.
  83.114       */
  83.115 -    public static int getClonedCount() {
  83.116 -        return clonedCount;
  83.117 +    public static long getClonedCount() {
  83.118 +        return clonedCount.longValue();
  83.119      }
  83.120  
  83.121      /**
  83.122       * @return The number of times history was successfully used.
  83.123       */
  83.124 -    public static int getHistoryHit() {
  83.125 -        return historyHit;
  83.126 +    public static long getHistoryHit() {
  83.127 +        return historyHit.longValue();
  83.128      }
  83.129  
  83.130      /**
  83.131       * @return The number of times prototype changes caused invalidation.
  83.132       */
  83.133 -    public static int getProtoInvalidations() {
  83.134 -        return protoInvalidations;
  83.135 +    public static long getProtoInvalidations() {
  83.136 +        return protoInvalidations.longValue();
  83.137      }
  83.138  
  83.139      /**
  83.140       * @return The number of times proto history was successfully used.
  83.141       */
  83.142 -    public static int getProtoHistoryHit() {
  83.143 -        return protoHistoryHit;
  83.144 +    public static long getProtoHistoryHit() {
  83.145 +        return protoHistoryHit.longValue();
  83.146      }
  83.147  
  83.148      /**
  83.149       * @return The number of times prototypes were modified.
  83.150       */
  83.151 -    public static int getSetProtoNewMapCount() {
  83.152 -        return setProtoNewMapCount;
  83.153 +    public static long getSetProtoNewMapCount() {
  83.154 +        return setProtoNewMapCount.longValue();
  83.155      }
  83.156  }
    84.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.2 +++ b/src/jdk/nashorn/internal/runtime/PrototypeObject.java	Thu Sep 24 10:09:56 2015 -0700
    84.3 @@ -0,0 +1,118 @@
    84.4 +/*
    84.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    84.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    84.7 + *
    84.8 + * This code is free software; you can redistribute it and/or modify it
    84.9 + * under the terms of the GNU General Public License version 2 only, as
   84.10 + * published by the Free Software Foundation.  Oracle designates this
   84.11 + * particular file as subject to the "Classpath" exception as provided
   84.12 + * by Oracle in the LICENSE file that accompanied this code.
   84.13 + *
   84.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   84.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   84.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   84.17 + * version 2 for more details (a copy is included in the LICENSE file that
   84.18 + * accompanied this code).
   84.19 + *
   84.20 + * You should have received a copy of the GNU General Public License version
   84.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   84.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   84.23 + *
   84.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   84.25 + * or visit www.oracle.com if you need additional information or have any
   84.26 + * questions.
   84.27 + */
   84.28 +
   84.29 +package jdk.nashorn.internal.runtime;
   84.30 +
   84.31 +import static jdk.nashorn.internal.lookup.Lookup.MH;
   84.32 +import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
   84.33 +
   84.34 +import java.lang.invoke.MethodHandle;
   84.35 +import java.lang.invoke.MethodHandles;
   84.36 +import java.util.ArrayList;
   84.37 +import jdk.nashorn.internal.objects.Global;
   84.38 +
   84.39 +/**
   84.40 + * Instances of this class serve as "prototype" object for script functions.
   84.41 + * The purpose is to expose "constructor" property from "prototype". Also, nasgen
   84.42 + * generated prototype classes extend from this class.
   84.43 + */
   84.44 +public class PrototypeObject extends ScriptObject {
   84.45 +    private static final PropertyMap map$;
   84.46 +
   84.47 +    private Object constructor;
   84.48 +
   84.49 +    private static final MethodHandle GET_CONSTRUCTOR = findOwnMH("getConstructor", Object.class, Object.class);
   84.50 +    private static final MethodHandle SET_CONSTRUCTOR = findOwnMH("setConstructor", void.class, Object.class, Object.class);
   84.51 +
   84.52 +    static {
   84.53 +        final ArrayList<Property> properties = new ArrayList<>(1);
   84.54 +        properties.add(AccessorProperty.create("constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR));
   84.55 +        map$ = PropertyMap.newMap(properties);
   84.56 +    }
   84.57 +
   84.58 +    private PrototypeObject(final Global global, final PropertyMap map) {
   84.59 +        super(global.getObjectPrototype(), map != map$? map.addAll(map$) : map$);
   84.60 +    }
   84.61 +
   84.62 +    /**
   84.63 +     * Prototype constructor
   84.64 +     */
   84.65 +    protected PrototypeObject() {
   84.66 +        this(Global.instance(), map$);
   84.67 +    }
   84.68 +
   84.69 +    /**
   84.70 +     * PropertyObject constructor
   84.71 +     *
   84.72 +     * @param map property map
   84.73 +     */
   84.74 +    protected PrototypeObject(final PropertyMap map) {
   84.75 +        this(Global.instance(), map);
   84.76 +    }
   84.77 +
   84.78 +    /**
   84.79 +     * PropertyObject constructor
   84.80 +     *
   84.81 +     * @param func constructor function
   84.82 +     */
   84.83 +    protected PrototypeObject(final ScriptFunction func) {
   84.84 +        this(Global.instance(), map$);
   84.85 +        this.constructor = func;
   84.86 +    }
   84.87 +
   84.88 +    /**
   84.89 +     * Get the constructor for this {@code PrototypeObject}
   84.90 +     * @param self self reference
   84.91 +     * @return constructor, probably, but not necessarily, a {@link ScriptFunction}
   84.92 +     */
   84.93 +    public static Object getConstructor(final Object self) {
   84.94 +        return (self instanceof PrototypeObject) ?
   84.95 +            ((PrototypeObject)self).getConstructor() :
   84.96 +            UNDEFINED;
   84.97 +    }
   84.98 +
   84.99 +    /**
  84.100 +     * Reset the constructor for this {@code PrototypeObject}
  84.101 +     * @param self self reference
  84.102 +     * @param constructor constructor, probably, but not necessarily, a {@link ScriptFunction}
  84.103 +     */
  84.104 +    public static void setConstructor(final Object self, final Object constructor) {
  84.105 +        if (self instanceof PrototypeObject) {
  84.106 +            ((PrototypeObject)self).setConstructor(constructor);
  84.107 +        }
  84.108 +    }
  84.109 +
  84.110 +    private Object getConstructor() {
  84.111 +        return constructor;
  84.112 +    }
  84.113 +
  84.114 +    private void setConstructor(final Object constructor) {
  84.115 +        this.constructor = constructor;
  84.116 +    }
  84.117 +
  84.118 +    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
  84.119 +        return MH.findStatic(MethodHandles.lookup(), PrototypeObject.class, name, MH.type(rtype, types));
  84.120 +    }
  84.121 +}
    85.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Thu Sep 24 10:00:42 2015 -0700
    85.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Thu Sep 24 10:09:56 2015 -0700
    85.3 @@ -26,16 +26,25 @@
    85.4  package jdk.nashorn.internal.runtime;
    85.5  
    85.6  import static jdk.nashorn.internal.lookup.Lookup.MH;
    85.7 +
    85.8  import java.io.IOException;
    85.9  import java.lang.invoke.MethodHandle;
   85.10  import java.lang.invoke.MethodHandles;
   85.11  import java.lang.invoke.MethodType;
   85.12 +import java.lang.ref.Reference;
   85.13 +import java.lang.ref.SoftReference;
   85.14  import java.util.Collection;
   85.15  import java.util.Collections;
   85.16  import java.util.HashSet;
   85.17 +import java.util.IdentityHashMap;
   85.18  import java.util.Map;
   85.19  import java.util.Set;
   85.20  import java.util.TreeMap;
   85.21 +import java.util.concurrent.ExecutorService;
   85.22 +import java.util.concurrent.LinkedBlockingDeque;
   85.23 +import java.util.concurrent.ThreadFactory;
   85.24 +import java.util.concurrent.ThreadPoolExecutor;
   85.25 +import java.util.concurrent.TimeUnit;
   85.26  import jdk.internal.dynalink.support.NameCodec;
   85.27  import jdk.nashorn.internal.codegen.Compiler;
   85.28  import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
   85.29 @@ -45,8 +54,15 @@
   85.30  import jdk.nashorn.internal.codegen.OptimisticTypesPersistence;
   85.31  import jdk.nashorn.internal.codegen.TypeMap;
   85.32  import jdk.nashorn.internal.codegen.types.Type;
   85.33 +import jdk.nashorn.internal.ir.Block;
   85.34 +import jdk.nashorn.internal.ir.ForNode;
   85.35  import jdk.nashorn.internal.ir.FunctionNode;
   85.36 +import jdk.nashorn.internal.ir.IdentNode;
   85.37  import jdk.nashorn.internal.ir.LexicalContext;
   85.38 +import jdk.nashorn.internal.ir.Node;
   85.39 +import jdk.nashorn.internal.ir.SwitchNode;
   85.40 +import jdk.nashorn.internal.ir.Symbol;
   85.41 +import jdk.nashorn.internal.ir.TryNode;
   85.42  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   85.43  import jdk.nashorn.internal.objects.Global;
   85.44  import jdk.nashorn.internal.parser.Parser;
   85.45 @@ -55,6 +71,7 @@
   85.46  import jdk.nashorn.internal.runtime.logging.DebugLogger;
   85.47  import jdk.nashorn.internal.runtime.logging.Loggable;
   85.48  import jdk.nashorn.internal.runtime.logging.Logger;
   85.49 +import jdk.nashorn.internal.runtime.options.Options;
   85.50  /**
   85.51   * This is a subclass that represents a script function that may be regenerated,
   85.52   * for example with specialization based on call site types, or lazily generated.
   85.53 @@ -66,6 +83,8 @@
   85.54      /** Prefix used for all recompiled script classes */
   85.55      public static final String RECOMPILATION_PREFIX = "Recompilation$";
   85.56  
   85.57 +    private static final ExecutorService astSerializerExecutorService = createAstSerializerExecutorService();
   85.58 +
   85.59      /** Unique function node id for this function node */
   85.60      private final int functionNodeId;
   85.61  
   85.62 @@ -77,8 +96,12 @@
   85.63      /** Source from which FunctionNode was parsed. */
   85.64      private transient Source source;
   85.65  
   85.66 -    /** Serialized, compressed form of the AST. Used by split functions as they can't be reparsed from source. */
   85.67 -    private final byte[] serializedAst;
   85.68 +    /**
   85.69 +     * Cached form of the AST. Either a {@code SerializedAst} object used by split functions as they can't be
   85.70 +     * reparsed from source, or a soft reference to a {@code FunctionNode} for other functions (it is safe
   85.71 +     * to be cleared as they can be reparsed).
   85.72 +     */
   85.73 +    private volatile Object cachedAst;
   85.74  
   85.75      /** Token of this function within the source. */
   85.76      private final long token;
   85.77 @@ -128,7 +151,6 @@
   85.78       * @param nestedFunctions     nested function map
   85.79       * @param externalScopeDepths external scope depths
   85.80       * @param internalSymbols     internal symbols to method, defined in its scope
   85.81 -     * @param serializedAst       a serialized AST representation. Normally only used for split functions.
   85.82       */
   85.83      public RecompilableScriptFunctionData(
   85.84          final FunctionNode functionNode,
   85.85 @@ -136,8 +158,7 @@
   85.86          final AllocationStrategy allocationStrategy,
   85.87          final Map<Integer, RecompilableScriptFunctionData> nestedFunctions,
   85.88          final Map<String, Integer> externalScopeDepths,
   85.89 -        final Set<String> internalSymbols,
   85.90 -        final byte[] serializedAst) {
   85.91 +        final Set<String> internalSymbols) {
   85.92  
   85.93          super(functionName(functionNode),
   85.94                Math.min(functionNode.getParameters().size(), MAX_ARITY),
   85.95 @@ -161,7 +182,6 @@
   85.96              nfn.setParent(this);
   85.97          }
   85.98  
   85.99 -        this.serializedAst = serializedAst;
  85.100          createLogger();
  85.101      }
  85.102  
  85.103 @@ -244,7 +264,7 @@
  85.104       * @return parent data, or null if non exists and also null IF UNKNOWN.
  85.105       */
  85.106      public RecompilableScriptFunctionData getParent() {
  85.107 -       return parent;
  85.108 +        return parent;
  85.109      }
  85.110  
  85.111      void setParent(final RecompilableScriptFunctionData parent) {
  85.112 @@ -358,13 +378,11 @@
  85.113          return allocationStrategy.allocate(map);
  85.114      }
  85.115  
  85.116 -    boolean isSerialized() {
  85.117 -        return serializedAst != null;
  85.118 -    }
  85.119 -
  85.120      FunctionNode reparse() {
  85.121 -        if (isSerialized()) {
  85.122 -            return deserialize();
  85.123 +        final FunctionNode cachedFunction = getCachedAst();
  85.124 +        if (cachedFunction != null) {
  85.125 +            assert cachedFunction.isCached();
  85.126 +            return cachedFunction;
  85.127          }
  85.128  
  85.129          final int descPosition = Token.descPosition(token);
  85.130 @@ -391,7 +409,104 @@
  85.131          return (isProgram() ? program : extractFunctionFromScript(program)).setName(null, functionName);
  85.132      }
  85.133  
  85.134 -    private FunctionNode deserialize() {
  85.135 +    private FunctionNode getCachedAst() {
  85.136 +        final Object lCachedAst = cachedAst;
  85.137 +        // Are we softly caching the AST?
  85.138 +        if (lCachedAst instanceof Reference<?>) {
  85.139 +            final FunctionNode fn = (FunctionNode)((Reference<?>)lCachedAst).get();
  85.140 +            if (fn != null) {
  85.141 +                // Yes we are - this is fast
  85.142 +                return cloneSymbols(fn);
  85.143 +            }
  85.144 +        // Are we strongly caching a serialized AST (for split functions only)?
  85.145 +        } else if (lCachedAst instanceof SerializedAst) {
  85.146 +            final SerializedAst serializedAst = (SerializedAst)lCachedAst;
  85.147 +            // Even so, are we also softly caching the AST?
  85.148 +            final FunctionNode cachedFn = serializedAst.cachedAst.get();
  85.149 +            if (cachedFn != null) {
  85.150 +                // Yes we are - this is fast
  85.151 +                return cloneSymbols(cachedFn);
  85.152 +            }
  85.153 +            final FunctionNode deserializedFn = deserialize(serializedAst.serializedAst);
  85.154 +            // Softly cache after deserialization, maybe next time we won't need to deserialize
  85.155 +            serializedAst.cachedAst = new SoftReference<>(deserializedFn);
  85.156 +            return deserializedFn;
  85.157 +        }
  85.158 +        // No cached representation; return null for reparsing
  85.159 +        return null;
  85.160 +    }
  85.161 +
  85.162 +    /**
  85.163 +     * Sets the AST to cache in this function
  85.164 +     * @param astToCache the new AST to cache
  85.165 +     */
  85.166 +    public void setCachedAst(final FunctionNode astToCache) {
  85.167 +        assert astToCache.getId() == functionNodeId; // same function
  85.168 +        assert !(cachedAst instanceof SerializedAst); // Can't overwrite serialized AST
  85.169 +
  85.170 +        final boolean isSplit = astToCache.isSplit();
  85.171 +        // If we're caching a split function, we're doing it in the eager pass, hence there can be no other
  85.172 +        // cached representation already. In other words, isSplit implies cachedAst == null.
  85.173 +        assert !isSplit || cachedAst == null; //
  85.174 +
  85.175 +        final FunctionNode symbolClonedAst = cloneSymbols(astToCache);
  85.176 +        final Reference<FunctionNode> ref = new SoftReference<>(symbolClonedAst);
  85.177 +        cachedAst = ref;
  85.178 +
  85.179 +        // Asynchronously serialize split functions.
  85.180 +        if (isSplit) {
  85.181 +            astSerializerExecutorService.execute(new Runnable() {
  85.182 +                @Override
  85.183 +                public void run() {
  85.184 +                    cachedAst = new SerializedAst(symbolClonedAst, ref);
  85.185 +                }
  85.186 +            });
  85.187 +        }
  85.188 +    }
  85.189 +
  85.190 +    /**
  85.191 +     * Creates the AST serializer executor service used for in-memory serialization of split functions' ASTs.
  85.192 +     * It is created with an unbounded queue (so it can queue any number of pending tasks). Its core and max
  85.193 +     * threads is the same, but they are all allowed to time out so when there's no work, they can all go
  85.194 +     * away. The threads will be daemons, and they will time out if idle for a minute. Their priority is also
  85.195 +     * slightly lower than normal priority as we'd prefer the CPU to keep running the program; serializing
  85.196 +     * split function is a memory conservation measure (it allows us to release the AST), it can wait a bit.
  85.197 +     * @return an executor service with above described characteristics.
  85.198 +     */
  85.199 +    private static ExecutorService createAstSerializerExecutorService() {
  85.200 +        final int threads = Math.max(1, Options.getIntProperty("nashorn.serialize.threads", Runtime.getRuntime().availableProcessors() / 2));
  85.201 +        final ThreadPoolExecutor service = new ThreadPoolExecutor(threads, threads, 1L, TimeUnit.MINUTES, new LinkedBlockingDeque<Runnable>(),
  85.202 +                new ThreadFactory() {
  85.203 +                    @Override
  85.204 +                    public Thread newThread(final Runnable r) {
  85.205 +                        final Thread t = new Thread(r, "Nashorn AST Serializer");
  85.206 +                        t.setDaemon(true);
  85.207 +                        t.setPriority(Thread.NORM_PRIORITY - 1);
  85.208 +                        return t;
  85.209 +                    }
  85.210 +                });
  85.211 +        service.allowCoreThreadTimeOut(true);
  85.212 +        return service;
  85.213 +    }
  85.214 +
  85.215 +    /**
  85.216 +     * A tuple of a serialized AST and a soft reference to a deserialized AST. This is used to cache split
  85.217 +     * functions. Since split functions are altered from their source form, they can't be reparsed from
  85.218 +     * source. While we could just use the {@code byte[]} representation in {@link RecompilableScriptFunctionData#cachedAst}
  85.219 +     * we're using this tuple instead to also keep a deserialized AST around in memory to cut down on
  85.220 +     * deserialization costs.
  85.221 +     */
  85.222 +    private static class SerializedAst {
  85.223 +        private final byte[] serializedAst;
  85.224 +        private volatile Reference<FunctionNode> cachedAst;
  85.225 +
  85.226 +        SerializedAst(final FunctionNode fn, final Reference<FunctionNode> cachedAst) {
  85.227 +            this.serializedAst = AstSerializer.serialize(fn);
  85.228 +            this.cachedAst = cachedAst;
  85.229 +        }
  85.230 +    }
  85.231 +
  85.232 +    private FunctionNode deserialize(final byte[] serializedAst) {
  85.233          final ScriptEnvironment env = installer.getOwner();
  85.234          final Timing timing = env._timing;
  85.235          final long t1 = System.nanoTime();
  85.236 @@ -402,6 +517,107 @@
  85.237          }
  85.238      }
  85.239  
  85.240 +    private FunctionNode cloneSymbols(final FunctionNode fn) {
  85.241 +        final IdentityHashMap<Symbol, Symbol> symbolReplacements = new IdentityHashMap<>();
  85.242 +        final boolean cached = fn.isCached();
  85.243 +        // blockDefinedSymbols is used to re-mark symbols defined outside the function as global. We only
  85.244 +        // need to do this when we cache an eagerly parsed function (which currently means a split one, as we
  85.245 +        // don't cache non-split functions from the eager pass); those already cached, or those not split
  85.246 +        // don't need this step.
  85.247 +        final Set<Symbol> blockDefinedSymbols = fn.isSplit() && !cached ? Collections.newSetFromMap(new IdentityHashMap<Symbol, Boolean>()) : null;
  85.248 +        FunctionNode newFn = (FunctionNode)fn.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  85.249 +
  85.250 +            private Symbol getReplacement(final Symbol original) {
  85.251 +                if (original == null) {
  85.252 +                    return null;
  85.253 +                }
  85.254 +                final Symbol existingReplacement = symbolReplacements.get(original);
  85.255 +                if (existingReplacement != null) {
  85.256 +                    return existingReplacement;
  85.257 +                }
  85.258 +                final Symbol newReplacement = original.clone();
  85.259 +                symbolReplacements.put(original, newReplacement);
  85.260 +                return newReplacement;
  85.261 +            }
  85.262 +
  85.263 +            @Override
  85.264 +            public Node leaveIdentNode(final IdentNode identNode) {
  85.265 +                final Symbol oldSymbol = identNode.getSymbol();
  85.266 +                if (oldSymbol != null) {
  85.267 +                    final Symbol replacement = getReplacement(oldSymbol);
  85.268 +                    return identNode.setSymbol(replacement);
  85.269 +                }
  85.270 +                return identNode;
  85.271 +            }
  85.272 +
  85.273 +            @Override
  85.274 +            public Node leaveForNode(final ForNode forNode) {
  85.275 +                return ensureUniqueLabels(forNode.setIterator(lc, getReplacement(forNode.getIterator())));
  85.276 +            }
  85.277 +
  85.278 +            @Override
  85.279 +            public Node leaveSwitchNode(final SwitchNode switchNode) {
  85.280 +                return ensureUniqueLabels(switchNode.setTag(lc, getReplacement(switchNode.getTag())));
  85.281 +            }
  85.282 +
  85.283 +            @Override
  85.284 +            public Node leaveTryNode(final TryNode tryNode) {
  85.285 +                return ensureUniqueLabels(tryNode.setException(lc, getReplacement(tryNode.getException())));
  85.286 +            }
  85.287 +
  85.288 +            @Override
  85.289 +            public boolean enterBlock(final Block block) {
  85.290 +                for(final Symbol symbol: block.getSymbols()) {
  85.291 +                    final Symbol replacement = getReplacement(symbol);
  85.292 +                    if (blockDefinedSymbols != null) {
  85.293 +                        blockDefinedSymbols.add(replacement);
  85.294 +                    }
  85.295 +                }
  85.296 +                return true;
  85.297 +            }
  85.298 +
  85.299 +            @Override
  85.300 +            public Node leaveBlock(final Block block) {
  85.301 +                return ensureUniqueLabels(block.replaceSymbols(lc, symbolReplacements));
  85.302 +            }
  85.303 +
  85.304 +            @Override
  85.305 +            public Node leaveFunctionNode(final FunctionNode functionNode) {
  85.306 +                return functionNode.setParameters(lc, functionNode.visitParameters(this));
  85.307 +            }
  85.308 +
  85.309 +            @Override
  85.310 +            protected Node leaveDefault(final Node node) {
  85.311 +                return ensureUniqueLabels(node);
  85.312 +            };
  85.313 +
  85.314 +            private Node ensureUniqueLabels(final Node node) {
  85.315 +                // If we're returning a cached AST, we must also ensure unique labels
  85.316 +                return cached ? node.ensureUniqueLabels(lc) : node;
  85.317 +            }
  85.318 +        });
  85.319 +
  85.320 +        if (blockDefinedSymbols != null) {
  85.321 +            // Mark all symbols not defined in blocks as globals
  85.322 +            Block newBody = null;
  85.323 +            for(final Symbol symbol: symbolReplacements.values()) {
  85.324 +                if(!blockDefinedSymbols.contains(symbol)) {
  85.325 +                    assert symbol.isScope(); // must be scope
  85.326 +                    assert externalScopeDepths.containsKey(symbol.getName()); // must be known to us as an external
  85.327 +                    // Register it in the function body symbol table as a new global symbol
  85.328 +                    symbol.setFlags((symbol.getFlags() & ~Symbol.KINDMASK) | Symbol.IS_GLOBAL);
  85.329 +                    if (newBody == null) {
  85.330 +                        newBody = newFn.getBody().copyWithNewSymbols();
  85.331 +                        newFn = newFn.setBody(null, newBody);
  85.332 +                    }
  85.333 +                    assert newBody.getExistingSymbol(symbol.getName()) == null; // must not be defined in the body already
  85.334 +                    newBody.putSymbol(symbol);
  85.335 +                }
  85.336 +            }
  85.337 +        }
  85.338 +        return newFn.setCached(null);
  85.339 +    }
  85.340 +
  85.341      private boolean getFunctionFlag(final int flag) {
  85.342          return (functionFlags & flag) != 0;
  85.343      }
  85.344 @@ -512,9 +728,9 @@
  85.345          final FunctionNode fn = reparse();
  85.346          final Compiler compiler = getCompiler(fn, actualCallSiteType, runtimeScope);
  85.347          final FunctionNode compiledFn = compiler.compile(fn,
  85.348 -                isSerialized() ? CompilationPhases.COMPILE_ALL_SERIALIZED : CompilationPhases.COMPILE_ALL);
  85.349 +                fn.isCached() ? CompilationPhases.COMPILE_ALL_CACHED : CompilationPhases.COMPILE_ALL);
  85.350  
  85.351 -        if (persist && !compiledFn.getFlag(FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION)) {
  85.352 +        if (persist && !compiledFn.hasApplyToCallSpecialization()) {
  85.353              compiler.persistClassInfo(cacheKey, compiledFn);
  85.354          }
  85.355          return new FunctionInitializer(compiledFn, compiler.getInvalidatedProgramPoints());
    86.1 --- a/src/jdk/nashorn/internal/runtime/Scope.java	Thu Sep 24 10:00:42 2015 -0700
    86.2 +++ b/src/jdk/nashorn/internal/runtime/Scope.java	Thu Sep 24 10:09:56 2015 -0700
    86.3 @@ -27,6 +27,7 @@
    86.4  
    86.5  import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
    86.6  
    86.7 +import java.util.concurrent.atomic.LongAdder;
    86.8  import jdk.nashorn.internal.codegen.CompilerConstants;
    86.9  
   86.10  /**
   86.11 @@ -38,7 +39,7 @@
   86.12      private int splitState = -1;
   86.13  
   86.14      /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created that are scope */
   86.15 -    private static int count;
   86.16 +    private static final LongAdder count = Context.DEBUG ? new LongAdder() : null;
   86.17  
   86.18      /** Method handle that points to {@link Scope#getSplitState}. */
   86.19      public static final CompilerConstants.Call GET_SPLIT_STATE = virtualCallNoLookup(Scope.class, "getSplitState", int.class);
   86.20 @@ -52,9 +53,7 @@
   86.21       */
   86.22      public Scope(final PropertyMap map) {
   86.23          super(map);
   86.24 -        if (Context.DEBUG) {
   86.25 -            count++;
   86.26 -        }
   86.27 +        incrementCount();
   86.28      }
   86.29  
   86.30      /**
   86.31 @@ -65,9 +64,7 @@
   86.32       */
   86.33      public Scope(final ScriptObject proto, final PropertyMap map) {
   86.34          super(proto, map);
   86.35 -        if (Context.DEBUG) {
   86.36 -            count++;
   86.37 -        }
   86.38 +        incrementCount();
   86.39      }
   86.40  
   86.41      /**
   86.42 @@ -79,9 +76,7 @@
   86.43       */
   86.44      public Scope(final PropertyMap map, final long[] primitiveSpill, final Object[] objectSpill) {
   86.45          super(map, primitiveSpill, objectSpill);
   86.46 -        if (Context.DEBUG) {
   86.47 -            count++;
   86.48 -        }
   86.49 +        incrementCount();
   86.50      }
   86.51  
   86.52      @Override
   86.53 @@ -123,7 +118,13 @@
   86.54       *
   86.55       * @return number of scope ScriptObjects created
   86.56       */
   86.57 -    public static int getScopeCount() {
   86.58 -        return count;
   86.59 +    public static long getScopeCount() {
   86.60 +        return count != null ? count.sum() : 0;
   86.61 +    }
   86.62 +
   86.63 +    private static void incrementCount() {
   86.64 +        if (Context.DEBUG) {
   86.65 +            count.increment();
   86.66 +        }
   86.67      }
   86.68  }
    87.1 --- a/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Thu Sep 24 10:00:42 2015 -0700
    87.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Thu Sep 24 10:09:56 2015 -0700
    87.3 @@ -46,6 +46,11 @@
    87.4   * and output and error writers, top level Namespace etc.
    87.5   */
    87.6  public final class ScriptEnvironment {
    87.7 +    // Primarily intended to be used in test environments so that eager compilation tests work without an
    87.8 +    // error when tested with optimistic compilation.
    87.9 +    private static final boolean ALLOW_EAGER_COMPILATION_SILENT_OVERRIDE = Options.getBooleanProperty(
   87.10 +            "nashorn.options.allowEagerCompilationSilentOverride", false);
   87.11 +
   87.12      /** Output writer for this environment */
   87.13      private final PrintWriter out;
   87.14  
   87.15 @@ -237,8 +242,20 @@
   87.16          }
   87.17          _fx                   = options.getBoolean("fx");
   87.18          _global_per_engine    = options.getBoolean("global.per.engine");
   87.19 -        _lazy_compilation     = options.getBoolean("lazy.compilation");
   87.20          _optimistic_types     = options.getBoolean("optimistic.types");
   87.21 +        final boolean lazy_compilation = options.getBoolean("lazy.compilation");
   87.22 +        if (!lazy_compilation && _optimistic_types) {
   87.23 +            if (!ALLOW_EAGER_COMPILATION_SILENT_OVERRIDE) {
   87.24 +                throw new IllegalStateException(
   87.25 +                        ECMAErrors.getMessage(
   87.26 +                                "config.error.eagerCompilationConflictsWithOptimisticTypes",
   87.27 +                                options.getOptionTemplateByKey("lazy.compilation").getName(),
   87.28 +                                options.getOptionTemplateByKey("optimistic.types").getName()));
   87.29 +            }
   87.30 +            _lazy_compilation = true;
   87.31 +        } else {
   87.32 +            _lazy_compilation = lazy_compilation;
   87.33 +        }
   87.34          _loader_per_compile   = options.getBoolean("loader.per.compile");
   87.35          _no_java              = options.getBoolean("no.java");
   87.36          _no_syntax_extensions = options.getBoolean("no.syntax.extensions");
    88.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Thu Sep 24 10:00:42 2015 -0700
    88.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Thu Sep 24 10:09:56 2015 -0700
    88.3 @@ -22,7 +22,6 @@
    88.4   * or visit www.oracle.com if you need additional information or have any
    88.5   * questions.
    88.6   */
    88.7 -
    88.8  package jdk.nashorn.internal.runtime;
    88.9  
   88.10  import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
   88.11 @@ -40,6 +39,7 @@
   88.12  import java.util.Collections;
   88.13  import java.util.HashSet;
   88.14  import java.util.List;
   88.15 +import java.util.concurrent.atomic.LongAdder;
   88.16  import jdk.internal.dynalink.CallSiteDescriptor;
   88.17  import jdk.internal.dynalink.linker.GuardedInvocation;
   88.18  import jdk.internal.dynalink.linker.LinkRequest;
   88.19 @@ -55,38 +55,54 @@
   88.20  import jdk.nashorn.internal.runtime.logging.DebugLogger;
   88.21  
   88.22  /**
   88.23 - * Runtime representation of a JavaScript function.
   88.24 + * Runtime representation of a JavaScript function. This class has only private
   88.25 + * and protected constructors. There are no *public* constructors - but only
   88.26 + * factory methods that follow the naming pattern "createXYZ".
   88.27   */
   88.28 -public abstract class ScriptFunction extends ScriptObject {
   88.29 +public class ScriptFunction extends ScriptObject {
   88.30  
   88.31 -    /** Method handle for prototype getter for this ScriptFunction */
   88.32 +    /**
   88.33 +     * Method handle for prototype getter for this ScriptFunction
   88.34 +     */
   88.35      public static final MethodHandle G$PROTOTYPE = findOwnMH_S("G$prototype", Object.class, Object.class);
   88.36  
   88.37 -    /** Method handle for prototype setter for this ScriptFunction */
   88.38 +    /**
   88.39 +     * Method handle for prototype setter for this ScriptFunction
   88.40 +     */
   88.41      public static final MethodHandle S$PROTOTYPE = findOwnMH_S("S$prototype", void.class, Object.class, Object.class);
   88.42  
   88.43 -    /** Method handle for length getter for this ScriptFunction */
   88.44 +    /**
   88.45 +     * Method handle for length getter for this ScriptFunction
   88.46 +     */
   88.47      public static final MethodHandle G$LENGTH = findOwnMH_S("G$length", int.class, Object.class);
   88.48  
   88.49 -    /** Method handle for name getter for this ScriptFunction */
   88.50 +    /**
   88.51 +     * Method handle for name getter for this ScriptFunction
   88.52 +     */
   88.53      public static final MethodHandle G$NAME = findOwnMH_S("G$name", Object.class, Object.class);
   88.54  
   88.55 -    /** Method handle used for implementing sync() in mozilla_compat */
   88.56 +    /**
   88.57 +     * Method handle used for implementing sync() in mozilla_compat
   88.58 +     */
   88.59      public static final MethodHandle INVOKE_SYNC = findOwnMH_S("invokeSync", Object.class, ScriptFunction.class, Object.class, Object.class, Object[].class);
   88.60  
   88.61 -    /** Method handle for allocate function for this ScriptFunction */
   88.62 +    /**
   88.63 +     * Method handle for allocate function for this ScriptFunction
   88.64 +     */
   88.65      static final MethodHandle ALLOCATE = findOwnMH_V("allocate", Object.class);
   88.66  
   88.67      private static final MethodHandle WRAPFILTER = findOwnMH_S("wrapFilter", Object.class, Object.class);
   88.68  
   88.69      private static final MethodHandle SCRIPTFUNCTION_GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class);
   88.70  
   88.71 -    /** method handle to scope getter for this ScriptFunction */
   88.72 +    /**
   88.73 +     * method handle to scope getter for this ScriptFunction
   88.74 +     */
   88.75      public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
   88.76  
   88.77 -    private static final MethodHandle IS_FUNCTION_MH  = findOwnMH_S("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class);
   88.78 +    private static final MethodHandle IS_FUNCTION_MH = findOwnMH_S("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class);
   88.79  
   88.80 -    private static final MethodHandle IS_APPLY_FUNCTION  = findOwnMH_S("isApplyFunction", boolean.class, boolean.class, Object.class, Object.class);
   88.81 +    private static final MethodHandle IS_APPLY_FUNCTION = findOwnMH_S("isApplyFunction", boolean.class, boolean.class, Object.class, Object.class);
   88.82  
   88.83      private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH_S("isNonStrictFunction", boolean.class, Object.class, Object.class, ScriptFunctionData.class);
   88.84  
   88.85 @@ -94,55 +110,298 @@
   88.86  
   88.87      private static final MethodHandle WRAP_THIS = MH.findStatic(MethodHandles.lookup(), ScriptFunctionData.class, "wrapThis", MH.type(Object.class, Object.class));
   88.88  
   88.89 -    /** The parent scope. */
   88.90 +    // various property maps used for different kinds of functions
   88.91 +    // property map for anonymous function that serves as Function.prototype
   88.92 +    private static final PropertyMap anonmap$;
   88.93 +    // property map for strict mode functions
   88.94 +    private static final PropertyMap strictmodemap$;
   88.95 +    // property map for bound functions
   88.96 +    private static final PropertyMap boundfunctionmap$;
   88.97 +    // property map for non-strict, non-bound functions.
   88.98 +    private static final PropertyMap map$;
   88.99 +
  88.100 +    // Marker object for lazily initialized prototype object
  88.101 +    private static final Object LAZY_PROTOTYPE = new Object();
  88.102 +
  88.103 +    private static PropertyMap createStrictModeMap(final PropertyMap map) {
  88.104 +        final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
  88.105 +        PropertyMap newMap = map;
  88.106 +        // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
  88.107 +        newMap = newMap.addPropertyNoHistory(map.newUserAccessors("arguments", flags));
  88.108 +        newMap = newMap.addPropertyNoHistory(map.newUserAccessors("caller", flags));
  88.109 +        return newMap;
  88.110 +    }
  88.111 +
  88.112 +    private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
  88.113 +        // Bound function map is same as strict function map, but additionally lacks the "prototype" property, see
  88.114 +        // ECMAScript 5.1 section 15.3.4.5
  88.115 +        return strictModeMap.deleteProperty(strictModeMap.findProperty("prototype"));
  88.116 +    }
  88.117 +
  88.118 +    static {
  88.119 +        anonmap$ = PropertyMap.newMap();
  88.120 +        final ArrayList<Property> properties = new ArrayList<>(3);
  88.121 +        properties.add(AccessorProperty.create("prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE));
  88.122 +        properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null));
  88.123 +        properties.add(AccessorProperty.create("name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null));
  88.124 +        map$ = PropertyMap.newMap(properties);
  88.125 +        strictmodemap$ = createStrictModeMap(map$);
  88.126 +        boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
  88.127 +    }
  88.128 +
  88.129 +    private static boolean isStrict(final int flags) {
  88.130 +        return (flags & ScriptFunctionData.IS_STRICT) != 0;
  88.131 +    }
  88.132 +
  88.133 +    // Choose the map based on strict mode!
  88.134 +    private static PropertyMap getMap(final boolean strict) {
  88.135 +        return strict ? strictmodemap$ : map$;
  88.136 +    }
  88.137 +
  88.138 +    /**
  88.139 +     * The parent scope.
  88.140 +     */
  88.141      private final ScriptObject scope;
  88.142  
  88.143      private final ScriptFunctionData data;
  88.144  
  88.145 -    /** The property map used for newly allocated object when function is used as constructor. */
  88.146 +    /**
  88.147 +     * The property map used for newly allocated object when function is used as
  88.148 +     * constructor.
  88.149 +     */
  88.150      protected PropertyMap allocatorMap;
  88.151  
  88.152      /**
  88.153 +     * Reference to constructor prototype.
  88.154 +     */
  88.155 +    protected Object prototype;
  88.156 +
  88.157 +    /**
  88.158       * Constructor
  88.159       *
  88.160 -     * @param name          function name
  88.161 -     * @param methodHandle  method handle to function (if specializations are present, assumed to be most generic)
  88.162 -     * @param map           property map
  88.163 -     * @param scope         scope
  88.164 -     * @param specs         specialized version of this function - other method handles
  88.165 -     * @param flags         {@link ScriptFunctionData} flags
  88.166 +     * @param data static function data
  88.167 +     * @param map property map
  88.168 +     * @param scope scope
  88.169       */
  88.170 -    protected ScriptFunction(
  88.171 +    private ScriptFunction(
  88.172 +            final ScriptFunctionData data,
  88.173 +            final PropertyMap map,
  88.174 +            final ScriptObject scope,
  88.175 +            final Global global) {
  88.176 +
  88.177 +        super(map);
  88.178 +
  88.179 +        if (Context.DEBUG) {
  88.180 +            constructorCount.increment();
  88.181 +        }
  88.182 +
  88.183 +        this.data = data;
  88.184 +        this.scope = scope;
  88.185 +        this.setInitialProto(global.getFunctionPrototype());
  88.186 +        this.prototype = LAZY_PROTOTYPE;
  88.187 +
  88.188 +        // We have to fill user accessor functions late as these are stored
  88.189 +        // in this object rather than in the PropertyMap of this object.
  88.190 +        assert objectSpill == null;
  88.191 +        if (isStrict() || isBoundFunction()) {
  88.192 +            final ScriptFunction typeErrorThrower = global.getTypeErrorThrower();
  88.193 +            initUserAccessors("arguments", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
  88.194 +            initUserAccessors("caller", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
  88.195 +        }
  88.196 +    }
  88.197 +
  88.198 +    /**
  88.199 +     * Constructor
  88.200 +     *
  88.201 +     * @param name function name
  88.202 +     * @param methodHandle method handle to function (if specializations are
  88.203 +     * present, assumed to be most generic)
  88.204 +     * @param map property map
  88.205 +     * @param scope scope
  88.206 +     * @param specs specialized version of this function - other method handles
  88.207 +     * @param flags {@link ScriptFunctionData} flags
  88.208 +     */
  88.209 +    private ScriptFunction(
  88.210              final String name,
  88.211              final MethodHandle methodHandle,
  88.212              final PropertyMap map,
  88.213              final ScriptObject scope,
  88.214              final Specialization[] specs,
  88.215 -            final int flags) {
  88.216 -
  88.217 -        this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope);
  88.218 +            final int flags,
  88.219 +            final Global global) {
  88.220 +        this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope, global);
  88.221      }
  88.222  
  88.223      /**
  88.224       * Constructor
  88.225       *
  88.226 -     * @param data          static function data
  88.227 -     * @param map           property map
  88.228 -     * @param scope         scope
  88.229 +     * @param name name of function
  88.230 +     * @param methodHandle handle for invocation
  88.231 +     * @param scope scope object
  88.232 +     * @param specs specialized versions of this method, if available, null
  88.233 +     * otherwise
  88.234 +     * @param flags {@link ScriptFunctionData} flags
  88.235       */
  88.236 -    protected ScriptFunction(
  88.237 -            final ScriptFunctionData data,
  88.238 -            final PropertyMap map,
  88.239 -            final ScriptObject scope) {
  88.240 +    private ScriptFunction(
  88.241 +            final String name,
  88.242 +            final MethodHandle methodHandle,
  88.243 +            final ScriptObject scope,
  88.244 +            final Specialization[] specs,
  88.245 +            final int flags) {
  88.246 +        this(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags, Global.instance());
  88.247 +    }
  88.248  
  88.249 -        super(map);
  88.250 +    /**
  88.251 +     * Constructor called by Nasgen generated code, zero added members, use the
  88.252 +     * default map. Creates builtin functions only.
  88.253 +     *
  88.254 +     * @param name name of function
  88.255 +     * @param invokeHandle handle for invocation
  88.256 +     * @param specs specialized versions of this method, if available, null
  88.257 +     * otherwise
  88.258 +     */
  88.259 +    protected ScriptFunction(final String name, final MethodHandle invokeHandle, final Specialization[] specs) {
  88.260 +        this(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR, Global.instance());
  88.261 +    }
  88.262  
  88.263 -        if (Context.DEBUG) {
  88.264 -            constructorCount++;
  88.265 +    /**
  88.266 +     * Constructor called by Nasgen generated code, non zero member count, use
  88.267 +     * the map passed as argument. Creates builtin functions only.
  88.268 +     *
  88.269 +     * @param name name of function
  88.270 +     * @param invokeHandle handle for invocation
  88.271 +     * @param map initial property map
  88.272 +     * @param specs specialized versions of this method, if available, null
  88.273 +     * otherwise
  88.274 +     */
  88.275 +    protected ScriptFunction(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs) {
  88.276 +        this(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR, Global.instance());
  88.277 +    }
  88.278 +
  88.279 +    // Factory methods to create various functions
  88.280 +    /**
  88.281 +     * Factory method called by compiler generated code for functions that need
  88.282 +     * parent scope.
  88.283 +     *
  88.284 +     * @param constants the generated class' constant array
  88.285 +     * @param index the index of the {@code RecompilableScriptFunctionData}
  88.286 +     * object in the constants array.
  88.287 +     * @param scope the parent scope object
  88.288 +     * @return a newly created function object
  88.289 +     */
  88.290 +    public static ScriptFunction create(final Object[] constants, final int index, final ScriptObject scope) {
  88.291 +        final RecompilableScriptFunctionData data = (RecompilableScriptFunctionData) constants[index];
  88.292 +        return new ScriptFunction(data, getMap(data.isStrict()), scope, Global.instance());
  88.293 +    }
  88.294 +
  88.295 +    /**
  88.296 +     * Factory method called by compiler generated code for functions that don't
  88.297 +     * need parent scope.
  88.298 +     *
  88.299 +     * @param constants the generated class' constant array
  88.300 +     * @param index the index of the {@code RecompilableScriptFunctionData}
  88.301 +     * object in the constants array.
  88.302 +     * @return a newly created function object
  88.303 +     */
  88.304 +    public static ScriptFunction create(final Object[] constants, final int index) {
  88.305 +        return create(constants, index, null);
  88.306 +    }
  88.307 +
  88.308 +    /**
  88.309 +     * Create anonymous function that serves as Function.prototype
  88.310 +     *
  88.311 +     * @return anonymous function object
  88.312 +     */
  88.313 +    public static ScriptFunction createAnonymous() {
  88.314 +        return new ScriptFunction("", GlobalFunctions.ANONYMOUS, anonmap$, null);
  88.315 +    }
  88.316 +
  88.317 +    // builtin function create helper factory
  88.318 +    private static ScriptFunction createBuiltin(final String name, final MethodHandle methodHandle, final Specialization[] specs, final int flags) {
  88.319 +        final ScriptFunction func = new ScriptFunction(name, methodHandle, null, specs, flags);
  88.320 +        func.setPrototype(UNDEFINED);
  88.321 +        // Non-constructor built-in functions do not have "prototype" property
  88.322 +        func.deleteOwnProperty(func.getMap().findProperty("prototype"));
  88.323 +
  88.324 +        return func;
  88.325 +    }
  88.326 +
  88.327 +    /**
  88.328 +     * Factory method for non-constructor built-in functions
  88.329 +     *
  88.330 +     * @param name function name
  88.331 +     * @param methodHandle handle for invocation
  88.332 +     * @param specs specialized versions of function if available, null
  88.333 +     * otherwise
  88.334 +     * @return new ScriptFunction
  88.335 +     */
  88.336 +    public static ScriptFunction createBuiltin(final String name, final MethodHandle methodHandle, final Specialization[] specs) {
  88.337 +        return ScriptFunction.createBuiltin(name, methodHandle, specs, ScriptFunctionData.IS_BUILTIN);
  88.338 +    }
  88.339 +
  88.340 +    /**
  88.341 +     * Factory method for non-constructor built-in functions
  88.342 +     *
  88.343 +     * @param name function name
  88.344 +     * @param methodHandle handle for invocation
  88.345 +     * @return new ScriptFunction
  88.346 +     */
  88.347 +    public static ScriptFunction createBuiltin(final String name, final MethodHandle methodHandle) {
  88.348 +        return ScriptFunction.createBuiltin(name, methodHandle, null);
  88.349 +    }
  88.350 +
  88.351 +    /**
  88.352 +     * Factory method for non-constructor built-in, strict functions
  88.353 +     *
  88.354 +     * @param name function name
  88.355 +     * @param methodHandle handle for invocation
  88.356 +     * @return new ScriptFunction
  88.357 +     */
  88.358 +    public static ScriptFunction createStrictBuiltin(final String name, final MethodHandle methodHandle) {
  88.359 +        return ScriptFunction.createBuiltin(name, methodHandle, null, ScriptFunctionData.IS_BUILTIN | ScriptFunctionData.IS_STRICT);
  88.360 +    }
  88.361 +
  88.362 +    // Subclass to represent bound functions
  88.363 +    private static class Bound extends ScriptFunction {
  88.364 +        private final ScriptFunction target;
  88.365 +
  88.366 +        Bound(final ScriptFunctionData boundData, final ScriptFunction target) {
  88.367 +            super(boundData, boundfunctionmap$, null, Global.instance());
  88.368 +            setPrototype(ScriptRuntime.UNDEFINED);
  88.369 +            this.target = target;
  88.370          }
  88.371  
  88.372 -        this.data  = data;
  88.373 -        this.scope = scope;
  88.374 +        @Override
  88.375 +        protected ScriptFunction getTargetFunction() {
  88.376 +            return target;
  88.377 +        }
  88.378 +    }
  88.379 +
  88.380 +    /**
  88.381 +     * Creates a version of this function bound to a specific "self" and other
  88.382 +     * arguments, as per {@code Function.prototype.bind} functionality in
  88.383 +     * ECMAScript 5.1 section 15.3.4.5.
  88.384 +     *
  88.385 +     * @param self the self to bind to this function. Can be null (in which
  88.386 +     * case, null is bound as this).
  88.387 +     * @param args additional arguments to bind to this function. Can be null or
  88.388 +     * empty to not bind additional arguments.
  88.389 +     * @return a function with the specified self and parameters bound.
  88.390 +     */
  88.391 +    public final ScriptFunction createBound(final Object self, final Object[] args) {
  88.392 +        return new Bound(data.makeBoundFunctionData(this, self, args), getTargetFunction());
  88.393 +    }
  88.394 +
  88.395 +    /**
  88.396 +     * Create a function that invokes this function synchronized on {@code sync}
  88.397 +     * or the self object of the invocation.
  88.398 +     *
  88.399 +     * @param sync the Object to synchronize on, or undefined
  88.400 +     * @return synchronized function
  88.401 +     */
  88.402 +    public final ScriptFunction createSynchronized(final Object sync) {
  88.403 +        final MethodHandle mh = MH.insertArguments(ScriptFunction.INVOKE_SYNC, 0, this, sync);
  88.404 +        return createBuiltin(getName(), mh);
  88.405      }
  88.406  
  88.407      @Override
  88.408 @@ -151,8 +410,8 @@
  88.409      }
  88.410  
  88.411      /**
  88.412 -     * ECMA 15.3.5.3 [[HasInstance]] (V)
  88.413 -     * Step 3 if "prototype" value is not an Object, throw TypeError
  88.414 +     * ECMA 15.3.5.3 [[HasInstance]] (V) Step 3 if "prototype" value is not an
  88.415 +     * Object, throw TypeError
  88.416       */
  88.417      @Override
  88.418      public boolean isInstance(final ScriptObject instance) {
  88.419 @@ -171,22 +430,25 @@
  88.420      }
  88.421  
  88.422      /**
  88.423 -     * Returns the target function for this function. If the function was not created using
  88.424 -     * {@link #makeBoundFunction(Object, Object[])}, its target function is itself. If it is bound, its target function
  88.425 -     * is the target function of the function it was made from (therefore, the target function is always the final,
  88.426 -     * unbound recipient of the calls).
  88.427 +     * Returns the target function for this function. If the function was not
  88.428 +     * created using {@link #createBound(Object, Object[])}, its target
  88.429 +     * function is itself. If it is bound, its target function is the target
  88.430 +     * function of the function it was made from (therefore, the target function
  88.431 +     * is always the final, unbound recipient of the calls).
  88.432 +     *
  88.433       * @return the target function for this function.
  88.434       */
  88.435      protected ScriptFunction getTargetFunction() {
  88.436          return this;
  88.437      }
  88.438  
  88.439 -    boolean isBoundFunction() {
  88.440 +    final boolean isBoundFunction() {
  88.441          return getTargetFunction() != this;
  88.442      }
  88.443  
  88.444      /**
  88.445       * Set the arity of this ScriptFunction
  88.446 +     *
  88.447       * @param arity arity
  88.448       */
  88.449      public final void setArity(final int arity) {
  88.450 @@ -195,59 +457,66 @@
  88.451  
  88.452      /**
  88.453       * Is this a ECMAScript 'use strict' function?
  88.454 +     *
  88.455       * @return true if function is in strict mode
  88.456       */
  88.457 -    public boolean isStrict() {
  88.458 +    public final boolean isStrict() {
  88.459          return data.isStrict();
  88.460      }
  88.461  
  88.462      /**
  88.463 -     * Returns true if this is a non-strict, non-built-in function that requires non-primitive this argument
  88.464 -     * according to ECMA 10.4.3.
  88.465 +     * Returns true if this is a non-strict, non-built-in function that requires
  88.466 +     * non-primitive this argument according to ECMA 10.4.3.
  88.467 +     *
  88.468       * @return true if this argument must be an object
  88.469       */
  88.470 -    public boolean needsWrappedThis() {
  88.471 +    public final boolean needsWrappedThis() {
  88.472          return data.needsWrappedThis();
  88.473      }
  88.474  
  88.475      private static boolean needsWrappedThis(final Object fn) {
  88.476 -        return fn instanceof ScriptFunction ? ((ScriptFunction)fn).needsWrappedThis() : false;
  88.477 +        return fn instanceof ScriptFunction ? ((ScriptFunction) fn).needsWrappedThis() : false;
  88.478      }
  88.479  
  88.480      /**
  88.481       * Execute this script function.
  88.482 -     * @param self  Target object.
  88.483 -     * @param arguments  Call arguments.
  88.484 +     *
  88.485 +     * @param self Target object.
  88.486 +     * @param arguments Call arguments.
  88.487       * @return ScriptFunction result.
  88.488 -     * @throws Throwable if there is an exception/error with the invocation or thrown from it
  88.489 +     * @throws Throwable if there is an exception/error with the invocation or
  88.490 +     * thrown from it
  88.491       */
  88.492 -    Object invoke(final Object self, final Object... arguments) throws Throwable {
  88.493 +    final Object invoke(final Object self, final Object... arguments) throws Throwable {
  88.494          if (Context.DEBUG) {
  88.495 -            invokes++;
  88.496 +            invokes.increment();
  88.497          }
  88.498          return data.invoke(this, self, arguments);
  88.499      }
  88.500  
  88.501      /**
  88.502       * Execute this script function as a constructor.
  88.503 -     * @param arguments  Call arguments.
  88.504 +     *
  88.505 +     * @param arguments Call arguments.
  88.506       * @return Newly constructed result.
  88.507 -     * @throws Throwable if there is an exception/error with the invocation or thrown from it
  88.508 +     * @throws Throwable if there is an exception/error with the invocation or
  88.509 +     * thrown from it
  88.510       */
  88.511 -    Object construct(final Object... arguments) throws Throwable {
  88.512 +    final Object construct(final Object... arguments) throws Throwable {
  88.513          return data.construct(this, arguments);
  88.514      }
  88.515  
  88.516      /**
  88.517 -     * Allocate function. Called from generated {@link ScriptObject} code
  88.518 -     * for allocation as a factory method
  88.519 +     * Allocate function. Called from generated {@link ScriptObject} code for
  88.520 +     * allocation as a factory method
  88.521       *
  88.522 -     * @return a new instance of the {@link ScriptObject} whose allocator this is
  88.523 +     * @return a new instance of the {@link ScriptObject} whose allocator this
  88.524 +     * is
  88.525       */
  88.526      @SuppressWarnings("unused")
  88.527      private Object allocate() {
  88.528          if (Context.DEBUG) {
  88.529 -            allocations++;
  88.530 +            allocations.increment();
  88.531          }
  88.532  
  88.533          assert !isBoundFunction(); // allocate never invoked on bound functions
  88.534 @@ -257,7 +526,7 @@
  88.535          if (object != null) {
  88.536              final Object prototype = getPrototype();
  88.537              if (prototype instanceof ScriptObject) {
  88.538 -                object.setInitialProto((ScriptObject)prototype);
  88.539 +                object.setInitialProto((ScriptObject) prototype);
  88.540              }
  88.541  
  88.542              if (object.getProto() == null) {
  88.543 @@ -277,43 +546,28 @@
  88.544  
  88.545      /**
  88.546       * Return Object.prototype - used by "allocate"
  88.547 +     *
  88.548       * @return Object.prototype
  88.549       */
  88.550 -    protected abstract ScriptObject getObjectPrototype();
  88.551 -
  88.552 -    /**
  88.553 -     * Creates a version of this function bound to a specific "self" and other arguments, as per
  88.554 -     * {@code Function.prototype.bind} functionality in ECMAScript 5.1 section 15.3.4.5.
  88.555 -     * @param self the self to bind to this function. Can be null (in which case, null is bound as this).
  88.556 -     * @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments.
  88.557 -     * @return a function with the specified self and parameters bound.
  88.558 -     */
  88.559 -    protected ScriptFunction makeBoundFunction(final Object self, final Object[] args) {
  88.560 -        return makeBoundFunction(data.makeBoundFunctionData(this, self, args));
  88.561 +    protected final ScriptObject getObjectPrototype() {
  88.562 +        return Global.objectPrototype();
  88.563      }
  88.564  
  88.565 -    /**
  88.566 -     * Create a version of this function as in {@link ScriptFunction#makeBoundFunction(Object, Object[])},
  88.567 -     * but using a {@link ScriptFunctionData} for the bound data.
  88.568 -     *
  88.569 -     * @param boundData ScriptFuntionData for the bound function
  88.570 -     * @return a function with the bindings performed according to the given data
  88.571 -     */
  88.572 -    protected abstract ScriptFunction makeBoundFunction(ScriptFunctionData boundData);
  88.573 -
  88.574      @Override
  88.575      public final String safeToString() {
  88.576          return toSource();
  88.577      }
  88.578  
  88.579      @Override
  88.580 -    public String toString() {
  88.581 +    public final String toString() {
  88.582          return data.toString();
  88.583      }
  88.584  
  88.585      /**
  88.586 -     * Get this function as a String containing its source code. If no source code
  88.587 -     * exists in this ScriptFunction, its contents will be displayed as {@code [native code]}
  88.588 +     * Get this function as a String containing its source code. If no source
  88.589 +     * code exists in this ScriptFunction, its contents will be displayed as
  88.590 +     * {@code [native code]}
  88.591 +     *
  88.592       * @return string representation of this function's source
  88.593       */
  88.594      public final String toSource() {
  88.595 @@ -322,27 +576,32 @@
  88.596  
  88.597      /**
  88.598       * Get the prototype object for this function
  88.599 +     *
  88.600       * @return prototype
  88.601       */
  88.602 -    public abstract Object getPrototype();
  88.603 +    public final Object getPrototype() {
  88.604 +        if (prototype == LAZY_PROTOTYPE) {
  88.605 +            prototype = new PrototypeObject(this);
  88.606 +        }
  88.607 +        return prototype;
  88.608 +    }
  88.609  
  88.610      /**
  88.611       * Set the prototype object for this function
  88.612 -     * @param prototype new prototype object
  88.613 +     *
  88.614 +     * @param newPrototype new prototype object
  88.615       */
  88.616 -    public abstract void setPrototype(Object prototype);
  88.617 +    public final void setPrototype(final Object newPrototype) {
  88.618 +        if (newPrototype instanceof ScriptObject && newPrototype != this.prototype && allocatorMap != null) {
  88.619 +            // Replace our current allocator map with one that is associated with the new prototype.
  88.620 +            allocatorMap = allocatorMap.changeProto((ScriptObject) newPrototype);
  88.621 +        }
  88.622 +        this.prototype = newPrototype;
  88.623 +    }
  88.624  
  88.625      /**
  88.626 -     * Create a function that invokes this function synchronized on {@code sync} or the self object
  88.627 -     * of the invocation.
  88.628 -     * @param sync the Object to synchronize on, or undefined
  88.629 -     * @return synchronized function
  88.630 -     */
  88.631 -   public abstract ScriptFunction makeSynchronizedFunction(Object sync);
  88.632 -
  88.633 -    /**
  88.634 -     * Return the invoke handle bound to a given ScriptObject self reference.
  88.635 -     * If callee parameter is required result is rebound to this.
  88.636 +     * Return the invoke handle bound to a given ScriptObject self reference. If
  88.637 +     * callee parameter is required result is rebound to this.
  88.638       *
  88.639       * @param self self reference
  88.640       * @return bound invoke handle
  88.641 @@ -352,9 +611,12 @@
  88.642      }
  88.643  
  88.644      /**
  88.645 -     * Bind the method handle to this {@code ScriptFunction} instance if it needs a callee parameter. If this function's
  88.646 -     * method handles don't have a callee parameter, the handle is returned unchanged.
  88.647 -     * @param methodHandle the method handle to potentially bind to this function instance.
  88.648 +     * Bind the method handle to this {@code ScriptFunction} instance if it
  88.649 +     * needs a callee parameter. If this function's method handles don't have a
  88.650 +     * callee parameter, the handle is returned unchanged.
  88.651 +     *
  88.652 +     * @param methodHandle the method handle to potentially bind to this
  88.653 +     * function instance.
  88.654       * @return the potentially bound method handle
  88.655       */
  88.656      private MethodHandle bindToCalleeIfNeeded(final MethodHandle methodHandle) {
  88.657 @@ -364,15 +626,16 @@
  88.658  
  88.659      /**
  88.660       * Get the name for this function
  88.661 +     *
  88.662       * @return the name
  88.663       */
  88.664      public final String getName() {
  88.665          return data.getName();
  88.666      }
  88.667  
  88.668 -
  88.669      /**
  88.670       * Get the scope for this function
  88.671 +     *
  88.672       * @return the scope
  88.673       */
  88.674      public final ScriptObject getScope() {
  88.675 @@ -383,36 +646,37 @@
  88.676       * Prototype getter for this ScriptFunction - follows the naming convention
  88.677       * used by Nasgen and the code generator
  88.678       *
  88.679 -     * @param self  self reference
  88.680 +     * @param self self reference
  88.681       * @return self's prototype
  88.682       */
  88.683      public static Object G$prototype(final Object self) {
  88.684 -        return self instanceof ScriptFunction ?
  88.685 -            ((ScriptFunction)self).getPrototype() :
  88.686 -            UNDEFINED;
  88.687 +        return self instanceof ScriptFunction
  88.688 +                ? ((ScriptFunction) self).getPrototype()
  88.689 +                : UNDEFINED;
  88.690      }
  88.691  
  88.692      /**
  88.693       * Prototype setter for this ScriptFunction - follows the naming convention
  88.694       * used by Nasgen and the code generator
  88.695       *
  88.696 -     * @param self  self reference
  88.697 +     * @param self self reference
  88.698       * @param prototype prototype to set
  88.699       */
  88.700      public static void S$prototype(final Object self, final Object prototype) {
  88.701          if (self instanceof ScriptFunction) {
  88.702 -            ((ScriptFunction)self).setPrototype(prototype);
  88.703 +            ((ScriptFunction) self).setPrototype(prototype);
  88.704          }
  88.705      }
  88.706  
  88.707      /**
  88.708       * Length getter - ECMA 15.3.3.2: Function.length
  88.709 +     *
  88.710       * @param self self reference
  88.711       * @return length
  88.712       */
  88.713      public static int G$length(final Object self) {
  88.714          if (self instanceof ScriptFunction) {
  88.715 -            return ((ScriptFunction)self).data.getArity();
  88.716 +            return ((ScriptFunction) self).data.getArity();
  88.717          }
  88.718  
  88.719          return 0;
  88.720 @@ -420,12 +684,13 @@
  88.721  
  88.722      /**
  88.723       * Name getter - ECMA Function.name
  88.724 +     *
  88.725       * @param self self refence
  88.726       * @return the name, or undefined if none
  88.727       */
  88.728      public static Object G$name(final Object self) {
  88.729          if (self instanceof ScriptFunction) {
  88.730 -            return ((ScriptFunction)self).getName();
  88.731 +            return ((ScriptFunction) self).getName();
  88.732          }
  88.733  
  88.734          return UNDEFINED;
  88.735 @@ -433,6 +698,7 @@
  88.736  
  88.737      /**
  88.738       * Get the prototype for this ScriptFunction
  88.739 +     *
  88.740       * @param constructor constructor
  88.741       * @return prototype, or null if given constructor is not a ScriptFunction
  88.742       */
  88.743 @@ -440,7 +706,7 @@
  88.744          if (constructor != null) {
  88.745              final Object proto = constructor.getPrototype();
  88.746              if (proto instanceof ScriptObject) {
  88.747 -                return (ScriptObject)proto;
  88.748 +                return (ScriptObject) proto;
  88.749              }
  88.750          }
  88.751  
  88.752 @@ -448,29 +714,37 @@
  88.753      }
  88.754  
  88.755      // These counters are updated only in debug mode.
  88.756 -    private static int constructorCount;
  88.757 -    private static int invokes;
  88.758 -    private static int allocations;
  88.759 +    private static LongAdder constructorCount;
  88.760 +    private static LongAdder invokes;
  88.761 +    private static LongAdder allocations;
  88.762 +
  88.763 +    static {
  88.764 +        if (Context.DEBUG) {
  88.765 +            constructorCount = new LongAdder();
  88.766 +            invokes = new LongAdder();
  88.767 +            allocations = new LongAdder();
  88.768 +        }
  88.769 +    }
  88.770  
  88.771      /**
  88.772       * @return the constructorCount
  88.773       */
  88.774 -    public static int getConstructorCount() {
  88.775 -        return constructorCount;
  88.776 +    public static long getConstructorCount() {
  88.777 +        return constructorCount.longValue();
  88.778      }
  88.779  
  88.780      /**
  88.781       * @return the invokes
  88.782       */
  88.783 -    public static int getInvokes() {
  88.784 -        return invokes;
  88.785 +    public static long getInvokes() {
  88.786 +        return invokes.longValue();
  88.787      }
  88.788  
  88.789      /**
  88.790       * @return the allocations
  88.791       */
  88.792 -    public static int getAllocations() {
  88.793 -        return allocations;
  88.794 +    public static long getAllocations() {
  88.795 +        return allocations.longValue();
  88.796      }
  88.797  
  88.798      @Override
  88.799 @@ -490,7 +764,6 @@
  88.800          return Context.getGlobal().wrapAsObject(obj);
  88.801      }
  88.802  
  88.803 -
  88.804      @SuppressWarnings("unused")
  88.805      private static Object globalFilter(final Object object) {
  88.806          // replace whatever we get with the current global object
  88.807 @@ -498,14 +771,16 @@
  88.808      }
  88.809  
  88.810      /**
  88.811 -     * Some receivers are primitive, in that case, according to the Spec we create a new
  88.812 -     * native object per callsite with the wrap filter. We can only apply optimistic builtins
  88.813 -     * if there is no per instance state saved for these wrapped objects (e.g. currently NativeStrings),
  88.814 -     * otherwise we can't create optimistic versions
  88.815 +     * Some receivers are primitive, in that case, according to the Spec we
  88.816 +     * create a new native object per callsite with the wrap filter. We can only
  88.817 +     * apply optimistic builtins if there is no per instance state saved for
  88.818 +     * these wrapped objects (e.g. currently NativeStrings), otherwise we can't
  88.819 +     * create optimistic versions
  88.820       *
  88.821 -     * @param self            receiver
  88.822 -     * @param linkLogicClass  linkLogicClass, or null if no link logic exists
  88.823 -     * @return link logic instance, or null if one could not be constructed for this receiver
  88.824 +     * @param self receiver
  88.825 +     * @param linkLogicClass linkLogicClass, or null if no link logic exists
  88.826 +     * @return link logic instance, or null if one could not be constructed for
  88.827 +     * this receiver
  88.828       */
  88.829      private static LinkLogic getLinkLogic(final Object self, final Class<? extends LinkLogic> linkLogicClass) {
  88.830          if (linkLogicClass == null) {
  88.831 @@ -518,25 +793,25 @@
  88.832  
  88.833          final Object wrappedSelf = wrapFilter(self);
  88.834          if (wrappedSelf instanceof OptimisticBuiltins) {
  88.835 -            if (wrappedSelf != self && ((OptimisticBuiltins)wrappedSelf).hasPerInstanceAssumptions()) {
  88.836 +            if (wrappedSelf != self && ((OptimisticBuiltins) wrappedSelf).hasPerInstanceAssumptions()) {
  88.837                  return null; //pessimistic - we created a wrapped object different from the primitive, but the assumptions have instance state
  88.838              }
  88.839 -            return ((OptimisticBuiltins)wrappedSelf).getLinkLogic(linkLogicClass);
  88.840 +            return ((OptimisticBuiltins) wrappedSelf).getLinkLogic(linkLogicClass);
  88.841          }
  88.842          return null;
  88.843      }
  88.844  
  88.845      /**
  88.846 -     * dyn:call call site signature: (callee, thiz, [args...])
  88.847 -     * generated method signature:   (callee, thiz, [args...])
  88.848 +     * dyn:call call site signature: (callee, thiz, [args...]) generated method
  88.849 +     * signature: (callee, thiz, [args...])
  88.850       *
  88.851       * cases:
  88.852       * (a) method has callee parameter
  88.853 -     *   (1) for local/scope calls, we just bind thiz and drop the second argument.
  88.854 -     *   (2) for normal this-calls, we have to swap thiz and callee to get matching signatures.
  88.855 +     *     (1) for local/scope calls, we just bind thiz and drop the second argument.
  88.856 +     *     (2) for normal this-calls, we have to swap thiz and callee to get matching signatures.
  88.857       * (b) method doesn't have callee parameter (builtin functions)
  88.858 -     *   (3) for local/scope calls, bind thiz and drop both callee and thiz.
  88.859 -     *   (4) for normal this-calls, drop callee.
  88.860 +     *     (3) for local/scope calls, bind thiz and drop both callee and thiz.
  88.861 +     *     (4) for normal this-calls, drop callee.
  88.862       *
  88.863       * @return guarded invocation for call
  88.864       */
  88.865 @@ -544,11 +819,11 @@
  88.866      protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
  88.867          final MethodType type = desc.getMethodType();
  88.868  
  88.869 -        final String  name       = getName();
  88.870 +        final String name = getName();
  88.871          final boolean isUnstable = request.isCallSiteUnstable();
  88.872 -        final boolean scopeCall  = NashornCallSiteDescriptor.isScope(desc);
  88.873 -        final boolean isCall     = !scopeCall && data.isBuiltin() && "call".equals(name);
  88.874 -        final boolean isApply    = !scopeCall && data.isBuiltin() && "apply".equals(name);
  88.875 +        final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
  88.876 +        final boolean isCall = !scopeCall && data.isBuiltin() && "call".equals(name);
  88.877 +        final boolean isApply = !scopeCall && data.isBuiltin() && "apply".equals(name);
  88.878  
  88.879          final boolean isApplyOrCall = isCall | isApply;
  88.880  
  88.881 @@ -569,7 +844,7 @@
  88.882              return new GuardedInvocation(
  88.883                      handle,
  88.884                      null,
  88.885 -                    (SwitchPoint)null,
  88.886 +                    (SwitchPoint) null,
  88.887                      ClassCastException.class);
  88.888          }
  88.889  
  88.890 @@ -672,14 +947,14 @@
  88.891                                  this,
  88.892                                  cf.getFlags()) :
  88.893                          guard,
  88.894 -                        spsArray,
  88.895 +                spsArray,
  88.896                  exceptionGuard);
  88.897      }
  88.898  
  88.899      private GuardedInvocation createApplyOrCallCall(final boolean isApply, final CallSiteDescriptor desc, final LinkRequest request, final Object[] args) {
  88.900          final MethodType descType = desc.getMethodType();
  88.901          final int paramCount = descType.parameterCount();
  88.902 -        if(descType.parameterType(paramCount - 1).isArray()) {
  88.903 +        if (descType.parameterType(paramCount - 1).isArray()) {
  88.904              // This is vararg invocation of apply or call. This can normally only happen when we do a recursive
  88.905              // invocation of createApplyOrCallCall (because we're doing apply-of-apply). In this case, create delegate
  88.906              // linkage by unpacking the vararg invocation and use pairArguments to introduce the necessary spreader.
  88.907 @@ -786,7 +1061,7 @@
  88.908                  inv = MH.filterArguments(inv, 2, NativeFunction.TO_APPLY_ARGS);
  88.909              } else {
  88.910                  // If the original call site doesn't pass argArray, pass in an empty array
  88.911 -                inv = MH.insertArguments(inv, 2, (Object)ScriptRuntime.EMPTY_ARRAY);
  88.912 +                inv = MH.insertArguments(inv, 2, (Object) ScriptRuntime.EMPTY_ARRAY);
  88.913              }
  88.914          }
  88.915  
  88.916 @@ -851,7 +1126,7 @@
  88.917              final LinkRequest request, final Object[] args) {
  88.918          final MethodType descType = desc.getMethodType();
  88.919          final int paramCount = descType.parameterCount();
  88.920 -        final Object[] varArgs = (Object[])args[paramCount - 1];
  88.921 +        final Object[] varArgs = (Object[]) args[paramCount - 1];
  88.922          // -1 'cause we're not passing the vararg array itself
  88.923          final int copiedArgCount = args.length - 1;
  88.924          final int varArgCount = varArgs.length;
  88.925 @@ -893,7 +1168,7 @@
  88.926          // If the last parameter type of the guard is an array, then it is already itself a guard for a vararg apply
  88.927          // invocation. We must filter the last argument with toApplyArgs otherwise deeper levels of nesting will fail
  88.928          // with ClassCastException of NativeArray to Object[].
  88.929 -        if(guardType.parameterType(guardParamCount - 1).isArray()) {
  88.930 +        if (guardType.parameterType(guardParamCount - 1).isArray()) {
  88.931              arrayConvertingGuard = MH.filterArguments(guard, guardParamCount - 1, NativeFunction.TO_APPLY_ARGS);
  88.932          } else {
  88.933              arrayConvertingGuard = guard;
  88.934 @@ -903,19 +1178,20 @@
  88.935      }
  88.936  
  88.937      private static MethodHandle bindImplicitThis(final Object fn, final MethodHandle mh) {
  88.938 -         final MethodHandle bound;
  88.939 -         if(fn instanceof ScriptFunction && ((ScriptFunction)fn).needsWrappedThis()) {
  88.940 -             bound = MH.filterArguments(mh, 1, SCRIPTFUNCTION_GLOBALFILTER);
  88.941 -         } else {
  88.942 -             bound = mh;
  88.943 -         }
  88.944 -         return MH.insertArguments(bound, 1, ScriptRuntime.UNDEFINED);
  88.945 -     }
  88.946 +        final MethodHandle bound;
  88.947 +        if (fn instanceof ScriptFunction && ((ScriptFunction) fn).needsWrappedThis()) {
  88.948 +            bound = MH.filterArguments(mh, 1, SCRIPTFUNCTION_GLOBALFILTER);
  88.949 +        } else {
  88.950 +            bound = mh;
  88.951 +        }
  88.952 +        return MH.insertArguments(bound, 1, ScriptRuntime.UNDEFINED);
  88.953 +    }
  88.954  
  88.955      /**
  88.956       * Used for noSuchMethod/noSuchProperty and JSAdapter hooks.
  88.957       *
  88.958 -     * These don't want a callee parameter, so bind that. Name binding is optional.
  88.959 +     * These don't want a callee parameter, so bind that. Name binding is
  88.960 +     * optional.
  88.961       */
  88.962      MethodHandle getCallMethodHandle(final MethodType type, final String bindName) {
  88.963          return pairArguments(bindToNameIfNeeded(bindToCalleeIfNeeded(data.getGenericInvoker(scope)), bindName), type);
  88.964 @@ -939,10 +1215,11 @@
  88.965      }
  88.966  
  88.967      /**
  88.968 -     * Get the guard that checks if a {@link ScriptFunction} is equal to
  88.969 -     * a known ScriptFunction, using reference comparison
  88.970 +     * Get the guard that checks if a {@link ScriptFunction} is equal to a known
  88.971 +     * ScriptFunction, using reference comparison
  88.972       *
  88.973 -     * @param function The ScriptFunction to check against. This will be bound to the guard method handle
  88.974 +     * @param function The ScriptFunction to check against. This will be bound
  88.975 +     * to the guard method handle
  88.976       *
  88.977       * @return method handle for guard
  88.978       */
  88.979 @@ -957,11 +1234,12 @@
  88.980      }
  88.981  
  88.982      /**
  88.983 -     * Get a guard that checks if a {@link ScriptFunction} is equal to
  88.984 -     * a known ScriptFunction using reference comparison, and whether the type of
  88.985 -     * the second argument (this-object) is not a JavaScript primitive type.
  88.986 +     * Get a guard that checks if a {@link ScriptFunction} is equal to a known
  88.987 +     * ScriptFunction using reference comparison, and whether the type of the
  88.988 +     * second argument (this-object) is not a JavaScript primitive type.
  88.989       *
  88.990 -     * @param function The ScriptFunction to check against. This will be bound to the guard method handle
  88.991 +     * @param function The ScriptFunction to check against. This will be bound
  88.992 +     * to the guard method handle
  88.993       *
  88.994       * @return method handle for guard
  88.995       */
  88.996 @@ -972,12 +1250,12 @@
  88.997  
  88.998      @SuppressWarnings("unused")
  88.999      private static boolean isFunctionMH(final Object self, final ScriptFunctionData data) {
 88.1000 -        return self instanceof ScriptFunction && ((ScriptFunction)self).data == data;
 88.1001 +        return self instanceof ScriptFunction && ((ScriptFunction) self).data == data;
 88.1002      }
 88.1003  
 88.1004      @SuppressWarnings("unused")
 88.1005      private static boolean isNonStrictFunction(final Object self, final Object arg, final ScriptFunctionData data) {
 88.1006 -        return self instanceof ScriptFunction && ((ScriptFunction)self).data == data && arg instanceof ScriptObject;
 88.1007 +        return self instanceof ScriptFunction && ((ScriptFunction) self).data == data && arg instanceof ScriptObject;
 88.1008      }
 88.1009  
 88.1010      //TODO this can probably be removed given that we have builtin switchpoints in the context
 88.1011 @@ -990,7 +1268,7 @@
 88.1012      @SuppressWarnings("unused")
 88.1013      private static Object[] addZerothElement(final Object[] args, final Object value) {
 88.1014          // extends input array with by adding new zeroth element
 88.1015 -        final Object[] src = args == null? ScriptRuntime.EMPTY_ARRAY : args;
 88.1016 +        final Object[] src = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
 88.1017          final Object[] result = new Object[src.length + 1];
 88.1018          System.arraycopy(src, 0, result, 1, src.length);
 88.1019          result[0] = value;
 88.1020 @@ -1014,4 +1292,3 @@
 88.1021          return MH.findVirtual(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types));
 88.1022      }
 88.1023  }
 88.1024 -
    89.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Thu Sep 24 10:00:42 2015 -0700
    89.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Thu Sep 24 10:09:56 2015 -0700
    89.3 @@ -151,7 +151,7 @@
    89.4       * Is this a ScriptFunction generated with strict semantics?
    89.5       * @return true if strict, false otherwise
    89.6       */
    89.7 -    public boolean isStrict() {
    89.8 +    public final boolean isStrict() {
    89.9          return (flags & IS_STRICT) != 0;
   89.10      }
   89.11  
   89.12 @@ -164,11 +164,11 @@
   89.13          return getName();
   89.14      }
   89.15  
   89.16 -    boolean isBuiltin() {
   89.17 +    final boolean isBuiltin() {
   89.18          return (flags & IS_BUILTIN) != 0;
   89.19      }
   89.20  
   89.21 -    boolean isConstructor() {
   89.22 +    final boolean isConstructor() {
   89.23          return (flags & IS_CONSTRUCTOR) != 0;
   89.24      }
   89.25  
   89.26 @@ -179,7 +179,7 @@
   89.27       * according to ECMA 10.4.3.
   89.28       * @return true if this argument must be an object
   89.29       */
   89.30 -    boolean needsWrappedThis() {
   89.31 +    final boolean needsWrappedThis() {
   89.32          return (flags & USES_THIS) != 0 && (flags & IS_STRICT_OR_BUILTIN) == 0;
   89.33      }
   89.34  
   89.35 @@ -318,7 +318,7 @@
   89.36       * Used to find an apply to call version that fits this callsite.
   89.37       * We cannot just, as in the normal matcher case, return e.g. (Object, Object, int)
   89.38       * for (Object, Object, int, int, int) or we will destroy the semantics and get
   89.39 -     * a function that, when padded with undefineds, behaves differently
   89.40 +     * a function that, when padded with undefined values, behaves differently
   89.41       * @param type actual call site type
   89.42       * @return apply to call that perfectly fits this callsite or null if none found
   89.43       */
   89.44 @@ -397,7 +397,7 @@
   89.45  
   89.46      /**
   89.47       * This method is used to create the immutable portion of a bound function.
   89.48 -     * See {@link ScriptFunction#makeBoundFunction(Object, Object[])}
   89.49 +     * See {@link ScriptFunction#createBound(Object, Object[])}
   89.50       *
   89.51       * @param fn the original function being bound
   89.52       * @param self this reference to bind. Can be null.
    90.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Sep 24 10:00:42 2015 -0700
    90.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Sep 24 10:09:56 2015 -0700
    90.3 @@ -64,6 +64,7 @@
    90.4  import java.util.List;
    90.5  import java.util.Map;
    90.6  import java.util.Set;
    90.7 +import java.util.concurrent.atomic.LongAdder;
    90.8  import jdk.internal.dynalink.CallSiteDescriptor;
    90.9  import jdk.internal.dynalink.linker.GuardedInvocation;
   90.10  import jdk.internal.dynalink.linker.LinkRequest;
   90.11 @@ -148,7 +149,7 @@
   90.12      /** Method handle to retrieve prototype of this object */
   90.13      public static final MethodHandle GETPROTO      = findOwnMH_V("getProto", ScriptObject.class);
   90.14  
   90.15 -    static final MethodHandle MEGAMORPHIC_GET    = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class);
   90.16 +    static final MethodHandle MEGAMORPHIC_GET    = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class, boolean.class);
   90.17      static final MethodHandle GLOBALFILTER       = findOwnMH_S("globalFilter", Object.class, Object.class);
   90.18      static final MethodHandle DECLARE_AND_SET    = findOwnMH_V("declareAndSet", void.class, String.class, Object.class);
   90.19  
   90.20 @@ -211,7 +212,7 @@
   90.21      */
   90.22      public ScriptObject(final PropertyMap map) {
   90.23          if (Context.DEBUG) {
   90.24 -            ScriptObject.count++;
   90.25 +            ScriptObject.count.increment();
   90.26          }
   90.27          this.arrayData = ArrayData.EMPTY_ARRAY;
   90.28          this.setMap(map == null ? PropertyMap.newMap() : map);
   90.29 @@ -224,7 +225,7 @@
   90.30       * same combination of prototype and property map.
   90.31       *
   90.32       * @param proto the prototype object
   90.33 -     * @param map intial {@link PropertyMap}
   90.34 +     * @param map initial {@link PropertyMap}
   90.35       */
   90.36      protected ScriptObject(final ScriptObject proto, final PropertyMap map) {
   90.37          this(map);
   90.38 @@ -1257,7 +1258,7 @@
   90.39          if (oldProto != newProto) {
   90.40              proto = newProto;
   90.41  
   90.42 -            // Let current listeners know that the protototype has changed and set our map
   90.43 +            // Let current listeners know that the prototype has changed and set our map
   90.44              final PropertyListeners listeners = getMap().getListeners();
   90.45              if (listeners != null) {
   90.46                  listeners.protoChanged();
   90.47 @@ -1452,7 +1453,7 @@
   90.48       * in {@link ScriptFunction} for hasInstance implementation, walks
   90.49       * the proto chain
   90.50       *
   90.51 -     * @param instance instace to check
   90.52 +     * @param instance instance to check
   90.53       * @return true if 'instance' is an instance of this object
   90.54       */
   90.55      public boolean isInstance(final ScriptObject instance) {
   90.56 @@ -1869,7 +1870,7 @@
   90.57       * @param desc    the call site descriptor.
   90.58       * @param request the link request
   90.59       *
   90.60 -     * @return GuardedInvocation to be invoed at call site.
   90.61 +     * @return GuardedInvocation to be invoked at call site.
   90.62       */
   90.63      protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
   90.64          return notAFunction(desc);
   90.65 @@ -2019,19 +2020,19 @@
   90.66  
   90.67      private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
   90.68          Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: " + desc + " " + name + " " +isMethod);
   90.69 -        final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
   90.70 +        final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, NashornCallSiteDescriptor.isScope(desc));
   90.71          final MethodHandle guard   = getScriptObjectGuard(desc.getMethodType(), true);
   90.72          return new GuardedInvocation(invoker, guard);
   90.73      }
   90.74  
   90.75      @SuppressWarnings("unused")
   90.76 -    private Object megamorphicGet(final String key, final boolean isMethod) {
   90.77 +    private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) {
   90.78          final FindProperty find = findProperty(key, true);
   90.79          if (find != null) {
   90.80              return find.getObjectValue();
   90.81          }
   90.82  
   90.83 -        return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
   90.84 +        return isMethod ? getNoSuchMethod(key, isScope, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, isScope, INVALID_PROGRAM_POINT);
   90.85      }
   90.86  
   90.87      // Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST
   90.88 @@ -2301,7 +2302,7 @@
   90.89                  MH.dropArguments(
   90.90                          MH.constant(
   90.91                                  ScriptFunction.class,
   90.92 -                                func.makeBoundFunction(thiz, new Object[] { name })),
   90.93 +                                func.createBound(thiz, new Object[] { name })),
   90.94                          0,
   90.95                          Object.class),
   90.96                  NashornGuards.combineGuards(
   90.97 @@ -2366,20 +2367,21 @@
   90.98      /**
   90.99       * Invoke fall back if a property is not found.
  90.100       * @param name Name of property.
  90.101 +     * @param isScope is this a scope access?
  90.102       * @param programPoint program point
  90.103       * @return Result from call.
  90.104       */
  90.105 -    protected Object invokeNoSuchProperty(final String name, final int programPoint) {
  90.106 +    protected Object invokeNoSuchProperty(final String name, final boolean isScope, final int programPoint) {
  90.107          final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
  90.108 +        final Object func = (find != null)? find.getObjectValue() : null;
  90.109  
  90.110          Object ret = UNDEFINED;
  90.111 -
  90.112 -        if (find != null) {
  90.113 -            final Object func = find.getObjectValue();
  90.114 -
  90.115 -            if (func instanceof ScriptFunction) {
  90.116 -                ret = ScriptRuntime.apply((ScriptFunction)func, this, name);
  90.117 -            }
  90.118 +        if (func instanceof ScriptFunction) {
  90.119 +            final ScriptFunction sfunc = (ScriptFunction)func;
  90.120 +            final Object self = isScope && sfunc.isStrict()? UNDEFINED : this;
  90.121 +            ret = ScriptRuntime.apply(sfunc, self, name);
  90.122 +        } else if (isScope) {
  90.123 +            throw referenceError("not.defined", name);
  90.124          }
  90.125  
  90.126          if (isValid(programPoint)) {
  90.127 @@ -2393,21 +2395,27 @@
  90.128      /**
  90.129       * Get __noSuchMethod__ as a function bound to this object and {@code name} if it is defined.
  90.130       * @param name the method name
  90.131 +     * @param isScope is this a scope access?
  90.132       * @return the bound function, or undefined
  90.133       */
  90.134 -    private Object getNoSuchMethod(final String name, final int programPoint) {
  90.135 +    private Object getNoSuchMethod(final String name, final boolean isScope, final int programPoint) {
  90.136          final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true);
  90.137  
  90.138          if (find == null) {
  90.139 -            return invokeNoSuchProperty(name, programPoint);
  90.140 +            return invokeNoSuchProperty(name, isScope, programPoint);
  90.141          }
  90.142  
  90.143          final Object value = find.getObjectValue();
  90.144          if (!(value instanceof ScriptFunction)) {
  90.145 +            if (isScope) {
  90.146 +                throw referenceError("not.defined", name);
  90.147 +            }
  90.148              return UNDEFINED;
  90.149          }
  90.150  
  90.151 -        return ((ScriptFunction)value).makeBoundFunction(this, new Object[] {name});
  90.152 +        final ScriptFunction func = (ScriptFunction)value;
  90.153 +        final Object self = isScope && func.isStrict()? UNDEFINED : this;
  90.154 +        return func.createBound(self, new Object[] {name});
  90.155      }
  90.156  
  90.157      private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String name) {
  90.158 @@ -2722,7 +2730,7 @@
  90.159              }
  90.160          }
  90.161  
  90.162 -        return JSType.toInt32(invokeNoSuchProperty(key, programPoint));
  90.163 +        return JSType.toInt32(invokeNoSuchProperty(key, false, programPoint));
  90.164      }
  90.165  
  90.166      @Override
  90.167 @@ -2804,7 +2812,7 @@
  90.168              }
  90.169          }
  90.170  
  90.171 -        return JSType.toLong(invokeNoSuchProperty(key, programPoint));
  90.172 +        return JSType.toLong(invokeNoSuchProperty(key, false, programPoint));
  90.173      }
  90.174  
  90.175      @Override
  90.176 @@ -2886,7 +2894,7 @@
  90.177              }
  90.178          }
  90.179  
  90.180 -        return JSType.toNumber(invokeNoSuchProperty(key, INVALID_PROGRAM_POINT));
  90.181 +        return JSType.toNumber(invokeNoSuchProperty(key, false, INVALID_PROGRAM_POINT));
  90.182      }
  90.183  
  90.184      @Override
  90.185 @@ -2967,7 +2975,7 @@
  90.186              }
  90.187          }
  90.188  
  90.189 -        return invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
  90.190 +        return invokeNoSuchProperty(key, false, INVALID_PROGRAM_POINT);
  90.191      }
  90.192  
  90.193      @Override
  90.194 @@ -3796,15 +3804,20 @@
  90.195      }
  90.196  
  90.197      /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created */
  90.198 -    private static int count;
  90.199 -
  90.200 +    private static LongAdder count;
  90.201 +
  90.202 +    static {
  90.203 +        if (Context.DEBUG) {
  90.204 +            count = new LongAdder();
  90.205 +        }
  90.206 +    }
  90.207      /**
  90.208       * Get number of {@code ScriptObject} instances created. If not running in debug
  90.209       * mode this is always 0
  90.210       *
  90.211       * @return number of ScriptObjects created
  90.212       */
  90.213 -    public static int getCount() {
  90.214 -        return count;
  90.215 +    public static long getCount() {
  90.216 +        return count.longValue();
  90.217      }
  90.218  }
    91.1 --- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Thu Sep 24 10:00:42 2015 -0700
    91.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Thu Sep 24 10:09:56 2015 -0700
    91.3 @@ -26,6 +26,7 @@
    91.4  package jdk.nashorn.internal.runtime;
    91.5  
    91.6  import static jdk.nashorn.internal.lookup.Lookup.MH;
    91.7 +import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
    91.8  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    91.9  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
   91.10  
   91.11 @@ -70,6 +71,9 @@
   91.12      /** EXIT name - special property used by $EXEC API. */
   91.13      public static final String EXIT_NAME = "$EXIT";
   91.14  
   91.15 +    /** THROW_ON_ERROR name - special property of the $EXEC function used by $EXEC API. */
   91.16 +    public static final String THROW_ON_ERROR_NAME = "throwOnError";
   91.17 +
   91.18      /** Names of special properties used by $ENV API. */
   91.19      public  static final String ENV_NAME  = "$ENV";
   91.20  
   91.21 @@ -244,6 +248,19 @@
   91.22              }
   91.23          }
   91.24  
   91.25 +        // if we got a non-zero exit code ("failure"), then we have to decide to throw error or not
   91.26 +        if (exit != 0) {
   91.27 +            // get the $EXEC function object from the global object
   91.28 +            final Object exec = global.get(EXEC_NAME);
   91.29 +            assert exec instanceof ScriptObject : EXEC_NAME + " is not a script object!";
   91.30 +
   91.31 +            // Check if the user has set $EXEC.throwOnError property to true. If so, throw RangeError
   91.32 +            // If that property is not set or set to false, then silently proceed with the rest.
   91.33 +            if (JSType.toBoolean(((ScriptObject)exec).get(THROW_ON_ERROR_NAME))) {
   91.34 +                throw rangeError("exec.returned.non.zero", ScriptRuntime.safeToString(exit));
   91.35 +            }
   91.36 +        }
   91.37 +
   91.38          // Return the result from stdout.
   91.39          return out;
   91.40      }
    92.1 --- a/src/jdk/nashorn/internal/runtime/Timing.java	Thu Sep 24 10:00:42 2015 -0700
    92.2 +++ b/src/jdk/nashorn/internal/runtime/Timing.java	Thu Sep 24 10:09:56 2015 -0700
    92.3 @@ -28,12 +28,14 @@
    92.4  import java.io.IOException;
    92.5  import java.io.StringReader;
    92.6  import java.util.ArrayList;
    92.7 -import java.util.LinkedHashMap;
    92.8  import java.util.List;
    92.9  import java.util.Map;
   92.10 +import java.util.concurrent.ConcurrentHashMap;
   92.11 +import java.util.concurrent.LinkedBlockingQueue;
   92.12  import java.util.concurrent.TimeUnit;
   92.13 +import java.util.concurrent.atomic.LongAdder;
   92.14 +import java.util.function.Function;
   92.15  import java.util.function.Supplier;
   92.16 -
   92.17  import jdk.nashorn.internal.codegen.CompileUnit;
   92.18  import jdk.nashorn.internal.runtime.logging.DebugLogger;
   92.19  import jdk.nashorn.internal.runtime.logging.Loggable;
   92.20 @@ -156,11 +158,15 @@
   92.21      }
   92.22  
   92.23      final class TimeSupplier implements Supplier<String> {
   92.24 -        private final Map<String, Long> timings;
   92.25 -
   92.26 -        TimeSupplier() {
   92.27 -            timings   = new LinkedHashMap<>();
   92.28 -        }
   92.29 +        private final Map<String, LongAdder> timings = new ConcurrentHashMap<>();
   92.30 +        private final LinkedBlockingQueue<String> orderedTimingNames = new LinkedBlockingQueue<>();
   92.31 +        private final Function<String, LongAdder> newTimingCreator = new Function<String, LongAdder>() {
   92.32 +            @Override
   92.33 +            public LongAdder apply(final String s) {
   92.34 +                orderedTimingNames.add(s);
   92.35 +                return new LongAdder();
   92.36 +            }
   92.37 +        };
   92.38  
   92.39          String[] getStrings() {
   92.40              final List<String> strs = new ArrayList<>();
   92.41 @@ -184,26 +190,26 @@
   92.42              int  maxKeyLength = 0;
   92.43              int  maxValueLength = 0;
   92.44  
   92.45 -            for (final Map.Entry<String, Long> entry : timings.entrySet()) {
   92.46 +            for (final Map.Entry<String, LongAdder> entry : timings.entrySet()) {
   92.47                  maxKeyLength   = Math.max(maxKeyLength, entry.getKey().length());
   92.48 -                maxValueLength = Math.max(maxValueLength, toMillisPrint(entry.getValue()).length());
   92.49 +                maxValueLength = Math.max(maxValueLength, toMillisPrint(entry.getValue().longValue()).length());
   92.50              }
   92.51              maxKeyLength++;
   92.52  
   92.53              final StringBuilder sb = new StringBuilder();
   92.54              sb.append("Accumulated compilation phase timings:\n\n");
   92.55 -            for (final Map.Entry<String, Long> entry : timings.entrySet()) {
   92.56 +            for (final String timingName: orderedTimingNames) {
   92.57                  int len;
   92.58  
   92.59                  len = sb.length();
   92.60 -                sb.append(entry.getKey());
   92.61 +                sb.append(timingName);
   92.62                  len = sb.length() - len;
   92.63  
   92.64                  while (len++ < maxKeyLength) {
   92.65                      sb.append(' ');
   92.66                  }
   92.67  
   92.68 -                final Long duration = entry.getValue();
   92.69 +                final long duration = timings.get(timingName).longValue();
   92.70                  final String strDuration = toMillisPrint(duration);
   92.71                  len = strDuration.length();
   92.72                  for (int i = 0; i < maxValueLength - len; i++) {
   92.73 @@ -233,11 +239,7 @@
   92.74          }
   92.75  
   92.76          private void accumulateTime(final String module, final long duration) {
   92.77 -            Long accumulatedTime = timings.get(module);
   92.78 -            if (accumulatedTime == null) {
   92.79 -                accumulatedTime = 0L;
   92.80 -            }
   92.81 -            timings.put(module, accumulatedTime + duration);
   92.82 +            timings.computeIfAbsent(module, newTimingCreator).add(duration);
   92.83          }
   92.84      }
   92.85  }
    93.1 --- a/src/jdk/nashorn/internal/runtime/WithObject.java	Thu Sep 24 10:00:42 2015 -0700
    93.2 +++ b/src/jdk/nashorn/internal/runtime/WithObject.java	Thu Sep 24 10:09:56 2015 -0700
    93.3 @@ -26,6 +26,7 @@
    93.4  package jdk.nashorn.internal.runtime;
    93.5  
    93.6  import static jdk.nashorn.internal.lookup.Lookup.MH;
    93.7 +import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    93.8  
    93.9  import java.lang.invoke.MethodHandle;
   93.10  import java.lang.invoke.MethodHandles;
   93.11 @@ -209,16 +210,18 @@
   93.12      }
   93.13  
   93.14      @Override
   93.15 -    protected Object invokeNoSuchProperty(final String name, final int programPoint) {
   93.16 +    protected Object invokeNoSuchProperty(final String name, final boolean isScope, final int programPoint) {
   93.17          FindProperty find = expression.findProperty(NO_SUCH_PROPERTY_NAME, true);
   93.18          if (find != null) {
   93.19              final Object func = find.getObjectValue();
   93.20              if (func instanceof ScriptFunction) {
   93.21 -                return ScriptRuntime.apply((ScriptFunction)func, expression, name);
   93.22 +                final ScriptFunction sfunc = (ScriptFunction)func;
   93.23 +                final Object self = isScope && sfunc.isStrict()? UNDEFINED : expression;
   93.24 +                return ScriptRuntime.apply(sfunc, self, name);
   93.25              }
   93.26          }
   93.27  
   93.28 -        return getProto().invokeNoSuchProperty(name, programPoint);
   93.29 +        return getProto().invokeNoSuchProperty(name, isScope, programPoint);
   93.30      }
   93.31  
   93.32      @Override
   93.33 @@ -352,7 +355,7 @@
   93.34      }
   93.35  
   93.36      private static Object bindToExpression(final ScriptFunction fn, final Object receiver) {
   93.37 -        return fn.makeBoundFunction(withFilterExpression(receiver), ScriptRuntime.EMPTY_ARRAY);
   93.38 +        return fn.createBound(withFilterExpression(receiver), ScriptRuntime.EMPTY_ARRAY);
   93.39      }
   93.40  
   93.41      private MethodHandle expressionGuard(final String name, final ScriptObject owner) {
    94.1 --- a/src/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java	Thu Sep 24 10:00:42 2015 -0700
    94.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java	Thu Sep 24 10:09:56 2015 -0700
    94.3 @@ -191,7 +191,7 @@
    94.4  
    94.5      /**
    94.6       * Return element setter for a {@link ContinuousArrayData}
    94.7 -     * @param clazz        clazz for exact type guard
    94.8 +     * @param clazz        class for exact type guard
    94.9       * @param setHas       set has guard
   94.10       * @param elementType  element type
   94.11       * @return method handle for element setter
    95.1 --- a/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java	Thu Sep 24 10:00:42 2015 -0700
    95.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java	Thu Sep 24 10:09:56 2015 -0700
    95.3 @@ -34,7 +34,7 @@
    95.4   * This filter handles the presence of undefined array elements.
    95.5   */
    95.6  final class UndefinedArrayFilter extends ArrayFilter {
    95.7 -    /** Bit vector tracking undefines. */
    95.8 +    /** Bit vector tracking undefined slots. */
    95.9      private final BitVector undefined;
   95.10  
   95.11      UndefinedArrayFilter(final ArrayData underlying) {
    96.1 --- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Thu Sep 24 10:00:42 2015 -0700
    96.2 +++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Thu Sep 24 10:09:56 2015 -0700
    96.3 @@ -50,7 +50,6 @@
    96.4  import jdk.nashorn.internal.codegen.ObjectClassGenerator;
    96.5  import jdk.nashorn.internal.lookup.MethodHandleFactory;
    96.6  import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
    96.7 -import jdk.nashorn.internal.objects.ScriptFunctionImpl;
    96.8  import jdk.nashorn.internal.runtime.ECMAException;
    96.9  import jdk.nashorn.internal.runtime.JSType;
   96.10  import jdk.nashorn.internal.runtime.OptimisticReturnFilters;
   96.11 @@ -70,7 +69,7 @@
   96.12      private static final MethodHandle VOID_TO_OBJECT = MH.constant(Object.class, ScriptRuntime.UNDEFINED);
   96.13  
   96.14      /**
   96.15 -     * The default dynalink relink threshold for megamorphisism is 8. In the case
   96.16 +     * The default dynalink relink threshold for megamorphism is 8. In the case
   96.17       * of object fields only, it is fine. However, with dual fields, in order to get
   96.18       * performance on benchmarks with a lot of object instantiation and then field
   96.19       * reassignment, it can take slightly more relinks to become stable with type
   96.20 @@ -214,7 +213,7 @@
   96.21       * @param type           method type
   96.22       * @param programPoint   program point to bind to callsite
   96.23       *
   96.24 -     * @return callsite for a math instrinic node
   96.25 +     * @return callsite for a math intrinsic node
   96.26       */
   96.27      public static CallSite mathBootstrap(final MethodHandles.Lookup lookup, final String name, final MethodType type, final int programPoint) {
   96.28          final MethodHandle mh;
   96.29 @@ -397,8 +396,8 @@
   96.30       * @throws ECMAException with {@code TypeError} if the object is not a callable.
   96.31       */
   96.32      public static Object bindCallable(final Object callable, final Object boundThis, final Object[] boundArgs) {
   96.33 -        if (callable instanceof ScriptFunctionImpl) {
   96.34 -            return ((ScriptFunctionImpl)callable).makeBoundFunction(boundThis, boundArgs);
   96.35 +        if (callable instanceof ScriptFunction) {
   96.36 +            return ((ScriptFunction)callable).createBound(boundThis, boundArgs);
   96.37          } else if (callable instanceof BoundCallable) {
   96.38              return ((BoundCallable)callable).bind(boundArgs);
   96.39          } else if (isCallable(callable)) {
    97.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Thu Sep 24 10:00:42 2015 -0700
    97.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Thu Sep 24 10:09:56 2015 -0700
    97.3 @@ -571,7 +571,7 @@
    97.4              mv.visitVarInsn(ALOAD, 0);
    97.5              if (fromFunction && !mi.getName().equals(samName)) {
    97.6                  // Constructors initializing from a ScriptFunction only initialize methods with the SAM name.
    97.7 -                // NOTE: if there's a concrete overloaded method sharing the SAM name, it'll be overriden too. This
    97.8 +                // NOTE: if there's a concrete overloaded method sharing the SAM name, it'll be overridden too. This
    97.9                  // is a deliberate design choice. All other method handles are initialized to null.
   97.10                  mv.visitInsn(ACONST_NULL);
   97.11              } else {
    98.1 --- a/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Thu Sep 24 10:00:42 2015 -0700
    98.2 +++ b/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Thu Sep 24 10:09:56 2015 -0700
    98.3 @@ -43,6 +43,7 @@
    98.4  import java.util.Random;
    98.5  import java.util.Set;
    98.6  import java.util.concurrent.atomic.AtomicInteger;
    98.7 +import java.util.concurrent.atomic.LongAdder;
    98.8  import jdk.internal.dynalink.ChainedCallSite;
    98.9  import jdk.internal.dynalink.DynamicLinker;
   98.10  import jdk.internal.dynalink.linker.GuardedInvocation;
   98.11 @@ -70,7 +71,7 @@
   98.12      LinkerCallSite(final NashornCallSiteDescriptor descriptor) {
   98.13          super(descriptor);
   98.14          if (Context.DEBUG) {
   98.15 -            LinkerCallSite.count++;
   98.16 +            LinkerCallSite.count.increment();
   98.17          }
   98.18      }
   98.19  
   98.20 @@ -173,7 +174,7 @@
   98.21       * @return self reference
   98.22       */
   98.23      public static Object increaseMissCount(final String desc, final Object self) {
   98.24 -        ++missCount;
   98.25 +        missCount.increment();
   98.26          if (r.nextInt(100) < missSamplingPercentage) {
   98.27              final AtomicInteger i = missCounts.get(desc);
   98.28              if (i == null) {
   98.29 @@ -500,7 +501,7 @@
   98.30           * @param desc callsite descriptor string
   98.31           * @param args arguments to function
   98.32           *
   98.33 -         * @throws Throwable if invocation failes or throws exception/error
   98.34 +         * @throws Throwable if invocation fails or throws exception/error
   98.35           */
   98.36          @SuppressWarnings("unused")
   98.37          public void traceMiss(final String desc, final Object... args) throws Throwable {
   98.38 @@ -509,12 +510,19 @@
   98.39      }
   98.40  
   98.41      // counters updated in debug mode
   98.42 -    private static int count;
   98.43 +    private static LongAdder count;
   98.44      private static final HashMap<String, AtomicInteger> missCounts = new HashMap<>();
   98.45 -    private static int missCount;
   98.46 +    private static LongAdder missCount;
   98.47      private static final Random r = new Random();
   98.48      private static final int missSamplingPercentage = Options.getIntProperty("nashorn.tcs.miss.samplePercent", 1);
   98.49  
   98.50 +    static {
   98.51 +        if (Context.DEBUG) {
   98.52 +            count = new LongAdder();
   98.53 +            missCount = new LongAdder();
   98.54 +        }
   98.55 +    }
   98.56 +
   98.57      @Override
   98.58      protected int getMaxChainLength() {
   98.59          return 8;
   98.60 @@ -524,16 +532,16 @@
   98.61       * Get the callsite count
   98.62       * @return the count
   98.63       */
   98.64 -    public static int getCount() {
   98.65 -        return count;
   98.66 +    public static long getCount() {
   98.67 +        return count.longValue();
   98.68      }
   98.69  
   98.70      /**
   98.71       * Get the callsite miss count
   98.72       * @return the missCount
   98.73       */
   98.74 -    public static int getMissCount() {
   98.75 -        return missCount;
   98.76 +    public static long getMissCount() {
   98.77 +        return missCount.longValue();
   98.78      }
   98.79  
   98.80      /**
    99.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Thu Sep 24 10:00:42 2015 -0700
    99.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Thu Sep 24 10:09:56 2015 -0700
    99.3 @@ -26,7 +26,6 @@
    99.4  package jdk.nashorn.internal.runtime.linker;
    99.5  
    99.6  import static jdk.nashorn.internal.lookup.Lookup.MH;
    99.7 -import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    99.8  
    99.9  import java.lang.invoke.MethodHandle;
   99.10  import java.lang.invoke.MethodHandles;
   99.11 @@ -42,13 +41,11 @@
   99.12  import jdk.internal.dynalink.linker.LinkerServices;
   99.13  import jdk.internal.dynalink.linker.MethodHandleTransformer;
   99.14  import jdk.internal.dynalink.support.DefaultInternalObjectFilter;
   99.15 -import jdk.internal.dynalink.support.Guards;
   99.16  import jdk.internal.dynalink.support.Lookup;
   99.17  import jdk.nashorn.api.scripting.ScriptUtils;
   99.18  import jdk.nashorn.internal.runtime.ConsString;
   99.19  import jdk.nashorn.internal.runtime.Context;
   99.20  import jdk.nashorn.internal.runtime.ScriptObject;
   99.21 -import jdk.nashorn.internal.runtime.ScriptRuntime;
   99.22  import jdk.nashorn.internal.runtime.options.Options;
   99.23  
   99.24  /**
   99.25 @@ -171,7 +168,7 @@
   99.26          }
   99.27  
   99.28          for (final Class<?> iface : clazz.getInterfaces()) {
   99.29 -            // check accessiblity up-front
   99.30 +            // check accessibility up-front
   99.31              if (! Context.isAccessibleClass(iface)) {
   99.32                  continue;
   99.33              }
   100.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Thu Sep 24 10:00:42 2015 -0700
   100.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Thu Sep 24 10:09:56 2015 -0700
   100.3 @@ -323,7 +323,7 @@
   100.4       * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
   100.5       * generated outside of Nashorn.
   100.6       * @param flag the tested flag
   100.7 -     * @return true if the flag is set, false otherwise (it will be false if the decriptor is not a Nashorn call site
   100.8 +     * @return true if the flag is set, false otherwise (it will be false if the descriptor is not a Nashorn call site
   100.9       * descriptor).
  100.10       */
  100.11      private static boolean isFlag(final CallSiteDescriptor desc, final int flag) {
   101.1 --- a/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java	Thu Sep 24 10:00:42 2015 -0700
   101.2 +++ b/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java	Thu Sep 24 10:09:56 2015 -0700
   101.3 @@ -163,7 +163,7 @@
   101.4  
   101.5      /**
   101.6       * Does this option automatically enable another option, i.e. a dependency.
   101.7 -     * @return the dependecy or null if non exists
   101.8 +     * @return the dependency or null if none exists
   101.9       */
  101.10      public String getDependency() {
  101.11          return this.dependency;
  101.12 @@ -304,8 +304,8 @@
  101.13          }
  101.14      }
  101.15  
  101.16 -    boolean matches(final String key0) {
  101.17 -        return key0.equals(this.shortName) || key0.equals(this.name);
  101.18 +    boolean nameMatches(final String aName) {
  101.19 +        return aName.equals(this.shortName) || aName.equals(this.name);
  101.20      }
  101.21  
  101.22      private static final int LINE_BREAK = 64;
   102.1 --- a/src/jdk/nashorn/internal/runtime/options/Options.java	Thu Sep 24 10:00:42 2015 -0700
   102.2 +++ b/src/jdk/nashorn/internal/runtime/options/Options.java	Thu Sep 24 10:09:56 2015 -0700
   102.3 @@ -519,9 +519,25 @@
   102.4          }
   102.5      }
   102.6  
   102.7 -    private static OptionTemplate getOptionTemplate(final String key) {
   102.8 +    /**
   102.9 +     * Retrieves an option template identified by key.
  102.10 +     * @param shortKey the short (that is without the e.g. "nashorn.option." part) key
  102.11 +     * @return the option template identified by the key
  102.12 +     * @throws IllegalArgumentException if the key doesn't specify an existing template
  102.13 +     */
  102.14 +    public OptionTemplate getOptionTemplateByKey(final String shortKey) {
  102.15 +        final String fullKey = key(shortKey);
  102.16 +        for(final OptionTemplate t: validOptions) {
  102.17 +            if(t.getKey().equals(fullKey)) {
  102.18 +                return t;
  102.19 +            }
  102.20 +        }
  102.21 +        throw new IllegalArgumentException(shortKey);
  102.22 +    }
  102.23 +
  102.24 +    private static OptionTemplate getOptionTemplateByName(final String name) {
  102.25          for (final OptionTemplate t : Options.validOptions) {
  102.26 -            if (t.matches(key)) {
  102.27 +            if (t.nameMatches(name)) {
  102.28                  return t;
  102.29              }
  102.30          }
  102.31 @@ -681,7 +697,7 @@
  102.32              }
  102.33  
  102.34              final String token = st.nextToken();
  102.35 -            this.template = Options.getOptionTemplate(token);
  102.36 +            this.template = getOptionTemplateByName(token);
  102.37              if (this.template == null) {
  102.38                  throw new IllegalArgumentException(argument);
  102.39              }
   103.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java	Thu Sep 24 10:00:42 2015 -0700
   103.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java	Thu Sep 24 10:09:56 2015 -0700
   103.3 @@ -65,7 +65,7 @@
   103.4  
   103.5      final boolean DONT_OPTIMIZE                     = false;
   103.6  
   103.7 -    final boolean USE_STRING_TEMPLATES              = true; // use embeded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
   103.8 +    final boolean USE_STRING_TEMPLATES              = true; // use embedded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
   103.9  
  103.10      final boolean NON_UNICODE_SDW                   = true;
  103.11  
   104.1 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Thu Sep 24 10:00:42 2015 -0700
   104.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Thu Sep 24 10:09:56 2015 -0700
   104.3 @@ -150,6 +150,7 @@
   104.4  type.error.method.not.constructor=Java method {0} cannot be used as a constructor.
   104.5  type.error.env.not.object=$ENV must be an Object.
   104.6  type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
   104.7 +type.error.java.array.conversion.failed=Java.to conversion to array type {0} failed
   104.8  type.error.constructor.requires.new=Constructor {0} requires "new".
   104.9  type.error.new.on.nonpublic.javatype=new cannot be used with non-public java type {0}.
  104.10  
  104.11 @@ -163,6 +164,7 @@
  104.12  range.error.invalid.date=Invalid Date
  104.13  range.error.too.many.errors=Script contains too many errors: {0} errors
  104.14  range.error.concat.string.too.big=Concatenated String is too big
  104.15 +range.error.exec.returned.non.zero=$EXEC returned non-zero exit code: {0}
  104.16  
  104.17  reference.error.not.defined="{0}" is not defined
  104.18  reference.error.cant.be.used.as.lhs="{0}" can not be used as the left-hand side of assignment
  104.19 @@ -173,7 +175,9 @@
  104.20  syntax.error.unprotected.switch.declaration=Unsupported {0} declaration in unprotected switch statement
  104.21  
  104.22  io.error.cant.write=cannot write "{0}"
  104.23 +
  104.24  config.error.no.dest=no destination directory supplied
  104.25 +config.error.eagerCompilationConflictsWithOptimisticTypes={0}=false (eager compilation) is not compatible with {1}=true.
  104.26  
  104.27  uri.error.bad.uri=Bad URI "{0}" near offset {1}
  104.28  list.adapter.null.global=Attempted to create the adapter from outside a JavaScript execution context.
   105.1 --- a/src/jdk/nashorn/internal/runtime/resources/parser.js	Thu Sep 24 10:00:42 2015 -0700
   105.2 +++ b/src/jdk/nashorn/internal/runtime/resources/parser.js	Thu Sep 24 10:09:56 2015 -0700
   105.3 @@ -55,7 +55,7 @@
   105.4                  // do not start with '/'. If regexp, then eval it to make RegExp object
   105.5                  return value.startsWith('/')? eval(value) : value.substring(1);
   105.6              } else {
   105.7 -                // anythin else is returned "as is""
   105.8 +                // anything else is returned "as is"
   105.9                  return value;
  105.10              }
  105.11          });
   106.1 --- a/test/script/basic/JDK-8043232.js	Thu Sep 24 10:00:42 2015 -0700
   106.2 +++ b/test/script/basic/JDK-8043232.js	Thu Sep 24 10:09:56 2015 -0700
   106.3 @@ -29,14 +29,14 @@
   106.4   */
   106.5  
   106.6  // call explicit constructor
   106.7 -print(new (java.awt["Color(int,int,int)"])(255,0,255));
   106.8 +print(new (java.lang["String(char[],int,int)"])(['a','b', 'c', 'd'], 1, 3));
   106.9  // print the constructor itself
  106.10 -print(java.awt["Color(int,int,int)"]);
  106.11 +print(java.lang["String(char[],int,int)"]);
  106.12  
  106.13  // store constructor to call later
  106.14 -var Color = java.awt["Color(int,int,int)"];
  106.15 +var Color = java.lang["String(char[],int,int)"];
  106.16  // call stored constructor
  106.17 -print(new Color(33, 233, 2))
  106.18 +print(new Color(['r','r', 'e', 'd'], 1, 3))
  106.19  
  106.20  // check if default constructor works
  106.21  var obj = new (java.lang["Object()"])();
   107.1 --- a/test/script/basic/JDK-8043232.js.EXPECTED	Thu Sep 24 10:00:42 2015 -0700
   107.2 +++ b/test/script/basic/JDK-8043232.js.EXPECTED	Thu Sep 24 10:09:56 2015 -0700
   107.3 @@ -1,14 +1,28 @@
   107.4 -java.awt.Color[r=255,g=0,b=255]
   107.5 -[jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)]
   107.6 -java.awt.Color[r=33,g=233,b=2]
   107.7 +bcd
   107.8 +[jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)]
   107.9 +red
  107.10  TypeError: No such Java class: java.lang.NonExistent
  107.11  TypeError: No such Java constructor: Object(String)
  107.12  TypeError: Java constructor signature invalid: Object()xxxxx
  107.13  TypeError: Java constructor signature invalid: Object(
  107.14  TypeError: Java constructor signature invalid: Object)
  107.15 -TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cannot be used as a constructor.
  107.16 -TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cannot be used as a constructor.
  107.17 -TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires "new".
  107.18 +TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod
  107.19 + String java.lang.System.getProperty(String,String)
  107.20 + String java.lang.System.getProperty(String)
  107.21 +] cannot be used as a constructor.
  107.22 +TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod
  107.23 + void java.io.PrintStream.println()
  107.24 + void java.io.PrintStream.println(boolean)
  107.25 + void java.io.PrintStream.println(char)
  107.26 + void java.io.PrintStream.println(char[])
  107.27 + void java.io.PrintStream.println(double)
  107.28 + void java.io.PrintStream.println(float)
  107.29 + void java.io.PrintStream.println(int)
  107.30 + void java.io.PrintStream.println(long)
  107.31 + void java.io.PrintStream.println(Object)
  107.32 + void java.io.PrintStream.println(String)
  107.33 +] cannot be used as a constructor.
  107.34 +TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] requires "new".
  107.35  TypeError: No such Java constructor: Runnable()
  107.36  TypeError: No such Java constructor: Runnable(int)
  107.37  java.lang.InstantiationException: java.io.InputStream
   108.1 --- a/test/script/basic/JDK-8044750.js	Thu Sep 24 10:00:42 2015 -0700
   108.2 +++ b/test/script/basic/JDK-8044750.js	Thu Sep 24 10:09:56 2015 -0700
   108.3 @@ -25,6 +25,8 @@
   108.4   * JDK-8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
   108.5   *
   108.6   * @test
   108.7 + * @fork
   108.8 + * @option -Dnashorn.unstable.relink.threshold=16
   108.9   * @run
  108.10   */
  108.11  
  108.12 @@ -40,7 +42,9 @@
  108.13      }
  108.14  }
  108.15  
  108.16 -for (var i = 0; i < 20; i++) {
  108.17 +var LIMIT = 20; // should be more than megamorphic threshold set via @option
  108.18 +
  108.19 +for (var i = 0; i < LIMIT; i++) {
  108.20      var obj = {};
  108.21      obj.foo = i;
  108.22      obj[i] = i;
  108.23 @@ -51,3 +55,30 @@
  108.24  // callsite inside func should see __noSuchProperty__
  108.25  // hook on global scope object.
  108.26  func({});
  108.27 +
  108.28 +function checkFoo() {
  108.29 +    with({}) {
  108.30 +        try {
  108.31 +            foo;
  108.32 +            return true;
  108.33 +        } catch (e) {
  108.34 +            return false;
  108.35 +        }
  108.36 +    }
  108.37 +}
  108.38 +
  108.39 +var oldNoSuchProperty = this.__noSuchProperty__;
  108.40 +delete this.__noSuchProperty__;
  108.41 +
  108.42 +// keep deleting/restorting __noSuchProperty__ alternatively
  108.43 +// to make "foo" access in checkFoo function megamorphic!
  108.44 +
  108.45 +for (var i = 0; i < LIMIT; i++) {
  108.46 +    // no __noSuchProperty__ and 'with' scope object has no 'foo'
  108.47 +    delete __noSuchProperty__;
  108.48 +    Assert.assertFalse(checkFoo(), "Expected false in iteration " + i);
  108.49 +
  108.50 +    // __noSuchProperty__ is exists but 'with' scope object has no 'foo'
  108.51 +    this.__noSuchProperty__ = oldNoSuchProperty;
  108.52 +    Assert.assertTrue(checkFoo(), "Expected true in iteration " + i);
  108.53 +}
   109.1 --- a/test/script/basic/JDK-8049086.js	Thu Sep 24 10:00:42 2015 -0700
   109.2 +++ b/test/script/basic/JDK-8049086.js	Thu Sep 24 10:09:56 2015 -0700
   109.3 @@ -58,7 +58,7 @@
   109.4  // (a) Java methods (b) Java classes (as these respond to new)
   109.5  // (c) FunctionalInterface objects (d) JSObjects that are 'functions'
   109.6  
   109.7 -print("java.awt.Color is java function? " + Java.isJavaFunction(java.awt.Color));
   109.8 +print("java.lang.String is java function? " + Java.isJavaFunction(java.lang.String));
   109.9  print("java.lang.Runnable instance is java function? "
  109.10      + Java.isJavaFunction(new java.lang.Runnable(function() {})));
  109.11  print("eval is java function? " + Java.isJavaFunction(eval));
   110.1 --- a/test/script/basic/JDK-8049086.js.EXPECTED	Thu Sep 24 10:00:42 2015 -0700
   110.2 +++ b/test/script/basic/JDK-8049086.js.EXPECTED	Thu Sep 24 10:09:56 2015 -0700
   110.3 @@ -13,7 +13,7 @@
   110.4  Object is script object? true
   110.5  {} is script object? true
   110.6  /foo/ is script object? true
   110.7 -java.awt.Color is java function? true
   110.8 +java.lang.String is java function? true
   110.9  java.lang.Runnable instance is java function? true
  110.10  eval is java function? false
  110.11  println is java function? true
   111.1 --- a/test/script/basic/JDK-8049242.js	Thu Sep 24 10:00:42 2015 -0700
   111.2 +++ b/test/script/basic/JDK-8049242.js	Thu Sep 24 10:09:56 2015 -0700
   111.3 @@ -29,14 +29,14 @@
   111.4   */
   111.5  
   111.6  // call explicit constructor
   111.7 -print(new (Java.type("java.awt.Color")["(int,int,int)"])(255,0,255));
   111.8 +print(new (Java.type("java.lang.String")["(char[],int,int)"])(['a', 'b', 'c'],0, 3));
   111.9  // print the constructor itself
  111.10 -print(Java.type("java.awt.Color")["(int,int,int)"]);
  111.11 +print(Java.type("java.lang.String")["(char[],int,int)"]);
  111.12  
  111.13  // store constructor to call later
  111.14 -var Color = Java.type("java.awt.Color")["(int,int,int)"];
  111.15 +var Color = Java.type("java.lang.String")["(char[],int,int)"];
  111.16  // call stored constructor
  111.17 -print(new Color(33, 233, 2))
  111.18 +print(new Color(['j', 'a', 'v', 'a'], 1, 3))
  111.19  
  111.20  // check if default constructor works
  111.21  var obj = new (Java.type("java.lang.Object")["()"])();
   112.1 --- a/test/script/basic/JDK-8049242.js.EXPECTED	Thu Sep 24 10:00:42 2015 -0700
   112.2 +++ b/test/script/basic/JDK-8049242.js.EXPECTED	Thu Sep 24 10:09:56 2015 -0700
   112.3 @@ -1,10 +1,10 @@
   112.4 -java.awt.Color[r=255,g=0,b=255]
   112.5 -[jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)]
   112.6 -java.awt.Color[r=33,g=233,b=2]
   112.7 +abc
   112.8 +[jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)]
   112.9 +ava
  112.10  TypeError: null is not a function
  112.11  TypeError: null is not a function
  112.12  TypeError: null is not a function
  112.13 -TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires "new".
  112.14 +TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] requires "new".
  112.15  TypeError: null is not a function
  112.16  TypeError: null is not a function
  112.17  java.lang.InstantiationException: java.io.InputStream
   113.1 --- a/test/script/basic/JDK-8053905.js	Thu Sep 24 10:00:42 2015 -0700
   113.2 +++ b/test/script/basic/JDK-8053905.js	Thu Sep 24 10:09:56 2015 -0700
   113.3 @@ -28,6 +28,7 @@
   113.4   * @runif external.octane
   113.5   * @fork
   113.6   * @option -Dnashorn.compiler.splitter.threshold=1000
   113.7 + * @option -Dnashorn.options.allowEagerCompilationSilentOverride
   113.8   * @option -scripting
   113.9   * @option --lazy-compilation=false
  113.10   */
   114.1 --- a/test/script/basic/JDK-8058561.js	Thu Sep 24 10:00:42 2015 -0700
   114.2 +++ b/test/script/basic/JDK-8058561.js	Thu Sep 24 10:09:56 2015 -0700
   114.3 @@ -26,7 +26,9 @@
   114.4   *
   114.5   * @test
   114.6   * @run
   114.7 + * @fork
   114.8   * @option --lazy-compilation=false
   114.9 + * @option -Dnashorn.options.allowEagerCompilationSilentOverride
  114.10   */
  114.11  
  114.12  // Just attempting to compile this caused the NPE
   115.1 --- a/test/script/basic/JDK-8078612_eager_1a.js	Thu Sep 24 10:00:42 2015 -0700
   115.2 +++ b/test/script/basic/JDK-8078612_eager_1a.js	Thu Sep 24 10:09:56 2015 -0700
   115.3 @@ -29,6 +29,7 @@
   115.4   * @option -pcc
   115.5   * @option --lazy-compilation=false
   115.6   * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   115.7 + * @option -Dnashorn.options.allowEagerCompilationSilentOverride
   115.8   * @fork
   115.9   */
  115.10  
   116.1 --- a/test/script/basic/JDK-8078612_eager_1b.js	Thu Sep 24 10:00:42 2015 -0700
   116.2 +++ b/test/script/basic/JDK-8078612_eager_1b.js	Thu Sep 24 10:09:56 2015 -0700
   116.3 @@ -29,6 +29,7 @@
   116.4   * @option -pcc
   116.5   * @option --lazy-compilation=false
   116.6   * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   116.7 + * @option -Dnashorn.options.allowEagerCompilationSilentOverride
   116.8   * @fork
   116.9   */
  116.10  
   117.1 --- a/test/script/basic/JDK-8078612_eager_2a.js	Thu Sep 24 10:00:42 2015 -0700
   117.2 +++ b/test/script/basic/JDK-8078612_eager_2a.js	Thu Sep 24 10:09:56 2015 -0700
   117.3 @@ -29,6 +29,7 @@
   117.4   * @option -pcc
   117.5   * @option --lazy-compilation=false
   117.6   * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   117.7 + * @option -Dnashorn.options.allowEagerCompilationSilentOverride
   117.8   * @fork
   117.9   */
  117.10  
   118.1 --- a/test/script/basic/JDK-8078612_eager_2b.js	Thu Sep 24 10:00:42 2015 -0700
   118.2 +++ b/test/script/basic/JDK-8078612_eager_2b.js	Thu Sep 24 10:09:56 2015 -0700
   118.3 @@ -29,6 +29,7 @@
   118.4   * @option -pcc
   118.5   * @option --lazy-compilation=false
   118.6   * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   118.7 + * @option -Dnashorn.options.allowEagerCompilationSilentOverride
   118.8   * @fork
   118.9   */
  118.10  
   119.1 --- a/test/script/basic/JDK-8079470.js.EXPECTED	Thu Sep 24 10:00:42 2015 -0700
   119.2 +++ b/test/script/basic/JDK-8079470.js.EXPECTED	Thu Sep 24 10:09:56 2015 -0700
   119.3 @@ -1,2 +1,2 @@
   119.4 -TypeError: Can not create new object with constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod File java.io.File.java.io.File(String,String)] with the passed arguments; they do not match any of its method signatures.
   119.5 -TypeError: Can not create new object with constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] with the passed arguments; they do not match any of its method signatures.
   119.6 +TypeError: Can not create new object with constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.io.File(String,String)] with the passed arguments; they do not match any of its method signatures.
   119.7 +TypeError: Can not create new object with constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.awt.Color(int,int,int)] with the passed arguments; they do not match any of its method signatures.
   120.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   120.2 +++ b/test/script/basic/JDK-8134939.js	Thu Sep 24 10:09:56 2015 -0700
   120.3 @@ -0,0 +1,43 @@
   120.4 +/*
   120.5 + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
   120.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   120.7 + * 
   120.8 + * This code is free software; you can redistribute it and/or modify it
   120.9 + * under the terms of the GNU General Public License version 2 only, as
  120.10 + * published by the Free Software Foundation.
  120.11 + * 
  120.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  120.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  120.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  120.15 + * version 2 for more details (a copy is included in the LICENSE file that
  120.16 + * accompanied this code).
  120.17 + * 
  120.18 + * You should have received a copy of the GNU General Public License version
  120.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  120.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  120.21 + * 
  120.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  120.23 + * or visit www.oracle.com if you need additional information or have any
  120.24 + * questions.
  120.25 + */
  120.26 +
  120.27 +/**
  120.28 + * JDK-8134939: Improve toString method of Dynalink OverloadedDynamicMethod
  120.29 + *
  120.30 + * @test
  120.31 + * @run
  120.32 + */
  120.33 +
  120.34 +var overloadedSetter = new (Java.type("jdk.nashorn.test.models.OverloadedSetter"));
  120.35 +
  120.36 +Assert.assertEquals(String(overloadedSetter.foo),
  120.37 +  "[jdk.internal.dynalink.beans.OverloadedDynamicMethod\n" +
  120.38 +  " String jdk.nashorn.test.models.OverloadedSetter.foo(String)\n" +
  120.39 +  " void jdk.nashorn.test.models.OverloadedSetter.foo(int)\n" +
  120.40 +  "]");
  120.41 +
  120.42 +Assert.assertEquals(String(overloadedSetter.setColor),
  120.43 +  "[jdk.internal.dynalink.beans.OverloadedDynamicMethod\n" +
  120.44 +  " void jdk.nashorn.test.models.OverloadedSetter.setColor(int)\n" +
  120.45 +  " void jdk.nashorn.test.models.OverloadedSetter.setColor(String)\n" +
  120.46 +  "]");
   121.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   121.2 +++ b/test/script/basic/JDK-8136544.js	Thu Sep 24 10:09:56 2015 -0700
   121.3 @@ -0,0 +1,65 @@
   121.4 +/*
   121.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   121.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   121.7 + *
   121.8 + * This code is free software; you can redistribute it and/or modify it
   121.9 + * under the terms of the GNU General Public License version 2 only, as
  121.10 + * published by the Free Software Foundation.
  121.11 + *
  121.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  121.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  121.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  121.15 + * version 2 for more details (a copy is included in the LICENSE file that
  121.16 + * accompanied this code).
  121.17 + *
  121.18 + * You should have received a copy of the GNU General Public License version
  121.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  121.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  121.21 + *
  121.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  121.23 + * or visit www.oracle.com if you need additional information or have any
  121.24 + * questions.
  121.25 + */
  121.26 +
  121.27 +/**
  121.28 + * JDK-8136544: Call site switching to megamorphic causes incorrect property read
  121.29 + *
  121.30 + * @test
  121.31 + * @fork
  121.32 + * @option -Dnashorn.unstable.relink.threshold=8
  121.33 + * @run
  121.34 + */
  121.35 +
  121.36 +var ScriptContext = Java.type("javax.script.ScriptContext");
  121.37 +var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
  121.38 +var m = new ScriptEngineManager();
  121.39 +var e = m.getEngineByName("nashorn");
  121.40 +
  121.41 +var scope = e.getBindings(ScriptContext.ENGINE_SCOPE);
  121.42 +var MYVAR = "myvar";
  121.43 +
  121.44 +function loopupVar() {
  121.45 +    try {
  121.46 +        e.eval(MYVAR);
  121.47 +        return true;
  121.48 +    } catch (e) {
  121.49 +        return false;
  121.50 +    }
  121.51 +}
  121.52 +
  121.53 +// make sure we exercise callsite beyond megamorphic threshold we set
  121.54 +// in this test via nashorn.unstable.relink.threshold property
  121.55 +// In each iteration, callsite is exercised twice (two evals)
  121.56 +// So, LIMIT should be more than 4 to exercise megamorphic callsites.
  121.57 +
  121.58 +var LIMIT = 5; // This LIMIT should be more than 4
  121.59 +
  121.60 +for (var i = 0; i < LIMIT; i++) {
  121.61 +    // remove the variable and lookup
  121.62 +    delete scope[MYVAR];
  121.63 +    Assert.assertFalse(loopupVar(), "Expected true in iteration " + i);
  121.64 +
  121.65 +    // set that variable and check again
  121.66 +    scope[MYVAR] = "foo";
  121.67 +    Assert.assertTrue(loopupVar(), "Expected false in iteration " + i);
  121.68 +}
   122.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   122.2 +++ b/test/script/basic/JDK-8136694.js	Thu Sep 24 10:09:56 2015 -0700
   122.3 @@ -0,0 +1,74 @@
   122.4 +/*
   122.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   122.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   122.7 + *
   122.8 + * This code is free software; you can redistribute it and/or modify it
   122.9 + * under the terms of the GNU General Public License version 2 only, as
  122.10 + * published by the Free Software Foundation.
  122.11 + *
  122.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  122.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  122.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  122.15 + * version 2 for more details (a copy is included in the LICENSE file that
  122.16 + * accompanied this code).
  122.17 + *
  122.18 + * You should have received a copy of the GNU General Public License version
  122.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  122.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  122.21 + *
  122.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  122.23 + * or visit www.oracle.com if you need additional information or have any
  122.24 + * questions.
  122.25 + */
  122.26 +
  122.27 +/**
  122.28 + * JDK-8136694: Megemorphic scope access does not throw ReferenceError when property is missing
  122.29 + *
  122.30 + * @test
  122.31 + * @fork
  122.32 + * @option -Dnashorn.unstable.relink.threshold=16
  122.33 + * @run
  122.34 + */
  122.35 +
  122.36 +function checkFoo() {
  122.37 +    try {
  122.38 +        // The 'foo' access becomes megamorphic
  122.39 +        foo;
  122.40 +        return true;
  122.41 +    } catch (e) {
  122.42 +        return false;
  122.43 +    }
  122.44 +}
  122.45 +
  122.46 +
  122.47 +// Similar check for 'with' blocks as well.
  122.48 +function checkFooInWith() {
  122.49 +    with({}) {
  122.50 +        try {
  122.51 +            // The 'foo' access becomes megamorphic
  122.52 +            foo;
  122.53 +            return true;
  122.54 +        } catch (e) {
  122.55 +            return false;
  122.56 +        }
  122.57 +    }
  122.58 +}
  122.59 +
  122.60 +function loop(checker) {
  122.61 +    // LIMIT has to be more than the megamorphic threashold
  122.62 +    // set via @option in this test header!
  122.63 +    var LIMIT = 20;
  122.64 +    for (var i = 0; i < LIMIT; i++) {
  122.65 +        // make sure global has no "foo"
  122.66 +        delete foo;
  122.67 +        Assert.assertFalse(checker(), "Expected false in interation " + i);
  122.68 +
  122.69 +        // now add 'foo' in global
  122.70 +        foo = 44;
  122.71 +        Assert.assertTrue(checker(), "Expected true in interation " + i);
  122.72 +    }
  122.73 +}
  122.74 +
  122.75 +
  122.76 +loop(checkFoo);
  122.77 +loop(checkFooInWith);
   123.1 --- a/test/script/basic/javaarrayconversion.js	Thu Sep 24 10:00:42 2015 -0700
   123.2 +++ b/test/script/basic/javaarrayconversion.js	Thu Sep 24 10:09:56 2015 -0700
   123.3 @@ -128,24 +128,32 @@
   123.4  // Converting to string, toString takes precedence over valueOf
   123.5  test({ valueOf: function() { return "42"; },  toString: function() { return "43"; } }, "java.lang.String", "43")
   123.6  
   123.7 +function assertCanConvert(sourceType, targetType) {
   123.8 +  Java.to([new (Java.type(sourceType))()], targetType + "[]")
   123.9 +  ++testCount;
  123.10 +}
  123.11 +
  123.12  function assertCantConvert(sourceType, targetType) {
  123.13    try {
  123.14 -    Java.to([new Java.type(sourceType)()], targetType + "[]")
  123.15 +    Java.to([new (Java.type(sourceType))()], targetType + "[]")
  123.16      throw "no TypeError encountered"
  123.17    } catch(e) {
  123.18 -      if(!(e instanceof TypeError)) {
  123.19 +      if(!(e instanceof TypeError) ||
  123.20 +          !e.message.startsWith("Java.to conversion to array type")) {
  123.21          throw e;
  123.22        }
  123.23        ++testCount;
  123.24    }
  123.25  }
  123.26  
  123.27 +// Arbitrary POJOs to JS Primitive type should work
  123.28 +assertCanConvert("java.util.BitSet", "int")
  123.29 +assertCanConvert("java.util.BitSet", "double")
  123.30 +assertCanConvert("java.util.BitSet", "long")
  123.31 +assertCanConvert("java.util.BitSet", "boolean")
  123.32 +assertCanConvert("java.util.BitSet", "java.lang.String")
  123.33 +
  123.34  // Arbitrary POJOs can't be converted to Java values
  123.35 -assertCantConvert("java.util.BitSet", "int")
  123.36 -assertCantConvert("java.util.BitSet", "double")
  123.37 -assertCantConvert("java.util.BitSet", "long")
  123.38 -assertCantConvert("java.util.BitSet", "boolean")
  123.39 -assertCantConvert("java.util.BitSet", "java.lang.String")
  123.40  assertCantConvert("java.util.BitSet", "java.lang.Double")
  123.41  assertCantConvert("java.util.BitSet", "java.lang.Long")
  123.42  
   124.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   124.2 +++ b/test/script/trusted/JDK-8087292.js	Thu Sep 24 10:09:56 2015 -0700
   124.3 @@ -0,0 +1,54 @@
   124.4 +/*
   124.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   124.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   124.7 + *
   124.8 + * This code is free software; you can redistribute it and/or modify it
   124.9 + * under the terms of the GNU General Public License version 2 only, as
  124.10 + * published by the Free Software Foundation.
  124.11 + *
  124.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  124.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  124.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  124.15 + * version 2 for more details (a copy is included in the LICENSE file that
  124.16 + * accompanied this code).
  124.17 + *
  124.18 + * You should have received a copy of the GNU General Public License version
  124.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  124.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  124.21 + *
  124.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  124.23 + * or visit www.oracle.com if you need additional information or have any
  124.24 + * questions.
  124.25 + */
  124.26 +
  124.27 +/**
  124.28 + * JDK-8087292: nashorn should have a "fail-fast" option for scripting, analog to bash "set -e"
  124.29 + *
  124.30 + * @test
  124.31 + * @option -scripting
  124.32 + * @run
  124.33 + */
  124.34 +
  124.35 +function tryExec() {
  124.36 +    try {
  124.37 +        `java`
  124.38 +    } catch (e) {
  124.39 +        print(e);
  124.40 +    }
  124.41 +
  124.42 +    // make sure we got non-zero ("failure") exit code!
  124.43 +    if ($EXIT == 0) {
  124.44 +        print("Error: expected $EXIT code to be non-zero");
  124.45 +    }
  124.46 +}
  124.47 +
  124.48 +// no exception now!
  124.49 +tryExec();
  124.50 +
  124.51 +// turn on error with non-zero exit code
  124.52 +$EXEC.throwOnError = true;
  124.53 +tryExec();
  124.54 +
  124.55 +// no exception after this
  124.56 +$EXEC.throwOnError = false;
  124.57 +tryExec();
   125.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   125.2 +++ b/test/script/trusted/JDK-8087292.js.EXPECTED	Thu Sep 24 10:09:56 2015 -0700
   125.3 @@ -0,0 +1,1 @@
   125.4 +RangeError: $EXEC returned non-zero exit code: 1
   126.1 --- a/test/script/trusted/classfilter.js.EXPECTED	Thu Sep 24 10:00:42 2015 -0700
   126.2 +++ b/test/script/trusted/classfilter.js.EXPECTED	Thu Sep 24 10:09:56 2015 -0700
   126.3 @@ -4,7 +4,18 @@
   126.4  typeof java.util.Map evalutes to function
   126.5  typeof java.util.HashMap evalutes to function
   126.6  var m = new java.util.HashMap(); m.put('foo', 42); m evalutes to {foo=42}
   126.7 -java.lang.System.out.println evalutes to [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println]
   126.8 +java.lang.System.out.println evalutes to [jdk.internal.dynalink.beans.OverloadedDynamicMethod
   126.9 + void java.io.PrintStream.println()
  126.10 + void java.io.PrintStream.println(boolean)
  126.11 + void java.io.PrintStream.println(char)
  126.12 + void java.io.PrintStream.println(char[])
  126.13 + void java.io.PrintStream.println(double)
  126.14 + void java.io.PrintStream.println(float)
  126.15 + void java.io.PrintStream.println(int)
  126.16 + void java.io.PrintStream.println(long)
  126.17 + void java.io.PrintStream.println(Object)
  126.18 + void java.io.PrintStream.println(String)
  126.19 +]
  126.20  java.lang.System.exit evalutes to [jdk.internal.dynalink.beans.SimpleDynamicMethod void java.lang.System.exit(int)]
  126.21  new javax.script.SimpleBindings throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.SimpleBindings
  126.22  Java.type('javax.script.ScriptContext') throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.ScriptContext
   127.1 --- a/test/src/jdk/nashorn/api/scripting/test/ScopeTest.java	Thu Sep 24 10:00:42 2015 -0700
   127.2 +++ b/test/src/jdk/nashorn/api/scripting/test/ScopeTest.java	Thu Sep 24 10:09:56 2015 -0700
   127.3 @@ -26,6 +26,7 @@
   127.4  
   127.5  import static org.testng.Assert.assertEquals;
   127.6  import static org.testng.Assert.assertNotNull;
   127.7 +import static org.testng.Assert.assertFalse;
   127.8  import static org.testng.Assert.assertTrue;
   127.9  import static org.testng.Assert.fail;
  127.10  import javax.script.Bindings;
  127.11 @@ -820,4 +821,38 @@
  127.12      public void recursiveEvalCallScriptContextTest() throws ScriptException {
  127.13          new RecursiveEval().program();
  127.14      }
  127.15 +
  127.16 +    private static final String VAR_NAME = "myvar";
  127.17 +
  127.18 +    private static boolean lookupVar(final ScriptEngine engine, final String varName) {
  127.19 +        try {
  127.20 +            engine.eval(varName);
  127.21 +            return true;
  127.22 +        } catch (final ScriptException se) {
  127.23 +            return false;
  127.24 +        }
  127.25 +    }
  127.26 +
  127.27 +    // @bug 8136544: Call site switching to megamorphic causes incorrect property read
  127.28 +    @Test
  127.29 +    public void megamorphicPropertyReadTest() throws ScriptException {
  127.30 +        final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
  127.31 +        final ScriptEngine engine = factory.getScriptEngine();
  127.32 +        final Bindings scope = engine.getBindings(ScriptContext.ENGINE_SCOPE);
  127.33 +        boolean ret;
  127.34 +
  127.35 +        // Why 16 is the upper limit of this loop? The default nashorn dynalink megamorphic threshold is 16.
  127.36 +        // See jdk.nashorn.internal.runtime.linker.Bootstrap.NASHORN_DEFAULT_UNSTABLE_RELINK_THRESHOLD
  127.37 +        // We do, 'eval' of the same in this loop twice. So, 16*2 = 32 times that callsite in the script
  127.38 +        // is exercised - much beyond the default megamorphic threshold.
  127.39 +
  127.40 +        for (int i = 0; i < 16; i++) {
  127.41 +            scope.remove(VAR_NAME);
  127.42 +            ret = lookupVar(engine, VAR_NAME);
  127.43 +            assertFalse(ret, "Expected false in iteration " + i);
  127.44 +            scope.put(VAR_NAME, "foo");
  127.45 +            ret = lookupVar(engine, VAR_NAME);
  127.46 +            assertTrue(ret, "Expected true in iteration " + i);
  127.47 +        }
  127.48 +    }
  127.49  }

mercurial