2 * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "DFGOperations.h"
29 #include "Arguments.h"
30 #include "ButterflyInlines.h"
31 #include "CodeBlock.h"
32 #include "CommonSlowPaths.h"
33 #include "CopiedSpaceInlines.h"
34 #include "DFGDriver.h"
35 #include "DFGJITCode.h"
36 #include "DFGOSRExit.h"
37 #include "DFGThunks.h"
38 #include "DFGToFTLDeferredCompilationCallback.h"
39 #include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
40 #include "DFGWorklist.h"
41 #include "FTLForOSREntryJITCode.h"
42 #include "FTLOSREntry.h"
43 #include "HostCallReturnValue.h"
44 #include "GetterSetter.h"
45 #include "Interpreter.h"
47 #include "JITExceptions.h"
48 #include "JSLexicalEnvironment.h"
50 #include "JSNameScope.h"
51 #include "ObjectConstructor.h"
52 #include "JSCInlines.h"
54 #include "StringConstructor.h"
56 #include "TypeProfilerLog.h"
57 #include "TypedArrayInlines.h"
58 #include <wtf/InlineASM.h>
63 namespace JSC { namespace DFG {
65 template<bool strict, bool direct>
66 static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
69 NativeCallFrameTracer tracer(&vm, exec);
71 RELEASE_ASSERT(baseValue.isObject());
72 asObject(baseValue)->putDirectIndex(exec, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
75 if (baseValue.isObject()) {
76 JSObject* object = asObject(baseValue);
77 if (object->canSetIndexQuickly(index)) {
78 object->setIndexQuickly(vm, index, value);
82 object->methodTable(vm)->putByIndex(object, exec, index, value, strict);
86 baseValue.putByIndex(exec, index, value, strict);
89 template<bool strict, bool direct>
90 ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
93 NativeCallFrameTracer tracer(vm, exec);
95 JSValue baseValue = JSValue::decode(encodedBase);
96 JSValue property = JSValue::decode(encodedProperty);
97 JSValue value = JSValue::decode(encodedValue);
99 if (LIKELY(property.isUInt32())) {
100 putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value);
104 if (property.isDouble()) {
105 double propertyAsDouble = property.asDouble();
106 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
107 if (propertyAsDouble == propertyAsUInt32) {
108 putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value);
113 // Don't put to an object if toString throws an exception.
114 PropertyName propertyName = property.toPropertyKey(exec);
115 if (!vm->exception()) {
116 PutPropertySlot slot(baseValue, strict);
118 RELEASE_ASSERT(baseValue.isObject());
119 asObject(baseValue)->putDirect(*vm, propertyName, value, slot);
121 baseValue.put(exec, propertyName, value, slot);
125 template<typename ViewClass>
126 char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
129 NativeCallFrameTracer tracer(&vm, exec);
131 vm.throwException(exec, createRangeError(exec, ASCIILiteral("Requested length is negative")));
134 return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
137 template<typename ViewClass>
138 char* newTypedArrayWithOneArgument(
139 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
142 NativeCallFrameTracer tracer(&vm, exec);
144 JSValue value = JSValue::decode(encodedValue);
146 if (JSArrayBuffer* jsBuffer = jsDynamicCast<JSArrayBuffer*>(value)) {
147 RefPtr<ArrayBuffer> buffer = jsBuffer->impl();
149 if (buffer->byteLength() % ViewClass::elementSize) {
150 vm.throwException(exec, createRangeError(exec, ASCIILiteral("ArrayBuffer length minus the byteOffset is not a multiple of the element size")));
153 return bitwise_cast<char*>(
155 exec, structure, buffer, 0, buffer->byteLength() / ViewClass::elementSize));
158 if (JSObject* object = jsDynamicCast<JSObject*>(value)) {
159 unsigned length = object->get(exec, vm.propertyNames->length).toUInt32(exec);
160 if (exec->hadException())
163 ViewClass* result = ViewClass::createUninitialized(exec, structure, length);
167 if (!result->set(exec, object, 0, length))
170 return bitwise_cast<char*>(result);
175 length = value.asInt32();
176 else if (!value.isNumber()) {
177 vm.throwException(exec, createTypeError(exec, ASCIILiteral("Invalid array length argument")));
180 length = static_cast<int>(value.asNumber());
181 if (length != value.asNumber()) {
182 vm.throwException(exec, createTypeError(exec, ASCIILiteral("Invalid array length argument (fractional lengths not allowed)")));
188 vm.throwException(exec, createRangeError(exec, ASCIILiteral("Requested length is negative")));
192 return bitwise_cast<char*>(ViewClass::create(exec, structure, length));
197 EncodedJSValue JIT_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
199 VM* vm = &exec->vm();
200 NativeCallFrameTracer tracer(vm, exec);
202 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, NotStrictMode));
205 EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState* exec, EncodedJSValue encodedOp)
207 VM* vm = &exec->vm();
208 NativeCallFrameTracer tracer(vm, exec);
210 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, StrictMode));
213 JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
216 NativeCallFrameTracer tracer(&vm, exec);
219 ConstructData constructData;
220 ASSERT(jsCast<JSFunction*>(constructor)->methodTable(vm)->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS);
223 return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->allocationProfile(exec, inlineCapacity)->structure());
226 EncodedJSValue JIT_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
228 VM* vm = &exec->vm();
229 NativeCallFrameTracer tracer(vm, exec);
231 JSValue op1 = JSValue::decode(encodedOp1);
232 JSValue op2 = JSValue::decode(encodedOp2);
234 return JSValue::encode(jsAdd(exec, op1, op2));
237 EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
239 VM* vm = &exec->vm();
240 NativeCallFrameTracer tracer(vm, exec);
242 JSValue op1 = JSValue::decode(encodedOp1);
243 JSValue op2 = JSValue::decode(encodedOp2);
245 ASSERT(!op1.isNumber() || !op2.isNumber());
247 if (op1.isString() && !op2.isObject())
248 return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
250 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
253 static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
256 NativeCallFrameTracer tracer(&vm, exec);
258 if (base->isObject()) {
259 JSObject* object = asObject(base);
260 if (object->canGetIndexQuickly(index))
261 return JSValue::encode(object->getIndexQuickly(index));
264 if (isJSString(base) && asString(base)->canGetIndex(index))
265 return JSValue::encode(asString(base)->getIndex(exec, index));
267 return JSValue::encode(JSValue(base).get(exec, index));
270 EncodedJSValue JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
273 NativeCallFrameTracer tracer(&vm, exec);
275 JSValue baseValue = JSValue::decode(encodedBase);
276 JSValue property = JSValue::decode(encodedProperty);
278 if (LIKELY(baseValue.isCell())) {
279 JSCell* base = baseValue.asCell();
281 if (property.isUInt32()) {
282 return getByVal(exec, base, property.asUInt32());
283 } else if (property.isDouble()) {
284 double propertyAsDouble = property.asDouble();
285 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
286 if (propertyAsUInt32 == propertyAsDouble)
287 return getByVal(exec, base, propertyAsUInt32);
288 } else if (property.isString()) {
289 Structure& structure = *base->structure(vm);
290 if (JSCell::canUseFastGetOwnProperty(structure)) {
291 if (AtomicStringImpl* existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
292 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString))
293 return JSValue::encode(result);
299 PropertyName propertyName = property.toPropertyKey(exec);
300 return JSValue::encode(baseValue.get(exec, propertyName));
303 EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
306 NativeCallFrameTracer tracer(&vm, exec);
308 JSValue property = JSValue::decode(encodedProperty);
310 if (property.isUInt32())
311 return getByVal(exec, base, property.asUInt32());
312 if (property.isDouble()) {
313 double propertyAsDouble = property.asDouble();
314 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
315 if (propertyAsUInt32 == propertyAsDouble)
316 return getByVal(exec, base, propertyAsUInt32);
317 } else if (property.isString()) {
318 Structure& structure = *base->structure(vm);
319 if (JSCell::canUseFastGetOwnProperty(structure)) {
320 if (AtomicStringImpl* existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
321 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString))
322 return JSValue::encode(result);
327 PropertyName propertyName = property.toPropertyKey(exec);
328 return JSValue::encode(JSValue(base).get(exec, propertyName));
331 ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
333 VM* vm = &exec->vm();
334 NativeCallFrameTracer tracer(vm, exec);
337 // Go the slowest way possible becase negative indices don't use indexed storage.
338 return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
341 // Use this since we know that the value is out of bounds.
342 return JSValue::encode(JSValue(base).get(exec, index));
345 EncodedJSValue JIT_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
347 return getByValCellInt(exec, base, index);
350 EncodedJSValue JIT_OPERATION operationGetByValStringInt(ExecState* exec, JSString* base, int32_t index)
352 return getByValCellInt(exec, base, index);
355 void JIT_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
357 VM* vm = &exec->vm();
358 NativeCallFrameTracer tracer(vm, exec);
360 operationPutByValInternal<true, false>(exec, encodedBase, encodedProperty, encodedValue);
363 void JIT_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
365 VM* vm = &exec->vm();
366 NativeCallFrameTracer tracer(vm, exec);
368 operationPutByValInternal<false, false>(exec, encodedBase, encodedProperty, encodedValue);
371 void JIT_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
373 VM* vm = &exec->vm();
374 NativeCallFrameTracer tracer(vm, exec);
376 operationPutByValInternal<true, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
379 void JIT_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
381 VM* vm = &exec->vm();
382 NativeCallFrameTracer tracer(vm, exec);
384 operationPutByValInternal<false, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
387 void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
390 NativeCallFrameTracer tracer(&vm, exec);
393 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
397 PutPropertySlot slot(array, true);
398 array->methodTable()->put(
399 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
402 void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
404 VM* vm = &exec->vm();
405 NativeCallFrameTracer tracer(vm, exec);
408 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
412 PutPropertySlot slot(array, false);
413 array->methodTable()->put(
414 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
417 void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
419 VM* vm = &exec->vm();
420 NativeCallFrameTracer tracer(vm, exec);
422 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
425 array->putByIndexInline(exec, index, jsValue, true);
429 PutPropertySlot slot(array, true);
430 array->methodTable()->put(
431 array, exec, Identifier::from(exec, index), jsValue, slot);
434 void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
436 VM* vm = &exec->vm();
437 NativeCallFrameTracer tracer(vm, exec);
439 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
442 array->putByIndexInline(exec, index, jsValue, false);
446 PutPropertySlot slot(array, false);
447 array->methodTable()->put(
448 array, exec, Identifier::from(exec, index), jsValue, slot);
451 void JIT_OPERATION operationPutByValDirectStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
453 VM* vm = &exec->vm();
454 NativeCallFrameTracer tracer(vm, exec);
456 operationPutByValInternal<true, true>(exec, encodedBase, encodedProperty, encodedValue);
459 void JIT_OPERATION operationPutByValDirectNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
461 VM* vm = &exec->vm();
462 NativeCallFrameTracer tracer(vm, exec);
464 operationPutByValInternal<false, true>(exec, encodedBase, encodedProperty, encodedValue);
467 void JIT_OPERATION operationPutByValDirectCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
469 VM* vm = &exec->vm();
470 NativeCallFrameTracer tracer(vm, exec);
472 operationPutByValInternal<true, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
475 void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
477 VM* vm = &exec->vm();
478 NativeCallFrameTracer tracer(vm, exec);
480 operationPutByValInternal<false, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
483 void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
485 VM* vm = &exec->vm();
486 NativeCallFrameTracer tracer(vm, exec);
488 array->putDirectIndex(exec, index, JSValue::decode(encodedValue), 0, PutDirectIndexShouldThrow);
492 PutPropertySlot slot(array, true);
493 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
496 void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
498 VM* vm = &exec->vm();
499 NativeCallFrameTracer tracer(vm, exec);
502 array->putDirectIndex(exec, index, JSValue::decode(encodedValue));
506 PutPropertySlot slot(array, false);
507 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
510 EncodedJSValue JIT_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
512 VM* vm = &exec->vm();
513 NativeCallFrameTracer tracer(vm, exec);
515 array->push(exec, JSValue::decode(encodedValue));
516 return JSValue::encode(jsNumber(array->length()));
519 EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
521 VM* vm = &exec->vm();
522 NativeCallFrameTracer tracer(vm, exec);
524 array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
525 return JSValue::encode(jsNumber(array->length()));
528 EncodedJSValue JIT_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
530 VM* vm = &exec->vm();
531 NativeCallFrameTracer tracer(vm, exec);
533 return JSValue::encode(array->pop(exec));
536 EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
538 VM* vm = &exec->vm();
539 NativeCallFrameTracer tracer(vm, exec);
541 array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
543 return JSValue::encode(array->pop(exec));
546 EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
549 NativeCallFrameTracer tracer(&vm, exec);
551 if (!base->inherits(RegExpObject::info()))
552 return throwVMTypeError(exec);
554 ASSERT(argument->isString() || argument->isObject());
555 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
556 return JSValue::encode(asRegExpObject(base)->exec(exec, input));
559 size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
562 NativeCallFrameTracer tracer(&vm, exec);
564 if (!base->inherits(RegExpObject::info())) {
565 throwTypeError(exec);
569 ASSERT(argument->isString() || argument->isObject());
570 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
571 return asRegExpObject(base)->test(exec, input);
574 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
576 VM* vm = &exec->vm();
577 NativeCallFrameTracer tracer(vm, exec);
579 JSValue op1 = JSValue::decode(encodedOp1);
580 JSValue op2 = JSValue::decode(encodedOp2);
582 ASSERT(op1.isCell());
583 ASSERT(op2.isCell());
585 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
588 size_t JIT_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
590 VM* vm = &exec->vm();
591 NativeCallFrameTracer tracer(vm, exec);
593 JSValue src1 = JSValue::decode(encodedOp1);
594 JSValue src2 = JSValue::decode(encodedOp2);
596 return JSValue::strictEqual(exec, src1, src2);
599 EncodedJSValue JIT_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
601 VM* vm = &exec->vm();
602 NativeCallFrameTracer tracer(vm, exec);
604 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
607 char* JIT_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
609 VM* vm = &exec->vm();
610 NativeCallFrameTracer tracer(vm, exec);
612 return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
615 char* JIT_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
617 VM* vm = &exec->vm();
618 NativeCallFrameTracer tracer(vm, exec);
620 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
623 char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size)
625 VM* vm = &exec->vm();
626 NativeCallFrameTracer tracer(vm, exec);
628 if (UNLIKELY(size < 0))
629 return bitwise_cast<char*>(exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
631 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure, size));
634 char* JIT_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
637 NativeCallFrameTracer tracer(&vm, exec);
638 return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
641 char* JIT_OPERATION operationNewInt8ArrayWithSize(
642 ExecState* exec, Structure* structure, int32_t length)
644 return newTypedArrayWithSize<JSInt8Array>(exec, structure, length);
647 char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
648 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
650 return newTypedArrayWithOneArgument<JSInt8Array>(exec, structure, encodedValue);
653 char* JIT_OPERATION operationNewInt16ArrayWithSize(
654 ExecState* exec, Structure* structure, int32_t length)
656 return newTypedArrayWithSize<JSInt16Array>(exec, structure, length);
659 char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
660 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
662 return newTypedArrayWithOneArgument<JSInt16Array>(exec, structure, encodedValue);
665 char* JIT_OPERATION operationNewInt32ArrayWithSize(
666 ExecState* exec, Structure* structure, int32_t length)
668 return newTypedArrayWithSize<JSInt32Array>(exec, structure, length);
671 char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
672 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
674 return newTypedArrayWithOneArgument<JSInt32Array>(exec, structure, encodedValue);
677 char* JIT_OPERATION operationNewUint8ArrayWithSize(
678 ExecState* exec, Structure* structure, int32_t length)
680 return newTypedArrayWithSize<JSUint8Array>(exec, structure, length);
683 char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
684 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
686 return newTypedArrayWithOneArgument<JSUint8Array>(exec, structure, encodedValue);
689 char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(
690 ExecState* exec, Structure* structure, int32_t length)
692 return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length);
695 char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
696 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
698 return newTypedArrayWithOneArgument<JSUint8ClampedArray>(exec, structure, encodedValue);
701 char* JIT_OPERATION operationNewUint16ArrayWithSize(
702 ExecState* exec, Structure* structure, int32_t length)
704 return newTypedArrayWithSize<JSUint16Array>(exec, structure, length);
707 char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
708 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
710 return newTypedArrayWithOneArgument<JSUint16Array>(exec, structure, encodedValue);
713 char* JIT_OPERATION operationNewUint32ArrayWithSize(
714 ExecState* exec, Structure* structure, int32_t length)
716 return newTypedArrayWithSize<JSUint32Array>(exec, structure, length);
719 char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
720 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
722 return newTypedArrayWithOneArgument<JSUint32Array>(exec, structure, encodedValue);
725 char* JIT_OPERATION operationNewFloat32ArrayWithSize(
726 ExecState* exec, Structure* structure, int32_t length)
728 return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length);
731 char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
732 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
734 return newTypedArrayWithOneArgument<JSFloat32Array>(exec, structure, encodedValue);
737 char* JIT_OPERATION operationNewFloat64ArrayWithSize(
738 ExecState* exec, Structure* structure, int32_t length)
740 return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length);
743 char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
744 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
746 return newTypedArrayWithOneArgument<JSFloat64Array>(exec, structure, encodedValue);
749 JSCell* JIT_OPERATION operationCreateInlinedArguments(
750 ExecState* exec, InlineCallFrame* inlineCallFrame)
753 NativeCallFrameTracer tracer(&vm, exec);
754 // NB: This needs to be exceedingly careful with top call frame tracking, since it
755 // may be called from OSR exit, while the state of the call stack is bizarre.
756 Arguments* result = Arguments::create(vm, exec, inlineCallFrame);
757 ASSERT(!vm.exception());
761 void JIT_OPERATION operationTearOffInlinedArguments(
762 ExecState* exec, JSCell* argumentsCell, JSCell* activationCell, InlineCallFrame* inlineCallFrame)
764 ASSERT_UNUSED(activationCell, !activationCell); // Currently, we don't inline functions with activations.
765 jsCast<Arguments*>(argumentsCell)->tearOff(exec, inlineCallFrame);
768 EncodedJSValue JIT_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index)
771 NativeCallFrameTracer tracer(&vm, exec);
773 JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
775 // If there are no arguments, and we're accessing out of bounds, then we have to create the
776 // arguments in case someone has installed a getter on a numeric property.
777 if (!argumentsValue) {
778 JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
779 exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec, lexicalEnvironment);
782 return JSValue::encode(argumentsValue.get(exec, index));
785 EncodedJSValue JIT_OPERATION operationGetInlinedArgumentByVal(
786 ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index)
789 NativeCallFrameTracer tracer(&vm, exec);
791 JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
793 // If there are no arguments, and we're accessing out of bounds, then we have to create the
794 // arguments in case someone has installed a getter on a numeric property.
795 if (!argumentsValue) {
796 exec->uncheckedR(argumentsRegister) = argumentsValue =
797 Arguments::create(exec->vm(), exec, inlineCallFrame);
800 return JSValue::encode(argumentsValue.get(exec, index));
803 JSCell* JIT_OPERATION operationNewFunctionNoCheck(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
805 ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
807 NativeCallFrameTracer tracer(&vm, exec);
808 return JSFunction::create(vm, static_cast<FunctionExecutable*>(functionExecutable), scope);
811 size_t JIT_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
813 return jsIsObjectType(exec, JSValue::decode(value));
816 size_t JIT_OPERATION operationIsFunction(EncodedJSValue value)
818 return jsIsFunctionType(JSValue::decode(value));
821 JSCell* JIT_OPERATION operationTypeOf(ExecState* exec, JSCell* value)
824 NativeCallFrameTracer tracer(&vm, exec);
825 return jsTypeStringForValue(exec, JSValue(value)).asCell();
828 char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
831 NativeCallFrameTracer tracer(&vm, exec);
833 return reinterpret_cast<char*>(
834 Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
837 char* JIT_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
840 NativeCallFrameTracer tracer(&vm, exec);
842 return reinterpret_cast<char*>(
843 Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
846 char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
849 NativeCallFrameTracer tracer(&vm, exec);
851 ASSERT(!object->structure()->outOfLineCapacity());
852 DeferGC deferGC(vm.heap);
853 Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
854 object->setButterflyWithoutChangingStructure(vm, result);
855 return reinterpret_cast<char*>(result);
858 char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
861 NativeCallFrameTracer tracer(&vm, exec);
863 DeferGC deferGC(vm.heap);
864 Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
865 object->setButterflyWithoutChangingStructure(vm, result);
866 return reinterpret_cast<char*>(result);
869 char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
872 NativeCallFrameTracer tracer(&vm, exec);
874 if (!cell->isObject())
877 return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
880 char* JIT_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
883 NativeCallFrameTracer tracer(&vm, exec);
885 if (!cell->isObject())
888 return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
891 char* JIT_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
894 NativeCallFrameTracer tracer(&vm, exec);
896 if (!cell->isObject())
899 return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
902 char* JIT_OPERATION operationRageEnsureContiguous(ExecState* exec, JSCell* cell)
905 NativeCallFrameTracer tracer(&vm, exec);
907 if (!cell->isObject())
910 return reinterpret_cast<char*>(asObject(cell)->rageEnsureContiguous(vm).data());
913 char* JIT_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
916 NativeCallFrameTracer tracer(&vm, exec);
918 if (!cell->isObject())
921 return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
924 StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
927 NativeCallFrameTracer tracer(&vm, exec);
929 return string->value(exec).impl();
932 JSString* JIT_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
935 NativeCallFrameTracer tracer(&vm, exec);
937 return jsSingleCharacterString(exec, static_cast<UChar>(character));
940 JSCell* JIT_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
943 NativeCallFrameTracer tracer(&vm, exec);
945 return StringObject::create(vm, structure, string);
948 JSCell* JIT_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
951 NativeCallFrameTracer tracer(&vm, exec);
953 return JSValue(cell).toString(exec);
956 JSCell* JIT_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
959 NativeCallFrameTracer tracer(&vm, exec);
961 return JSValue::decode(value).toString(exec);
964 JSCell* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
967 NativeCallFrameTracer tracer(&vm, exec);
969 if (sumOverflows<int32_t>(left->length(), right->length())) {
970 throwOutOfMemoryError(exec);
974 return JSRopeString::create(vm, left, right);
977 JSCell* JIT_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
980 NativeCallFrameTracer tracer(&vm, exec);
982 if (sumOverflows<int32_t>(a->length(), b->length(), c->length())) {
983 throwOutOfMemoryError(exec);
987 return JSRopeString::create(vm, a, b, c);
990 char* JIT_OPERATION operationFindSwitchImmTargetForDouble(
991 ExecState* exec, EncodedJSValue encodedValue, size_t tableIndex)
993 CodeBlock* codeBlock = exec->codeBlock();
994 SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
995 JSValue value = JSValue::decode(encodedValue);
996 ASSERT(value.isDouble());
997 double asDouble = value.asDouble();
998 int32_t asInt32 = static_cast<int32_t>(asDouble);
999 if (asDouble == asInt32)
1000 return static_cast<char*>(table.ctiForValue(asInt32).executableAddress());
1001 return static_cast<char*>(table.ctiDefault.executableAddress());
1004 char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
1006 VM& vm = exec->vm();
1007 NativeCallFrameTracer tracer(&vm, exec);
1009 return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
1012 void JIT_OPERATION operationNotifyWrite(ExecState* exec, VariableWatchpointSet* set, EncodedJSValue encodedValue)
1014 VM& vm = exec->vm();
1015 NativeCallFrameTracer tracer(&vm, exec);
1016 JSValue value = JSValue::decode(encodedValue);
1018 set->notifyWrite(vm, value, "Executed NotifyWrite");
1021 double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
1026 JSCell* JIT_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
1028 VM* vm = &exec->vm();
1029 NativeCallFrameTracer tracer(vm, exec);
1030 return JSC::stringFromCharCode(exec, op1);
1033 int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue encodedValue)
1035 JSValue value = JSValue::decode(encodedValue);
1036 if (!value.isDouble())
1037 return JSValue::notInt52;
1038 return tryConvertToInt52(value.asDouble());
1041 int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
1043 return tryConvertToInt52(value);
1046 void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec)
1048 exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside DFG."));
1051 size_t JIT_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
1053 VM* vm = &exec->vm();
1054 NativeCallFrameTracer tracer(vm, exec);
1056 // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1057 return JSValue::decode(value).toUInt32(exec);
1060 void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
1062 VM* vm = &exec->vm();
1063 NativeCallFrameTracer tracer(vm, exec);
1065 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
1066 CodeBlock* codeBlock = debugInfo->codeBlock;
1067 CodeBlock* alternative = codeBlock->alternative();
1068 dataLog("Speculation failure in ", *codeBlock);
1069 dataLog(" @ exit #", vm->osrExitIndex, " (bc#", debugInfo->bytecodeOffset, ", ", exitKindToString(debugInfo->kind), ") with ");
1072 "executeCounter = ", alternative->jitExecuteCounter(),
1073 ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1074 ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1076 dataLog("no alternative code block (i.e. we've been jettisoned)");
1077 dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
1078 dataLog(" GPRs at time of exit:");
1079 char* scratchPointer = static_cast<char*>(scratch);
1080 for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1081 GPRReg gpr = GPRInfo::toRegister(i);
1082 dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
1083 scratchPointer += sizeof(EncodedJSValue);
1086 dataLog(" FPRs at time of exit:");
1087 for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1088 FPRReg fpr = FPRInfo::toRegister(i);
1089 dataLog(" ", FPRInfo::debugName(fpr), ":");
1090 uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1091 double value = *reinterpret_cast_ptr<double*>(scratchPointer);
1092 dataLogF("%llx:%lf", static_cast<long long>(bits), value);
1093 scratchPointer += sizeof(EncodedJSValue);
1098 extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
1100 // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
1101 // really be profitable.
1102 DeferGCForAWhile deferGC(codeBlock->vm()->heap);
1104 if (Options::verboseOSR())
1105 dataLog(*codeBlock, ": Entered reoptimize\n");
1106 // We must be called with the baseline code block.
1107 ASSERT(JITCode::isBaselineCode(codeBlock->jitType()));
1109 // If I am my own replacement, then reoptimization has already been triggered.
1110 // This can happen in recursive functions.
1111 if (codeBlock->replacement() == codeBlock) {
1112 if (Options::verboseOSR())
1113 dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
1117 // Otherwise, the replacement must be optimized code. Use this as an opportunity
1118 // to check our logic.
1119 ASSERT(codeBlock->hasOptimizedReplacement());
1120 CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1121 ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
1123 bool didTryToEnterIntoInlinedLoops = false;
1124 for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
1125 if (inlineCallFrame->executable->didTryToEnterInLoop()) {
1126 didTryToEnterIntoInlinedLoops = true;
1131 // In order to trigger reoptimization, one of two things must have happened:
1132 // 1) We exited more than some number of times.
1133 // 2) We exited and got stuck in a loop, and now we're exiting again.
1134 bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
1135 bool didGetStuckInLoop =
1136 (codeBlock->checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
1137 && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
1139 if (!didExitABunch && !didGetStuckInLoop) {
1140 if (Options::verboseOSR())
1141 dataLog(*codeBlock, ": Not reoptimizing ", *optimizedCodeBlock, " because it either didn't exit enough or didn't loop enough after exit.\n");
1142 codeBlock->optimizeAfterLongWarmUp();
1146 optimizedCodeBlock->jettison(Profiler::JettisonDueToOSRExit, CountReoptimization);
1150 static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
1152 if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
1153 if (Options::verboseOSR())
1154 dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
1155 jitCode->dontOptimizeAnytimeSoon(codeBlock);
1159 if (!jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
1160 if (Options::verboseOSR())
1161 dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
1165 Worklist::State worklistState;
1166 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
1167 worklistState = worklist->completeAllReadyPlansForVM(
1168 *vm, CompilationKey(codeBlock->baselineVersion(), FTLMode));
1170 worklistState = Worklist::NotKnown;
1172 if (worklistState == Worklist::Compiling) {
1173 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1174 codeBlock, CompilationDeferred);
1178 if (codeBlock->hasOptimizedReplacement()) {
1179 // That's great, we've compiled the code - next time we call this function,
1180 // we'll enter that replacement.
1181 jitCode->optimizeSoon(codeBlock);
1185 if (worklistState == Worklist::Compiled) {
1186 // This means that we finished compiling, but failed somehow; in that case the
1187 // thresholds will be set appropriately.
1188 if (Options::verboseOSR())
1189 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1193 // We need to compile the code.
1195 *vm, codeBlock->newReplacement().get(), codeBlock, FTLMode, UINT_MAX,
1196 Operands<JSValue>(), ToFTLDeferredCompilationCallback::create(codeBlock));
1199 void JIT_OPERATION triggerTierUpNow(ExecState* exec)
1201 VM* vm = &exec->vm();
1202 NativeCallFrameTracer tracer(vm, exec);
1203 DeferGC deferGC(vm->heap);
1204 CodeBlock* codeBlock = exec->codeBlock();
1206 JITCode* jitCode = codeBlock->jitCode()->dfg();
1208 if (Options::verboseOSR()) {
1210 *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
1211 jitCode->tierUpCounter, "\n");
1214 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
1217 char* JIT_OPERATION triggerOSREntryNow(
1218 ExecState* exec, int32_t bytecodeIndex, int32_t streamIndex)
1220 VM* vm = &exec->vm();
1221 NativeCallFrameTracer tracer(vm, exec);
1222 DeferGC deferGC(vm->heap);
1223 CodeBlock* codeBlock = exec->codeBlock();
1225 JITCode* jitCode = codeBlock->jitCode()->dfg();
1227 if (Options::verboseOSR()) {
1229 *codeBlock, ": Entered triggerOSREntryNow with executeCounter = ",
1230 jitCode->tierUpCounter, "\n");
1233 // - If we don't have an FTL code block, then try to compile one.
1234 // - If we do have an FTL code block, then try to enter for a while.
1235 // - If we couldn't enter for a while, then trigger OSR entry.
1237 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
1239 if (!codeBlock->hasOptimizedReplacement())
1242 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
1243 jitCode->osrEntryRetry++;
1247 // It's time to try to compile code for OSR entry.
1248 Worklist::State worklistState;
1249 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
1250 worklistState = worklist->completeAllReadyPlansForVM(
1251 *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
1253 worklistState = Worklist::NotKnown;
1255 if (worklistState == Worklist::Compiling)
1258 if (CodeBlock* entryBlock = jitCode->osrEntryBlock.get()) {
1259 void* address = FTL::prepareOSREntry(
1260 exec, codeBlock, entryBlock, bytecodeIndex, streamIndex);
1262 return static_cast<char*>(address);
1264 FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
1265 entryCode->countEntryFailure();
1266 if (entryCode->entryFailureCount() <
1267 Options::ftlOSREntryFailureCountForReoptimization())
1270 // OSR entry failed. Oh no! This implies that we need to retry. We retry
1271 // without exponential backoff and we only do this for the entry code block.
1272 jitCode->osrEntryBlock.clear();
1273 jitCode->osrEntryRetry = 0;
1277 if (worklistState == Worklist::Compiled) {
1278 // This means that compilation failed and we already set the thresholds.
1279 if (Options::verboseOSR())
1280 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1284 // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
1286 Operands<JSValue> mustHandleValues;
1287 jitCode->reconstruct(
1288 exec, codeBlock, CodeOrigin(bytecodeIndex), streamIndex, mustHandleValues);
1289 RefPtr<CodeBlock> replacementCodeBlock = codeBlock->newReplacement();
1290 CompilationResult forEntryResult = compile(
1291 *vm, replacementCodeBlock.get(), codeBlock, FTLForOSREntryMode, bytecodeIndex,
1292 mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(codeBlock));
1294 if (forEntryResult != CompilationSuccessful) {
1295 ASSERT(forEntryResult == CompilationDeferred || replacementCodeBlock->hasOneRef());
1299 // It's possible that the for-entry compile already succeeded. In that case OSR
1300 // entry will succeed unless we ran out of stack. It's not clear what we should do.
1301 // We signal to try again after a while if that happens.
1302 void* address = FTL::prepareOSREntry(
1303 exec, codeBlock, jitCode->osrEntryBlock.get(), bytecodeIndex, streamIndex);
1304 return static_cast<char*>(address);
1306 #endif // ENABLE(FTL_JIT)
1309 } } // namespace JSC::DFG
1311 #endif // ENABLE(DFG_JIT)
1313 #endif // ENABLE(JIT)