nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ApplySpecialization.java
author lagergren
Fri, 26 Sep 2014 18:47:20 +0200
changeset 26886 18c744ab4df2
parent 26768 751b0f427090
child 27206 d4a707c9db5a
permissions -rw-r--r--
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this Reviewed-by: attila, hannesw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
     1
/*
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
     2
 * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
     4
 *
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    10
 *
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    15
 * accompanied this code).
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    16
 *
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    20
 *
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    23
 * questions.
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    24
 */
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    25
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    26
package jdk.nashorn.internal.codegen;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    27
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    28
import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    29
import static jdk.nashorn.internal.codegen.CompilerConstants.EXPLODED_ARGUMENT_PREFIX;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    30
import java.lang.invoke.MethodType;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    31
import java.util.ArrayDeque;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    32
import java.util.ArrayList;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    33
import java.util.Deque;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    34
import java.util.HashSet;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    35
import java.util.List;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    36
import java.util.Set;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    37
import jdk.nashorn.internal.ir.AccessNode;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    38
import jdk.nashorn.internal.ir.CallNode;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    39
import jdk.nashorn.internal.ir.Expression;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    40
import jdk.nashorn.internal.ir.FunctionNode;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    41
import jdk.nashorn.internal.ir.IdentNode;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    42
import jdk.nashorn.internal.ir.LexicalContext;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    43
import jdk.nashorn.internal.ir.Node;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    44
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    45
import jdk.nashorn.internal.objects.Global;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24746
diff changeset
    46
import jdk.nashorn.internal.runtime.Context;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
    47
import jdk.nashorn.internal.runtime.logging.DebugLogger;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
    48
import jdk.nashorn.internal.runtime.logging.Loggable;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
    49
import jdk.nashorn.internal.runtime.logging.Logger;
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
    50
import jdk.nashorn.internal.runtime.options.Options;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    51
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    52
/**
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    53
 * An optimization that attempts to turn applies into calls. This pattern
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    54
 * is very common for fake class instance creation, and apply
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    55
 * introduces expensive args collection and boxing
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    56
 *
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    57
 * <pre>
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    58
 * var Class = {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    59
 *     create: function() {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    60
 *         return function() { //vararg
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    61
 *             this.initialize.apply(this, arguments);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    62
 *         }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    63
 *     }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    64
 * };
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    65
 *
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    66
 * Color = Class.create();
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    67
 *
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    68
 * Color.prototype = {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    69
 *    red: 0, green: 0, blue: 0,
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    70
 *    initialize: function(r,g,b) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    71
 *        this.red = r;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    72
 *        this.green = g;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    73
 *        this.blue = b;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    74
 *    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    75
 * }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    76
 *
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    77
 * new Color(17, 47, 11);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    78
 * </pre>
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    79
 */
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    80
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
    81
@Logger(name="apply2call")
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    82
public final class ApplySpecialization extends NodeVisitor<LexicalContext> implements Loggable {
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
    83
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
    84
    private static final boolean USE_APPLY2CALL = Options.getBooleanProperty("nashorn.apply2call", true);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    85
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
    86
    private final DebugLogger log;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    87
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    88
    private final Compiler compiler;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    89
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    90
    private final Set<Integer> changed = new HashSet<>();
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    91
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    92
    private final Deque<List<IdentNode>> explodedArguments = new ArrayDeque<>();
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    93
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    94
    private static final String ARGUMENTS = ARGUMENTS_VAR.symbolName();
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    95
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    96
    /**
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    97
     * Apply specialization optimization. Try to explode arguments and call
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    98
     * applies as calls if they just pass on the "arguments" array and
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
    99
     * "arguments" doesn't escape.
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   100
     *
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   101
     * @param compiler compiler
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   102
     */
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   103
    public ApplySpecialization(final Compiler compiler) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   104
        super(new LexicalContext());
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   105
        this.compiler = compiler;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   106
        this.log = initLogger(compiler.getContext());
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
   107
    }
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
   108
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
   109
    @Override
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
   110
    public DebugLogger getLogger() {
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
   111
        return log;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
   112
    }
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
   113
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24740
diff changeset
   114
    @Override
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   115
    public DebugLogger initLogger(final Context context) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   116
        return context.getLogger(this.getClass());
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   117
    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   118
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   119
    /**
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   120
     * Arguments may only be used as args to the apply. Everything else is disqualified
24746
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   121
     * We cannot control arguments if they escape from the method and go into an unknown
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   122
     * scope, thus we are conservative and treat any access to arguments outside the
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   123
     * apply call as a case of "we cannot apply the optimization".
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   124
     *
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   125
     * @return true if arguments escape
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   126
     */
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   127
    private boolean argumentsEscape(final FunctionNode functionNode) {
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   128
26245
136ee2110f57 8055906: Avoid throwing an exception with filled in stack trace as part of the normal control flow
lagergren
parents: 25865
diff changeset
   129
        @SuppressWarnings("serial")
136ee2110f57 8055906: Avoid throwing an exception with filled in stack trace as part of the normal control flow
lagergren
parents: 25865
diff changeset
   130
        final UnsupportedOperationException uoe = new UnsupportedOperationException() {
136ee2110f57 8055906: Avoid throwing an exception with filled in stack trace as part of the normal control flow
lagergren
parents: 25865
diff changeset
   131
            @Override
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   132
            public synchronized Throwable fillInStackTrace() {
26245
136ee2110f57 8055906: Avoid throwing an exception with filled in stack trace as part of the normal control flow
lagergren
parents: 25865
diff changeset
   133
                return null;
136ee2110f57 8055906: Avoid throwing an exception with filled in stack trace as part of the normal control flow
lagergren
parents: 25865
diff changeset
   134
            }
136ee2110f57 8055906: Avoid throwing an exception with filled in stack trace as part of the normal control flow
lagergren
parents: 25865
diff changeset
   135
        };
136ee2110f57 8055906: Avoid throwing an exception with filled in stack trace as part of the normal control flow
lagergren
parents: 25865
diff changeset
   136
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   137
        final Set<Expression> argumentsFound = new HashSet<>();
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   138
        final Deque<Set<Expression>> stack = new ArrayDeque<>();
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   139
        //ensure that arguments is only passed as arg to apply
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   140
        try {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   141
            functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   142
                private boolean isCurrentArg(final Expression expr) {
24746
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   143
                    return !stack.isEmpty() && stack.peek().contains(expr); //args to current apply call
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   144
                }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   145
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   146
                private boolean isArguments(final Expression expr) {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   147
                    if (expr instanceof IdentNode && ARGUMENTS.equals(((IdentNode)expr).getName())) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   148
                        argumentsFound.add(expr);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   149
                        return true;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   150
                    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   151
                    return false;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   152
                }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   153
24746
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   154
                private boolean isParam(final String name) {
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   155
                    for (final IdentNode param : functionNode.getParameters()) {
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   156
                        if (param.getName().equals(name)) {
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   157
                            return true;
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   158
                        }
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   159
                    }
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   160
                    return false;
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   161
                }
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   162
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   163
                @Override
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   164
                public Node leaveIdentNode(final IdentNode identNode) {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   165
                    if (isParam(identNode.getName()) || isArguments(identNode) && !isCurrentArg(identNode)) {
26245
136ee2110f57 8055906: Avoid throwing an exception with filled in stack trace as part of the normal control flow
lagergren
parents: 25865
diff changeset
   166
                        throw uoe; //avoid filling in stack trace
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   167
                    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   168
                    return identNode;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   169
                }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   170
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   171
                @Override
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   172
                public boolean enterCallNode(final CallNode callNode) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   173
                    final Set<Expression> callArgs = new HashSet<>();
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   174
                    if (isApply(callNode)) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   175
                        final List<Expression> argList = callNode.getArgs();
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   176
                        if (argList.size() != 2 || !isArguments(argList.get(argList.size() - 1))) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   177
                            throw new UnsupportedOperationException();
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   178
                        }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   179
                        callArgs.addAll(callNode.getArgs());
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   180
                    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   181
                    stack.push(callArgs);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   182
                    return true;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   183
                }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   184
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   185
                @Override
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   186
                public Node leaveCallNode(final CallNode callNode) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   187
                    stack.pop();
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   188
                    return callNode;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   189
                }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   190
            });
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   191
        } catch (final UnsupportedOperationException e) {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   192
            if (!argumentsFound.isEmpty()) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   193
                log.fine("'arguments' is used but escapes, or is reassigned in '" + functionNode.getName() + "'. Aborting");
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   194
            }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   195
            return true; //bad
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   196
        }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   197
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   198
        return false;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   199
    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   200
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   201
    @Override
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   202
    public boolean enterCallNode(final CallNode callNode) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   203
        return !explodedArguments.isEmpty();
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   204
    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   205
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   206
    @Override
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   207
    public Node leaveCallNode(final CallNode callNode) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   208
        //apply needs to be a global symbol or we don't allow it
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   209
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   210
        final List<IdentNode> newParams = explodedArguments.peek();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   211
        if (isApply(callNode)) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   212
            final List<Expression> newArgs = new ArrayList<>();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   213
            for (final Expression arg : callNode.getArgs()) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   214
                if (arg instanceof IdentNode && ARGUMENTS.equals(((IdentNode)arg).getName())) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   215
                    newArgs.addAll(newParams);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   216
                } else {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   217
                    newArgs.add(arg);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   218
                }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   219
            }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   220
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   221
            changed.add(lc.getCurrentFunction().getId());
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   222
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   223
            final CallNode newCallNode = callNode.setArgs(newArgs).setIsApplyToCall();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   224
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   225
            log.fine("Transformed ",
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   226
                    callNode,
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   227
                    " from apply to call => ",
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   228
                    newCallNode,
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   229
                    " in ",
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   230
                    DebugLogger.quote(lc.getCurrentFunction().getName()));
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   231
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   232
            return newCallNode;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   233
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   234
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   235
        return callNode;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   236
    }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   237
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   238
    private boolean pushExplodedArgs(final FunctionNode functionNode) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   239
        int start = 0;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   240
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   241
        final MethodType actualCallSiteType = compiler.getCallSiteType(functionNode);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   242
        if (actualCallSiteType == null) {
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   243
            return false;
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   244
        }
24746
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   245
        assert actualCallSiteType.parameterType(actualCallSiteType.parameterCount() - 1) != Object[].class : "error vararg callsite passed to apply2call " + functionNode.getName() + " " + actualCallSiteType;
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   246
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   247
        final TypeMap ptm = compiler.getTypeMap();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   248
        if (ptm.needsCallee()) {
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   249
            start++;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   250
        }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   251
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   252
        start++; //we always uses this
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   253
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   254
        final List<IdentNode> params    = functionNode.getParameters();
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   255
        final List<IdentNode> newParams = new ArrayList<>();
24746
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   256
        final long to = Math.max(params.size(), actualCallSiteType.parameterCount() - start);
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   257
        for (int i = 0; i < to; i++) {
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   258
            if (i >= params.size()) {
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   259
                newParams.add(new IdentNode(functionNode.getToken(), functionNode.getFinish(), EXPLODED_ARGUMENT_PREFIX.symbolName() + (i)));
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   260
            } else {
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   261
                newParams.add(params.get(i));
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   262
            }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   263
        }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   264
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   265
        explodedArguments.push(newParams);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   266
        return true;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   267
    }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   268
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   269
    @Override
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   270
    public boolean enterFunctionNode(final FunctionNode functionNode) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   271
        if (!USE_APPLY2CALL) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   272
            return false;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   273
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   274
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   275
        if (!Global.isBuiltinFunctionPrototypeApply()) {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   276
            log.fine("Apply transform disabled: apply/call overridden");
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26245
diff changeset
   277
            assert !Global.isBuiltinFunctionPrototypeCall() : "call and apply should have the same SwitchPoint";
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   278
            return false;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   279
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   280
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   281
        if (!compiler.isOnDemandCompilation()) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   282
            return false;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   283
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   284
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   285
        if (functionNode.hasEval()) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   286
            return false;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   287
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   288
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   289
        if (argumentsEscape(functionNode)) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   290
            return false;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   291
        }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   292
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   293
        return pushExplodedArgs(functionNode);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   294
    }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   295
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   296
    /**
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   297
     * Try to do the apply to call transformation
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   298
     * @return true if successful, false otherwise
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   299
     */
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   300
    @Override
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   301
    public Node leaveFunctionNode(final FunctionNode functionNode0) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   302
        FunctionNode newFunctionNode = functionNode0;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   303
        final String functionName = newFunctionNode.getName();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   304
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   305
        if (changed.contains(newFunctionNode.getId())) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   306
            newFunctionNode = newFunctionNode.clearFlag(lc, FunctionNode.USES_ARGUMENTS).
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   307
                    setFlag(lc, FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION).
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   308
                    setParameters(lc, explodedArguments.peek());
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   309
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   310
            if (log.isEnabled()) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   311
                log.info("Successfully specialized apply to call in '",
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   312
                        functionName,
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   313
                        " params=",
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   314
                        explodedArguments.peek(),
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   315
                        "' id=",
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   316
                        newFunctionNode.getId(),
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   317
                        " source=",
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   318
                        newFunctionNode.getSource().getURL());
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   319
            }
24746
4b8db7796091 8041905: Fix apply2call bug that prevented avatar.js unit tests from running correctly
lagergren
parents: 24745
diff changeset
   320
        }
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   321
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   322
        explodedArguments.pop();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   323
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   324
        return newFunctionNode;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   325
    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   326
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   327
    private static boolean isApply(final CallNode callNode) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   328
        final Expression f = callNode.getFunction();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24746
diff changeset
   329
        return f instanceof AccessNode && "apply".equals(((AccessNode)f).getProperty());
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   330
    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   331
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
diff changeset
   332
}