src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Splitter.java
author hannesw
Wed, 20 Dec 2017 21:40:11 +0100
changeset 48380 597f69e5f1e3
parent 47949 002e99dd12f2
permissions -rw-r--r--
8193508: Expressions in split literals must never be optimistic Reviewed-by: jlaskey, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.codegen;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    30
import java.util.ArrayList;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
import java.util.HashMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import java.util.List;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import java.util.Map;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import jdk.nashorn.internal.ir.Block;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    35
import jdk.nashorn.internal.ir.FunctionNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    36
import jdk.nashorn.internal.ir.LiteralNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import jdk.nashorn.internal.ir.Node;
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
    39
import jdk.nashorn.internal.ir.ObjectNode;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
    40
import jdk.nashorn.internal.ir.PropertyNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
import jdk.nashorn.internal.ir.SplitNode;
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
    42
import jdk.nashorn.internal.ir.Splittable;
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
    43
import jdk.nashorn.internal.ir.Statement;
47949
002e99dd12f2 8059835: Optimistic splitting doesn't work with let and const
hannesw
parents: 47216
diff changeset
    44
import jdk.nashorn.internal.ir.VarNode;
32888
24f99be3d5ab 8134502: introduce abstraction for basic NodeVisitor usage
attila
parents: 32781
diff changeset
    45
import jdk.nashorn.internal.ir.visitor.SimpleNodeVisitor;
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    46
import jdk.nashorn.internal.runtime.Context;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24731
diff changeset
    47
import jdk.nashorn.internal.runtime.logging.DebugLogger;
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    48
import jdk.nashorn.internal.runtime.logging.Loggable;
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    49
import jdk.nashorn.internal.runtime.logging.Logger;
16168
f0c208287983 8005976: Break out AccessSpecializer into one pass before CodeGenerator instead of iterative applications from CodeGenerator
lagergren
parents: 16152
diff changeset
    50
import jdk.nashorn.internal.runtime.options.Options;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
 * Split the IR into smaller compile units.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
 */
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    55
@Logger(name="splitter")
32888
24f99be3d5ab 8134502: introduce abstraction for basic NodeVisitor usage
attila
parents: 32781
diff changeset
    56
final class Splitter extends SimpleNodeVisitor implements Loggable {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
    /** Current compiler. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
    private final Compiler compiler;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    59
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    60
    /** IR to be broken down. */
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17524
diff changeset
    61
    private final FunctionNode outermost;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
    /** Compile unit for the main script. */
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
    64
    private final CompileUnit outermostCompileUnit;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    66
    /** Cache for calculated block weights. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    67
    private final Map<Node, Long> weightCache = new HashMap<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
    /** Weight threshold for when to start a split. */
16168
f0c208287983 8005976: Break out AccessSpecializer into one pass before CodeGenerator instead of iterative applications from CodeGenerator
lagergren
parents: 16152
diff changeset
    70
    public static final long SPLIT_THRESHOLD = Options.getIntProperty("nashorn.compiler.splitter.threshold", 32 * 1024);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24731
diff changeset
    72
    private final DebugLogger log;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24731
diff changeset
    73
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
     * Constructor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
     *
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
    77
     * @param compiler              the compiler
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
    78
     * @param functionNode          function node to split
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
    79
     * @param outermostCompileUnit  compile unit for outermost function, if non-lazy this is the script's compile unit
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
     */
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
    81
    public Splitter(final Compiler compiler, final FunctionNode functionNode, final CompileUnit outermostCompileUnit) {
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
    82
        this.compiler             = compiler;
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17233
diff changeset
    83
        this.outermost            = functionNode;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
    84
        this.outermostCompileUnit = outermostCompileUnit;
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    85
        this.log                  = initLogger(compiler.getContext());
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    86
    }
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    87
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    88
    @Override
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    89
    public DebugLogger initLogger(final Context context) {
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    90
        return context.getLogger(this.getClass());
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    91
    }
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    92
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    93
    @Override
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    94
    public DebugLogger getLogger() {
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    95
        return log;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    96
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    97
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    99
     * Execute the split.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   100
     * @param fn the function to split
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   101
     * @param top whether this is the topmost compiled function (it's either a program, or we're doing a recompilation).
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   102
     */
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24719
diff changeset
   103
    FunctionNode split(final FunctionNode fn, final boolean top) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   104
        FunctionNode functionNode = fn;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   105
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
   106
        log.fine("Initiating split of '", functionNode.getName(), "'");
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   107
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
        long weight = WeighNodes.weigh(functionNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   110
        // We know that our LexicalContext is empty outside the call to functionNode.accept(this) below,
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   111
        // so we can pass null to all methods expecting a LexicalContext parameter.
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   112
        assert lc.isEmpty() : "LexicalContext not empty";
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   113
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   114
        if (weight >= SPLIT_THRESHOLD) {
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   115
            log.info("Splitting function '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   116
            functionNode = (FunctionNode)functionNode.accept(this);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   117
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
            if (functionNode.isSplit()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   119
                // Weight has changed so weigh again, this time using block weight cache
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
                weight = WeighNodes.weigh(functionNode, weightCache);
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   121
                functionNode = functionNode.setBody(null, functionNode.getBody().setNeedsScope(null));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   124
            if (weight >= SPLIT_THRESHOLD) {
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   125
                functionNode = functionNode.setBody(null, splitBlock(functionNode.getBody(), functionNode));
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   126
                functionNode = functionNode.setFlag(null, FunctionNode.IS_SPLIT);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   127
                weight = WeighNodes.weigh(functionNode.getBody(), weightCache);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   128
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   129
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   130
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   131
        assert functionNode.getCompileUnit() == null : "compile unit already set for " + functionNode.getName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   132
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   133
        if (top) {
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
   134
            assert outermostCompileUnit != null : "outermost compile unit is null";
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   135
            functionNode = functionNode.setCompileUnit(null, outermostCompileUnit);
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
   136
            outermostCompileUnit.addWeight(weight + WeighNodes.FUNCTION_WEIGHT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   137
        } else {
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   138
            functionNode = functionNode.setCompileUnit(null, findUnit(weight));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   139
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   140
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   141
        final Block body = functionNode.getBody();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   142
        final List<FunctionNode> dc = directChildren(functionNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   143
32888
24f99be3d5ab 8134502: introduce abstraction for basic NodeVisitor usage
attila
parents: 32781
diff changeset
   144
        final Block newBody = (Block)body.accept(new SimpleNodeVisitor() {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   145
            @Override
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   146
            public boolean enterFunctionNode(final FunctionNode nestedFunction) {
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   147
                return dc.contains(nestedFunction);
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   148
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   149
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   150
            @Override
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   151
            public Node leaveFunctionNode(final FunctionNode nestedFunction) {
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24719
diff changeset
   152
                final FunctionNode split = new Splitter(compiler, nestedFunction, outermostCompileUnit).split(nestedFunction, false);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17524
diff changeset
   153
                lc.replace(nestedFunction, split);
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   154
                return split;
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   155
            }
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   156
        });
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   157
        functionNode = functionNode.setBody(null, newBody);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   158
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   159
        assert functionNode.getCompileUnit() != null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   160
32692
8f60bd284bf4 8055917: jdk.nashorn.internal.codegen.CompilationPhase$N should be renamed to proper classes
sundar
parents: 31195
diff changeset
   161
        return functionNode;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   162
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   163
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   164
    private static List<FunctionNode> directChildren(final FunctionNode functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   165
        final List<FunctionNode> dc = new ArrayList<>();
32888
24f99be3d5ab 8134502: introduce abstraction for basic NodeVisitor usage
attila
parents: 32781
diff changeset
   166
        functionNode.accept(new SimpleNodeVisitor() {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   167
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   168
            public boolean enterFunctionNode(final FunctionNode child) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   169
                if (child == functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   170
                    return true;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   171
                }
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17524
diff changeset
   172
                if (lc.getParentFunction(child) == functionNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   173
                    dc.add(child);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   174
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   175
                return false;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   176
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   177
        });
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   178
        return dc;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   179
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   180
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   181
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   182
     * Override this logic to look up compile units in a different way
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   183
     * @param weight weight needed
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
     * @return compile unit
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
    protected CompileUnit findUnit(final long weight) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
        return compiler.findUnit(weight);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   189
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   190
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   191
     * Split a block into sub methods.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   192
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   193
     * @param block Block or function to split.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   194
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   195
     * @return new weight for the resulting block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   196
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   197
    private Block splitBlock(final Block block, final FunctionNode function) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   198
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   199
        final List<Statement> splits = new ArrayList<>();
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   200
        List<Statement> statements = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   201
        long statementsWeight = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   202
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   203
        for (final Statement statement : block.getStatements()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
            final long weight = WeighNodes.weigh(statement, weightCache);
47949
002e99dd12f2 8059835: Optimistic splitting doesn't work with let and const
hannesw
parents: 47216
diff changeset
   205
            final boolean isBlockScopedVarNode = isBlockScopedVarNode(statement);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   206
47949
002e99dd12f2 8059835: Optimistic splitting doesn't work with let and const
hannesw
parents: 47216
diff changeset
   207
            if (statementsWeight + weight >= SPLIT_THRESHOLD || statement.isTerminal() || isBlockScopedVarNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   208
                if (!statements.isEmpty()) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   209
                    splits.add(createBlockSplitNode(block, function, statements, statementsWeight));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   210
                    statements = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   211
                    statementsWeight = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   212
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   213
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   214
47949
002e99dd12f2 8059835: Optimistic splitting doesn't work with let and const
hannesw
parents: 47216
diff changeset
   215
            if (statement.isTerminal() || isBlockScopedVarNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   216
                splits.add(statement);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   217
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   218
                statements.add(statement);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   219
                statementsWeight += weight;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   222
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   223
        if (!statements.isEmpty()) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   224
            splits.add(createBlockSplitNode(block, function, statements, statementsWeight));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   225
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   226
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17524
diff changeset
   227
        return block.setStatements(lc, splits);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   229
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   230
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   231
     * Create a new split node from statements contained in a parent block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   232
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   233
     * @param parent     Parent block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   234
     * @param statements Statements to include.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   236
     * @return New split node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
     */
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   238
    private SplitNode createBlockSplitNode(final Block parent, final FunctionNode function, final List<Statement> statements, final long weight) {
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   239
        final long   token      = parent.getToken();
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   240
        final int    finish     = parent.getFinish();
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   241
        final String name       = function.uniqueName(SPLIT_PREFIX.symbolName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   243
        final Block newBlock = new Block(token, finish, statements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   244
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   245
        return new SplitNode(name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   246
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   247
47949
002e99dd12f2 8059835: Optimistic splitting doesn't work with let and const
hannesw
parents: 47216
diff changeset
   248
    private boolean isBlockScopedVarNode(final Statement statement) {
002e99dd12f2 8059835: Optimistic splitting doesn't work with let and const
hannesw
parents: 47216
diff changeset
   249
        return statement instanceof VarNode && ((VarNode) statement).isBlockScoped();
002e99dd12f2 8059835: Optimistic splitting doesn't work with let and const
hannesw
parents: 47216
diff changeset
   250
    }
002e99dd12f2 8059835: Optimistic splitting doesn't work with let and const
hannesw
parents: 47216
diff changeset
   251
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   252
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   253
    public boolean enterBlock(final Block block) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   254
        if (block.isCatchBlock()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   255
            return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   256
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   257
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   258
        final long weight = WeighNodes.weigh(block, weightCache);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   259
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   260
        if (weight < SPLIT_THRESHOLD) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   261
            weightCache.put(block, weight);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   262
            return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   263
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   264
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   265
        return true;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   266
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   267
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   268
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   269
    public Node leaveBlock(final Block block) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   270
        assert !block.isCatchBlock();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   271
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   272
        Block newBlock = block;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   273
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   274
        // Block was heavier than SLIT_THRESHOLD in enter, but a sub-block may have
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   275
        // been split already, so weigh again before splitting.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   276
        long weight = WeighNodes.weigh(block, weightCache);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   277
        if (weight >= SPLIT_THRESHOLD) {
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   278
            final FunctionNode currentFunction = lc.getCurrentFunction();
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   279
            newBlock = splitBlock(block, currentFunction);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   280
            weight   = WeighNodes.weigh(newBlock, weightCache);
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   281
            lc.setFlag(currentFunction, FunctionNode.IS_SPLIT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   282
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   283
        weightCache.put(newBlock, weight);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   284
        return newBlock;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   285
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   286
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   287
    @SuppressWarnings("rawtypes")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   288
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   289
    public Node leaveLiteralNode(final LiteralNode literal) {
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   290
        final long weight = WeighNodes.weigh(literal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   291
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   292
        if (weight < SPLIT_THRESHOLD) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   293
            return literal;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   294
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   295
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17524
diff changeset
   296
        final FunctionNode functionNode = lc.getCurrentFunction();
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17233
diff changeset
   297
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17524
diff changeset
   298
        lc.setFlag(functionNode, FunctionNode.IS_SPLIT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   299
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   300
        if (literal instanceof ArrayLiteralNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   301
            final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode) literal;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   302
            final Node[]           value            = arrayLiteralNode.getValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   303
            final int[]            postsets         = arrayLiteralNode.getPostsets();
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   304
            final List<Splittable.SplitRange> ranges = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   305
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   306
            long totalWeight = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   307
            int  lo          = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   308
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   309
            for (int i = 0; i < postsets.length; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   310
                final int  postset = postsets[i];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   311
                final Node element = value[postset];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   312
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   313
                final long elementWeight = WeighNodes.weigh(element);
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   314
                totalWeight += WeighNodes.AASTORE_WEIGHT + elementWeight;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   315
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   316
                if (totalWeight >= SPLIT_THRESHOLD) {
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   317
                    final CompileUnit unit = compiler.findUnit(totalWeight - elementWeight);
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   318
                    ranges.add(new Splittable.SplitRange(unit, lo, i));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   319
                    lo = i;
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   320
                    totalWeight = elementWeight;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   321
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   322
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   323
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   324
            if (lo != postsets.length) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   325
                final CompileUnit unit = compiler.findUnit(totalWeight);
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   326
                ranges.add(new Splittable.SplitRange(unit, lo, postsets.length));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   327
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   328
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   329
            log.info("Splitting array literal in '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   330
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   331
            return arrayLiteralNode.setSplitRanges(lc, ranges);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   332
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   333
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   334
        return literal;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   335
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   336
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   337
    @Override
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   338
    public Node leaveObjectNode(final ObjectNode objectNode) {
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   339
        final long weight = WeighNodes.weigh(objectNode);
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   340
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   341
        if (weight < SPLIT_THRESHOLD) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   342
            return objectNode;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   343
        }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   344
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   345
        final FunctionNode functionNode = lc.getCurrentFunction();
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   346
        lc.setFlag(functionNode, FunctionNode.IS_SPLIT);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   347
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   348
        final List<Splittable.SplitRange> ranges        = new ArrayList<>();
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   349
        final List<PropertyNode>          properties    = objectNode.getElements();
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   350
        final boolean                     isSpillObject = properties.size() > CodeGenerator.OBJECT_SPILL_THRESHOLD;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   351
        long totalWeight = 0;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   352
        int  lo          = 0;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   353
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   354
        for (int i = 0; i < properties.size(); i++) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   355
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   356
            final PropertyNode property = properties.get(i);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   357
            final boolean isConstant = LiteralNode.isConstant(property.getValue());
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   358
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   359
            if (!isConstant || !isSpillObject) {
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   360
                final long propertyWeight = isConstant ? 0 : WeighNodes.weigh(property.getValue());
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   361
                totalWeight += WeighNodes.AASTORE_WEIGHT + propertyWeight;
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   362
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   363
                if (totalWeight >= SPLIT_THRESHOLD) {
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   364
                    final CompileUnit unit = compiler.findUnit(totalWeight - propertyWeight);
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   365
                    ranges.add(new Splittable.SplitRange(unit, lo, i));
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   366
                    lo = i;
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   367
                    totalWeight = propertyWeight;
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   368
                }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   369
            }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   370
        }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   371
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   372
        if (lo != properties.size()) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   373
            final CompileUnit unit = compiler.findUnit(totalWeight);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   374
            ranges.add(new Splittable.SplitRange(unit, lo, properties.size()));
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   375
        }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   376
48380
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   377
        log.info("Splitting object node in '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
597f69e5f1e3 8193508: Expressions in split literals must never be optimistic
hannesw
parents: 47949
diff changeset
   378
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   379
        return objectNode.setSplitRanges(lc, ranges);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   380
    }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   381
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   382
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   383
    public boolean enterFunctionNode(final FunctionNode node) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   384
        //only go into the function node for this splitter. any subfunctions are rejected
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   385
        return node == outermost;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   386
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   387
}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   388