author | lagergren |
Wed, 23 Apr 2014 16:13:47 +0200 | |
changeset 24744 | 5290da85fc3d |
parent 24742 | a9afb384e654 |
child 24745 | 3a6e1477362b |
permissions | -rw-r--r-- |
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 | 27 |
import static jdk.nashorn.internal.lookup.Lookup.MH; |
28 |
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; |
|
29 |
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid; |
|
24740
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
30 |
|
24719 | 31 |
import java.lang.invoke.CallSite; |
16523
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
32 |
import java.lang.invoke.MethodHandle; |
24719 | 33 |
import java.lang.invoke.MethodHandles; |
16523
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
34 |
import java.lang.invoke.MethodType; |
24719 | 35 |
import java.lang.invoke.MutableCallSite; |
36 |
import java.lang.invoke.SwitchPoint; |
|
37 |
import java.util.Map; |
|
38 |
import java.util.TreeMap; |
|
24731
ab0c8fc915ae
8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents:
24729
diff
changeset
|
39 |
import java.util.logging.Level; |
ab0c8fc915ae
8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents:
24729
diff
changeset
|
40 |
|
24719 | 41 |
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
|
42 |
import jdk.nashorn.internal.codegen.types.Type; |
24719 | 43 |
import jdk.nashorn.internal.ir.FunctionNode; |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
44 |
import jdk.nashorn.internal.objects.Global; |
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
|
45 |
import jdk.nashorn.internal.runtime.events.RecompilationEvent; |
24719 | 46 |
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
|
47 |
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
|
48 |
|
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
49 |
/** |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
50 |
* 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
|
51 |
* 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
|
52 |
*/ |
24719 | 53 |
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
|
54 |
|
24719 | 55 |
private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class); |
56 |
private static final MethodHandle RELINK_COMPOSABLE_INVOKER = findOwnMH("relinkComposableInvoker", void.class, CallSite.class, CompiledFunction.class, boolean.class); |
|
57 |
private static final MethodHandle HANDLE_REWRITE_EXCEPTION = findOwnMH("handleRewriteException", MethodHandle.class, CompiledFunction.class, OptimismInfo.class, RewriteException.class); |
|
58 |
private static final MethodHandle RESTOF_INVOKER = MethodHandles.exactInvoker(MethodType.methodType(Object.class, RewriteException.class)); |
|
59 |
||
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
60 |
private final DebugLogger log; |
24719 | 61 |
|
62 |
/** |
|
63 |
* The method type may be more specific than the invoker, if. e.g. |
|
64 |
* the invoker is guarded, and a guard with a generic object only |
|
65 |
* fallback, while the target is more specific, we still need the |
|
66 |
* more specific type for sorting |
|
67 |
*/ |
|
68 |
private MethodHandle invoker; |
|
69 |
private MethodHandle constructor; |
|
70 |
private OptimismInfo optimismInfo; |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
71 |
private int flags; // from FunctionNode |
24740
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
72 |
private boolean applyToCall; |
24719 | 73 |
|
74 |
CompiledFunction(final MethodHandle invoker) { |
|
75 |
this.invoker = invoker; |
|
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
76 |
this.log = Global.instance().getLogger(RecompilableScriptFunctionData.class); |
24719 | 77 |
} |
78 |
||
79 |
static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) { |
|
80 |
return new CompiledFunction(MH.insertArguments(invoker, 0, false), |
|
81 |
createConstructorFromInvoker(MH.insertArguments(invoker, 0, true))); |
|
82 |
} |
|
83 |
||
84 |
CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) { |
|
85 |
this(invoker); |
|
17756
daaa1e643f71
8006069: Range analysis first iteration, runtime specializations
lagergren
parents:
17518
diff
changeset
|
86 |
this.constructor = constructor; |
16523
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
87 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
88 |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
89 |
CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData, final int flags) { |
24719 | 90 |
this(invoker); |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
91 |
this.flags = flags; |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
92 |
if ((flags & FunctionNode.IS_OPTIMISTIC) != 0) { |
24719 | 93 |
optimismInfo = new OptimismInfo(functionData); |
94 |
} else { |
|
95 |
optimismInfo = null; |
|
96 |
} |
|
97 |
} |
|
98 |
||
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
99 |
int getFlags() { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
100 |
return flags; |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
101 |
} |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
102 |
|
24740
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
103 |
void setIsApplyToCall() { |
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
104 |
applyToCall = true; |
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
105 |
} |
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
106 |
|
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
107 |
boolean isApplyToCall() { |
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
108 |
return applyToCall; |
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
109 |
} |
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
110 |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
111 |
boolean isVarArg() { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
112 |
return isVarArgsType(invoker.type()); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
113 |
} |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
114 |
|
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
|
115 |
@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
|
116 |
public String toString() { |
24740
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
117 |
return "[invokerType=" + invoker.type() + " ctor=" + constructor + " weight=" + weight() + " isApplyToCall=" + isApplyToCall() + "]"; |
24719 | 118 |
} |
119 |
||
120 |
boolean needsCallee() { |
|
121 |
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
|
122 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
123 |
|
24719 | 124 |
/** |
125 |
* Returns an invoker method handle for this function. Note that the handle is safely composable in |
|
126 |
* the sense that you can compose it with other handles using any combinators even if you can't affect call site |
|
127 |
* invalidation. If this compiled function is non-optimistic, then it returns the same value as |
|
128 |
* {@link #getInvoker()}. However, if the function is optimistic, then this handle will incur an overhead as it will |
|
129 |
* add an intermediate internal call site that can relink itself when the function needs to regenerate its code to |
|
130 |
* always point at the latest generated code version. |
|
131 |
* @return a guaranteed composable invoker method handle for this function. |
|
132 |
*/ |
|
133 |
MethodHandle createComposableInvoker() { |
|
134 |
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
|
135 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
136 |
|
24719 | 137 |
/** |
138 |
* Returns an invoker method handle for this function when invoked as a constructor. Note that the handle should be |
|
139 |
* considered non-composable in the sense that you can only compose it with other handles using any combinators if |
|
140 |
* you can ensure that the composition is guarded by {@link #getOptimisticAssumptionsSwitchPoint()} if it's |
|
141 |
* non-null, and that you can relink the call site it is set into as a target if the switch point is invalidated. In |
|
142 |
* all other cases, use {@link #createComposableConstructor()}. |
|
143 |
* @return a direct constructor method handle for this function. |
|
144 |
*/ |
|
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
|
145 |
MethodHandle getConstructor() { |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
146 |
if (constructor == null) { |
24719 | 147 |
constructor = createConstructorFromInvoker(createInvokerForPessimisticCaller()); |
148 |
} |
|
149 |
||
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
|
150 |
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
|
151 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
152 |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
153 |
MethodHandle getInvoker() { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
154 |
return invoker; |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
155 |
} |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
156 |
|
24719 | 157 |
/** |
158 |
* Creates a version of the invoker intended for a pessimistic caller (return type is Object, no caller optimistic |
|
159 |
* program point available). |
|
160 |
* @return a version of the invoker intended for a pessimistic caller. |
|
161 |
*/ |
|
162 |
private MethodHandle createInvokerForPessimisticCaller() { |
|
163 |
return createInvoker(Object.class, INVALID_PROGRAM_POINT); |
|
164 |
} |
|
165 |
||
166 |
/** |
|
167 |
* Compose a constructor from an invoker. |
|
168 |
* |
|
169 |
* @param invoker invoker |
|
170 |
* @param needsCallee do we need to pass a callee |
|
171 |
* |
|
172 |
* @return the composed constructor |
|
173 |
*/ |
|
174 |
private static MethodHandle createConstructorFromInvoker(final MethodHandle invoker) { |
|
175 |
final boolean needsCallee = ScriptFunctionData.needsCallee(invoker); |
|
176 |
// If it was (callee, this, args...), permute it to (this, callee, args...). We're doing this because having |
|
177 |
// "this" in the first argument position is what allows the elegant folded composition of |
|
178 |
// (newFilter x constructor x allocator) further down below in the code. Also, ensure the composite constructor |
|
179 |
// always returns Object. |
|
180 |
final MethodHandle swapped = needsCallee ? swapCalleeAndThis(invoker) : invoker; |
|
181 |
||
182 |
final MethodHandle returnsObject = MH.asType(swapped, swapped.type().changeReturnType(Object.class)); |
|
183 |
||
184 |
final MethodType ctorType = returnsObject.type(); |
|
185 |
||
186 |
// Construct a dropping type list for NEWFILTER, but don't include constructor "this" into it, so it's actually |
|
187 |
// captured as "allocation" parameter of NEWFILTER after we fold the constructor into it. |
|
188 |
// (this, [callee, ]args...) => ([callee, ]args...) |
|
189 |
final Class<?>[] ctorArgs = ctorType.dropParameterTypes(0, 1).parameterArray(); |
|
190 |
||
191 |
// Fold constructor into newFilter that replaces the return value from the constructor with the originally |
|
192 |
// allocated value when the originally allocated value is a JS primitive (String, Boolean, Number). |
|
193 |
// (result, this, [callee, ]args...) x (this, [callee, ]args...) => (this, [callee, ]args...) |
|
194 |
final MethodHandle filtered = MH.foldArguments(MH.dropArguments(NEWFILTER, 2, ctorArgs), returnsObject); |
|
195 |
||
196 |
// allocate() takes a ScriptFunction and returns a newly allocated ScriptObject... |
|
197 |
if (needsCallee) { |
|
198 |
// ...we either fold it into the previous composition, if we need both the ScriptFunction callee object and |
|
199 |
// the newly allocated object in the arguments, so (this, callee, args...) x (callee) => (callee, args...), |
|
200 |
// or... |
|
201 |
return MH.foldArguments(filtered, ScriptFunction.ALLOCATE); |
|
202 |
} |
|
203 |
||
204 |
// ...replace the ScriptFunction argument with the newly allocated object, if it doesn't need the callee |
|
205 |
// (this, args...) filter (callee) => (callee, args...) |
|
206 |
return MH.filterArguments(filtered, 0, ScriptFunction.ALLOCATE); |
|
207 |
} |
|
208 |
||
209 |
/** |
|
210 |
* Permutes the parameters in the method handle from {@code (callee, this, ...)} to {@code (this, callee, ...)}. |
|
211 |
* Used when creating a constructor handle. |
|
212 |
* @param mh a method handle with order of arguments {@code (callee, this, ...)} |
|
213 |
* @return a method handle with order of arguments {@code (this, callee, ...)} |
|
214 |
*/ |
|
215 |
private static MethodHandle swapCalleeAndThis(final MethodHandle mh) { |
|
216 |
final MethodType type = mh.type(); |
|
217 |
assert type.parameterType(0) == ScriptFunction.class : type; |
|
218 |
assert type.parameterType(1) == Object.class : type; |
|
219 |
final MethodType newType = type.changeParameterType(0, Object.class).changeParameterType(1, ScriptFunction.class); |
|
220 |
final int[] reorder = new int[type.parameterCount()]; |
|
221 |
reorder[0] = 1; |
|
222 |
assert reorder[1] == 0; |
|
223 |
for (int i = 2; i < reorder.length; ++i) { |
|
224 |
reorder[i] = i; |
|
225 |
} |
|
226 |
return MethodHandles.permuteArguments(mh, newType, reorder); |
|
227 |
} |
|
228 |
||
229 |
/** |
|
230 |
* Returns an invoker method handle for this function when invoked as a constructor. Note that the handle is safely |
|
231 |
* composable in the sense that you can compose it with other handles using any combinators even if you can't affect |
|
232 |
* call site invalidation. If this compiled function is non-optimistic, then it returns the same value as |
|
233 |
* {@link #getConstructor()}. However, if the function is optimistic, then this handle will incur an overhead as it |
|
234 |
* will add an intermediate internal call site that can relink itself when the function needs to regenerate its code |
|
235 |
* to always point at the latest generated code version. |
|
236 |
* @return a guaranteed composable constructor method handle for this function. |
|
237 |
*/ |
|
238 |
MethodHandle createComposableConstructor() { |
|
239 |
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
|
240 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
241 |
|
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
242 |
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
|
243 |
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
|
244 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
245 |
|
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
246 |
MethodType type() { |
24719 | 247 |
return invoker.type(); |
20570
b1c8d1e8013a
8025965: Specialized functions with same weight replace each other in TreeSet
hannesw
parents:
17756
diff
changeset
|
248 |
} |
b1c8d1e8013a
8025965: Specialized functions with same weight replace each other in TreeSet
hannesw
parents:
17756
diff
changeset
|
249 |
|
24719 | 250 |
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
|
251 |
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
|
252 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
253 |
|
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
254 |
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
|
255 |
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
|
256 |
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
|
257 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
258 |
|
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
259 |
int weight = Type.typeFor(type.returnType()).getWeight(); |
24719 | 260 |
for (int i = 0 ; i < type.parameterCount() ; i++) { |
261 |
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
|
262 |
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
|
263 |
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
|
264 |
} |
24719 | 265 |
|
266 |
weight += type.parameterCount(); //more params outweigh few parameters |
|
267 |
||
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
|
268 |
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
|
269 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
270 |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
271 |
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
|
272 |
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
|
273 |
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
|
274 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
275 |
|
24719 | 276 |
static boolean moreGenericThan(final MethodType mt0, final MethodType mt1) { |
277 |
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
|
278 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
279 |
|
24719 | 280 |
boolean betterThanFinal(final CompiledFunction other, final MethodType callSiteMethodType) { |
281 |
// Prefer anything over nothing, as we can't compile new versions. |
|
282 |
if (other == null) { |
|
283 |
return true; |
|
284 |
} |
|
285 |
return betterThanFinal(type(), other.type(), callSiteMethodType); |
|
16523
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
286 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
287 |
|
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
|
288 |
static boolean betterThanFinal(final MethodType thisMethodType, final MethodType otherMethodType, final MethodType callSiteMethodType) { |
24719 | 289 |
final int thisParamCount = getParamCount(thisMethodType); |
290 |
final int otherParamCount = getParamCount(otherMethodType); |
|
291 |
final int callSiteRawParamCount = getParamCount(callSiteMethodType); |
|
292 |
final boolean csVarArg = callSiteRawParamCount == Integer.MAX_VALUE; |
|
293 |
// Subtract 1 for callee for non-vararg call sites |
|
294 |
final int callSiteParamCount = csVarArg ? callSiteRawParamCount : callSiteRawParamCount - 1; |
|
295 |
||
296 |
// Prefer the function that discards less parameters |
|
297 |
final int thisDiscardsParams = Math.max(callSiteParamCount - thisParamCount, 0); |
|
298 |
final int otherDiscardsParams = Math.max(callSiteParamCount - otherParamCount, 0); |
|
299 |
if(thisDiscardsParams < otherDiscardsParams) { |
|
300 |
return true; |
|
301 |
} |
|
302 |
if(thisDiscardsParams > otherDiscardsParams) { |
|
303 |
return false; |
|
304 |
} |
|
305 |
||
306 |
final boolean thisVarArg = thisParamCount == Integer.MAX_VALUE; |
|
307 |
final boolean otherVarArg = otherParamCount == Integer.MAX_VALUE; |
|
308 |
if(!(thisVarArg && otherVarArg && csVarArg)) { |
|
309 |
// At least one of them isn't vararg |
|
310 |
final Type[] thisType = toTypeWithoutCallee(thisMethodType, 0); // Never has callee |
|
311 |
final Type[] otherType = toTypeWithoutCallee(otherMethodType, 0); // Never has callee |
|
312 |
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
|
313 |
|
24719 | 314 |
int narrowWeightDelta = 0; |
315 |
int widenWeightDelta = 0; |
|
316 |
final int minParamsCount = Math.min(Math.min(thisParamCount, otherParamCount), callSiteParamCount); |
|
317 |
for(int i = 0; i < minParamsCount; ++i) { |
|
318 |
final int callSiteParamWeight = getParamType(i, callSiteType, csVarArg).getWeight(); |
|
319 |
// Delta is negative for narrowing, positive for widening |
|
320 |
final int thisParamWeightDelta = getParamType(i, thisType, thisVarArg).getWeight() - callSiteParamWeight; |
|
321 |
final int otherParamWeightDelta = getParamType(i, otherType, otherVarArg).getWeight() - callSiteParamWeight; |
|
322 |
// Only count absolute values of narrowings |
|
323 |
narrowWeightDelta += Math.max(-thisParamWeightDelta, 0) - Math.max(-otherParamWeightDelta, 0); |
|
324 |
// Only count absolute values of widenings |
|
325 |
widenWeightDelta += Math.max(thisParamWeightDelta, 0) - Math.max(otherParamWeightDelta, 0); |
|
326 |
} |
|
327 |
||
328 |
// If both functions accept more arguments than what is passed at the call site, account for ability |
|
329 |
// to receive Undefined un-narrowed in the remaining arguments. |
|
330 |
if(!thisVarArg) { |
|
331 |
for(int i = callSiteParamCount; i < thisParamCount; ++i) { |
|
332 |
narrowWeightDelta += Math.max(Type.OBJECT.getWeight() - thisType[i].getWeight(), 0); |
|
333 |
} |
|
334 |
} |
|
335 |
if(!otherVarArg) { |
|
336 |
for(int i = callSiteParamCount; i < otherParamCount; ++i) { |
|
337 |
narrowWeightDelta -= Math.max(Type.OBJECT.getWeight() - otherType[i].getWeight(), 0); |
|
338 |
} |
|
339 |
} |
|
340 |
||
341 |
// Prefer function that narrows less |
|
342 |
if(narrowWeightDelta < 0) { |
|
343 |
return true; |
|
344 |
} |
|
345 |
if(narrowWeightDelta > 0) { |
|
346 |
return false; |
|
347 |
} |
|
348 |
||
349 |
// Prefer function that widens less |
|
350 |
if(widenWeightDelta < 0) { |
|
351 |
return true; |
|
352 |
} |
|
353 |
if(widenWeightDelta > 0) { |
|
354 |
return false; |
|
355 |
} |
|
356 |
} |
|
357 |
||
358 |
// Prefer the function that exactly matches the arity of the call site. |
|
359 |
if(thisParamCount == callSiteParamCount && otherParamCount != callSiteParamCount) { |
|
360 |
return true; |
|
361 |
} |
|
362 |
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
|
363 |
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
|
364 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
365 |
|
24719 | 366 |
// Otherwise, neither function matches arity exactly. We also know that at this point, they both can receive |
367 |
// more arguments than call site, otherwise we would've already chosen the one that discards less parameters. |
|
368 |
// Note that variable arity methods are preferred, as they actually match the call site arity better, since they |
|
369 |
// really have arbitrary arity. |
|
370 |
if(thisVarArg) { |
|
371 |
if(!otherVarArg) { |
|
372 |
return true; // |
|
373 |
} |
|
374 |
} else if(otherVarArg) { |
|
375 |
return false; |
|
376 |
} |
|
377 |
||
378 |
// Neither is variable arity; chose the one that has less extra parameters. |
|
379 |
final int fnParamDelta = thisParamCount - otherParamCount; |
|
380 |
if(fnParamDelta < 0) { |
|
381 |
return true; |
|
382 |
} |
|
383 |
if(fnParamDelta > 0) { |
|
384 |
return false; |
|
385 |
} |
|
386 |
||
387 |
final int callSiteRetWeight = Type.typeFor(callSiteMethodType.returnType()).getWeight(); |
|
388 |
// Delta is negative for narrower return type, positive for wider return type |
|
389 |
final int thisRetWeightDelta = Type.typeFor(thisMethodType.returnType()).getWeight() - callSiteRetWeight; |
|
390 |
final int otherRetWeightDelta = Type.typeFor(otherMethodType.returnType()).getWeight() - callSiteRetWeight; |
|
391 |
||
392 |
// Prefer function that returns a less wide return type |
|
393 |
final int widenRetDelta = Math.max(thisRetWeightDelta, 0) - Math.max(otherRetWeightDelta, 0); |
|
394 |
if(widenRetDelta < 0) { |
|
395 |
return true; |
|
396 |
} |
|
397 |
if(widenRetDelta > 0) { |
|
398 |
return false; |
|
399 |
} |
|
400 |
||
401 |
// Prefer function that returns a less narrow return type |
|
402 |
final int narrowRetDelta = Math.max(-thisRetWeightDelta, 0) - Math.max(-otherRetWeightDelta, 0); |
|
403 |
if(narrowRetDelta < 0) { |
|
404 |
return true; |
|
405 |
} |
|
406 |
if(narrowRetDelta > 0) { |
|
407 |
return false; |
|
408 |
} |
|
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
|
409 |
|
24719 | 410 |
throw new AssertionError(thisMethodType + " identically applicable to " + otherMethodType + " for " + callSiteMethodType); // Signatures are identical |
411 |
} |
|
412 |
||
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
|
413 |
private static Type[] toTypeWithoutCallee(final MethodType type, final int thisIndex) { |
24719 | 414 |
final int paramCount = type.parameterCount(); |
415 |
final Type[] t = new Type[paramCount - thisIndex]; |
|
416 |
for(int i = thisIndex; i < paramCount; ++i) { |
|
417 |
t[i - thisIndex] = Type.typeFor(type.parameterType(i)); |
|
418 |
} |
|
419 |
return t; |
|
420 |
} |
|
421 |
||
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
|
422 |
private static Type getParamType(final int i, final Type[] paramTypes, final boolean isVarArg) { |
24719 | 423 |
final int fixParamCount = paramTypes.length - (isVarArg ? 1 : 0); |
424 |
if(i < fixParamCount) { |
|
425 |
return paramTypes[i]; |
|
426 |
} |
|
427 |
assert isVarArg; |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
428 |
return ((ArrayType)paramTypes[paramTypes.length - 1]).getElementType(); |
24719 | 429 |
} |
430 |
||
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
431 |
boolean matchesCallSite(final MethodType callSiteType, final boolean pickVarArg) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
432 |
if (!ScriptEnvironment.globalOptimistic()) { |
24719 | 433 |
// Without optimistic recompilation, always choose the first eagerly compiled version. |
434 |
return true; |
|
435 |
} |
|
436 |
||
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
437 |
final MethodType type = type(); |
24719 | 438 |
final int fnParamCount = getParamCount(type); |
439 |
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
|
440 |
if (isVarArg) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
441 |
return pickVarArg; |
24719 | 442 |
} |
443 |
||
444 |
final int csParamCount = getParamCount(callSiteType); |
|
445 |
final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE; |
|
446 |
final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type |
|
447 |
||
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
|
448 |
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
|
449 |
final int minParams = Math.min(csParamCount - 1, fnParamCountNoCallee); // callSiteType always has callee, so subtract 1 |
24719 | 450 |
// We must match all incoming parameters, except "this". Starting from 1 to skip "this". |
451 |
for(int i = 1; i < minParams; ++i) { |
|
452 |
final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex)); |
|
453 |
final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(callSiteType.parameterType(i + 1)); |
|
454 |
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
|
455 |
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
|
456 |
} |
24719 | 457 |
} |
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
|
458 |
|
24719 | 459 |
// Must match any undefined parameters to Object type. |
460 |
for(int i = minParams; i < fnParamCountNoCallee; ++i) { |
|
461 |
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
|
462 |
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
|
463 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
464 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
465 |
|
24719 | 466 |
return true; |
467 |
} |
|
468 |
||
469 |
private static int getParamCount(final MethodType type) { |
|
470 |
final int paramCount = type.parameterCount(); |
|
471 |
return type.parameterType(paramCount - 1).isArray() ? Integer.MAX_VALUE : paramCount; |
|
472 |
} |
|
473 |
||
474 |
/** |
|
475 |
* Returns the switch point embodying the optimistic assumptions in this compiled function. It should be used to |
|
476 |
* guard any linking to the function's invoker or constructor. |
|
477 |
* @return the switch point embodying the optimistic assumptions in this compiled function. Null is returned if the |
|
478 |
* function has no optimistic assumptions. |
|
479 |
*/ |
|
480 |
SwitchPoint getOptimisticAssumptionsSwitchPoint() { |
|
481 |
return isOptimistic() ? optimismInfo.optimisticAssumptions : null; |
|
482 |
} |
|
483 |
||
484 |
boolean isOptimistic() { |
|
485 |
return optimismInfo != null; |
|
486 |
} |
|
487 |
||
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
|
488 |
private MethodHandle createComposableInvoker(final boolean isConstructor) { |
24719 | 489 |
final MethodHandle handle = getInvokerOrConstructor(isConstructor); |
490 |
||
491 |
// If compiled function is not optimistic, it can't ever change its invoker/constructor, so just return them |
|
492 |
// directly. |
|
493 |
if(!isOptimistic()) { |
|
494 |
return handle; |
|
495 |
} |
|
496 |
||
497 |
// Otherwise, we need a new level of indirection; need to introduce a mutable call site that can relink itslef |
|
498 |
// to the compiled function's changed target whenever the optimistic assumptions are invalidated. |
|
499 |
final CallSite cs = new MutableCallSite(handle.type()); |
|
500 |
relinkComposableInvoker(cs, this, isConstructor); |
|
501 |
return cs.dynamicInvoker(); |
|
502 |
} |
|
503 |
private static void relinkComposableInvoker(final CallSite cs, final CompiledFunction inv, final boolean constructor) { |
|
504 |
final MethodHandle handle = inv.getInvokerOrConstructor(constructor); |
|
505 |
final SwitchPoint assumptions = inv.getOptimisticAssumptionsSwitchPoint(); |
|
506 |
final MethodHandle target; |
|
507 |
if(assumptions == null) { |
|
508 |
target = handle; |
|
509 |
} else { |
|
510 |
// This assertion can obviously fail in a multithreaded environment, as we can be in a situation where |
|
511 |
// one thread is in the middle of a deoptimizing compilation when we hit this and thus, it has invalidated |
|
512 |
// the old switch point, but hasn't created the new one yet. Note that the behavior of invalidating the old |
|
513 |
// switch point before recompilation, and only creating the new one after recompilation is by design. |
|
514 |
// TODO: We need to think about thread safety of CompiledFunction objects. |
|
515 |
assert !assumptions.hasBeenInvalidated(); |
|
516 |
final MethodHandle relink = MethodHandles.insertArguments(RELINK_COMPOSABLE_INVOKER, 0, cs, inv, constructor); |
|
517 |
target = assumptions.guardWithTest(handle, MethodHandles.foldArguments(cs.dynamicInvoker(), relink)); |
|
518 |
} |
|
519 |
cs.setTarget(target); |
|
520 |
} |
|
521 |
||
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
|
522 |
private MethodHandle getInvokerOrConstructor(final boolean selectCtor) { |
24719 | 523 |
return selectCtor ? getConstructor() : createInvokerForPessimisticCaller(); |
524 |
} |
|
525 |
||
526 |
MethodHandle createInvoker(final Class<?> callSiteReturnType, final int callerProgramPoint) { |
|
527 |
final boolean isOptimistic = isOptimistic(); |
|
528 |
MethodHandle handleRewriteException = isOptimistic ? createRewriteExceptionHandler() : null; |
|
529 |
||
530 |
MethodHandle inv = invoker; |
|
531 |
if(isValid(callerProgramPoint)) { |
|
532 |
inv = OptimisticReturnFilters.filterOptimisticReturnValue(inv, callSiteReturnType, callerProgramPoint); |
|
533 |
if(callSiteReturnType.isPrimitive() && handleRewriteException != null) { |
|
534 |
// because handleRewriteException always returns Object |
|
535 |
handleRewriteException = OptimisticReturnFilters.filterOptimisticReturnValue(handleRewriteException, |
|
536 |
callSiteReturnType, callerProgramPoint); |
|
537 |
} |
|
538 |
} else if(isOptimistic) { |
|
539 |
// Required so that rewrite exception has the same return type. It'd be okay to do it even if we weren't |
|
540 |
// optimistic, but it isn't necessary as the linker upstream will eventually convert the return type. |
|
541 |
inv = changeReturnType(inv, callSiteReturnType); |
|
542 |
} |
|
543 |
||
544 |
if(isOptimistic) { |
|
545 |
assert handleRewriteException != null; |
|
546 |
final MethodHandle typedHandleRewriteException = changeReturnType(handleRewriteException, inv.type().returnType()); |
|
547 |
return MH.catchException(inv, RewriteException.class, typedHandleRewriteException); |
|
548 |
} |
|
549 |
return inv; |
|
550 |
} |
|
551 |
||
552 |
private MethodHandle createRewriteExceptionHandler() { |
|
553 |
return MH.foldArguments(RESTOF_INVOKER, MH.insertArguments(HANDLE_REWRITE_EXCEPTION, 0, this, optimismInfo)); |
|
554 |
} |
|
555 |
||
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
|
556 |
private static MethodHandle changeReturnType(final MethodHandle mh, final Class<?> newReturnType) { |
24719 | 557 |
return Bootstrap.getLinkerServices().asType(mh, mh.type().changeReturnType(newReturnType)); |
558 |
} |
|
559 |
||
560 |
@SuppressWarnings("unused") |
|
561 |
private static MethodHandle handleRewriteException(final CompiledFunction function, final OptimismInfo oldOptimismInfo, final RewriteException re) { |
|
562 |
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
|
563 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
564 |
|
24719 | 565 |
/** |
566 |
* Handles a {@link RewriteException} raised during the execution of this function by recompiling (if needed) the |
|
567 |
* function with an optimistic assumption invalidated at the program point indicated by the exception, and then |
|
568 |
* executing a rest-of method to complete the execution with the deoptimized version. |
|
569 |
* @param oldOptimismInfo the optimism info of this function. We must store it explicitly as a bound argument in the |
|
570 |
* method handle, otherwise it would be null for handling a rewrite exception in an outer invocation of a recursive |
|
571 |
* function when inner invocations of the function have completely deoptimized it. |
|
572 |
* @param re the rewrite exception that was raised |
|
573 |
* @return the method handle for the rest-of method, for folding composition. |
|
574 |
*/ |
|
575 |
private MethodHandle handleRewriteException(final OptimismInfo oldOptimismInfo, final RewriteException re) { |
|
576 |
final MethodType type = type(); |
|
577 |
// Compiler needs a call site type as its input, which always has a callee parameter, so we must add it if |
|
578 |
// this function doesn't have a callee parameter. |
|
579 |
final MethodType callSiteType = type.parameterType(0) == ScriptFunction.class ? type : type.insertParameterTypes(0, ScriptFunction.class); |
|
16523
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
diff
changeset
|
580 |
|
24719 | 581 |
final FunctionNode fn = oldOptimismInfo.recompile(callSiteType, re); |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
582 |
if (log.isEnabled()) { |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
583 |
log.info(new RecompilationEvent(Level.INFO, re, re.getReturnValueNonDestructive()), "\tRewriteException ", re.getMessageShort()); |
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
|
584 |
} |
24719 | 585 |
|
586 |
// It didn't necessarily recompile, e.g. for an outer invocation of a recursive function if we already |
|
587 |
// recompiled a deoptimized version for an inner invocation. |
|
588 |
||
589 |
final boolean isOptimistic; |
|
590 |
if (fn != null) { |
|
591 |
//is recompiled |
|
592 |
assert optimismInfo == oldOptimismInfo; |
|
593 |
isOptimistic = fn.isOptimistic(); |
|
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
594 |
if (log.isEnabled()) { |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
595 |
log.info("Recompiled '", fn.getName(), "' (", Debug.id(this), ")", isOptimistic ? " remains optimistic." : " is no longer optimistic."); |
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
|
596 |
} |
24719 | 597 |
final MethodHandle newInvoker = oldOptimismInfo.data.lookup(fn); |
598 |
invoker = newInvoker.asType(type.changeReturnType(newInvoker.type().returnType())); |
|
599 |
constructor = null; // Will be regenerated when needed |
|
600 |
// Note that we only adjust the switch point after we set the invoker/constructor. This is important. |
|
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
|
601 |
if (isOptimistic) { |
24719 | 602 |
// Otherwise, set a new switch point. |
603 |
oldOptimismInfo.newOptimisticAssumptions(); |
|
604 |
} else { |
|
605 |
// If we got to a point where we no longer have optimistic assumptions, let the optimism info go. |
|
606 |
optimismInfo = null; |
|
607 |
} |
|
608 |
} else { |
|
609 |
isOptimistic = isOptimistic(); |
|
610 |
assert !isOptimistic || optimismInfo == oldOptimismInfo; |
|
611 |
} |
|
612 |
||
613 |
final MethodHandle restOf = changeReturnType(oldOptimismInfo.compileRestOfMethod(callSiteType, re), Object.class); |
|
614 |
// If rest-of is itself optimistic, we must make sure that we can repeat a deoptimization if it, too hits an exception. |
|
615 |
return isOptimistic ? MH.catchException(restOf, RewriteException.class, createRewriteExceptionHandler()) : restOf; |
|
616 |
} |
|
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
|
617 |
|
24719 | 618 |
private static class OptimismInfo { |
619 |
// TODO: this is pointing to its owning ScriptFunctionData. Re-evaluate if that's okay. |
|
620 |
private final RecompilableScriptFunctionData data; |
|
621 |
private final Map<Integer, Type> invalidatedProgramPoints = new TreeMap<>(); |
|
622 |
private SwitchPoint optimisticAssumptions; |
|
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
623 |
private final DebugLogger log = Global.instance().getLogger(RecompilableScriptFunctionData.class); |
24719 | 624 |
|
625 |
OptimismInfo(final RecompilableScriptFunctionData data) { |
|
626 |
this.data = data; |
|
627 |
newOptimisticAssumptions(); |
|
628 |
} |
|
629 |
||
630 |
private void newOptimisticAssumptions() { |
|
631 |
optimisticAssumptions = new SwitchPoint(); |
|
632 |
} |
|
633 |
||
634 |
FunctionNode recompile(final MethodType callSiteType, final RewriteException e) { |
|
635 |
final Type retType = e.getReturnType(); |
|
636 |
final Type previousFailedType = invalidatedProgramPoints.put(e.getProgramPoint(), retType); |
|
637 |
if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) { |
|
638 |
final StackTraceElement[] stack = e.getStackTrace(); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
639 |
final String functionId = stack.length == 0 ? data.getName() : stack[0].getClassName() + "." + stack[0].getMethodName(); |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
640 |
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."); |
24719 | 641 |
return null; |
642 |
} |
|
643 |
SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions }); |
|
24740
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
644 |
return data.compile(callSiteType, invalidatedProgramPoints, e.getRuntimeScope(), "Deoptimizing recompilation", data.getDefaultTransform(callSiteType)); |
24719 | 645 |
} |
646 |
||
647 |
MethodHandle compileRestOfMethod(final MethodType callSiteType, final RewriteException e) { |
|
648 |
final int[] prevEntryPoints = e.getPreviousContinuationEntryPoints(); |
|
649 |
final int[] entryPoints; |
|
650 |
if(prevEntryPoints == null) { |
|
651 |
entryPoints = new int[1]; |
|
652 |
} else { |
|
653 |
final int l = prevEntryPoints.length; |
|
654 |
entryPoints = new int[l + 1]; |
|
655 |
System.arraycopy(prevEntryPoints, 0, entryPoints, 1, l); |
|
656 |
} |
|
657 |
entryPoints[0] = e.getProgramPoint(); |
|
24740
26791be09688
8040089: Apply to call transform was incomplete. Now passes all tests and performance is back
lagergren
parents:
24738
diff
changeset
|
658 |
return data.compileRestOfMethod(callSiteType, invalidatedProgramPoints, entryPoints, e.getRuntimeScope(), data.getDefaultTransform(callSiteType)); |
24719 | 659 |
} |
660 |
} |
|
661 |
||
662 |
@SuppressWarnings("unused") |
|
663 |
private static Object newFilter(final Object result, final Object allocation) { |
|
664 |
return (result instanceof ScriptObject || !JSType.isPrimitive(result))? result : allocation; |
|
665 |
} |
|
666 |
||
667 |
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { |
|
668 |
return MH.findStatic(MethodHandles.lookup(), CompiledFunction.class, name, MH.type(rtype, types)); |
|
669 |
} |
|
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
|
670 |
} |