author | lagergren |
Wed, 23 Apr 2014 17:37:41 +0200 | |
changeset 24745 | 3a6e1477362b |
parent 24744 | 5290da85fc3d |
child 24753 | 675feda2f82d |
permissions | -rw-r--r-- |
16147 | 1 |
/* |
16151 | 2 |
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
16147 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package jdk.nashorn.internal.runtime; |
|
27 |
||
28 |
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; |
|
22669 | 29 |
import static jdk.nashorn.internal.lookup.Lookup.MH; |
16147 | 30 |
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; |
31 |
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; |
|
24719 | 32 |
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; |
16147 | 33 |
|
34 |
import java.lang.invoke.MethodHandle; |
|
35 |
import java.lang.invoke.MethodHandles; |
|
36 |
import java.lang.invoke.MethodType; |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
37 |
import java.lang.invoke.SwitchPoint; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
16233
diff
changeset
|
38 |
import jdk.internal.dynalink.CallSiteDescriptor; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
16233
diff
changeset
|
39 |
import jdk.internal.dynalink.linker.GuardedInvocation; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
16233
diff
changeset
|
40 |
import jdk.internal.dynalink.linker.LinkRequest; |
24719 | 41 |
import jdk.internal.dynalink.support.Guards; |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
42 |
import jdk.nashorn.internal.codegen.ApplySpecialization; |
16147 | 43 |
import jdk.nashorn.internal.codegen.CompilerConstants.Call; |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
44 |
import jdk.nashorn.internal.objects.Global; |
24719 | 45 |
import jdk.nashorn.internal.objects.NativeFunction; |
46 |
import jdk.nashorn.internal.runtime.linker.Bootstrap; |
|
16147 | 47 |
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; |
48 |
||
49 |
/** |
|
50 |
* Runtime representation of a JavaScript function. |
|
51 |
*/ |
|
52 |
public abstract class ScriptFunction extends ScriptObject { |
|
53 |
||
54 |
/** Method handle for prototype getter for this ScriptFunction */ |
|
24719 | 55 |
public static final MethodHandle G$PROTOTYPE = findOwnMH_S("G$prototype", Object.class, Object.class); |
16147 | 56 |
|
57 |
/** Method handle for prototype setter for this ScriptFunction */ |
|
24719 | 58 |
public static final MethodHandle S$PROTOTYPE = findOwnMH_S("S$prototype", void.class, Object.class, Object.class); |
16147 | 59 |
|
60 |
/** Method handle for length getter for this ScriptFunction */ |
|
24719 | 61 |
public static final MethodHandle G$LENGTH = findOwnMH_S("G$length", int.class, Object.class); |
16147 | 62 |
|
63 |
/** Method handle for name getter for this ScriptFunction */ |
|
24719 | 64 |
public static final MethodHandle G$NAME = findOwnMH_S("G$name", Object.class, Object.class); |
16147 | 65 |
|
20946 | 66 |
/** Method handle used for implementing sync() in mozilla_compat */ |
24719 | 67 |
public static final MethodHandle INVOKE_SYNC = findOwnMH_S("invokeSync", Object.class, ScriptFunction.class, Object.class, Object.class, Object[].class); |
20946 | 68 |
|
16147 | 69 |
/** Method handle for allocate function for this ScriptFunction */ |
24719 | 70 |
static final MethodHandle ALLOCATE = findOwnMH_V("allocate", Object.class); |
16147 | 71 |
|
24719 | 72 |
private static final MethodHandle WRAPFILTER = findOwnMH_S("wrapFilter", Object.class, Object.class); |
16207
ed4aec2d599c
8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents:
16206
diff
changeset
|
73 |
|
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
|
74 |
private static final MethodHandle SCRIPTFUNCTION_GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class); |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
75 |
|
16147 | 76 |
/** method handle to scope getter for this ScriptFunction */ |
77 |
public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class); |
|
78 |
||
24719 | 79 |
private static final MethodHandle IS_FUNCTION_MH = findOwnMH_S("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class); |
80 |
||
81 |
private static final MethodHandle IS_APPLY_FUNCTION = findOwnMH_S("isApplyFunction", boolean.class, boolean.class, Object.class, Object.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:
16277
diff
changeset
|
82 |
|
24719 | 83 |
private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH_S("isNonStrictFunction", boolean.class, Object.class, Object.class, ScriptFunctionData.class); |
16147 | 84 |
|
24719 | 85 |
private static final MethodHandle ADD_ZEROTH_ELEMENT = findOwnMH_S("addZerothElement", Object[].class, Object[].class, Object.class); |
86 |
||
87 |
private static final MethodHandle WRAP_THIS = MH.findStatic(MethodHandles.lookup(), ScriptFunctionData.class, "wrapThis", MH.type(Object.class, Object.class)); |
|
18868
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
88 |
|
16147 | 89 |
/** The parent scope. */ |
90 |
private final ScriptObject scope; |
|
91 |
||
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:
16277
diff
changeset
|
92 |
private final ScriptFunctionData data; |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
93 |
|
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
22669
diff
changeset
|
94 |
/** The property map used for newly allocated object when function is used as constructor. */ |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
22669
diff
changeset
|
95 |
protected PropertyMap allocatorMap; |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
22669
diff
changeset
|
96 |
|
16147 | 97 |
/** |
98 |
* Constructor |
|
99 |
* |
|
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
100 |
* @param name function name |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
101 |
* @param methodHandle method handle to function (if specializations are present, assumed to be most generic) |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
102 |
* @param map property map |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
103 |
* @param scope scope |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
104 |
* @param specs specialized version of this function - other method handles |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
105 |
* @param flags {@link ScriptFunctionData} flags |
16147 | 106 |
*/ |
107 |
protected ScriptFunction( |
|
108 |
final String name, |
|
109 |
final MethodHandle methodHandle, |
|
110 |
final PropertyMap map, |
|
111 |
final ScriptObject scope, |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
112 |
final MethodHandle[] specs, |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
113 |
final int flags) { |
16206
83069fa0935b
8006529: Methods always get callee - it should be conditional
attila
parents:
16202
diff
changeset
|
114 |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
115 |
this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope); |
16147 | 116 |
} |
117 |
||
118 |
/** |
|
119 |
* Constructor |
|
120 |
* |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
121 |
* @param data static function data |
16147 | 122 |
* @param map property map |
123 |
* @param scope scope |
|
124 |
*/ |
|
125 |
protected ScriptFunction( |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
126 |
final ScriptFunctionData data, |
16147 | 127 |
final PropertyMap map, |
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
128 |
final ScriptObject scope) { |
16147 | 129 |
|
130 |
super(map); |
|
131 |
||
132 |
if (Context.DEBUG) { |
|
133 |
constructorCount++; |
|
134 |
} |
|
135 |
||
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:
16277
diff
changeset
|
136 |
this.data = data; |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
137 |
this.scope = scope; |
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
22669
diff
changeset
|
138 |
this.allocatorMap = data.getAllocatorMap(); |
16147 | 139 |
} |
140 |
||
141 |
@Override |
|
142 |
public String getClassName() { |
|
143 |
return "Function"; |
|
144 |
} |
|
145 |
||
146 |
/** |
|
147 |
* ECMA 15.3.5.3 [[HasInstance]] (V) |
|
148 |
* Step 3 if "prototype" value is not an Object, throw TypeError |
|
149 |
*/ |
|
150 |
@Override |
|
151 |
public boolean isInstance(final ScriptObject instance) { |
|
16228 | 152 |
final Object basePrototype = getTargetFunction().getPrototype(); |
153 |
if (!(basePrototype instanceof ScriptObject)) { |
|
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16234
diff
changeset
|
154 |
throw typeError("prototype.not.an.object", ScriptRuntime.safeToString(getTargetFunction()), ScriptRuntime.safeToString(basePrototype)); |
16147 | 155 |
} |
156 |
||
157 |
for (ScriptObject proto = instance.getProto(); proto != null; proto = proto.getProto()) { |
|
16228 | 158 |
if (proto == basePrototype) { |
16147 | 159 |
return true; |
160 |
} |
|
161 |
} |
|
162 |
||
163 |
return false; |
|
164 |
} |
|
165 |
||
166 |
/** |
|
16228 | 167 |
* Returns the target function for this function. If the function was not created using |
168 |
* {@link #makeBoundFunction(Object, Object[])}, its target function is itself. If it is bound, its target function |
|
169 |
* is the target function of the function it was made from (therefore, the target function is always the final, |
|
170 |
* unbound recipient of the calls). |
|
171 |
* @return the target function for this function. |
|
16147 | 172 |
*/ |
16228 | 173 |
protected ScriptFunction getTargetFunction() { |
174 |
return this; |
|
175 |
} |
|
176 |
||
177 |
boolean isBoundFunction() { |
|
178 |
return getTargetFunction() != this; |
|
16147 | 179 |
} |
180 |
||
181 |
/** |
|
182 |
* Set the arity of this ScriptFunction |
|
183 |
* @param arity arity |
|
184 |
*/ |
|
185 |
public final void setArity(final int arity) { |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
186 |
data.setArity(arity); |
16147 | 187 |
} |
188 |
||
189 |
/** |
|
190 |
* Is this a ECMAScript 'use strict' function? |
|
191 |
* @return true if function is in strict mode |
|
192 |
*/ |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
193 |
public boolean isStrict() { |
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
194 |
return data.isStrict(); |
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
195 |
} |
16147 | 196 |
|
197 |
/** |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
198 |
* Returns true if this is a non-strict, non-built-in function that requires non-primitive this argument |
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
199 |
* according to ECMA 10.4.3. |
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
200 |
* @return true if this argument must be an object |
16186
91bd9d2aa2f5
8006570: This-value for non-strict functions should be converted to object
hannesw
parents:
16173
diff
changeset
|
201 |
*/ |
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
202 |
public boolean needsWrappedThis() { |
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
203 |
return data.needsWrappedThis(); |
16186
91bd9d2aa2f5
8006570: This-value for non-strict functions should be converted to object
hannesw
parents:
16173
diff
changeset
|
204 |
} |
91bd9d2aa2f5
8006570: This-value for non-strict functions should be converted to object
hannesw
parents:
16173
diff
changeset
|
205 |
|
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:
24721
diff
changeset
|
206 |
private static boolean needsWrappedThis(final Object fn) { |
24719 | 207 |
return fn instanceof ScriptFunction ? ((ScriptFunction)fn).needsWrappedThis() : false; |
208 |
} |
|
209 |
||
16186
91bd9d2aa2f5
8006570: This-value for non-strict functions should be converted to object
hannesw
parents:
16173
diff
changeset
|
210 |
/** |
16147 | 211 |
* Execute this script function. |
212 |
* @param self Target object. |
|
213 |
* @param arguments Call arguments. |
|
214 |
* @return ScriptFunction result. |
|
215 |
* @throws Throwable if there is an exception/error with the invocation or thrown from it |
|
216 |
*/ |
|
16232
efd57dd90de6
8008197: Cross script engine function calls do not work as expected
sundar
parents:
16228
diff
changeset
|
217 |
Object invoke(final Object self, final Object... arguments) throws Throwable { |
16147 | 218 |
if (Context.DEBUG) { |
219 |
invokes++; |
|
220 |
} |
|
16228 | 221 |
return data.invoke(this, self, arguments); |
16147 | 222 |
} |
223 |
||
224 |
/** |
|
18614 | 225 |
* Execute this script function as a constructor. |
226 |
* @param arguments Call arguments. |
|
227 |
* @return Newly constructed result. |
|
228 |
* @throws Throwable if there is an exception/error with the invocation or thrown from it |
|
229 |
*/ |
|
230 |
Object construct(final Object... arguments) throws Throwable { |
|
231 |
return data.construct(this, arguments); |
|
232 |
} |
|
233 |
||
234 |
/** |
|
16147 | 235 |
* Allocate function. Called from generated {@link ScriptObject} code |
236 |
* for allocation as a factory method |
|
237 |
* |
|
238 |
* @return a new instance of the {@link ScriptObject} whose allocator this is |
|
239 |
*/ |
|
16228 | 240 |
@SuppressWarnings("unused") |
241 |
private Object allocate() { |
|
16147 | 242 |
if (Context.DEBUG) { |
243 |
allocations++; |
|
244 |
} |
|
24721
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
245 |
|
16228 | 246 |
assert !isBoundFunction(); // allocate never invoked on bound functions |
16147 | 247 |
|
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
22669
diff
changeset
|
248 |
final ScriptObject object = data.allocate(allocatorMap); |
16147 | 249 |
|
250 |
if (object != null) { |
|
24721
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
251 |
final Object prototype = getPrototype(); |
16147 | 252 |
if (prototype instanceof ScriptObject) { |
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
22669
diff
changeset
|
253 |
object.setInitialProto((ScriptObject)prototype); |
16147 | 254 |
} |
255 |
||
256 |
if (object.getProto() == null) { |
|
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
22669
diff
changeset
|
257 |
object.setInitialProto(getObjectPrototype()); |
16147 | 258 |
} |
259 |
} |
|
260 |
||
261 |
return object; |
|
262 |
} |
|
263 |
||
264 |
/** |
|
265 |
* Return Object.prototype - used by "allocate" |
|
266 |
* @return Object.prototype |
|
267 |
*/ |
|
268 |
protected abstract ScriptObject getObjectPrototype(); |
|
269 |
||
270 |
/** |
|
16228 | 271 |
* Creates a version of this function bound to a specific "self" and other arguments, as per |
272 |
* {@code Function.prototype.bind} functionality in ECMAScript 5.1 section 15.3.4.5. |
|
273 |
* @param self the self to bind to this function. Can be null (in which case, null is bound as this). |
|
274 |
* @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments. |
|
275 |
* @return a function with the specified self and parameters bound. |
|
16147 | 276 |
*/ |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
277 |
protected ScriptFunction makeBoundFunction(final Object self, final Object[] args) { |
16228 | 278 |
return makeBoundFunction(data.makeBoundFunctionData(this, self, args)); |
279 |
} |
|
16147 | 280 |
|
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
281 |
/** |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
282 |
* Create a version of this function as in {@link ScriptFunction#makeBoundFunction(Object, Object[])}, |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
283 |
* but using a {@link ScriptFunctionData} for the bound data. |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
284 |
* |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
285 |
* @param boundData ScriptFuntionData for the bound function |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
286 |
* @return a function with the bindings performed according to the given data |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16232
diff
changeset
|
287 |
*/ |
16228 | 288 |
protected abstract ScriptFunction makeBoundFunction(ScriptFunctionData boundData); |
16147 | 289 |
|
290 |
@Override |
|
291 |
public final String safeToString() { |
|
292 |
return toSource(); |
|
293 |
} |
|
294 |
||
295 |
@Override |
|
296 |
public String toString() { |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
297 |
return data.toString(); |
16147 | 298 |
} |
299 |
||
300 |
/** |
|
301 |
* Get this function as a String containing its source code. If no source code |
|
302 |
* exists in this ScriptFunction, its contents will be displayed as {@code [native code]} |
|
303 |
* @return string representation of this function's source |
|
304 |
*/ |
|
305 |
public final String toSource() { |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
306 |
return data.toSource(); |
16147 | 307 |
} |
308 |
||
309 |
/** |
|
310 |
* Get the prototype object for this function |
|
311 |
* @return prototype |
|
312 |
*/ |
|
17252
9aeb443c4740
8006559: Octane:pdfjs leaks memory, runs slower iteration to iteration
hannesw
parents:
16523
diff
changeset
|
313 |
public abstract Object getPrototype(); |
16147 | 314 |
|
315 |
/** |
|
316 |
* Set the prototype object for this function |
|
317 |
* @param prototype new prototype object |
|
318 |
*/ |
|
17252
9aeb443c4740
8006559: Octane:pdfjs leaks memory, runs slower iteration to iteration
hannesw
parents:
16523
diff
changeset
|
319 |
public abstract void setPrototype(Object prototype); |
16147 | 320 |
|
321 |
/** |
|
20946 | 322 |
* Create a function that invokes this function synchronized on {@code sync} or the self object |
323 |
* of the invocation. |
|
324 |
* @param sync the Object to synchronize on, or undefined |
|
325 |
* @return synchronized function |
|
326 |
*/ |
|
24719 | 327 |
public abstract ScriptFunction makeSynchronizedFunction(Object sync); |
20946 | 328 |
|
329 |
/** |
|
16147 | 330 |
* Return the invoke handle bound to a given ScriptObject self reference. |
331 |
* If callee parameter is required result is rebound to this. |
|
332 |
* |
|
333 |
* @param self self reference |
|
334 |
* @return bound invoke handle |
|
335 |
*/ |
|
20932 | 336 |
public final MethodHandle getBoundInvokeHandle(final Object self) { |
24729
2b13051f2122
8037534: Use scope types to determine optimistic types
attila
parents:
24727
diff
changeset
|
337 |
return MH.bindTo(bindToCalleeIfNeeded(data.getGenericInvoker(scope)), self); |
16147 | 338 |
} |
339 |
||
16225
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
340 |
/** |
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
341 |
* Bind the method handle to this {@code ScriptFunction} instance if it needs a callee parameter. If this function's |
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
342 |
* method handles don't have a callee parameter, the handle is returned unchanged. |
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
343 |
* @param methodHandle the method handle to potentially bind to this function instance. |
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
344 |
* @return the potentially bound method handle |
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
345 |
*/ |
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
346 |
private MethodHandle bindToCalleeIfNeeded(final MethodHandle methodHandle) { |
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:
16277
diff
changeset
|
347 |
return ScriptFunctionData.needsCallee(methodHandle) ? MH.bindTo(methodHandle, this) : methodHandle; |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
348 |
|
16225
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
349 |
} |
16147 | 350 |
|
351 |
/** |
|
352 |
* Get the name for this function |
|
353 |
* @return the name |
|
354 |
*/ |
|
355 |
public final String getName() { |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
356 |
return data.getName(); |
16147 | 357 |
} |
358 |
||
359 |
||
360 |
/** |
|
361 |
* Get the scope for this function |
|
362 |
* @return the scope |
|
363 |
*/ |
|
364 |
public final ScriptObject getScope() { |
|
365 |
return scope; |
|
366 |
} |
|
367 |
||
368 |
/** |
|
369 |
* Prototype getter for this ScriptFunction - follows the naming convention |
|
370 |
* used by Nasgen and the code generator |
|
371 |
* |
|
372 |
* @param self self reference |
|
373 |
* @return self's prototype |
|
374 |
*/ |
|
375 |
public static Object G$prototype(final Object self) { |
|
24721
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
376 |
return self instanceof ScriptFunction ? |
16147 | 377 |
((ScriptFunction)self).getPrototype() : |
378 |
UNDEFINED; |
|
379 |
} |
|
380 |
||
381 |
/** |
|
382 |
* Prototype setter for this ScriptFunction - follows the naming convention |
|
383 |
* used by Nasgen and the code generator |
|
384 |
* |
|
385 |
* @param self self reference |
|
386 |
* @param prototype prototype to set |
|
387 |
*/ |
|
388 |
public static void S$prototype(final Object self, final Object prototype) { |
|
389 |
if (self instanceof ScriptFunction) { |
|
390 |
((ScriptFunction)self).setPrototype(prototype); |
|
391 |
} |
|
392 |
} |
|
393 |
||
394 |
/** |
|
395 |
* Length getter - ECMA 15.3.3.2: Function.length |
|
396 |
* @param self self reference |
|
397 |
* @return length |
|
398 |
*/ |
|
399 |
public static int G$length(final Object self) { |
|
400 |
if (self instanceof ScriptFunction) { |
|
16228 | 401 |
return ((ScriptFunction)self).data.getArity(); |
16147 | 402 |
} |
403 |
||
404 |
return 0; |
|
405 |
} |
|
406 |
||
407 |
/** |
|
408 |
* Name getter - ECMA Function.name |
|
409 |
* @param self self refence |
|
410 |
* @return the name, or undefined if none |
|
411 |
*/ |
|
412 |
public static Object G$name(final Object self) { |
|
413 |
if (self instanceof ScriptFunction) { |
|
414 |
return ((ScriptFunction)self).getName(); |
|
415 |
} |
|
416 |
||
417 |
return UNDEFINED; |
|
418 |
} |
|
419 |
||
420 |
/** |
|
421 |
* Get the prototype for this ScriptFunction |
|
422 |
* @param constructor constructor |
|
423 |
* @return prototype, or null if given constructor is not a ScriptFunction |
|
424 |
*/ |
|
425 |
public static ScriptObject getPrototype(final Object constructor) { |
|
426 |
if (constructor instanceof ScriptFunction) { |
|
427 |
final Object proto = ((ScriptFunction)constructor).getPrototype(); |
|
428 |
if (proto instanceof ScriptObject) { |
|
429 |
return (ScriptObject)proto; |
|
430 |
} |
|
431 |
} |
|
432 |
||
433 |
return null; |
|
434 |
} |
|
435 |
||
436 |
// These counters are updated only in debug mode. |
|
437 |
private static int constructorCount; |
|
438 |
private static int invokes; |
|
439 |
private static int allocations; |
|
440 |
||
441 |
/** |
|
442 |
* @return the constructorCount |
|
443 |
*/ |
|
444 |
public static int getConstructorCount() { |
|
445 |
return constructorCount; |
|
446 |
} |
|
447 |
||
448 |
/** |
|
449 |
* @return the invokes |
|
450 |
*/ |
|
451 |
public static int getInvokes() { |
|
452 |
return invokes; |
|
453 |
} |
|
454 |
||
455 |
/** |
|
456 |
* @return the allocations |
|
457 |
*/ |
|
458 |
public static int getAllocations() { |
|
459 |
return allocations; |
|
460 |
} |
|
461 |
||
462 |
@Override |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
463 |
protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) { |
16147 | 464 |
final MethodType type = desc.getMethodType(); |
24719 | 465 |
assert desc.getMethodType().returnType() == Object.class && !NashornCallSiteDescriptor.isOptimistic(desc); |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
466 |
final CompiledFunction cf = data.getBestConstructor(type, scope); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
467 |
final GuardedInvocation bestCtorInv = new GuardedInvocation(cf.getConstructor(), cf.getOptimisticAssumptionsSwitchPoint()); |
24720 | 468 |
//TODO - ClassCastException |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
469 |
return new GuardedInvocation(pairArguments(bestCtorInv.getInvocation(), type), getFunctionGuard(this, cf.getFlags()), bestCtorInv.getSwitchPoints(), null); |
16147 | 470 |
} |
471 |
||
16207
ed4aec2d599c
8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents:
16206
diff
changeset
|
472 |
@SuppressWarnings("unused") |
ed4aec2d599c
8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents:
16206
diff
changeset
|
473 |
private static Object wrapFilter(final Object obj) { |
16228 | 474 |
if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) { |
16207
ed4aec2d599c
8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents:
16206
diff
changeset
|
475 |
return obj; |
ed4aec2d599c
8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents:
16206
diff
changeset
|
476 |
} |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
477 |
return Context.getGlobal().wrapAsObject(obj); |
16207
ed4aec2d599c
8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents:
16206
diff
changeset
|
478 |
} |
ed4aec2d599c
8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents:
16206
diff
changeset
|
479 |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
480 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
481 |
@SuppressWarnings("unused") |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
482 |
private static Object globalFilter(final Object object) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
483 |
// replace whatever we get with the current global object |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
484 |
return Context.getGlobal(); |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
485 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
486 |
|
16147 | 487 |
/** |
488 |
* dyn:call call site signature: (callee, thiz, [args...]) |
|
16225
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
489 |
* generated method signature: (callee, thiz, [args...]) |
16147 | 490 |
* |
491 |
* cases: |
|
492 |
* (a) method has callee parameter |
|
493 |
* (1) for local/scope calls, we just bind thiz and drop the second argument. |
|
494 |
* (2) for normal this-calls, we have to swap thiz and callee to get matching signatures. |
|
495 |
* (b) method doesn't have callee parameter (builtin functions) |
|
496 |
* (3) for local/scope calls, bind thiz and drop both callee and thiz. |
|
497 |
* (4) for normal this-calls, drop callee. |
|
24719 | 498 |
* |
499 |
* @return guarded invocation for call |
|
16147 | 500 |
*/ |
501 |
@Override |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16188
diff
changeset
|
502 |
protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) { |
16147 | 503 |
final MethodType type = desc.getMethodType(); |
504 |
||
24719 | 505 |
final String name = getName(); |
506 |
final boolean isUnstable = request.isCallSiteUnstable(); |
|
507 |
final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
508 |
|
24719 | 509 |
final boolean isCall = !scopeCall && data.isBuiltin() && "call".equals(name); |
510 |
final boolean isApply = !scopeCall && data.isBuiltin() && "apply".equals(name); |
|
16147 | 511 |
|
24719 | 512 |
if (isUnstable && !(isApply || isCall)) { |
513 |
//megamorphic - replace call with apply |
|
514 |
final MethodHandle handle; |
|
515 |
//ensure that the callsite is vararg so apply can consume it |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
516 |
if (type.parameterCount() == 3 && type.parameterType(2) == Object[].class) { |
24719 | 517 |
// Vararg call site |
518 |
handle = ScriptRuntime.APPLY.methodHandle(); |
|
519 |
} else { |
|
520 |
// (callee, this, args...) => (callee, this, args[]) |
|
521 |
handle = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2); |
|
522 |
} |
|
16147 | 523 |
|
16225
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
524 |
// If call site is statically typed to take a ScriptFunction, we don't need a guard, otherwise we need a |
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
525 |
// generic "is this a ScriptFunction?" guard. |
24719 | 526 |
return new GuardedInvocation( |
527 |
handle, |
|
528 |
null, |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
529 |
(SwitchPoint)null, |
24719 | 530 |
ClassCastException.class); |
16147 | 531 |
} |
532 |
||
533 |
MethodHandle boundHandle; |
|
16207
ed4aec2d599c
8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents:
16206
diff
changeset
|
534 |
MethodHandle guard = null; |
ed4aec2d599c
8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents:
16206
diff
changeset
|
535 |
|
24719 | 536 |
// Special handling of Function.apply and Function.call. Note we must be invoking |
537 |
if ((isApply || isCall) && !isUnstable) { |
|
538 |
final Object[] args = request.getArguments(); |
|
539 |
if (Bootstrap.isCallable(args[1])) { |
|
540 |
return createApplyOrCallCall(isApply, desc, request, args); |
|
541 |
} |
|
542 |
} //else just fall through and link as ordinary function or unstable apply |
|
19456
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
543 |
|
24719 | 544 |
final int programPoint = NashornCallSiteDescriptor.isOptimistic(desc) ? NashornCallSiteDescriptor.getProgramPoint(desc) : INVALID_PROGRAM_POINT; |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
545 |
final CompiledFunction cf = data.getBestInvoker(type, programPoint, scope); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
546 |
final GuardedInvocation bestInvoker = |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
547 |
new GuardedInvocation( |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
548 |
cf.createInvoker(type.returnType(), programPoint), |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
549 |
cf.getOptimisticAssumptionsSwitchPoint()); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
550 |
|
24719 | 551 |
final MethodHandle callHandle = bestInvoker.getInvocation(); |
24727 | 552 |
|
16216
46ed48fd84d3
8007273: Creation of ScriptFunctions can be refactored
hannesw
parents:
16210
diff
changeset
|
553 |
if (data.needsCallee()) { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
554 |
if (scopeCall && needsWrappedThis()) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
555 |
// (callee, this, args...) => (callee, [this], args...) |
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
|
556 |
boundHandle = MH.filterArguments(callHandle, 1, SCRIPTFUNCTION_GLOBALFILTER); |
16147 | 557 |
} else { |
16225
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
558 |
// It's already (callee, this, args...), just what we need |
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
559 |
boundHandle = callHandle; |
16147 | 560 |
} |
24719 | 561 |
} else if (data.isBuiltin() && "extend".equals(data.getName())) { |
562 |
// NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the |
|
563 |
// current lookup as its "this" so it can do security-sensitive creation of adapter classes. |
|
564 |
boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, type.parameterType(0), type.parameterType(1)); |
|
24727 | 565 |
} else if (scopeCall && needsWrappedThis()) { |
24719 | 566 |
// Make a handle that drops the passed "this" argument and substitutes either Global or Undefined |
24727 | 567 |
// (this, args...) => ([this], args...) |
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
|
568 |
boundHandle = MH.filterArguments(callHandle, 0, SCRIPTFUNCTION_GLOBALFILTER); |
24727 | 569 |
// ([this], args...) => ([callee], [this], args...) |
570 |
boundHandle = MH.dropArguments(boundHandle, 0, type.parameterType(0)); |
|
16147 | 571 |
} else { |
24719 | 572 |
// (this, args...) => ([callee], this, args...) |
573 |
boundHandle = MH.dropArguments(callHandle, 0, type.parameterType(0)); |
|
16147 | 574 |
} |
575 |
||
19456
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
576 |
// For non-strict functions, check whether this-object is primitive type. |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
577 |
// If so add a to-object-wrapper argument filter. |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
578 |
// Else install a guard that will trigger a relink when the argument becomes primitive. |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
579 |
if (!scopeCall && needsWrappedThis()) { |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
580 |
if (ScriptFunctionData.isPrimitiveThis(request.getArguments()[1])) { |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
581 |
boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER); |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
582 |
} else { |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
583 |
guard = getNonStrictFunctionGuard(this); |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
584 |
} |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
585 |
} |
8cc345d620c8
8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents:
18868
diff
changeset
|
586 |
|
16147 | 587 |
boundHandle = pairArguments(boundHandle, 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:
16277
diff
changeset
|
588 |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
589 |
return new GuardedInvocation(boundHandle, guard == null ? getFunctionGuard(this, cf.getFlags()) : guard, bestInvoker.getSwitchPoints(), null); |
24719 | 590 |
} |
591 |
||
592 |
private GuardedInvocation createApplyOrCallCall(final boolean isApply, final CallSiteDescriptor desc, final LinkRequest request, final Object[] args) { |
|
593 |
final MethodType descType = desc.getMethodType(); |
|
594 |
final int paramCount = descType.parameterCount(); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
595 |
|
24719 | 596 |
final boolean passesThis = paramCount > 2; |
597 |
final boolean passesArgs = paramCount > 3; |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
598 |
final int realArgCount = passesArgs ? paramCount - 3 : 0; |
24719 | 599 |
|
600 |
final Object appliedFn = args[1]; |
|
601 |
final boolean appliedFnNeedsWrappedThis = needsWrappedThis(appliedFn); |
|
602 |
||
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
603 |
//box call back to apply |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
604 |
CallSiteDescriptor appliedDesc = desc; |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
605 |
final SwitchPoint applyToCallSwitchPoint = Global.instance().getChangeCallback("apply"); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
606 |
//enough to change the proto switchPoint here |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
607 |
|
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
608 |
final boolean isApplyToCall = NashornCallSiteDescriptor.isApplyToCall(desc); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
609 |
final boolean isFailedApplyToCall = isApplyToCall && applyToCallSwitchPoint.hasBeenInvalidated(); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
610 |
|
24719 | 611 |
// R(apply|call, ...) => R(...) |
612 |
MethodType appliedType = descType.dropParameterTypes(0, 1); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
613 |
if (!passesThis) { |
24719 | 614 |
// R() => R(this) |
615 |
appliedType = appliedType.insertParameterTypes(1, Object.class); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
616 |
} else if (appliedFnNeedsWrappedThis) { |
24719 | 617 |
appliedType = appliedType.changeParameterType(1, Object.class); |
618 |
} |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
619 |
|
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
620 |
if (isApply || isFailedApplyToCall) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
621 |
if (passesArgs) { |
24719 | 622 |
// R(this, args) => R(this, Object[]) |
623 |
appliedType = appliedType.changeParameterType(2, Object[].class); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
624 |
// drop any extraneous arguments for the apply fail case |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
625 |
if (isFailedApplyToCall) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
626 |
appliedType = appliedType.dropParameterTypes(3, paramCount - 1); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
627 |
} |
24719 | 628 |
} else { |
629 |
// R(this) => R(this, Object[]) |
|
630 |
appliedType = appliedType.insertParameterTypes(2, Object[].class); |
|
631 |
} |
|
632 |
} |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
633 |
|
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
634 |
appliedDesc = appliedDesc.changeMethodType(appliedType); |
24719 | 635 |
|
636 |
// Create the same arguments for the delegate linking request that would be passed in an actual apply'd invocation |
|
637 |
final Object[] appliedArgs = new Object[isApply ? 3 : appliedType.parameterCount()]; |
|
638 |
appliedArgs[0] = appliedFn; |
|
24721
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
639 |
appliedArgs[1] = passesThis ? appliedFnNeedsWrappedThis ? ScriptFunctionData.wrapThis(args[2]) : args[2] : ScriptRuntime.UNDEFINED; |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
640 |
if (isApply && !isFailedApplyToCall) { |
24719 | 641 |
appliedArgs[2] = passesArgs ? NativeFunction.toApplyArgs(args[3]) : ScriptRuntime.EMPTY_ARRAY; |
642 |
} else { |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
643 |
if (passesArgs) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
644 |
if (isFailedApplyToCall) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
645 |
final Object[] tmp = new Object[args.length - 3]; |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
646 |
System.arraycopy(args, 3, tmp, 0, tmp.length); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
647 |
appliedArgs[2] = NativeFunction.toApplyArgs(tmp); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
648 |
} else { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
649 |
System.arraycopy(args, 3, appliedArgs, 2, args.length - 3); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
650 |
} |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
651 |
} else if (isFailedApplyToCall) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
652 |
appliedArgs[2] = ScriptRuntime.EMPTY_ARRAY; |
24719 | 653 |
} |
654 |
} |
|
655 |
||
656 |
// Ask the linker machinery for an invocation of the target function |
|
657 |
final LinkRequest appliedRequest = request.replaceArguments(appliedDesc, appliedArgs); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
658 |
GuardedInvocation appliedInvocation; |
24719 | 659 |
try { |
660 |
appliedInvocation = Bootstrap.getLinkerServices().getGuardedInvocation(appliedRequest); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
661 |
} catch (final RuntimeException | Error e) { |
24719 | 662 |
throw e; |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
663 |
} catch (final Exception e) { |
24719 | 664 |
throw new RuntimeException(e); |
665 |
} |
|
666 |
assert appliedRequest != null; // Bootstrap.isCallable() returned true for args[1], so it must produce a linkage. |
|
667 |
||
668 |
final Class<?> applyFnType = descType.parameterType(0); |
|
669 |
MethodHandle inv = appliedInvocation.getInvocation(); //method handle from apply invocation. the applied function invocation |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
670 |
|
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
671 |
if (isApply && !isFailedApplyToCall) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
672 |
if (passesArgs) { |
24719 | 673 |
// Make sure that the passed argArray is converted to Object[] the same way NativeFunction.apply() would do it. |
674 |
inv = MH.filterArguments(inv, 2, NativeFunction.TO_APPLY_ARGS); |
|
675 |
} else { |
|
676 |
// If the original call site doesn't pass argArray, pass in an empty array |
|
677 |
inv = MH.insertArguments(inv, 2, (Object)ScriptRuntime.EMPTY_ARRAY); |
|
678 |
} |
|
679 |
} |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
680 |
|
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
681 |
if (isApplyToCall) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
682 |
if (isFailedApplyToCall) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
683 |
//take the real arguments that were passed to a call and force them into the apply instead |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
684 |
Context.getContextTrusted().getLogger(ApplySpecialization.class).info("Collection arguments to revert call to apply in " + appliedFn); |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
685 |
inv = MH.asCollector(inv, Object[].class, realArgCount); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
686 |
} else { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
687 |
appliedInvocation = appliedInvocation.addSwitchPoint(applyToCallSwitchPoint); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
688 |
} |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
689 |
} |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
690 |
|
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
691 |
if (!passesThis) { |
24719 | 692 |
// If the original call site doesn't pass in a thisArg, pass in Global/undefined as needed |
693 |
inv = bindImplicitThis(appliedFn, inv); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
694 |
} else if (appliedFnNeedsWrappedThis) { |
24719 | 695 |
// target function needs a wrapped this, so make sure we filter for that |
696 |
inv = MH.filterArguments(inv, 1, WRAP_THIS); |
|
697 |
} |
|
698 |
inv = MH.dropArguments(inv, 0, applyFnType); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
699 |
|
24719 | 700 |
MethodHandle guard = appliedInvocation.getGuard(); |
701 |
// If the guard checks the value of "this" but we aren't passing thisArg, insert the default one |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
702 |
if (!passesThis && guard.type().parameterCount() > 1) { |
24719 | 703 |
guard = bindImplicitThis(appliedFn, guard); |
704 |
} |
|
705 |
final MethodType guardType = guard.type(); |
|
706 |
||
707 |
// Original function guard will expect the invoked function in parameter position 0, but we're passing it in |
|
708 |
// position 1. |
|
709 |
guard = MH.dropArguments(guard, 0, descType.parameterType(0)); |
|
710 |
// Take the "isApplyFunction" guard, and bind it to this function. |
|
711 |
MethodHandle applyFnGuard = MH.insertArguments(IS_APPLY_FUNCTION, 2, this); |
|
712 |
// Adapt the guard to receive all the arguments that the original guard does. |
|
713 |
applyFnGuard = MH.dropArguments(applyFnGuard, 2, guardType.parameterArray()); |
|
714 |
// Fold the original function guard into our apply guard. |
|
715 |
guard = MH.foldArguments(applyFnGuard, guard); |
|
716 |
||
717 |
return appliedInvocation.replaceMethods(inv, guard); |
|
718 |
} |
|
719 |
||
720 |
private static MethodHandle bindImplicitThis(final Object fn, final MethodHandle mh) { |
|
24727 | 721 |
final MethodHandle bound; |
722 |
if(fn instanceof ScriptFunction && ((ScriptFunction)fn).needsWrappedThis()) { |
|
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
|
723 |
bound = MH.filterArguments(mh, 1, SCRIPTFUNCTION_GLOBALFILTER); |
24727 | 724 |
} else { |
725 |
bound = mh; |
|
726 |
} |
|
727 |
return MH.insertArguments(bound, 1, ScriptRuntime.UNDEFINED); |
|
24719 | 728 |
} |
16147 | 729 |
|
730 |
/** |
|
731 |
* Used for noSuchMethod/noSuchProperty and JSAdapter hooks. |
|
732 |
* |
|
733 |
* These don't want a callee parameter, so bind that. Name binding is optional. |
|
734 |
*/ |
|
735 |
MethodHandle getCallMethodHandle(final MethodType type, final String bindName) { |
|
24729
2b13051f2122
8037534: Use scope types to determine optimistic types
attila
parents:
24727
diff
changeset
|
736 |
return pairArguments(bindToNameIfNeeded(bindToCalleeIfNeeded(data.getGenericInvoker(scope)), bindName), type); |
16225
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
737 |
} |
16147 | 738 |
|
16225
81d58c2b9fcf
8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents:
16216
diff
changeset
|
739 |
private static MethodHandle bindToNameIfNeeded(final MethodHandle methodHandle, final String bindName) { |
18868
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
740 |
if (bindName == null) { |
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
741 |
return methodHandle; |
19472
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
742 |
} |
18868
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
743 |
|
19472
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
744 |
// if it is vararg method, we need to extend argument array with |
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
745 |
// a new zeroth element that is set to bindName value. |
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
746 |
final MethodType methodType = methodHandle.type(); |
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
747 |
final int parameterCount = methodType.parameterCount(); |
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
748 |
final boolean isVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray(); |
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
749 |
|
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
750 |
if (isVarArg) { |
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
751 |
return MH.filterArguments(methodHandle, 1, MH.insertArguments(ADD_ZEROTH_ELEMENT, 1, bindName)); |
18868
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
752 |
} |
19472
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19456
diff
changeset
|
753 |
return MH.insertArguments(methodHandle, 1, bindName); |
16147 | 754 |
} |
755 |
||
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:
16277
diff
changeset
|
756 |
/** |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
757 |
* Get the guard that checks if a {@link ScriptFunction} is equal to |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
758 |
* a known ScriptFunction, using reference comparison |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
759 |
* |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
760 |
* @param function The ScriptFunction to check against. This will be bound to the guard method handle |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
761 |
* |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
762 |
* @return method handle for guard |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
763 |
*/ |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
764 |
private static MethodHandle getFunctionGuard(final ScriptFunction function, final int flags) { |
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:
16277
diff
changeset
|
765 |
assert function.data != null; |
24719 | 766 |
// Built-in functions have a 1-1 correspondence to their ScriptFunctionData, so we can use a cheaper identity |
767 |
// comparison for them. |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
768 |
if (function.data.isBuiltin()) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
769 |
return Guards.getIdentityGuard(function); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
770 |
} |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24731
diff
changeset
|
771 |
return MH.insertArguments(IS_FUNCTION_MH, 1, function.data); |
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:
16277
diff
changeset
|
772 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
773 |
|
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
774 |
/** |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
775 |
* Get a guard that checks if a {@link ScriptFunction} is equal to |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
776 |
* a known ScriptFunction using reference comparison, and whether the type of |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
777 |
* the second argument (this-object) is not a JavaScript primitive 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:
16277
diff
changeset
|
778 |
* |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
779 |
* @param function The ScriptFunction to check against. This will be bound to the guard method handle |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
780 |
* |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
781 |
* @return method handle for guard |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
782 |
*/ |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
783 |
private static MethodHandle getNonStrictFunctionGuard(final ScriptFunction function) { |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
784 |
assert function.data != 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:
16277
diff
changeset
|
785 |
return MH.insertArguments(IS_NONSTRICT_FUNCTION, 2, function.data); |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
786 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
787 |
|
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
788 |
@SuppressWarnings("unused") |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
789 |
private static boolean isFunctionMH(final Object self, final ScriptFunctionData data) { |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
790 |
return self instanceof ScriptFunction && ((ScriptFunction)self).data == data; |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
791 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
792 |
|
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
793 |
@SuppressWarnings("unused") |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
794 |
private static boolean isNonStrictFunction(final Object self, final Object arg, final ScriptFunctionData data) { |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
795 |
return self instanceof ScriptFunction && ((ScriptFunction)self).data == data && arg instanceof ScriptObject; |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
796 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16277
diff
changeset
|
797 |
|
18868
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
798 |
@SuppressWarnings("unused") |
24719 | 799 |
private static boolean isApplyFunction(final boolean appliedFnCondition, final Object self, final Object expectedSelf) { |
800 |
// NOTE: we're using self == expectedSelf as we're only using this with built-in functions apply() and call() |
|
801 |
return appliedFnCondition && self == expectedSelf; |
|
802 |
} |
|
803 |
||
804 |
@SuppressWarnings("unused") |
|
18868
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
805 |
private static Object[] addZerothElement(final Object[] args, final Object value) { |
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
806 |
// extends input array with by adding new zeroth element |
24721
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
807 |
final Object[] src = args == null? ScriptRuntime.EMPTY_ARRAY : args; |
18868
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
808 |
final Object[] result = new Object[src.length + 1]; |
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
809 |
System.arraycopy(src, 0, result, 1, src.length); |
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
810 |
result[0] = value; |
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
811 |
return result; |
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
812 |
} |
f5359cad148c
8012191: noSuchProperty can't cope with vararg functions
sundar
parents:
18614
diff
changeset
|
813 |
|
20946 | 814 |
@SuppressWarnings("unused") |
815 |
private static Object invokeSync(final ScriptFunction func, final Object sync, final Object self, final Object... args) |
|
816 |
throws Throwable { |
|
817 |
final Object syncObj = sync == UNDEFINED ? self : sync; |
|
818 |
synchronized (syncObj) { |
|
819 |
return func.invoke(self, args); |
|
820 |
} |
|
821 |
} |
|
822 |
||
24719 | 823 |
private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) { |
824 |
return MH.findStatic(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types)); |
|
825 |
} |
|
826 |
||
827 |
private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) { |
|
828 |
return MH.findVirtual(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types)); |
|
16147 | 829 |
} |
830 |
} |
|
831 |