nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Splitter.java
author hannesw
Sat, 19 Sep 2015 16:04:28 +0200
changeset 32781 d8f34ffbbc7a
parent 32692 8f60bd284bf4
child 32888 24f99be3d5ab
permissions -rw-r--r--
8135190: Method code too large in Babel browser.js script Reviewed-by: attila, 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;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
    36
import jdk.nashorn.internal.ir.LexicalContext;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
import jdk.nashorn.internal.ir.LiteralNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    39
import jdk.nashorn.internal.ir.Node;
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
    40
import jdk.nashorn.internal.ir.ObjectNode;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
    41
import jdk.nashorn.internal.ir.PropertyNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
import jdk.nashorn.internal.ir.SplitNode;
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
    43
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
    44
import jdk.nashorn.internal.ir.Statement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
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")
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    56
final class Splitter extends NodeVisitor<LexicalContext> 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) {
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
    82
        super(new LexicalContext());
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
    83
        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
    84
        this.outermost            = functionNode;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
    85
        this.outermostCompileUnit = outermostCompileUnit;
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    86
        this.log                  = initLogger(compiler.getContext());
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
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    89
    @Override
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    90
    public DebugLogger initLogger(final Context context) {
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    91
        return context.getLogger(this.getClass());
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
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    94
    @Override
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    95
    public DebugLogger getLogger() {
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
    96
        return log;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    97
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   100
     * Execute the split.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   101
     * @param fn the function to split
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   102
     * @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
   103
     */
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
   104
    FunctionNode split(final FunctionNode fn, final boolean top) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   105
        FunctionNode functionNode = fn;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   106
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
   107
        log.fine("Initiating split of '", functionNode.getName(), "'");
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   108
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
        long weight = WeighNodes.weigh(functionNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   110
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   111
        // 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
   112
        // 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
   113
        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
   114
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   115
        if (weight >= SPLIT_THRESHOLD) {
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 25865
diff changeset
   116
            log.info("Splitting '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   117
            functionNode = (FunctionNode)functionNode.accept(this);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   119
            if (functionNode.isSplit()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
                // Weight has changed so weigh again, this time using block weight cache
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   121
                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
   122
                functionNode = functionNode.setBody(null, functionNode.getBody().setNeedsScope(null));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   124
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   125
            if (weight >= SPLIT_THRESHOLD) {
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   126
                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
   127
                functionNode = functionNode.setFlag(null, FunctionNode.IS_SPLIT);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   128
                weight = WeighNodes.weigh(functionNode.getBody(), weightCache);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   129
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   130
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   131
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   132
        assert functionNode.getCompileUnit() == null : "compile unit already set for " + functionNode.getName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   133
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   134
        if (top) {
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
   135
            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
   136
            functionNode = functionNode.setCompileUnit(null, outermostCompileUnit);
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16168
diff changeset
   137
            outermostCompileUnit.addWeight(weight + WeighNodes.FUNCTION_WEIGHT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   138
        } else {
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   139
            functionNode = functionNode.setCompileUnit(null, findUnit(weight));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   140
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   141
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   142
        final Block body = functionNode.getBody();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   143
        final List<FunctionNode> dc = directChildren(functionNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   144
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
   145
        final Block newBody = (Block)body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
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
   146
            @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
   147
            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
   148
                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
   149
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   150
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
   151
            @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
   152
            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
   153
                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
   154
                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
   155
                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
   156
            }
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
   157
        });
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   158
        functionNode = functionNode.setBody(null, newBody);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   159
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   160
        assert functionNode.getCompileUnit() != null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   161
32692
8f60bd284bf4 8055917: jdk.nashorn.internal.codegen.CompilationPhase$N should be renamed to proper classes
sundar
parents: 31195
diff changeset
   162
        return functionNode;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   163
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   164
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   165
    private static List<FunctionNode> directChildren(final FunctionNode functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   166
        final List<FunctionNode> dc = new ArrayList<>();
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
   167
        functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   168
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   169
            public boolean enterFunctionNode(final FunctionNode child) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   170
                if (child == functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   171
                    return true;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   172
                }
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
   173
                if (lc.getParentFunction(child) == functionNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   174
                    dc.add(child);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   175
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   176
                return false;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   177
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   178
        });
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   179
        return dc;
16147
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
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   183
     * Override this logic to look up compile units in a different way
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
     * @param weight weight needed
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
     * @return compile unit
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
    protected CompileUnit findUnit(final long weight) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
        return compiler.findUnit(weight);
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
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   192
     * Split a block into sub methods.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   193
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   194
     * @param block Block or function to split.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   195
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   196
     * @return new weight for the resulting block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   197
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   198
    private Block splitBlock(final Block block, final FunctionNode function) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   199
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
   200
        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
   201
        List<Statement> statements = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   202
        long statementsWeight = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   203
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
   204
        for (final Statement statement : block.getStatements()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   205
            final long weight = WeighNodes.weigh(statement, weightCache);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   206
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   207
            if (statementsWeight + weight >= SPLIT_THRESHOLD || statement.isTerminal()) {
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
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   215
            if (statement.isTerminal()) {
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
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   248
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   249
    public boolean enterBlock(final Block block) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   250
        if (block.isCatchBlock()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   251
            return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   252
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   253
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   254
        final long weight = WeighNodes.weigh(block, weightCache);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   255
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   256
        if (weight < SPLIT_THRESHOLD) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   257
            weightCache.put(block, weight);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   258
            return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   259
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   260
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   261
        return true;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   262
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   263
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   264
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   265
    public Node leaveBlock(final Block block) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   266
        assert !block.isCatchBlock();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   267
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   268
        Block newBlock = block;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   269
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   270
        // Block was heavier than SLIT_THRESHOLD in enter, but a sub-block may have
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   271
        // been split already, so weigh again before splitting.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   272
        long weight = WeighNodes.weigh(block, weightCache);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   273
        if (weight >= SPLIT_THRESHOLD) {
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   274
            final FunctionNode currentFunction = lc.getCurrentFunction();
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   275
            newBlock = splitBlock(block, currentFunction);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   276
            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
   277
            lc.setFlag(currentFunction, FunctionNode.IS_SPLIT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   278
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   279
        weightCache.put(newBlock, weight);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   280
        return newBlock;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   281
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   282
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   283
    @SuppressWarnings("rawtypes")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   284
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16523
diff changeset
   285
    public Node leaveLiteralNode(final LiteralNode literal) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   286
        long weight = WeighNodes.weigh(literal);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   287
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   288
        if (weight < SPLIT_THRESHOLD) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   289
            return literal;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   290
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   291
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
   292
        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
   293
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
   294
        lc.setFlag(functionNode, FunctionNode.IS_SPLIT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   295
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   296
        if (literal instanceof ArrayLiteralNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   297
            final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode) literal;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   298
            final Node[]           value            = arrayLiteralNode.getValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   299
            final int[]            postsets         = arrayLiteralNode.getPostsets();
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   300
            final List<Splittable.SplitRange> ranges = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   301
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   302
            long totalWeight = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   303
            int  lo          = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   304
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   305
            for (int i = 0; i < postsets.length; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   306
                final int  postset = postsets[i];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   307
                final Node element = value[postset];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   308
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   309
                weight = WeighNodes.weigh(element);
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   310
                totalWeight += WeighNodes.AASTORE_WEIGHT + weight;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   311
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   312
                if (totalWeight >= SPLIT_THRESHOLD) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   313
                    final CompileUnit unit = compiler.findUnit(totalWeight - weight);
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   314
                    ranges.add(new Splittable.SplitRange(unit, lo, i));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   315
                    lo = i;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   316
                    totalWeight = weight;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   317
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   318
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   319
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   320
            if (lo != postsets.length) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   321
                final CompileUnit unit = compiler.findUnit(totalWeight);
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   322
                ranges.add(new Splittable.SplitRange(unit, lo, postsets.length));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   323
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   324
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   325
            return arrayLiteralNode.setSplitRanges(lc, ranges);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   326
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   327
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   328
        return literal;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   329
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   330
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   331
    @Override
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   332
    public Node leaveObjectNode(final ObjectNode objectNode) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   333
        long weight = WeighNodes.weigh(objectNode);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   334
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   335
        if (weight < SPLIT_THRESHOLD) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   336
            return objectNode;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   337
        }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   338
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   339
        final FunctionNode functionNode = lc.getCurrentFunction();
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   340
        lc.setFlag(functionNode, FunctionNode.IS_SPLIT);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   341
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   342
        final List<Splittable.SplitRange> ranges        = new ArrayList<>();
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   343
        final List<PropertyNode>          properties    = objectNode.getElements();
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   344
        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
   345
        long totalWeight = 0;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   346
        int  lo          = 0;
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
        for (int i = 0; i < properties.size(); i++) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   349
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   350
            final PropertyNode property = properties.get(i);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   351
            final boolean isConstant = LiteralNode.isConstant(property.getValue());
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   352
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   353
            if (!isConstant || !isSpillObject) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   354
                weight = isConstant ? 0 : WeighNodes.weigh(property.getValue());
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   355
                totalWeight += WeighNodes.AASTORE_WEIGHT + weight;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   356
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   357
                if (totalWeight >= SPLIT_THRESHOLD) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   358
                    final CompileUnit unit = compiler.findUnit(totalWeight - weight);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   359
                    ranges.add(new Splittable.SplitRange(unit, lo, i));
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   360
                    lo = i;
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   361
                    totalWeight = weight;
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
            }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   364
        }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   365
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   366
        if (lo != properties.size()) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   367
            final CompileUnit unit = compiler.findUnit(totalWeight);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   368
            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
   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
        return objectNode.setSplitRanges(lc, ranges);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   372
    }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   373
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32692
diff changeset
   374
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   375
    public boolean enterFunctionNode(final FunctionNode node) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   376
        //only go into the function node for this splitter. any subfunctions are rejected
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   377
        return node == outermost;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   378
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   379
}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   380