nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/CompiledFunction.java
author lagergren
Fri, 26 Sep 2014 18:47:20 +0200
changeset 26886 18c744ab4df2
parent 26768 751b0f427090
child 26888 2722a9c501a5
permissions -rw-r--r--
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this Reviewed-by: attila, hannesw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
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
    31
import java.lang.invoke.MethodHandle;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    32
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
    33
import java.lang.invoke.MethodType;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    34
import java.lang.invoke.MutableCallSite;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    35
import java.lang.invoke.SwitchPoint;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    36
import java.util.Collection;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    37
import java.util.Collections;
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    38
import java.util.Iterator;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    39
import java.util.Map;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    40
import java.util.TreeMap;
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
    41
import java.util.function.Supplier;
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24729
diff changeset
    42
import java.util.logging.Level;
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
    43
import jdk.internal.dynalink.linker.GuardedInvocation;
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    44
import jdk.nashorn.internal.codegen.Compiler;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    45
import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
    46
import jdk.nashorn.internal.codegen.TypeMap;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    47
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
    48
import jdk.nashorn.internal.codegen.types.Type;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    49
import jdk.nashorn.internal.ir.FunctionNode;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    50
import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
24742
a9afb384e654 8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents: 24741
diff changeset
    51
import jdk.nashorn.internal.runtime.events.RecompilationEvent;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    52
import jdk.nashorn.internal.runtime.linker.Bootstrap;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
    53
import jdk.nashorn.internal.runtime.logging.DebugLogger;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    54
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    55
/**
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
 * 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
    57
 * 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
    58
 */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    59
final class CompiledFunction {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
    60
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    61
    private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    62
    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
    63
    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
    64
    private static final MethodHandle RESTOF_INVOKER = MethodHandles.exactInvoker(MethodType.methodType(Object.class, RewriteException.class));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    65
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
    66
    private final DebugLogger log;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    67
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    68
    static final Collection<CompiledFunction> NO_FUNCTIONS = Collections.emptySet();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    69
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    70
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    71
     * The method type may be more specific than the invoker, if. e.g.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    72
     * the invoker is guarded, and a guard with a generic object only
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    73
     * fallback, while the target is more specific, we still need the
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    74
     * more specific type for sorting
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    75
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    76
    private MethodHandle invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    77
    private MethodHandle constructor;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    78
    private OptimismInfo optimismInfo;
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
    79
    private final int flags; // from FunctionNode
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
    80
    private final MethodType callSiteType;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    81
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    82
    private final Specialization specialization;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    83
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    84
    CompiledFunction(final MethodHandle invoker) {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    85
        this(invoker, null, null);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    86
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    87
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    88
    static CompiledFunction createBuiltInConstructor(final MethodHandle invoker, final Specialization specialization) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    89
        return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)), specialization);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    90
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    91
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    92
    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor, final Specialization specialization) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    93
        this(invoker, constructor, 0, null, specialization, DebugLogger.DISABLED_LOGGER);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    94
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
    95
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    96
    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor, final int flags, final MethodType callSiteType, final Specialization specialization, final DebugLogger log) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    97
        this.specialization = specialization;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    98
        if (specialization != null && specialization.isOptimistic()) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
    99
            /*
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   100
             * An optimistic builtin with isOptimistic=true works like any optimistic generated function, i.e. it
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   101
             * can throw unwarranted optimism exceptions. As native functions trivially can't have parts of them
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   102
             * regenerated as restof methods, this only works if the methods are atomic/functional in their behavior
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   103
             * and doesn't modify state before an UOE can be thrown. If they aren't, we can reexecute a wider version
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   104
             * of the same builtin in a recompilation handler for FinalScriptFunctionData. There are several
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   105
             * candidate methods in Native* that would benefit from this, but I haven't had time to implement any
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   106
             * of them currently. In order to fit in with the relinking framework, the current thinking is
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   107
             * that the methods still take a program point to fit in with other optimistic functions, but
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   108
             * it is set to "first", which is the beginning of the method. The relinker can tell the difference
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   109
             * between builtin and JavaScript functions. This might change. TODO
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   110
             */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   111
            this.invoker = MH.insertArguments(invoker, invoker.type().parameterCount() - 1, UnwarrantedOptimismException.FIRST_PROGRAM_POINT);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   112
            throw new AssertionError("Optimistic (UnwarrantedOptimismException throwing) builtin functions are currently not in use");
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   113
        }
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   114
        this.invoker = invoker;
17756
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17518
diff changeset
   115
        this.constructor = constructor;
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   116
        this.flags = flags;
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   117
        this.callSiteType = callSiteType;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   118
        this.log = log;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   119
    }
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
   120
25236
fac419f1e889 8046921: Deoptimization type information peristence
attila
parents: 24779
diff changeset
   121
    CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData,
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   122
            final Map<Integer, Type> invalidatedProgramPoints, final MethodType callSiteType, final int flags) {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   123
        this(invoker, null, flags, callSiteType, null, functionData.getLogger());
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   124
        if ((flags & FunctionNode.IS_DEOPTIMIZABLE) != 0) {
25236
fac419f1e889 8046921: Deoptimization type information peristence
attila
parents: 24779
diff changeset
   125
            optimismInfo = new OptimismInfo(functionData, invalidatedProgramPoints);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   126
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   127
            optimismInfo = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   128
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   129
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   130
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   131
    static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   132
        return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)), null);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   133
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   134
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   135
    boolean isSpecialization() {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   136
        return specialization != null;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   137
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   138
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   139
    boolean hasLinkLogic() {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   140
        return getLinkLogicClass() != null;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   141
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   142
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   143
    Class<? extends LinkLogic> getLinkLogicClass() {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   144
        if (isSpecialization()) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   145
            final Class<? extends LinkLogic> linkLogicClass = specialization.getLinkLogicClass();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   146
            assert !LinkLogic.isEmpty(linkLogicClass) : "empty link logic classes should have been removed by nasgen";
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   147
            return linkLogicClass;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   148
        }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   149
        return null;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   150
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   151
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   152
    int getFlags() {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   153
        return flags;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   154
    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   155
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   156
    /**
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   157
     * An optimistic specialization is one that can throw UnwarrantedOptimismException.
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   158
     * This is allowed for native methods, as long as they are functional, i.e. don't change
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   159
     * any state between entering and throwing the UOE. Then we can re-execute a wider version
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   160
     * of the method in the continuation. Rest-of method generation for optimistic builtins is
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   161
     * of course not possible, but this approach works and fits into the same relinking
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   162
     * framework
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   163
     *
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   164
     * @return true if optimistic builtin
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   165
     */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   166
    boolean isOptimistic() {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   167
        return isSpecialization() ? specialization.isOptimistic() : false;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   168
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   169
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   170
    boolean isApplyToCall() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   171
        return (flags & FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION) != 0;
24740
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   172
    }
26791be09688 8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents: 24738
diff changeset
   173
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   174
    boolean isVarArg() {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   175
        return isVarArgsType(invoker.type());
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   176
    }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   177
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
   178
    @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
   179
    public String toString() {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   180
        final StringBuilder sb = new StringBuilder();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   181
        final Class<? extends LinkLogic> linkLogicClass = getLinkLogicClass();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   182
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   183
        sb.append("[invokerType=").
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   184
            append(invoker.type()).
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   185
            append(" ctor=").
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   186
            append(constructor).
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   187
            append(" weight=").
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   188
            append(weight()).
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   189
            append(" linkLogic=").
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   190
            append(linkLogicClass != null ? linkLogicClass.getSimpleName() : "none");
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   191
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   192
        return sb.toString();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   193
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   194
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   195
    boolean needsCallee() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   196
        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
   197
    }
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
   198
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   199
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   200
     * 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
   201
     * 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
   202
     * invalidation. If this compiled function is non-optimistic, then it returns the same value as
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   203
     * {@link #getInvokerOrConstructor(boolean)}. However, if the function is optimistic, then this handle will
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   204
     * incur an overhead as it will add an intermediate internal call site that can relink itself when the function
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   205
     * needs to regenerate its code to always point at the latest generated code version.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   206
     * @return a guaranteed composable invoker method handle for this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   207
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   208
    MethodHandle createComposableInvoker() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   209
        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
   210
    }
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
   211
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   212
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   213
     * 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
   214
     * 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
   215
     * you can ensure that the composition is guarded by {@link #getOptimisticAssumptionsSwitchPoint()} if it's
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   216
     * 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
   217
     * all other cases, use {@link #createComposableConstructor()}.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   218
     * @return a direct constructor method handle for this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   219
     */
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   220
    private MethodHandle getConstructor() {
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   221
        if (constructor == null) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   222
            constructor = createConstructorFromInvoker(createInvokerForPessimisticCaller());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   223
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   224
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
   225
        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
   226
    }
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
   227
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   228
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   229
     * 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
   230
     * program point available).
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   231
     * @return a version of the invoker intended for a pessimistic caller.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   232
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   233
    private MethodHandle createInvokerForPessimisticCaller() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   234
        return createInvoker(Object.class, INVALID_PROGRAM_POINT);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   235
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   236
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   237
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   238
     * Compose a constructor from an invoker.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   239
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   240
     * @param invoker         invoker
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   241
     * @return the composed constructor
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   242
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   243
    private static MethodHandle createConstructorFromInvoker(final MethodHandle invoker) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   244
        final boolean needsCallee = ScriptFunctionData.needsCallee(invoker);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   245
        // 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
   246
        // "this" in the first argument position is what allows the elegant folded composition of
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   247
        // (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
   248
        // always returns Object.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   249
        final MethodHandle swapped = needsCallee ? swapCalleeAndThis(invoker) : invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   250
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   251
        final MethodHandle returnsObject = MH.asType(swapped, swapped.type().changeReturnType(Object.class));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   252
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   253
        final MethodType ctorType = returnsObject.type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   254
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   255
        // 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
   256
        // captured as "allocation" parameter of NEWFILTER after we fold the constructor into it.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   257
        // (this, [callee, ]args...) => ([callee, ]args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   258
        final Class<?>[] ctorArgs = ctorType.dropParameterTypes(0, 1).parameterArray();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   259
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   260
        // Fold constructor into newFilter that replaces the return value from the constructor with the originally
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   261
        // allocated value when the originally allocated value is a JS primitive (String, Boolean, Number).
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   262
        // (result, this, [callee, ]args...) x (this, [callee, ]args...) => (this, [callee, ]args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   263
        final MethodHandle filtered = MH.foldArguments(MH.dropArguments(NEWFILTER, 2, ctorArgs), returnsObject);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   264
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   265
        // allocate() takes a ScriptFunction and returns a newly allocated ScriptObject...
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   266
        if (needsCallee) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   267
            // ...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
   268
            // the newly allocated object in the arguments, so (this, callee, args...) x (callee) => (callee, args...),
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   269
            // or...
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   270
            return MH.foldArguments(filtered, ScriptFunction.ALLOCATE);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   271
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   272
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   273
        // ...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
   274
        // (this, args...) filter (callee) => (callee, args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   275
        return MH.filterArguments(filtered, 0, ScriptFunction.ALLOCATE);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   276
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   277
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   278
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   279
     * Permutes the parameters in the method handle from {@code (callee, this, ...)} to {@code (this, callee, ...)}.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   280
     * Used when creating a constructor handle.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   281
     * @param mh a method handle with order of arguments {@code (callee, this, ...)}
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   282
     * @return a method handle with order of arguments {@code (this, callee, ...)}
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   283
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   284
    private static MethodHandle swapCalleeAndThis(final MethodHandle mh) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   285
        final MethodType type = mh.type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   286
        assert type.parameterType(0) == ScriptFunction.class : type;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   287
        assert type.parameterType(1) == Object.class : type;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   288
        final MethodType newType = type.changeParameterType(0, Object.class).changeParameterType(1, ScriptFunction.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   289
        final int[] reorder = new int[type.parameterCount()];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   290
        reorder[0] = 1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   291
        assert reorder[1] == 0;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   292
        for (int i = 2; i < reorder.length; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   293
            reorder[i] = i;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   294
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   295
        return MethodHandles.permuteArguments(mh, newType, reorder);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   296
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   297
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   298
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   299
     * 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
   300
     * 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
   301
     * 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
   302
     * {@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
   303
     * 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
   304
     * to always point at the latest generated code version.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   305
     * @return a guaranteed composable constructor method handle for this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   306
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   307
    MethodHandle createComposableConstructor() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   308
        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
   309
    }
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
   310
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
   311
    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
   312
        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
   313
    }
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
   314
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
   315
    MethodType type() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   316
        return invoker.type();
20570
b1c8d1e8013a 8025965: Specialized functions with same weight replace each other in TreeSet
hannesw
parents: 17756
diff changeset
   317
    }
b1c8d1e8013a 8025965: Specialized functions with same weight replace each other in TreeSet
hannesw
parents: 17756
diff changeset
   318
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   319
    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
   320
        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
   321
    }
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
   322
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
   323
    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
   324
        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
   325
            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
   326
        }
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
   327
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
   328
        int weight = Type.typeFor(type.returnType()).getWeight();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   329
        for (int i = 0 ; i < type.parameterCount() ; i++) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   330
            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
   331
            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
   332
            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
   333
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   334
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   335
        weight += type.parameterCount(); //more params outweigh few parameters
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   336
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
   337
        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
   338
    }
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
   339
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   340
    static boolean isVarArgsType(final MethodType type) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff changeset
   341
        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
   342
        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
   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
    static boolean moreGenericThan(final MethodType mt0, final MethodType mt1) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   346
        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
   347
    }
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
   348
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   349
    boolean betterThanFinal(final CompiledFunction other, final MethodType callSiteMethodType) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   350
        // Prefer anything over nothing, as we can't compile new versions.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   351
        if (other == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   352
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   353
        }
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   354
        return betterThanFinal(this, other, 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
   355
    }
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
   356
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   357
    private static boolean betterThanFinal(final CompiledFunction cf, final CompiledFunction other, final MethodType callSiteMethodType) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   358
        final MethodType thisMethodType  = cf.type();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   359
        final MethodType otherMethodType = other.type();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   360
        final int thisParamCount = getParamCount(thisMethodType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   361
        final int otherParamCount = getParamCount(otherMethodType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   362
        final int callSiteRawParamCount = getParamCount(callSiteMethodType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   363
        final boolean csVarArg = callSiteRawParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   364
        // Subtract 1 for callee for non-vararg call sites
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   365
        final int callSiteParamCount = csVarArg ? callSiteRawParamCount : callSiteRawParamCount - 1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   366
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   367
        // Prefer the function that discards less parameters
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   368
        final int thisDiscardsParams = Math.max(callSiteParamCount - thisParamCount, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   369
        final int otherDiscardsParams = Math.max(callSiteParamCount - otherParamCount, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   370
        if(thisDiscardsParams < otherDiscardsParams) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   371
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   372
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   373
        if(thisDiscardsParams > otherDiscardsParams) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   374
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   375
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   376
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   377
        final boolean thisVarArg = thisParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   378
        final boolean otherVarArg = otherParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   379
        if(!(thisVarArg && otherVarArg && csVarArg)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   380
            // At least one of them isn't vararg
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   381
            final Type[] thisType = toTypeWithoutCallee(thisMethodType, 0); // Never has callee
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   382
            final Type[] otherType = toTypeWithoutCallee(otherMethodType, 0); // Never has callee
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   383
            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
   384
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   385
            int narrowWeightDelta = 0;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   386
            int widenWeightDelta = 0;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   387
            final int minParamsCount = Math.min(Math.min(thisParamCount, otherParamCount), callSiteParamCount);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   388
            for(int i = 0; i < minParamsCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   389
                final int callSiteParamWeight = getParamType(i, callSiteType, csVarArg).getWeight();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   390
                // Delta is negative for narrowing, positive for widening
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   391
                final int thisParamWeightDelta = getParamType(i, thisType, thisVarArg).getWeight() - callSiteParamWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   392
                final int otherParamWeightDelta = getParamType(i, otherType, otherVarArg).getWeight() - callSiteParamWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   393
                // Only count absolute values of narrowings
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   394
                narrowWeightDelta += Math.max(-thisParamWeightDelta, 0) - Math.max(-otherParamWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   395
                // Only count absolute values of widenings
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   396
                widenWeightDelta += Math.max(thisParamWeightDelta, 0) - Math.max(otherParamWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   397
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   398
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   399
            // 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
   400
            // to receive Undefined un-narrowed in the remaining arguments.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   401
            if(!thisVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   402
                for(int i = callSiteParamCount; i < thisParamCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   403
                    narrowWeightDelta += Math.max(Type.OBJECT.getWeight() - thisType[i].getWeight(), 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   404
                }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   405
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   406
            if(!otherVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   407
                for(int i = callSiteParamCount; i < otherParamCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   408
                    narrowWeightDelta -= Math.max(Type.OBJECT.getWeight() - otherType[i].getWeight(), 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   409
                }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   410
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   411
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   412
            // Prefer function that narrows less
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   413
            if(narrowWeightDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   414
                return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   415
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   416
            if(narrowWeightDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   417
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   418
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   419
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   420
            // Prefer function that widens less
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   421
            if(widenWeightDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   422
                return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   423
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   424
            if(widenWeightDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   425
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   426
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   427
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   428
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   429
        // Prefer the function that exactly matches the arity of the call site.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   430
        if(thisParamCount == callSiteParamCount && otherParamCount != callSiteParamCount) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   431
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   432
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   433
        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
   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
        }
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
   436
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   437
        // 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
   438
        // 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
   439
        // 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
   440
        // really have arbitrary arity.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   441
        if(thisVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   442
            if(!otherVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   443
                return true; //
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   444
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   445
        } else if(otherVarArg) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   446
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   447
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   448
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   449
        // Neither is variable arity; chose the one that has less extra parameters.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   450
        final int fnParamDelta = thisParamCount - otherParamCount;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   451
        if(fnParamDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   452
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   453
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   454
        if(fnParamDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   455
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   456
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   457
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   458
        final int callSiteRetWeight = Type.typeFor(callSiteMethodType.returnType()).getWeight();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   459
        // Delta is negative for narrower return type, positive for wider return type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   460
        final int thisRetWeightDelta = Type.typeFor(thisMethodType.returnType()).getWeight() - callSiteRetWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   461
        final int otherRetWeightDelta = Type.typeFor(otherMethodType.returnType()).getWeight() - callSiteRetWeight;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   462
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   463
        // Prefer function that returns a less wide return type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   464
        final int widenRetDelta = Math.max(thisRetWeightDelta, 0) - Math.max(otherRetWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   465
        if(widenRetDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   466
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   467
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   468
        if(widenRetDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   469
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   470
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   471
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   472
        // Prefer function that returns a less narrow return type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   473
        final int narrowRetDelta = Math.max(-thisRetWeightDelta, 0) - Math.max(-otherRetWeightDelta, 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   474
        if(narrowRetDelta < 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   475
            return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   476
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   477
        if(narrowRetDelta > 0) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   478
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   479
        }
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
   480
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   481
        //if they are equal, pick the specialized one first
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   482
        if (cf.isSpecialization() != other.isSpecialization()) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   483
            return cf.isSpecialization(); //always pick the specialized version if we can
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   484
        }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   485
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   486
        if (cf.isSpecialization() && other.isSpecialization()) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   487
            return cf.getLinkLogicClass() != null; //pick link logic specialization above generic specializations
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   488
        }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   489
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   490
        // Signatures are identical
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26500
diff changeset
   491
        throw new AssertionError(thisMethodType + " identically applicable to " + otherMethodType + " for " + callSiteMethodType);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   492
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   493
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
   494
    private static Type[] toTypeWithoutCallee(final MethodType type, final int thisIndex) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   495
        final int paramCount = type.parameterCount();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   496
        final Type[] t = new Type[paramCount - thisIndex];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   497
        for(int i = thisIndex; i < paramCount; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   498
            t[i - thisIndex] = Type.typeFor(type.parameterType(i));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   499
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   500
        return t;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   501
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   502
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
   503
    private static Type getParamType(final int i, final Type[] paramTypes, final boolean isVarArg) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   504
        final int fixParamCount = paramTypes.length - (isVarArg ? 1 : 0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   505
        if(i < fixParamCount) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   506
            return paramTypes[i];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   507
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   508
        assert isVarArg;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   509
        return ((ArrayType)paramTypes[paramTypes.length - 1]).getElementType();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   510
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   511
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   512
    boolean matchesCallSite(final MethodType other, final boolean pickVarArg) {
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   513
        if (other.equals(this.callSiteType)) {
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   514
            return true;
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   515
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   516
        final MethodType type  = type();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   517
        final int fnParamCount = getParamCount(type);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   518
        final boolean isVarArg = fnParamCount == Integer.MAX_VALUE;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   519
        if (isVarArg) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   520
            return pickVarArg;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   521
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   522
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   523
        final int csParamCount = getParamCount(other);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   524
        final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   525
        final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   526
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
   527
        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
   528
        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
   529
        // We must match all incoming parameters, except "this". Starting from 1 to skip "this".
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   530
        for(int i = 1; i < minParams; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   531
            final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex));
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   532
            final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(other.parameterType(i + 1));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   533
            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
   534
                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
   535
            }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   536
        }
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
   537
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   538
        // Must match any undefined parameters to Object type.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   539
        for(int i = minParams; i < fnParamCountNoCallee; ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   540
            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
   541
                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
   542
            }
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
   543
        }
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
   544
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   545
        return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   546
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   547
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   548
    private static int getParamCount(final MethodType type) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   549
        final int paramCount = type.parameterCount();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   550
        return type.parameterType(paramCount - 1).isArray() ? Integer.MAX_VALUE : paramCount;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   551
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   552
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   553
    private boolean canBeDeoptimized() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   554
        return optimismInfo != null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   555
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   556
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
   557
    private MethodHandle createComposableInvoker(final boolean isConstructor) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   558
        final MethodHandle handle = getInvokerOrConstructor(isConstructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   559
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   560
        // 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
   561
        // directly.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   562
        if(!canBeDeoptimized()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   563
            return handle;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   564
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   565
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   566
        // 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
   567
        // to the compiled function's changed target whenever the optimistic assumptions are invalidated.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   568
        final CallSite cs = new MutableCallSite(handle.type());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   569
        relinkComposableInvoker(cs, this, isConstructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   570
        return cs.dynamicInvoker();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   571
    }
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   572
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   573
    private static class HandleAndAssumptions {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   574
        final MethodHandle handle;
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   575
        final SwitchPoint assumptions;
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   576
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   577
        HandleAndAssumptions(final MethodHandle handle, final SwitchPoint assumptions) {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   578
            this.handle = handle;
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   579
            this.assumptions = assumptions;
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   580
        }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   581
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   582
        GuardedInvocation createInvocation() {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   583
            return new GuardedInvocation(handle, assumptions);
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   584
        }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   585
    }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   586
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   587
    /**
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   588
     * Returns a pair of an invocation created with a passed-in supplier and a non-invalidated switch point for
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   589
     * optimistic assumptions (or null for the switch point if the function can not be deoptimized). While the method
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   590
     * makes a best effort to return a non-invalidated switch point (compensating for possible deoptimizing
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   591
     * recompilation happening on another thread) it is still possible that by the time this method returns the
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   592
     * switchpoint has been invalidated by a {@code RewriteException} triggered on another thread for this function.
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   593
     * This is not a problem, though, as these switch points are always used to produce call sites that fall back to
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   594
     * relinking when they are invalidated, and in this case the execution will end up here again. What this method
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   595
     * basically does is minimize such busy-loop relinking while the function is being recompiled on a different thread.
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   596
     * @param invocationSupplier the supplier that constructs the actual invocation method handle; should use the
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   597
     * {@code CompiledFunction} method itself in some capacity.
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   598
     * @return a tuple object containing the method handle as created by the supplier and an optimistic assumptions
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   599
     * switch point that is guaranteed to not have been invalidated before the call to this method (or null if the
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   600
     * function can't be further deoptimized).
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   601
     */
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   602
    private synchronized HandleAndAssumptions getValidOptimisticInvocation(final Supplier<MethodHandle> invocationSupplier) {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   603
        for(;;) {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   604
            final MethodHandle handle = invocationSupplier.get();
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   605
            final SwitchPoint assumptions = canBeDeoptimized() ? optimismInfo.optimisticAssumptions : null;
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   606
            if(assumptions != null && assumptions.hasBeenInvalidated()) {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   607
                // We can be in a situation where one thread is in the middle of a deoptimizing compilation when we hit
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   608
                // this and thus, it has invalidated the old switch point, but hasn't created the new one yet. Note that
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   609
                // the behavior of invalidating the old switch point before recompilation, and only creating the new one
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   610
                // after recompilation is by design. If we didn't wait here for the recompilation to complete, we would
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   611
                // be busy looping through the fallback path of the invalidated switch point, relinking the call site
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   612
                // again with the same invalidated switch point, invoking the fallback, etc. stealing CPU cycles from
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   613
                // the recompilation task we're dependent on. This can still happen if the switch point gets invalidated
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   614
                // after we grabbed it here, in which case we'll indeed do one busy relink immediately.
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   615
                try {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   616
                    wait();
26067
b32ccc3a76c9 8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents: 26055
diff changeset
   617
                } catch (final InterruptedException e) {
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   618
                    // Intentionally ignored. There's nothing meaningful we can do if we're interrupted
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   619
                }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   620
            } else {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   621
                return new HandleAndAssumptions(handle, assumptions);
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   622
            }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   623
        }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   624
    }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   625
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   626
    private static void relinkComposableInvoker(final CallSite cs, final CompiledFunction inv, final boolean constructor) {
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   627
        final HandleAndAssumptions handleAndAssumptions = inv.getValidOptimisticInvocation(new Supplier<MethodHandle>() {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   628
            @Override
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   629
            public MethodHandle get() {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   630
                return inv.getInvokerOrConstructor(constructor);
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   631
            }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   632
        });
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   633
        final MethodHandle handle = handleAndAssumptions.handle;
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   634
        final SwitchPoint assumptions = handleAndAssumptions.assumptions;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   635
        final MethodHandle target;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   636
        if(assumptions == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   637
            target = handle;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   638
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   639
            final MethodHandle relink = MethodHandles.insertArguments(RELINK_COMPOSABLE_INVOKER, 0, cs, inv, constructor);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   640
            target = assumptions.guardWithTest(handle, MethodHandles.foldArguments(cs.dynamicInvoker(), relink));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   641
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   642
        cs.setTarget(target.asType(cs.type()));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   643
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   644
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
   645
    private MethodHandle getInvokerOrConstructor(final boolean selectCtor) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   646
        return selectCtor ? getConstructor() : createInvokerForPessimisticCaller();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   647
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   648
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   649
    /**
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   650
     * Returns a guarded invocation for this function when not invoked as a constructor. The guarded invocation has no
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   651
     * guard but it potentially has an optimistic assumptions switch point. As such, it will probably not be used as a
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   652
     * final guarded invocation, but rather as a holder for an invocation handle and switch point to be decomposed and
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   653
     * reassembled into a different final invocation by the user of this method. Any recompositions should take care to
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   654
     * continue to use the switch point. If that is not possible, use {@link #createComposableInvoker()} instead.
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   655
     * @return a guarded invocation for an ordinary (non-constructor) invocation of this function.
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   656
     */
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   657
    GuardedInvocation createFunctionInvocation(final Class<?> callSiteReturnType, final int callerProgramPoint) {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   658
        return getValidOptimisticInvocation(new Supplier<MethodHandle>() {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   659
            @Override
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   660
            public MethodHandle get() {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   661
                return createInvoker(callSiteReturnType, callerProgramPoint);
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   662
            }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   663
        }).createInvocation();
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   664
    }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   665
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   666
    /**
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   667
     * Returns a guarded invocation for this function when invoked as a constructor. The guarded invocation has no guard
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   668
     * but it potentially has an optimistic assumptions switch point. As such, it will probably not be used as a final
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   669
     * guarded invocation, but rather as a holder for an invocation handle and switch point to be decomposed and
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   670
     * reassembled into a different final invocation by the user of this method. Any recompositions should take care to
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   671
     * continue to use the switch point. If that is not possible, use {@link #createComposableConstructor()} instead.
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   672
     * @return a guarded invocation for invocation of this function as a constructor.
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   673
     */
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   674
    GuardedInvocation createConstructorInvocation() {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   675
        return getValidOptimisticInvocation(new Supplier<MethodHandle>() {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   676
            @Override
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   677
            public MethodHandle get() {
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   678
                return getConstructor();
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   679
            }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   680
        }).createInvocation();
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   681
    }
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   682
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   683
    private MethodHandle createInvoker(final Class<?> callSiteReturnType, final int callerProgramPoint) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   684
        final boolean isOptimistic = canBeDeoptimized();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   685
        MethodHandle handleRewriteException = isOptimistic ? createRewriteExceptionHandler() : null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   686
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   687
        MethodHandle inv = invoker;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   688
        if(isValid(callerProgramPoint)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   689
            inv = OptimisticReturnFilters.filterOptimisticReturnValue(inv, callSiteReturnType, callerProgramPoint);
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   690
            inv = changeReturnType(inv, callSiteReturnType);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   691
            if(callSiteReturnType.isPrimitive() && handleRewriteException != null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   692
                // because handleRewriteException always returns Object
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   693
                handleRewriteException = OptimisticReturnFilters.filterOptimisticReturnValue(handleRewriteException,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   694
                        callSiteReturnType, callerProgramPoint);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   695
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   696
        } else if(isOptimistic) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   697
            // 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
   698
            // 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
   699
            inv = changeReturnType(inv, callSiteReturnType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   700
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   701
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   702
        if(isOptimistic) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   703
            assert handleRewriteException != null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   704
            final MethodHandle typedHandleRewriteException = changeReturnType(handleRewriteException, inv.type().returnType());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   705
            return MH.catchException(inv, RewriteException.class, typedHandleRewriteException);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   706
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   707
        return inv;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   708
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   709
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   710
    private MethodHandle createRewriteExceptionHandler() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   711
        return MH.foldArguments(RESTOF_INVOKER, MH.insertArguments(HANDLE_REWRITE_EXCEPTION, 0, this, optimismInfo));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   712
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   713
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
   714
    private static MethodHandle changeReturnType(final MethodHandle mh, final Class<?> newReturnType) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   715
        return Bootstrap.getLinkerServices().asType(mh, mh.type().changeReturnType(newReturnType));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   716
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   717
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   718
    @SuppressWarnings("unused")
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   719
    private static MethodHandle handleRewriteException(final CompiledFunction function, final OptimismInfo oldOptimismInfo, final RewriteException re) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   720
        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
   721
    }
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
   722
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   723
    /**
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   724
     * Debug function for printing out all invalidated program points and their
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   725
     * invalidation mapping to next type
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   726
     * @param ipp
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   727
     * @return string describing the ipp map
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   728
     */
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   729
    private static String toStringInvalidations(final Map<Integer, Type> ipp) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   730
        if (ipp == null) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   731
            return "";
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   732
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   733
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   734
        final StringBuilder sb = new StringBuilder();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   735
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   736
        for (final Iterator<Map.Entry<Integer, Type>> iter = ipp.entrySet().iterator(); iter.hasNext(); ) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   737
            final Map.Entry<Integer, Type> entry = iter.next();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   738
            final char bct = entry.getValue().getBytecodeStackType();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   739
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   740
            sb.append('[').
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   741
                    append(entry.getKey()).
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   742
                    append("->").
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   743
                    append(bct == 'A' ? 'O' : bct).
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   744
                    append(']');
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   745
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   746
            if (iter.hasNext()) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   747
                sb.append(' ');
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   748
            }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   749
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   750
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   751
        return sb.toString();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   752
    }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   753
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   754
    private void logRecompile(final String reason, final FunctionNode fn, final MethodType type, final Map<Integer, Type> ipp) {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   755
        if (log.isEnabled()) {
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   756
            log.info(reason, DebugLogger.quote(fn.getName()), " signature: ", type, " ", toStringInvalidations(ipp));
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   757
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   758
    }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   760
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   761
     * 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
   762
     * 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
   763
     * executing a rest-of method to complete the execution with the deoptimized version.
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   764
     * @param oldOptInfo the optimism info of this function. We must store it explicitly as a bound argument in the
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   765
     * method handle, otherwise it could be null for handling a rewrite exception in an outer invocation of a recursive
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   766
     * function when recursive invocations of the function have completely deoptimized it.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   767
     * @param re the rewrite exception that was raised
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   768
     * @return the method handle for the rest-of method, for folding composition.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   769
     */
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   770
    private synchronized MethodHandle handleRewriteException(final OptimismInfo oldOptInfo, final RewriteException re) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   771
        if (log.isEnabled()) {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   772
            log.info(new RecompilationEvent(Level.INFO, re, re.getReturnValueNonDestructive()), "RewriteException ", re.getMessageShort());
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   773
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   774
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   775
        final MethodType type = type();
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   776
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   777
        // 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
   778
        // this function doesn't have a callee parameter.
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   779
        final MethodType callSiteType = type.parameterType(0) == ScriptFunction.class ?
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   780
                type :
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   781
                type.insertParameterTypes(0, ScriptFunction.class);
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   782
        final OptimismInfo currentOptInfo = optimismInfo;
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   783
        final boolean shouldRecompile = currentOptInfo != null && currentOptInfo.requestRecompile(re);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   784
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   785
        // Effective optimism info, for subsequent use. We'll normally try to use the current (latest) one, but if it
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   786
        // isn't available, we'll use the old one bound into the call site.
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   787
        final OptimismInfo effectiveOptInfo = currentOptInfo != null ? currentOptInfo : oldOptInfo;
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   788
        FunctionNode fn = effectiveOptInfo.reparse();
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   789
        final Compiler compiler = effectiveOptInfo.getCompiler(fn, callSiteType, re); //set to non rest-of
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   790
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   791
        if (!shouldRecompile) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   792
            // It didn't necessarily recompile, e.g. for an outer invocation of a recursive function if we already
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   793
            // recompiled a deoptimized version for an inner invocation.
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   794
            // We still need to do the rest of from the beginning
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   795
            logRecompile("Rest-of compilation [STANDALONE] ", fn, callSiteType, effectiveOptInfo.invalidatedProgramPoints);
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   796
            return restOfHandle(effectiveOptInfo, compiler.compile(fn, CompilationPhases.COMPILE_ALL_RESTOF), currentOptInfo != null);
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   797
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   798
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   799
        logRecompile("Deoptimizing recompilation (up to bytecode) ", fn, callSiteType, effectiveOptInfo.invalidatedProgramPoints);
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   800
        fn = compiler.compile(fn, CompilationPhases.COMPILE_UPTO_BYTECODE);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   801
        log.info("Reusable IR generated");
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   802
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   803
        // compile the rest of the function, and install it
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   804
        log.info("Generating and installing bytecode from reusable IR...");
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   805
        logRecompile("Rest-of compilation [CODE PIPELINE REUSE] ", fn, callSiteType, effectiveOptInfo.invalidatedProgramPoints);
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   806
        final FunctionNode normalFn = compiler.compile(fn, CompilationPhases.COMPILE_FROM_BYTECODE);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   807
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   808
        if (effectiveOptInfo.data.usePersistentCodeCache()) {
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   809
            final RecompilableScriptFunctionData data = effectiveOptInfo.data;
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   810
            final int functionNodeId = data.getFunctionNodeId();
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   811
            final TypeMap typeMap = data.typeMap(callSiteType);
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   812
            final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId);
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   813
            final String cacheKey = CodeStore.getCacheKey(functionNodeId, paramTypes);
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   814
            compiler.persistClassInfo(cacheKey, normalFn);
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   815
        }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   816
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   817
        FunctionNode fn2 = effectiveOptInfo.reparse();
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   818
        fn2 = compiler.compile(fn2, CompilationPhases.COMPILE_UPTO_BYTECODE);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   819
        log.info("Done.");
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   820
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   821
        final boolean canBeDeoptimized = normalFn.canBeDeoptimized();
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   822
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   823
        if (log.isEnabled()) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   824
            log.info("Recompiled '", fn.getName(), "' (", Debug.id(this), ") ", canBeDeoptimized ? " can still be deoptimized." : " is completely deoptimized.");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   825
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   826
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   827
        log.info("Looking up invoker...");
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   828
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   829
        final MethodHandle newInvoker = effectiveOptInfo.data.lookup(fn);
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   830
        invoker     = newInvoker.asType(type.changeReturnType(newInvoker.type().returnType()));
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   831
        constructor = null; // Will be regenerated when needed
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   832
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   833
        log.info("Done: ", invoker);
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   834
        final MethodHandle restOf = restOfHandle(effectiveOptInfo, compiler.compile(fn, CompilationPhases.COMPILE_FROM_BYTECODE_RESTOF), canBeDeoptimized);
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   835
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   836
        // Note that we only adjust the switch point after we set the invoker/constructor. This is important.
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   837
        if (canBeDeoptimized) {
25257
c1c2eb19a90e 8047331: Assertion in CompiledFunction when running earley-boyer after Merge
attila
parents: 25236
diff changeset
   838
            effectiveOptInfo.newOptimisticAssumptions(); // Otherwise, set a new switch point.
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   839
        } else {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   840
            optimismInfo = null; // If we got to a point where we no longer have optimistic assumptions, let the optimism info go.
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   841
        }
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25257
diff changeset
   842
        notifyAll();
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   843
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   844
        return restOf;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   845
    }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   846
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   847
    private MethodHandle restOfHandle(final OptimismInfo info, final FunctionNode restOfFunction, final boolean canBeDeoptimized) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   848
        assert info != null;
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   849
        assert restOfFunction.getCompileUnit().getUnitClassName().contains("restOf");
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   850
        final MethodHandle restOf =
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   851
                changeReturnType(
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   852
                        info.data.lookupCodeMethod(
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 26053
diff changeset
   853
                                restOfFunction.getCompileUnit().getCode(),
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   854
                                MH.type(restOfFunction.getReturnType().getTypeClass(),
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   855
                                        RewriteException.class)),
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   856
                        Object.class);
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   857
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   858
        if (!canBeDeoptimized) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   859
            return restOf;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   860
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   861
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   862
        // If rest-of is itself optimistic, we must make sure that we can repeat a deoptimization if it, too hits an exception.
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   863
        return MH.catchException(restOf, RewriteException.class, createRewriteExceptionHandler());
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   864
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   865
    }
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
   866
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   867
    private static class OptimismInfo {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   868
        // TODO: this is pointing to its owning ScriptFunctionData. Re-evaluate if that's okay.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   869
        private final RecompilableScriptFunctionData data;
25236
fac419f1e889 8046921: Deoptimization type information peristence
attila
parents: 24779
diff changeset
   870
        private final Map<Integer, Type> invalidatedProgramPoints;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   871
        private SwitchPoint optimisticAssumptions;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   872
        private final DebugLogger log;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   873
25236
fac419f1e889 8046921: Deoptimization type information peristence
attila
parents: 24779
diff changeset
   874
        OptimismInfo(final RecompilableScriptFunctionData data, final Map<Integer, Type> invalidatedProgramPoints) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   875
            this.data = data;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   876
            this.log  = data.getLogger();
25236
fac419f1e889 8046921: Deoptimization type information peristence
attila
parents: 24779
diff changeset
   877
            this.invalidatedProgramPoints = invalidatedProgramPoints == null ? new TreeMap<Integer, Type>() : invalidatedProgramPoints;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   878
            newOptimisticAssumptions();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   879
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   880
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   881
        private void newOptimisticAssumptions() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   882
            optimisticAssumptions = new SwitchPoint();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   883
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   884
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   885
        boolean requestRecompile(final RewriteException e) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   886
            final Type retType            = e.getReturnType();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   887
            final Type previousFailedType = invalidatedProgramPoints.put(e.getProgramPoint(), retType);
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   888
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   889
            if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   890
                final StackTraceElement[] stack      = e.getStackTrace();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   891
                final String              functionId = stack.length == 0 ?
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   892
                        data.getName() :
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   893
                        stack[0].getClassName() + "." + stack[0].getMethodName();
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   894
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
   895
                log.info("RewriteException for an already invalidated program point ", e.getProgramPoint(), " in ", functionId, ". This is okay for a recursive function invocation, but a bug otherwise.");
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   896
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   897
                return false;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   898
            }
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   899
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   900
            SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions });
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   901
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   902
            return true;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   903
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   904
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   905
        Compiler getCompiler(final FunctionNode fn, final MethodType actualCallSiteType, final RewriteException e) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   906
            return data.getCompiler(fn, actualCallSiteType, e.getRuntimeScope(), invalidatedProgramPoints, getEntryPoints(e));
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   907
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   908
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   909
        private static int[] getEntryPoints(final RewriteException e) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   910
            final int[] prevEntryPoints = e.getPreviousContinuationEntryPoints();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   911
            final int[] entryPoints;
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   912
            if (prevEntryPoints == null) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   913
                entryPoints = new int[1];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   914
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   915
                final int l = prevEntryPoints.length;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   916
                entryPoints = new int[l + 1];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   917
                System.arraycopy(prevEntryPoints, 0, entryPoints, 1, l);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   918
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   919
            entryPoints[0] = e.getProgramPoint();
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   920
            return entryPoints;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   921
        }
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   922
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   923
        FunctionNode reparse() {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   924
            return data.reparse();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   925
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   926
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   927
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   928
    @SuppressWarnings("unused")
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   929
    private static Object newFilter(final Object result, final Object allocation) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   930
        return (result instanceof ScriptObject || !JSType.isPrimitive(result))? result : allocation;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   931
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   932
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   933
    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   934
        return MH.findStatic(MethodHandles.lookup(), CompiledFunction.class, name, MH.type(rtype, types));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20570
diff changeset
   935
    }
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
   936
}