b387aa61cb818f35a22492aa4e57ed80d9d29a02
[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 "ArrayConstructor.h"
30 #include "ButterflyInlines.h"
31 #include "ClonedArguments.h"
32 #include "CodeBlock.h"
33 #include "CommonSlowPaths.h"
34 #include "CopiedSpaceInlines.h"
35 #include "DFGDriver.h"
36 #include "DFGJITCode.h"
37 #include "DFGOSRExit.h"
38 #include "DFGThunks.h"
39 #include "DFGToFTLDeferredCompilationCallback.h"
40 #include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
41 #include "DFGWorklist.h"
42 #include "DirectArguments.h"
43 #include "FTLForOSREntryJITCode.h"
44 #include "FTLOSREntry.h"
45 #include "GetterSetter.h"
46 #include "HostCallReturnValue.h"
47 #include "Interpreter.h"
48 #include "JIT.h"
49 #include "JITExceptions.h"
50 #include "JSCInlines.h"
51 #include "JSGenericTypedArrayViewConstructorInlines.h"
52 #include "JSLexicalEnvironment.h"
53 #include "ObjectConstructor.h"
54 #include "Repatch.h"
55 #include "ScopedArguments.h"
56 #include "StringConstructor.h"
57 #include "SuperSampler.h"
58 #include "Symbol.h"
59 #include "TypeProfilerLog.h"
60 #include "TypedArrayInlines.h"
61 #include "VMInlines.h"
62 #include <wtf/InlineASM.h>
63
64 #if ENABLE(JIT)
65 #if ENABLE(DFG_JIT)
66
67 namespace JSC { namespace DFG {
68
69 template<bool strict, bool direct>
70 static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
71 {
72     VM& vm = exec->vm();
73     NativeCallFrameTracer tracer(&vm, exec);
74     ASSERT(isIndex(index));
75     if (direct) {
76         RELEASE_ASSERT(baseValue.isObject());
77         asObject(baseValue)->putDirectIndex(exec, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
78         return;
79     }
80     if (baseValue.isObject()) {
81         JSObject* object = asObject(baseValue);
82         if (object->canSetIndexQuickly(index)) {
83             object->setIndexQuickly(vm, index, value);
84             return;
85         }
86
87         object->methodTable(vm)->putByIndex(object, exec, index, value, strict);
88         return;
89     }
90
91     baseValue.putByIndex(exec, index, value, strict);
92 }
93
94 template<bool strict, bool direct>
95 ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
96 {
97     VM* vm = &exec->vm();
98     NativeCallFrameTracer tracer(vm, exec);
99
100     JSValue baseValue = JSValue::decode(encodedBase);
101     JSValue property = JSValue::decode(encodedProperty);
102     JSValue value = JSValue::decode(encodedValue);
103
104     if (LIKELY(property.isUInt32())) {
105         // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
106         ASSERT(isIndex(property.asUInt32()));
107         putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value);
108         return;
109     }
110
111     if (property.isDouble()) {
112         double propertyAsDouble = property.asDouble();
113         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
114         if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) {
115             putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value);
116             return;
117         }
118     }
119
120     // Don't put to an object if toString throws an exception.
121     auto propertyName = property.toPropertyKey(exec);
122     if (vm->exception())
123         return;
124
125     PutPropertySlot slot(baseValue, strict);
126     if (direct) {
127         RELEASE_ASSERT(baseValue.isObject());
128         if (Optional<uint32_t> index = parseIndex(propertyName))
129             asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
130         else
131             asObject(baseValue)->putDirect(*vm, propertyName, value, slot);
132     } else
133         baseValue.put(exec, propertyName, value, slot);
134 }
135
136 template<typename ViewClass>
137 char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
138 {
139     VM& vm = exec->vm();
140     NativeCallFrameTracer tracer(&vm, exec);
141     auto scope = DECLARE_THROW_SCOPE(vm);
142
143     if (size < 0) {
144         throwException(exec, scope, createRangeError(exec, ASCIILiteral("Requested length is negative")));
145         return 0;
146     }
147     return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
148 }
149
150 template <bool strict>
151 static ALWAYS_INLINE void putWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, const Identifier& ident)
152 {
153     JSValue baseValue = JSValue::decode(encodedBase);
154     JSValue thisVal = JSValue::decode(encodedThis);
155     JSValue putValue = JSValue::decode(encodedValue);
156     PutPropertySlot slot(thisVal, strict);
157     baseValue.putInline(exec, ident, putValue, slot);
158 }
159
160 extern "C" {
161
162 EncodedJSValue JIT_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
163 {
164     VM* vm = &exec->vm();
165     NativeCallFrameTracer tracer(vm, exec);
166
167     return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, NotStrictMode));
168 }
169
170 EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState* exec, EncodedJSValue encodedOp)
171 {
172     VM* vm = &exec->vm();
173     NativeCallFrameTracer tracer(vm, exec);
174
175     return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, StrictMode));
176 }
177
178 JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
179 {
180     VM& vm = exec->vm();
181     NativeCallFrameTracer tracer(&vm, exec);
182     if (constructor->type() == JSFunctionType)
183         return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->rareData(exec, inlineCapacity)->objectAllocationProfile()->structure());
184
185     JSValue proto = constructor->get(exec, exec->propertyNames().prototype);
186     if (vm.exception())
187         return nullptr;
188     if (proto.isObject())
189         return constructEmptyObject(exec, asObject(proto));
190     return constructEmptyObject(exec);
191 }
192
193 JSCell* JIT_OPERATION operationObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
194 {
195     VM* vm = &exec->vm();
196     NativeCallFrameTracer tracer(vm, exec);
197
198     JSValue value = JSValue::decode(encodedTarget);
199     ASSERT(!value.isObject());
200
201     if (value.isUndefinedOrNull())
202         return constructEmptyObject(exec, globalObject->objectPrototype());
203     return value.toObject(exec, globalObject);
204 }
205
206 EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
207 {
208     VM* vm = &exec->vm();
209     NativeCallFrameTracer tracer(vm, exec);
210
211     JSValue op1 = JSValue::decode(encodedOp1);
212     JSValue op2 = JSValue::decode(encodedOp2);
213
214     int32_t a = op1.toInt32(exec);
215     if (UNLIKELY(vm->exception()))
216         return JSValue::encode(JSValue());
217     int32_t b = op2.toInt32(exec);
218     return JSValue::encode(jsNumber(a & b));
219 }
220
221 EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
222 {
223     VM* vm = &exec->vm();
224     NativeCallFrameTracer tracer(vm, exec);
225
226     JSValue op1 = JSValue::decode(encodedOp1);
227     JSValue op2 = JSValue::decode(encodedOp2);
228
229     int32_t a = op1.toInt32(exec);
230     if (UNLIKELY(vm->exception()))
231         return JSValue::encode(JSValue());
232     int32_t b = op2.toInt32(exec);
233     return JSValue::encode(jsNumber(a | b));
234 }
235
236 EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
237 {
238     VM* vm = &exec->vm();
239     NativeCallFrameTracer tracer(vm, exec);
240
241     JSValue op1 = JSValue::decode(encodedOp1);
242     JSValue op2 = JSValue::decode(encodedOp2);
243
244     int32_t a = op1.toInt32(exec);
245     if (UNLIKELY(vm->exception()))
246         return JSValue::encode(JSValue());
247     int32_t b = op2.toInt32(exec);
248     return JSValue::encode(jsNumber(a ^ b));
249 }
250
251 EncodedJSValue JIT_OPERATION operationValueBitLShift(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     int32_t a = op1.toInt32(exec);
260     if (UNLIKELY(vm->exception()))
261         return JSValue::encode(JSValue());
262     uint32_t b = op2.toUInt32(exec);
263     return JSValue::encode(jsNumber(a << (b & 0x1f)));
264 }
265
266 EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
267 {
268     VM* vm = &exec->vm();
269     NativeCallFrameTracer tracer(vm, exec);
270
271     JSValue op1 = JSValue::decode(encodedOp1);
272     JSValue op2 = JSValue::decode(encodedOp2);
273
274     int32_t a = op1.toInt32(exec);
275     if (UNLIKELY(vm->exception()))
276         return JSValue::encode(JSValue());
277     uint32_t b = op2.toUInt32(exec);
278     return JSValue::encode(jsNumber(a >> (b & 0x1f)));
279 }
280
281 EncodedJSValue JIT_OPERATION operationValueBitURShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
282 {
283     VM* vm = &exec->vm();
284     NativeCallFrameTracer tracer(vm, exec);
285
286     JSValue op1 = JSValue::decode(encodedOp1);
287     JSValue op2 = JSValue::decode(encodedOp2);
288
289     uint32_t a = op1.toUInt32(exec);
290     if (UNLIKELY(vm->exception()))
291         return JSValue::encode(JSValue());
292     uint32_t b = op2.toUInt32(exec);
293     return JSValue::encode(jsNumber(static_cast<int32_t>(a >> (b & 0x1f))));
294 }
295
296 EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
297 {
298     VM* vm = &exec->vm();
299     NativeCallFrameTracer tracer(vm, exec);
300     
301     JSValue op1 = JSValue::decode(encodedOp1);
302     JSValue op2 = JSValue::decode(encodedOp2);
303     
304     ASSERT(!op1.isNumber() || !op2.isNumber());
305     
306     if (op1.isString() && !op2.isObject())
307         return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
308
309     return JSValue::encode(jsAddSlowCase(exec, op1, op2));
310 }
311
312 EncodedJSValue JIT_OPERATION operationValueDiv(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
313 {
314     VM* vm = &exec->vm();
315     NativeCallFrameTracer tracer(vm, exec);
316
317     JSValue op1 = JSValue::decode(encodedOp1);
318     JSValue op2 = JSValue::decode(encodedOp2);
319
320     double a = op1.toNumber(exec);
321     if (UNLIKELY(vm->exception()))
322         return JSValue::encode(JSValue());
323     double b = op2.toNumber(exec);
324     return JSValue::encode(jsNumber(a / b));
325 }
326
327 double JIT_OPERATION operationArithAbs(ExecState* exec, EncodedJSValue encodedOp1)
328 {
329     VM* vm = &exec->vm();
330     NativeCallFrameTracer tracer(vm, exec);
331
332     JSValue op1 = JSValue::decode(encodedOp1);
333     double a = op1.toNumber(exec);
334     if (UNLIKELY(vm->exception()))
335         return JSValue::encode(JSValue());
336     return fabs(a);
337 }
338
339 double JIT_OPERATION operationArithCos(ExecState* exec, EncodedJSValue encodedOp1)
340 {
341     VM* vm = &exec->vm();
342     NativeCallFrameTracer tracer(vm, exec);
343
344     JSValue op1 = JSValue::decode(encodedOp1);
345     double a = op1.toNumber(exec);
346     if (UNLIKELY(vm->exception()))
347         return JSValue::encode(JSValue());
348     return cos(a);
349 }
350
351 double JIT_OPERATION operationArithFRound(ExecState* exec, EncodedJSValue encodedOp1)
352 {
353     VM* vm = &exec->vm();
354     NativeCallFrameTracer tracer(vm, exec);
355
356     JSValue op1 = JSValue::decode(encodedOp1);
357     double a = op1.toNumber(exec);
358     if (UNLIKELY(vm->exception()))
359         return JSValue::encode(JSValue());
360     return static_cast<float>(a);
361 }
362
363 double JIT_OPERATION operationArithLog(ExecState* exec, EncodedJSValue encodedOp1)
364 {
365     VM* vm = &exec->vm();
366     NativeCallFrameTracer tracer(vm, exec);
367
368     JSValue op1 = JSValue::decode(encodedOp1);
369     double a = op1.toNumber(exec);
370     if (UNLIKELY(vm->exception()))
371         return JSValue::encode(JSValue());
372     return log(a);
373 }
374
375 double JIT_OPERATION operationArithSin(ExecState* exec, EncodedJSValue encodedOp1)
376 {
377     VM* vm = &exec->vm();
378     NativeCallFrameTracer tracer(vm, exec);
379
380     JSValue op1 = JSValue::decode(encodedOp1);
381     double a = op1.toNumber(exec);
382     if (UNLIKELY(vm->exception()))
383         return JSValue::encode(JSValue());
384     return sin(a);
385 }
386
387 double JIT_OPERATION operationArithSqrt(ExecState* exec, EncodedJSValue encodedOp1)
388 {
389     VM* vm = &exec->vm();
390     NativeCallFrameTracer tracer(vm, exec);
391
392     JSValue op1 = JSValue::decode(encodedOp1);
393     double a = op1.toNumber(exec);
394     if (UNLIKELY(vm->exception()))
395         return JSValue::encode(JSValue());
396     return sqrt(a);
397 }
398
399 static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
400 {
401     VM& vm = exec->vm();
402     NativeCallFrameTracer tracer(&vm, exec);
403     
404     if (base->isObject()) {
405         JSObject* object = asObject(base);
406         if (object->canGetIndexQuickly(index))
407             return JSValue::encode(object->getIndexQuickly(index));
408     }
409
410     if (isJSString(base) && asString(base)->canGetIndex(index))
411         return JSValue::encode(asString(base)->getIndex(exec, index));
412
413     return JSValue::encode(JSValue(base).get(exec, index));
414 }
415
416 EncodedJSValue JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
417 {
418     VM& vm = exec->vm();
419     NativeCallFrameTracer tracer(&vm, exec);
420     
421     JSValue baseValue = JSValue::decode(encodedBase);
422     JSValue property = JSValue::decode(encodedProperty);
423
424     if (LIKELY(baseValue.isCell())) {
425         JSCell* base = baseValue.asCell();
426
427         if (property.isUInt32()) {
428             return getByVal(exec, base, property.asUInt32());
429         } else if (property.isDouble()) {
430             double propertyAsDouble = property.asDouble();
431             uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
432             if (propertyAsUInt32 == propertyAsDouble && isIndex(propertyAsUInt32))
433                 return getByVal(exec, base, propertyAsUInt32);
434         } else if (property.isString()) {
435             Structure& structure = *base->structure(vm);
436             if (JSCell::canUseFastGetOwnProperty(structure)) {
437                 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
438                     if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
439                         return JSValue::encode(result);
440                 }
441             }
442         }
443     }
444
445     baseValue.requireObjectCoercible(exec);
446     if (vm.exception())
447         return JSValue::encode(jsUndefined());
448     auto propertyName = property.toPropertyKey(exec);
449     if (vm.exception())
450         return JSValue::encode(jsUndefined());
451     return JSValue::encode(baseValue.get(exec, propertyName));
452 }
453
454 EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
455 {
456     VM& vm = exec->vm();
457     NativeCallFrameTracer tracer(&vm, exec);
458     
459     JSValue property = JSValue::decode(encodedProperty);
460
461     if (property.isUInt32())
462         return getByVal(exec, base, property.asUInt32());
463     if (property.isDouble()) {
464         double propertyAsDouble = property.asDouble();
465         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
466         if (propertyAsUInt32 == propertyAsDouble)
467             return getByVal(exec, base, propertyAsUInt32);
468     } else if (property.isString()) {
469         Structure& structure = *base->structure(vm);
470         if (JSCell::canUseFastGetOwnProperty(structure)) {
471             if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
472                 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
473                     return JSValue::encode(result);
474             }
475         }
476     }
477
478     auto propertyName = property.toPropertyKey(exec);
479     if (vm.exception())
480         return JSValue::encode(jsUndefined());
481     return JSValue::encode(JSValue(base).get(exec, propertyName));
482 }
483
484 ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
485 {
486     VM* vm = &exec->vm();
487     NativeCallFrameTracer tracer(vm, exec);
488     
489     if (index < 0) {
490         // Go the slowest way possible becase negative indices don't use indexed storage.
491         return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
492     }
493
494     // Use this since we know that the value is out of bounds.
495     return JSValue::encode(JSValue(base).get(exec, static_cast<unsigned>(index)));
496 }
497
498 EncodedJSValue JIT_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
499 {
500     return getByValCellInt(exec, base, index);
501 }
502
503 EncodedJSValue JIT_OPERATION operationGetByValStringInt(ExecState* exec, JSString* base, int32_t index)
504 {
505     return getByValCellInt(exec, base, index);
506 }
507
508 void JIT_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
509 {
510     VM* vm = &exec->vm();
511     NativeCallFrameTracer tracer(vm, exec);
512     
513     operationPutByValInternal<true, false>(exec, encodedBase, encodedProperty, encodedValue);
514 }
515
516 void JIT_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
517 {
518     VM* vm = &exec->vm();
519     NativeCallFrameTracer tracer(vm, exec);
520     
521     operationPutByValInternal<false, false>(exec, encodedBase, encodedProperty, encodedValue);
522 }
523
524 void JIT_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
525 {
526     VM* vm = &exec->vm();
527     NativeCallFrameTracer tracer(vm, exec);
528     
529     operationPutByValInternal<true, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
530 }
531
532 void JIT_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
533 {
534     VM* vm = &exec->vm();
535     NativeCallFrameTracer tracer(vm, exec);
536     
537     operationPutByValInternal<false, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
538 }
539
540 void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
541 {
542     VM& vm = exec->vm();
543     NativeCallFrameTracer tracer(&vm, exec);
544     
545     if (index >= 0) {
546         array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
547         return;
548     }
549     
550     PutPropertySlot slot(array, true);
551     array->methodTable()->put(
552         array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
553 }
554
555 void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
556 {
557     VM* vm = &exec->vm();
558     NativeCallFrameTracer tracer(vm, exec);
559     
560     if (index >= 0) {
561         array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
562         return;
563     }
564     
565     PutPropertySlot slot(array, false);
566     array->methodTable()->put(
567         array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
568 }
569
570 void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
571 {
572     VM* vm = &exec->vm();
573     NativeCallFrameTracer tracer(vm, exec);
574     
575     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
576     
577     if (index >= 0) {
578         array->putByIndexInline(exec, index, jsValue, true);
579         return;
580     }
581     
582     PutPropertySlot slot(array, true);
583     array->methodTable()->put(
584         array, exec, Identifier::from(exec, index), jsValue, slot);
585 }
586
587 void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
588 {
589     VM* vm = &exec->vm();
590     NativeCallFrameTracer tracer(vm, exec);
591     
592     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
593     
594     if (index >= 0) {
595         array->putByIndexInline(exec, index, jsValue, false);
596         return;
597     }
598     
599     PutPropertySlot slot(array, false);
600     array->methodTable()->put(
601         array, exec, Identifier::from(exec, index), jsValue, slot);
602 }
603
604 void JIT_OPERATION operationPutByValDirectStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
605 {
606     VM* vm = &exec->vm();
607     NativeCallFrameTracer tracer(vm, exec);
608     
609     operationPutByValInternal<true, true>(exec, encodedBase, encodedProperty, encodedValue);
610 }
611
612 void JIT_OPERATION operationPutByValDirectNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
613 {
614     VM* vm = &exec->vm();
615     NativeCallFrameTracer tracer(vm, exec);
616     
617     operationPutByValInternal<false, true>(exec, encodedBase, encodedProperty, encodedValue);
618 }
619
620 void JIT_OPERATION operationPutByValDirectCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
621 {
622     VM* vm = &exec->vm();
623     NativeCallFrameTracer tracer(vm, exec);
624     
625     operationPutByValInternal<true, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
626 }
627
628 void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
629 {
630     VM* vm = &exec->vm();
631     NativeCallFrameTracer tracer(vm, exec);
632     
633     operationPutByValInternal<false, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
634 }
635
636 void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
637 {
638     VM* vm = &exec->vm();
639     NativeCallFrameTracer tracer(vm, exec);
640     if (index >= 0) {
641         array->putDirectIndex(exec, index, JSValue::decode(encodedValue), 0, PutDirectIndexShouldThrow);
642         return;
643     }
644     
645     PutPropertySlot slot(array, true);
646     array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
647 }
648
649 void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
650 {
651     VM* vm = &exec->vm();
652     NativeCallFrameTracer tracer(vm, exec);
653     
654     if (index >= 0) {
655         array->putDirectIndex(exec, index, JSValue::decode(encodedValue));
656         return;
657     }
658     
659     PutPropertySlot slot(array, false);
660     array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
661 }
662
663 EncodedJSValue JIT_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
664 {
665     VM* vm = &exec->vm();
666     NativeCallFrameTracer tracer(vm, exec);
667     
668     array->push(exec, JSValue::decode(encodedValue));
669     return JSValue::encode(jsNumber(array->length()));
670 }
671
672 EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
673 {
674     VM* vm = &exec->vm();
675     NativeCallFrameTracer tracer(vm, exec);
676     
677     array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
678     return JSValue::encode(jsNumber(array->length()));
679 }
680
681 EncodedJSValue JIT_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
682 {
683     VM* vm = &exec->vm();
684     NativeCallFrameTracer tracer(vm, exec);
685     
686     return JSValue::encode(array->pop(exec));
687 }
688         
689 EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
690 {
691     VM* vm = &exec->vm();
692     NativeCallFrameTracer tracer(vm, exec);
693     
694     array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
695     
696     return JSValue::encode(array->pop(exec));
697 }
698         
699 EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* argument)
700 {
701     SuperSamplerScope superSamplerScope(false);
702     
703     VM& vm = globalObject->vm();
704     NativeCallFrameTracer tracer(&vm, exec);
705     
706     return JSValue::encode(regExpObject->execInline(exec, globalObject, argument));
707 }
708         
709 EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
710 {
711     SuperSamplerScope superSamplerScope(false);
712     
713     VM& vm = globalObject->vm();
714     NativeCallFrameTracer tracer(&vm, exec);
715     
716     JSValue argument = JSValue::decode(encodedArgument);
717
718     JSString* input = argument.toStringOrNull(exec);
719     if (!input)
720         return JSValue::encode(jsUndefined());
721     return JSValue::encode(regExpObject->execInline(exec, globalObject, input));
722 }
723         
724 EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
725 {
726     SuperSamplerScope superSamplerScope(false);
727     
728     VM& vm = globalObject->vm();
729     NativeCallFrameTracer tracer(&vm, exec);
730     auto scope = DECLARE_THROW_SCOPE(vm);
731
732     JSValue base = JSValue::decode(encodedBase);
733     JSValue argument = JSValue::decode(encodedArgument);
734     
735     if (!base.inherits(RegExpObject::info()))
736         return throwVMTypeError(exec, scope);
737
738     JSString* input = argument.toStringOrNull(exec);
739     if (!input)
740         return JSValue::encode(jsUndefined());
741     return JSValue::encode(asRegExpObject(base)->exec(exec, globalObject, input));
742 }
743         
744 size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* input)
745 {
746     SuperSamplerScope superSamplerScope(false);
747     
748     VM& vm = globalObject->vm();
749     NativeCallFrameTracer tracer(&vm, exec);
750
751     return regExpObject->testInline(exec, globalObject, input);
752 }
753
754 size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
755 {
756     SuperSamplerScope superSamplerScope(false);
757     
758     VM& vm = globalObject->vm();
759     NativeCallFrameTracer tracer(&vm, exec);
760
761     JSValue argument = JSValue::decode(encodedArgument);
762
763     JSString* input = argument.toStringOrNull(exec);
764     if (!input)
765         return false;
766     return regExpObject->testInline(exec, globalObject, input);
767 }
768
769 size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
770 {
771     SuperSamplerScope superSamplerScope(false);
772     
773     VM& vm = globalObject->vm();
774     NativeCallFrameTracer tracer(&vm, exec);
775     auto scope = DECLARE_THROW_SCOPE(vm);
776
777     JSValue base = JSValue::decode(encodedBase);
778     JSValue argument = JSValue::decode(encodedArgument);
779
780     if (!base.inherits(RegExpObject::info())) {
781         throwTypeError(exec, scope);
782         return false;
783     }
784
785     JSString* input = argument.toStringOrNull(exec);
786     if (!input)
787         return false;
788     return asRegExpObject(base)->test(exec, globalObject, input);
789 }
790
791 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
792 {
793     VM* vm = &exec->vm();
794     NativeCallFrameTracer tracer(vm, exec);
795     
796     JSValue op1 = JSValue::decode(encodedOp1);
797     JSValue op2 = JSValue::decode(encodedOp2);
798     
799     ASSERT(op1.isCell());
800     ASSERT(op2.isCell());
801     
802     return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
803 }
804
805 size_t JIT_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
806 {
807     VM* vm = &exec->vm();
808     NativeCallFrameTracer tracer(vm, exec);
809
810     JSValue src1 = JSValue::decode(encodedOp1);
811     JSValue src2 = JSValue::decode(encodedOp2);
812     
813     return JSValue::strictEqual(exec, src1, src2);
814 }
815
816 EncodedJSValue JIT_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
817 {
818     VM* vm = &exec->vm();
819     NativeCallFrameTracer tracer(vm, exec);
820     
821     return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
822 }
823
824 EncodedJSValue JIT_OPERATION operationToNumber(ExecState* exec, EncodedJSValue value)
825 {
826     VM* vm = &exec->vm();
827     NativeCallFrameTracer tracer(vm, exec);
828
829     return JSValue::encode(jsNumber(JSValue::decode(value).toNumber(exec)));
830 }
831
832 EncodedJSValue JIT_OPERATION operationGetByIdWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, UniquedStringImpl* impl)
833 {
834     VM& vm = exec->vm();
835     NativeCallFrameTracer tracer(&vm, exec);
836
837     JSValue baseValue = JSValue::decode(encodedBase);
838     JSValue thisVal = JSValue::decode(encodedThis);
839     PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
840     JSValue result = baseValue.get(exec, Identifier::fromUid(exec, impl), slot);
841     return JSValue::encode(result);
842 }
843
844 EncodedJSValue JIT_OPERATION operationGetByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript)
845 {
846     VM& vm = exec->vm();
847     NativeCallFrameTracer tracer(&vm, exec);
848
849     JSValue baseValue = JSValue::decode(encodedBase);
850     JSValue thisVal = JSValue::decode(encodedThis);
851     JSValue subscript = JSValue::decode(encodedSubscript);
852
853     if (LIKELY(baseValue.isCell() && subscript.isString())) {
854         Structure& structure = *baseValue.asCell()->structure(vm);
855         if (JSCell::canUseFastGetOwnProperty(structure)) {
856             if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
857                 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
858                     return JSValue::encode(result);
859             }
860         }
861     }
862     
863     PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
864     if (subscript.isUInt32()) {
865         uint32_t i = subscript.asUInt32();
866         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
867             return JSValue::encode(asString(baseValue)->getIndex(exec, i));
868         
869         return JSValue::encode(baseValue.get(exec, i, slot));
870     }
871
872     baseValue.requireObjectCoercible(exec);
873     if (vm.exception())
874         return JSValue::encode(JSValue());
875
876     auto property = subscript.toPropertyKey(exec);
877     if (vm.exception())
878         return JSValue::encode(JSValue());
879     return JSValue::encode(baseValue.get(exec, property, slot));
880 }
881
882 void JIT_OPERATION operationPutByIdWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
883 {
884     VM& vm = exec->vm();
885     NativeCallFrameTracer tracer(&vm, exec);
886
887     putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
888 }
889
890 void JIT_OPERATION operationPutByIdWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
891 {
892     VM& vm = exec->vm();
893     NativeCallFrameTracer tracer(&vm, exec);
894
895     putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
896 }
897
898 void JIT_OPERATION operationPutByValWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
899 {
900     VM& vm = exec->vm();
901     NativeCallFrameTracer tracer(&vm, exec);
902
903     Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
904     if (vm.exception())
905         return;
906     putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, property);
907 }
908
909 void JIT_OPERATION operationPutByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
910 {
911     VM& vm = exec->vm();
912     NativeCallFrameTracer tracer(&vm, exec);
913
914     Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
915     if (vm.exception())
916         return;
917     putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, property);
918 }
919
920 char* JIT_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
921 {
922     VM* vm = &exec->vm();
923     NativeCallFrameTracer tracer(vm, exec);
924     
925     return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
926 }
927
928 char* JIT_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
929 {
930     VM* vm = &exec->vm();
931     NativeCallFrameTracer tracer(vm, exec);
932     
933     return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
934 }
935
936 char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size, Butterfly* butterfly)
937 {
938     VM& vm = exec->vm();
939     NativeCallFrameTracer tracer(&vm, exec);
940     auto scope = DECLARE_THROW_SCOPE(vm);
941
942     if (UNLIKELY(size < 0))
943         return bitwise_cast<char*>(throwException(exec, scope, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
944
945     JSArray* result;
946     if (butterfly)
947         result = JSArray::createWithButterfly(vm, arrayStructure, butterfly);
948     else
949         result = JSArray::create(vm, arrayStructure, size);
950     return bitwise_cast<char*>(result);
951 }
952
953 char* JIT_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
954 {
955     VM& vm = exec->vm();
956     NativeCallFrameTracer tracer(&vm, exec);
957     return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
958 }
959
960 char* JIT_OPERATION operationNewInt8ArrayWithSize(
961     ExecState* exec, Structure* structure, int32_t length)
962 {
963     return newTypedArrayWithSize<JSInt8Array>(exec, structure, length);
964 }
965
966 char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
967     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
968 {
969     VM& vm = exec->vm();
970     NativeCallFrameTracer tracer(&vm, exec);
971     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt8Array>(exec, structure, encodedValue, 0, Nullopt));
972 }
973
974 char* JIT_OPERATION operationNewInt16ArrayWithSize(
975     ExecState* exec, Structure* structure, int32_t length)
976 {
977     return newTypedArrayWithSize<JSInt16Array>(exec, structure, length);
978 }
979
980 char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
981     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
982 {
983     VM& vm = exec->vm();
984     NativeCallFrameTracer tracer(&vm, exec);
985     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt16Array>(exec, structure, encodedValue, 0, Nullopt));
986 }
987
988 char* JIT_OPERATION operationNewInt32ArrayWithSize(
989     ExecState* exec, Structure* structure, int32_t length)
990 {
991     return newTypedArrayWithSize<JSInt32Array>(exec, structure, length);
992 }
993
994 char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
995     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
996 {
997     VM& vm = exec->vm();
998     NativeCallFrameTracer tracer(&vm, exec);
999     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt32Array>(exec, structure, encodedValue, 0, Nullopt));
1000 }
1001
1002 char* JIT_OPERATION operationNewUint8ArrayWithSize(
1003     ExecState* exec, Structure* structure, int32_t length)
1004 {
1005     return newTypedArrayWithSize<JSUint8Array>(exec, structure, length);
1006 }
1007
1008 char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
1009     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1010 {
1011     VM& vm = exec->vm();
1012     NativeCallFrameTracer tracer(&vm, exec);
1013     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8Array>(exec, structure, encodedValue, 0, Nullopt));
1014 }
1015
1016 char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(
1017     ExecState* exec, Structure* structure, int32_t length)
1018 {
1019     return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length);
1020 }
1021
1022 char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
1023     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1024 {
1025     VM& vm = exec->vm();
1026     NativeCallFrameTracer tracer(&vm, exec);
1027     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8ClampedArray>(exec, structure, encodedValue, 0, Nullopt));
1028 }
1029
1030 char* JIT_OPERATION operationNewUint16ArrayWithSize(
1031     ExecState* exec, Structure* structure, int32_t length)
1032 {
1033     return newTypedArrayWithSize<JSUint16Array>(exec, structure, length);
1034 }
1035
1036 char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
1037     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1038 {
1039     VM& vm = exec->vm();
1040     NativeCallFrameTracer tracer(&vm, exec);
1041     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint16Array>(exec, structure, encodedValue, 0, Nullopt));
1042 }
1043
1044 char* JIT_OPERATION operationNewUint32ArrayWithSize(
1045     ExecState* exec, Structure* structure, int32_t length)
1046 {
1047     return newTypedArrayWithSize<JSUint32Array>(exec, structure, length);
1048 }
1049
1050 char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
1051     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1052 {
1053     VM& vm = exec->vm();
1054     NativeCallFrameTracer tracer(&vm, exec);
1055     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint32Array>(exec, structure, encodedValue, 0, Nullopt));
1056 }
1057
1058 char* JIT_OPERATION operationNewFloat32ArrayWithSize(
1059     ExecState* exec, Structure* structure, int32_t length)
1060 {
1061     return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length);
1062 }
1063
1064 char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
1065     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1066 {
1067     VM& vm = exec->vm();
1068     NativeCallFrameTracer tracer(&vm, exec);
1069     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat32Array>(exec, structure, encodedValue, 0, Nullopt));
1070 }
1071
1072 char* JIT_OPERATION operationNewFloat64ArrayWithSize(
1073     ExecState* exec, Structure* structure, int32_t length)
1074 {
1075     return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length);
1076 }
1077
1078 char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
1079     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1080 {
1081     VM& vm = exec->vm();
1082     NativeCallFrameTracer tracer(&vm, exec);
1083     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat64Array>(exec, structure, encodedValue, 0, Nullopt));
1084 }
1085
1086 JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table, EncodedJSValue initialValueEncoded)
1087 {
1088     JSValue initialValue = JSValue::decode(initialValueEncoded);
1089     ASSERT(initialValue == jsUndefined() || initialValue == jsTDZValue());
1090     VM& vm = exec->vm();
1091     NativeCallFrameTracer tracer(&vm, exec);
1092     return JSLexicalEnvironment::create(vm, structure, scope, table, initialValue);
1093 }
1094
1095 JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, int32_t length, int32_t minCapacity)
1096 {
1097     VM& vm = exec->vm();
1098     NativeCallFrameTracer target(&vm, exec);
1099     DirectArguments* result = DirectArguments::create(
1100         vm, structure, length, std::max(length, minCapacity));
1101     // The caller will store to this object without barriers. Most likely, at this point, this is
1102     // still a young object and so no barriers are needed. But it's good to be careful anyway,
1103     // since the GC should be allowed to do crazy (like pretenuring, for example).
1104     vm.heap.writeBarrier(result);
1105     return result;
1106 }
1107
1108 JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
1109 {
1110     VM& vm = exec->vm();
1111     NativeCallFrameTracer target(&vm, exec);
1112     
1113     // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
1114     // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
1115     ScopedArgumentsTable* table = scope->symbolTable()->arguments();
1116     
1117     return ScopedArguments::createByCopyingFrom(
1118         vm, structure, argumentStart, length, callee, table, scope);
1119 }
1120
1121 JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee)
1122 {
1123     VM& vm = exec->vm();
1124     NativeCallFrameTracer target(&vm, exec);
1125     return ClonedArguments::createByCopyingFrom(
1126         exec, structure, argumentStart, length, callee);
1127 }
1128
1129 JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
1130 {
1131     VM& vm = exec->vm();
1132     NativeCallFrameTracer target(&vm, exec);
1133     
1134     DeferGCForAWhile deferGC(vm.heap);
1135     
1136     CodeBlock* codeBlock;
1137     if (inlineCallFrame)
1138         codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1139     else
1140         codeBlock = exec->codeBlock();
1141     
1142     unsigned length = argumentCount - 1;
1143     unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
1144     DirectArguments* result = DirectArguments::create(
1145         vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
1146     
1147     result->callee().set(vm, result, callee);
1148     
1149     Register* arguments =
1150         exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1151         CallFrame::argumentOffset(0);
1152     for (unsigned i = length; i--;)
1153         result->setIndexQuickly(vm, i, arguments[i].jsValue());
1154     
1155     return result;
1156 }
1157
1158 JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
1159 {
1160     VM& vm = exec->vm();
1161     NativeCallFrameTracer target(&vm, exec);
1162     
1163     DeferGCForAWhile deferGC(vm.heap);
1164     
1165     CodeBlock* codeBlock;
1166     if (inlineCallFrame)
1167         codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1168     else
1169         codeBlock = exec->codeBlock();
1170     
1171     unsigned length = argumentCount - 1;
1172     ClonedArguments* result = ClonedArguments::createEmpty(
1173         vm, codeBlock->globalObject()->clonedArgumentsStructure(), callee, length);
1174     
1175     Register* arguments =
1176         exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1177         CallFrame::argumentOffset(0);
1178     for (unsigned i = length; i--;)
1179         result->initializeIndex(vm, i, arguments[i].jsValue());
1180
1181     
1182     return result;
1183 }
1184
1185 JSCell* JIT_OPERATION operationCreateRest(ExecState* exec, Register* argumentStart, unsigned numberOfParamsToSkip, unsigned arraySize)
1186 {
1187     VM* vm = &exec->vm();
1188     NativeCallFrameTracer tracer(vm, exec);
1189
1190     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
1191     Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
1192     static_assert(sizeof(Register) == sizeof(JSValue), "This is a strong assumption here.");
1193     JSValue* argumentsToCopyRegion = bitwise_cast<JSValue*>(argumentStart) + numberOfParamsToSkip;
1194     return constructArray(exec, structure, argumentsToCopyRegion, arraySize);
1195 }
1196
1197 size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1198 {
1199     VM& vm = exec->vm();
1200     NativeCallFrameTracer tracer(&vm, exec);
1201
1202     ASSERT(jsDynamicCast<JSObject*>(object));
1203     
1204     if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1205         return false;
1206     if (object->type() == JSFunctionType)
1207         return false;
1208     if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1209         CallData callData;
1210         if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
1211             return false;
1212     }
1213     
1214     return true;
1215 }
1216
1217 size_t JIT_OPERATION operationObjectIsFunction(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1218 {
1219     VM& vm = exec->vm();
1220     NativeCallFrameTracer tracer(&vm, exec);
1221
1222     ASSERT(jsDynamicCast<JSObject*>(object));
1223     
1224     if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1225         return false;
1226     if (object->type() == JSFunctionType)
1227         return true;
1228     if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1229         CallData callData;
1230         if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
1231             return true;
1232     }
1233     
1234     return false;
1235 }
1236
1237 JSCell* JIT_OPERATION operationTypeOfObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1238 {
1239     VM& vm = exec->vm();
1240     NativeCallFrameTracer tracer(&vm, exec);
1241
1242     ASSERT(jsDynamicCast<JSObject*>(object));
1243     
1244     if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1245         return vm.smallStrings.undefinedString();
1246     if (object->type() == JSFunctionType)
1247         return vm.smallStrings.functionString();
1248     if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1249         CallData callData;
1250         if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
1251             return vm.smallStrings.functionString();
1252     }
1253     
1254     return vm.smallStrings.objectString();
1255 }
1256
1257 int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1258 {
1259     VM& vm = exec->vm();
1260     NativeCallFrameTracer tracer(&vm, exec);
1261
1262     ASSERT(jsDynamicCast<JSObject*>(object));
1263     
1264     if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1265         return static_cast<int32_t>(TypeofType::Undefined);
1266     if (object->type() == JSFunctionType)
1267         return static_cast<int32_t>(TypeofType::Function);
1268     if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1269         CallData callData;
1270         if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
1271             return static_cast<int32_t>(TypeofType::Function);
1272     }
1273     
1274     return static_cast<int32_t>(TypeofType::Object);
1275 }
1276
1277 char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
1278 {
1279     VM& vm = exec->vm();
1280     NativeCallFrameTracer tracer(&vm, exec);
1281
1282     return reinterpret_cast<char*>(
1283         Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
1284 }
1285
1286 char* JIT_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
1287 {
1288     VM& vm = exec->vm();
1289     NativeCallFrameTracer tracer(&vm, exec);
1290
1291     return reinterpret_cast<char*>(
1292         Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
1293 }
1294
1295 char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
1296 {
1297     VM& vm = exec->vm();
1298     NativeCallFrameTracer tracer(&vm, exec);
1299     
1300     if (!cell->isObject())
1301         return 0;
1302     
1303     return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
1304 }
1305
1306 char* JIT_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
1307 {
1308     VM& vm = exec->vm();
1309     NativeCallFrameTracer tracer(&vm, exec);
1310     
1311     if (!cell->isObject())
1312         return 0;
1313     
1314     return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
1315 }
1316
1317 char* JIT_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
1318 {
1319     VM& vm = exec->vm();
1320     NativeCallFrameTracer tracer(&vm, exec);
1321     
1322     if (!cell->isObject())
1323         return 0;
1324     
1325     return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
1326 }
1327
1328 char* JIT_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
1329 {
1330     VM& vm = exec->vm();
1331     NativeCallFrameTracer tracer(&vm, exec);
1332     
1333     if (!cell->isObject())
1334         return 0;
1335
1336     return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
1337 }
1338
1339 StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
1340 {
1341     VM& vm = exec->vm();
1342     NativeCallFrameTracer tracer(&vm, exec);
1343
1344     return string->value(exec).impl();
1345 }
1346
1347 JSString* JIT_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
1348 {
1349     VM& vm = exec->vm();
1350     NativeCallFrameTracer tracer(&vm, exec);
1351     
1352     return jsSingleCharacterString(exec, static_cast<UChar>(character));
1353 }
1354
1355 JSCell* JIT_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
1356 {
1357     VM& vm = exec->vm();
1358     NativeCallFrameTracer tracer(&vm, exec);
1359     
1360     return StringObject::create(vm, structure, string);
1361 }
1362
1363 JSCell* JIT_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
1364 {
1365     VM& vm = exec->vm();
1366     NativeCallFrameTracer tracer(&vm, exec);
1367     
1368     return JSValue(cell).toString(exec);
1369 }
1370
1371 JSCell* JIT_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
1372 {
1373     VM& vm = exec->vm();
1374     NativeCallFrameTracer tracer(&vm, exec);
1375
1376     return JSValue::decode(value).toString(exec);
1377 }
1378
1379 JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState* exec, JSCell* cell)
1380 {
1381     VM& vm = exec->vm();
1382     NativeCallFrameTracer tracer(&vm, exec);
1383
1384     return stringConstructor(exec, cell);
1385 }
1386
1387 JSCell* JIT_OPERATION operationCallStringConstructor(ExecState* exec, EncodedJSValue value)
1388 {
1389     VM& vm = exec->vm();
1390     NativeCallFrameTracer tracer(&vm, exec);
1391
1392     return stringConstructor(exec, JSValue::decode(value));
1393 }
1394
1395 JSCell* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
1396 {
1397     VM& vm = exec->vm();
1398     NativeCallFrameTracer tracer(&vm, exec);
1399     auto scope = DECLARE_THROW_SCOPE(vm);
1400
1401     if (sumOverflows<int32_t>(left->length(), right->length())) {
1402         throwOutOfMemoryError(exec, scope);
1403         return nullptr;
1404     }
1405
1406     return JSRopeString::create(vm, left, right);
1407 }
1408
1409 JSCell* JIT_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
1410 {
1411     VM& vm = exec->vm();
1412     NativeCallFrameTracer tracer(&vm, exec);
1413     auto scope = DECLARE_THROW_SCOPE(vm);
1414
1415     if (sumOverflows<int32_t>(a->length(), b->length(), c->length())) {
1416         throwOutOfMemoryError(exec, scope);
1417         return nullptr;
1418     }
1419
1420     return JSRopeString::create(vm, a, b, c);
1421 }
1422
1423 JSCell* JIT_OPERATION operationStrCat2(ExecState* exec, EncodedJSValue a, EncodedJSValue b)
1424 {
1425     VM& vm = exec->vm();
1426     NativeCallFrameTracer tracer(&vm, exec);
1427     auto scope = DECLARE_THROW_SCOPE(vm);
1428
1429     JSString* str1 = JSValue::decode(a).toString(exec);
1430     ASSERT(!vm.exception()); // Impossible, since we must have been given primitives.
1431     JSString* str2 = JSValue::decode(b).toString(exec);
1432     ASSERT(!vm.exception());
1433
1434     if (sumOverflows<int32_t>(str1->length(), str2->length())) {
1435         throwOutOfMemoryError(exec, scope);
1436         return nullptr;
1437     }
1438
1439     return JSRopeString::create(vm, str1, str2);
1440 }
1441     
1442 JSCell* JIT_OPERATION operationStrCat3(ExecState* exec, EncodedJSValue a, EncodedJSValue b, EncodedJSValue c)
1443 {
1444     VM& vm = exec->vm();
1445     NativeCallFrameTracer tracer(&vm, exec);
1446     auto scope = DECLARE_THROW_SCOPE(vm);
1447
1448     JSString* str1 = JSValue::decode(a).toString(exec);
1449     ASSERT(!vm.exception()); // Impossible, since we must have been given primitives.
1450     JSString* str2 = JSValue::decode(b).toString(exec);
1451     ASSERT(!vm.exception());
1452     JSString* str3 = JSValue::decode(c).toString(exec);
1453     ASSERT(!vm.exception());
1454
1455     if (sumOverflows<int32_t>(str1->length(), str2->length(), str3->length())) {
1456         throwOutOfMemoryError(exec, scope);
1457         return nullptr;
1458     }
1459
1460     return JSRopeString::create(vm, str1, str2, str3);
1461 }
1462
1463 char* JIT_OPERATION operationFindSwitchImmTargetForDouble(
1464     ExecState* exec, EncodedJSValue encodedValue, size_t tableIndex)
1465 {
1466     VM& vm = exec->vm();
1467     NativeCallFrameTracer tracer(&vm, exec);
1468
1469     CodeBlock* codeBlock = exec->codeBlock();
1470     SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
1471     JSValue value = JSValue::decode(encodedValue);
1472     ASSERT(value.isDouble());
1473     double asDouble = value.asDouble();
1474     int32_t asInt32 = static_cast<int32_t>(asDouble);
1475     if (asDouble == asInt32)
1476         return static_cast<char*>(table.ctiForValue(asInt32).executableAddress());
1477     return static_cast<char*>(table.ctiDefault.executableAddress());
1478 }
1479
1480 char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
1481 {
1482     VM& vm = exec->vm();
1483     NativeCallFrameTracer tracer(&vm, exec);
1484
1485     return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
1486 }
1487
1488 int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
1489 {
1490     VM& vm = exec->vm();
1491     NativeCallFrameTracer tracer(&vm, exec);
1492
1493     return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(string->value(exec).impl(), std::numeric_limits<int32_t>::min());
1494 }
1495
1496 uintptr_t JIT_OPERATION operationCompareStringImplLess(StringImpl* a, StringImpl* b)
1497 {
1498     return codePointCompare(a, b) < 0;
1499 }
1500
1501 uintptr_t JIT_OPERATION operationCompareStringImplLessEq(StringImpl* a, StringImpl* b)
1502 {
1503     return codePointCompare(a, b) <= 0;
1504 }
1505
1506 uintptr_t JIT_OPERATION operationCompareStringImplGreater(StringImpl* a, StringImpl* b)
1507 {
1508     return codePointCompare(a, b) > 0;
1509 }
1510
1511 uintptr_t JIT_OPERATION operationCompareStringImplGreaterEq(StringImpl* a, StringImpl* b)
1512 {
1513     return codePointCompare(a, b) >= 0;
1514 }
1515
1516 uintptr_t JIT_OPERATION operationCompareStringLess(ExecState* exec, JSString* a, JSString* b)
1517 {
1518     VM& vm = exec->vm();
1519     NativeCallFrameTracer tracer(&vm, exec);
1520
1521     return codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
1522 }
1523
1524 uintptr_t JIT_OPERATION operationCompareStringLessEq(ExecState* exec, JSString* a, JSString* b)
1525 {
1526     VM& vm = exec->vm();
1527     NativeCallFrameTracer tracer(&vm, exec);
1528
1529     return !codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
1530 }
1531
1532 uintptr_t JIT_OPERATION operationCompareStringGreater(ExecState* exec, JSString* a, JSString* b)
1533 {
1534     VM& vm = exec->vm();
1535     NativeCallFrameTracer tracer(&vm, exec);
1536
1537     return codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
1538 }
1539
1540 uintptr_t JIT_OPERATION operationCompareStringGreaterEq(ExecState* exec, JSString* a, JSString* b)
1541 {
1542     VM& vm = exec->vm();
1543     NativeCallFrameTracer tracer(&vm, exec);
1544
1545     return !codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
1546 }
1547
1548 void JIT_OPERATION operationNotifyWrite(ExecState* exec, WatchpointSet* set)
1549 {
1550     VM& vm = exec->vm();
1551     NativeCallFrameTracer tracer(&vm, exec);
1552
1553     set->touch(vm, "Executed NotifyWrite");
1554 }
1555
1556 void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
1557 {
1558     VM& vm = exec->vm();
1559     NativeCallFrameTracer tracer(&vm, exec);
1560     auto scope = DECLARE_THROW_SCOPE(vm);
1561     throwStackOverflowError(exec, scope);
1562 }
1563
1564 int32_t JIT_OPERATION operationSizeOfVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
1565 {
1566     VM& vm = exec->vm();
1567     NativeCallFrameTracer tracer(&vm, exec);
1568     JSValue arguments = JSValue::decode(encodedArguments);
1569     
1570     return sizeOfVarargs(exec, arguments, firstVarArgOffset);
1571 }
1572
1573 void JIT_OPERATION operationLoadVarargs(ExecState* exec, int32_t firstElementDest, EncodedJSValue encodedArguments, int32_t offset, int32_t length, int32_t mandatoryMinimum)
1574 {
1575     VM& vm = exec->vm();
1576     NativeCallFrameTracer tracer(&vm, exec);
1577     JSValue arguments = JSValue::decode(encodedArguments);
1578     
1579     loadVarargs(exec, VirtualRegister(firstElementDest), arguments, offset, length);
1580     
1581     for (int32_t i = length; i < mandatoryMinimum; ++i)
1582         exec->r(firstElementDest + i) = jsUndefined();
1583 }
1584
1585 double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
1586 {
1587     return fmod(a, b);
1588 }
1589
1590 #if USE(JSVALUE32_64)
1591 double JIT_OPERATION operationRandom(JSGlobalObject* globalObject)
1592 {
1593     return globalObject->weakRandomNumber();
1594 }
1595 #endif
1596
1597 JSCell* JIT_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
1598 {
1599     VM* vm = &exec->vm();
1600     NativeCallFrameTracer tracer(vm, exec);
1601     return JSC::stringFromCharCode(exec, op1);
1602 }
1603
1604 EncodedJSValue JIT_OPERATION operationStringFromCharCodeUntyped(ExecState* exec, EncodedJSValue encodedValue)
1605 {
1606     VM* vm = &exec->vm();
1607     NativeCallFrameTracer tracer(vm, exec);
1608     JSValue charValue = JSValue::decode(encodedValue);
1609     int32_t chInt = charValue.toUInt32(exec);
1610     return JSValue::encode(JSC::stringFromCharCode(exec, chInt));
1611 }
1612
1613 int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue encodedValue)
1614 {
1615     JSValue value = JSValue::decode(encodedValue);
1616     if (!value.isDouble())
1617         return JSValue::notInt52;
1618     return tryConvertToInt52(value.asDouble());
1619 }
1620
1621 int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
1622 {
1623     return tryConvertToInt52(value);
1624 }
1625
1626 size_t JIT_OPERATION operationDefaultHasInstance(ExecState* exec, JSCell* value, JSCell* proto) // Returns jsBoolean(True|False) on 64-bit.
1627 {
1628     VM* vm = &exec->vm();
1629     NativeCallFrameTracer tracer(vm, exec);
1630     if (JSObject::defaultHasInstance(exec, value, proto))
1631         return 1;
1632     return 0;
1633 }
1634
1635 char* JIT_OPERATION operationNewRawObject(ExecState* exec, Structure* structure, int32_t length, Butterfly* butterfly)
1636 {
1637     VM& vm = exec->vm();
1638     NativeCallFrameTracer tracer(&vm, exec);
1639
1640     if (!butterfly
1641         && (structure->outOfLineCapacity() || hasIndexedProperties(structure->indexingType()))) {
1642         IndexingHeader header;
1643         header.setVectorLength(length);
1644         header.setPublicLength(0);
1645         
1646         butterfly = Butterfly::create(
1647             vm, nullptr, 0, structure->outOfLineCapacity(),
1648             hasIndexedProperties(structure->indexingType()), header,
1649             length * sizeof(EncodedJSValue));
1650     }
1651
1652     JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
1653     result->butterfly(); // Ensure that the butterfly is in to-space.
1654     return bitwise_cast<char*>(result);
1655 }
1656
1657 JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure, Butterfly* butterfly)
1658 {
1659     VM& vm = exec->vm();
1660     NativeCallFrameTracer tracer(&vm, exec);
1661     
1662     if (!butterfly) {
1663         butterfly = Butterfly::create(
1664             vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0);
1665     }
1666     
1667     JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
1668     result->butterfly(); // Ensure that the butterfly is in to-space.
1669     return result;
1670 }
1671
1672 JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(ExecState* exec, Structure* structure, unsigned length, Butterfly* butterfly)
1673 {
1674     VM& vm = exec->vm();
1675     NativeCallFrameTracer tracer(&vm, exec);
1676
1677     IndexingHeader header;
1678     header.setVectorLength(length);
1679     header.setPublicLength(0);
1680     if (butterfly)
1681         *butterfly->indexingHeader() = header;
1682     else {
1683         butterfly = Butterfly::create(
1684             vm, nullptr, 0, structure->outOfLineCapacity(), true, header,
1685             sizeof(EncodedJSValue) * length);
1686     }
1687     
1688     // Paradoxically this may allocate a JSArray. That's totally cool.
1689     JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
1690     result->butterfly(); // Ensure that the butterfly is in to-space.
1691     return result;
1692 }
1693
1694 void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec) 
1695 {
1696     VM& vm = exec->vm();
1697     NativeCallFrameTracer tracer(&vm, exec);
1698
1699     vm.typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside DFG."));
1700 }
1701
1702 void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
1703 {
1704     VM* vm = &exec->vm();
1705     NativeCallFrameTracer tracer(vm, exec);
1706     
1707     SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
1708     CodeBlock* codeBlock = debugInfo->codeBlock;
1709     CodeBlock* alternative = codeBlock->alternative();
1710     dataLog("Speculation failure in ", *codeBlock);
1711     dataLog(" @ exit #", vm->osrExitIndex, " (bc#", debugInfo->bytecodeOffset, ", ", exitKindToString(debugInfo->kind), ") with ");
1712     if (alternative) {
1713         dataLog(
1714             "executeCounter = ", alternative->jitExecuteCounter(),
1715             ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1716             ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1717     } else
1718         dataLog("no alternative code block (i.e. we've been jettisoned)");
1719     dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
1720     dataLog("    GPRs at time of exit:");
1721     char* scratchPointer = static_cast<char*>(scratch);
1722     for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1723         GPRReg gpr = GPRInfo::toRegister(i);
1724         dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
1725         scratchPointer += sizeof(EncodedJSValue);
1726     }
1727     dataLog("\n");
1728     dataLog("    FPRs at time of exit:");
1729     for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1730         FPRReg fpr = FPRInfo::toRegister(i);
1731         dataLog(" ", FPRInfo::debugName(fpr), ":");
1732         uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1733         double value = *reinterpret_cast_ptr<double*>(scratchPointer);
1734         dataLogF("%llx:%lf", static_cast<long long>(bits), value);
1735         scratchPointer += sizeof(EncodedJSValue);
1736     }
1737     dataLog("\n");
1738 }
1739
1740 JSCell* JIT_OPERATION operationResolveScope(ExecState* exec, JSScope* scope, UniquedStringImpl* impl)
1741 {
1742     VM& vm = exec->vm();
1743     NativeCallFrameTracer tracer(&vm, exec);
1744
1745     JSObject* resolvedScope = JSScope::resolve(exec, scope, Identifier::fromUid(exec, impl));
1746     return resolvedScope;
1747 }
1748
1749 EncodedJSValue JIT_OPERATION operationGetDynamicVar(ExecState* exec, JSObject* scope, UniquedStringImpl* impl, unsigned getPutInfoBits)
1750 {
1751     VM& vm = exec->vm();
1752     NativeCallFrameTracer tracer(&vm, exec);
1753     auto throwScope = DECLARE_THROW_SCOPE(vm);
1754
1755     Identifier ident = Identifier::fromUid(exec, impl);
1756     return JSValue::encode(scope->getPropertySlot(exec, ident, [&] (bool found, PropertySlot& slot) -> JSValue {
1757         if (!found) {
1758             GetPutInfo getPutInfo(getPutInfoBits);
1759             if (getPutInfo.resolveMode() == ThrowIfNotFound)
1760                 throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
1761             return jsUndefined();
1762         }
1763
1764         if (scope->isGlobalLexicalEnvironment()) {
1765             // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1766             JSValue result = slot.getValue(exec, ident);
1767             if (result == jsTDZValue()) {
1768                 throwException(exec, throwScope, createTDZError(exec));
1769                 return jsUndefined();
1770             }
1771             return result;
1772         }
1773
1774         return slot.getValue(exec, ident);
1775     }));
1776 }
1777
1778 void JIT_OPERATION operationPutDynamicVar(ExecState* exec, JSObject* scope, EncodedJSValue value, UniquedStringImpl* impl, unsigned getPutInfoBits)
1779 {
1780     VM& vm = exec->vm();
1781     NativeCallFrameTracer tracer(&vm, exec);
1782     auto throwScope = DECLARE_THROW_SCOPE(vm);
1783
1784     const Identifier& ident = Identifier::fromUid(exec, impl);
1785     GetPutInfo getPutInfo(getPutInfoBits);
1786     bool hasProperty = scope->hasProperty(exec, ident);
1787     if (hasProperty
1788         && scope->isGlobalLexicalEnvironment()
1789         && !isInitialization(getPutInfo.initializationMode())) {
1790         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1791         PropertySlot slot(scope, PropertySlot::InternalMethodType::Get);
1792         JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
1793         if (slot.getValue(exec, ident) == jsTDZValue()) {
1794             throwException(exec, throwScope, createTDZError(exec));
1795             return;
1796         }
1797     }
1798
1799     if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty) {
1800         throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
1801         return;
1802     }
1803
1804     CodeOrigin origin = exec->codeOrigin();
1805     bool strictMode;
1806     if (origin.inlineCallFrame)
1807         strictMode = origin.inlineCallFrame->baselineCodeBlock->isStrictMode();
1808     else
1809         strictMode = exec->codeBlock()->isStrictMode();
1810     PutPropertySlot slot(scope, strictMode, PutPropertySlot::UnknownContext, isInitialization(getPutInfo.initializationMode()));
1811     scope->methodTable()->put(scope, exec, ident, JSValue::decode(value), slot);
1812 }
1813
1814 extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
1815 {
1816     // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
1817     // really be profitable.
1818     DeferGCForAWhile deferGC(codeBlock->vm()->heap);
1819     
1820     if (Options::verboseOSR())
1821         dataLog(*codeBlock, ": Entered reoptimize\n");
1822     // We must be called with the baseline code block.
1823     ASSERT(JITCode::isBaselineCode(codeBlock->jitType()));
1824
1825     // If I am my own replacement, then reoptimization has already been triggered.
1826     // This can happen in recursive functions.
1827     if (codeBlock->replacement() == codeBlock) {
1828         if (Options::verboseOSR())
1829             dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
1830         return;
1831     }
1832     
1833     // Otherwise, the replacement must be optimized code. Use this as an opportunity
1834     // to check our logic.
1835     ASSERT(codeBlock->hasOptimizedReplacement());
1836     CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1837     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
1838     
1839     bool didTryToEnterIntoInlinedLoops = false;
1840     for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame) {
1841         if (inlineCallFrame->baselineCodeBlock->ownerScriptExecutable()->didTryToEnterInLoop()) {
1842             didTryToEnterIntoInlinedLoops = true;
1843             break;
1844         }
1845     }
1846
1847     // In order to trigger reoptimization, one of two things must have happened:
1848     // 1) We exited more than some number of times.
1849     // 2) We exited and got stuck in a loop, and now we're exiting again.
1850     bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
1851     bool didGetStuckInLoop =
1852         (codeBlock->checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
1853         && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
1854     
1855     if (!didExitABunch && !didGetStuckInLoop) {
1856         if (Options::verboseOSR())
1857             dataLog(*codeBlock, ": Not reoptimizing ", *optimizedCodeBlock, " because it either didn't exit enough or didn't loop enough after exit.\n");
1858         codeBlock->optimizeAfterLongWarmUp();
1859         return;
1860     }
1861
1862     optimizedCodeBlock->jettison(Profiler::JettisonDueToOSRExit, CountReoptimization);
1863 }
1864
1865 #if ENABLE(FTL_JIT)
1866 static bool shouldTriggerFTLCompile(CodeBlock* codeBlock, JITCode* jitCode)
1867 {
1868     if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
1869         CODEBLOCK_LOG_EVENT(codeBlock, "abortFTLCompile", ());
1870         if (Options::verboseOSR())
1871             dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
1872         jitCode->dontOptimizeAnytimeSoon(codeBlock);
1873         return false;
1874     }
1875
1876     if (!codeBlock->hasOptimizedReplacement()
1877         && !jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
1878         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("counter = ", jitCode->tierUpCounter));
1879         if (Options::verboseOSR())
1880             dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
1881         return false;
1882     }
1883     return true;
1884 }
1885
1886 static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
1887 {
1888     Worklist::State worklistState;
1889     if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
1890         worklistState = worklist->completeAllReadyPlansForVM(
1891             *vm, CompilationKey(codeBlock->baselineVersion(), FTLMode));
1892     } else
1893         worklistState = Worklist::NotKnown;
1894     
1895     if (worklistState == Worklist::Compiling) {
1896         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
1897         jitCode->setOptimizationThresholdBasedOnCompilationResult(
1898             codeBlock, CompilationDeferred);
1899         return;
1900     }
1901     
1902     if (codeBlock->hasOptimizedReplacement()) {
1903         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("has replacement"));
1904         // That's great, we've compiled the code - next time we call this function,
1905         // we'll enter that replacement.
1906         jitCode->optimizeSoon(codeBlock);
1907         return;
1908     }
1909     
1910     if (worklistState == Worklist::Compiled) {
1911         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
1912         // This means that we finished compiling, but failed somehow; in that case the
1913         // thresholds will be set appropriately.
1914         if (Options::verboseOSR())
1915             dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1916         return;
1917     }
1918
1919     CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLReplacement", ());
1920     // We need to compile the code.
1921     compile(
1922         *vm, codeBlock->newReplacement(), codeBlock, FTLMode, UINT_MAX,
1923         Operands<JSValue>(), ToFTLDeferredCompilationCallback::create());
1924
1925     // If we reached here, the counter has not be reset. Do that now.
1926     jitCode->setOptimizationThresholdBasedOnCompilationResult(
1927         codeBlock, CompilationDeferred);
1928 }
1929
1930 void JIT_OPERATION triggerTierUpNow(ExecState* exec)
1931 {
1932     VM* vm = &exec->vm();
1933     NativeCallFrameTracer tracer(vm, exec);
1934     DeferGCForAWhile deferGC(vm->heap);
1935     CodeBlock* codeBlock = exec->codeBlock();
1936     
1937     if (codeBlock->jitType() != JITCode::DFGJIT) {
1938         dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
1939         RELEASE_ASSERT_NOT_REACHED();
1940     }
1941     
1942     JITCode* jitCode = codeBlock->jitCode()->dfg();
1943     
1944     if (Options::verboseOSR()) {
1945         dataLog(
1946             *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
1947             jitCode->tierUpCounter, "\n");
1948     }
1949
1950     if (shouldTriggerFTLCompile(codeBlock, jitCode))
1951         triggerFTLReplacementCompile(vm, codeBlock, jitCode);
1952
1953     if (codeBlock->hasOptimizedReplacement()) {
1954         if (jitCode->tierUpEntryTriggers.isEmpty()) {
1955             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("replacement in place, delaying indefinitely"));
1956             // There is nothing more we can do, the only way this will be entered
1957             // is through the function entry point.
1958             jitCode->dontOptimizeAnytimeSoon(codeBlock);
1959             return;
1960         }
1961         if (jitCode->osrEntryBlock() && jitCode->tierUpEntryTriggers.size() == 1) {
1962             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("trigger in place, delaying indefinitely"));
1963             // There is only one outer loop and its trigger must have been set
1964             // when the plan completed.
1965             // Exiting the inner loop is useless, we can ignore the counter and leave
1966             // the trigger do its job.
1967             jitCode->dontOptimizeAnytimeSoon(codeBlock);
1968             return;
1969         }
1970     }
1971 }
1972
1973 static char* tierUpCommon(ExecState* exec, unsigned originBytecodeIndex, unsigned osrEntryBytecodeIndex)
1974 {
1975     VM* vm = &exec->vm();
1976     CodeBlock* codeBlock = exec->codeBlock();
1977
1978     // Resolve any pending plan for OSR Enter on this function.
1979     Worklist::State worklistState;
1980     if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
1981         worklistState = worklist->completeAllReadyPlansForVM(
1982             *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
1983     } else
1984         worklistState = Worklist::NotKnown;
1985
1986     JITCode* jitCode = codeBlock->jitCode()->dfg();
1987     if (worklistState == Worklist::Compiling) {
1988         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
1989         jitCode->setOptimizationThresholdBasedOnCompilationResult(
1990             codeBlock, CompilationDeferred);
1991         return nullptr;
1992     }
1993
1994     if (worklistState == Worklist::Compiled) {
1995         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
1996         // This means that compilation failed and we already set the thresholds.
1997         if (Options::verboseOSR())
1998             dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1999         return nullptr;
2000     }
2001
2002     // If we can OSR Enter, do it right away.
2003     if (originBytecodeIndex == osrEntryBytecodeIndex) {
2004         unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(originBytecodeIndex);
2005         if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
2006             if (void* address = FTL::prepareOSREntry(exec, codeBlock, entryBlock, originBytecodeIndex, streamIndex)) {
2007                 CODEBLOCK_LOG_EVENT(entryBlock, "osrEntry", ("at bc#", originBytecodeIndex));
2008                 return static_cast<char*>(address);
2009             }
2010         }
2011     }
2012
2013     // - If we don't have an FTL code block, then try to compile one.
2014     // - If we do have an FTL code block, then try to enter for a while.
2015     // - If we couldn't enter for a while, then trigger OSR entry.
2016
2017     if (!shouldTriggerFTLCompile(codeBlock, jitCode))
2018         return nullptr;
2019
2020     if (!jitCode->neverExecutedEntry) {
2021         triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2022
2023         if (!codeBlock->hasOptimizedReplacement())
2024             return nullptr;
2025
2026         if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
2027             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding OSR entry compile"));
2028             jitCode->osrEntryRetry++;
2029             return nullptr;
2030         }
2031     } else
2032         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding replacement compile"));
2033
2034     // It's time to try to compile code for OSR entry.
2035     if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
2036         if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
2037             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed, OSR entry threshold not met"));
2038             jitCode->osrEntryRetry++;
2039             jitCode->setOptimizationThresholdBasedOnCompilationResult(
2040                 codeBlock, CompilationDeferred);
2041             return nullptr;
2042         }
2043
2044         FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
2045         entryCode->countEntryFailure();
2046         if (entryCode->entryFailureCount() <
2047             Options::ftlOSREntryFailureCountForReoptimization()) {
2048             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed"));
2049             jitCode->setOptimizationThresholdBasedOnCompilationResult(
2050                 codeBlock, CompilationDeferred);
2051             return nullptr;
2052         }
2053
2054         // OSR entry failed. Oh no! This implies that we need to retry. We retry
2055         // without exponential backoff and we only do this for the entry code block.
2056         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed too many times"));
2057         unsigned osrEntryBytecode = entryBlock->jitCode()->ftlForOSREntry()->bytecodeIndex();
2058         jitCode->clearOSREntryBlock();
2059         jitCode->osrEntryRetry = 0;
2060         jitCode->tierUpEntryTriggers.set(osrEntryBytecode, 0);
2061         jitCode->setOptimizationThresholdBasedOnCompilationResult(
2062             codeBlock, CompilationDeferred);
2063         return nullptr;
2064     }
2065
2066     unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(osrEntryBytecodeIndex);
2067     auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(osrEntryBytecodeIndex);
2068     if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end()) {
2069         for (unsigned osrEntryCandidate : tierUpHierarchyEntry->value) {
2070             if (jitCode->tierUpEntrySeen.contains(osrEntryCandidate)) {
2071                 osrEntryBytecodeIndex = osrEntryCandidate;
2072                 streamIndex = jitCode->bytecodeIndexToStreamIndex.get(osrEntryBytecodeIndex);
2073             }
2074         }
2075     }
2076
2077     // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
2078     // something.
2079     auto triggerIterator = jitCode->tierUpEntryTriggers.find(osrEntryBytecodeIndex);
2080     RELEASE_ASSERT(triggerIterator != jitCode->tierUpEntryTriggers.end());
2081     uint8_t* triggerAddress = &(triggerIterator->value);
2082
2083     Operands<JSValue> mustHandleValues;
2084     jitCode->reconstruct(
2085         exec, codeBlock, CodeOrigin(osrEntryBytecodeIndex), streamIndex, mustHandleValues);
2086     CodeBlock* replacementCodeBlock = codeBlock->newReplacement();
2087
2088     CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLOSR", ());
2089     CompilationResult forEntryResult = compile(
2090         *vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, osrEntryBytecodeIndex,
2091         mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(triggerAddress));
2092
2093     if (jitCode->neverExecutedEntry)
2094         triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2095
2096     if (forEntryResult != CompilationSuccessful) {
2097         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR ecompilation not successful"));
2098         jitCode->setOptimizationThresholdBasedOnCompilationResult(
2099             codeBlock, CompilationDeferred);
2100         return nullptr;
2101     }
2102     
2103     CODEBLOCK_LOG_EVENT(jitCode->osrEntryBlock(), "osrEntry", ("at bc#", originBytecodeIndex));
2104     // It's possible that the for-entry compile already succeeded. In that case OSR
2105     // entry will succeed unless we ran out of stack. It's not clear what we should do.
2106     // We signal to try again after a while if that happens.
2107     void* address = FTL::prepareOSREntry(
2108         exec, codeBlock, jitCode->osrEntryBlock(), originBytecodeIndex, streamIndex);
2109     return static_cast<char*>(address);
2110 }
2111
2112 void JIT_OPERATION triggerTierUpNowInLoop(ExecState* exec, unsigned bytecodeIndex)
2113 {
2114     VM* vm = &exec->vm();
2115     NativeCallFrameTracer tracer(vm, exec);
2116     DeferGCForAWhile deferGC(vm->heap);
2117     CodeBlock* codeBlock = exec->codeBlock();
2118
2119     if (codeBlock->jitType() != JITCode::DFGJIT) {
2120         dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2121         RELEASE_ASSERT_NOT_REACHED();
2122     }
2123
2124     JITCode* jitCode = codeBlock->jitCode()->dfg();
2125
2126     if (Options::verboseOSR()) {
2127         dataLog(
2128             *codeBlock, ": Entered triggerTierUpNowInLoop with executeCounter = ",
2129             jitCode->tierUpCounter, "\n");
2130     }
2131
2132     auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(bytecodeIndex);
2133     if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end()
2134         && !tierUpHierarchyEntry->value.isEmpty()) {
2135         tierUpCommon(exec, bytecodeIndex, tierUpHierarchyEntry->value.first());
2136     } else if (shouldTriggerFTLCompile(codeBlock, jitCode))
2137         triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2138
2139     // Since we cannot OSR Enter here, the default "optimizeSoon()" is not useful.
2140     if (codeBlock->hasOptimizedReplacement()) {
2141         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR in loop failed, deferring"));
2142         jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
2143     }
2144 }
2145
2146 char* JIT_OPERATION triggerOSREntryNow(ExecState* exec, unsigned bytecodeIndex)
2147 {
2148     VM* vm = &exec->vm();
2149     NativeCallFrameTracer tracer(vm, exec);
2150     DeferGCForAWhile deferGC(vm->heap);
2151     CodeBlock* codeBlock = exec->codeBlock();
2152
2153     if (codeBlock->jitType() != JITCode::DFGJIT) {
2154         dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2155         RELEASE_ASSERT_NOT_REACHED();
2156     }
2157
2158     JITCode* jitCode = codeBlock->jitCode()->dfg();
2159     jitCode->tierUpEntrySeen.add(bytecodeIndex);
2160
2161     if (Options::verboseOSR()) {
2162         dataLog(
2163             *codeBlock, ": Entered triggerOSREntryNow with executeCounter = ",
2164             jitCode->tierUpCounter, "\n");
2165     }
2166
2167     return tierUpCommon(exec, bytecodeIndex, bytecodeIndex);
2168 }
2169
2170 #endif // ENABLE(FTL_JIT)
2171
2172 } // extern "C"
2173 } } // namespace JSC::DFG
2174
2175 #endif // ENABLE(DFG_JIT)
2176
2177 #endif // ENABLE(JIT)