nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
author attila
Wed, 04 Jun 2014 14:32:23 +0200
changeset 24779 3bf490e146c3
parent 24778 2ff5d7041566
child 25236 fac419f1e889
permissions -rw-r--r--
8044502: Get rid of global optimistic flag Reviewed-by: lagergren, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
     1
/*
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
     4
 *
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    10
 *
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    15
 * accompanied this code).
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    16
 *
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    20
 *
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    23
 * questions.
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    24
 */
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    25
package jdk.nashorn.internal.runtime;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    26
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    27
import static jdk.nashorn.internal.lookup.Lookup.MH;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    28
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    29
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
    30
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    31
import java.lang.invoke.CallSite;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    32
import java.lang.invoke.MethodHandle;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    33
import java.lang.invoke.MethodHandles;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    34
import java.lang.invoke.MethodType;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    35
import java.lang.invoke.MutableCallSite;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    36
import java.lang.invoke.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
    37
import java.util.Iterator;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    38
import java.util.Map;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    39
import java.util.TreeMap;
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: 24729
diff changeset
    40
import java.util.logging.Level;
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    41
import jdk.nashorn.internal.codegen.Compiler;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    42
import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    43
import jdk.nashorn.internal.codegen.types.ArrayType;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    44
import jdk.nashorn.internal.codegen.types.Type;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    45
import jdk.nashorn.internal.ir.FunctionNode;
24742
a9afb384e654 8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents: 24741
diff changeset
    46
import jdk.nashorn.internal.runtime.events.RecompilationEvent;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    47
import jdk.nashorn.internal.runtime.linker.Bootstrap;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
    48
import jdk.nashorn.internal.runtime.logging.DebugLogger;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    49
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    50
/**
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    51
 * An version of a JavaScript function, native or JavaScript.
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    52
 * Supports lazily generating a constructor version of the invocation.
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    53
 */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    54
final class CompiledFunction {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    55
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    56
    private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    57
    private static final MethodHandle RELINK_COMPOSABLE_INVOKER = findOwnMH("relinkComposableInvoker", void.class, CallSite.class, CompiledFunction.class, boolean.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    58
    private static final MethodHandle HANDLE_REWRITE_EXCEPTION = findOwnMH("handleRewriteException", MethodHandle.class, CompiledFunction.class, OptimismInfo.class, RewriteException.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    59
    private static final MethodHandle RESTOF_INVOKER = MethodHandles.exactInvoker(MethodType.methodType(Object.class, RewriteException.class));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    60
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
    61
    private final DebugLogger log;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    62
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    63
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    64
     * The method type may be more specific than the invoker, if. e.g.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    65
     * the invoker is guarded, and a guard with a generic object only
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    66
     * fallback, while the target is more specific, we still need the
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    67
     * more specific type for sorting
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    68
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    69
    private MethodHandle invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    70
    private MethodHandle constructor;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    71
    private OptimismInfo optimismInfo;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
    72
    private int flags; // from FunctionNode
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    73
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    74
    CompiledFunction(final MethodHandle invoker) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    75
        this(invoker, null);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    76
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    77
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    78
    static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    79
        return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    80
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    81
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    82
    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    83
        this(invoker, constructor, DebugLogger.DISABLED_LOGGER);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    84
    }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    85
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    86
    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor, final DebugLogger log) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    87
        this.invoker = invoker;
17756
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17518
diff changeset
    88
        this.constructor = constructor;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    89
        this.log = log;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    90
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    91
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
    92
    CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData, final int flags) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    93
        this(invoker, null, functionData.getLogger());
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
    94
        this.flags = flags;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
    95
        if ((flags & FunctionNode.IS_DEOPTIMIZABLE) != 0) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    96
            optimismInfo = new OptimismInfo(functionData);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    97
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    98
            optimismInfo = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    99
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   100
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   101
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   102
    int getFlags() {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   103
        return flags;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   104
    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   105
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   106
    boolean isApplyToCall() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   107
        return (flags & FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION) != 0;
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   108
    }
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   109
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   110
    boolean isVarArg() {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   111
        return isVarArgsType(invoker.type());
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   112
    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   113
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   114
    @Override
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   115
    public String toString() {
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   116
        return "[invokerType=" + invoker.type() + " ctor=" + constructor + " weight=" + weight() + " isApplyToCall=" + isApplyToCall() + "]";
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   117
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   118
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   119
    boolean needsCallee() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   120
        return ScriptFunctionData.needsCallee(invoker);
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   121
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   122
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   123
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   124
     * Returns an invoker method handle for this function. Note that the handle is safely composable in
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   125
     * the sense that you can compose it with other handles using any combinators even if you can't affect call site
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   126
     * invalidation. If this compiled function is non-optimistic, then it returns the same value as
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   127
     * {@link #getInvoker()}. However, if the function is optimistic, then this handle will incur an overhead as it will
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   128
     * add an intermediate internal call site that can relink itself when the function needs to regenerate its code to
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   129
     * always point at the latest generated code version.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   130
     * @return a guaranteed composable invoker method handle for this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   131
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   132
    MethodHandle createComposableInvoker() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   133
        return createComposableInvoker(false);
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   134
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   135
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   136
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   137
     * Returns an invoker method handle for this function when invoked as a constructor. Note that the handle should be
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   138
     * considered non-composable in the sense that you can only compose it with other handles using any combinators if
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   139
     * you can ensure that the composition is guarded by {@link #getOptimisticAssumptionsSwitchPoint()} if it's
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   140
     * non-null, and that you can relink the call site it is set into as a target if the switch point is invalidated. In
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   141
     * all other cases, use {@link #createComposableConstructor()}.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   142
     * @return a direct constructor method handle for this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   143
     */
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   144
    MethodHandle getConstructor() {
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   145
        if (constructor == null) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   146
            constructor = createConstructorFromInvoker(createInvokerForPessimisticCaller());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   147
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   148
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   149
        return constructor;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   150
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   151
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   152
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   153
     * Creates a version of the invoker intended for a pessimistic caller (return type is Object, no caller optimistic
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   154
     * program point available).
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   155
     * @return a version of the invoker intended for a pessimistic caller.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   156
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   157
    private MethodHandle createInvokerForPessimisticCaller() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   158
        return createInvoker(Object.class, INVALID_PROGRAM_POINT);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   159
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   160
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   161
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   162
     * Compose a constructor from an invoker.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   163
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   164
     * @param invoker         invoker
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   165
     * @param needsCallee  do we need to pass a callee
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   166
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   167
     * @return the composed constructor
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   168
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   169
    private static MethodHandle createConstructorFromInvoker(final MethodHandle invoker) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   170
        final boolean needsCallee = ScriptFunctionData.needsCallee(invoker);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   171
        // If it was (callee, this, args...), permute it to (this, callee, args...). We're doing this because having
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   172
        // "this" in the first argument position is what allows the elegant folded composition of
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   173
        // (newFilter x constructor x allocator) further down below in the code. Also, ensure the composite constructor
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   174
        // always returns Object.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   175
        final MethodHandle swapped = needsCallee ? swapCalleeAndThis(invoker) : invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   176
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   177
        final MethodHandle returnsObject = MH.asType(swapped, swapped.type().changeReturnType(Object.class));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   178
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   179
        final MethodType ctorType = returnsObject.type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   180
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   181
        // Construct a dropping type list for NEWFILTER, but don't include constructor "this" into it, so it's actually
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   182
        // captured as "allocation" parameter of NEWFILTER after we fold the constructor into it.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   183
        // (this, [callee, ]args...) => ([callee, ]args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   184
        final Class<?>[] ctorArgs = ctorType.dropParameterTypes(0, 1).parameterArray();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   185
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   186
        // Fold constructor into newFilter that replaces the return value from the constructor with the originally
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   187
        // allocated value when the originally allocated value is a JS primitive (String, Boolean, Number).
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   188
        // (result, this, [callee, ]args...) x (this, [callee, ]args...) => (this, [callee, ]args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   189
        final MethodHandle filtered = MH.foldArguments(MH.dropArguments(NEWFILTER, 2, ctorArgs), returnsObject);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   190
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   191
        // allocate() takes a ScriptFunction and returns a newly allocated ScriptObject...
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   192
        if (needsCallee) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   193
            // ...we either fold it into the previous composition, if we need both the ScriptFunction callee object and
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   194
            // the newly allocated object in the arguments, so (this, callee, args...) x (callee) => (callee, args...),
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   195
            // or...
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   196
            return MH.foldArguments(filtered, ScriptFunction.ALLOCATE);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   197
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   198
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   199
        // ...replace the ScriptFunction argument with the newly allocated object, if it doesn't need the callee
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   200
        // (this, args...) filter (callee) => (callee, args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   201
        return MH.filterArguments(filtered, 0, ScriptFunction.ALLOCATE);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   202
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   203
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   204
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   205
     * Permutes the parameters in the method handle from {@code (callee, this, ...)} to {@code (this, callee, ...)}.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   206
     * Used when creating a constructor handle.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   207
     * @param mh a method handle with order of arguments {@code (callee, this, ...)}
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   208
     * @return a method handle with order of arguments {@code (this, callee, ...)}
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   209
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   210
    private static MethodHandle swapCalleeAndThis(final MethodHandle mh) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   211
        final MethodType type = mh.type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   212
        assert type.parameterType(0) == ScriptFunction.class : type;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   213
        assert type.parameterType(1) == Object.class : type;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   214
        final MethodType newType = type.changeParameterType(0, Object.class).changeParameterType(1, ScriptFunction.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   215
        final int[] reorder = new int[type.parameterCount()];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   216
        reorder[0] = 1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   217
        assert reorder[1] == 0;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   218
        for (int i = 2; i < reorder.length; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   219
            reorder[i] = i;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   220
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   221
        return MethodHandles.permuteArguments(mh, newType, reorder);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   222
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   223
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   224
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   225
     * Returns an invoker method handle for this function when invoked as a constructor. Note that the handle is safely
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   226
     * composable in the sense that you can compose it with other handles using any combinators even if you can't affect
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   227
     * call site invalidation. If this compiled function is non-optimistic, then it returns the same value as
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   228
     * {@link #getConstructor()}. However, if the function is optimistic, then this handle will incur an overhead as it
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   229
     * will add an intermediate internal call site that can relink itself when the function needs to regenerate its code
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   230
     * to always point at the latest generated code version.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   231
     * @return a guaranteed composable constructor method handle for this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   232
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   233
    MethodHandle createComposableConstructor() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   234
        return createComposableInvoker(true);
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   235
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   236
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   237
    boolean hasConstructor() {
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   238
        return constructor != null;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   239
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   240
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   241
    MethodType type() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   242
        return invoker.type();
20570
b1c8d1e8013a 8025965: Specialized functions with same weight replace each other in TreeSet
hannesw
parents: 17756
diff changeset
   243
    }
b1c8d1e8013a 8025965: Specialized functions with same weight replace each other in TreeSet
hannesw
parents: 17756
diff changeset
   244
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   245
    int weight() {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   246
        return weight(type());
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   247
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   248
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   249
    private static int weight(final MethodType type) {
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   250
        if (isVarArgsType(type)) {
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   251
            return Integer.MAX_VALUE; //if there is a varargs it should be the heavist and last fallback
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   252
        }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   253
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   254
        int weight = Type.typeFor(type.returnType()).getWeight();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   255
        for (int i = 0 ; i < type.parameterCount() ; i++) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   256
            final Class<?> paramType = type.parameterType(i);
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: 16523
diff changeset
   257
            final int pweight = Type.typeFor(paramType).getWeight() * 2; //params are more important than call types as return values are always specialized
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   258
            weight += pweight;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   259
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   260
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   261
        weight += type.parameterCount(); //more params outweigh few parameters
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   262
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   263
        return weight;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   264
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   265
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   266
    static boolean isVarArgsType(final MethodType type) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   267
        assert type.parameterCount() >= 1 : type;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   268
        return type.parameterType(type.parameterCount() - 1) == Object[].class;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   269
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   270
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   271
    static boolean moreGenericThan(final MethodType mt0, final MethodType mt1) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   272
        return weight(mt0) > weight(mt1);
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   273
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   274
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   275
    boolean betterThanFinal(final CompiledFunction other, final MethodType callSiteMethodType) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   276
        // Prefer anything over nothing, as we can't compile new versions.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   277
        if (other == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   278
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   279
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   280
        return betterThanFinal(type(), other.type(), callSiteMethodType);
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   281
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   282
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   283
    static boolean betterThanFinal(final MethodType thisMethodType, final MethodType otherMethodType, final MethodType callSiteMethodType) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   284
        final int thisParamCount = getParamCount(thisMethodType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   285
        final int otherParamCount = getParamCount(otherMethodType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   286
        final int callSiteRawParamCount = getParamCount(callSiteMethodType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   287
        final boolean csVarArg = callSiteRawParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   288
        // Subtract 1 for callee for non-vararg call sites
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   289
        final int callSiteParamCount = csVarArg ? callSiteRawParamCount : callSiteRawParamCount - 1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   290
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   291
        // Prefer the function that discards less parameters
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   292
        final int thisDiscardsParams = Math.max(callSiteParamCount - thisParamCount, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   293
        final int otherDiscardsParams = Math.max(callSiteParamCount - otherParamCount, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   294
        if(thisDiscardsParams < otherDiscardsParams) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   295
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   296
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   297
        if(thisDiscardsParams > otherDiscardsParams) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   298
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   299
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   300
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   301
        final boolean thisVarArg = thisParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   302
        final boolean otherVarArg = otherParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   303
        if(!(thisVarArg && otherVarArg && csVarArg)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   304
            // At least one of them isn't vararg
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   305
            final Type[] thisType = toTypeWithoutCallee(thisMethodType, 0); // Never has callee
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   306
            final Type[] otherType = toTypeWithoutCallee(otherMethodType, 0); // Never has callee
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   307
            final Type[] callSiteType = toTypeWithoutCallee(callSiteMethodType, 1); // Always has callee
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   308
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   309
            int narrowWeightDelta = 0;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   310
            int widenWeightDelta = 0;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   311
            final int minParamsCount = Math.min(Math.min(thisParamCount, otherParamCount), callSiteParamCount);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   312
            for(int i = 0; i < minParamsCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   313
                final int callSiteParamWeight = getParamType(i, callSiteType, csVarArg).getWeight();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   314
                // Delta is negative for narrowing, positive for widening
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   315
                final int thisParamWeightDelta = getParamType(i, thisType, thisVarArg).getWeight() - callSiteParamWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   316
                final int otherParamWeightDelta = getParamType(i, otherType, otherVarArg).getWeight() - callSiteParamWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   317
                // Only count absolute values of narrowings
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   318
                narrowWeightDelta += Math.max(-thisParamWeightDelta, 0) - Math.max(-otherParamWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   319
                // Only count absolute values of widenings
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   320
                widenWeightDelta += Math.max(thisParamWeightDelta, 0) - Math.max(otherParamWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   321
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   322
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   323
            // If both functions accept more arguments than what is passed at the call site, account for ability
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   324
            // to receive Undefined un-narrowed in the remaining arguments.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   325
            if(!thisVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   326
                for(int i = callSiteParamCount; i < thisParamCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   327
                    narrowWeightDelta += Math.max(Type.OBJECT.getWeight() - thisType[i].getWeight(), 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   328
                }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   329
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   330
            if(!otherVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   331
                for(int i = callSiteParamCount; i < otherParamCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   332
                    narrowWeightDelta -= Math.max(Type.OBJECT.getWeight() - otherType[i].getWeight(), 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   333
                }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   334
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   335
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   336
            // Prefer function that narrows less
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   337
            if(narrowWeightDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   338
                return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   339
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   340
            if(narrowWeightDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   341
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   342
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   343
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   344
            // Prefer function that widens less
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   345
            if(widenWeightDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   346
                return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   347
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   348
            if(widenWeightDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   349
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   350
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   351
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   352
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   353
        // Prefer the function that exactly matches the arity of the call site.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   354
        if(thisParamCount == callSiteParamCount && otherParamCount != callSiteParamCount) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   355
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   356
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   357
        if(thisParamCount != callSiteParamCount && otherParamCount == callSiteParamCount) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   358
            return false;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   359
        }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   360
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   361
        // Otherwise, neither function matches arity exactly. We also know that at this point, they both can receive
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   362
        // more arguments than call site, otherwise we would've already chosen the one that discards less parameters.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   363
        // Note that variable arity methods are preferred, as they actually match the call site arity better, since they
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   364
        // really have arbitrary arity.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   365
        if(thisVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   366
            if(!otherVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   367
                return true; //
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   368
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   369
        } else if(otherVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   370
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   371
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   372
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   373
        // Neither is variable arity; chose the one that has less extra parameters.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   374
        final int fnParamDelta = thisParamCount - otherParamCount;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   375
        if(fnParamDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   376
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   377
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   378
        if(fnParamDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   379
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   380
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   381
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   382
        final int callSiteRetWeight = Type.typeFor(callSiteMethodType.returnType()).getWeight();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   383
        // Delta is negative for narrower return type, positive for wider return type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   384
        final int thisRetWeightDelta = Type.typeFor(thisMethodType.returnType()).getWeight() - callSiteRetWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   385
        final int otherRetWeightDelta = Type.typeFor(otherMethodType.returnType()).getWeight() - callSiteRetWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   386
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   387
        // Prefer function that returns a less wide return type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   388
        final int widenRetDelta = Math.max(thisRetWeightDelta, 0) - Math.max(otherRetWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   389
        if(widenRetDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   390
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   391
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   392
        if(widenRetDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   393
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   394
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   395
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   396
        // Prefer function that returns a less narrow return type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   397
        final int narrowRetDelta = Math.max(-thisRetWeightDelta, 0) - Math.max(-otherRetWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   398
        if(narrowRetDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   399
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   400
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   401
        if(narrowRetDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   402
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   403
        }
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   404
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   405
        throw new AssertionError(thisMethodType + " identically applicable to " + otherMethodType + " for " + callSiteMethodType); // Signatures are identical
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   406
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   407
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   408
    private static Type[] toTypeWithoutCallee(final MethodType type, final int thisIndex) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   409
        final int paramCount = type.parameterCount();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   410
        final Type[] t = new Type[paramCount - thisIndex];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   411
        for(int i = thisIndex; i < paramCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   412
            t[i - thisIndex] = Type.typeFor(type.parameterType(i));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   413
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   414
        return t;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   415
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   416
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   417
    private static Type getParamType(final int i, final Type[] paramTypes, final boolean isVarArg) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   418
        final int fixParamCount = paramTypes.length - (isVarArg ? 1 : 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   419
        if(i < fixParamCount) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   420
            return paramTypes[i];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   421
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   422
        assert isVarArg;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   423
        return ((ArrayType)paramTypes[paramTypes.length - 1]).getElementType();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   424
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   425
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   426
    boolean matchesCallSite(final MethodType callSiteType, final boolean pickVarArg) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   427
        final MethodType type  = type();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   428
        final int fnParamCount = getParamCount(type);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   429
        final boolean isVarArg = fnParamCount == Integer.MAX_VALUE;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   430
        if (isVarArg) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   431
            return pickVarArg;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   432
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   433
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   434
        final int csParamCount = getParamCount(callSiteType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   435
        final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   436
        final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   437
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   438
        final int fnParamCountNoCallee = fnParamCount - thisThisIndex;
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   439
        final int minParams = Math.min(csParamCount - 1, fnParamCountNoCallee); // callSiteType always has callee, so subtract 1
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   440
        // We must match all incoming parameters, except "this". Starting from 1 to skip "this".
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   441
        for(int i = 1; i < minParams; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   442
            final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   443
            final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(callSiteType.parameterType(i + 1));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   444
            if(!fnType.isEquivalentTo(csType)) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   445
                return false;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   446
            }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   447
        }
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   448
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   449
        // Must match any undefined parameters to Object type.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   450
        for(int i = minParams; i < fnParamCountNoCallee; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   451
            if(!Type.typeFor(type.parameterType(i + thisThisIndex)).isEquivalentTo(Type.OBJECT)) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   452
                return false;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   453
            }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   454
        }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   455
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   456
        return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   457
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   458
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   459
    private static int getParamCount(final MethodType type) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   460
        final int paramCount = type.parameterCount();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   461
        return type.parameterType(paramCount - 1).isArray() ? Integer.MAX_VALUE : paramCount;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   462
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   463
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   464
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   465
     * Returns the switch point embodying the optimistic assumptions in this compiled function. It should be used to
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   466
     * guard any linking to the function's invoker or constructor.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   467
     * @return the switch point embodying the optimistic assumptions in this compiled function. Null is returned if the
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   468
     * function has no optimistic assumptions.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   469
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   470
    SwitchPoint getOptimisticAssumptionsSwitchPoint() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   471
        return canBeDeoptimized() ? optimismInfo.optimisticAssumptions : null;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   472
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   473
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   474
    boolean canBeDeoptimized() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   475
        return optimismInfo != null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   476
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   477
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   478
    private MethodHandle createComposableInvoker(final boolean isConstructor) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   479
        final MethodHandle handle = getInvokerOrConstructor(isConstructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   480
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   481
        // If compiled function is not optimistic, it can't ever change its invoker/constructor, so just return them
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   482
        // directly.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   483
        if(!canBeDeoptimized()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   484
            return handle;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   485
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   486
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   487
        // Otherwise, we need a new level of indirection; need to introduce a mutable call site that can relink itslef
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   488
        // to the compiled function's changed target whenever the optimistic assumptions are invalidated.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   489
        final CallSite cs = new MutableCallSite(handle.type());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   490
        relinkComposableInvoker(cs, this, isConstructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   491
        return cs.dynamicInvoker();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   492
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   493
    private static void relinkComposableInvoker(final CallSite cs, final CompiledFunction inv, final boolean constructor) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   494
        final MethodHandle handle = inv.getInvokerOrConstructor(constructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   495
        final SwitchPoint assumptions = inv.getOptimisticAssumptionsSwitchPoint();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   496
        final MethodHandle target;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   497
        if(assumptions == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   498
            target = handle;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   499
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   500
            // This assertion can obviously fail in a multithreaded environment, as we can be in a situation where
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   501
            // one thread is in the middle of a deoptimizing compilation when we hit this and thus, it has invalidated
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   502
            // the old switch point, but hasn't created the new one yet. Note that the behavior of invalidating the old
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   503
            // switch point before recompilation, and only creating the new one after recompilation is by design.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   504
            // TODO: We need to think about thread safety of CompiledFunction objects.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   505
            assert !assumptions.hasBeenInvalidated();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   506
            final MethodHandle relink = MethodHandles.insertArguments(RELINK_COMPOSABLE_INVOKER, 0, cs, inv, constructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   507
            target = assumptions.guardWithTest(handle, MethodHandles.foldArguments(cs.dynamicInvoker(), relink));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   508
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   509
        cs.setTarget(target.asType(cs.type()));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   510
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   511
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   512
    private MethodHandle getInvokerOrConstructor(final boolean selectCtor) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   513
        return selectCtor ? getConstructor() : createInvokerForPessimisticCaller();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   514
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   515
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   516
    MethodHandle createInvoker(final Class<?> callSiteReturnType, final int callerProgramPoint) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   517
        final boolean isOptimistic = canBeDeoptimized();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   518
        MethodHandle handleRewriteException = isOptimistic ? createRewriteExceptionHandler() : null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   519
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   520
        MethodHandle inv = invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   521
        if(isValid(callerProgramPoint)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   522
            inv = OptimisticReturnFilters.filterOptimisticReturnValue(inv, callSiteReturnType, callerProgramPoint);
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   523
            inv = changeReturnType(inv, callSiteReturnType);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   524
            if(callSiteReturnType.isPrimitive() && handleRewriteException != null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   525
                // because handleRewriteException always returns Object
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   526
                handleRewriteException = OptimisticReturnFilters.filterOptimisticReturnValue(handleRewriteException,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   527
                        callSiteReturnType, callerProgramPoint);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   528
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   529
        } else if(isOptimistic) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   530
            // Required so that rewrite exception has the same return type. It'd be okay to do it even if we weren't
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   531
            // optimistic, but it isn't necessary as the linker upstream will eventually convert the return type.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   532
            inv = changeReturnType(inv, callSiteReturnType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   533
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   534
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   535
        if(isOptimistic) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   536
            assert handleRewriteException != null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   537
            final MethodHandle typedHandleRewriteException = changeReturnType(handleRewriteException, inv.type().returnType());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   538
            return MH.catchException(inv, RewriteException.class, typedHandleRewriteException);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   539
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   540
        return inv;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   541
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   542
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   543
    private MethodHandle createRewriteExceptionHandler() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   544
        return MH.foldArguments(RESTOF_INVOKER, MH.insertArguments(HANDLE_REWRITE_EXCEPTION, 0, this, optimismInfo));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   545
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   546
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   547
    private static MethodHandle changeReturnType(final MethodHandle mh, final Class<?> newReturnType) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   548
        return Bootstrap.getLinkerServices().asType(mh, mh.type().changeReturnType(newReturnType));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   549
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   550
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   551
    @SuppressWarnings("unused")
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   552
    private static MethodHandle handleRewriteException(final CompiledFunction function, final OptimismInfo oldOptimismInfo, final RewriteException re) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   553
        return function.handleRewriteException(oldOptimismInfo, re);
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   554
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   555
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   556
    /**
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   557
     * Debug function for printing out all invalidated program points and their
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   558
     * invalidation mapping to next type
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   559
     * @param ipp
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   560
     * @return string describing the ipp map
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   561
     */
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   562
    private static String toStringInvalidations(final Map<Integer, Type> ipp) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   563
        if (ipp == null) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   564
            return "";
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   565
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   566
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   567
        final StringBuilder sb = new StringBuilder();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   568
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   569
        for (final Iterator<Map.Entry<Integer, Type>> iter = ipp.entrySet().iterator(); iter.hasNext(); ) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   570
            final Map.Entry<Integer, Type> entry = iter.next();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   571
            final char bct = entry.getValue().getBytecodeStackType();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   572
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   573
            sb.append('[').
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   574
                    append(entry.getKey()).
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   575
                    append("->").
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   576
                    append(bct == 'A' ? 'O' : bct).
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   577
                    append(']');
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   578
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   579
            if (iter.hasNext()) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   580
                sb.append(' ');
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   581
            }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   582
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   583
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   584
        return sb.toString();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   585
    }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   586
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   587
    private void logRecompile(final String reason, final FunctionNode fn, final MethodType callSiteType, final Map<Integer, Type> ipp) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   588
        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
   589
            log.info(reason, DebugLogger.quote(fn.getName()), " signature: ", callSiteType, " ", toStringInvalidations(ipp));
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   590
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   591
    }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   592
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   593
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   594
     * Handles a {@link RewriteException} raised during the execution of this function by recompiling (if needed) the
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   595
     * function with an optimistic assumption invalidated at the program point indicated by the exception, and then
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   596
     * executing a rest-of method to complete the execution with the deoptimized version.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   597
     * @param oldOptimismInfo the optimism info of this function. We must store it explicitly as a bound argument in the
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   598
     * method handle, otherwise it would be null for handling a rewrite exception in an outer invocation of a recursive
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   599
     * function when inner invocations of the function have completely deoptimized it.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   600
     * @param re the rewrite exception that was raised
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   601
     * @return the method handle for the rest-of method, for folding composition.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   602
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   603
    private MethodHandle handleRewriteException(final OptimismInfo oldOptimismInfo, final RewriteException re) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   604
        if (log.isEnabled()) {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   605
            log.info(new RecompilationEvent(Level.INFO, re, re.getReturnValueNonDestructive()), "RewriteException ", re.getMessageShort());
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   606
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   607
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   608
        final MethodType type = type();
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   609
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   610
        // Compiler needs a call site type as its input, which always has a callee parameter, so we must add it if
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   611
        // this function doesn't have a callee parameter.
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   612
        final MethodType callSiteType = type.parameterType(0) == ScriptFunction.class ?
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   613
                type :
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   614
                type.insertParameterTypes(0, ScriptFunction.class);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   615
        final boolean shouldRecompile = oldOptimismInfo.requestRecompile(re);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   616
        final boolean  canBeDeoptimized;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   617
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   618
        FunctionNode fn = oldOptimismInfo.reparse();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   619
        final Compiler compiler = oldOptimismInfo.getCompiler(fn, callSiteType, re); //set to non rest-of
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   620
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   621
        if (!shouldRecompile) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   622
            // It didn't necessarily recompile, e.g. for an outer invocation of a recursive function if we already
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   623
            // recompiled a deoptimized version for an inner invocation.
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   624
            // We still need to do the rest of from the beginning
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   625
            canBeDeoptimized = canBeDeoptimized();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   626
            assert !canBeDeoptimized || optimismInfo == oldOptimismInfo;
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   627
            logRecompile("Rest-of compilation [STANDALONE] ", fn, callSiteType, oldOptimismInfo.invalidatedProgramPoints);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   628
            return restOfHandle(oldOptimismInfo, compiler.compile(fn, CompilationPhases.COMPILE_ALL_RESTOF), canBeDeoptimized);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   629
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   630
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   631
        logRecompile("Deoptimizing recompilation (up to bytecode) ", fn, callSiteType, oldOptimismInfo.invalidatedProgramPoints);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   632
        fn = compiler.compile(fn, CompilationPhases.COMPILE_UPTO_BYTECODE);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   633
        log.info("Reusable IR generated");
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   634
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   635
        assert optimismInfo == oldOptimismInfo;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   636
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   637
        // compile the rest of the function, and install it
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   638
        log.info("Generating and installing bytecode from reusable IR...");
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   639
        logRecompile("Rest-of compilation [CODE PIPELINE REUSE] ", fn, callSiteType, oldOptimismInfo.invalidatedProgramPoints);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   640
        final FunctionNode normalFn = compiler.compile(fn, CompilationPhases.COMPILE_FROM_BYTECODE);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   641
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   642
        FunctionNode fn2 = oldOptimismInfo.reparse();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   643
        fn2 = compiler.compile(fn2, CompilationPhases.COMPILE_UPTO_BYTECODE);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   644
        log.info("Done.");
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   645
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   646
        canBeDeoptimized = normalFn.canBeDeoptimized();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   647
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   648
        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
   649
            log.info("Recompiled '", fn.getName(), "' (", Debug.id(this), ") ", canBeDeoptimized ? " can still be deoptimized." : " is completely deoptimized.");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   650
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   651
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   652
        log.info("Looking up invoker...");
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   653
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   654
        final MethodHandle newInvoker = oldOptimismInfo.data.lookup(fn);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   655
        invoker     = newInvoker.asType(type.changeReturnType(newInvoker.type().returnType()));
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   656
        constructor = null; // Will be regenerated when needed
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   657
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   658
        log.info("Done: ", invoker);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   659
        final MethodHandle restOf = restOfHandle(oldOptimismInfo, compiler.compile(fn, CompilationPhases.COMPILE_FROM_BYTECODE_RESTOF), canBeDeoptimized);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   660
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   661
        // Note that we only adjust the switch point after we set the invoker/constructor. This is important.
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   662
        if (canBeDeoptimized) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   663
            oldOptimismInfo.newOptimisticAssumptions(); // Otherwise, set a new switch point.
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   664
        } else {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   665
            optimismInfo = null; // If we got to a point where we no longer have optimistic assumptions, let the optimism info go.
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   666
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   667
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   668
        return restOf;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   669
    }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   670
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   671
    private MethodHandle restOfHandle(final OptimismInfo info, final FunctionNode restOfFunction, final boolean canBeDeoptimized) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   672
        assert info != null;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   673
        assert restOfFunction.getCompileUnit().getUnitClassName().indexOf("restOf") != -1;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   674
        final MethodHandle restOf =
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   675
                changeReturnType(
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   676
                        info.data.lookupWithExplicitType(
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   677
                                restOfFunction,
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   678
                                MH.type(restOfFunction.getReturnType().getTypeClass(),
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   679
                                        RewriteException.class)),
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   680
                        Object.class);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   681
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   682
        if (!canBeDeoptimized) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   683
            return restOf;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   684
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   685
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   686
        // If rest-of is itself optimistic, we must make sure that we can repeat a deoptimization if it, too hits an exception.
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   687
        return MH.catchException(restOf, RewriteException.class, createRewriteExceptionHandler());
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   688
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   689
    }
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   690
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   691
    private static class OptimismInfo {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   692
        // TODO: this is pointing to its owning ScriptFunctionData. Re-evaluate if that's okay.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   693
        private final RecompilableScriptFunctionData data;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   694
        private final Map<Integer, Type> invalidatedProgramPoints = new TreeMap<>();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   695
        private SwitchPoint optimisticAssumptions;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   696
        private final DebugLogger log;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   697
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   698
        OptimismInfo(final RecompilableScriptFunctionData data) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   699
            this.data = data;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   700
            this.log  = data.getLogger();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   701
            newOptimisticAssumptions();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   702
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   703
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   704
        private void newOptimisticAssumptions() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   705
            optimisticAssumptions = new SwitchPoint();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   706
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   707
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   708
        boolean requestRecompile(final RewriteException e) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   709
            final Type retType            = e.getReturnType();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   710
            final Type previousFailedType = invalidatedProgramPoints.put(e.getProgramPoint(), retType);
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   711
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   712
            if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   713
                final StackTraceElement[] stack      = e.getStackTrace();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   714
                final String              functionId = stack.length == 0 ?
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   715
                        data.getName() :
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   716
                        stack[0].getClassName() + "." + stack[0].getMethodName();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   717
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
   718
                log.info("RewriteException for an already invalidated program point ", e.getProgramPoint(), " in ", functionId, ". This is okay for a recursive function invocation, but a bug otherwise.");
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   719
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   720
                return false;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   721
            }
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   722
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   723
            SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions });
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   724
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   725
            return true;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   726
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   727
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   728
        Compiler getCompiler(final FunctionNode fn, final MethodType actualCallSiteType, final RewriteException e) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   729
            return data.getCompiler(fn, actualCallSiteType, e.getRuntimeScope(), invalidatedProgramPoints, getEntryPoints(e));
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   730
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   731
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   732
        private static int[] getEntryPoints(final RewriteException e) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   733
            final int[] prevEntryPoints = e.getPreviousContinuationEntryPoints();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   734
            final int[] entryPoints;
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   735
            if (prevEntryPoints == null) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   736
                entryPoints = new int[1];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   737
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   738
                final int l = prevEntryPoints.length;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   739
                entryPoints = new int[l + 1];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   740
                System.arraycopy(prevEntryPoints, 0, entryPoints, 1, l);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   741
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   742
            entryPoints[0] = e.getProgramPoint();
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   743
            return entryPoints;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   744
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   745
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   746
        FunctionNode reparse() {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   747
            return data.reparse();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   748
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   749
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   750
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   751
    @SuppressWarnings("unused")
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   752
    private static Object newFilter(final Object result, final Object allocation) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   753
        return (result instanceof ScriptObject || !JSType.isPrimitive(result))? result : allocation;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   754
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   755
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   756
    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   757
        return MH.findStatic(MethodHandles.lookup(), CompiledFunction.class, name, MH.type(rtype, types));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   758
    }
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   759
}