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