nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
author lagergren
Thu, 20 Mar 2014 16:16:42 +0100
changeset 24725 7bb1f687a852
parent 24719 f726e9d67629
child 24729 2b13051f2122
permissions -rw-r--r--
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation Summary: Compute RecompiledScriptFunctionDatas eagerly, annotate them with scope depth information and use them in recompilations. Reviewed-by: attila, hannesw, jlaskey
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;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    30
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;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    37
import java.util.Map;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    38
import java.util.TreeMap;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    39
import jdk.internal.dynalink.support.CatchExceptionCombinator;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    40
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
    41
import jdk.nashorn.internal.codegen.types.Type;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    42
import jdk.nashorn.internal.ir.FunctionNode;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    43
import jdk.nashorn.internal.runtime.linker.Bootstrap;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    44
import jdk.nashorn.internal.runtime.options.Options;
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
    45
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
    46
/**
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
    47
 * 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
    48
 * 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
    49
 */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    50
final class CompiledFunction {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    51
    private static final boolean USE_FAST_REWRITE = Options.getBooleanProperty("nashorn.fastrewrite");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    52
    static {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    53
        if(USE_FAST_REWRITE && CompiledFunction.class.getClassLoader() != null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    54
            throw new AssertionError("-Dnashorn.fastrewrite can only be used with Nashorn in boot class path! (Try -Xbootclasspath/p:dist/nashorn.jar )");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    55
        }
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
    56
    }
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
    57
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    58
    private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    59
    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
    60
    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
    61
    private static final MethodHandle RESTOF_INVOKER = MethodHandles.exactInvoker(MethodType.methodType(Object.class, RewriteException.class));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    62
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    63
    private static final DebugLogger LOG = new DebugLogger("recompile", "nashorn.codegen.debug");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    64
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    65
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    66
     * The method type may be more specific than the invoker, if. e.g.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    67
     * the invoker is guarded, and a guard with a generic object only
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    68
     * fallback, while the target is more specific, we still need the
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    69
     * more specific type for sorting
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    70
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    71
    private MethodHandle invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    72
    private MethodHandle constructor;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    73
    private OptimismInfo optimismInfo;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    74
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    75
    CompiledFunction(final MethodHandle invoker) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    76
        this.invoker = invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    77
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    78
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    79
    static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    80
        return new CompiledFunction(MH.insertArguments(invoker, 0, false),
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    81
                createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    82
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    83
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    84
    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    85
        this(invoker);
17756
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17518
diff changeset
    86
        this.constructor = constructor;
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
    87
    }
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
    88
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    89
    CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData, final boolean isOptimistic) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    90
        this(invoker);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    91
        if(isOptimistic) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    92
            optimismInfo = new OptimismInfo(functionData);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    93
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    94
            optimismInfo = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    95
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    96
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    97
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
    98
    @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
    99
    public String toString() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   100
        return "<callSiteType=" + invoker.type() + " invoker=" + invoker + " ctor=" + constructor + " weight=" + weight() + ">";
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   101
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   102
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   103
    boolean needsCallee() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   104
        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
   105
    }
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
   106
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   107
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   108
     * 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
   109
     * 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
   110
     * invalidation. If this compiled function is non-optimistic, then it returns the same value as
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   111
     * {@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
   112
     * 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
   113
     * always point at the latest generated code version.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   114
     * @return a guaranteed composable invoker method handle for this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   115
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   116
    MethodHandle createComposableInvoker() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   117
        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
   118
    }
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
   119
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   120
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   121
     * 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
   122
     * 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
   123
     * you can ensure that the composition is guarded by {@link #getOptimisticAssumptionsSwitchPoint()} if it's
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   124
     * 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
   125
     * all other cases, use {@link #createComposableConstructor()}.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   126
     * @return a direct constructor method handle for this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   127
     */
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
   128
    MethodHandle getConstructor() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   129
        if(constructor == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   130
            constructor = createConstructorFromInvoker(createInvokerForPessimisticCaller());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   131
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   132
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
   133
        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
   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
     * 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
   138
     * program point available).
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   139
     * @return a version of the invoker intended for a pessimistic caller.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   140
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   141
    private MethodHandle createInvokerForPessimisticCaller() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   142
        return createInvoker(Object.class, INVALID_PROGRAM_POINT);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   143
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   144
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   145
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   146
     * Compose a constructor from an invoker.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   147
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   148
     * @param invoker         invoker
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   149
     * @param needsCallee  do we need to pass a callee
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   150
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   151
     * @return the composed constructor
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   152
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   153
    private static MethodHandle createConstructorFromInvoker(final MethodHandle invoker) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   154
        final boolean needsCallee = ScriptFunctionData.needsCallee(invoker);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   155
        // 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
   156
        // "this" in the first argument position is what allows the elegant folded composition of
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   157
        // (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
   158
        // always returns Object.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   159
        final MethodHandle swapped = needsCallee ? swapCalleeAndThis(invoker) : invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   160
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   161
        final MethodHandle returnsObject = MH.asType(swapped, swapped.type().changeReturnType(Object.class));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   162
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   163
        final MethodType ctorType = returnsObject.type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   164
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   165
        // 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
   166
        // captured as "allocation" parameter of NEWFILTER after we fold the constructor into it.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   167
        // (this, [callee, ]args...) => ([callee, ]args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   168
        final Class<?>[] ctorArgs = ctorType.dropParameterTypes(0, 1).parameterArray();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   169
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   170
        // Fold constructor into newFilter that replaces the return value from the constructor with the originally
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   171
        // allocated value when the originally allocated value is a JS primitive (String, Boolean, Number).
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   172
        // (result, this, [callee, ]args...) x (this, [callee, ]args...) => (this, [callee, ]args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   173
        final MethodHandle filtered = MH.foldArguments(MH.dropArguments(NEWFILTER, 2, ctorArgs), returnsObject);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   174
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   175
        // allocate() takes a ScriptFunction and returns a newly allocated ScriptObject...
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   176
        if (needsCallee) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   177
            // ...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
   178
            // the newly allocated object in the arguments, so (this, callee, args...) x (callee) => (callee, args...),
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   179
            // or...
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   180
            return MH.foldArguments(filtered, ScriptFunction.ALLOCATE);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   181
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   182
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   183
        // ...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
   184
        // (this, args...) filter (callee) => (callee, args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   185
        return MH.filterArguments(filtered, 0, ScriptFunction.ALLOCATE);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   186
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   187
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   188
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   189
     * Permutes the parameters in the method handle from {@code (callee, this, ...)} to {@code (this, callee, ...)}.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   190
     * Used when creating a constructor handle.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   191
     * @param mh a method handle with order of arguments {@code (callee, this, ...)}
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   192
     * @return a method handle with order of arguments {@code (this, callee, ...)}
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   193
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   194
    private static MethodHandle swapCalleeAndThis(final MethodHandle mh) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   195
        final MethodType type = mh.type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   196
        assert type.parameterType(0) == ScriptFunction.class : type;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   197
        assert type.parameterType(1) == Object.class : type;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   198
        final MethodType newType = type.changeParameterType(0, Object.class).changeParameterType(1, ScriptFunction.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   199
        final int[] reorder = new int[type.parameterCount()];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   200
        reorder[0] = 1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   201
        assert reorder[1] == 0;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   202
        for (int i = 2; i < reorder.length; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   203
            reorder[i] = i;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   204
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   205
        return MethodHandles.permuteArguments(mh, newType, reorder);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   206
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   207
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   208
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   209
     * 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
   210
     * 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
   211
     * 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
   212
     * {@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
   213
     * 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
   214
     * to always point at the latest generated code version.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   215
     * @return a guaranteed composable constructor method handle for this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   216
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   217
    MethodHandle createComposableConstructor() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   218
        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
   219
    }
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
   220
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
   221
    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
   222
        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
   223
    }
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
   224
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
   225
    MethodType type() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   226
        return invoker.type();
20570
b1c8d1e8013a 8025965: Specialized functions with same weight replace each other in TreeSet
hannesw
parents: 17756
diff changeset
   227
    }
b1c8d1e8013a 8025965: Specialized functions with same weight replace each other in TreeSet
hannesw
parents: 17756
diff changeset
   228
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   229
    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
   230
        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
   231
    }
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
   232
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
   233
    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
   234
        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
   235
            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
   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
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
        int weight = Type.typeFor(type.returnType()).getWeight();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   239
        for (int i = 0 ; i < type.parameterCount() ; i++) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   240
            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
   241
            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
   242
            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
   243
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   244
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   245
        weight += type.parameterCount(); //more params outweigh few parameters
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   246
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
   247
        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
   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
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
    private static boolean isVarArgsType(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
   251
        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
   252
        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
   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
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   255
    static boolean moreGenericThan(final MethodType mt0, final MethodType mt1) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   256
        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
   257
    }
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
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   259
    boolean betterThanFinal(final CompiledFunction other, final MethodType callSiteMethodType) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   260
        // Prefer anything over nothing, as we can't compile new versions.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   261
        if (other == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   262
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   263
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   264
        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
   265
    }
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
   266
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
   267
    static boolean betterThanFinal(final MethodType thisMethodType, final MethodType otherMethodType, final MethodType callSiteMethodType) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   268
        final int thisParamCount = getParamCount(thisMethodType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   269
        final int otherParamCount = getParamCount(otherMethodType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   270
        final int callSiteRawParamCount = getParamCount(callSiteMethodType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   271
        final boolean csVarArg = callSiteRawParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   272
        // Subtract 1 for callee for non-vararg call sites
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   273
        final int callSiteParamCount = csVarArg ? callSiteRawParamCount : callSiteRawParamCount - 1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   274
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   275
        // Prefer the function that discards less parameters
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   276
        final int thisDiscardsParams = Math.max(callSiteParamCount - thisParamCount, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   277
        final int otherDiscardsParams = Math.max(callSiteParamCount - otherParamCount, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   278
        if(thisDiscardsParams < otherDiscardsParams) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   279
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   280
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   281
        if(thisDiscardsParams > otherDiscardsParams) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   282
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   283
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   284
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   285
        final boolean thisVarArg = thisParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   286
        final boolean otherVarArg = otherParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   287
        if(!(thisVarArg && otherVarArg && csVarArg)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   288
            // At least one of them isn't vararg
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   289
            final Type[] thisType = toTypeWithoutCallee(thisMethodType, 0); // Never has callee
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   290
            final Type[] otherType = toTypeWithoutCallee(otherMethodType, 0); // Never has callee
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   291
            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
   292
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   293
            int narrowWeightDelta = 0;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   294
            int widenWeightDelta = 0;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   295
            final int minParamsCount = Math.min(Math.min(thisParamCount, otherParamCount), callSiteParamCount);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   296
            for(int i = 0; i < minParamsCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   297
                final int callSiteParamWeight = getParamType(i, callSiteType, csVarArg).getWeight();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   298
                // Delta is negative for narrowing, positive for widening
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   299
                final int thisParamWeightDelta = getParamType(i, thisType, thisVarArg).getWeight() - callSiteParamWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   300
                final int otherParamWeightDelta = getParamType(i, otherType, otherVarArg).getWeight() - callSiteParamWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   301
                // Only count absolute values of narrowings
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   302
                narrowWeightDelta += Math.max(-thisParamWeightDelta, 0) - Math.max(-otherParamWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   303
                // Only count absolute values of widenings
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   304
                widenWeightDelta += Math.max(thisParamWeightDelta, 0) - Math.max(otherParamWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   305
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   306
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   307
            // 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
   308
            // to receive Undefined un-narrowed in the remaining arguments.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   309
            if(!thisVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   310
                for(int i = callSiteParamCount; i < thisParamCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   311
                    narrowWeightDelta += Math.max(Type.OBJECT.getWeight() - thisType[i].getWeight(), 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   312
                }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   313
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   314
            if(!otherVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   315
                for(int i = callSiteParamCount; i < otherParamCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   316
                    narrowWeightDelta -= Math.max(Type.OBJECT.getWeight() - otherType[i].getWeight(), 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   317
                }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   318
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   319
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   320
            // Prefer function that narrows less
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   321
            if(narrowWeightDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   322
                return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   323
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   324
            if(narrowWeightDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   325
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   326
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   327
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   328
            // Prefer function that widens less
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   329
            if(widenWeightDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   330
                return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   331
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   332
            if(widenWeightDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   333
                return false;
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
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   337
        // Prefer the function that exactly matches the arity of the call site.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   338
        if(thisParamCount == callSiteParamCount && otherParamCount != callSiteParamCount) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   339
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   340
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   341
        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
   342
            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
   343
        }
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
   344
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   345
        // 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
   346
        // 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
   347
        // 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
   348
        // really have arbitrary arity.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   349
        if(thisVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   350
            if(!otherVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   351
                return true; //
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   352
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   353
        } else if(otherVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   354
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   355
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   356
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   357
        // Neither is variable arity; chose the one that has less extra parameters.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   358
        final int fnParamDelta = thisParamCount - otherParamCount;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   359
        if(fnParamDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   360
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   361
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   362
        if(fnParamDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   363
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   364
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   365
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   366
        final int callSiteRetWeight = Type.typeFor(callSiteMethodType.returnType()).getWeight();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   367
        // Delta is negative for narrower return type, positive for wider return type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   368
        final int thisRetWeightDelta = Type.typeFor(thisMethodType.returnType()).getWeight() - callSiteRetWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   369
        final int otherRetWeightDelta = Type.typeFor(otherMethodType.returnType()).getWeight() - callSiteRetWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   370
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   371
        // Prefer function that returns a less wide return type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   372
        final int widenRetDelta = Math.max(thisRetWeightDelta, 0) - Math.max(otherRetWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   373
        if(widenRetDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   374
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   375
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   376
        if(widenRetDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   377
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   378
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   379
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   380
        // Prefer function that returns a less narrow return type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   381
        final int narrowRetDelta = Math.max(-thisRetWeightDelta, 0) - Math.max(-otherRetWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   382
        if(narrowRetDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   383
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   384
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   385
        if(narrowRetDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   386
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   387
        }
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
   388
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   389
        throw new AssertionError(thisMethodType + " identically applicable to " + otherMethodType + " for " + callSiteMethodType); // Signatures are identical
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   390
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   391
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
   392
    private static Type[] toTypeWithoutCallee(final MethodType type, final int thisIndex) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   393
        final int paramCount = type.parameterCount();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   394
        final Type[] t = new Type[paramCount - thisIndex];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   395
        for(int i = thisIndex; i < paramCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   396
            t[i - thisIndex] = Type.typeFor(type.parameterType(i));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   397
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   398
        return t;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   399
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   400
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
   401
    private static Type getParamType(final int i, final Type[] paramTypes, final boolean isVarArg) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   402
        final int fixParamCount = paramTypes.length - (isVarArg ? 1 : 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   403
        if(i < fixParamCount) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   404
            return paramTypes[i];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   405
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   406
        assert isVarArg;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   407
        return ((ArrayType)(paramTypes[paramTypes.length - 1])).getElementType();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   408
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   409
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   410
    boolean matchesCallSite(final MethodType callSiteType) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   411
        if(!ScriptEnvironment.globalOptimistic()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   412
            // Without optimistic recompilation, always choose the first eagerly compiled version.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   413
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   414
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   415
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   416
        final MethodType type = type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   417
        final int fnParamCount = getParamCount(type);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   418
        final boolean isVarArg = fnParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   419
        if(isVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   420
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   421
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   422
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   423
        final int csParamCount = getParamCount(callSiteType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   424
        final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   425
        final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   426
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
   427
        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
   428
        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
   429
        // We must match all incoming parameters, except "this". Starting from 1 to skip "this".
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   430
        for(int i = 1; i < minParams; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   431
            final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   432
            final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(callSiteType.parameterType(i + 1));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   433
            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
   434
                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
   435
            }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   436
        }
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
   437
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   438
        // Must match any undefined parameters to Object type.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   439
        for(int i = minParams; i < fnParamCountNoCallee; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   440
            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
   441
                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
   442
            }
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
   443
        }
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
   444
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   445
        return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   446
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   447
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   448
    private static int getParamCount(final MethodType type) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   449
        final int paramCount = type.parameterCount();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   450
        return type.parameterType(paramCount - 1).isArray() ? Integer.MAX_VALUE : paramCount;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   451
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   452
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   453
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   454
     * 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
   455
     * guard any linking to the function's invoker or constructor.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   456
     * @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
   457
     * function has no optimistic assumptions.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   458
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   459
    SwitchPoint getOptimisticAssumptionsSwitchPoint() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   460
        return isOptimistic() ? optimismInfo.optimisticAssumptions : null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   461
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   462
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   463
    boolean isOptimistic() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   464
        return optimismInfo != null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   465
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   466
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
   467
    private MethodHandle createComposableInvoker(final boolean isConstructor) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   468
        final MethodHandle handle = getInvokerOrConstructor(isConstructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   469
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   470
        // 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
   471
        // directly.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   472
        if(!isOptimistic()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   473
            return handle;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   474
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   475
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   476
        // 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
   477
        // to the compiled function's changed target whenever the optimistic assumptions are invalidated.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   478
        final CallSite cs = new MutableCallSite(handle.type());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   479
        relinkComposableInvoker(cs, this, isConstructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   480
        return cs.dynamicInvoker();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   481
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   482
    private static void relinkComposableInvoker(final CallSite cs, final CompiledFunction inv, final boolean constructor) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   483
        final MethodHandle handle = inv.getInvokerOrConstructor(constructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   484
        final SwitchPoint assumptions = inv.getOptimisticAssumptionsSwitchPoint();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   485
        final MethodHandle target;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   486
        if(assumptions == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   487
            target = handle;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   488
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   489
            // 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
   490
            // 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
   491
            // 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
   492
            // switch point before recompilation, and only creating the new one after recompilation is by design.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   493
            // TODO: We need to think about thread safety of CompiledFunction objects.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   494
            assert !assumptions.hasBeenInvalidated();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   495
            final MethodHandle relink = MethodHandles.insertArguments(RELINK_COMPOSABLE_INVOKER, 0, cs, inv, constructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   496
            target = assumptions.guardWithTest(handle, MethodHandles.foldArguments(cs.dynamicInvoker(), relink));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   497
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   498
        cs.setTarget(target);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   499
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   500
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
   501
    private MethodHandle getInvokerOrConstructor(final boolean selectCtor) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   502
        return selectCtor ? getConstructor() : createInvokerForPessimisticCaller();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   503
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   504
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   505
    MethodHandle createInvoker(final Class<?> callSiteReturnType, final int callerProgramPoint) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   506
        final boolean isOptimistic = isOptimistic();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   507
        MethodHandle handleRewriteException = isOptimistic ? createRewriteExceptionHandler() : null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   508
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   509
        MethodHandle inv = invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   510
        if(isValid(callerProgramPoint)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   511
            inv = OptimisticReturnFilters.filterOptimisticReturnValue(inv, callSiteReturnType, callerProgramPoint);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   512
            if(callSiteReturnType.isPrimitive() && handleRewriteException != null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   513
                // because handleRewriteException always returns Object
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   514
                handleRewriteException = OptimisticReturnFilters.filterOptimisticReturnValue(handleRewriteException,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   515
                        callSiteReturnType, callerProgramPoint);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   516
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   517
        } else if(isOptimistic) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   518
            // 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
   519
            // 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
   520
            inv = changeReturnType(inv, callSiteReturnType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   521
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   522
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   523
        if(isOptimistic) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   524
            assert handleRewriteException != null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   525
            final MethodHandle typedHandleRewriteException = changeReturnType(handleRewriteException, inv.type().returnType());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   526
            if(USE_FAST_REWRITE) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   527
                return CatchExceptionCombinator.catchException(inv, RewriteException.class, typedHandleRewriteException);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   528
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   529
            return MH.catchException(inv, RewriteException.class, typedHandleRewriteException);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   530
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   531
        return inv;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   532
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   533
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   534
    private MethodHandle createRewriteExceptionHandler() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   535
        return MH.foldArguments(RESTOF_INVOKER, MH.insertArguments(HANDLE_REWRITE_EXCEPTION, 0, this, optimismInfo));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   536
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   537
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
   538
    private static MethodHandle changeReturnType(final MethodHandle mh, final Class<?> newReturnType) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   539
        return Bootstrap.getLinkerServices().asType(mh, mh.type().changeReturnType(newReturnType));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   540
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   541
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   542
    @SuppressWarnings("unused")
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   543
    private static MethodHandle handleRewriteException(final CompiledFunction function, final OptimismInfo oldOptimismInfo, final RewriteException re) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   544
        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
   545
    }
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
   546
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   547
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   548
     * 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
   549
     * 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
   550
     * executing a rest-of method to complete the execution with the deoptimized version.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   551
     * @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
   552
     * 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
   553
     * function when inner invocations of the function have completely deoptimized it.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   554
     * @param re the rewrite exception that was raised
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   555
     * @return the method handle for the rest-of method, for folding composition.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   556
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   557
    private MethodHandle handleRewriteException(final OptimismInfo oldOptimismInfo, final RewriteException re) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   558
        final MethodType type = type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   559
        // 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
   560
        // this function doesn't have a callee parameter.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   561
        final MethodType callSiteType = type.parameterType(0) == ScriptFunction.class ? type : type.insertParameterTypes(0, ScriptFunction.class);
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
   562
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   563
        final FunctionNode fn = oldOptimismInfo.recompile(callSiteType, re);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   564
        LOG.info("    RewriteException ", re.getMessageShort());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   565
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   566
        // It didn't necessarily recompile, e.g. for an outer invocation of a recursive function if we already
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   567
        // recompiled a deoptimized version for an inner invocation.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   568
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   569
        final boolean isOptimistic;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   570
        if (fn != null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   571
            //is recompiled
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   572
            assert optimismInfo == oldOptimismInfo;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   573
            isOptimistic = fn.isOptimistic();
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
   574
            if (LOG.isEnabled()) {
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
   575
                LOG.info("Recompiled '", fn.getName(), "' (", Debug.id(this), ")", isOptimistic ? " remains optimistic." : " is no longer optimistic.");
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
   576
            }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   577
            final MethodHandle newInvoker = oldOptimismInfo.data.lookup(fn);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   578
            invoker = newInvoker.asType(type.changeReturnType(newInvoker.type().returnType()));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   579
            constructor = null; // Will be regenerated when needed
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   580
            // Note that we only adjust the switch point after we set the invoker/constructor. This is important.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   581
            if(isOptimistic) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   582
                // Otherwise, set a new switch point.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   583
                oldOptimismInfo.newOptimisticAssumptions();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   584
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   585
                // If we got to a point where we no longer have optimistic assumptions, let the optimism info go.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   586
                optimismInfo = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   587
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   588
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   589
            isOptimistic = isOptimistic();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   590
            assert !isOptimistic || optimismInfo == oldOptimismInfo;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   591
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   592
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   593
        final MethodHandle restOf = changeReturnType(oldOptimismInfo.compileRestOfMethod(callSiteType, re), Object.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   594
        // If rest-of is itself optimistic, we must make sure that we can repeat a deoptimization if it, too hits an exception.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   595
        return isOptimistic ? MH.catchException(restOf, RewriteException.class, createRewriteExceptionHandler()) : restOf;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   596
    }
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
   597
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   598
    private static class OptimismInfo {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   599
        // TODO: this is pointing to its owning ScriptFunctionData. Re-evaluate if that's okay.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   600
        private final RecompilableScriptFunctionData data;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   601
        private final Map<Integer, Type> invalidatedProgramPoints = new TreeMap<>();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   602
        private SwitchPoint optimisticAssumptions;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   603
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   604
        OptimismInfo(final RecompilableScriptFunctionData data) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   605
            this.data = data;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   606
            newOptimisticAssumptions();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   607
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   608
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   609
        private void newOptimisticAssumptions() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   610
            optimisticAssumptions = new SwitchPoint();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   611
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   612
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   613
        FunctionNode recompile(final MethodType callSiteType, final RewriteException e) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   614
            final Type retType = e.getReturnType();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   615
            final Type previousFailedType = invalidatedProgramPoints.put(e.getProgramPoint(), retType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   616
            if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   617
                final StackTraceElement[] stack = e.getStackTrace();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   618
                final String functionId = stack.length == 0 ? data.getName() : (stack[0].getClassName() + "." + stack[0].getMethodName());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   619
                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.");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   620
                return null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   621
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   622
            SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions });
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   623
            return data.compile(callSiteType, invalidatedProgramPoints, "Deoptimizing recompilation");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   624
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   625
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   626
        MethodHandle compileRestOfMethod(final MethodType callSiteType, final RewriteException e) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   627
            final int[] prevEntryPoints = e.getPreviousContinuationEntryPoints();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   628
            final int[] entryPoints;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   629
            if(prevEntryPoints == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   630
                entryPoints = new int[1];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   631
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   632
                final int l = prevEntryPoints.length;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   633
                entryPoints = new int[l + 1];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   634
                System.arraycopy(prevEntryPoints, 0, entryPoints, 1, l);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   635
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   636
            entryPoints[0] = e.getProgramPoint();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   637
            return data.compileRestOfMethod(callSiteType, invalidatedProgramPoints, entryPoints);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   638
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   639
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   640
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   641
    @SuppressWarnings("unused")
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   642
    private static Object newFilter(final Object result, final Object allocation) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   643
        return (result instanceof ScriptObject || !JSType.isPrimitive(result))? result : allocation;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   644
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   645
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   646
    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   647
        return MH.findStatic(MethodHandles.lookup(), CompiledFunction.class, name, MH.type(rtype, types));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   648
    }
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
   649
}