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