]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGOperations.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGOperations.cpp
CommitLineData
14957cd0 1/*
ed1e77d3 2 * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
14957cd0
A
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "DFGOperations.h"
28
93a37866 29#include "ButterflyInlines.h"
ed1e77d3 30#include "ClonedArguments.h"
14957cd0 31#include "CodeBlock.h"
81345200 32#include "CommonSlowPaths.h"
93a37866 33#include "CopiedSpaceInlines.h"
81345200
A
34#include "DFGDriver.h"
35#include "DFGJITCode.h"
6fe7ccc8 36#include "DFGOSRExit.h"
93a37866 37#include "DFGThunks.h"
81345200
A
38#include "DFGToFTLDeferredCompilationCallback.h"
39#include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
40#include "DFGWorklist.h"
ed1e77d3 41#include "DirectArguments.h"
81345200
A
42#include "FTLForOSREntryJITCode.h"
43#include "FTLOSREntry.h"
6fe7ccc8
A
44#include "HostCallReturnValue.h"
45#include "GetterSetter.h"
14957cd0 46#include "Interpreter.h"
93a37866 47#include "JIT.h"
6fe7ccc8 48#include "JITExceptions.h"
ed1e77d3
A
49#include "JSCInlines.h"
50#include "JSLexicalEnvironment.h"
93a37866 51#include "JSNameScope.h"
93a37866 52#include "ObjectConstructor.h"
81345200 53#include "Repatch.h"
ed1e77d3 54#include "ScopedArguments.h"
93a37866 55#include "StringConstructor.h"
ed1e77d3
A
56#include "Symbol.h"
57#include "TypeProfilerLog.h"
81345200 58#include "TypedArrayInlines.h"
ed1e77d3 59#include "VM.h"
93a37866
A
60#include <wtf/InlineASM.h>
61
62#if ENABLE(JIT)
6fe7ccc8
A
63#if ENABLE(DFG_JIT)
64
14957cd0
A
65namespace JSC { namespace DFG {
66
81345200 67template<bool strict, bool direct>
6fe7ccc8
A
68static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
69{
93a37866
A
70 VM& vm = exec->vm();
71 NativeCallFrameTracer tracer(&vm, exec);
ed1e77d3 72 ASSERT(isIndex(index));
81345200
A
73 if (direct) {
74 RELEASE_ASSERT(baseValue.isObject());
75 asObject(baseValue)->putDirectIndex(exec, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
76 return;
77 }
93a37866
A
78 if (baseValue.isObject()) {
79 JSObject* object = asObject(baseValue);
80 if (object->canSetIndexQuickly(index)) {
81 object->setIndexQuickly(vm, index, value);
6fe7ccc8
A
82 return;
83 }
84
81345200 85 object->methodTable(vm)->putByIndex(object, exec, index, value, strict);
6fe7ccc8
A
86 return;
87 }
88
89 baseValue.putByIndex(exec, index, value, strict);
90}
91
81345200
A
92template<bool strict, bool direct>
93ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
14957cd0 94{
93a37866
A
95 VM* vm = &exec->vm();
96 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
97
98 JSValue baseValue = JSValue::decode(encodedBase);
99 JSValue property = JSValue::decode(encodedProperty);
100 JSValue value = JSValue::decode(encodedValue);
101
102 if (LIKELY(property.isUInt32())) {
ed1e77d3
A
103 // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
104 ASSERT(isIndex(property.asUInt32()));
81345200 105 putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value);
6fe7ccc8
A
106 return;
107 }
108
109 if (property.isDouble()) {
110 double propertyAsDouble = property.asDouble();
111 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
ed1e77d3 112 if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) {
81345200 113 putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value);
6fe7ccc8
A
114 return;
115 }
116 }
117
ed1e77d3
A
118 // Don't put to an object if toString throws an exception.
119 auto propertyName = property.toPropertyKey(exec);
120 if (vm->exception())
93a37866 121 return;
6fe7ccc8 122
ed1e77d3
A
123 PutPropertySlot slot(baseValue, strict);
124 if (direct) {
125 RELEASE_ASSERT(baseValue.isObject());
126 if (Optional<uint32_t> index = parseIndex(propertyName))
127 asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
128 else
129 asObject(baseValue)->putDirect(*vm, propertyName, value, slot);
130 } else
131 baseValue.put(exec, propertyName, value, slot);
81345200
A
132}
133
134template<typename ViewClass>
135char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
136{
137 VM& vm = exec->vm();
138 NativeCallFrameTracer tracer(&vm, exec);
139 if (size < 0) {
ed1e77d3 140 vm.throwException(exec, createRangeError(exec, ASCIILiteral("Requested length is negative")));
81345200
A
141 return 0;
142 }
143 return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
144}
145
146template<typename ViewClass>
147char* newTypedArrayWithOneArgument(
148 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
149{
150 VM& vm = exec->vm();
151 NativeCallFrameTracer tracer(&vm, exec);
152
153 JSValue value = JSValue::decode(encodedValue);
154
155 if (JSArrayBuffer* jsBuffer = jsDynamicCast<JSArrayBuffer*>(value)) {
156 RefPtr<ArrayBuffer> buffer = jsBuffer->impl();
157
158 if (buffer->byteLength() % ViewClass::elementSize) {
ed1e77d3 159 vm.throwException(exec, createRangeError(exec, ASCIILiteral("ArrayBuffer length minus the byteOffset is not a multiple of the element size")));
81345200
A
160 return 0;
161 }
162 return bitwise_cast<char*>(
163 ViewClass::create(
164 exec, structure, buffer, 0, buffer->byteLength() / ViewClass::elementSize));
165 }
166
167 if (JSObject* object = jsDynamicCast<JSObject*>(value)) {
168 unsigned length = object->get(exec, vm.propertyNames->length).toUInt32(exec);
169 if (exec->hadException())
170 return 0;
171
172 ViewClass* result = ViewClass::createUninitialized(exec, structure, length);
173 if (!result)
174 return 0;
175
176 if (!result->set(exec, object, 0, length))
177 return 0;
178
179 return bitwise_cast<char*>(result);
180 }
181
182 int length;
183 if (value.isInt32())
184 length = value.asInt32();
185 else if (!value.isNumber()) {
ed1e77d3 186 vm.throwException(exec, createTypeError(exec, ASCIILiteral("Invalid array length argument")));
81345200
A
187 return 0;
188 } else {
189 length = static_cast<int>(value.asNumber());
190 if (length != value.asNumber()) {
ed1e77d3 191 vm.throwException(exec, createTypeError(exec, ASCIILiteral("Invalid array length argument (fractional lengths not allowed)")));
81345200
A
192 return 0;
193 }
194 }
195
196 if (length < 0) {
ed1e77d3 197 vm.throwException(exec, createRangeError(exec, ASCIILiteral("Requested length is negative")));
81345200 198 return 0;
6fe7ccc8 199 }
81345200
A
200
201 return bitwise_cast<char*>(ViewClass::create(exec, structure, length));
6fe7ccc8
A
202}
203
204extern "C" {
205
81345200 206EncodedJSValue JIT_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
6fe7ccc8 207{
93a37866
A
208 VM* vm = &exec->vm();
209 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 210
81345200 211 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, NotStrictMode));
14957cd0
A
212}
213
81345200 214EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState* exec, EncodedJSValue encodedOp)
14957cd0 215{
93a37866
A
216 VM* vm = &exec->vm();
217 NativeCallFrameTracer tracer(vm, exec);
218
81345200
A
219 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, StrictMode));
220}
221
222JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
223{
224 VM& vm = exec->vm();
225 NativeCallFrameTracer tracer(&vm, exec);
226
6fe7ccc8
A
227#if !ASSERT_DISABLED
228 ConstructData constructData;
81345200 229 ASSERT(jsCast<JSFunction*>(constructor)->methodTable(vm)->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS);
6fe7ccc8
A
230#endif
231
ed1e77d3 232 return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->rareData(exec, inlineCapacity)->allocationProfile()->structure());
6fe7ccc8
A
233}
234
81345200 235EncodedJSValue JIT_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
6fe7ccc8 236{
93a37866
A
237 VM* vm = &exec->vm();
238 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 239
14957cd0
A
240 JSValue op1 = JSValue::decode(encodedOp1);
241 JSValue op2 = JSValue::decode(encodedOp2);
6fe7ccc8
A
242
243 return JSValue::encode(jsAdd(exec, op1, op2));
244}
14957cd0 245
81345200 246EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
6fe7ccc8 247{
93a37866
A
248 VM* vm = &exec->vm();
249 NativeCallFrameTracer tracer(vm, exec);
14957cd0 250
6fe7ccc8
A
251 JSValue op1 = JSValue::decode(encodedOp1);
252 JSValue op2 = JSValue::decode(encodedOp2);
253
254 ASSERT(!op1.isNumber() || !op2.isNumber());
255
256 if (op1.isString() && !op2.isObject())
257 return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
14957cd0
A
258
259 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
260}
261
81345200 262static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
6fe7ccc8 263{
93a37866
A
264 VM& vm = exec->vm();
265 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8 266
93a37866
A
267 if (base->isObject()) {
268 JSObject* object = asObject(base);
269 if (object->canGetIndexQuickly(index))
270 return JSValue::encode(object->getIndexQuickly(index));
271 }
6fe7ccc8 272
6fe7ccc8
A
273 if (isJSString(base) && asString(base)->canGetIndex(index))
274 return JSValue::encode(asString(base)->getIndex(exec, index));
275
276 return JSValue::encode(JSValue(base).get(exec, index));
277}
278
81345200 279EncodedJSValue JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
14957cd0 280{
81345200
A
281 VM& vm = exec->vm();
282 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8 283
14957cd0
A
284 JSValue baseValue = JSValue::decode(encodedBase);
285 JSValue property = JSValue::decode(encodedProperty);
286
287 if (LIKELY(baseValue.isCell())) {
288 JSCell* base = baseValue.asCell();
289
290 if (property.isUInt32()) {
6fe7ccc8
A
291 return getByVal(exec, base, property.asUInt32());
292 } else if (property.isDouble()) {
293 double propertyAsDouble = property.asDouble();
294 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
ed1e77d3 295 if (propertyAsUInt32 == propertyAsDouble && isIndex(propertyAsUInt32))
6fe7ccc8
A
296 return getByVal(exec, base, propertyAsUInt32);
297 } else if (property.isString()) {
81345200
A
298 Structure& structure = *base->structure(vm);
299 if (JSCell::canUseFastGetOwnProperty(structure)) {
ed1e77d3
A
300 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
301 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
302 return JSValue::encode(result);
303 }
81345200 304 }
6fe7ccc8
A
305 }
306 }
14957cd0 307
ed1e77d3
A
308 baseValue.requireObjectCoercible(exec);
309 if (exec->hadException())
310 return JSValue::encode(jsUndefined());
311 auto propertyName = property.toPropertyKey(exec);
312 if (exec->hadException())
313 return JSValue::encode(jsUndefined());
314 return JSValue::encode(baseValue.get(exec, propertyName));
6fe7ccc8 315}
14957cd0 316
81345200 317EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
6fe7ccc8 318{
81345200
A
319 VM& vm = exec->vm();
320 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8
A
321
322 JSValue property = JSValue::decode(encodedProperty);
14957cd0 323
6fe7ccc8
A
324 if (property.isUInt32())
325 return getByVal(exec, base, property.asUInt32());
326 if (property.isDouble()) {
327 double propertyAsDouble = property.asDouble();
328 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
329 if (propertyAsUInt32 == propertyAsDouble)
330 return getByVal(exec, base, propertyAsUInt32);
331 } else if (property.isString()) {
81345200
A
332 Structure& structure = *base->structure(vm);
333 if (JSCell::canUseFastGetOwnProperty(structure)) {
ed1e77d3
A
334 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
335 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
336 return JSValue::encode(result);
337 }
81345200 338 }
6fe7ccc8 339 }
14957cd0 340
ed1e77d3
A
341 auto propertyName = property.toPropertyKey(exec);
342 if (exec->hadException())
343 return JSValue::encode(jsUndefined());
344 return JSValue::encode(JSValue(base).get(exec, propertyName));
6fe7ccc8 345}
14957cd0 346
81345200 347ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
93a37866
A
348{
349 VM* vm = &exec->vm();
350 NativeCallFrameTracer tracer(vm, exec);
351
352 if (index < 0) {
353 // Go the slowest way possible becase negative indices don't use indexed storage.
354 return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
355 }
356
357 // Use this since we know that the value is out of bounds.
358 return JSValue::encode(JSValue(base).get(exec, index));
359}
360
81345200 361EncodedJSValue JIT_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
14957cd0 362{
81345200 363 return getByValCellInt(exec, base, index);
6fe7ccc8 364}
14957cd0 365
81345200 366EncodedJSValue JIT_OPERATION operationGetByValStringInt(ExecState* exec, JSString* base, int32_t index)
6fe7ccc8 367{
81345200 368 return getByValCellInt(exec, base, index);
6fe7ccc8 369}
14957cd0 370
81345200 371void JIT_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
6fe7ccc8 372{
93a37866
A
373 VM* vm = &exec->vm();
374 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 375
81345200 376 operationPutByValInternal<true, false>(exec, encodedBase, encodedProperty, encodedValue);
6fe7ccc8 377}
14957cd0 378
81345200 379void JIT_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
6fe7ccc8 380{
93a37866
A
381 VM* vm = &exec->vm();
382 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 383
81345200 384 operationPutByValInternal<false, false>(exec, encodedBase, encodedProperty, encodedValue);
6fe7ccc8
A
385}
386
81345200 387void JIT_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
6fe7ccc8 388{
93a37866
A
389 VM* vm = &exec->vm();
390 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 391
81345200 392 operationPutByValInternal<true, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
6fe7ccc8
A
393}
394
81345200 395void JIT_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
6fe7ccc8 396{
93a37866
A
397 VM* vm = &exec->vm();
398 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 399
81345200 400 operationPutByValInternal<false, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
6fe7ccc8
A
401}
402
81345200 403void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
6fe7ccc8 404{
81345200
A
405 VM& vm = exec->vm();
406 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8
A
407
408 if (index >= 0) {
93a37866 409 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
6fe7ccc8
A
410 return;
411 }
412
81345200 413 PutPropertySlot slot(array, true);
6fe7ccc8
A
414 array->methodTable()->put(
415 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
416}
14957cd0 417
81345200 418void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
6fe7ccc8 419{
93a37866
A
420 VM* vm = &exec->vm();
421 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
422
423 if (index >= 0) {
93a37866 424 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
14957cd0
A
425 return;
426 }
6fe7ccc8 427
81345200 428 PutPropertySlot slot(array, false);
6fe7ccc8
A
429 array->methodTable()->put(
430 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
431}
14957cd0 432
81345200 433void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
93a37866
A
434{
435 VM* vm = &exec->vm();
436 NativeCallFrameTracer tracer(vm, exec);
437
438 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
439
440 if (index >= 0) {
441 array->putByIndexInline(exec, index, jsValue, true);
442 return;
443 }
444
81345200 445 PutPropertySlot slot(array, true);
93a37866
A
446 array->methodTable()->put(
447 array, exec, Identifier::from(exec, index), jsValue, slot);
448}
449
81345200 450void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
93a37866
A
451{
452 VM* vm = &exec->vm();
453 NativeCallFrameTracer tracer(vm, exec);
454
455 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
456
457 if (index >= 0) {
458 array->putByIndexInline(exec, index, jsValue, false);
459 return;
460 }
461
81345200 462 PutPropertySlot slot(array, false);
93a37866
A
463 array->methodTable()->put(
464 array, exec, Identifier::from(exec, index), jsValue, slot);
465}
466
81345200 467void JIT_OPERATION operationPutByValDirectStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
14957cd0 468{
93a37866
A
469 VM* vm = &exec->vm();
470 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 471
81345200 472 operationPutByValInternal<true, true>(exec, encodedBase, encodedProperty, encodedValue);
6fe7ccc8
A
473}
474
81345200 475void JIT_OPERATION operationPutByValDirectNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
6fe7ccc8 476{
93a37866
A
477 VM* vm = &exec->vm();
478 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 479
81345200 480 operationPutByValInternal<false, true>(exec, encodedBase, encodedProperty, encodedValue);
6fe7ccc8
A
481}
482
81345200 483void JIT_OPERATION operationPutByValDirectCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
6fe7ccc8 484{
93a37866
A
485 VM* vm = &exec->vm();
486 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 487
81345200 488 operationPutByValInternal<true, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
6fe7ccc8
A
489}
490
81345200 491void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
6fe7ccc8 492{
93a37866
A
493 VM* vm = &exec->vm();
494 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 495
81345200 496 operationPutByValInternal<false, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
6fe7ccc8
A
497}
498
81345200 499void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
6fe7ccc8 500{
93a37866
A
501 VM* vm = &exec->vm();
502 NativeCallFrameTracer tracer(vm, exec);
81345200
A
503 if (index >= 0) {
504 array->putDirectIndex(exec, index, JSValue::decode(encodedValue), 0, PutDirectIndexShouldThrow);
93a37866 505 return;
81345200 506 }
6fe7ccc8 507
81345200
A
508 PutPropertySlot slot(array, true);
509 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
6fe7ccc8
A
510}
511
81345200 512void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
6fe7ccc8 513{
93a37866
A
514 VM* vm = &exec->vm();
515 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 516
81345200
A
517 if (index >= 0) {
518 array->putDirectIndex(exec, index, JSValue::decode(encodedValue));
93a37866 519 return;
81345200 520 }
6fe7ccc8 521
81345200
A
522 PutPropertySlot slot(array, false);
523 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
14957cd0
A
524}
525
81345200 526EncodedJSValue JIT_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
14957cd0 527{
93a37866
A
528 VM* vm = &exec->vm();
529 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 530
81345200
A
531 array->push(exec, JSValue::decode(encodedValue));
532 return JSValue::encode(jsNumber(array->length()));
14957cd0
A
533}
534
81345200 535EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
14957cd0 536{
93a37866
A
537 VM* vm = &exec->vm();
538 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 539
81345200
A
540 array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
541 return JSValue::encode(jsNumber(array->length()));
14957cd0
A
542}
543
81345200 544EncodedJSValue JIT_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
14957cd0 545{
93a37866
A
546 VM* vm = &exec->vm();
547 NativeCallFrameTracer tracer(vm, exec);
548
81345200 549 return JSValue::encode(array->pop(exec));
14957cd0 550}
81345200
A
551
552EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
14957cd0 553{
93a37866
A
554 VM* vm = &exec->vm();
555 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 556
81345200 557 array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
6fe7ccc8 558
81345200 559 return JSValue::encode(array->pop(exec));
14957cd0 560}
81345200
A
561
562EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
14957cd0 563{
81345200
A
564 VM& vm = exec->vm();
565 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8 566
81345200
A
567 if (!base->inherits(RegExpObject::info()))
568 return throwVMTypeError(exec);
14957cd0 569
81345200
A
570 ASSERT(argument->isString() || argument->isObject());
571 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
572 return JSValue::encode(asRegExpObject(base)->exec(exec, input));
14957cd0 573}
81345200
A
574
575size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
14957cd0 576{
81345200
A
577 VM& vm = exec->vm();
578 NativeCallFrameTracer tracer(&vm, exec);
14957cd0 579
81345200
A
580 if (!base->inherits(RegExpObject::info())) {
581 throwTypeError(exec);
582 return false;
583 }
6fe7ccc8 584
81345200
A
585 ASSERT(argument->isString() || argument->isObject());
586 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
587 return asRegExpObject(base)->test(exec, input);
93a37866
A
588}
589
81345200 590size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
6fe7ccc8 591{
93a37866
A
592 VM* vm = &exec->vm();
593 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
594
595 JSValue op1 = JSValue::decode(encodedOp1);
596 JSValue op2 = JSValue::decode(encodedOp2);
597
598 ASSERT(op1.isCell());
599 ASSERT(op2.isCell());
600
601 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
602}
603
81345200 604size_t JIT_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
6fe7ccc8 605{
93a37866
A
606 VM* vm = &exec->vm();
607 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
608
609 JSValue src1 = JSValue::decode(encodedOp1);
610 JSValue src2 = JSValue::decode(encodedOp2);
611
612 return JSValue::strictEqual(exec, src1, src2);
613}
614
81345200 615EncodedJSValue JIT_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
6fe7ccc8 616{
93a37866 617 VM* vm = &exec->vm();
81345200 618 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 619
81345200 620 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
6fe7ccc8
A
621}
622
81345200 623char* JIT_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
6fe7ccc8 624{
93a37866
A
625 VM* vm = &exec->vm();
626 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 627
81345200 628 return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
6fe7ccc8
A
629}
630
81345200 631char* JIT_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
6fe7ccc8 632{
81345200
A
633 VM* vm = &exec->vm();
634 NativeCallFrameTracer tracer(vm, exec);
635
636 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
6fe7ccc8
A
637}
638
81345200 639char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size)
6fe7ccc8 640{
93a37866
A
641 VM* vm = &exec->vm();
642 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 643
81345200
A
644 if (UNLIKELY(size < 0))
645 return bitwise_cast<char*>(exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
646
647 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure, size));
6fe7ccc8
A
648}
649
81345200 650char* JIT_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
93a37866 651{
81345200
A
652 VM& vm = exec->vm();
653 NativeCallFrameTracer tracer(&vm, exec);
654 return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
6fe7ccc8
A
655}
656
81345200
A
657char* JIT_OPERATION operationNewInt8ArrayWithSize(
658 ExecState* exec, Structure* structure, int32_t length)
6fe7ccc8 659{
81345200 660 return newTypedArrayWithSize<JSInt8Array>(exec, structure, length);
6fe7ccc8
A
661}
662
81345200
A
663char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
664 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
6fe7ccc8 665{
81345200 666 return newTypedArrayWithOneArgument<JSInt8Array>(exec, structure, encodedValue);
93a37866 667}
6fe7ccc8 668
81345200
A
669char* JIT_OPERATION operationNewInt16ArrayWithSize(
670 ExecState* exec, Structure* structure, int32_t length)
671{
672 return newTypedArrayWithSize<JSInt16Array>(exec, structure, length);
93a37866 673}
6fe7ccc8 674
81345200
A
675char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
676 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
93a37866 677{
81345200 678 return newTypedArrayWithOneArgument<JSInt16Array>(exec, structure, encodedValue);
6fe7ccc8
A
679}
680
81345200
A
681char* JIT_OPERATION operationNewInt32ArrayWithSize(
682 ExecState* exec, Structure* structure, int32_t length)
6fe7ccc8 683{
81345200 684 return newTypedArrayWithSize<JSInt32Array>(exec, structure, length);
6fe7ccc8
A
685}
686
81345200
A
687char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
688 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
6fe7ccc8 689{
81345200 690 return newTypedArrayWithOneArgument<JSInt32Array>(exec, structure, encodedValue);
6fe7ccc8
A
691}
692
81345200
A
693char* JIT_OPERATION operationNewUint8ArrayWithSize(
694 ExecState* exec, Structure* structure, int32_t length)
6fe7ccc8 695{
81345200 696 return newTypedArrayWithSize<JSUint8Array>(exec, structure, length);
93a37866 697}
6fe7ccc8 698
81345200
A
699char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
700 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
93a37866 701{
81345200 702 return newTypedArrayWithOneArgument<JSUint8Array>(exec, structure, encodedValue);
93a37866 703}
6fe7ccc8 704
81345200
A
705char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(
706 ExecState* exec, Structure* structure, int32_t length)
93a37866 707{
81345200 708 return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length);
6fe7ccc8
A
709}
710
81345200
A
711char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
712 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
6fe7ccc8 713{
81345200 714 return newTypedArrayWithOneArgument<JSUint8ClampedArray>(exec, structure, encodedValue);
6fe7ccc8
A
715}
716
81345200
A
717char* JIT_OPERATION operationNewUint16ArrayWithSize(
718 ExecState* exec, Structure* structure, int32_t length)
6fe7ccc8 719{
81345200 720 return newTypedArrayWithSize<JSUint16Array>(exec, structure, length);
93a37866 721}
6fe7ccc8 722
81345200
A
723char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
724 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
93a37866 725{
81345200 726 return newTypedArrayWithOneArgument<JSUint16Array>(exec, structure, encodedValue);
6fe7ccc8
A
727}
728
81345200
A
729char* JIT_OPERATION operationNewUint32ArrayWithSize(
730 ExecState* exec, Structure* structure, int32_t length)
6fe7ccc8 731{
81345200
A
732 return newTypedArrayWithSize<JSUint32Array>(exec, structure, length);
733}
93a37866 734
81345200
A
735char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
736 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
737{
738 return newTypedArrayWithOneArgument<JSUint32Array>(exec, structure, encodedValue);
6fe7ccc8
A
739}
740
81345200
A
741char* JIT_OPERATION operationNewFloat32ArrayWithSize(
742 ExecState* exec, Structure* structure, int32_t length)
6fe7ccc8 743{
81345200 744 return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length);
6fe7ccc8
A
745}
746
81345200
A
747char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
748 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
6fe7ccc8 749{
81345200 750 return newTypedArrayWithOneArgument<JSFloat32Array>(exec, structure, encodedValue);
6fe7ccc8
A
751}
752
81345200
A
753char* JIT_OPERATION operationNewFloat64ArrayWithSize(
754 ExecState* exec, Structure* structure, int32_t length)
6fe7ccc8 755{
81345200 756 return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length);
6fe7ccc8
A
757}
758
81345200
A
759char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
760 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
93a37866 761{
81345200 762 return newTypedArrayWithOneArgument<JSFloat64Array>(exec, structure, encodedValue);
93a37866
A
763}
764
ed1e77d3 765JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table)
93a37866
A
766{
767 VM& vm = exec->vm();
768 NativeCallFrameTracer tracer(&vm, exec);
ed1e77d3
A
769 return JSLexicalEnvironment::create(vm, structure, scope, table);
770}
771
772JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, int32_t length, int32_t minCapacity)
773{
774 VM& vm = exec->vm();
775 NativeCallFrameTracer target(&vm, exec);
776 DirectArguments* result = DirectArguments::create(
777 vm, structure, length, std::max(length, minCapacity));
778 // The caller will store to this object without barriers. Most likely, at this point, this is
779 // still a young object and so no barriers are needed. But it's good to be careful anyway,
780 // since the GC should be allowed to do crazy (like pretenuring, for example).
781 vm.heap.writeBarrier(result);
93a37866
A
782 return result;
783}
784
ed1e77d3 785JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
93a37866 786{
ed1e77d3
A
787 VM& vm = exec->vm();
788 NativeCallFrameTracer target(&vm, exec);
789
790 // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
791 // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
792 ScopedArgumentsTable* table = scope->symbolTable()->arguments();
793
794 return ScopedArguments::createByCopyingFrom(
795 vm, structure, argumentStart, length, callee, table, scope);
93a37866
A
796}
797
ed1e77d3 798JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee)
93a37866 799{
ed1e77d3
A
800 VM& vm = exec->vm();
801 NativeCallFrameTracer target(&vm, exec);
802 return ClonedArguments::createByCopyingFrom(
803 exec, structure, argumentStart, length, callee);
93a37866
A
804}
805
ed1e77d3 806JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
6fe7ccc8 807{
93a37866 808 VM& vm = exec->vm();
ed1e77d3
A
809 NativeCallFrameTracer target(&vm, exec);
810
811 DeferGCForAWhile deferGC(vm.heap);
812
813 CodeBlock* codeBlock;
814 if (inlineCallFrame)
815 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
816 else
817 codeBlock = exec->codeBlock();
818
819 unsigned length = argumentCount - 1;
820 unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
821 DirectArguments* result = DirectArguments::create(
822 vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
823
824 result->callee().set(vm, result, callee);
825
826 Register* arguments =
827 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
828 CallFrame::argumentOffset(0);
829 for (unsigned i = length; i--;)
830 result->setIndexQuickly(vm, i, arguments[i].jsValue());
831
832 return result;
833}
93a37866 834
ed1e77d3
A
835JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
836{
837 VM& vm = exec->vm();
838 NativeCallFrameTracer target(&vm, exec);
839
840 DeferGCForAWhile deferGC(vm.heap);
93a37866 841
ed1e77d3
A
842 CodeBlock* codeBlock;
843 if (inlineCallFrame)
844 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
845 else
846 codeBlock = exec->codeBlock();
93a37866 847
ed1e77d3
A
848 unsigned length = argumentCount - 1;
849 ClonedArguments* result = ClonedArguments::createEmpty(
850 vm, codeBlock->globalObject()->outOfBandArgumentsStructure(), callee);
851
852 Register* arguments =
853 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
854 CallFrame::argumentOffset(0);
855 for (unsigned i = length; i--;)
856 result->putDirectIndex(exec, i, arguments[i].jsValue());
857
858 result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
859
860 return result;
93a37866
A
861}
862
ed1e77d3 863size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
93a37866
A
864{
865 VM& vm = exec->vm();
866 NativeCallFrameTracer tracer(&vm, exec);
867
ed1e77d3 868 ASSERT(jsDynamicCast<JSObject*>(object));
93a37866 869
ed1e77d3
A
870 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
871 return false;
872 if (object->type() == JSFunctionType)
873 return false;
874 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
875 CallData callData;
876 if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
877 return false;
93a37866
A
878 }
879
ed1e77d3 880 return true;
93a37866
A
881}
882
ed1e77d3 883size_t JIT_OPERATION operationObjectIsFunction(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
6fe7ccc8 884{
93a37866
A
885 VM& vm = exec->vm();
886 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8 887
ed1e77d3
A
888 ASSERT(jsDynamicCast<JSObject*>(object));
889
890 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
891 return false;
892 if (object->type() == JSFunctionType)
893 return true;
894 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
895 CallData callData;
896 if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
897 return true;
898 }
899
900 return false;
6fe7ccc8
A
901}
902
ed1e77d3 903JSCell* JIT_OPERATION operationTypeOfObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
6fe7ccc8 904{
ed1e77d3
A
905 VM& vm = exec->vm();
906 NativeCallFrameTracer tracer(&vm, exec);
907
908 ASSERT(jsDynamicCast<JSObject*>(object));
909
910 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
911 return vm.smallStrings.undefinedString();
912 if (object->type() == JSFunctionType)
913 return vm.smallStrings.functionString();
914 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
915 CallData callData;
916 if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
917 return vm.smallStrings.functionString();
918 }
919
920 return vm.smallStrings.objectString();
6fe7ccc8
A
921}
922
ed1e77d3 923int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
93a37866
A
924{
925 VM& vm = exec->vm();
926 NativeCallFrameTracer tracer(&vm, exec);
ed1e77d3
A
927
928 ASSERT(jsDynamicCast<JSObject*>(object));
929
930 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
931 return static_cast<int32_t>(TypeofType::Undefined);
932 if (object->type() == JSFunctionType)
933 return static_cast<int32_t>(TypeofType::Function);
934 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
935 CallData callData;
936 if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
937 return static_cast<int32_t>(TypeofType::Function);
938 }
939
940 return static_cast<int32_t>(TypeofType::Object);
93a37866
A
941}
942
81345200 943char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
93a37866
A
944{
945 VM& vm = exec->vm();
946 NativeCallFrameTracer tracer(&vm, exec);
947
948 return reinterpret_cast<char*>(
81345200 949 Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
93a37866
A
950}
951
81345200 952char* JIT_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
93a37866
A
953{
954 VM& vm = exec->vm();
955 NativeCallFrameTracer tracer(&vm, exec);
956
957 return reinterpret_cast<char*>(
81345200 958 Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
93a37866
A
959}
960
81345200 961char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
93a37866
A
962{
963 VM& vm = exec->vm();
964 NativeCallFrameTracer tracer(&vm, exec);
965
966 ASSERT(!object->structure()->outOfLineCapacity());
81345200 967 DeferGC deferGC(vm.heap);
93a37866 968 Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
81345200 969 object->setButterflyWithoutChangingStructure(vm, result);
93a37866
A
970 return reinterpret_cast<char*>(result);
971}
972
81345200 973char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
93a37866
A
974{
975 VM& vm = exec->vm();
976 NativeCallFrameTracer tracer(&vm, exec);
977
81345200 978 DeferGC deferGC(vm.heap);
93a37866 979 Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
81345200 980 object->setButterflyWithoutChangingStructure(vm, result);
93a37866
A
981 return reinterpret_cast<char*>(result);
982}
983
81345200 984char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
93a37866
A
985{
986 VM& vm = exec->vm();
987 NativeCallFrameTracer tracer(&vm, exec);
988
989 if (!cell->isObject())
990 return 0;
991
992 return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
993}
994
81345200 995char* JIT_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
93a37866
A
996{
997 VM& vm = exec->vm();
998 NativeCallFrameTracer tracer(&vm, exec);
999
1000 if (!cell->isObject())
1001 return 0;
1002
1003 return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
1004}
1005
81345200 1006char* JIT_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
93a37866
A
1007{
1008 VM& vm = exec->vm();
1009 NativeCallFrameTracer tracer(&vm, exec);
1010
1011 if (!cell->isObject())
1012 return 0;
1013
1014 return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
1015}
1016
81345200 1017char* JIT_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
93a37866
A
1018{
1019 VM& vm = exec->vm();
1020 NativeCallFrameTracer tracer(&vm, exec);
1021
1022 if (!cell->isObject())
1023 return 0;
1024
1025 return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
1026}
1027
81345200 1028StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
93a37866
A
1029{
1030 VM& vm = exec->vm();
1031 NativeCallFrameTracer tracer(&vm, exec);
1032
1033 return string->value(exec).impl();
1034}
1035
81345200
A
1036JSString* JIT_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
1037{
1038 VM& vm = exec->vm();
1039 NativeCallFrameTracer tracer(&vm, exec);
1040
1041 return jsSingleCharacterString(exec, static_cast<UChar>(character));
1042}
1043
1044JSCell* JIT_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
93a37866
A
1045{
1046 VM& vm = exec->vm();
1047 NativeCallFrameTracer tracer(&vm, exec);
1048
81345200 1049 return StringObject::create(vm, structure, string);
93a37866
A
1050}
1051
81345200 1052JSCell* JIT_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
93a37866
A
1053{
1054 VM& vm = exec->vm();
1055 NativeCallFrameTracer tracer(&vm, exec);
1056
1057 return JSValue(cell).toString(exec);
1058}
1059
81345200 1060JSCell* JIT_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
93a37866
A
1061{
1062 VM& vm = exec->vm();
1063 NativeCallFrameTracer tracer(&vm, exec);
1064
1065 return JSValue::decode(value).toString(exec);
1066}
1067
ed1e77d3
A
1068JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState* exec, JSCell* cell)
1069{
1070 VM& vm = exec->vm();
1071 NativeCallFrameTracer tracer(&vm, exec);
1072
1073 return stringConstructor(exec, cell);
1074}
1075
1076JSCell* JIT_OPERATION operationCallStringConstructor(ExecState* exec, EncodedJSValue value)
1077{
1078 VM& vm = exec->vm();
1079 NativeCallFrameTracer tracer(&vm, exec);
1080
1081 return stringConstructor(exec, JSValue::decode(value));
1082}
1083
81345200 1084JSCell* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
93a37866
A
1085{
1086 VM& vm = exec->vm();
1087 NativeCallFrameTracer tracer(&vm, exec);
1088
4be4e309
A
1089 if (sumOverflows<int32_t>(left->length(), right->length())) {
1090 throwOutOfMemoryError(exec);
1091 return nullptr;
1092 }
1093
93a37866
A
1094 return JSRopeString::create(vm, left, right);
1095}
1096
81345200 1097JSCell* JIT_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
93a37866
A
1098{
1099 VM& vm = exec->vm();
1100 NativeCallFrameTracer tracer(&vm, exec);
1101
4be4e309
A
1102 if (sumOverflows<int32_t>(a->length(), b->length(), c->length())) {
1103 throwOutOfMemoryError(exec);
1104 return nullptr;
1105 }
1106
93a37866
A
1107 return JSRopeString::create(vm, a, b, c);
1108}
1109
81345200
A
1110char* JIT_OPERATION operationFindSwitchImmTargetForDouble(
1111 ExecState* exec, EncodedJSValue encodedValue, size_t tableIndex)
6fe7ccc8 1112{
81345200
A
1113 CodeBlock* codeBlock = exec->codeBlock();
1114 SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
1115 JSValue value = JSValue::decode(encodedValue);
1116 ASSERT(value.isDouble());
1117 double asDouble = value.asDouble();
1118 int32_t asInt32 = static_cast<int32_t>(asDouble);
1119 if (asDouble == asInt32)
1120 return static_cast<char*>(table.ctiForValue(asInt32).executableAddress());
1121 return static_cast<char*>(table.ctiDefault.executableAddress());
6fe7ccc8
A
1122}
1123
81345200 1124char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
93a37866 1125{
81345200
A
1126 VM& vm = exec->vm();
1127 NativeCallFrameTracer tracer(&vm, exec);
1128
1129 return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
93a37866
A
1130}
1131
ed1e77d3 1132int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
6fe7ccc8 1133{
81345200
A
1134 VM& vm = exec->vm();
1135 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8 1136
ed1e77d3
A
1137 return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(string->value(exec).impl(), std::numeric_limits<int32_t>::min());
1138}
1139
1140void JIT_OPERATION operationNotifyWrite(ExecState* exec, WatchpointSet* set)
1141{
1142 VM& vm = exec->vm();
1143 NativeCallFrameTracer tracer(&vm, exec);
1144
1145 set->touch("Executed NotifyWrite");
1146}
1147
1148void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
1149{
1150 VM& vm = exec->vm();
1151 NativeCallFrameTracer tracer(&vm, exec);
1152 throwStackOverflowError(exec);
1153}
1154
1155int32_t JIT_OPERATION operationSizeOfVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
1156{
1157 VM& vm = exec->vm();
1158 NativeCallFrameTracer tracer(&vm, exec);
1159 JSValue arguments = JSValue::decode(encodedArguments);
1160
1161 return sizeOfVarargs(exec, arguments, firstVarArgOffset);
1162}
1163
1164void JIT_OPERATION operationLoadVarargs(ExecState* exec, int32_t firstElementDest, EncodedJSValue encodedArguments, int32_t offset, int32_t length, int32_t mandatoryMinimum)
1165{
1166 VM& vm = exec->vm();
1167 NativeCallFrameTracer tracer(&vm, exec);
1168 JSValue arguments = JSValue::decode(encodedArguments);
1169
1170 loadVarargs(exec, VirtualRegister(firstElementDest), arguments, offset, length);
1171
1172 for (int32_t i = length; i < mandatoryMinimum; ++i)
1173 exec->r(firstElementDest + i) = jsUndefined();
6fe7ccc8 1174}
14957cd0 1175
81345200
A
1176double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
1177{
1178 return fmod(a, b);
1179}
1180
1181JSCell* JIT_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
6fe7ccc8 1182{
93a37866
A
1183 VM* vm = &exec->vm();
1184 NativeCallFrameTracer tracer(vm, exec);
81345200
A
1185 return JSC::stringFromCharCode(exec, op1);
1186}
14957cd0 1187
81345200
A
1188int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue encodedValue)
1189{
1190 JSValue value = JSValue::decode(encodedValue);
1191 if (!value.isDouble())
1192 return JSValue::notInt52;
1193 return tryConvertToInt52(value.asDouble());
14957cd0
A
1194}
1195
81345200 1196int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
14957cd0 1197{
81345200 1198 return tryConvertToInt52(value);
14957cd0
A
1199}
1200
ed1e77d3
A
1201void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec)
1202{
1203 exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside DFG."));
1204}
1205
81345200 1206size_t JIT_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
14957cd0 1207{
93a37866
A
1208 VM* vm = &exec->vm();
1209 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 1210
81345200
A
1211 // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1212 return JSValue::decode(value).toUInt32(exec);
14957cd0
A
1213}
1214
81345200 1215void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
6fe7ccc8 1216{
93a37866
A
1217 VM* vm = &exec->vm();
1218 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1219
1220 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
1221 CodeBlock* codeBlock = debugInfo->codeBlock;
1222 CodeBlock* alternative = codeBlock->alternative();
81345200
A
1223 dataLog("Speculation failure in ", *codeBlock);
1224 dataLog(" @ exit #", vm->osrExitIndex, " (bc#", debugInfo->bytecodeOffset, ", ", exitKindToString(debugInfo->kind), ") with ");
93a37866
A
1225 if (alternative) {
1226 dataLog(
1227 "executeCounter = ", alternative->jitExecuteCounter(),
1228 ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1229 ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1230 } else
1231 dataLog("no alternative code block (i.e. we've been jettisoned)");
1232 dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
1233 dataLog(" GPRs at time of exit:");
1234 char* scratchPointer = static_cast<char*>(scratch);
1235 for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1236 GPRReg gpr = GPRInfo::toRegister(i);
1237 dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
1238 scratchPointer += sizeof(EncodedJSValue);
1239 }
1240 dataLog("\n");
1241 dataLog(" FPRs at time of exit:");
1242 for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1243 FPRReg fpr = FPRInfo::toRegister(i);
1244 dataLog(" ", FPRInfo::debugName(fpr), ":");
1245 uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1246 double value = *reinterpret_cast_ptr<double*>(scratchPointer);
1247 dataLogF("%llx:%lf", static_cast<long long>(bits), value);
1248 scratchPointer += sizeof(EncodedJSValue);
1249 }
1250 dataLog("\n");
6fe7ccc8 1251}
93a37866 1252
ed1e77d3 1253extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
93a37866 1254{
81345200
A
1255 // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
1256 // really be profitable.
1257 DeferGCForAWhile deferGC(codeBlock->vm()->heap);
1258
1259 if (Options::verboseOSR())
1260 dataLog(*codeBlock, ": Entered reoptimize\n");
93a37866 1261 // We must be called with the baseline code block.
81345200 1262 ASSERT(JITCode::isBaselineCode(codeBlock->jitType()));
93a37866
A
1263
1264 // If I am my own replacement, then reoptimization has already been triggered.
1265 // This can happen in recursive functions.
81345200
A
1266 if (codeBlock->replacement() == codeBlock) {
1267 if (Options::verboseOSR())
1268 dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
93a37866 1269 return;
81345200
A
1270 }
1271
93a37866
A
1272 // Otherwise, the replacement must be optimized code. Use this as an opportunity
1273 // to check our logic.
1274 ASSERT(codeBlock->hasOptimizedReplacement());
81345200
A
1275 CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1276 ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
ed1e77d3
A
1277
1278 bool didTryToEnterIntoInlinedLoops = false;
1279 for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
1280 if (inlineCallFrame->executable->didTryToEnterInLoop()) {
1281 didTryToEnterIntoInlinedLoops = true;
1282 break;
1283 }
1284 }
81345200
A
1285
1286 // In order to trigger reoptimization, one of two things must have happened:
1287 // 1) We exited more than some number of times.
1288 // 2) We exited and got stuck in a loop, and now we're exiting again.
1289 bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
1290 bool didGetStuckInLoop =
ed1e77d3 1291 (codeBlock->checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
81345200
A
1292 && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
1293
1294 if (!didExitABunch && !didGetStuckInLoop) {
1295 if (Options::verboseOSR())
1296 dataLog(*codeBlock, ": Not reoptimizing ", *optimizedCodeBlock, " because it either didn't exit enough or didn't loop enough after exit.\n");
1297 codeBlock->optimizeAfterLongWarmUp();
1298 return;
1299 }
93a37866 1300
81345200 1301 optimizedCodeBlock->jettison(Profiler::JettisonDueToOSRExit, CountReoptimization);
93a37866 1302}
6fe7ccc8 1303
81345200
A
1304#if ENABLE(FTL_JIT)
1305static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
1306{
1307 if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
1308 if (Options::verboseOSR())
1309 dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
1310 jitCode->dontOptimizeAnytimeSoon(codeBlock);
1311 return;
1312 }
1313
1314 if (!jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
1315 if (Options::verboseOSR())
1316 dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
1317 return;
1318 }
1319
1320 Worklist::State worklistState;
1321 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
1322 worklistState = worklist->completeAllReadyPlansForVM(
1323 *vm, CompilationKey(codeBlock->baselineVersion(), FTLMode));
1324 } else
1325 worklistState = Worklist::NotKnown;
1326
1327 if (worklistState == Worklist::Compiling) {
1328 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1329 codeBlock, CompilationDeferred);
1330 return;
1331 }
1332
1333 if (codeBlock->hasOptimizedReplacement()) {
1334 // That's great, we've compiled the code - next time we call this function,
1335 // we'll enter that replacement.
1336 jitCode->optimizeSoon(codeBlock);
1337 return;
1338 }
1339
1340 if (worklistState == Worklist::Compiled) {
1341 // This means that we finished compiling, but failed somehow; in that case the
1342 // thresholds will be set appropriately.
1343 if (Options::verboseOSR())
1344 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1345 return;
1346 }
14957cd0 1347
81345200
A
1348 // We need to compile the code.
1349 compile(
1350 *vm, codeBlock->newReplacement().get(), codeBlock, FTLMode, UINT_MAX,
1351 Operands<JSValue>(), ToFTLDeferredCompilationCallback::create(codeBlock));
1352}
6fe7ccc8 1353
ed1e77d3 1354static void triggerTierUpNowCommon(ExecState* exec, bool inLoop)
81345200
A
1355{
1356 VM* vm = &exec->vm();
1357 NativeCallFrameTracer tracer(vm, exec);
1358 DeferGC deferGC(vm->heap);
1359 CodeBlock* codeBlock = exec->codeBlock();
1360
ed1e77d3
A
1361 if (codeBlock->jitType() != JITCode::DFGJIT) {
1362 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
1363 RELEASE_ASSERT_NOT_REACHED();
1364 }
1365
81345200
A
1366 JITCode* jitCode = codeBlock->jitCode()->dfg();
1367
1368 if (Options::verboseOSR()) {
1369 dataLog(
1370 *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
1371 jitCode->tierUpCounter, "\n");
1372 }
ed1e77d3
A
1373 if (inLoop)
1374 jitCode->nestedTriggerIsSet = 1;
1375
81345200
A
1376 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
1377}
6fe7ccc8 1378
ed1e77d3
A
1379void JIT_OPERATION triggerTierUpNow(ExecState* exec)
1380{
1381 triggerTierUpNowCommon(exec, false);
1382}
1383
1384void JIT_OPERATION triggerTierUpNowInLoop(ExecState* exec)
1385{
1386 triggerTierUpNowCommon(exec, true);
1387}
1388
81345200
A
1389char* JIT_OPERATION triggerOSREntryNow(
1390 ExecState* exec, int32_t bytecodeIndex, int32_t streamIndex)
6fe7ccc8 1391{
81345200
A
1392 VM* vm = &exec->vm();
1393 NativeCallFrameTracer tracer(vm, exec);
1394 DeferGC deferGC(vm->heap);
1395 CodeBlock* codeBlock = exec->codeBlock();
1396
ed1e77d3
A
1397 if (codeBlock->jitType() != JITCode::DFGJIT) {
1398 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
1399 RELEASE_ASSERT_NOT_REACHED();
1400 }
1401
81345200 1402 JITCode* jitCode = codeBlock->jitCode()->dfg();
ed1e77d3 1403 jitCode->nestedTriggerIsSet = 0;
81345200
A
1404
1405 if (Options::verboseOSR()) {
1406 dataLog(
ed1e77d3 1407 *codeBlock, ": Entered triggerOSREntryNow with executeCounter = ",
81345200
A
1408 jitCode->tierUpCounter, "\n");
1409 }
1410
1411 // - If we don't have an FTL code block, then try to compile one.
1412 // - If we do have an FTL code block, then try to enter for a while.
1413 // - If we couldn't enter for a while, then trigger OSR entry.
1414
1415 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
1416
1417 if (!codeBlock->hasOptimizedReplacement())
1418 return 0;
1419
1420 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
1421 jitCode->osrEntryRetry++;
1422 return 0;
1423 }
1424
1425 // It's time to try to compile code for OSR entry.
1426 Worklist::State worklistState;
1427 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
1428 worklistState = worklist->completeAllReadyPlansForVM(
1429 *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
1430 } else
1431 worklistState = Worklist::NotKnown;
1432
1433 if (worklistState == Worklist::Compiling)
1434 return 0;
1435
1436 if (CodeBlock* entryBlock = jitCode->osrEntryBlock.get()) {
1437 void* address = FTL::prepareOSREntry(
1438 exec, codeBlock, entryBlock, bytecodeIndex, streamIndex);
1439 if (address)
1440 return static_cast<char*>(address);
1441
1442 FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
1443 entryCode->countEntryFailure();
1444 if (entryCode->entryFailureCount() <
1445 Options::ftlOSREntryFailureCountForReoptimization())
1446 return 0;
1447
1448 // OSR entry failed. Oh no! This implies that we need to retry. We retry
1449 // without exponential backoff and we only do this for the entry code block.
ed1e77d3 1450 jitCode->osrEntryBlock = nullptr;
81345200
A
1451 jitCode->osrEntryRetry = 0;
1452 return 0;
1453 }
1454
1455 if (worklistState == Worklist::Compiled) {
1456 // This means that compilation failed and we already set the thresholds.
1457 if (Options::verboseOSR())
1458 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1459 return 0;
1460 }
1461
1462 // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
1463 // something.
1464 Operands<JSValue> mustHandleValues;
1465 jitCode->reconstruct(
1466 exec, codeBlock, CodeOrigin(bytecodeIndex), streamIndex, mustHandleValues);
1467 RefPtr<CodeBlock> replacementCodeBlock = codeBlock->newReplacement();
1468 CompilationResult forEntryResult = compile(
1469 *vm, replacementCodeBlock.get(), codeBlock, FTLForOSREntryMode, bytecodeIndex,
1470 mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(codeBlock));
1471
1472 if (forEntryResult != CompilationSuccessful) {
1473 ASSERT(forEntryResult == CompilationDeferred || replacementCodeBlock->hasOneRef());
1474 return 0;
1475 }
1476
1477 // It's possible that the for-entry compile already succeeded. In that case OSR
1478 // entry will succeed unless we ran out of stack. It's not clear what we should do.
1479 // We signal to try again after a while if that happens.
1480 void* address = FTL::prepareOSREntry(
1481 exec, codeBlock, jitCode->osrEntryBlock.get(), bytecodeIndex, streamIndex);
1482 return static_cast<char*>(address);
6fe7ccc8 1483}
81345200 1484#endif // ENABLE(FTL_JIT)
6fe7ccc8 1485
81345200
A
1486} // extern "C"
1487} } // namespace JSC::DFG
1488
1489#endif // ENABLE(DFG_JIT)
6fe7ccc8 1490
93a37866 1491#endif // ENABLE(JIT)