d3d82264e30e42cc3757cc0f947ad9b5d1d8740b
[WebKit-https.git] / Source / JavaScriptCore / jit / JITOperations.cpp
1 /*
2  * Copyright (C) 2013-2019 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 "JITOperations.h"
28
29 #if ENABLE(JIT)
30
31 #include "ArithProfile.h"
32 #include "ArrayConstructor.h"
33 #include "CommonSlowPaths.h"
34 #include "DFGCompilationMode.h"
35 #include "DFGDriver.h"
36 #include "DFGOSREntry.h"
37 #include "DFGThunks.h"
38 #include "DFGWorklist.h"
39 #include "Debugger.h"
40 #include "DirectArguments.h"
41 #include "Error.h"
42 #include "ErrorHandlingScope.h"
43 #include "EvalCodeBlock.h"
44 #include "ExceptionFuzz.h"
45 #include "ExecutableBaseInlines.h"
46 #include "FTLOSREntry.h"
47 #include "FrameTracers.h"
48 #include "FunctionCodeBlock.h"
49 #include "GetterSetter.h"
50 #include "HostCallReturnValue.h"
51 #include "ICStats.h"
52 #include "Interpreter.h"
53 #include "JIT.h"
54 #include "JITExceptions.h"
55 #include "JITToDFGDeferredCompilationCallback.h"
56 #include "JSAsyncFunction.h"
57 #include "JSAsyncGeneratorFunction.h"
58 #include "JSCInlines.h"
59 #include "JSCPtrTag.h"
60 #include "JSGeneratorFunction.h"
61 #include "JSGlobalObjectFunctions.h"
62 #include "JSLexicalEnvironment.h"
63 #include "JSWithScope.h"
64 #include "ModuleProgramCodeBlock.h"
65 #include "ObjectConstructor.h"
66 #include "PolymorphicAccess.h"
67 #include "ProgramCodeBlock.h"
68 #include "PropertyName.h"
69 #include "RegExpObject.h"
70 #include "Repatch.h"
71 #include "ScopedArguments.h"
72 #include "ShadowChicken.h"
73 #include "StructureStubInfo.h"
74 #include "SuperSampler.h"
75 #include "TestRunnerUtils.h"
76 #include "ThunkGenerators.h"
77 #include "TypeProfilerLog.h"
78 #include "VMInlines.h"
79 #include "WebAssemblyFunction.h"
80 #include <wtf/InlineASM.h>
81
82 namespace JSC {
83
84 extern "C" {
85
86 #if COMPILER(MSVC)
87 void * _ReturnAddress(void);
88 #pragma intrinsic(_ReturnAddress)
89
90 #define OUR_RETURN_ADDRESS _ReturnAddress()
91 #else
92 #define OUR_RETURN_ADDRESS __builtin_return_address(0)
93 #endif
94
95 #if ENABLE(OPCODE_SAMPLING)
96 #define CTI_SAMPLER vm->interpreter->sampler()
97 #else
98 #define CTI_SAMPLER 0
99 #endif
100
101
102 void JIT_OPERATION operationThrowStackOverflowError(ExecState* exec, CodeBlock* codeBlock)
103 {
104     // We pass in our own code block, because the callframe hasn't been populated.
105     VM* vm = codeBlock->vm();
106     auto scope = DECLARE_THROW_SCOPE(*vm);
107     exec->convertToStackOverflowFrame(*vm, codeBlock);
108     NativeCallFrameTracer tracer(vm, exec);
109     throwStackOverflowError(exec, scope);
110 }
111
112 int32_t JIT_OPERATION operationCallArityCheck(ExecState* exec)
113 {
114     VM* vm = &exec->vm();
115     auto scope = DECLARE_THROW_SCOPE(*vm);
116
117     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, *vm, CodeForCall);
118     if (UNLIKELY(missingArgCount < 0)) {
119         CodeBlock* codeBlock = CommonSlowPaths::codeBlockFromCallFrameCallee(exec, CodeForCall);
120         exec->convertToStackOverflowFrame(*vm, codeBlock);
121         NativeCallFrameTracer tracer(vm, exec);
122         throwStackOverflowError(vm->topCallFrame, scope);
123     }
124
125     return missingArgCount;
126 }
127
128 int32_t JIT_OPERATION operationConstructArityCheck(ExecState* exec)
129 {
130     VM* vm = &exec->vm();
131     auto scope = DECLARE_THROW_SCOPE(*vm);
132
133     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, *vm, CodeForConstruct);
134     if (UNLIKELY(missingArgCount < 0)) {
135         CodeBlock* codeBlock = CommonSlowPaths::codeBlockFromCallFrameCallee(exec, CodeForConstruct);
136         exec->convertToStackOverflowFrame(*vm, codeBlock);
137         NativeCallFrameTracer tracer(vm, exec);
138         throwStackOverflowError(vm->topCallFrame, scope);
139     }
140
141     return missingArgCount;
142 }
143
144 EncodedJSValue JIT_OPERATION operationTryGetById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
145 {
146     VM* vm = &exec->vm();
147     NativeCallFrameTracer tracer(vm, exec);
148     Identifier ident = Identifier::fromUid(vm, uid);
149     stubInfo->tookSlowPath = true;
150
151     JSValue baseValue = JSValue::decode(base);
152     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
153     baseValue.getPropertySlot(exec, ident, slot);
154
155     return JSValue::encode(slot.getPureResult());
156 }
157
158
159 EncodedJSValue JIT_OPERATION operationTryGetByIdGeneric(ExecState* exec, EncodedJSValue base, UniquedStringImpl* uid)
160 {
161     VM* vm = &exec->vm();
162     NativeCallFrameTracer tracer(vm, exec);
163     Identifier ident = Identifier::fromUid(vm, uid);
164
165     JSValue baseValue = JSValue::decode(base);
166     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
167     baseValue.getPropertySlot(exec, ident, slot);
168
169     return JSValue::encode(slot.getPureResult());
170 }
171
172 EncodedJSValue JIT_OPERATION operationTryGetByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
173 {
174     VM* vm = &exec->vm();
175     NativeCallFrameTracer tracer(vm, exec);
176     auto scope = DECLARE_THROW_SCOPE(*vm);
177     Identifier ident = Identifier::fromUid(vm, uid);
178
179     JSValue baseValue = JSValue::decode(base);
180     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
181
182     baseValue.getPropertySlot(exec, ident, slot);
183     RETURN_IF_EXCEPTION(scope, encodedJSValue());
184
185     if (stubInfo->considerCaching(exec->codeBlock(), baseValue.structureOrNull()) && !slot.isTaintedByOpaqueObject() && (slot.isCacheableValue() || slot.isCacheableGetter() || slot.isUnset()))
186         repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Try);
187
188     return JSValue::encode(slot.getPureResult());
189 }
190
191 EncodedJSValue JIT_OPERATION operationGetByIdDirect(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
192 {
193     VM& vm = exec->vm();
194     NativeCallFrameTracer tracer(&vm, exec);
195     auto scope = DECLARE_THROW_SCOPE(vm);
196     Identifier ident = Identifier::fromUid(&vm, uid);
197     stubInfo->tookSlowPath = true;
198
199     JSValue baseValue = JSValue::decode(base);
200     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::GetOwnProperty);
201
202     bool found = baseValue.getOwnPropertySlot(exec, ident, slot);
203     RETURN_IF_EXCEPTION(scope, encodedJSValue());
204
205     RELEASE_AND_RETURN(scope, JSValue::encode(found ? slot.getValue(exec, ident) : jsUndefined()));
206 }
207
208 EncodedJSValue JIT_OPERATION operationGetByIdDirectGeneric(ExecState* exec, EncodedJSValue base, UniquedStringImpl* uid)
209 {
210     VM& vm = exec->vm();
211     NativeCallFrameTracer tracer(&vm, exec);
212     auto scope = DECLARE_THROW_SCOPE(vm);
213     Identifier ident = Identifier::fromUid(&vm, uid);
214
215     JSValue baseValue = JSValue::decode(base);
216     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::GetOwnProperty);
217
218     bool found = baseValue.getOwnPropertySlot(exec, ident, slot);
219     RETURN_IF_EXCEPTION(scope, encodedJSValue());
220
221     RELEASE_AND_RETURN(scope, JSValue::encode(found ? slot.getValue(exec, ident) : jsUndefined()));
222 }
223
224 EncodedJSValue JIT_OPERATION operationGetByIdDirectOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
225 {
226     VM& vm = exec->vm();
227     NativeCallFrameTracer tracer(&vm, exec);
228     auto scope = DECLARE_THROW_SCOPE(vm);
229     Identifier ident = Identifier::fromUid(&vm, uid);
230
231     JSValue baseValue = JSValue::decode(base);
232     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::GetOwnProperty);
233
234     bool found = baseValue.getOwnPropertySlot(exec, ident, slot);
235     RETURN_IF_EXCEPTION(scope, encodedJSValue());
236
237     if (stubInfo->considerCaching(exec->codeBlock(), baseValue.structureOrNull()))
238         repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Direct);
239
240     RELEASE_AND_RETURN(scope, JSValue::encode(found ? slot.getValue(exec, ident) : jsUndefined()));
241 }
242
243 EncodedJSValue JIT_OPERATION operationGetById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
244 {
245     SuperSamplerScope superSamplerScope(false);
246     
247     VM* vm = &exec->vm();
248     NativeCallFrameTracer tracer(vm, exec);
249     
250     stubInfo->tookSlowPath = true;
251     
252     JSValue baseValue = JSValue::decode(base);
253     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::Get);
254     Identifier ident = Identifier::fromUid(vm, uid);
255     JSValue result = baseValue.get(exec, ident, slot);
256
257     LOG_IC((ICEvent::OperationGetById, baseValue.classInfoOrNull(*vm), ident, baseValue == slot.slotBase()));
258
259     return JSValue::encode(result);
260 }
261
262 EncodedJSValue JIT_OPERATION operationGetByIdGeneric(ExecState* exec, EncodedJSValue base, UniquedStringImpl* uid)
263 {
264     SuperSamplerScope superSamplerScope(false);
265     
266     VM* vm = &exec->vm();
267     NativeCallFrameTracer tracer(vm, exec);
268     
269     JSValue baseValue = JSValue::decode(base);
270     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::Get);
271     Identifier ident = Identifier::fromUid(vm, uid);
272     JSValue result = baseValue.get(exec, ident, slot);
273     
274     LOG_IC((ICEvent::OperationGetByIdGeneric, baseValue.classInfoOrNull(*vm), ident, baseValue == slot.slotBase()));
275     
276     return JSValue::encode(result);
277 }
278
279 EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
280 {
281     SuperSamplerScope superSamplerScope(false);
282     
283     VM* vm = &exec->vm();
284     NativeCallFrameTracer tracer(vm, exec);
285     Identifier ident = Identifier::fromUid(vm, uid);
286
287     JSValue baseValue = JSValue::decode(base);
288
289     return JSValue::encode(baseValue.getPropertySlot(exec, ident, [&] (bool found, PropertySlot& slot) -> JSValue {
290         
291         LOG_IC((ICEvent::OperationGetByIdOptimize, baseValue.classInfoOrNull(*vm), ident, baseValue == slot.slotBase()));
292         
293         if (stubInfo->considerCaching(exec->codeBlock(), baseValue.structureOrNull()))
294             repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Normal);
295         return found ? slot.getValue(exec, ident) : jsUndefined();
296     }));
297 }
298
299 EncodedJSValue JIT_OPERATION operationGetByIdWithThis(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, EncodedJSValue thisEncoded, UniquedStringImpl* uid)
300 {
301     SuperSamplerScope superSamplerScope(false);
302
303     VM* vm = &exec->vm();
304     NativeCallFrameTracer tracer(vm, exec);
305     Identifier ident = Identifier::fromUid(vm, uid);
306
307     stubInfo->tookSlowPath = true;
308
309     JSValue baseValue = JSValue::decode(base);
310     JSValue thisValue = JSValue::decode(thisEncoded);
311     PropertySlot slot(thisValue, PropertySlot::InternalMethodType::Get);
312
313     return JSValue::encode(baseValue.get(exec, ident, slot));
314 }
315
316 EncodedJSValue JIT_OPERATION operationGetByIdWithThisGeneric(ExecState* exec, EncodedJSValue base, EncodedJSValue thisEncoded, UniquedStringImpl* uid)
317 {
318     SuperSamplerScope superSamplerScope(false);
319
320     VM* vm = &exec->vm();
321     NativeCallFrameTracer tracer(vm, exec);
322     Identifier ident = Identifier::fromUid(vm, uid);
323
324     JSValue baseValue = JSValue::decode(base);
325     JSValue thisValue = JSValue::decode(thisEncoded);
326     PropertySlot slot(thisValue, PropertySlot::InternalMethodType::Get);
327
328     return JSValue::encode(baseValue.get(exec, ident, slot));
329 }
330
331 EncodedJSValue JIT_OPERATION operationGetByIdWithThisOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, EncodedJSValue thisEncoded, UniquedStringImpl* uid)
332 {
333     SuperSamplerScope superSamplerScope(false);
334     
335     VM* vm = &exec->vm();
336     NativeCallFrameTracer tracer(vm, exec);
337     Identifier ident = Identifier::fromUid(vm, uid);
338
339     JSValue baseValue = JSValue::decode(base);
340     JSValue thisValue = JSValue::decode(thisEncoded);
341
342     PropertySlot slot(thisValue, PropertySlot::InternalMethodType::Get);
343     return JSValue::encode(baseValue.getPropertySlot(exec, ident, slot, [&] (bool found, PropertySlot& slot) -> JSValue {
344         LOG_IC((ICEvent::OperationGetByIdWithThisOptimize, baseValue.classInfoOrNull(*vm), ident, baseValue == slot.slotBase()));
345         
346         if (stubInfo->considerCaching(exec->codeBlock(), baseValue.structureOrNull()))
347             repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::WithThis);
348         return found ? slot.getValue(exec, ident) : jsUndefined();
349     }));
350 }
351
352 EncodedJSValue JIT_OPERATION operationInById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
353 {
354     SuperSamplerScope superSamplerScope(false);
355
356     VM& vm = exec->vm();
357     NativeCallFrameTracer tracer(&vm, exec);
358     auto scope = DECLARE_THROW_SCOPE(vm);
359
360     stubInfo->tookSlowPath = true;
361
362     Identifier ident = Identifier::fromUid(&vm, uid);
363
364     JSValue baseValue = JSValue::decode(base);
365     if (!baseValue.isObject()) {
366         throwException(exec, scope, createInvalidInParameterError(exec, baseValue));
367         return JSValue::encode(jsUndefined());
368     }
369     JSObject* baseObject = asObject(baseValue);
370
371     LOG_IC((ICEvent::OperationInById, baseObject->classInfo(vm), ident));
372
373     scope.release();
374     PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
375     return JSValue::encode(jsBoolean(baseObject->getPropertySlot(exec, ident, slot)));
376 }
377
378 EncodedJSValue JIT_OPERATION operationInByIdGeneric(ExecState* exec, EncodedJSValue base, UniquedStringImpl* uid)
379 {
380     SuperSamplerScope superSamplerScope(false);
381
382     VM& vm = exec->vm();
383     NativeCallFrameTracer tracer(&vm, exec);
384     auto scope = DECLARE_THROW_SCOPE(vm);
385
386     Identifier ident = Identifier::fromUid(&vm, uid);
387
388     JSValue baseValue = JSValue::decode(base);
389     if (!baseValue.isObject()) {
390         throwException(exec, scope, createInvalidInParameterError(exec, baseValue));
391         return JSValue::encode(jsUndefined());
392     }
393     JSObject* baseObject = asObject(baseValue);
394
395     LOG_IC((ICEvent::OperationInByIdGeneric, baseObject->classInfo(vm), ident));
396
397     scope.release();
398     PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
399     return JSValue::encode(jsBoolean(baseObject->getPropertySlot(exec, ident, slot)));
400 }
401
402 EncodedJSValue JIT_OPERATION operationInByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
403 {
404     SuperSamplerScope superSamplerScope(false);
405
406     VM& vm = exec->vm();
407     NativeCallFrameTracer tracer(&vm, exec);
408     auto scope = DECLARE_THROW_SCOPE(vm);
409
410     Identifier ident = Identifier::fromUid(&vm, uid);
411
412     JSValue baseValue = JSValue::decode(base);
413     if (!baseValue.isObject()) {
414         throwException(exec, scope, createInvalidInParameterError(exec, baseValue));
415         return JSValue::encode(jsUndefined());
416     }
417     JSObject* baseObject = asObject(baseValue);
418
419     LOG_IC((ICEvent::OperationInByIdOptimize, baseObject->classInfo(vm), ident));
420
421     scope.release();
422     PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
423     bool found = baseObject->getPropertySlot(exec, ident, slot);
424     if (stubInfo->considerCaching(exec->codeBlock(), baseObject->structure(vm)))
425         repatchInByID(exec, baseObject, ident, found, slot, *stubInfo);
426     return JSValue::encode(jsBoolean(found));
427 }
428
429 EncodedJSValue JIT_OPERATION operationInByVal(ExecState* exec, JSCell* base, EncodedJSValue key)
430 {
431     SuperSamplerScope superSamplerScope(false);
432     
433     VM* vm = &exec->vm();
434     NativeCallFrameTracer tracer(vm, exec);
435
436     return JSValue::encode(jsBoolean(CommonSlowPaths::opInByVal(exec, base, JSValue::decode(key))));
437 }
438
439 void JIT_OPERATION operationPutByIdStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
440 {
441     SuperSamplerScope superSamplerScope(false);
442     
443     VM* vm = &exec->vm();
444     NativeCallFrameTracer tracer(vm, exec);
445     
446     stubInfo->tookSlowPath = true;
447     
448     JSValue baseValue = JSValue::decode(encodedBase);
449     Identifier ident = Identifier::fromUid(vm, uid);
450     PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
451     baseValue.putInline(exec, ident, JSValue::decode(encodedValue), slot);
452     
453     LOG_IC((ICEvent::OperationPutByIdStrict, baseValue.classInfoOrNull(*vm), ident, slot.base() == baseValue));
454 }
455
456 void JIT_OPERATION operationPutByIdNonStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
457 {
458     SuperSamplerScope superSamplerScope(false);
459     
460     VM* vm = &exec->vm();
461     NativeCallFrameTracer tracer(vm, exec);
462     
463     stubInfo->tookSlowPath = true;
464     
465     JSValue baseValue = JSValue::decode(encodedBase);
466     Identifier ident = Identifier::fromUid(vm, uid);
467     PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
468     baseValue.putInline(exec, ident, JSValue::decode(encodedValue), slot);
469
470     LOG_IC((ICEvent::OperationPutByIdNonStrict, baseValue.classInfoOrNull(*vm), ident, slot.base() == baseValue));
471 }
472
473 void JIT_OPERATION operationPutByIdDirectStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
474 {
475     SuperSamplerScope superSamplerScope(false);
476     
477     VM& vm = exec->vm();
478     NativeCallFrameTracer tracer(&vm, exec);
479     
480     stubInfo->tookSlowPath = true;
481     
482     JSValue baseValue = JSValue::decode(encodedBase);
483     Identifier ident = Identifier::fromUid(&vm, uid);
484     PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
485     CommonSlowPaths::putDirectWithReify(vm, exec, asObject(baseValue), ident, JSValue::decode(encodedValue), slot);
486
487     LOG_IC((ICEvent::OperationPutByIdDirectStrict, baseValue.classInfoOrNull(vm), ident, slot.base() == baseValue));
488 }
489
490 void JIT_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
491 {
492     SuperSamplerScope superSamplerScope(false);
493     
494     VM& vm = exec->vm();
495     NativeCallFrameTracer tracer(&vm, exec);
496     
497     stubInfo->tookSlowPath = true;
498     
499     JSValue baseValue = JSValue::decode(encodedBase);
500     Identifier ident = Identifier::fromUid(&vm, uid);
501     PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
502     CommonSlowPaths::putDirectWithReify(vm, exec, asObject(baseValue), ident, JSValue::decode(encodedValue), slot);
503
504     LOG_IC((ICEvent::OperationPutByIdDirectNonStrict, baseValue.classInfoOrNull(vm), ident, slot.base() == baseValue));
505 }
506
507 void JIT_OPERATION operationPutByIdStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
508 {
509     SuperSamplerScope superSamplerScope(false);
510     
511     VM* vm = &exec->vm();
512     NativeCallFrameTracer tracer(vm, exec);
513     auto scope = DECLARE_THROW_SCOPE(*vm);
514
515     Identifier ident = Identifier::fromUid(vm, uid);
516     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
517
518     JSValue value = JSValue::decode(encodedValue);
519     JSValue baseValue = JSValue::decode(encodedBase);
520     CodeBlock* codeBlock = exec->codeBlock();
521     PutPropertySlot slot(baseValue, true, codeBlock->putByIdContext());
522
523     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
524     baseValue.putInline(exec, ident, value, slot);
525
526     LOG_IC((ICEvent::OperationPutByIdStrictOptimize, baseValue.classInfoOrNull(*vm), ident, slot.base() == baseValue));
527
528     RETURN_IF_EXCEPTION(scope, void());
529
530     if (accessType != static_cast<AccessType>(stubInfo->accessType))
531         return;
532     
533     if (stubInfo->considerCaching(codeBlock, structure))
534         repatchPutByID(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
535 }
536
537 void JIT_OPERATION operationPutByIdNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
538 {
539     SuperSamplerScope superSamplerScope(false);
540     
541     VM* vm = &exec->vm();
542     NativeCallFrameTracer tracer(vm, exec);
543     auto scope = DECLARE_THROW_SCOPE(*vm);
544
545     Identifier ident = Identifier::fromUid(vm, uid);
546     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
547
548     JSValue value = JSValue::decode(encodedValue);
549     JSValue baseValue = JSValue::decode(encodedBase);
550     CodeBlock* codeBlock = exec->codeBlock();
551     PutPropertySlot slot(baseValue, false, codeBlock->putByIdContext());
552
553     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;    
554     baseValue.putInline(exec, ident, value, slot);
555
556     LOG_IC((ICEvent::OperationPutByIdNonStrictOptimize, baseValue.classInfoOrNull(*vm), ident, slot.base() == baseValue));
557
558     RETURN_IF_EXCEPTION(scope, void());
559
560     if (accessType != static_cast<AccessType>(stubInfo->accessType))
561         return;
562     
563     if (stubInfo->considerCaching(codeBlock, structure))
564         repatchPutByID(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
565 }
566
567 void JIT_OPERATION operationPutByIdDirectStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
568 {
569     SuperSamplerScope superSamplerScope(false);
570     
571     VM& vm = exec->vm();
572     NativeCallFrameTracer tracer(&vm, exec);
573     auto scope = DECLARE_THROW_SCOPE(vm);
574     
575     Identifier ident = Identifier::fromUid(&vm, uid);
576     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
577
578     JSValue value = JSValue::decode(encodedValue);
579     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
580     CodeBlock* codeBlock = exec->codeBlock();
581     PutPropertySlot slot(baseObject, true, codeBlock->putByIdContext());
582     Structure* structure = nullptr;
583     CommonSlowPaths::putDirectWithReify(vm, exec, baseObject, ident, value, slot, &structure);
584
585     LOG_IC((ICEvent::OperationPutByIdDirectStrictOptimize, baseObject->classInfo(vm), ident, slot.base() == baseObject));
586
587     RETURN_IF_EXCEPTION(scope, void());
588     
589     if (accessType != static_cast<AccessType>(stubInfo->accessType))
590         return;
591     
592     if (stubInfo->considerCaching(codeBlock, structure))
593         repatchPutByID(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
594 }
595
596 void JIT_OPERATION operationPutByIdDirectNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
597 {
598     SuperSamplerScope superSamplerScope(false);
599     
600     VM& vm = exec->vm();
601     NativeCallFrameTracer tracer(&vm, exec);
602     auto scope = DECLARE_THROW_SCOPE(vm);
603     
604     Identifier ident = Identifier::fromUid(&vm, uid);
605     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
606
607     JSValue value = JSValue::decode(encodedValue);
608     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
609     CodeBlock* codeBlock = exec->codeBlock();
610     PutPropertySlot slot(baseObject, false, codeBlock->putByIdContext());
611     Structure* structure = nullptr;
612     CommonSlowPaths::putDirectWithReify(vm, exec, baseObject, ident, value, slot, &structure);
613
614     LOG_IC((ICEvent::OperationPutByIdDirectNonStrictOptimize, baseObject->classInfo(vm), ident, slot.base() == baseObject));
615
616     RETURN_IF_EXCEPTION(scope, void());
617     
618     if (accessType != static_cast<AccessType>(stubInfo->accessType))
619         return;
620     
621     if (stubInfo->considerCaching(codeBlock, structure))
622         repatchPutByID(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
623 }
624
625 ALWAYS_INLINE static bool isStringOrSymbol(JSValue value)
626 {
627     return value.isString() || value.isSymbol();
628 }
629
630 static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value, ByValInfo* byValInfo)
631 {
632     VM& vm = callFrame->vm();
633     auto scope = DECLARE_THROW_SCOPE(vm);
634     if (LIKELY(subscript.isUInt32())) {
635         byValInfo->tookSlowPath = true;
636         uint32_t i = subscript.asUInt32();
637         if (baseValue.isObject()) {
638             JSObject* object = asObject(baseValue);
639             if (object->canSetIndexQuickly(i)) {
640                 object->setIndexQuickly(vm, i, value);
641                 return;
642             }
643
644             // FIXME: This will make us think that in-bounds typed array accesses are actually
645             // out-of-bounds.
646             // https://bugs.webkit.org/show_bug.cgi?id=149886
647             byValInfo->arrayProfile->setOutOfBounds();
648             scope.release();
649             object->methodTable(vm)->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
650             return;
651         }
652
653         scope.release();
654         baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
655         return;
656     }
657
658     auto property = subscript.toPropertyKey(callFrame);
659     // Don't put to an object if toString threw an exception.
660     RETURN_IF_EXCEPTION(scope, void());
661
662     if (byValInfo->stubInfo && (!isStringOrSymbol(subscript) || byValInfo->cachedId != property))
663         byValInfo->tookSlowPath = true;
664
665     scope.release();
666     PutPropertySlot slot(baseValue, callFrame->codeBlock()->isStrictMode());
667     baseValue.putInline(callFrame, property, value, slot);
668 }
669
670 static void directPutByVal(CallFrame* callFrame, JSObject* baseObject, JSValue subscript, JSValue value, ByValInfo* byValInfo)
671 {
672     VM& vm = callFrame->vm();
673     auto scope = DECLARE_THROW_SCOPE(vm);
674     bool isStrictMode = callFrame->codeBlock()->isStrictMode();
675
676     if (LIKELY(subscript.isUInt32())) {
677         // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
678         byValInfo->tookSlowPath = true;
679         uint32_t index = subscript.asUInt32();
680         ASSERT(isIndex(index));
681
682         switch (baseObject->indexingType()) {
683         case ALL_INT32_INDEXING_TYPES:
684         case ALL_DOUBLE_INDEXING_TYPES:
685         case ALL_CONTIGUOUS_INDEXING_TYPES:
686         case ALL_ARRAY_STORAGE_INDEXING_TYPES:
687             if (index < baseObject->butterfly()->vectorLength())
688                 break;
689             FALLTHROUGH;
690         default:
691             byValInfo->arrayProfile->setOutOfBounds();
692             break;
693         }
694
695         scope.release();
696         baseObject->putDirectIndex(callFrame, index, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
697         return;
698     }
699
700     if (subscript.isDouble()) {
701         double subscriptAsDouble = subscript.asDouble();
702         uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
703         if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) {
704             byValInfo->tookSlowPath = true;
705             scope.release();
706             baseObject->putDirectIndex(callFrame, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
707             return;
708         }
709     }
710
711     // Don't put to an object if toString threw an exception.
712     auto property = subscript.toPropertyKey(callFrame);
713     RETURN_IF_EXCEPTION(scope, void());
714
715     if (Optional<uint32_t> index = parseIndex(property)) {
716         byValInfo->tookSlowPath = true;
717         scope.release();
718         baseObject->putDirectIndex(callFrame, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
719         return;
720     }
721
722     if (byValInfo->stubInfo && (!isStringOrSymbol(subscript) || byValInfo->cachedId != property))
723         byValInfo->tookSlowPath = true;
724
725     scope.release();
726     PutPropertySlot slot(baseObject, isStrictMode);
727     CommonSlowPaths::putDirectWithReify(vm, callFrame, baseObject, property, value, slot);
728 }
729
730 enum class OptimizationResult {
731     NotOptimized,
732     SeenOnce,
733     Optimized,
734     GiveUp,
735 };
736
737 static OptimizationResult tryPutByValOptimize(ExecState* exec, JSValue baseValue, JSValue subscript, ByValInfo* byValInfo, ReturnAddressPtr returnAddress)
738 {
739     // See if it's worth optimizing at all.
740     OptimizationResult optimizationResult = OptimizationResult::NotOptimized;
741
742     VM& vm = exec->vm();
743     auto scope = DECLARE_THROW_SCOPE(vm);
744
745     if (baseValue.isObject() && isCopyOnWrite(baseValue.getObject()->indexingMode()))
746         return OptimizationResult::GiveUp;
747
748     if (baseValue.isObject() && subscript.isInt32()) {
749         JSObject* object = asObject(baseValue);
750
751         ASSERT(exec->bytecodeOffset());
752         ASSERT(!byValInfo->stubRoutine);
753
754         Structure* structure = object->structure(vm);
755         if (hasOptimizableIndexing(structure)) {
756             // Attempt to optimize.
757             JITArrayMode arrayMode = jitArrayModeForStructure(structure);
758             if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo->arrayMode) {
759                 CodeBlock* codeBlock = exec->codeBlock();
760                 ConcurrentJSLocker locker(codeBlock->m_lock);
761                 byValInfo->arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
762                 JIT::compilePutByVal(locker, &vm, codeBlock, byValInfo, returnAddress, arrayMode);
763                 optimizationResult = OptimizationResult::Optimized;
764             }
765         }
766
767         // If we failed to patch and we have some object that intercepts indexed get, then don't even wait until 10 times.
768         if (optimizationResult != OptimizationResult::Optimized && object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero())
769             optimizationResult = OptimizationResult::GiveUp;
770     }
771
772     if (baseValue.isObject() && isStringOrSymbol(subscript)) {
773         const Identifier propertyName = subscript.toPropertyKey(exec);
774         RETURN_IF_EXCEPTION(scope, OptimizationResult::GiveUp);
775         if (subscript.isSymbol() || !parseIndex(propertyName)) {
776             ASSERT(exec->bytecodeOffset());
777             ASSERT(!byValInfo->stubRoutine);
778             if (byValInfo->seen) {
779                 if (byValInfo->cachedId == propertyName) {
780                     JIT::compilePutByValWithCachedId<OpPutByVal>(&vm, exec->codeBlock(), byValInfo, returnAddress, NotDirect, propertyName);
781                     optimizationResult = OptimizationResult::Optimized;
782                 } else {
783                     // Seem like a generic property access site.
784                     optimizationResult = OptimizationResult::GiveUp;
785                 }
786             } else {
787                 CodeBlock* codeBlock = exec->codeBlock();
788                 ConcurrentJSLocker locker(codeBlock->m_lock);
789                 byValInfo->seen = true;
790                 byValInfo->cachedId = propertyName;
791                 if (subscript.isSymbol())
792                     byValInfo->cachedSymbol.set(vm, codeBlock, asSymbol(subscript));
793                 optimizationResult = OptimizationResult::SeenOnce;
794             }
795         }
796     }
797
798     if (optimizationResult != OptimizationResult::Optimized && optimizationResult != OptimizationResult::SeenOnce) {
799         // If we take slow path more than 10 times without patching then make sure we
800         // never make that mistake again. For cases where we see non-index-intercepting
801         // objects, this gives 10 iterations worth of opportunity for us to observe
802         // that the put_by_val may be polymorphic. We count up slowPathCount even if
803         // the result is GiveUp.
804         if (++byValInfo->slowPathCount >= 10)
805             optimizationResult = OptimizationResult::GiveUp;
806     }
807
808     return optimizationResult;
809 }
810
811 void JIT_OPERATION operationPutByValOptimize(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ByValInfo* byValInfo)
812 {
813     VM& vm = exec->vm();
814     NativeCallFrameTracer tracer(&vm, exec);
815     auto scope = DECLARE_THROW_SCOPE(vm);
816
817     JSValue baseValue = JSValue::decode(encodedBaseValue);
818     JSValue subscript = JSValue::decode(encodedSubscript);
819     JSValue value = JSValue::decode(encodedValue);
820     OptimizationResult result = tryPutByValOptimize(exec, baseValue, subscript, byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS));
821     RETURN_IF_EXCEPTION(scope, void());
822     if (result == OptimizationResult::GiveUp) {
823         // Don't ever try to optimize.
824         byValInfo->tookSlowPath = true;
825         ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationPutByValGeneric);
826     }
827     RELEASE_AND_RETURN(scope, putByVal(exec, baseValue, subscript, value, byValInfo));
828 }
829
830 static OptimizationResult tryDirectPutByValOptimize(ExecState* exec, JSObject* object, JSValue subscript, ByValInfo* byValInfo, ReturnAddressPtr returnAddress)
831 {
832     // See if it's worth optimizing at all.
833     OptimizationResult optimizationResult = OptimizationResult::NotOptimized;
834
835     VM& vm = exec->vm();
836     auto scope = DECLARE_THROW_SCOPE(vm);
837
838     if (subscript.isInt32()) {
839         ASSERT(exec->bytecodeOffset());
840         ASSERT(!byValInfo->stubRoutine);
841
842         Structure* structure = object->structure(vm);
843         if (hasOptimizableIndexing(structure)) {
844             // Attempt to optimize.
845             JITArrayMode arrayMode = jitArrayModeForStructure(structure);
846             if (jitArrayModePermitsPutDirect(arrayMode) && arrayMode != byValInfo->arrayMode) {
847                 CodeBlock* codeBlock = exec->codeBlock();
848                 ConcurrentJSLocker locker(codeBlock->m_lock);
849                 byValInfo->arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
850
851                 JIT::compileDirectPutByVal(locker, &vm, codeBlock, byValInfo, returnAddress, arrayMode);
852                 optimizationResult = OptimizationResult::Optimized;
853             }
854         }
855
856         // If we failed to patch and we have some object that intercepts indexed get, then don't even wait until 10 times.
857         if (optimizationResult != OptimizationResult::Optimized && object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero())
858             optimizationResult = OptimizationResult::GiveUp;
859     } else if (isStringOrSymbol(subscript)) {
860         const Identifier propertyName = subscript.toPropertyKey(exec);
861         RETURN_IF_EXCEPTION(scope, OptimizationResult::GiveUp);
862         if (subscript.isSymbol() || !parseIndex(propertyName)) {
863             ASSERT(exec->bytecodeOffset());
864             ASSERT(!byValInfo->stubRoutine);
865             if (byValInfo->seen) {
866                 if (byValInfo->cachedId == propertyName) {
867                     JIT::compilePutByValWithCachedId<OpPutByValDirect>(&vm, exec->codeBlock(), byValInfo, returnAddress, Direct, propertyName);
868                     optimizationResult = OptimizationResult::Optimized;
869                 } else {
870                     // Seem like a generic property access site.
871                     optimizationResult = OptimizationResult::GiveUp;
872                 }
873             } else {
874                 CodeBlock* codeBlock = exec->codeBlock();
875                 ConcurrentJSLocker locker(codeBlock->m_lock);
876                 byValInfo->seen = true;
877                 byValInfo->cachedId = propertyName;
878                 if (subscript.isSymbol())
879                     byValInfo->cachedSymbol.set(vm, codeBlock, asSymbol(subscript));
880                 optimizationResult = OptimizationResult::SeenOnce;
881             }
882         }
883     }
884
885     if (optimizationResult != OptimizationResult::Optimized && optimizationResult != OptimizationResult::SeenOnce) {
886         // If we take slow path more than 10 times without patching then make sure we
887         // never make that mistake again. For cases where we see non-index-intercepting
888         // objects, this gives 10 iterations worth of opportunity for us to observe
889         // that the get_by_val may be polymorphic. We count up slowPathCount even if
890         // the result is GiveUp.
891         if (++byValInfo->slowPathCount >= 10)
892             optimizationResult = OptimizationResult::GiveUp;
893     }
894
895     return optimizationResult;
896 }
897
898 void JIT_OPERATION operationDirectPutByValOptimize(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ByValInfo* byValInfo)
899 {
900     VM& vm = exec->vm();
901     NativeCallFrameTracer tracer(&vm, exec);
902     auto scope = DECLARE_THROW_SCOPE(vm);
903
904     JSValue baseValue = JSValue::decode(encodedBaseValue);
905     JSValue subscript = JSValue::decode(encodedSubscript);
906     JSValue value = JSValue::decode(encodedValue);
907     RELEASE_ASSERT(baseValue.isObject());
908     JSObject* object = asObject(baseValue);
909     OptimizationResult result = tryDirectPutByValOptimize(exec, object, subscript, byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS));
910     RETURN_IF_EXCEPTION(scope, void());
911     if (result == OptimizationResult::GiveUp) {
912         // Don't ever try to optimize.
913         byValInfo->tookSlowPath = true;
914         ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationDirectPutByValGeneric);
915     }
916
917     RELEASE_AND_RETURN(scope, directPutByVal(exec, object, subscript, value, byValInfo));
918 }
919
920 void JIT_OPERATION operationPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ByValInfo* byValInfo)
921 {
922     VM& vm = exec->vm();
923     NativeCallFrameTracer tracer(&vm, exec);
924     
925     JSValue baseValue = JSValue::decode(encodedBaseValue);
926     JSValue subscript = JSValue::decode(encodedSubscript);
927     JSValue value = JSValue::decode(encodedValue);
928
929     putByVal(exec, baseValue, subscript, value, byValInfo);
930 }
931
932
933 void JIT_OPERATION operationDirectPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ByValInfo* byValInfo)
934 {
935     VM& vm = exec->vm();
936     NativeCallFrameTracer tracer(&vm, exec);
937     
938     JSValue baseValue = JSValue::decode(encodedBaseValue);
939     JSValue subscript = JSValue::decode(encodedSubscript);
940     JSValue value = JSValue::decode(encodedValue);
941     RELEASE_ASSERT(baseValue.isObject());
942     directPutByVal(exec, asObject(baseValue), subscript, value, byValInfo);
943 }
944
945 EncodedJSValue JIT_OPERATION operationCallEval(ExecState* exec, ExecState* execCallee)
946 {
947     VM* vm = &exec->vm();
948     auto scope = DECLARE_THROW_SCOPE(*vm);
949
950     execCallee->setCodeBlock(0);
951     
952     if (!isHostFunction(execCallee->guaranteedJSValueCallee(), globalFuncEval))
953         return JSValue::encode(JSValue());
954
955     JSValue result = eval(execCallee);
956     RETURN_IF_EXCEPTION(scope, encodedJSValue());
957     
958     return JSValue::encode(result);
959 }
960
961 static SlowPathReturnType handleHostCall(ExecState* execCallee, JSValue callee, CallLinkInfo* callLinkInfo)
962 {
963     ExecState* exec = execCallee->callerFrame();
964     VM* vm = &exec->vm();
965     auto scope = DECLARE_THROW_SCOPE(*vm);
966
967     execCallee->setCodeBlock(0);
968
969     if (callLinkInfo->specializationKind() == CodeForCall) {
970         CallData callData;
971         CallType callType = getCallData(*vm, callee, callData);
972     
973         ASSERT(callType != CallType::JS);
974     
975         if (callType == CallType::Host) {
976             NativeCallFrameTracer tracer(vm, execCallee);
977             execCallee->setCallee(asObject(callee));
978             vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
979             if (UNLIKELY(scope.exception())) {
980                 return encodeResult(
981                     vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress(),
982                     reinterpret_cast<void*>(KeepTheFrame));
983             }
984
985             return encodeResult(
986                 tagCFunctionPtr<void*, JSEntryPtrTag>(getHostCallReturnValue),
987                 reinterpret_cast<void*>(callLinkInfo->callMode() == CallMode::Tail ? ReuseTheFrame : KeepTheFrame));
988         }
989     
990         ASSERT(callType == CallType::None);
991         throwException(exec, scope, createNotAFunctionError(exec, callee));
992         return encodeResult(
993             vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress(),
994             reinterpret_cast<void*>(KeepTheFrame));
995     }
996
997     ASSERT(callLinkInfo->specializationKind() == CodeForConstruct);
998     
999     ConstructData constructData;
1000     ConstructType constructType = getConstructData(*vm, callee, constructData);
1001     
1002     ASSERT(constructType != ConstructType::JS);
1003     
1004     if (constructType == ConstructType::Host) {
1005         NativeCallFrameTracer tracer(vm, execCallee);
1006         execCallee->setCallee(asObject(callee));
1007         vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1008         if (UNLIKELY(scope.exception())) {
1009             return encodeResult(
1010                 vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress(),
1011                 reinterpret_cast<void*>(KeepTheFrame));
1012         }
1013
1014         return encodeResult(tagCFunctionPtr<void*, JSEntryPtrTag>(getHostCallReturnValue), reinterpret_cast<void*>(KeepTheFrame));
1015     }
1016     
1017     ASSERT(constructType == ConstructType::None);
1018     throwException(exec, scope, createNotAConstructorError(exec, callee));
1019     return encodeResult(
1020         vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress(),
1021         reinterpret_cast<void*>(KeepTheFrame));
1022 }
1023
1024 SlowPathReturnType JIT_OPERATION operationLinkCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
1025 {
1026     ExecState* exec = execCallee->callerFrame();
1027     VM* vm = &exec->vm();
1028     auto throwScope = DECLARE_THROW_SCOPE(*vm);
1029
1030     CodeSpecializationKind kind = callLinkInfo->specializationKind();
1031     NativeCallFrameTracer tracer(vm, exec);
1032     
1033     RELEASE_ASSERT(!callLinkInfo->isDirect());
1034     
1035     JSValue calleeAsValue = execCallee->guaranteedJSValueCallee();
1036     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1037     if (!calleeAsFunctionCell) {
1038         if (auto* internalFunction = jsDynamicCast<InternalFunction*>(*vm, calleeAsValue)) {
1039             MacroAssemblerCodePtr<JSEntryPtrTag> codePtr = vm->getCTIInternalFunctionTrampolineFor(kind);
1040             RELEASE_ASSERT(!!codePtr);
1041
1042             if (!callLinkInfo->seenOnce())
1043                 callLinkInfo->setSeen();
1044             else
1045                 linkFor(execCallee, *callLinkInfo, nullptr, internalFunction, codePtr);
1046
1047             void* linkedTarget = codePtr.executableAddress();
1048             return encodeResult(linkedTarget, reinterpret_cast<void*>(callLinkInfo->callMode() == CallMode::Tail ? ReuseTheFrame : KeepTheFrame));
1049         }
1050         RELEASE_AND_RETURN(throwScope, handleHostCall(execCallee, calleeAsValue, callLinkInfo));
1051     }
1052
1053     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1054     JSScope* scope = callee->scopeUnchecked();
1055     ExecutableBase* executable = callee->executable();
1056
1057     MacroAssemblerCodePtr<JSEntryPtrTag> codePtr;
1058     CodeBlock* codeBlock = nullptr;
1059     if (executable->isHostFunction()) {
1060         codePtr = jsToWasmICCodePtr(*vm, kind, callee);
1061         if (!codePtr)
1062             codePtr = executable->entrypointFor(kind, MustCheckArity);
1063     } else {
1064         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1065
1066         auto handleThrowException = [&] () {
1067             void* throwTarget = vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress();
1068             return encodeResult(throwTarget, reinterpret_cast<void*>(KeepTheFrame));
1069         };
1070
1071         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
1072             throwException(exec, throwScope, createNotAConstructorError(exec, callee));
1073             return handleThrowException();
1074         }
1075
1076         CodeBlock** codeBlockSlot = execCallee->addressOfCodeBlock();
1077         Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(*vm, callee, scope, kind, *codeBlockSlot);
1078         EXCEPTION_ASSERT(throwScope.exception() == error);
1079         if (UNLIKELY(error))
1080             return handleThrowException();
1081         codeBlock = *codeBlockSlot;
1082         ArityCheckMode arity;
1083         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo->isVarargs())
1084             arity = MustCheckArity;
1085         else
1086             arity = ArityCheckNotRequired;
1087         codePtr = functionExecutable->entrypointFor(kind, arity);
1088     }
1089
1090     if (!callLinkInfo->seenOnce())
1091         callLinkInfo->setSeen();
1092     else
1093         linkFor(execCallee, *callLinkInfo, codeBlock, callee, codePtr);
1094
1095     return encodeResult(codePtr.executableAddress(), reinterpret_cast<void*>(callLinkInfo->callMode() == CallMode::Tail ? ReuseTheFrame : KeepTheFrame));
1096 }
1097
1098 void JIT_OPERATION operationLinkDirectCall(ExecState* exec, CallLinkInfo* callLinkInfo, JSFunction* callee)
1099 {
1100     VM* vm = &exec->vm();
1101     auto throwScope = DECLARE_THROW_SCOPE(*vm);
1102
1103     CodeSpecializationKind kind = callLinkInfo->specializationKind();
1104     NativeCallFrameTracer tracer(vm, exec);
1105     
1106     RELEASE_ASSERT(callLinkInfo->isDirect());
1107     
1108     // This would happen if the executable died during GC but the CodeBlock did not die. That should
1109     // not happen because the CodeBlock should have a weak reference to any executable it uses for
1110     // this purpose.
1111     RELEASE_ASSERT(callLinkInfo->executable());
1112     
1113     // Having a CodeBlock indicates that this is linked. We shouldn't be taking this path if it's
1114     // linked.
1115     RELEASE_ASSERT(!callLinkInfo->codeBlock());
1116     
1117     // We just don't support this yet.
1118     RELEASE_ASSERT(!callLinkInfo->isVarargs());
1119     
1120     ExecutableBase* executable = callLinkInfo->executable();
1121     RELEASE_ASSERT(callee->executable() == callLinkInfo->executable());
1122
1123     JSScope* scope = callee->scopeUnchecked();
1124
1125     MacroAssemblerCodePtr<JSEntryPtrTag> codePtr;
1126     CodeBlock* codeBlock = nullptr;
1127     if (executable->isHostFunction())
1128         codePtr = executable->entrypointFor(kind, MustCheckArity);
1129     else {
1130         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1131
1132         RELEASE_ASSERT(isCall(kind) || functionExecutable->constructAbility() != ConstructAbility::CannotConstruct);
1133         
1134         Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(*vm, callee, scope, kind, codeBlock);
1135         EXCEPTION_ASSERT_UNUSED(throwScope, throwScope.exception() == error);
1136         if (UNLIKELY(error))
1137             return;
1138         unsigned argumentStackSlots = callLinkInfo->maxNumArguments();
1139         if (argumentStackSlots < static_cast<size_t>(codeBlock->numParameters()))
1140             codePtr = functionExecutable->entrypointFor(kind, MustCheckArity);
1141         else
1142             codePtr = functionExecutable->entrypointFor(kind, ArityCheckNotRequired);
1143     }
1144     
1145     linkDirectFor(exec, *callLinkInfo, codeBlock, codePtr);
1146 }
1147
1148 inline SlowPathReturnType virtualForWithFunction(
1149     ExecState* execCallee, CallLinkInfo* callLinkInfo, JSCell*& calleeAsFunctionCell)
1150 {
1151     ExecState* exec = execCallee->callerFrame();
1152     VM* vm = &exec->vm();
1153     auto throwScope = DECLARE_THROW_SCOPE(*vm);
1154
1155     CodeSpecializationKind kind = callLinkInfo->specializationKind();
1156     NativeCallFrameTracer tracer(vm, exec);
1157
1158     JSValue calleeAsValue = execCallee->guaranteedJSValueCallee();
1159     calleeAsFunctionCell = getJSFunction(calleeAsValue);
1160     if (UNLIKELY(!calleeAsFunctionCell)) {
1161         if (jsDynamicCast<InternalFunction*>(*vm, calleeAsValue)) {
1162             MacroAssemblerCodePtr<JSEntryPtrTag> codePtr = vm->getCTIInternalFunctionTrampolineFor(kind);
1163             ASSERT(!!codePtr);
1164             return encodeResult(codePtr.executableAddress(), reinterpret_cast<void*>(callLinkInfo->callMode() == CallMode::Tail ? ReuseTheFrame : KeepTheFrame));
1165         }
1166         RELEASE_AND_RETURN(throwScope, handleHostCall(execCallee, calleeAsValue, callLinkInfo));
1167     }
1168     
1169     JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
1170     JSScope* scope = function->scopeUnchecked();
1171     ExecutableBase* executable = function->executable();
1172     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
1173         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1174
1175         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
1176             throwException(exec, throwScope, createNotAConstructorError(exec, function));
1177             return encodeResult(
1178                 vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress(),
1179                 reinterpret_cast<void*>(KeepTheFrame));
1180         }
1181
1182         CodeBlock** codeBlockSlot = execCallee->addressOfCodeBlock();
1183         Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(*vm, function, scope, kind, *codeBlockSlot);
1184         EXCEPTION_ASSERT(throwScope.exception() == error);
1185         if (UNLIKELY(error)) {
1186             return encodeResult(
1187                 vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress(),
1188                 reinterpret_cast<void*>(KeepTheFrame));
1189         }
1190     }
1191     return encodeResult(executable->entrypointFor(
1192         kind, MustCheckArity).executableAddress(),
1193         reinterpret_cast<void*>(callLinkInfo->callMode() == CallMode::Tail ? ReuseTheFrame : KeepTheFrame));
1194 }
1195
1196 SlowPathReturnType JIT_OPERATION operationLinkPolymorphicCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
1197 {
1198     ASSERT(callLinkInfo->specializationKind() == CodeForCall);
1199     JSCell* calleeAsFunctionCell;
1200     SlowPathReturnType result = virtualForWithFunction(execCallee, callLinkInfo, calleeAsFunctionCell);
1201
1202     linkPolymorphicCall(execCallee, *callLinkInfo, CallVariant(calleeAsFunctionCell));
1203     
1204     return result;
1205 }
1206
1207 SlowPathReturnType JIT_OPERATION operationVirtualCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
1208 {
1209     JSCell* calleeAsFunctionCellIgnored;
1210     return virtualForWithFunction(execCallee, callLinkInfo, calleeAsFunctionCellIgnored);
1211 }
1212
1213 size_t JIT_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1214 {
1215     VM* vm = &exec->vm();
1216     NativeCallFrameTracer tracer(vm, exec);
1217     
1218     return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
1219 }
1220
1221 size_t JIT_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1222 {
1223     VM* vm = &exec->vm();
1224     NativeCallFrameTracer tracer(vm, exec);
1225
1226     return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
1227 }
1228
1229 size_t JIT_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1230 {
1231     VM* vm = &exec->vm();
1232     NativeCallFrameTracer tracer(vm, exec);
1233
1234     return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
1235 }
1236
1237 size_t JIT_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1238 {
1239     VM* vm = &exec->vm();
1240     NativeCallFrameTracer tracer(vm, exec);
1241
1242     return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
1243 }
1244
1245 size_t JIT_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1246 {
1247     VM* vm = &exec->vm();
1248     NativeCallFrameTracer tracer(vm, exec);
1249
1250     return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
1251 }
1252
1253 #if USE(JSVALUE64)
1254 EncodedJSValue JIT_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
1255 #else
1256 size_t JIT_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
1257 #endif
1258 {
1259     VM* vm = &exec->vm();
1260     NativeCallFrameTracer tracer(vm, exec);
1261
1262     bool result = asString(left)->equal(exec, asString(right));
1263 #if USE(JSVALUE64)
1264     return JSValue::encode(jsBoolean(result));
1265 #else
1266     return result;
1267 #endif
1268 }
1269
1270 size_t JIT_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1271 {
1272     VM* vm = &exec->vm();
1273     NativeCallFrameTracer tracer(vm, exec);
1274
1275     JSValue src1 = JSValue::decode(encodedOp1);
1276     JSValue src2 = JSValue::decode(encodedOp2);
1277
1278     return JSValue::strictEqual(exec, src1, src2);
1279 }
1280
1281 EncodedJSValue JIT_OPERATION operationNewArrayWithProfile(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, int size)
1282 {
1283     VM* vm = &exec->vm();
1284     NativeCallFrameTracer tracer(vm, exec);
1285     return JSValue::encode(constructArrayNegativeIndexed(exec, profile, values, size));
1286 }
1287
1288 EncodedJSValue JIT_OPERATION operationNewArrayWithSizeAndProfile(ExecState* exec, ArrayAllocationProfile* profile, EncodedJSValue size)
1289 {
1290     VM* vm = &exec->vm();
1291     NativeCallFrameTracer tracer(vm, exec);
1292     JSValue sizeValue = JSValue::decode(size);
1293     return JSValue::encode(constructArrayWithSizeQuirk(exec, profile, exec->lexicalGlobalObject(), sizeValue));
1294 }
1295
1296 }
1297
1298 template<typename FunctionType>
1299 static EncodedJSValue operationNewFunctionCommon(ExecState* exec, JSScope* scope, JSCell* functionExecutable, bool isInvalidated)
1300 {
1301     VM& vm = exec->vm();
1302     ASSERT(functionExecutable->inherits<FunctionExecutable>(vm));
1303     NativeCallFrameTracer tracer(&vm, exec);
1304     if (isInvalidated)
1305         return JSValue::encode(FunctionType::createWithInvalidatedReallocationWatchpoint(vm, static_cast<FunctionExecutable*>(functionExecutable), scope));
1306     return JSValue::encode(FunctionType::create(vm, static_cast<FunctionExecutable*>(functionExecutable), scope));
1307 }
1308
1309 extern "C" {
1310
1311 EncodedJSValue JIT_OPERATION operationNewFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
1312 {
1313     return operationNewFunctionCommon<JSFunction>(exec, scope, functionExecutable, false);
1314 }
1315
1316 EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
1317 {
1318     return operationNewFunctionCommon<JSFunction>(exec, scope, functionExecutable, true);
1319 }
1320
1321 EncodedJSValue JIT_OPERATION operationNewGeneratorFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
1322 {
1323     return operationNewFunctionCommon<JSGeneratorFunction>(exec, scope, functionExecutable, false);
1324 }
1325
1326 EncodedJSValue JIT_OPERATION operationNewGeneratorFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
1327 {
1328     return operationNewFunctionCommon<JSGeneratorFunction>(exec, scope, functionExecutable, true);
1329 }
1330
1331 EncodedJSValue JIT_OPERATION operationNewAsyncFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
1332 {
1333     return operationNewFunctionCommon<JSAsyncFunction>(exec, scope, functionExecutable, false);
1334 }
1335
1336 EncodedJSValue JIT_OPERATION operationNewAsyncFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
1337 {
1338     return operationNewFunctionCommon<JSAsyncFunction>(exec, scope, functionExecutable, true);
1339 }
1340
1341 EncodedJSValue JIT_OPERATION operationNewAsyncGeneratorFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
1342 {
1343     return operationNewFunctionCommon<JSAsyncGeneratorFunction>(exec, scope, functionExecutable, false);
1344 }
1345     
1346 EncodedJSValue JIT_OPERATION operationNewAsyncGeneratorFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
1347 {
1348     return operationNewFunctionCommon<JSAsyncGeneratorFunction>(exec, scope, functionExecutable, true);
1349 }
1350     
1351 void JIT_OPERATION operationSetFunctionName(ExecState* exec, JSCell* funcCell, EncodedJSValue encodedName)
1352 {
1353     VM* vm = &exec->vm();
1354     NativeCallFrameTracer tracer(vm, exec);
1355
1356     JSFunction* func = jsCast<JSFunction*>(funcCell);
1357     JSValue name = JSValue::decode(encodedName);
1358     func->setFunctionName(exec, name);
1359 }
1360
1361 JSCell* JIT_OPERATION operationNewObject(ExecState* exec, Structure* structure)
1362 {
1363     VM* vm = &exec->vm();
1364     NativeCallFrameTracer tracer(vm, exec);
1365
1366     return constructEmptyObject(exec, structure);
1367 }
1368
1369 JSCell* JIT_OPERATION operationNewRegexp(ExecState* exec, JSCell* regexpPtr)
1370 {
1371     SuperSamplerScope superSamplerScope(false);
1372     VM& vm = exec->vm();
1373     NativeCallFrameTracer tracer(&vm, exec);
1374
1375     RegExp* regexp = static_cast<RegExp*>(regexpPtr);
1376     ASSERT(regexp->isValid());
1377     return RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regexp);
1378 }
1379
1380 // The only reason for returning an UnusedPtr (instead of void) is so that we can reuse the
1381 // existing DFG slow path generator machinery when creating the slow path for CheckTraps
1382 // in the DFG. If a DFG slow path generator that supports a void return type is added in the
1383 // future, we can switch to using that then.
1384 UnusedPtr JIT_OPERATION operationHandleTraps(ExecState* exec)
1385 {
1386     VM& vm = exec->vm();
1387     NativeCallFrameTracer tracer(&vm, exec);
1388     ASSERT(vm.needTrapHandling());
1389     vm.handleTraps(exec);
1390     return nullptr;
1391 }
1392
1393 void JIT_OPERATION operationDebug(ExecState* exec, int32_t debugHookType)
1394 {
1395     VM& vm = exec->vm();
1396     NativeCallFrameTracer tracer(&vm, exec);
1397
1398     vm.interpreter->debug(exec, static_cast<DebugHookType>(debugHookType));
1399 }
1400
1401 #if ENABLE(DFG_JIT)
1402 static void updateAllPredictionsAndOptimizeAfterWarmUp(CodeBlock* codeBlock)
1403 {
1404     codeBlock->updateAllPredictions();
1405     codeBlock->optimizeAfterWarmUp();
1406 }
1407
1408 SlowPathReturnType JIT_OPERATION operationOptimize(ExecState* exec, uint32_t bytecodeIndex)
1409 {
1410     VM& vm = exec->vm();
1411     NativeCallFrameTracer tracer(&vm, exec);
1412
1413     // Defer GC for a while so that it doesn't run between when we enter into this
1414     // slow path and when we figure out the state of our code block. This prevents
1415     // a number of awkward reentrancy scenarios, including:
1416     //
1417     // - The optimized version of our code block being jettisoned by GC right after
1418     //   we concluded that we wanted to use it, but have not planted it into the JS
1419     //   stack yet.
1420     //
1421     // - An optimized version of our code block being installed just as we decided
1422     //   that it wasn't ready yet.
1423     //
1424     // Note that jettisoning won't happen if we already initiated OSR, because in
1425     // that case we would have already planted the optimized code block into the JS
1426     // stack.
1427     DeferGCForAWhile deferGC(vm.heap);
1428     
1429     CodeBlock* codeBlock = exec->codeBlock();
1430     if (UNLIKELY(codeBlock->jitType() != JITCode::BaselineJIT)) {
1431         dataLog("Unexpected code block in Baseline->DFG tier-up: ", *codeBlock, "\n");
1432         RELEASE_ASSERT_NOT_REACHED();
1433     }
1434     
1435     if (bytecodeIndex) {
1436         // If we're attempting to OSR from a loop, assume that this should be
1437         // separately optimized.
1438         codeBlock->m_shouldAlwaysBeInlined = false;
1439     }
1440
1441     if (UNLIKELY(Options::verboseOSR())) {
1442         dataLog(
1443             *codeBlock, ": Entered optimize with bytecodeIndex = ", bytecodeIndex,
1444             ", executeCounter = ", codeBlock->jitExecuteCounter(),
1445             ", optimizationDelayCounter = ", codeBlock->reoptimizationRetryCounter(),
1446             ", exitCounter = ");
1447         if (codeBlock->hasOptimizedReplacement())
1448             dataLog(codeBlock->replacement()->osrExitCounter());
1449         else
1450             dataLog("N/A");
1451         dataLog("\n");
1452     }
1453
1454     if (!codeBlock->checkIfOptimizationThresholdReached()) {
1455         CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("counter = ", codeBlock->jitExecuteCounter()));
1456         codeBlock->updateAllPredictions();
1457         if (UNLIKELY(Options::verboseOSR()))
1458             dataLog("Choosing not to optimize ", *codeBlock, " yet, because the threshold hasn't been reached.\n");
1459         return encodeResult(0, 0);
1460     }
1461     
1462     Debugger* debugger = codeBlock->globalObject()->debugger();
1463     if (UNLIKELY(debugger && (debugger->isStepping() || codeBlock->baselineAlternative()->hasDebuggerRequests()))) {
1464         CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("debugger is stepping or has requests"));
1465         updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
1466         return encodeResult(0, 0);
1467     }
1468
1469     if (codeBlock->m_shouldAlwaysBeInlined) {
1470         CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("should always be inlined"));
1471         updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
1472         if (UNLIKELY(Options::verboseOSR()))
1473             dataLog("Choosing not to optimize ", *codeBlock, " yet, because m_shouldAlwaysBeInlined == true.\n");
1474         return encodeResult(0, 0);
1475     }
1476
1477     // We cannot be in the process of asynchronous compilation and also have an optimized
1478     // replacement.
1479     DFG::Worklist* worklist = DFG::existingGlobalDFGWorklistOrNull();
1480     ASSERT(
1481         !worklist
1482         || !(worklist->compilationState(DFG::CompilationKey(codeBlock, DFG::DFGMode)) != DFG::Worklist::NotKnown
1483         && codeBlock->hasOptimizedReplacement()));
1484
1485     DFG::Worklist::State worklistState;
1486     if (worklist) {
1487         // The call to DFG::Worklist::completeAllReadyPlansForVM() will complete all ready
1488         // (i.e. compiled) code blocks. But if it completes ours, we also need to know
1489         // what the result was so that we don't plow ahead and attempt OSR or immediate
1490         // reoptimization. This will have already also set the appropriate JIT execution
1491         // count threshold depending on what happened, so if the compilation was anything
1492         // but successful we just want to return early. See the case for worklistState ==
1493         // DFG::Worklist::Compiled, below.
1494         
1495         // Note that we could have alternatively just called Worklist::compilationState()
1496         // here, and if it returned Compiled, we could have then called
1497         // completeAndScheduleOSR() below. But that would have meant that it could take
1498         // longer for code blocks to be completed: they would only complete when *their*
1499         // execution count trigger fired; but that could take a while since the firing is
1500         // racy. It could also mean that code blocks that never run again after being
1501         // compiled would sit on the worklist until next GC. That's fine, but it's
1502         // probably a waste of memory. Our goal here is to complete code blocks as soon as
1503         // possible in order to minimize the chances of us executing baseline code after
1504         // optimized code is already available.
1505         worklistState = worklist->completeAllReadyPlansForVM(
1506             vm, DFG::CompilationKey(codeBlock, DFG::DFGMode));
1507     } else
1508         worklistState = DFG::Worklist::NotKnown;
1509
1510     if (worklistState == DFG::Worklist::Compiling) {
1511         CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("compiling"));
1512         // We cannot be in the process of asynchronous compilation and also have an optimized
1513         // replacement.
1514         RELEASE_ASSERT(!codeBlock->hasOptimizedReplacement());
1515         codeBlock->setOptimizationThresholdBasedOnCompilationResult(CompilationDeferred);
1516         return encodeResult(0, 0);
1517     }
1518
1519     if (worklistState == DFG::Worklist::Compiled) {
1520         // If we don't have an optimized replacement but we did just get compiled, then
1521         // the compilation failed or was invalidated, in which case the execution count
1522         // thresholds have already been set appropriately by
1523         // CodeBlock::setOptimizationThresholdBasedOnCompilationResult() and we have
1524         // nothing left to do.
1525         if (!codeBlock->hasOptimizedReplacement()) {
1526             CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("compiled and failed"));
1527             codeBlock->updateAllPredictions();
1528             if (UNLIKELY(Options::verboseOSR()))
1529                 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1530             return encodeResult(0, 0);
1531         }
1532     } else if (codeBlock->hasOptimizedReplacement()) {
1533         CodeBlock* replacement = codeBlock->replacement();
1534         if (UNLIKELY(Options::verboseOSR()))
1535             dataLog("Considering OSR ", codeBlock, " -> ", replacement, ".\n");
1536         // If we have an optimized replacement, then it must be the case that we entered
1537         // cti_optimize from a loop. That's because if there's an optimized replacement,
1538         // then all calls to this function will be relinked to the replacement and so
1539         // the prologue OSR will never fire.
1540         
1541         // This is an interesting threshold check. Consider that a function OSR exits
1542         // in the middle of a loop, while having a relatively low exit count. The exit
1543         // will reset the execution counter to some target threshold, meaning that this
1544         // code won't be reached until that loop heats up for >=1000 executions. But then
1545         // we do a second check here, to see if we should either reoptimize, or just
1546         // attempt OSR entry. Hence it might even be correct for
1547         // shouldReoptimizeFromLoopNow() to always return true. But we make it do some
1548         // additional checking anyway, to reduce the amount of recompilation thrashing.
1549         if (replacement->shouldReoptimizeFromLoopNow()) {
1550             CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("should reoptimize from loop now"));
1551             if (UNLIKELY(Options::verboseOSR())) {
1552                 dataLog(
1553                     "Triggering reoptimization of ", codeBlock,
1554                     "(", replacement, ") (in loop).\n");
1555             }
1556             replacement->jettison(Profiler::JettisonDueToBaselineLoopReoptimizationTrigger, CountReoptimization);
1557             return encodeResult(0, 0);
1558         }
1559     } else {
1560         if (!codeBlock->shouldOptimizeNow()) {
1561             CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("insufficient profiling"));
1562             if (UNLIKELY(Options::verboseOSR())) {
1563                 dataLog(
1564                     "Delaying optimization for ", *codeBlock,
1565                     " because of insufficient profiling.\n");
1566             }
1567             return encodeResult(0, 0);
1568         }
1569
1570         if (UNLIKELY(Options::verboseOSR()))
1571             dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
1572
1573         unsigned numVarsWithValues;
1574         if (bytecodeIndex)
1575             numVarsWithValues = codeBlock->numCalleeLocals();
1576         else
1577             numVarsWithValues = 0;
1578         Operands<Optional<JSValue>> mustHandleValues(codeBlock->numParameters(), numVarsWithValues);
1579         int localsUsedForCalleeSaves = static_cast<int>(CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters());
1580         for (size_t i = 0; i < mustHandleValues.size(); ++i) {
1581             int operand = mustHandleValues.operandForIndex(i);
1582             if (operandIsLocal(operand) && VirtualRegister(operand).toLocal() < localsUsedForCalleeSaves)
1583                 continue;
1584             mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
1585         }
1586
1587         CodeBlock* replacementCodeBlock = codeBlock->newReplacement();
1588         CompilationResult result = DFG::compile(
1589             vm, replacementCodeBlock, nullptr, DFG::DFGMode, bytecodeIndex,
1590             mustHandleValues, JITToDFGDeferredCompilationCallback::create());
1591         
1592         if (result != CompilationSuccessful) {
1593             CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("compilation failed"));
1594             return encodeResult(0, 0);
1595         }
1596     }
1597     
1598     CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1599     ASSERT(optimizedCodeBlock && JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
1600     
1601     if (void* dataBuffer = DFG::prepareOSREntry(exec, optimizedCodeBlock, bytecodeIndex)) {
1602         CODEBLOCK_LOG_EVENT(optimizedCodeBlock, "osrEntry", ("at bc#", bytecodeIndex));
1603         if (UNLIKELY(Options::verboseOSR())) {
1604             dataLog(
1605                 "Performing OSR ", codeBlock, " -> ", optimizedCodeBlock, ".\n");
1606         }
1607
1608         codeBlock->optimizeSoon();
1609         codeBlock->unlinkedCodeBlock()->setDidOptimize(TrueTriState);
1610         void* targetPC = vm.getCTIStub(DFG::osrEntryThunkGenerator).code().executableAddress();
1611         targetPC = retagCodePtr(targetPC, JITThunkPtrTag, bitwise_cast<PtrTag>(exec));
1612         return encodeResult(targetPC, dataBuffer);
1613     }
1614
1615     if (UNLIKELY(Options::verboseOSR())) {
1616         dataLog(
1617             "Optimizing ", codeBlock, " -> ", codeBlock->replacement(),
1618             " succeeded, OSR failed, after a delay of ",
1619             codeBlock->optimizationDelayCounter(), ".\n");
1620     }
1621
1622     // Count the OSR failure as a speculation failure. If this happens a lot, then
1623     // reoptimize.
1624     optimizedCodeBlock->countOSRExit();
1625
1626     // We are a lot more conservative about triggering reoptimization after OSR failure than
1627     // before it. If we enter the optimize_from_loop trigger with a bucket full of fail
1628     // already, then we really would like to reoptimize immediately. But this case covers
1629     // something else: there weren't many (or any) speculation failures before, but we just
1630     // failed to enter the speculative code because some variable had the wrong value or
1631     // because the OSR code decided for any spurious reason that it did not want to OSR
1632     // right now. So, we only trigger reoptimization only upon the more conservative (non-loop)
1633     // reoptimization trigger.
1634     if (optimizedCodeBlock->shouldReoptimizeNow()) {
1635         CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("should reoptimize now"));
1636         if (UNLIKELY(Options::verboseOSR())) {
1637             dataLog(
1638                 "Triggering reoptimization of ", codeBlock, " -> ",
1639                 codeBlock->replacement(), " (after OSR fail).\n");
1640         }
1641         optimizedCodeBlock->jettison(Profiler::JettisonDueToBaselineLoopReoptimizationTriggerOnOSREntryFail, CountReoptimization);
1642         return encodeResult(0, 0);
1643     }
1644
1645     // OSR failed this time, but it might succeed next time! Let the code run a bit
1646     // longer and then try again.
1647     codeBlock->optimizeAfterWarmUp();
1648     
1649     CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("OSR failed"));
1650     return encodeResult(0, 0);
1651 }
1652
1653 char* JIT_OPERATION operationTryOSREnterAtCatch(ExecState* exec, uint32_t bytecodeIndex)
1654 {
1655     VM& vm = exec->vm();
1656     NativeCallFrameTracer tracer(&vm, exec);
1657
1658     CodeBlock* optimizedReplacement = exec->codeBlock()->replacement();
1659     if (UNLIKELY(!optimizedReplacement))
1660         return nullptr;
1661
1662     switch (optimizedReplacement->jitType()) {
1663     case JITCode::DFGJIT:
1664     case JITCode::FTLJIT: {
1665         MacroAssemblerCodePtr<ExceptionHandlerPtrTag> entry = DFG::prepareCatchOSREntry(exec, optimizedReplacement, bytecodeIndex);
1666         return entry.executableAddress<char*>();
1667     }
1668     default:
1669         break;
1670     }
1671     return nullptr;
1672 }
1673
1674 char* JIT_OPERATION operationTryOSREnterAtCatchAndValueProfile(ExecState* exec, uint32_t bytecodeIndex)
1675 {
1676     VM& vm = exec->vm();
1677     NativeCallFrameTracer tracer(&vm, exec);
1678
1679     CodeBlock* codeBlock = exec->codeBlock();
1680     CodeBlock* optimizedReplacement = codeBlock->replacement();
1681     if (UNLIKELY(!optimizedReplacement))
1682         return nullptr;
1683
1684     switch (optimizedReplacement->jitType()) {
1685     case JITCode::DFGJIT:
1686     case JITCode::FTLJIT: {
1687         MacroAssemblerCodePtr<ExceptionHandlerPtrTag> entry = DFG::prepareCatchOSREntry(exec, optimizedReplacement, bytecodeIndex);
1688         return entry.executableAddress<char*>();
1689     }
1690     default:
1691         break;
1692     }
1693
1694     codeBlock->ensureCatchLivenessIsComputedForBytecodeOffset(bytecodeIndex);
1695     auto bytecode = codeBlock->instructions().at(bytecodeIndex)->as<OpCatch>();
1696     auto& metadata = bytecode.metadata(codeBlock);
1697     metadata.m_buffer->forEach([&] (ValueProfileAndOperand& profile) {
1698         profile.m_profile.m_buckets[0] = JSValue::encode(exec->uncheckedR(profile.m_operand).jsValue());
1699     });
1700
1701     return nullptr;
1702 }
1703
1704 #endif
1705
1706 void JIT_OPERATION operationPutByIndex(ExecState* exec, EncodedJSValue encodedArrayValue, int32_t index, EncodedJSValue encodedValue)
1707 {
1708     VM& vm = exec->vm();
1709     NativeCallFrameTracer tracer(&vm, exec);
1710
1711     JSValue arrayValue = JSValue::decode(encodedArrayValue);
1712     ASSERT(isJSArray(arrayValue));
1713     asArray(arrayValue)->putDirectIndex(exec, index, JSValue::decode(encodedValue));
1714 }
1715
1716 enum class AccessorType {
1717     Getter,
1718     Setter
1719 };
1720
1721 static void putAccessorByVal(ExecState* exec, JSObject* base, JSValue subscript, int32_t attribute, JSObject* accessor, AccessorType accessorType)
1722 {
1723     VM& vm = exec->vm();
1724     auto scope = DECLARE_THROW_SCOPE(vm);
1725     auto propertyKey = subscript.toPropertyKey(exec);
1726     RETURN_IF_EXCEPTION(scope, void());
1727
1728     scope.release();
1729     if (accessorType == AccessorType::Getter)
1730         base->putGetter(exec, propertyKey, accessor, attribute);
1731     else
1732         base->putSetter(exec, propertyKey, accessor, attribute);
1733 }
1734
1735 void JIT_OPERATION operationPutGetterById(ExecState* exec, JSCell* object, UniquedStringImpl* uid, int32_t options, JSCell* getter)
1736 {
1737     VM& vm = exec->vm();
1738     NativeCallFrameTracer tracer(&vm, exec);
1739
1740     ASSERT(object && object->isObject());
1741     JSObject* baseObj = object->getObject();
1742
1743     ASSERT(getter->isObject());
1744     baseObj->putGetter(exec, uid, getter, options);
1745 }
1746
1747 void JIT_OPERATION operationPutSetterById(ExecState* exec, JSCell* object, UniquedStringImpl* uid, int32_t options, JSCell* setter)
1748 {
1749     VM& vm = exec->vm();
1750     NativeCallFrameTracer tracer(&vm, exec);
1751
1752     ASSERT(object && object->isObject());
1753     JSObject* baseObj = object->getObject();
1754
1755     ASSERT(setter->isObject());
1756     baseObj->putSetter(exec, uid, setter, options);
1757 }
1758
1759 void JIT_OPERATION operationPutGetterByVal(ExecState* exec, JSCell* base, EncodedJSValue encodedSubscript, int32_t attribute, JSCell* getter)
1760 {
1761     VM& vm = exec->vm();
1762     NativeCallFrameTracer tracer(&vm, exec);
1763
1764     putAccessorByVal(exec, asObject(base), JSValue::decode(encodedSubscript), attribute, asObject(getter), AccessorType::Getter);
1765 }
1766
1767 void JIT_OPERATION operationPutSetterByVal(ExecState* exec, JSCell* base, EncodedJSValue encodedSubscript, int32_t attribute, JSCell* setter)
1768 {
1769     VM& vm = exec->vm();
1770     NativeCallFrameTracer tracer(&vm, exec);
1771
1772     putAccessorByVal(exec, asObject(base), JSValue::decode(encodedSubscript), attribute, asObject(setter), AccessorType::Setter);
1773 }
1774
1775 #if USE(JSVALUE64)
1776 void JIT_OPERATION operationPutGetterSetter(ExecState* exec, JSCell* object, UniquedStringImpl* uid, int32_t attribute, EncodedJSValue encodedGetterValue, EncodedJSValue encodedSetterValue)
1777 {
1778     VM& vm = exec->vm();
1779     NativeCallFrameTracer tracer(&vm, exec);
1780
1781     ASSERT(object && object->isObject());
1782     JSObject* baseObject = asObject(object);
1783
1784     JSValue getter = JSValue::decode(encodedGetterValue);
1785     JSValue setter = JSValue::decode(encodedSetterValue);
1786     ASSERT(getter.isObject() || setter.isObject());
1787     GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject(), getter, setter);
1788     CommonSlowPaths::putDirectAccessorWithReify(vm, exec, baseObject, uid, accessor, attribute);
1789 }
1790
1791 #else
1792 void JIT_OPERATION operationPutGetterSetter(ExecState* exec, JSCell* object, UniquedStringImpl* uid, int32_t attribute, JSCell* getterCell, JSCell* setterCell)
1793 {
1794     VM& vm = exec->vm();
1795     NativeCallFrameTracer tracer(&vm, exec);
1796
1797     ASSERT(object && object->isObject());
1798     JSObject* baseObject = asObject(object);
1799
1800     ASSERT(getterCell || setterCell);
1801     JSObject* getter = getterCell ? getterCell->getObject() : nullptr;
1802     JSObject* setter = setterCell ? setterCell->getObject() : nullptr;
1803     GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject(), getter, setter);
1804     CommonSlowPaths::putDirectAccessorWithReify(vm, exec, baseObject, uid, accessor, attribute);
1805 }
1806 #endif
1807
1808 void JIT_OPERATION operationPopScope(ExecState* exec, int32_t scopeReg)
1809 {
1810     VM& vm = exec->vm();
1811     NativeCallFrameTracer tracer(&vm, exec);
1812
1813     JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
1814     exec->uncheckedR(scopeReg) = scope->next();
1815 }
1816
1817 int32_t JIT_OPERATION operationInstanceOfCustom(ExecState* exec, EncodedJSValue encodedValue, JSObject* constructor, EncodedJSValue encodedHasInstance)
1818 {
1819     VM& vm = exec->vm();
1820     NativeCallFrameTracer tracer(&vm, exec);
1821
1822     JSValue value = JSValue::decode(encodedValue);
1823     JSValue hasInstanceValue = JSValue::decode(encodedHasInstance);
1824
1825     if (constructor->hasInstance(exec, value, hasInstanceValue))
1826         return 1;
1827     return 0;
1828 }
1829
1830 }
1831
1832 static JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript, ByValInfo* byValInfo, ReturnAddressPtr returnAddress)
1833 {
1834     VM& vm = exec->vm();
1835     auto scope = DECLARE_THROW_SCOPE(vm);
1836
1837     if (LIKELY(baseValue.isCell() && subscript.isString())) {
1838         Structure& structure = *baseValue.asCell()->structure(vm);
1839         if (JSCell::canUseFastGetOwnProperty(structure)) {
1840             RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec);
1841             RETURN_IF_EXCEPTION(scope, JSValue());
1842             if (existingAtomicString) {
1843                 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get())) {
1844                     ASSERT(exec->bytecodeOffset());
1845                     if (byValInfo->stubInfo && byValInfo->cachedId.impl() != existingAtomicString)
1846                         byValInfo->tookSlowPath = true;
1847                     return result;
1848                 }
1849             }
1850         }
1851     }
1852
1853     if (subscript.isUInt32()) {
1854         ASSERT(exec->bytecodeOffset());
1855         byValInfo->tookSlowPath = true;
1856
1857         uint32_t i = subscript.asUInt32();
1858         if (isJSString(baseValue)) {
1859             if (asString(baseValue)->canGetIndex(i)) {
1860                 ctiPatchCallByReturnAddress(returnAddress, operationGetByValString);
1861                 RELEASE_AND_RETURN(scope, asString(baseValue)->getIndex(exec, i));
1862             }
1863             byValInfo->arrayProfile->setOutOfBounds();
1864         } else if (baseValue.isObject()) {
1865             JSObject* object = asObject(baseValue);
1866             if (object->canGetIndexQuickly(i))
1867                 return object->getIndexQuickly(i);
1868
1869             bool skipMarkingOutOfBounds = false;
1870
1871             if (object->indexingType() == ArrayWithContiguous && i < object->butterfly()->publicLength()) {
1872                 // FIXME: expand this to ArrayStorage, Int32, and maybe Double:
1873                 // https://bugs.webkit.org/show_bug.cgi?id=182940
1874                 auto* globalObject = object->globalObject(vm);
1875                 skipMarkingOutOfBounds = globalObject->isOriginalArrayStructure(object->structure(vm)) && globalObject->arrayPrototypeChainIsSane();
1876             }
1877
1878             if (!skipMarkingOutOfBounds && !CommonSlowPaths::canAccessArgumentIndexQuickly(*object, i)) {
1879                 // FIXME: This will make us think that in-bounds typed array accesses are actually
1880                 // out-of-bounds.
1881                 // https://bugs.webkit.org/show_bug.cgi?id=149886
1882                 byValInfo->arrayProfile->setOutOfBounds();
1883             }
1884         }
1885
1886         RELEASE_AND_RETURN(scope, baseValue.get(exec, i));
1887     }
1888
1889     baseValue.requireObjectCoercible(exec);
1890     RETURN_IF_EXCEPTION(scope, JSValue());
1891     auto property = subscript.toPropertyKey(exec);
1892     RETURN_IF_EXCEPTION(scope, JSValue());
1893
1894     ASSERT(exec->bytecodeOffset());
1895     if (byValInfo->stubInfo && (!isStringOrSymbol(subscript) || byValInfo->cachedId != property))
1896         byValInfo->tookSlowPath = true;
1897
1898     RELEASE_AND_RETURN(scope, baseValue.get(exec, property));
1899 }
1900
1901 static OptimizationResult tryGetByValOptimize(ExecState* exec, JSValue baseValue, JSValue subscript, ByValInfo* byValInfo, ReturnAddressPtr returnAddress)
1902 {
1903     // See if it's worth optimizing this at all.
1904     OptimizationResult optimizationResult = OptimizationResult::NotOptimized;
1905
1906     VM& vm = exec->vm();
1907     auto scope = DECLARE_THROW_SCOPE(vm);
1908
1909     if (baseValue.isObject() && subscript.isInt32()) {
1910         JSObject* object = asObject(baseValue);
1911
1912         ASSERT(exec->bytecodeOffset());
1913         ASSERT(!byValInfo->stubRoutine);
1914
1915         if (hasOptimizableIndexing(object->structure(vm))) {
1916             // Attempt to optimize.
1917             Structure* structure = object->structure(vm);
1918             JITArrayMode arrayMode = jitArrayModeForStructure(structure);
1919             if (arrayMode != byValInfo->arrayMode) {
1920                 // If we reached this case, we got an interesting array mode we did not expect when we compiled.
1921                 // Let's update the profile to do better next time.
1922                 CodeBlock* codeBlock = exec->codeBlock();
1923                 ConcurrentJSLocker locker(codeBlock->m_lock);
1924                 byValInfo->arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
1925
1926                 JIT::compileGetByVal(locker, &vm, codeBlock, byValInfo, returnAddress, arrayMode);
1927                 optimizationResult = OptimizationResult::Optimized;
1928             }
1929         }
1930
1931         // If we failed to patch and we have some object that intercepts indexed get, then don't even wait until 10 times.
1932         if (optimizationResult != OptimizationResult::Optimized && object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero())
1933             optimizationResult = OptimizationResult::GiveUp;
1934     }
1935
1936     if (baseValue.isObject() && isStringOrSymbol(subscript)) {
1937         const Identifier propertyName = subscript.toPropertyKey(exec);
1938         RETURN_IF_EXCEPTION(scope, OptimizationResult::GiveUp);
1939         if (subscript.isSymbol() || !parseIndex(propertyName)) {
1940             ASSERT(exec->bytecodeOffset());
1941             ASSERT(!byValInfo->stubRoutine);
1942             if (byValInfo->seen) {
1943                 if (byValInfo->cachedId == propertyName) {
1944                     JIT::compileGetByValWithCachedId(&vm, exec->codeBlock(), byValInfo, returnAddress, propertyName);
1945                     optimizationResult = OptimizationResult::Optimized;
1946                 } else {
1947                     // Seem like a generic property access site.
1948                     optimizationResult = OptimizationResult::GiveUp;
1949                 }
1950             } else {
1951                 CodeBlock* codeBlock = exec->codeBlock();
1952                 ConcurrentJSLocker locker(codeBlock->m_lock);
1953                 byValInfo->seen = true;
1954                 byValInfo->cachedId = propertyName;
1955                 if (subscript.isSymbol())
1956                     byValInfo->cachedSymbol.set(vm, codeBlock, asSymbol(subscript));
1957                 optimizationResult = OptimizationResult::SeenOnce;
1958             }
1959         }
1960     }
1961
1962     if (optimizationResult != OptimizationResult::Optimized && optimizationResult != OptimizationResult::SeenOnce) {
1963         // If we take slow path more than 10 times without patching then make sure we
1964         // never make that mistake again. For cases where we see non-index-intercepting
1965         // objects, this gives 10 iterations worth of opportunity for us to observe
1966         // that the get_by_val may be polymorphic. We count up slowPathCount even if
1967         // the result is GiveUp.
1968         if (++byValInfo->slowPathCount >= 10)
1969             optimizationResult = OptimizationResult::GiveUp;
1970     }
1971
1972     return optimizationResult;
1973 }
1974
1975 extern "C" {
1976
1977 EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo* byValInfo)
1978 {
1979     VM& vm = exec->vm();
1980     NativeCallFrameTracer tracer(&vm, exec);
1981     JSValue baseValue = JSValue::decode(encodedBase);
1982     JSValue subscript = JSValue::decode(encodedSubscript);
1983
1984     JSValue result = getByVal(exec, baseValue, subscript, byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS));
1985     return JSValue::encode(result);
1986 }
1987
1988 EncodedJSValue JIT_OPERATION operationGetByValOptimize(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo* byValInfo)
1989 {
1990     VM& vm = exec->vm();
1991     NativeCallFrameTracer tracer(&vm, exec);
1992     auto scope = DECLARE_THROW_SCOPE(vm);
1993
1994     JSValue baseValue = JSValue::decode(encodedBase);
1995     JSValue subscript = JSValue::decode(encodedSubscript);
1996     ReturnAddressPtr returnAddress = ReturnAddressPtr(OUR_RETURN_ADDRESS);
1997     OptimizationResult result = tryGetByValOptimize(exec, baseValue, subscript, byValInfo, returnAddress);
1998     RETURN_IF_EXCEPTION(scope, { });
1999     if (result == OptimizationResult::GiveUp) {
2000         // Don't ever try to optimize.
2001         byValInfo->tookSlowPath = true;
2002         ctiPatchCallByReturnAddress(returnAddress, operationGetByValGeneric);
2003     }
2004
2005     RELEASE_AND_RETURN(scope, JSValue::encode(getByVal(exec, baseValue, subscript, byValInfo, returnAddress)));
2006 }
2007
2008 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo* byValInfo)
2009 {
2010     VM& vm = exec->vm();
2011     NativeCallFrameTracer tracer(&vm, exec);
2012     JSValue baseValue = JSValue::decode(encodedBase);
2013     JSValue subscript = JSValue::decode(encodedSubscript);
2014     
2015     ASSERT(baseValue.isObject());
2016     ASSERT(subscript.isUInt32AsAnyInt());
2017
2018     JSObject* object = asObject(baseValue);
2019     bool didOptimize = false;
2020
2021     ASSERT(exec->bytecodeOffset());
2022     ASSERT(!byValInfo->stubRoutine);
2023     
2024     if (hasOptimizableIndexing(object->structure(vm))) {
2025         // Attempt to optimize.
2026         JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
2027         if (arrayMode != byValInfo->arrayMode) {
2028             JIT::compileHasIndexedProperty(&vm, exec->codeBlock(), byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
2029             didOptimize = true;
2030         }
2031     }
2032     
2033     if (!didOptimize) {
2034         // If we take slow path more than 10 times without patching then make sure we
2035         // never make that mistake again. Or, if we failed to patch and we have some object
2036         // that intercepts indexed get, then don't even wait until 10 times. For cases
2037         // where we see non-index-intercepting objects, this gives 10 iterations worth of
2038         // opportunity for us to observe that the get_by_val may be polymorphic.
2039         if (++byValInfo->slowPathCount >= 10
2040             || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
2041             // Don't ever try to optimize.
2042             ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationHasIndexedPropertyGeneric);
2043         }
2044     }
2045
2046     uint32_t index = subscript.asUInt32AsAnyInt();
2047     if (object->canGetIndexQuickly(index))
2048         return JSValue::encode(JSValue(JSValue::JSTrue));
2049
2050     if (!CommonSlowPaths::canAccessArgumentIndexQuickly(*object, index)) {
2051         // FIXME: This will make us think that in-bounds typed array accesses are actually
2052         // out-of-bounds.
2053         // https://bugs.webkit.org/show_bug.cgi?id=149886
2054         byValInfo->arrayProfile->setOutOfBounds();
2055     }
2056     return JSValue::encode(jsBoolean(object->hasPropertyGeneric(exec, index, PropertySlot::InternalMethodType::GetOwnProperty)));
2057 }
2058     
2059 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo* byValInfo)
2060 {
2061     VM& vm = exec->vm();
2062     NativeCallFrameTracer tracer(&vm, exec);
2063     JSValue baseValue = JSValue::decode(encodedBase);
2064     JSValue subscript = JSValue::decode(encodedSubscript);
2065     
2066     ASSERT(baseValue.isObject());
2067     ASSERT(subscript.isUInt32AsAnyInt());
2068
2069     JSObject* object = asObject(baseValue);
2070     uint32_t index = subscript.asUInt32AsAnyInt();
2071     if (object->canGetIndexQuickly(index))
2072         return JSValue::encode(JSValue(JSValue::JSTrue));
2073
2074     if (!CommonSlowPaths::canAccessArgumentIndexQuickly(*object, index)) {
2075         // FIXME: This will make us think that in-bounds typed array accesses are actually
2076         // out-of-bounds.
2077         // https://bugs.webkit.org/show_bug.cgi?id=149886
2078         byValInfo->arrayProfile->setOutOfBounds();
2079     }
2080     return JSValue::encode(jsBoolean(object->hasPropertyGeneric(exec, index, PropertySlot::InternalMethodType::GetOwnProperty)));
2081 }
2082     
2083 EncodedJSValue JIT_OPERATION operationGetByValString(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo* byValInfo)
2084 {
2085     VM& vm = exec->vm();
2086     NativeCallFrameTracer tracer(&vm, exec);
2087     auto scope = DECLARE_THROW_SCOPE(vm);
2088     JSValue baseValue = JSValue::decode(encodedBase);
2089     JSValue subscript = JSValue::decode(encodedSubscript);
2090     
2091     JSValue result;
2092     if (LIKELY(subscript.isUInt32())) {
2093         uint32_t i = subscript.asUInt32();
2094         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
2095             RELEASE_AND_RETURN(scope, JSValue::encode(asString(baseValue)->getIndex(exec, i)));
2096
2097         result = baseValue.get(exec, i);
2098         RETURN_IF_EXCEPTION(scope, encodedJSValue());
2099         if (!isJSString(baseValue)) {
2100             ASSERT(exec->bytecodeOffset());
2101             auto getByValFunction = byValInfo->stubRoutine ? operationGetByValGeneric : operationGetByValOptimize;
2102             ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), getByValFunction);
2103         }
2104     } else {
2105         baseValue.requireObjectCoercible(exec);
2106         RETURN_IF_EXCEPTION(scope, encodedJSValue());
2107         auto property = subscript.toPropertyKey(exec);
2108         RETURN_IF_EXCEPTION(scope, encodedJSValue());
2109         scope.release();
2110         result = baseValue.get(exec, property);
2111     }
2112
2113     return JSValue::encode(result);
2114 }
2115
2116 EncodedJSValue JIT_OPERATION operationDeleteByIdJSResult(ExecState* exec, EncodedJSValue base, UniquedStringImpl* uid)
2117 {
2118     return JSValue::encode(jsBoolean(operationDeleteById(exec, base, uid)));
2119 }
2120
2121 size_t JIT_OPERATION operationDeleteById(ExecState* exec, EncodedJSValue encodedBase, UniquedStringImpl* uid)
2122 {
2123     VM& vm = exec->vm();
2124     NativeCallFrameTracer tracer(&vm, exec);
2125     auto scope = DECLARE_THROW_SCOPE(vm);
2126
2127     JSObject* baseObj = JSValue::decode(encodedBase).toObject(exec);
2128     RETURN_IF_EXCEPTION(scope, false);
2129     if (!baseObj)
2130         return false;
2131     bool couldDelete = baseObj->methodTable(vm)->deleteProperty(baseObj, exec, Identifier::fromUid(&vm, uid));
2132     RETURN_IF_EXCEPTION(scope, false);
2133     if (!couldDelete && exec->codeBlock()->isStrictMode())
2134         throwTypeError(exec, scope, UnableToDeletePropertyError);
2135     return couldDelete;
2136 }
2137
2138 EncodedJSValue JIT_OPERATION operationDeleteByValJSResult(ExecState* exec, EncodedJSValue base,  EncodedJSValue key)
2139 {
2140     return JSValue::encode(jsBoolean(operationDeleteByVal(exec, base, key)));
2141 }
2142
2143 size_t JIT_OPERATION operationDeleteByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedKey)
2144 {
2145     VM& vm = exec->vm();
2146     NativeCallFrameTracer tracer(&vm, exec);
2147     auto scope = DECLARE_THROW_SCOPE(vm);
2148
2149     JSObject* baseObj = JSValue::decode(encodedBase).toObject(exec);
2150     RETURN_IF_EXCEPTION(scope, false);
2151     JSValue key = JSValue::decode(encodedKey);
2152     if (!baseObj)
2153         return false;
2154
2155     bool couldDelete;
2156     uint32_t index;
2157     if (key.getUInt32(index))
2158         couldDelete = baseObj->methodTable(vm)->deletePropertyByIndex(baseObj, exec, index);
2159     else {
2160         Identifier property = key.toPropertyKey(exec);
2161         RETURN_IF_EXCEPTION(scope, false);
2162         couldDelete = baseObj->methodTable(vm)->deleteProperty(baseObj, exec, property);
2163     }
2164     RETURN_IF_EXCEPTION(scope, false);
2165     if (!couldDelete && exec->codeBlock()->isStrictMode())
2166         throwTypeError(exec, scope, UnableToDeletePropertyError);
2167     return couldDelete;
2168 }
2169
2170 JSCell* JIT_OPERATION operationPushWithScope(ExecState* exec, JSCell* currentScopeCell, EncodedJSValue objectValue)
2171 {
2172     VM& vm = exec->vm();
2173     NativeCallFrameTracer tracer(&vm, exec);
2174     auto scope = DECLARE_THROW_SCOPE(vm);
2175
2176     JSObject* object = JSValue::decode(objectValue).toObject(exec);
2177     RETURN_IF_EXCEPTION(scope, nullptr);
2178
2179     JSScope* currentScope = jsCast<JSScope*>(currentScopeCell);
2180
2181     return JSWithScope::create(vm, exec->lexicalGlobalObject(), currentScope, object);
2182 }
2183
2184 JSCell* JIT_OPERATION operationPushWithScopeObject(ExecState* exec, JSCell* currentScopeCell, JSObject* object)
2185 {
2186     VM& vm = exec->vm();
2187     NativeCallFrameTracer tracer(&vm, exec);
2188     JSScope* currentScope = jsCast<JSScope*>(currentScopeCell);
2189     return JSWithScope::create(vm, exec->lexicalGlobalObject(), currentScope, object);
2190 }
2191
2192 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedProto)
2193 {
2194     VM& vm = exec->vm();
2195     NativeCallFrameTracer tracer(&vm, exec);
2196     JSValue value = JSValue::decode(encodedValue);
2197     JSValue proto = JSValue::decode(encodedProto);
2198     
2199     bool result = JSObject::defaultHasInstance(exec, value, proto);
2200     return JSValue::encode(jsBoolean(result));
2201 }
2202
2203 EncodedJSValue JIT_OPERATION operationInstanceOfGeneric(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedProto)
2204 {
2205     VM& vm = exec->vm();
2206     NativeCallFrameTracer tracer(&vm, exec);
2207     JSValue value = JSValue::decode(encodedValue);
2208     JSValue proto = JSValue::decode(encodedProto);
2209     
2210     stubInfo->tookSlowPath = true;
2211     
2212     bool result = JSObject::defaultHasInstance(exec, value, proto);
2213     return JSValue::encode(jsBoolean(result));
2214 }
2215
2216 EncodedJSValue JIT_OPERATION operationInstanceOfOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedProto)
2217 {
2218     VM& vm = exec->vm();
2219     NativeCallFrameTracer tracer(&vm, exec);
2220     auto scope = DECLARE_THROW_SCOPE(vm);
2221     JSValue value = JSValue::decode(encodedValue);
2222     JSValue proto = JSValue::decode(encodedProto);
2223     
2224     bool result = JSObject::defaultHasInstance(exec, value, proto);
2225     RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
2226     
2227     if (stubInfo->considerCaching(exec->codeBlock(), value.structureOrNull()))
2228         repatchInstanceOf(exec, value, proto, *stubInfo, result);
2229     
2230     return JSValue::encode(jsBoolean(result));
2231 }
2232
2233 int32_t JIT_OPERATION operationSizeFrameForForwardArguments(ExecState* exec, EncodedJSValue, int32_t numUsedStackSlots, int32_t)
2234 {
2235     VM& vm = exec->vm();
2236     NativeCallFrameTracer tracer(&vm, exec);
2237     return sizeFrameForForwardArguments(exec, vm, numUsedStackSlots);
2238 }
2239
2240 int32_t JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset)
2241 {
2242     VM& vm = exec->vm();
2243     NativeCallFrameTracer tracer(&vm, exec);
2244     JSValue arguments = JSValue::decode(encodedArguments);
2245     return sizeFrameForVarargs(exec, vm, arguments, numUsedStackSlots, firstVarArgOffset);
2246 }
2247
2248 CallFrame* JIT_OPERATION operationSetupForwardArgumentsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue, int32_t, int32_t length)
2249 {
2250     VM& vm = exec->vm();
2251     NativeCallFrameTracer tracer(&vm, exec);
2252     setupForwardArgumentsFrame(exec, newCallFrame, length);
2253     return newCallFrame;
2254 }
2255
2256 CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset, int32_t length)
2257 {
2258     VM& vm = exec->vm();
2259     NativeCallFrameTracer tracer(&vm, exec);
2260     JSValue arguments = JSValue::decode(encodedArguments);
2261     setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset, length);
2262     return newCallFrame;
2263 }
2264
2265 char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
2266 {
2267     VM& vm = exec->vm();
2268     NativeCallFrameTracer tracer(&vm, exec);
2269     JSValue key = JSValue::decode(encodedKey);
2270     CodeBlock* codeBlock = exec->codeBlock();
2271
2272     SimpleJumpTable& jumpTable = codeBlock->switchJumpTable(tableIndex);
2273     void* result = jumpTable.ctiDefault.executableAddress();
2274
2275     if (key.isString()) {
2276         StringImpl* value = asString(key)->value(exec).impl();
2277         if (value->length() == 1)
2278             result = jumpTable.ctiForValue((*value)[0]).executableAddress();
2279     }
2280
2281     assertIsTaggedWith(result, JSSwitchPtrTag);
2282     return reinterpret_cast<char*>(result);
2283 }
2284
2285 char* JIT_OPERATION operationSwitchImmWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
2286 {
2287     VM& vm = exec->vm();
2288     NativeCallFrameTracer tracer(&vm, exec);
2289     JSValue key = JSValue::decode(encodedKey);
2290     CodeBlock* codeBlock = exec->codeBlock();
2291
2292     SimpleJumpTable& jumpTable = codeBlock->switchJumpTable(tableIndex);
2293     void* result;
2294     if (key.isInt32())
2295         result = jumpTable.ctiForValue(key.asInt32()).executableAddress();
2296     else if (key.isDouble() && key.asDouble() == static_cast<int32_t>(key.asDouble()))
2297         result = jumpTable.ctiForValue(static_cast<int32_t>(key.asDouble())).executableAddress();
2298     else
2299         result = jumpTable.ctiDefault.executableAddress();
2300     assertIsTaggedWith(result, JSSwitchPtrTag);
2301     return reinterpret_cast<char*>(result);
2302 }
2303
2304 char* JIT_OPERATION operationSwitchStringWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
2305 {
2306     VM& vm = exec->vm();
2307     NativeCallFrameTracer tracer(&vm, exec);
2308     JSValue key = JSValue::decode(encodedKey);
2309     CodeBlock* codeBlock = exec->codeBlock();
2310
2311     void* result;
2312     StringJumpTable& jumpTable = codeBlock->stringSwitchJumpTable(tableIndex);
2313
2314     if (key.isString()) {
2315         StringImpl* value = asString(key)->value(exec).impl();
2316         result = jumpTable.ctiForValue(value).executableAddress();
2317     } else
2318         result = jumpTable.ctiDefault.executableAddress();
2319
2320     assertIsTaggedWith(result, JSSwitchPtrTag);
2321     return reinterpret_cast<char*>(result);
2322 }
2323
2324 EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState* exec, const Instruction* pc)
2325 {
2326     VM& vm = exec->vm();
2327     NativeCallFrameTracer tracer(&vm, exec);
2328     auto throwScope = DECLARE_THROW_SCOPE(vm);
2329
2330     CodeBlock* codeBlock = exec->codeBlock();
2331
2332     auto bytecode = pc->as<OpGetFromScope>();
2333     const Identifier& ident = codeBlock->identifier(bytecode.m_var);
2334     JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(bytecode.m_scope.offset()).jsValue());
2335     GetPutInfo& getPutInfo = bytecode.metadata(codeBlock).m_getPutInfo;
2336
2337     // ModuleVar is always converted to ClosureVar for get_from_scope.
2338     ASSERT(getPutInfo.resolveType() != ModuleVar);
2339
2340     RELEASE_AND_RETURN(throwScope, JSValue::encode(scope->getPropertySlot(exec, ident, [&] (bool found, PropertySlot& slot) -> JSValue {
2341         if (!found) {
2342             if (getPutInfo.resolveMode() == ThrowIfNotFound)
2343                 throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
2344             return jsUndefined();
2345         }
2346
2347         JSValue result = JSValue();
2348         if (scope->isGlobalLexicalEnvironment()) {
2349             // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
2350             result = slot.getValue(exec, ident);
2351             if (result == jsTDZValue()) {
2352                 throwException(exec, throwScope, createTDZError(exec));
2353                 return jsUndefined();
2354             }
2355         }
2356
2357         CommonSlowPaths::tryCacheGetFromScopeGlobal(exec, vm, bytecode, scope, slot, ident);
2358
2359         if (!result)
2360             return slot.getValue(exec, ident);
2361         return result;
2362     })));
2363 }
2364
2365 void JIT_OPERATION operationPutToScope(ExecState* exec, const Instruction* pc)
2366 {
2367     VM& vm = exec->vm();
2368     NativeCallFrameTracer tracer(&vm, exec);
2369     auto throwScope = DECLARE_THROW_SCOPE(vm);
2370
2371     CodeBlock* codeBlock = exec->codeBlock();
2372     auto bytecode = pc->as<OpPutToScope>();
2373     auto& metadata = bytecode.metadata(codeBlock);
2374
2375     const Identifier& ident = codeBlock->identifier(bytecode.m_var);
2376     JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(bytecode.m_scope.offset()).jsValue());
2377     JSValue value = exec->r(bytecode.m_value.offset()).jsValue();
2378     GetPutInfo& getPutInfo = metadata.m_getPutInfo;
2379
2380     // ModuleVar does not keep the scope register value alive in DFG.
2381     ASSERT(getPutInfo.resolveType() != ModuleVar);
2382
2383     if (getPutInfo.resolveType() == LocalClosureVar) {
2384         JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
2385         environment->variableAt(ScopeOffset(metadata.m_operand)).set(vm, environment, value);
2386         if (WatchpointSet* set = metadata.m_watchpointSet)
2387             set->touch(vm, "Executed op_put_scope<LocalClosureVar>");
2388         return;
2389     }
2390
2391     bool hasProperty = scope->hasProperty(exec, ident);
2392     RETURN_IF_EXCEPTION(throwScope, void());
2393     if (hasProperty
2394         && scope->isGlobalLexicalEnvironment()
2395         && !isInitialization(getPutInfo.initializationMode())) {
2396         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
2397         PropertySlot slot(scope, PropertySlot::InternalMethodType::Get);
2398         JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
2399         if (slot.getValue(exec, ident) == jsTDZValue()) {
2400             throwException(exec, throwScope, createTDZError(exec));
2401             return;
2402         }
2403     }
2404
2405     if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty) {
2406         throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
2407         return;
2408     }
2409
2410     PutPropertySlot slot(scope, codeBlock->isStrictMode(), PutPropertySlot::UnknownContext, isInitialization(getPutInfo.initializationMode()));
2411     scope->methodTable(vm)->put(scope, exec, ident, value, slot);
2412     
2413     RETURN_IF_EXCEPTION(throwScope, void());
2414
2415     CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, bytecode, scope, slot, ident);
2416 }
2417
2418 void JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExceptionValue)
2419 {
2420     VM* vm = &exec->vm();
2421     NativeCallFrameTracer tracer(vm, exec);
2422     auto scope = DECLARE_THROW_SCOPE(*vm);
2423
2424     JSValue exceptionValue = JSValue::decode(encodedExceptionValue);
2425     throwException(exec, scope, exceptionValue);
2426
2427     // Results stored out-of-band in vm.targetMachinePCForThrow & vm.callFrameForCatch
2428     genericUnwind(vm, exec);
2429 }
2430
2431 char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
2432 {
2433     VM& vm = exec->vm();
2434     NativeCallFrameTracer tracer(&vm, exec);
2435
2436     ASSERT(!object->structure(vm)->outOfLineCapacity());
2437     Butterfly* result = object->allocateMoreOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
2438     object->nukeStructureAndSetButterfly(vm, object->structureID(), result);
2439     return reinterpret_cast<char*>(result);
2440 }
2441
2442 char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
2443 {
2444     VM& vm = exec->vm();
2445     NativeCallFrameTracer tracer(&vm, exec);
2446
2447     Butterfly* result = object->allocateMoreOutOfLineStorage(vm, object->structure(vm)->outOfLineCapacity(), newSize);
2448     object->nukeStructureAndSetButterfly(vm, object->structureID(), result);
2449     return reinterpret_cast<char*>(result);
2450 }
2451
2452 void JIT_OPERATION operationOSRWriteBarrier(ExecState* exec, JSCell* cell)
2453 {
2454     VM* vm = &exec->vm();
2455     NativeCallFrameTracer tracer(vm, exec);
2456     vm->heap.writeBarrier(cell);
2457 }
2458
2459 void JIT_OPERATION operationWriteBarrierSlowPath(ExecState* exec, JSCell* cell)
2460 {
2461     VM* vm = &exec->vm();
2462     NativeCallFrameTracer tracer(vm, exec);
2463     vm->heap.writeBarrierSlowPath(cell);
2464 }
2465
2466 void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec)
2467 {
2468     NativeCallFrameTracer tracer(vm, exec);
2469     genericUnwind(vm, exec);
2470     ASSERT(vm->targetMachinePCForThrow);
2471 }
2472
2473 void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM* vm, ExecState* exec)
2474 {
2475     ASSERT(exec->isStackOverflowFrame());
2476     ASSERT(jsCast<ErrorInstance*>(vm->exceptionForInspection()->value().asCell())->isStackOverflowError());
2477     lookupExceptionHandler(vm, exec);
2478 }
2479
2480 void JIT_OPERATION operationVMHandleException(ExecState* exec)
2481 {
2482     VM* vm = &exec->vm();
2483     NativeCallFrameTracer tracer(vm, exec);
2484     genericUnwind(vm, exec);
2485 }
2486
2487 // This function "should" just take the ExecState*, but doing so would make it more difficult
2488 // to call from exception check sites. So, unlike all of our other functions, we allow
2489 // ourselves to play some gnarly ABI tricks just to simplify the calling convention. This is
2490 // particularly safe here since this is never called on the critical path - it's only for
2491 // testing.
2492 void JIT_OPERATION operationExceptionFuzz(ExecState* exec)
2493 {
2494     VM* vm = &exec->vm();
2495     NativeCallFrameTracer tracer(vm, exec);
2496     auto scope = DECLARE_THROW_SCOPE(*vm);
2497     UNUSED_PARAM(scope);
2498 #if COMPILER(GCC_COMPATIBLE)
2499     void* returnPC = __builtin_return_address(0);
2500     doExceptionFuzzing(exec, scope, "JITOperations", returnPC);
2501 #endif // COMPILER(GCC_COMPATIBLE)
2502 }
2503
2504 ALWAYS_INLINE static EncodedJSValue unprofiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
2505 {
2506     VM* vm = &exec->vm();
2507     NativeCallFrameTracer tracer(vm, exec);
2508     
2509     JSValue op1 = JSValue::decode(encodedOp1);
2510     JSValue op2 = JSValue::decode(encodedOp2);
2511     
2512     return JSValue::encode(jsAdd(exec, op1, op2));
2513 }
2514
2515 ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile)
2516 {
2517     VM* vm = &exec->vm();
2518     NativeCallFrameTracer tracer(vm, exec);
2519     
2520     JSValue op1 = JSValue::decode(encodedOp1);
2521     JSValue op2 = JSValue::decode(encodedOp2);
2522
2523     arithProfile.observeLHSAndRHS(op1, op2);
2524     JSValue result = jsAdd(exec, op1, op2);
2525     arithProfile.observeResult(result);
2526
2527     return JSValue::encode(result);
2528 }
2529
2530 EncodedJSValue JIT_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
2531 {
2532     return unprofiledAdd(exec, encodedOp1, encodedOp2);
2533 }
2534
2535 EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
2536 {
2537     ASSERT(arithProfile);
2538     return profiledAdd(exec, encodedOp1, encodedOp2, *arithProfile);
2539 }
2540
2541 EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC* addIC)
2542 {
2543     VM* vm = &exec->vm();
2544     NativeCallFrameTracer tracer(vm, exec);
2545     
2546     JSValue op1 = JSValue::decode(encodedOp1);
2547     JSValue op2 = JSValue::decode(encodedOp2);
2548
2549     ArithProfile* arithProfile = addIC->arithProfile();
2550     ASSERT(arithProfile);
2551     arithProfile->observeLHSAndRHS(op1, op2);
2552     auto nonOptimizeVariant = operationValueAddProfiledNoOptimize;
2553     addIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant);
2554
2555 #if ENABLE(MATH_IC_STATS)
2556     exec->codeBlock()->dumpMathICStats();
2557 #endif
2558     
2559     JSValue result = jsAdd(exec, op1, op2);
2560     arithProfile->observeResult(result);
2561
2562     return JSValue::encode(result);
2563 }
2564
2565 EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC* addIC)
2566 {
2567     VM* vm = &exec->vm();
2568     NativeCallFrameTracer tracer(vm, exec);
2569
2570     ArithProfile* arithProfile = addIC->arithProfile();
2571     ASSERT(arithProfile);
2572     return profiledAdd(exec, encodedOp1, encodedOp2, *arithProfile);
2573 }
2574
2575 EncodedJSValue JIT_OPERATION operationValueAddOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC* addIC)
2576 {
2577     VM* vm = &exec->vm();
2578     NativeCallFrameTracer tracer(vm, exec);
2579
2580     JSValue op1 = JSValue::decode(encodedOp1);
2581     JSValue op2 = JSValue::decode(encodedOp2);
2582
2583     auto nonOptimizeVariant = operationValueAddNoOptimize;
2584     if (ArithProfile* arithProfile = addIC->arithProfile())
2585         arithProfile->observeLHSAndRHS(op1, op2);
2586     addIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant);
2587
2588 #if ENABLE(MATH_IC_STATS)
2589     exec->codeBlock()->dumpMathICStats();
2590 #endif
2591
2592     return JSValue::encode(jsAdd(exec, op1, op2));
2593 }
2594
2595 EncodedJSValue JIT_OPERATION operationValueAddNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*)
2596 {
2597     VM* vm = &exec->vm();
2598     NativeCallFrameTracer tracer(vm, exec);
2599     
2600     JSValue op1 = JSValue::decode(encodedOp1);
2601     JSValue op2 = JSValue::decode(encodedOp2);
2602     
2603     JSValue result = jsAdd(exec, op1, op2);
2604
2605     return JSValue::encode(result);
2606 }
2607
2608 ALWAYS_INLINE static EncodedJSValue unprofiledMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
2609 {
2610     JSValue op1 = JSValue::decode(encodedOp1);
2611     JSValue op2 = JSValue::decode(encodedOp2);
2612
2613     return JSValue::encode(jsMul(exec, op1, op2));
2614 }
2615
2616 ALWAYS_INLINE static EncodedJSValue profiledMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)
2617 {
2618     VM& vm = exec->vm();
2619     auto scope = DECLARE_THROW_SCOPE(vm);
2620     JSValue op1 = JSValue::decode(encodedOp1);
2621     JSValue op2 = JSValue::decode(encodedOp2);
2622
2623     if (shouldObserveLHSAndRHSTypes)
2624         arithProfile.observeLHSAndRHS(op1, op2);
2625
2626     JSValue result = jsMul(exec, op1, op2);
2627     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2628     arithProfile.observeResult(result);
2629     return JSValue::encode(result);
2630 }
2631
2632 EncodedJSValue JIT_OPERATION operationValueMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
2633 {
2634     VM* vm = &exec->vm();
2635     NativeCallFrameTracer tracer(vm, exec);
2636
2637     return unprofiledMul(exec, encodedOp1, encodedOp2);
2638 }
2639
2640 EncodedJSValue JIT_OPERATION operationValueMulNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*)
2641 {
2642     VM* vm = &exec->vm();
2643     NativeCallFrameTracer tracer(vm, exec);
2644
2645     return unprofiledMul(exec, encodedOp1, encodedOp2);
2646 }
2647
2648 EncodedJSValue JIT_OPERATION operationValueMulOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
2649 {
2650     VM* vm = &exec->vm();
2651     NativeCallFrameTracer tracer(vm, exec);
2652
2653     auto nonOptimizeVariant = operationValueMulNoOptimize;
2654     if (ArithProfile* arithProfile = mulIC->arithProfile())
2655         arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
2656     mulIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant);
2657
2658 #if ENABLE(MATH_IC_STATS)
2659     exec->codeBlock()->dumpMathICStats();
2660 #endif
2661
2662     return unprofiledMul(exec, encodedOp1, encodedOp2);
2663 }
2664
2665 EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
2666 {
2667     VM* vm = &exec->vm();
2668     NativeCallFrameTracer tracer(vm, exec);
2669
2670     ASSERT(arithProfile);
2671     return profiledMul(exec, encodedOp1, encodedOp2, *arithProfile);
2672 }
2673
2674 EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
2675 {
2676     VM* vm = &exec->vm();
2677     NativeCallFrameTracer tracer(vm, exec);
2678
2679     ArithProfile* arithProfile = mulIC->arithProfile();
2680     ASSERT(arithProfile);
2681     arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
2682     auto nonOptimizeVariant = operationValueMulProfiledNoOptimize;
2683     mulIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant);
2684
2685 #if ENABLE(MATH_IC_STATS)
2686     exec->codeBlock()->dumpMathICStats();
2687 #endif
2688
2689     return profiledMul(exec, encodedOp1, encodedOp2, *arithProfile, false);
2690 }
2691
2692 EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
2693 {
2694     VM* vm = &exec->vm();
2695     NativeCallFrameTracer tracer(vm, exec);
2696
2697     ArithProfile* arithProfile = mulIC->arithProfile();
2698     ASSERT(arithProfile);
2699     return profiledMul(exec, encodedOp1, encodedOp2, *arithProfile);
2700 }
2701
2702 ALWAYS_INLINE static EncodedJSValue unprofiledNegate(ExecState* exec, EncodedJSValue encodedOperand)
2703 {
2704     VM& vm = exec->vm();
2705     auto scope = DECLARE_THROW_SCOPE(vm);
2706     NativeCallFrameTracer tracer(&vm, exec);
2707     
2708     JSValue operand = JSValue::decode(encodedOperand);
2709     
2710     JSValue primValue = operand.toPrimitive(exec, PreferNumber);
2711     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2712     
2713     if (primValue.isBigInt())
2714         return JSValue::encode(JSBigInt::unaryMinus(vm, asBigInt(primValue)));
2715     
2716     double number = primValue.toNumber(exec);
2717     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2718     return JSValue::encode(jsNumber(-number));
2719 }
2720
2721 ALWAYS_INLINE static EncodedJSValue profiledNegate(ExecState* exec, EncodedJSValue encodedOperand, ArithProfile& arithProfile)
2722 {
2723     VM& vm = exec->vm();
2724     auto scope = DECLARE_THROW_SCOPE(vm);
2725     NativeCallFrameTracer tracer(&vm, exec);
2726
2727     JSValue operand = JSValue::decode(encodedOperand);
2728     arithProfile.observeLHS(operand);
2729     
2730     JSValue primValue = operand.toPrimitive(exec);
2731     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2732     
2733     if (primValue.isBigInt()) {
2734         JSBigInt* result = JSBigInt::unaryMinus(vm, asBigInt(primValue));
2735         arithProfile.observeResult(result);
2736
2737         return JSValue::encode(result);
2738     }
2739
2740     double number = primValue.toNumber(exec);
2741     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2742     JSValue result = jsNumber(-number);
2743     arithProfile.observeResult(result);
2744     return JSValue::encode(result);
2745 }
2746
2747 EncodedJSValue JIT_OPERATION operationArithNegate(ExecState* exec, EncodedJSValue operand)
2748 {
2749     return unprofiledNegate(exec, operand);
2750 }
2751
2752 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState* exec, EncodedJSValue operand, ArithProfile* arithProfile)
2753 {
2754     ASSERT(arithProfile);
2755     return profiledNegate(exec, operand, *arithProfile);
2756 }
2757
2758 EncodedJSValue JIT_OPERATION operationArithNegateProfiledOptimize(ExecState* exec, EncodedJSValue encodedOperand, JITNegIC* negIC)
2759 {
2760     VM& vm = exec->vm();
2761     auto scope = DECLARE_THROW_SCOPE(vm);
2762     NativeCallFrameTracer tracer(&vm, exec);
2763     
2764     JSValue operand = JSValue::decode(encodedOperand);
2765
2766     ArithProfile* arithProfile = negIC->arithProfile();
2767     ASSERT(arithProfile);
2768     arithProfile->observeLHS(operand);
2769     negIC->generateOutOfLine(exec->codeBlock(), operationArithNegateProfiled);
2770
2771 #if ENABLE(MATH_IC_STATS)
2772     exec->codeBlock()->dumpMathICStats();
2773 #endif
2774     
2775     JSValue primValue = operand.toPrimitive(exec);
2776     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2777     
2778     if (primValue.isBigInt()) {
2779         JSBigInt* result = JSBigInt::unaryMinus(vm, asBigInt(primValue));
2780         arithProfile->observeResult(result);
2781         return JSValue::encode(result);
2782     }
2783
2784     double number = primValue.toNumber(exec);
2785     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2786     JSValue result = jsNumber(-number);
2787     arithProfile->observeResult(result);
2788     return JSValue::encode(result);
2789 }
2790
2791 EncodedJSValue JIT_OPERATION operationArithNegateOptimize(ExecState* exec, EncodedJSValue encodedOperand, JITNegIC* negIC)
2792 {
2793     VM& vm = exec->vm();
2794     auto scope = DECLARE_THROW_SCOPE(vm);
2795     NativeCallFrameTracer tracer(&vm, exec);
2796
2797     JSValue operand = JSValue::decode(encodedOperand);
2798
2799     if (ArithProfile* arithProfile = negIC->arithProfile())
2800         arithProfile->observeLHS(operand);
2801     negIC->generateOutOfLine(exec->codeBlock(), operationArithNegate);
2802
2803 #if ENABLE(MATH_IC_STATS)
2804     exec->codeBlock()->dumpMathICStats();
2805 #endif
2806
2807     JSValue primValue = operand.toPrimitive(exec);
2808     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2809     
2810     if (primValue.isBigInt())
2811         return JSValue::encode(JSBigInt::unaryMinus(vm, asBigInt(primValue)));
2812
2813     double number = primValue.toNumber(exec);
2814     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2815     return JSValue::encode(jsNumber(-number));
2816 }
2817
2818 ALWAYS_INLINE static EncodedJSValue unprofiledSub(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
2819 {
2820     JSValue op1 = JSValue::decode(encodedOp1);
2821     JSValue op2 = JSValue::decode(encodedOp2);
2822     
2823     return JSValue::encode(jsSub(exec, op1, op2));
2824 }
2825
2826 ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)
2827 {
2828     auto scope = DECLARE_THROW_SCOPE(vm);
2829
2830     JSValue op1 = JSValue::decode(encodedOp1);
2831     JSValue op2 = JSValue::decode(encodedOp2);
2832
2833     if (shouldObserveLHSAndRHSTypes)
2834         arithProfile.observeLHSAndRHS(op1, op2);
2835
2836     JSValue result = jsSub(exec, op1, op2);
2837     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2838     arithProfile.observeResult(result);
2839     return JSValue::encode(result);
2840 }
2841
2842 EncodedJSValue JIT_OPERATION operationValueSub(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
2843 {
2844     VM* vm = &exec->vm();
2845     NativeCallFrameTracer tracer(vm, exec);
2846     return unprofiledSub(exec, encodedOp1, encodedOp2);
2847 }
2848
2849 EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
2850 {
2851     ASSERT(arithProfile);
2852
2853     VM* vm = &exec->vm();
2854     NativeCallFrameTracer tracer(vm, exec);
2855
2856     return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
2857 }
2858
2859 EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC)
2860 {
2861     VM* vm = &exec->vm();
2862     NativeCallFrameTracer tracer(vm, exec);
2863
2864     auto nonOptimizeVariant = operationValueSubNoOptimize;
2865     if (ArithProfile* arithProfile = subIC->arithProfile())
2866         arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
2867     subIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant);
2868
2869 #if ENABLE(MATH_IC_STATS)
2870     exec->codeBlock()->dumpMathICStats();
2871 #endif
2872
2873     return unprofiledSub(exec, encodedOp1, encodedOp2);
2874 }
2875
2876 EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*)
2877 {
2878     VM* vm = &exec->vm();
2879     NativeCallFrameTracer tracer(vm, exec);
2880
2881     return unprofiledSub(exec, encodedOp1, encodedOp2);
2882 }
2883
2884 EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC)
2885 {
2886     VM* vm = &exec->vm();
2887     NativeCallFrameTracer tracer(vm, exec);
2888
2889     ArithProfile* arithProfile = subIC->arithProfile();
2890     ASSERT(arithProfile);
2891     arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
2892     auto nonOptimizeVariant = operationValueSubProfiledNoOptimize;
2893     subIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant);
2894
2895 #if ENABLE(MATH_IC_STATS)
2896     exec->codeBlock()->dumpMathICStats();
2897 #endif
2898
2899     return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile, false);
2900 }
2901
2902 EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC)
2903 {
2904     VM* vm = &exec->vm();
2905     NativeCallFrameTracer tracer(vm, exec);
2906
2907     ArithProfile* arithProfile = subIC->arithProfile();
2908     ASSERT(arithProfile);
2909     return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
2910 }
2911
2912 void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec)
2913 {
2914     VM& vm = exec->vm();
2915     NativeCallFrameTracer tracer(&vm, exec);
2916     vm.typeProfilerLog()->processLogEntries(vm, "Log Full, called from inside baseline JIT"_s);
2917 }
2918
2919 void JIT_OPERATION operationProcessShadowChickenLog(ExecState* exec)
2920 {
2921     VM& vm = exec->vm();
2922     NativeCallFrameTracer tracer(&vm, exec);
2923     RELEASE_ASSERT(vm.shadowChicken());
2924     vm.shadowChicken()->update(vm, exec);
2925 }
2926
2927 int32_t JIT_OPERATION operationCheckIfExceptionIsUncatchableAndNotifyProfiler(ExecState* exec)
2928 {
2929     VM& vm = exec->vm();
2930     NativeCallFrameTracer tracer(&vm, exec);
2931     auto scope = DECLARE_THROW_SCOPE(vm);
2932     RELEASE_ASSERT(!!scope.exception());
2933
2934     if (isTerminatedExecutionException(vm, scope.exception())) {
2935         genericUnwind(&vm, exec);
2936         return 1;
2937     }
2938     return 0;
2939 }
2940
2941 } // extern "C"
2942
2943 } // namespace JSC
2944
2945 #endif // ENABLE(JIT)