Replace JSFunctionNameScope with JSLexicalEnvironment for the function name scope.
[WebKit-https.git] / Source / JavaScriptCore / jit / JITOperations.cpp
1 /*
2  * Copyright (C) 2013-2015 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 "ArrayConstructor.h"
32 #include "DFGCompilationMode.h"
33 #include "DFGDriver.h"
34 #include "DFGOSREntry.h"
35 #include "DFGThunks.h"
36 #include "DFGWorklist.h"
37 #include "Debugger.h"
38 #include "DirectArguments.h"
39 #include "Error.h"
40 #include "ErrorHandlingScope.h"
41 #include "ExceptionFuzz.h"
42 #include "GetterSetter.h"
43 #include "HostCallReturnValue.h"
44 #include "JIT.h"
45 #include "JITToDFGDeferredCompilationCallback.h"
46 #include "JSCInlines.h"
47 #include "JSGlobalObjectFunctions.h"
48 #include "JSLexicalEnvironment.h"
49 #include "JSPropertyNameEnumerator.h"
50 #include "JSStackInlines.h"
51 #include "JSWithScope.h"
52 #include "LegacyProfiler.h"
53 #include "ObjectConstructor.h"
54 #include "PropertyName.h"
55 #include "Repatch.h"
56 #include "RepatchBuffer.h"
57 #include "ScopedArguments.h"
58 #include "TestRunnerUtils.h"
59 #include "TypeProfilerLog.h"
60 #include <wtf/InlineASM.h>
61
62 namespace JSC {
63
64 extern "C" {
65
66 #if COMPILER(MSVC)
67 void * _ReturnAddress(void);
68 #pragma intrinsic(_ReturnAddress)
69
70 #define OUR_RETURN_ADDRESS _ReturnAddress()
71 #else
72 #define OUR_RETURN_ADDRESS __builtin_return_address(0)
73 #endif
74
75 #if ENABLE(OPCODE_SAMPLING)
76 #define CTI_SAMPLER vm->interpreter->sampler()
77 #else
78 #define CTI_SAMPLER 0
79 #endif
80
81
82 void JIT_OPERATION operationThrowStackOverflowError(ExecState* exec, CodeBlock* codeBlock)
83 {
84     // We pass in our own code block, because the callframe hasn't been populated.
85     VM* vm = codeBlock->vm();
86
87     VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
88     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
89     if (!callerFrame)
90         callerFrame = exec;
91
92     NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
93     ErrorHandlingScope errorScope(*vm);
94     vm->throwException(callerFrame, createStackOverflowError(callerFrame));
95 }
96
97 int32_t JIT_OPERATION operationCallArityCheck(ExecState* exec)
98 {
99     VM* vm = &exec->vm();
100     VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
101     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
102
103     JSStack& stack = vm->interpreter->stack();
104
105     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForCall);
106     if (missingArgCount < 0) {
107         NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
108         throwStackOverflowError(callerFrame);
109     }
110
111     return missingArgCount;
112 }
113
114 int32_t JIT_OPERATION operationConstructArityCheck(ExecState* exec)
115 {
116     VM* vm = &exec->vm();
117     VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
118     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
119
120     JSStack& stack = vm->interpreter->stack();
121
122     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForConstruct);
123     if (missingArgCount < 0) {
124         NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
125         throwStackOverflowError(callerFrame);
126     }
127
128     return missingArgCount;
129 }
130
131 EncodedJSValue JIT_OPERATION operationGetById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
132 {
133     VM* vm = &exec->vm();
134     NativeCallFrameTracer tracer(vm, exec);
135     
136     stubInfo->tookSlowPath = true;
137     
138     JSValue baseValue = JSValue::decode(base);
139     PropertySlot slot(baseValue);
140     Identifier ident = Identifier::fromUid(vm, uid);
141     return JSValue::encode(baseValue.get(exec, ident, slot));
142 }
143
144 EncodedJSValue JIT_OPERATION operationGetByIdGeneric(ExecState* exec, EncodedJSValue base, UniquedStringImpl* uid)
145 {
146     VM* vm = &exec->vm();
147     NativeCallFrameTracer tracer(vm, exec);
148     
149     JSValue baseValue = JSValue::decode(base);
150     PropertySlot slot(baseValue);
151     Identifier ident = Identifier::fromUid(vm, uid);
152     return JSValue::encode(baseValue.get(exec, ident, slot));
153 }
154
155 EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
156 {
157     VM* vm = &exec->vm();
158     NativeCallFrameTracer tracer(vm, exec);
159
160     Identifier ident = Identifier::fromUid(vm, uid);
161     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
162
163     JSValue baseValue = JSValue::decode(base);
164     PropertySlot slot(baseValue);
165     bool hasResult = baseValue.getPropertySlot(exec, ident, slot);
166     
167     if (accessType == static_cast<AccessType>(stubInfo->accessType))
168         buildGetByIDList(exec, baseValue, ident, slot, *stubInfo);
169
170     return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined());
171 }
172
173 EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
174 {
175     VM* vm = &exec->vm();
176     NativeCallFrameTracer tracer(vm, exec);
177     Identifier ident = Identifier::fromUid(vm, uid);
178
179     JSValue baseValue = JSValue::decode(base);
180     PropertySlot slot(baseValue);
181     
182     bool hasResult = baseValue.getPropertySlot(exec, ident, slot);
183     if (stubInfo->seen)
184         repatchGetByID(exec, baseValue, ident, slot, *stubInfo);
185     else
186         stubInfo->seen = true;
187     
188     return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined());
189
190 }
191
192 EncodedJSValue JIT_OPERATION operationInOptimize(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, UniquedStringImpl* key)
193 {
194     VM* vm = &exec->vm();
195     NativeCallFrameTracer tracer(vm, exec);
196     
197     if (!base->isObject()) {
198         vm->throwException(exec, createInvalidInParameterError(exec, base));
199         return JSValue::encode(jsUndefined());
200     }
201     
202     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
203
204     Identifier ident = Identifier::fromUid(vm, key);
205     PropertySlot slot(base);
206     bool result = asObject(base)->getPropertySlot(exec, ident, slot);
207     
208     RELEASE_ASSERT(accessType == stubInfo->accessType);
209     
210     if (stubInfo->seen)
211         repatchIn(exec, base, ident, result, slot, *stubInfo);
212     else
213         stubInfo->seen = true;
214     
215     return JSValue::encode(jsBoolean(result));
216 }
217
218 EncodedJSValue JIT_OPERATION operationIn(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, UniquedStringImpl* key)
219 {
220     VM* vm = &exec->vm();
221     NativeCallFrameTracer tracer(vm, exec);
222     
223     stubInfo->tookSlowPath = true;
224
225     if (!base->isObject()) {
226         vm->throwException(exec, createInvalidInParameterError(exec, base));
227         return JSValue::encode(jsUndefined());
228     }
229
230     Identifier ident = Identifier::fromUid(vm, key);
231     return JSValue::encode(jsBoolean(asObject(base)->hasProperty(exec, ident)));
232 }
233
234 EncodedJSValue JIT_OPERATION operationGenericIn(ExecState* exec, JSCell* base, EncodedJSValue key)
235 {
236     VM* vm = &exec->vm();
237     NativeCallFrameTracer tracer(vm, exec);
238
239     return JSValue::encode(jsBoolean(CommonSlowPaths::opIn(exec, JSValue::decode(key), base)));
240 }
241
242 void JIT_OPERATION operationPutByIdStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
243 {
244     VM* vm = &exec->vm();
245     NativeCallFrameTracer tracer(vm, exec);
246     
247     stubInfo->tookSlowPath = true;
248     
249     Identifier ident = Identifier::fromUid(vm, uid);
250     PutPropertySlot slot(JSValue::decode(encodedBase), true, exec->codeBlock()->putByIdContext());
251     JSValue::decode(encodedBase).put(exec, ident, JSValue::decode(encodedValue), slot);
252 }
253
254 void JIT_OPERATION operationPutByIdNonStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
255 {
256     VM* vm = &exec->vm();
257     NativeCallFrameTracer tracer(vm, exec);
258     
259     stubInfo->tookSlowPath = true;
260     
261     Identifier ident = Identifier::fromUid(vm, uid);
262     PutPropertySlot slot(JSValue::decode(encodedBase), false, exec->codeBlock()->putByIdContext());
263     JSValue::decode(encodedBase).put(exec, ident, JSValue::decode(encodedValue), slot);
264 }
265
266 void JIT_OPERATION operationPutByIdDirectStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
267 {
268     VM* vm = &exec->vm();
269     NativeCallFrameTracer tracer(vm, exec);
270     
271     stubInfo->tookSlowPath = true;
272     
273     Identifier ident = Identifier::fromUid(vm, uid);
274     PutPropertySlot slot(JSValue::decode(encodedBase), true, exec->codeBlock()->putByIdContext());
275     asObject(JSValue::decode(encodedBase))->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
276 }
277
278 void JIT_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
279 {
280     VM* vm = &exec->vm();
281     NativeCallFrameTracer tracer(vm, exec);
282     
283     stubInfo->tookSlowPath = true;
284     
285     Identifier ident = Identifier::fromUid(vm, uid);
286     PutPropertySlot slot(JSValue::decode(encodedBase), false, exec->codeBlock()->putByIdContext());
287     asObject(JSValue::decode(encodedBase))->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
288 }
289
290 void JIT_OPERATION operationPutByIdStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
291 {
292     VM* vm = &exec->vm();
293     NativeCallFrameTracer tracer(vm, exec);
294     
295     Identifier ident = Identifier::fromUid(vm, uid);
296     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
297
298     JSValue value = JSValue::decode(encodedValue);
299     JSValue baseValue = JSValue::decode(encodedBase);
300     PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
301
302     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
303     baseValue.put(exec, ident, value, slot);
304     
305     if (accessType != static_cast<AccessType>(stubInfo->accessType))
306         return;
307     
308     if (stubInfo->seen)
309         repatchPutByID(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
310     else
311         stubInfo->seen = true;
312 }
313
314 void JIT_OPERATION operationPutByIdNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
315 {
316     VM* vm = &exec->vm();
317     NativeCallFrameTracer tracer(vm, exec);
318     
319     Identifier ident = Identifier::fromUid(vm, uid);
320     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
321
322     JSValue value = JSValue::decode(encodedValue);
323     JSValue baseValue = JSValue::decode(encodedBase);
324     PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
325
326     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;    
327     baseValue.put(exec, ident, value, slot);
328     
329     if (accessType != static_cast<AccessType>(stubInfo->accessType))
330         return;
331     
332     if (stubInfo->seen)
333         repatchPutByID(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
334     else
335         stubInfo->seen = true;
336 }
337
338 void JIT_OPERATION operationPutByIdDirectStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
339 {
340     VM* vm = &exec->vm();
341     NativeCallFrameTracer tracer(vm, exec);
342     
343     Identifier ident = Identifier::fromUid(vm, uid);
344     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
345
346     JSValue value = JSValue::decode(encodedValue);
347     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
348     PutPropertySlot slot(baseObject, true, exec->codeBlock()->putByIdContext());
349     
350     Structure* structure = baseObject->structure(*vm);
351     baseObject->putDirect(exec->vm(), ident, value, slot);
352     
353     if (accessType != static_cast<AccessType>(stubInfo->accessType))
354         return;
355     
356     if (stubInfo->seen)
357         repatchPutByID(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
358     else
359         stubInfo->seen = true;
360 }
361
362 void JIT_OPERATION operationPutByIdDirectNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
363 {
364     VM* vm = &exec->vm();
365     NativeCallFrameTracer tracer(vm, exec);
366     
367     Identifier ident = Identifier::fromUid(vm, uid);
368     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
369
370     JSValue value = JSValue::decode(encodedValue);
371     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
372     PutPropertySlot slot(baseObject, false, exec->codeBlock()->putByIdContext());
373     
374     Structure* structure = baseObject->structure(*vm);
375     baseObject->putDirect(exec->vm(), ident, value, slot);
376     
377     if (accessType != static_cast<AccessType>(stubInfo->accessType))
378         return;
379     
380     if (stubInfo->seen)
381         repatchPutByID(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
382     else
383         stubInfo->seen = true;
384 }
385
386 void JIT_OPERATION operationPutByIdStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
387 {
388     VM* vm = &exec->vm();
389     NativeCallFrameTracer tracer(vm, exec);
390     
391     Identifier ident = Identifier::fromUid(vm, uid);
392     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
393
394     JSValue value = JSValue::decode(encodedValue);
395     JSValue baseValue = JSValue::decode(encodedBase);
396     PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
397     
398     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr; 
399     baseValue.put(exec, ident, value, slot);
400
401     if (accessType != static_cast<AccessType>(stubInfo->accessType))
402         return;
403
404     buildPutByIdList(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
405 }
406
407 void JIT_OPERATION operationPutByIdNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
408 {
409     VM* vm = &exec->vm();
410     NativeCallFrameTracer tracer(vm, exec);
411     
412     Identifier ident = Identifier::fromUid(vm, uid);
413     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
414
415     JSValue value = JSValue::decode(encodedValue);
416     JSValue baseValue = JSValue::decode(encodedBase);
417     PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
418
419     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
420     baseValue.put(exec, ident, value, slot);
421     
422     if (accessType != static_cast<AccessType>(stubInfo->accessType))
423         return;
424     
425     buildPutByIdList(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
426 }
427
428 void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
429 {
430     VM* vm = &exec->vm();
431     NativeCallFrameTracer tracer(vm, exec);
432     
433     Identifier ident = Identifier::fromUid(vm, uid);
434     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
435     
436     JSValue value = JSValue::decode(encodedValue);
437     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
438     PutPropertySlot slot(baseObject, true, exec->codeBlock()->putByIdContext());
439
440     Structure* structure = baseObject->structure(*vm);    
441     baseObject->putDirect(*vm, ident, value, slot);
442     
443     if (accessType != static_cast<AccessType>(stubInfo->accessType))
444         return;
445     
446     buildPutByIdList(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
447 }
448
449 void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
450 {
451     VM* vm = &exec->vm();
452     NativeCallFrameTracer tracer(vm, exec);
453     
454     Identifier ident = Identifier::fromUid(vm, uid);
455     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
456
457     JSValue value = JSValue::decode(encodedValue);
458     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
459     PutPropertySlot slot(baseObject, false, exec->codeBlock()->putByIdContext());
460
461     Structure* structure = baseObject->structure(*vm);    
462     baseObject->putDirect(*vm, ident, value, slot);
463
464     if (accessType != static_cast<AccessType>(stubInfo->accessType))
465         return;
466     
467     buildPutByIdList(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
468 }
469
470 void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)
471 {
472     VM& vm = exec->vm();
473     NativeCallFrameTracer tracer(&vm, exec);
474
475     ASSERT(structure->outOfLineCapacity() > base->structure(vm)->outOfLineCapacity());
476     ASSERT(!vm.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue)));
477     base->setStructureAndReallocateStorageIfNecessary(vm, structure);
478     base->putDirect(vm, offset, JSValue::decode(value));
479 }
480
481 static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value, ArrayProfile* arrayProfile)
482 {
483     VM& vm = callFrame->vm();
484     if (LIKELY(subscript.isUInt32())) {
485         uint32_t i = subscript.asUInt32();
486         if (baseValue.isObject()) {
487             JSObject* object = asObject(baseValue);
488             if (object->canSetIndexQuickly(i))
489                 object->setIndexQuickly(callFrame->vm(), i, value);
490             else {
491                 arrayProfile->setOutOfBounds();
492                 object->methodTable(vm)->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
493             }
494         } else
495             baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
496     } else {
497         auto property = subscript.toPropertyKey(callFrame);
498         if (!callFrame->vm().exception()) { // Don't put to an object if toString threw an exception.
499             PutPropertySlot slot(baseValue, callFrame->codeBlock()->isStrictMode());
500             baseValue.put(callFrame, property, value, slot);
501         }
502     }
503 }
504
505 static void directPutByVal(CallFrame* callFrame, JSObject* baseObject, JSValue subscript, JSValue value, ArrayProfile* arrayProfile)
506 {
507     bool isStrictMode = callFrame->codeBlock()->isStrictMode();
508     if (LIKELY(subscript.isUInt32())) {
509         // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
510         uint32_t index = subscript.asUInt32();
511         ASSERT(isIndex(index));
512         if (baseObject->canSetIndexQuicklyForPutDirect(index)) {
513             baseObject->setIndexQuickly(callFrame->vm(), index, value);
514             return;
515         }
516
517         arrayProfile->setOutOfBounds();
518         baseObject->putDirectIndex(callFrame, index, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
519         return;
520     }
521
522     if (subscript.isDouble()) {
523         double subscriptAsDouble = subscript.asDouble();
524         uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
525         if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) {
526             baseObject->putDirectIndex(callFrame, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
527             return;
528         }
529     }
530
531     // Don't put to an object if toString threw an exception.
532     auto property = subscript.toPropertyKey(callFrame);
533     if (callFrame->vm().exception())
534         return;
535
536     if (Optional<uint32_t> index = parseIndex(property))
537         baseObject->putDirectIndex(callFrame, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
538     else {
539         PutPropertySlot slot(baseObject, isStrictMode);
540         baseObject->putDirect(callFrame->vm(), property, value, slot);
541     }
542 }
543 void JIT_OPERATION operationPutByVal(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
544 {
545     VM& vm = exec->vm();
546     NativeCallFrameTracer tracer(&vm, exec);
547
548     JSValue baseValue = JSValue::decode(encodedBaseValue);
549     JSValue subscript = JSValue::decode(encodedSubscript);
550     JSValue value = JSValue::decode(encodedValue);
551
552     if (baseValue.isObject() && subscript.isInt32()) {
553         // See if it's worth optimizing at all.
554         JSObject* object = asObject(baseValue);
555         bool didOptimize = false;
556
557         unsigned bytecodeOffset = exec->locationAsBytecodeOffset();
558         ASSERT(bytecodeOffset);
559         ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1);
560         ASSERT(!byValInfo.stubRoutine);
561
562         Structure* structure = object->structure(vm);
563         if (hasOptimizableIndexing(structure)) {
564             // Attempt to optimize.
565             JITArrayMode arrayMode = jitArrayModeForStructure(structure);
566             if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
567                 CodeBlock* codeBlock = exec->codeBlock();
568                 ConcurrentJITLocker locker(codeBlock->m_lock);
569                 arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
570
571                 JIT::compilePutByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
572                 didOptimize = true;
573             }
574         }
575
576         if (!didOptimize) {
577             // If we take slow path more than 10 times without patching then make sure we
578             // never make that mistake again. Or, if we failed to patch and we have some object
579             // that intercepts indexed get, then don't even wait until 10 times. For cases
580             // where we see non-index-intercepting objects, this gives 10 iterations worth of
581             // opportunity for us to observe that the get_by_val may be polymorphic.
582             if (++byValInfo.slowPathCount >= 10
583                 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
584                 // Don't ever try to optimize.
585                 ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationPutByValGeneric));
586             }
587         }
588     }
589
590     putByVal(exec, baseValue, subscript, value, arrayProfile);
591 }
592
593 void JIT_OPERATION operationDirectPutByVal(ExecState* callFrame, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
594 {
595     VM& vm = callFrame->vm();
596     NativeCallFrameTracer tracer(&vm, callFrame);
597     
598     JSValue baseValue = JSValue::decode(encodedBaseValue);
599     JSValue subscript = JSValue::decode(encodedSubscript);
600     JSValue value = JSValue::decode(encodedValue);
601     RELEASE_ASSERT(baseValue.isObject());
602     JSObject* object = asObject(baseValue);
603     if (subscript.isInt32()) {
604         // See if it's worth optimizing at all.
605         bool didOptimize = false;
606         
607         unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset();
608         ASSERT(bytecodeOffset);
609         ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
610         ASSERT(!byValInfo.stubRoutine);
611
612         Structure* structure = object->structure(vm);
613         if (hasOptimizableIndexing(structure)) {
614             // Attempt to optimize.
615             JITArrayMode arrayMode = jitArrayModeForStructure(structure);
616             if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
617                 CodeBlock* codeBlock = callFrame->codeBlock();
618                 ConcurrentJITLocker locker(codeBlock->m_lock);
619                 arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
620
621                 JIT::compileDirectPutByVal(&vm, callFrame->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
622                 didOptimize = true;
623             }
624         }
625         
626         if (!didOptimize) {
627             // If we take slow path more than 10 times without patching then make sure we
628             // never make that mistake again. Or, if we failed to patch and we have some object
629             // that intercepts indexed get, then don't even wait until 10 times. For cases
630             // where we see non-index-intercepting objects, this gives 10 iterations worth of
631             // opportunity for us to observe that the get_by_val may be polymorphic.
632             if (++byValInfo.slowPathCount >= 10
633                 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
634                 // Don't ever try to optimize.
635                 ctiPatchCallByReturnAddress(callFrame->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationDirectPutByValGeneric));
636             }
637         }
638     }
639     directPutByVal(callFrame, object, subscript, value, arrayProfile);
640 }
641
642 void JIT_OPERATION operationPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
643 {
644     VM& vm = exec->vm();
645     NativeCallFrameTracer tracer(&vm, exec);
646     
647     JSValue baseValue = JSValue::decode(encodedBaseValue);
648     JSValue subscript = JSValue::decode(encodedSubscript);
649     JSValue value = JSValue::decode(encodedValue);
650
651     putByVal(exec, baseValue, subscript, value, arrayProfile);
652 }
653
654
655 void JIT_OPERATION operationDirectPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
656 {
657     VM& vm = exec->vm();
658     NativeCallFrameTracer tracer(&vm, exec);
659     
660     JSValue baseValue = JSValue::decode(encodedBaseValue);
661     JSValue subscript = JSValue::decode(encodedSubscript);
662     JSValue value = JSValue::decode(encodedValue);
663     RELEASE_ASSERT(baseValue.isObject());
664     directPutByVal(exec, asObject(baseValue), subscript, value, arrayProfile);
665 }
666
667 EncodedJSValue JIT_OPERATION operationCallEval(ExecState* exec, ExecState* execCallee)
668 {
669     UNUSED_PARAM(exec);
670
671     execCallee->setCodeBlock(0);
672
673     if (!isHostFunction(execCallee->calleeAsValue(), globalFuncEval))
674         return JSValue::encode(JSValue());
675
676     VM* vm = &execCallee->vm();
677     JSValue result = eval(execCallee);
678     if (vm->exception())
679         return EncodedJSValue();
680     
681     return JSValue::encode(result);
682 }
683
684 static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
685 {
686     ExecState* exec = execCallee->callerFrame();
687     VM* vm = &exec->vm();
688
689     execCallee->setCodeBlock(0);
690
691     if (kind == CodeForCall) {
692         CallData callData;
693         CallType callType = getCallData(callee, callData);
694     
695         ASSERT(callType != CallTypeJS);
696     
697         if (callType == CallTypeHost) {
698             NativeCallFrameTracer tracer(vm, execCallee);
699             execCallee->setCallee(asObject(callee));
700             vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
701             if (vm->exception())
702                 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
703
704             return reinterpret_cast<void*>(getHostCallReturnValue);
705         }
706     
707         ASSERT(callType == CallTypeNone);
708         exec->vm().throwException(exec, createNotAFunctionError(exec, callee));
709         return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
710     }
711
712     ASSERT(kind == CodeForConstruct);
713     
714     ConstructData constructData;
715     ConstructType constructType = getConstructData(callee, constructData);
716     
717     ASSERT(constructType != ConstructTypeJS);
718     
719     if (constructType == ConstructTypeHost) {
720         NativeCallFrameTracer tracer(vm, execCallee);
721         execCallee->setCallee(asObject(callee));
722         vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
723         if (vm->exception())
724             return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
725
726         return reinterpret_cast<void*>(getHostCallReturnValue);
727     }
728     
729     ASSERT(constructType == ConstructTypeNone);
730     exec->vm().throwException(exec, createNotAConstructorError(exec, callee));
731     return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
732 }
733
734 char* JIT_OPERATION operationLinkCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
735 {
736     ExecState* exec = execCallee->callerFrame();
737     VM* vm = &exec->vm();
738     CodeSpecializationKind kind = callLinkInfo->specializationKind();
739     NativeCallFrameTracer tracer(vm, exec);
740     
741     JSValue calleeAsValue = execCallee->calleeAsValue();
742     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
743     if (!calleeAsFunctionCell) {
744         // FIXME: We should cache these kinds of calls. They can be common and currently they are
745         // expensive.
746         // https://bugs.webkit.org/show_bug.cgi?id=144458
747         return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
748     }
749
750     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
751     JSScope* scope = callee->scopeUnchecked();
752     ExecutableBase* executable = callee->executable();
753
754     MacroAssemblerCodePtr codePtr;
755     CodeBlock* codeBlock = 0;
756     if (executable->isHostFunction())
757         codePtr = executable->entrypointFor(*vm, kind, MustCheckArity, callLinkInfo->registerPreservationMode());
758     else {
759         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
760
761         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
762             exec->vm().throwException(exec, createNotAConstructorError(exec, callee));
763             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
764         }
765
766         JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, scope, kind);
767         if (error) {
768             exec->vm().throwException(exec, error);
769             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
770         }
771         codeBlock = functionExecutable->codeBlockFor(kind);
772         ArityCheckMode arity;
773         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo->callType() == CallLinkInfo::CallVarargs || callLinkInfo->callType() == CallLinkInfo::ConstructVarargs)
774             arity = MustCheckArity;
775         else
776             arity = ArityCheckNotRequired;
777         codePtr = functionExecutable->entrypointFor(*vm, kind, arity, callLinkInfo->registerPreservationMode());
778     }
779     if (!callLinkInfo->seenOnce())
780         callLinkInfo->setSeen();
781     else
782         linkFor(execCallee, *callLinkInfo, codeBlock, callee, codePtr);
783     
784     return reinterpret_cast<char*>(codePtr.executableAddress());
785 }
786
787 inline char* virtualForWithFunction(
788     ExecState* execCallee, CallLinkInfo* callLinkInfo, JSCell*& calleeAsFunctionCell)
789 {
790     ExecState* exec = execCallee->callerFrame();
791     VM* vm = &exec->vm();
792     CodeSpecializationKind kind = callLinkInfo->specializationKind();
793     NativeCallFrameTracer tracer(vm, exec);
794
795     JSValue calleeAsValue = execCallee->calleeAsValue();
796     calleeAsFunctionCell = getJSFunction(calleeAsValue);
797     if (UNLIKELY(!calleeAsFunctionCell))
798         return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
799     
800     JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
801     JSScope* scope = function->scopeUnchecked();
802     ExecutableBase* executable = function->executable();
803     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
804         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
805
806         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
807             exec->vm().throwException(exec, createNotAConstructorError(exec, function));
808             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
809         }
810
811         JSObject* error = functionExecutable->prepareForExecution(execCallee, function, scope, kind);
812         if (error) {
813             exec->vm().throwException(exec, error);
814             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
815         }
816     }
817     return reinterpret_cast<char*>(executable->entrypointFor(
818         *vm, kind, MustCheckArity, callLinkInfo->registerPreservationMode()).executableAddress());
819 }
820
821 char* JIT_OPERATION operationLinkPolymorphicCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
822 {
823     ASSERT(callLinkInfo->specializationKind() == CodeForCall);
824     JSCell* calleeAsFunctionCell;
825     char* result = virtualForWithFunction(execCallee, callLinkInfo, calleeAsFunctionCell);
826
827     linkPolymorphicCall(execCallee, *callLinkInfo, CallVariant(calleeAsFunctionCell));
828     
829     return result;
830 }
831
832 char* JIT_OPERATION operationVirtualCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
833 {
834     JSCell* calleeAsFunctionCellIgnored;
835     return virtualForWithFunction(execCallee, callLinkInfo, calleeAsFunctionCellIgnored);
836 }
837
838 size_t JIT_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
839 {
840     VM* vm = &exec->vm();
841     NativeCallFrameTracer tracer(vm, exec);
842     
843     return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
844 }
845
846 size_t JIT_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
847 {
848     VM* vm = &exec->vm();
849     NativeCallFrameTracer tracer(vm, exec);
850
851     return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
852 }
853
854 size_t JIT_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
855 {
856     VM* vm = &exec->vm();
857     NativeCallFrameTracer tracer(vm, exec);
858
859     return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
860 }
861
862 size_t JIT_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
863 {
864     VM* vm = &exec->vm();
865     NativeCallFrameTracer tracer(vm, exec);
866
867     return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
868 }
869
870 size_t JIT_OPERATION operationConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
871 {
872     VM* vm = &exec->vm();
873     NativeCallFrameTracer tracer(vm, exec);
874     
875     return JSValue::decode(encodedOp).toBoolean(exec);
876 }
877
878 size_t JIT_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
879 {
880     VM* vm = &exec->vm();
881     NativeCallFrameTracer tracer(vm, exec);
882
883     return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
884 }
885
886 #if USE(JSVALUE64)
887 EncodedJSValue JIT_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
888 #else
889 size_t JIT_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
890 #endif
891 {
892     VM* vm = &exec->vm();
893     NativeCallFrameTracer tracer(vm, exec);
894
895     bool result = WTF::equal(*asString(left)->value(exec).impl(), *asString(right)->value(exec).impl());
896 #if USE(JSVALUE64)
897     return JSValue::encode(jsBoolean(result));
898 #else
899     return result;
900 #endif
901 }
902
903 size_t JIT_OPERATION operationHasProperty(ExecState* exec, JSObject* base, JSString* property)
904 {
905     int result = base->hasProperty(exec, property->toIdentifier(exec));
906     return result;
907 }
908     
909
910 EncodedJSValue JIT_OPERATION operationNewArrayWithProfile(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, int size)
911 {
912     VM* vm = &exec->vm();
913     NativeCallFrameTracer tracer(vm, exec);
914     return JSValue::encode(constructArrayNegativeIndexed(exec, profile, values, size));
915 }
916
917 EncodedJSValue JIT_OPERATION operationNewArrayBufferWithProfile(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, int size)
918 {
919     VM* vm = &exec->vm();
920     NativeCallFrameTracer tracer(vm, exec);
921     return JSValue::encode(constructArray(exec, profile, values, size));
922 }
923
924 EncodedJSValue JIT_OPERATION operationNewArrayWithSizeAndProfile(ExecState* exec, ArrayAllocationProfile* profile, EncodedJSValue size)
925 {
926     VM* vm = &exec->vm();
927     NativeCallFrameTracer tracer(vm, exec);
928     JSValue sizeValue = JSValue::decode(size);
929     return JSValue::encode(constructArrayWithSizeQuirk(exec, profile, exec->lexicalGlobalObject(), sizeValue));
930 }
931
932 EncodedJSValue JIT_OPERATION operationNewFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
933 {
934     ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
935     VM& vm = exec->vm();
936     NativeCallFrameTracer tracer(&vm, exec);
937     return JSValue::encode(JSFunction::create(vm, static_cast<FunctionExecutable*>(functionExecutable), scope));
938 }
939
940 EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
941 {
942     ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
943     VM& vm = exec->vm();
944     NativeCallFrameTracer tracer(&vm, exec);
945     return JSValue::encode(JSFunction::createWithInvalidatedReallocationWatchpoint(vm, static_cast<FunctionExecutable*>(functionExecutable), scope));
946 }
947
948 JSCell* JIT_OPERATION operationNewObject(ExecState* exec, Structure* structure)
949 {
950     VM* vm = &exec->vm();
951     NativeCallFrameTracer tracer(vm, exec);
952     
953     return constructEmptyObject(exec, structure);
954 }
955
956 EncodedJSValue JIT_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
957 {
958     VM& vm = exec->vm();
959     NativeCallFrameTracer tracer(&vm, exec);
960     RegExp* regexp = static_cast<RegExp*>(regexpPtr);
961     if (!regexp->isValid()) {
962         vm.throwException(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor.")));
963         return JSValue::encode(jsUndefined());
964     }
965
966     return JSValue::encode(RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regexp));
967 }
968
969 void JIT_OPERATION operationHandleWatchdogTimer(ExecState* exec)
970 {
971     VM& vm = exec->vm();
972     NativeCallFrameTracer tracer(&vm, exec);
973
974     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(exec)))
975         vm.throwException(exec, createTerminatedExecutionException(&vm));
976 }
977
978 void JIT_OPERATION operationThrowStaticError(ExecState* exec, EncodedJSValue encodedValue, int32_t referenceErrorFlag)
979 {
980     VM& vm = exec->vm();
981     NativeCallFrameTracer tracer(&vm, exec);
982     JSValue errorMessageValue = JSValue::decode(encodedValue);
983     RELEASE_ASSERT(errorMessageValue.isString());
984     String errorMessage = asString(errorMessageValue)->value(exec);
985     if (referenceErrorFlag)
986         vm.throwException(exec, createReferenceError(exec, errorMessage));
987     else
988         vm.throwException(exec, createTypeError(exec, errorMessage));
989 }
990
991 void JIT_OPERATION operationDebug(ExecState* exec, int32_t debugHookID)
992 {
993     VM& vm = exec->vm();
994     NativeCallFrameTracer tracer(&vm, exec);
995
996     vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID));
997 }
998
999 #if ENABLE(DFG_JIT)
1000 static void updateAllPredictionsAndOptimizeAfterWarmUp(CodeBlock* codeBlock)
1001 {
1002     codeBlock->updateAllPredictions();
1003     codeBlock->optimizeAfterWarmUp();
1004 }
1005
1006 SlowPathReturnType JIT_OPERATION operationOptimize(ExecState* exec, int32_t bytecodeIndex)
1007 {
1008     VM& vm = exec->vm();
1009     NativeCallFrameTracer tracer(&vm, exec);
1010
1011     // Defer GC for a while so that it doesn't run between when we enter into this
1012     // slow path and when we figure out the state of our code block. This prevents
1013     // a number of awkward reentrancy scenarios, including:
1014     //
1015     // - The optimized version of our code block being jettisoned by GC right after
1016     //   we concluded that we wanted to use it, but have not planted it into the JS
1017     //   stack yet.
1018     //
1019     // - An optimized version of our code block being installed just as we decided
1020     //   that it wasn't ready yet.
1021     //
1022     // Note that jettisoning won't happen if we already initiated OSR, because in
1023     // that case we would have already planted the optimized code block into the JS
1024     // stack.
1025     DeferGCForAWhile deferGC(vm.heap);
1026     
1027     CodeBlock* codeBlock = exec->codeBlock();
1028     if (codeBlock->jitType() != JITCode::BaselineJIT) {
1029         dataLog("Unexpected code block in Baseline->DFG tier-up: ", *codeBlock, "\n");
1030         RELEASE_ASSERT_NOT_REACHED();
1031     }
1032     
1033     if (bytecodeIndex) {
1034         // If we're attempting to OSR from a loop, assume that this should be
1035         // separately optimized.
1036         codeBlock->m_shouldAlwaysBeInlined = false;
1037     }
1038
1039     if (Options::verboseOSR()) {
1040         dataLog(
1041             *codeBlock, ": Entered optimize with bytecodeIndex = ", bytecodeIndex,
1042             ", executeCounter = ", codeBlock->jitExecuteCounter(),
1043             ", optimizationDelayCounter = ", codeBlock->reoptimizationRetryCounter(),
1044             ", exitCounter = ");
1045         if (codeBlock->hasOptimizedReplacement())
1046             dataLog(codeBlock->replacement()->osrExitCounter());
1047         else
1048             dataLog("N/A");
1049         dataLog("\n");
1050     }
1051
1052     if (!codeBlock->checkIfOptimizationThresholdReached()) {
1053         codeBlock->updateAllPredictions();
1054         if (Options::verboseOSR())
1055             dataLog("Choosing not to optimize ", *codeBlock, " yet, because the threshold hasn't been reached.\n");
1056         return encodeResult(0, 0);
1057     }
1058     
1059     if (vm.enabledProfiler()) {
1060         updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
1061         return encodeResult(0, 0);
1062     }
1063
1064     Debugger* debugger = codeBlock->globalObject()->debugger();
1065     if (debugger && (debugger->isStepping() || codeBlock->baselineAlternative()->hasDebuggerRequests())) {
1066         updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
1067         return encodeResult(0, 0);
1068     }
1069
1070     if (codeBlock->m_shouldAlwaysBeInlined) {
1071         updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
1072         if (Options::verboseOSR())
1073             dataLog("Choosing not to optimize ", *codeBlock, " yet, because m_shouldAlwaysBeInlined == true.\n");
1074         return encodeResult(0, 0);
1075     }
1076
1077     // We cannot be in the process of asynchronous compilation and also have an optimized
1078     // replacement.
1079     DFG::Worklist* worklist = DFG::existingGlobalDFGWorklistOrNull();
1080     ASSERT(
1081         !worklist
1082         || !(worklist->compilationState(DFG::CompilationKey(codeBlock, DFG::DFGMode)) != DFG::Worklist::NotKnown
1083         && codeBlock->hasOptimizedReplacement()));
1084
1085     DFG::Worklist::State worklistState;
1086     if (worklist) {
1087         // The call to DFG::Worklist::completeAllReadyPlansForVM() will complete all ready
1088         // (i.e. compiled) code blocks. But if it completes ours, we also need to know
1089         // what the result was so that we don't plow ahead and attempt OSR or immediate
1090         // reoptimization. This will have already also set the appropriate JIT execution
1091         // count threshold depending on what happened, so if the compilation was anything
1092         // but successful we just want to return early. See the case for worklistState ==
1093         // DFG::Worklist::Compiled, below.
1094         
1095         // Note that we could have alternatively just called Worklist::compilationState()
1096         // here, and if it returned Compiled, we could have then called
1097         // completeAndScheduleOSR() below. But that would have meant that it could take
1098         // longer for code blocks to be completed: they would only complete when *their*
1099         // execution count trigger fired; but that could take a while since the firing is
1100         // racy. It could also mean that code blocks that never run again after being
1101         // compiled would sit on the worklist until next GC. That's fine, but it's
1102         // probably a waste of memory. Our goal here is to complete code blocks as soon as
1103         // possible in order to minimize the chances of us executing baseline code after
1104         // optimized code is already available.
1105         worklistState = worklist->completeAllReadyPlansForVM(
1106             vm, DFG::CompilationKey(codeBlock, DFG::DFGMode));
1107     } else
1108         worklistState = DFG::Worklist::NotKnown;
1109
1110     if (worklistState == DFG::Worklist::Compiling) {
1111         // We cannot be in the process of asynchronous compilation and also have an optimized
1112         // replacement.
1113         RELEASE_ASSERT(!codeBlock->hasOptimizedReplacement());
1114         codeBlock->setOptimizationThresholdBasedOnCompilationResult(CompilationDeferred);
1115         return encodeResult(0, 0);
1116     }
1117
1118     if (worklistState == DFG::Worklist::Compiled) {
1119         // If we don't have an optimized replacement but we did just get compiled, then
1120         // the compilation failed or was invalidated, in which case the execution count
1121         // thresholds have already been set appropriately by
1122         // CodeBlock::setOptimizationThresholdBasedOnCompilationResult() and we have
1123         // nothing left to do.
1124         if (!codeBlock->hasOptimizedReplacement()) {
1125             codeBlock->updateAllPredictions();
1126             if (Options::verboseOSR())
1127                 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1128             return encodeResult(0, 0);
1129         }
1130     } else if (codeBlock->hasOptimizedReplacement()) {
1131         if (Options::verboseOSR())
1132             dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
1133         // If we have an optimized replacement, then it must be the case that we entered
1134         // cti_optimize from a loop. That's because if there's an optimized replacement,
1135         // then all calls to this function will be relinked to the replacement and so
1136         // the prologue OSR will never fire.
1137         
1138         // This is an interesting threshold check. Consider that a function OSR exits
1139         // in the middle of a loop, while having a relatively low exit count. The exit
1140         // will reset the execution counter to some target threshold, meaning that this
1141         // code won't be reached until that loop heats up for >=1000 executions. But then
1142         // we do a second check here, to see if we should either reoptimize, or just
1143         // attempt OSR entry. Hence it might even be correct for
1144         // shouldReoptimizeFromLoopNow() to always return true. But we make it do some
1145         // additional checking anyway, to reduce the amount of recompilation thrashing.
1146         if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
1147             if (Options::verboseOSR()) {
1148                 dataLog(
1149                     "Triggering reoptimization of ", *codeBlock,
1150                     "(", *codeBlock->replacement(), ") (in loop).\n");
1151             }
1152             codeBlock->replacement()->jettison(Profiler::JettisonDueToBaselineLoopReoptimizationTrigger, CountReoptimization);
1153             return encodeResult(0, 0);
1154         }
1155     } else {
1156         if (!codeBlock->shouldOptimizeNow()) {
1157             if (Options::verboseOSR()) {
1158                 dataLog(
1159                     "Delaying optimization for ", *codeBlock,
1160                     " because of insufficient profiling.\n");
1161             }
1162             return encodeResult(0, 0);
1163         }
1164
1165         if (Options::verboseOSR())
1166             dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
1167
1168         unsigned numVarsWithValues;
1169         if (bytecodeIndex)
1170             numVarsWithValues = codeBlock->m_numVars;
1171         else
1172             numVarsWithValues = 0;
1173         Operands<JSValue> mustHandleValues(codeBlock->numParameters(), numVarsWithValues);
1174         for (size_t i = 0; i < mustHandleValues.size(); ++i) {
1175             int operand = mustHandleValues.operandForIndex(i);
1176             mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
1177         }
1178
1179         RefPtr<CodeBlock> replacementCodeBlock = codeBlock->newReplacement();
1180         CompilationResult result = DFG::compile(
1181             vm, replacementCodeBlock.get(), 0, DFG::DFGMode, bytecodeIndex,
1182             mustHandleValues, JITToDFGDeferredCompilationCallback::create());
1183         
1184         if (result != CompilationSuccessful) {
1185             ASSERT(result == CompilationDeferred || replacementCodeBlock->hasOneRef());
1186             return encodeResult(0, 0);
1187         }
1188     }
1189     
1190     CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1191     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
1192     
1193     if (void* dataBuffer = DFG::prepareOSREntry(exec, optimizedCodeBlock, bytecodeIndex)) {
1194         if (Options::verboseOSR()) {
1195             dataLog(
1196                 "Performing OSR ", *codeBlock, " -> ", *optimizedCodeBlock, ".\n");
1197         }
1198
1199         codeBlock->optimizeSoon();
1200         return encodeResult(vm.getCTIStub(DFG::osrEntryThunkGenerator).code().executableAddress(), dataBuffer);
1201     }
1202
1203     if (Options::verboseOSR()) {
1204         dataLog(
1205             "Optimizing ", *codeBlock, " -> ", *codeBlock->replacement(),
1206             " succeeded, OSR failed, after a delay of ",
1207             codeBlock->optimizationDelayCounter(), ".\n");
1208     }
1209
1210     // Count the OSR failure as a speculation failure. If this happens a lot, then
1211     // reoptimize.
1212     optimizedCodeBlock->countOSRExit();
1213
1214     // We are a lot more conservative about triggering reoptimization after OSR failure than
1215     // before it. If we enter the optimize_from_loop trigger with a bucket full of fail
1216     // already, then we really would like to reoptimize immediately. But this case covers
1217     // something else: there weren't many (or any) speculation failures before, but we just
1218     // failed to enter the speculative code because some variable had the wrong value or
1219     // because the OSR code decided for any spurious reason that it did not want to OSR
1220     // right now. So, we only trigger reoptimization only upon the more conservative (non-loop)
1221     // reoptimization trigger.
1222     if (optimizedCodeBlock->shouldReoptimizeNow()) {
1223         if (Options::verboseOSR()) {
1224             dataLog(
1225                 "Triggering reoptimization of ", *codeBlock, " -> ",
1226                 *codeBlock->replacement(), " (after OSR fail).\n");
1227         }
1228         optimizedCodeBlock->jettison(Profiler::JettisonDueToBaselineLoopReoptimizationTriggerOnOSREntryFail, CountReoptimization);
1229         return encodeResult(0, 0);
1230     }
1231
1232     // OSR failed this time, but it might succeed next time! Let the code run a bit
1233     // longer and then try again.
1234     codeBlock->optimizeAfterWarmUp();
1235     
1236     return encodeResult(0, 0);
1237 }
1238 #endif
1239
1240 void JIT_OPERATION operationPutByIndex(ExecState* exec, EncodedJSValue encodedArrayValue, int32_t index, EncodedJSValue encodedValue)
1241 {
1242     VM& vm = exec->vm();
1243     NativeCallFrameTracer tracer(&vm, exec);
1244
1245     JSValue arrayValue = JSValue::decode(encodedArrayValue);
1246     ASSERT(isJSArray(arrayValue));
1247     asArray(arrayValue)->putDirectIndex(exec, index, JSValue::decode(encodedValue));
1248 }
1249
1250 #if USE(JSVALUE64)
1251 void JIT_OPERATION operationPutGetterById(ExecState* exec, EncodedJSValue encodedObjectValue, Identifier* identifier, EncodedJSValue encodedGetterValue)
1252 {
1253     VM& vm = exec->vm();
1254     NativeCallFrameTracer tracer(&vm, exec);
1255
1256     ASSERT(JSValue::decode(encodedObjectValue).isObject());
1257     JSObject* baseObj = asObject(JSValue::decode(encodedObjectValue));
1258
1259     JSValue getter = JSValue::decode(encodedGetterValue);
1260     ASSERT(getter.isObject());
1261     baseObj->putGetter(exec, *identifier, asObject(getter));
1262 }
1263
1264 void JIT_OPERATION operationPutSetterById(ExecState* exec, EncodedJSValue encodedObjectValue, Identifier* identifier, EncodedJSValue encodedSetterValue)
1265 {
1266     VM& vm = exec->vm();
1267     NativeCallFrameTracer tracer(&vm, exec);
1268
1269     ASSERT(JSValue::decode(encodedObjectValue).isObject());
1270     JSObject* baseObj = asObject(JSValue::decode(encodedObjectValue));
1271
1272     JSValue setter = JSValue::decode(encodedSetterValue);
1273     ASSERT(setter.isObject());
1274     baseObj->putSetter(exec, *identifier, asObject(setter));
1275 }
1276
1277 void JIT_OPERATION operationPutGetterSetter(ExecState* exec, EncodedJSValue encodedObjectValue, Identifier* identifier, EncodedJSValue encodedGetterValue, EncodedJSValue encodedSetterValue)
1278 {
1279     VM& vm = exec->vm();
1280     NativeCallFrameTracer tracer(&vm, exec);
1281
1282     ASSERT(JSValue::decode(encodedObjectValue).isObject());
1283     JSObject* baseObj = asObject(JSValue::decode(encodedObjectValue));
1284
1285     GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
1286
1287     JSValue getter = JSValue::decode(encodedGetterValue);
1288     JSValue setter = JSValue::decode(encodedSetterValue);
1289     ASSERT(getter.isObject() || getter.isUndefined());
1290     ASSERT(setter.isObject() || setter.isUndefined());
1291     ASSERT(getter.isObject() || setter.isObject());
1292
1293     if (!getter.isUndefined())
1294         accessor->setGetter(vm, exec->lexicalGlobalObject(), asObject(getter));
1295     if (!setter.isUndefined())
1296         accessor->setSetter(vm, exec->lexicalGlobalObject(), asObject(setter));
1297     baseObj->putDirectAccessor(exec, *identifier, accessor, Accessor);
1298 }
1299 #else
1300 void JIT_OPERATION operationPutGetterById(ExecState* exec, JSCell* object, Identifier* identifier, JSCell* getter)
1301 {
1302     VM& vm = exec->vm();
1303     NativeCallFrameTracer tracer(&vm, exec);
1304
1305     ASSERT(object && object->isObject());
1306     JSObject* baseObj = object->getObject();
1307
1308     ASSERT(getter->isObject());
1309     baseObj->putGetter(exec, *identifier, getter);
1310 }
1311
1312 void JIT_OPERATION operationPutSetterById(ExecState* exec, JSCell* object, Identifier* identifier, JSCell* setter)
1313 {
1314     VM& vm = exec->vm();
1315     NativeCallFrameTracer tracer(&vm, exec);
1316
1317     ASSERT(object && object->isObject());
1318     JSObject* baseObj = object->getObject();
1319
1320     ASSERT(setter->isObject());
1321     baseObj->putSetter(exec, *identifier, setter);
1322 }
1323
1324 void JIT_OPERATION operationPutGetterSetter(ExecState* exec, JSCell* object, Identifier* identifier, JSCell* getter, JSCell* setter)
1325 {
1326     VM& vm = exec->vm();
1327     NativeCallFrameTracer tracer(&vm, exec);
1328
1329     ASSERT(object && object->isObject());
1330     JSObject* baseObj = object->getObject();
1331
1332     GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
1333
1334     ASSERT(!getter || getter->isObject());
1335     ASSERT(!setter || setter->isObject());
1336     ASSERT(getter || setter);
1337
1338     if (getter)
1339         accessor->setGetter(vm, exec->lexicalGlobalObject(), getter->getObject());
1340     if (setter)
1341         accessor->setSetter(vm, exec->lexicalGlobalObject(), setter->getObject());
1342     baseObj->putDirectAccessor(exec, *identifier, accessor, Accessor);
1343 }
1344 #endif
1345
1346 void JIT_OPERATION operationPushWithScope(ExecState* exec, int32_t dst, EncodedJSValue encodedValue)
1347 {
1348     VM& vm = exec->vm();
1349     NativeCallFrameTracer tracer(&vm, exec);
1350
1351     JSObject* o = JSValue::decode(encodedValue).toObject(exec);
1352     if (vm.exception())
1353         return;
1354
1355     // FIXME: This won't work if this operation is called from the DFG or FTL.
1356     // This should be changed to pass in the old scope and return the new scope.
1357     JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
1358     exec->uncheckedR(dst) = JSWithScope::create(exec, o, currentScope);
1359 }
1360
1361 void JIT_OPERATION operationPopScope(ExecState* exec, int32_t scopeReg)
1362 {
1363     VM& vm = exec->vm();
1364     NativeCallFrameTracer tracer(&vm, exec);
1365
1366     JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
1367     exec->uncheckedR(scopeReg) = scope->next();
1368 }
1369
1370 void JIT_OPERATION operationProfileDidCall(ExecState* exec, EncodedJSValue encodedValue)
1371 {
1372     VM& vm = exec->vm();
1373     NativeCallFrameTracer tracer(&vm, exec);
1374
1375     if (LegacyProfiler* profiler = vm.enabledProfiler())
1376         profiler->didExecute(exec, JSValue::decode(encodedValue));
1377 }
1378
1379 void JIT_OPERATION operationProfileWillCall(ExecState* exec, EncodedJSValue encodedValue)
1380 {
1381     VM& vm = exec->vm();
1382     NativeCallFrameTracer tracer(&vm, exec);
1383
1384     if (LegacyProfiler* profiler = vm.enabledProfiler())
1385         profiler->willExecute(exec, JSValue::decode(encodedValue));
1386 }
1387
1388 EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBaseVal)
1389 {
1390     VM& vm = exec->vm();
1391     NativeCallFrameTracer tracer(&vm, exec);
1392
1393     JSValue value = JSValue::decode(encodedValue);
1394     JSValue baseVal = JSValue::decode(encodedBaseVal);
1395
1396     if (baseVal.isObject()) {
1397         JSObject* baseObject = asObject(baseVal);
1398         ASSERT(!baseObject->structure(vm)->typeInfo().implementsDefaultHasInstance());
1399         if (baseObject->structure(vm)->typeInfo().implementsHasInstance()) {
1400             bool result = baseObject->methodTable(vm)->customHasInstance(baseObject, exec, value);
1401             return JSValue::encode(jsBoolean(result));
1402         }
1403     }
1404
1405     vm.throwException(exec, createInvalidInstanceofParameterError(exec, baseVal));
1406     return JSValue::encode(JSValue());
1407 }
1408
1409 }
1410
1411 static bool canAccessArgumentIndexQuickly(JSObject& object, uint32_t index)
1412 {
1413     switch (object.structure()->typeInfo().type()) {
1414     case DirectArgumentsType: {
1415         DirectArguments* directArguments = jsCast<DirectArguments*>(&object);
1416         if (directArguments->canAccessArgumentIndexQuicklyInDFG(index))
1417             return true;
1418         break;
1419     }
1420     case ScopedArgumentsType: {
1421         ScopedArguments* scopedArguments = jsCast<ScopedArguments*>(&object);
1422         if (scopedArguments->canAccessArgumentIndexQuicklyInDFG(index))
1423             return true;
1424         break;
1425     }
1426     default:
1427         break;
1428     }
1429     return false;
1430 }
1431
1432 static JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript, ArrayProfile* arrayProfile, ReturnAddressPtr returnAddress)
1433 {
1434     if (LIKELY(baseValue.isCell() && subscript.isString())) {
1435         VM& vm = exec->vm();
1436         Structure& structure = *baseValue.asCell()->structure(vm);
1437         if (JSCell::canUseFastGetOwnProperty(structure)) {
1438             if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
1439                 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
1440                     return result;
1441             }
1442         }
1443     }
1444
1445     if (subscript.isUInt32()) {
1446         uint32_t i = subscript.asUInt32();
1447         if (isJSString(baseValue)) {
1448             if (asString(baseValue)->canGetIndex(i)) {
1449                 ctiPatchCallByReturnAddress(exec->codeBlock(), returnAddress, FunctionPtr(operationGetByValString));
1450                 return asString(baseValue)->getIndex(exec, i);
1451             }
1452             arrayProfile->setOutOfBounds();
1453         } else if (baseValue.isObject()) {
1454             JSObject* object = asObject(baseValue);
1455             if (object->canGetIndexQuickly(i))
1456                 return object->getIndexQuickly(i);
1457
1458             if (!canAccessArgumentIndexQuickly(*object, i))
1459                 arrayProfile->setOutOfBounds();
1460         }
1461
1462         return baseValue.get(exec, i);
1463     }
1464
1465     baseValue.requireObjectCoercible(exec);
1466     if (exec->hadException())
1467         return jsUndefined();
1468     auto property = subscript.toPropertyKey(exec);
1469     if (exec->hadException())
1470         return jsUndefined();
1471     return baseValue.get(exec, property);
1472 }
1473
1474 extern "C" {
1475     
1476 EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
1477 {
1478     VM& vm = exec->vm();
1479     NativeCallFrameTracer tracer(&vm, exec);
1480     JSValue baseValue = JSValue::decode(encodedBase);
1481     JSValue subscript = JSValue::decode(encodedSubscript);
1482
1483     JSValue result = getByVal(exec, baseValue, subscript, arrayProfile, ReturnAddressPtr(OUR_RETURN_ADDRESS));
1484     return JSValue::encode(result);
1485 }
1486
1487 EncodedJSValue JIT_OPERATION operationGetByValOptimize(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
1488 {
1489     VM& vm = exec->vm();
1490     NativeCallFrameTracer tracer(&vm, exec);
1491     JSValue baseValue = JSValue::decode(encodedBase);
1492     JSValue subscript = JSValue::decode(encodedSubscript);
1493     
1494     if (baseValue.isObject() && subscript.isInt32()) {
1495         // See if it's worth optimizing this at all.
1496         JSObject* object = asObject(baseValue);
1497         bool didOptimize = false;
1498
1499         unsigned bytecodeOffset = exec->locationAsBytecodeOffset();
1500         ASSERT(bytecodeOffset);
1501         ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1);
1502         ASSERT(!byValInfo.stubRoutine);
1503         
1504         if (hasOptimizableIndexing(object->structure(vm))) {
1505             // Attempt to optimize.
1506             Structure* structure = object->structure(vm);
1507             JITArrayMode arrayMode = jitArrayModeForStructure(structure);
1508             if (arrayMode != byValInfo.arrayMode) {
1509                 // If we reached this case, we got an interesting array mode we did not expect when we compiled.
1510                 // Let's update the profile to do better next time.
1511                 CodeBlock* codeBlock = exec->codeBlock();
1512                 ConcurrentJITLocker locker(codeBlock->m_lock);
1513                 arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
1514
1515                 JIT::compileGetByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
1516                 didOptimize = true;
1517             }
1518         }
1519         
1520         if (!didOptimize) {
1521             // If we take slow path more than 10 times without patching then make sure we
1522             // never make that mistake again. Or, if we failed to patch and we have some object
1523             // that intercepts indexed get, then don't even wait until 10 times. For cases
1524             // where we see non-index-intercepting objects, this gives 10 iterations worth of
1525             // opportunity for us to observe that the get_by_val may be polymorphic.
1526             if (++byValInfo.slowPathCount >= 10
1527                 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
1528                 // Don't ever try to optimize.
1529                 ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationGetByValGeneric));
1530             }
1531         }
1532     }
1533     
1534     JSValue result = getByVal(exec, baseValue, subscript, arrayProfile, ReturnAddressPtr(OUR_RETURN_ADDRESS));
1535     return JSValue::encode(result);
1536 }
1537     
1538 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
1539 {
1540     VM& vm = exec->vm();
1541     NativeCallFrameTracer tracer(&vm, exec);
1542     JSValue baseValue = JSValue::decode(encodedBase);
1543     JSValue subscript = JSValue::decode(encodedSubscript);
1544     
1545     ASSERT(baseValue.isObject());
1546     ASSERT(subscript.isUInt32());
1547
1548     JSObject* object = asObject(baseValue);
1549     bool didOptimize = false;
1550
1551     unsigned bytecodeOffset = exec->locationAsBytecodeOffset();
1552     ASSERT(bytecodeOffset);
1553     ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1);
1554     ASSERT(!byValInfo.stubRoutine);
1555     
1556     if (hasOptimizableIndexing(object->structure(vm))) {
1557         // Attempt to optimize.
1558         JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
1559         if (arrayMode != byValInfo.arrayMode) {
1560             JIT::compileHasIndexedProperty(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
1561             didOptimize = true;
1562         }
1563     }
1564     
1565     if (!didOptimize) {
1566         // If we take slow path more than 10 times without patching then make sure we
1567         // never make that mistake again. Or, if we failed to patch and we have some object
1568         // that intercepts indexed get, then don't even wait until 10 times. For cases
1569         // where we see non-index-intercepting objects, this gives 10 iterations worth of
1570         // opportunity for us to observe that the get_by_val may be polymorphic.
1571         if (++byValInfo.slowPathCount >= 10
1572             || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
1573             // Don't ever try to optimize.
1574             ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationHasIndexedPropertyGeneric)); 
1575         }
1576     }
1577
1578     uint32_t index = subscript.asUInt32();
1579     if (object->canGetIndexQuickly(index))
1580         return JSValue::encode(JSValue(JSValue::JSTrue));
1581
1582     if (!canAccessArgumentIndexQuickly(*object, index))
1583         arrayProfile->setOutOfBounds();
1584     return JSValue::encode(jsBoolean(object->hasProperty(exec, index)));
1585 }
1586     
1587 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
1588 {
1589     VM& vm = exec->vm();
1590     NativeCallFrameTracer tracer(&vm, exec);
1591     JSValue baseValue = JSValue::decode(encodedBase);
1592     JSValue subscript = JSValue::decode(encodedSubscript);
1593     
1594     ASSERT(baseValue.isObject());
1595     ASSERT(subscript.isUInt32());
1596
1597     JSObject* object = asObject(baseValue);
1598     uint32_t index = subscript.asUInt32();
1599     if (object->canGetIndexQuickly(index))
1600         return JSValue::encode(JSValue(JSValue::JSTrue));
1601
1602     if (!canAccessArgumentIndexQuickly(*object, index))
1603         arrayProfile->setOutOfBounds();
1604     return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript.asUInt32())));
1605 }
1606     
1607 EncodedJSValue JIT_OPERATION operationGetByValString(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript)
1608 {
1609     VM& vm = exec->vm();
1610     NativeCallFrameTracer tracer(&vm, exec);
1611     JSValue baseValue = JSValue::decode(encodedBase);
1612     JSValue subscript = JSValue::decode(encodedSubscript);
1613     
1614     JSValue result;
1615     if (LIKELY(subscript.isUInt32())) {
1616         uint32_t i = subscript.asUInt32();
1617         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
1618             result = asString(baseValue)->getIndex(exec, i);
1619         else {
1620             result = baseValue.get(exec, i);
1621             if (!isJSString(baseValue)) {
1622                 unsigned bytecodeOffset = exec->locationAsBytecodeOffset();
1623                 ASSERT(bytecodeOffset);
1624                 ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1);
1625                 ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(byValInfo.stubRoutine ? operationGetByValGeneric : operationGetByValOptimize));
1626             }
1627         }
1628     } else {
1629         baseValue.requireObjectCoercible(exec);
1630         if (exec->hadException())
1631             return JSValue::encode(jsUndefined());
1632         auto property = subscript.toPropertyKey(exec);
1633         if (exec->hadException())
1634             return JSValue::encode(jsUndefined());
1635         result = baseValue.get(exec, property);
1636     }
1637
1638     return JSValue::encode(result);
1639 }
1640
1641 EncodedJSValue JIT_OPERATION operationDeleteById(ExecState* exec, EncodedJSValue encodedBase, const Identifier* identifier)
1642 {
1643     VM& vm = exec->vm();
1644     NativeCallFrameTracer tracer(&vm, exec);
1645
1646     JSObject* baseObj = JSValue::decode(encodedBase).toObject(exec);
1647     bool couldDelete = baseObj->methodTable(vm)->deleteProperty(baseObj, exec, *identifier);
1648     JSValue result = jsBoolean(couldDelete);
1649     if (!couldDelete && exec->codeBlock()->isStrictMode())
1650         vm.throwException(exec, createTypeError(exec, ASCIILiteral("Unable to delete property.")));
1651     return JSValue::encode(result);
1652 }
1653
1654 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedProto)
1655 {
1656     VM& vm = exec->vm();
1657     NativeCallFrameTracer tracer(&vm, exec);
1658     JSValue value = JSValue::decode(encodedValue);
1659     JSValue proto = JSValue::decode(encodedProto);
1660     
1661     ASSERT(!value.isObject() || !proto.isObject());
1662
1663     bool result = JSObject::defaultHasInstance(exec, value, proto);
1664     return JSValue::encode(jsBoolean(result));
1665 }
1666
1667 int32_t JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset)
1668 {
1669     VM& vm = exec->vm();
1670     NativeCallFrameTracer tracer(&vm, exec);
1671     JSStack* stack = &exec->interpreter()->stack();
1672     JSValue arguments = JSValue::decode(encodedArguments);
1673     return sizeFrameForVarargs(exec, stack, arguments, numUsedStackSlots, firstVarArgOffset);
1674 }
1675
1676 CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset, int32_t length)
1677 {
1678     VM& vm = exec->vm();
1679     NativeCallFrameTracer tracer(&vm, exec);
1680     JSValue arguments = JSValue::decode(encodedArguments);
1681     setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset, length);
1682     return newCallFrame;
1683 }
1684
1685 EncodedJSValue JIT_OPERATION operationToObject(ExecState* exec, EncodedJSValue value)
1686 {
1687     VM& vm = exec->vm();
1688     NativeCallFrameTracer tracer(&vm, exec);
1689     return JSValue::encode(JSValue::decode(value).toObject(exec));
1690 }
1691
1692 char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
1693 {
1694     VM& vm = exec->vm();
1695     NativeCallFrameTracer tracer(&vm, exec);
1696     JSValue key = JSValue::decode(encodedKey);
1697     CodeBlock* codeBlock = exec->codeBlock();
1698
1699     SimpleJumpTable& jumpTable = codeBlock->switchJumpTable(tableIndex);
1700     void* result = jumpTable.ctiDefault.executableAddress();
1701
1702     if (key.isString()) {
1703         StringImpl* value = asString(key)->value(exec).impl();
1704         if (value->length() == 1)
1705             result = jumpTable.ctiForValue((*value)[0]).executableAddress();
1706     }
1707
1708     return reinterpret_cast<char*>(result);
1709 }
1710
1711 char* JIT_OPERATION operationSwitchImmWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
1712 {
1713     VM& vm = exec->vm();
1714     NativeCallFrameTracer tracer(&vm, exec);
1715     JSValue key = JSValue::decode(encodedKey);
1716     CodeBlock* codeBlock = exec->codeBlock();
1717
1718     SimpleJumpTable& jumpTable = codeBlock->switchJumpTable(tableIndex);
1719     void* result;
1720     if (key.isInt32())
1721         result = jumpTable.ctiForValue(key.asInt32()).executableAddress();
1722     else if (key.isDouble() && key.asDouble() == static_cast<int32_t>(key.asDouble()))
1723         result = jumpTable.ctiForValue(static_cast<int32_t>(key.asDouble())).executableAddress();
1724     else
1725         result = jumpTable.ctiDefault.executableAddress();
1726     return reinterpret_cast<char*>(result);
1727 }
1728
1729 char* JIT_OPERATION operationSwitchStringWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
1730 {
1731     VM& vm = exec->vm();
1732     NativeCallFrameTracer tracer(&vm, exec);
1733     JSValue key = JSValue::decode(encodedKey);
1734     CodeBlock* codeBlock = exec->codeBlock();
1735
1736     void* result;
1737     StringJumpTable& jumpTable = codeBlock->stringSwitchJumpTable(tableIndex);
1738
1739     if (key.isString()) {
1740         StringImpl* value = asString(key)->value(exec).impl();
1741         result = jumpTable.ctiForValue(value).executableAddress();
1742     } else
1743         result = jumpTable.ctiDefault.executableAddress();
1744
1745     return reinterpret_cast<char*>(result);
1746 }
1747
1748 EncodedJSValue JIT_OPERATION operationResolveScope(ExecState* exec, int32_t scopeReg, int32_t identifierIndex)
1749 {
1750     VM& vm = exec->vm();
1751     NativeCallFrameTracer tracer(&vm, exec);
1752     const Identifier& ident = exec->codeBlock()->identifier(identifierIndex);
1753     JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
1754     return JSValue::encode(JSScope::resolve(exec, scope, ident));
1755 }
1756
1757 EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState* exec, Instruction* bytecodePC)
1758 {
1759     VM& vm = exec->vm();
1760     NativeCallFrameTracer tracer(&vm, exec);
1761     CodeBlock* codeBlock = exec->codeBlock();
1762     Instruction* pc = bytecodePC;
1763
1764     const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
1765     JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(pc[2].u.operand).jsValue());
1766     ResolveModeAndType modeAndType(pc[4].u.operand);
1767
1768     PropertySlot slot(scope);
1769     if (!scope->getPropertySlot(exec, ident, slot)) {
1770         if (modeAndType.mode() == ThrowIfNotFound)
1771             vm.throwException(exec, createUndefinedVariableError(exec, ident));
1772         return JSValue::encode(jsUndefined());
1773     }
1774
1775     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1776     if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure(vm)->propertyAccessesAreCacheable()) {
1777         if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1778             Structure* structure = scope->structure(vm);
1779             {
1780                 ConcurrentJITLocker locker(codeBlock->m_lock);
1781                 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
1782                 pc[6].u.operand = slot.cachedOffset();
1783             }
1784             structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
1785         }
1786     }
1787
1788     return JSValue::encode(slot.getValue(exec, ident));
1789 }
1790
1791 void JIT_OPERATION operationPutToScope(ExecState* exec, Instruction* bytecodePC)
1792 {
1793     VM& vm = exec->vm();
1794     NativeCallFrameTracer tracer(&vm, exec);
1795     Instruction* pc = bytecodePC;
1796
1797     CodeBlock* codeBlock = exec->codeBlock();
1798     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1799     JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(pc[1].u.operand).jsValue());
1800     JSValue value = exec->r(pc[3].u.operand).jsValue();
1801     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
1802     if (modeAndType.type() == LocalClosureVar) {
1803         JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
1804         environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
1805         if (WatchpointSet* set = pc[5].u.watchpointSet)
1806             set->touch("Executed op_put_scope<LocalClosureVar>");
1807         return;
1808     }
1809     if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident)) {
1810         exec->vm().throwException(exec, createUndefinedVariableError(exec, ident));
1811         return;
1812     }
1813
1814     PutPropertySlot slot(scope, codeBlock->isStrictMode());
1815     scope->methodTable()->put(scope, exec, ident, value, slot);
1816     
1817     if (exec->vm().exception())
1818         return;
1819
1820     CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
1821 }
1822
1823 void JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExceptionValue)
1824 {
1825     VM* vm = &exec->vm();
1826     NativeCallFrameTracer tracer(vm, exec);
1827
1828     JSValue exceptionValue = JSValue::decode(encodedExceptionValue);
1829     vm->throwException(exec, exceptionValue);
1830
1831     // Results stored out-of-band in vm.targetMachinePCForThrow, vm.callFrameForThrow & vm.vmEntryFrameForThrow
1832     genericUnwind(vm, exec);
1833 }
1834
1835 void JIT_OPERATION operationFlushWriteBarrierBuffer(ExecState* exec, JSCell* cell)
1836 {
1837     VM* vm = &exec->vm();
1838     NativeCallFrameTracer tracer(vm, exec);
1839     vm->heap.flushWriteBarrierBuffer(cell);
1840 }
1841
1842 void JIT_OPERATION operationOSRWriteBarrier(ExecState* exec, JSCell* cell)
1843 {
1844     VM* vm = &exec->vm();
1845     NativeCallFrameTracer tracer(vm, exec);
1846     vm->heap.writeBarrier(cell);
1847 }
1848
1849 // NB: We don't include the value as part of the barrier because the write barrier elision
1850 // phase in the DFG only tracks whether the object being stored to has been barriered. It 
1851 // would be much more complicated to try to model the value being stored as well.
1852 void JIT_OPERATION operationUnconditionalWriteBarrier(ExecState* exec, JSCell* cell)
1853 {
1854     VM* vm = &exec->vm();
1855     NativeCallFrameTracer tracer(vm, exec);
1856     vm->heap.writeBarrier(cell);
1857 }
1858
1859 void JIT_OPERATION operationInitGlobalConst(ExecState* exec, Instruction* pc)
1860 {
1861     VM* vm = &exec->vm();
1862     NativeCallFrameTracer tracer(vm, exec);
1863
1864     JSValue value = exec->r(pc[2].u.operand).jsValue();
1865     pc[1].u.variablePointer->set(*vm, exec->codeBlock()->globalObject(), value);
1866 }
1867
1868 void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec)
1869 {
1870     NativeCallFrameTracer tracer(vm, exec);
1871     genericUnwind(vm, exec);
1872     ASSERT(vm->targetMachinePCForThrow);
1873 }
1874
1875 void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM* vm, ExecState* exec)
1876 {
1877     VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
1878     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
1879     ASSERT(callerFrame);
1880
1881     NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
1882     genericUnwind(vm, callerFrame);
1883     ASSERT(vm->targetMachinePCForThrow);
1884 }
1885
1886 void JIT_OPERATION operationVMHandleException(ExecState* exec)
1887 {
1888     VM* vm = &exec->vm();
1889     NativeCallFrameTracer tracer(vm, exec);
1890     genericUnwind(vm, exec);
1891 }
1892
1893 // This function "should" just take the ExecState*, but doing so would make it more difficult
1894 // to call from exception check sites. So, unlike all of our other functions, we allow
1895 // ourselves to play some gnarly ABI tricks just to simplify the calling convention. This is
1896 // particularly safe here since this is never called on the critical path - it's only for
1897 // testing.
1898 void JIT_OPERATION operationExceptionFuzz()
1899 {
1900 #if COMPILER(GCC_OR_CLANG)
1901     ExecState* exec = static_cast<ExecState*>(__builtin_frame_address(1));
1902     void* returnPC = __builtin_return_address(0);
1903     doExceptionFuzzing(exec, "JITOperations", returnPC);
1904 #endif // COMPILER(GCC_OR_CLANG)
1905 }
1906
1907 EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* propertyName)
1908 {
1909     VM& vm = exec->vm();
1910     NativeCallFrameTracer tracer(&vm, exec);
1911     JSValue baseValue = JSValue::decode(encodedBaseValue);
1912     if (baseValue.isUndefinedOrNull())
1913         return JSValue::encode(jsBoolean(false));
1914
1915     JSObject* base = baseValue.toObject(exec);
1916     return JSValue::encode(jsBoolean(base->hasProperty(exec, asString(propertyName)->toIdentifier(exec))));
1917 }
1918
1919 EncodedJSValue JIT_OPERATION operationHasIndexedProperty(ExecState* exec, JSCell* baseCell, int32_t subscript)
1920 {
1921     VM& vm = exec->vm();
1922     NativeCallFrameTracer tracer(&vm, exec);
1923     JSObject* object = baseCell->toObject(exec, exec->lexicalGlobalObject());
1924     return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript)));
1925 }
1926     
1927 JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState* exec, JSCell* cell)
1928 {
1929     VM& vm = exec->vm();
1930     NativeCallFrameTracer tracer(&vm, exec);
1931
1932     JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject());
1933
1934     return propertyNameEnumerator(exec, base);
1935 }
1936
1937 EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState* exec, JSCell* enumeratorCell, int32_t index)
1938 {
1939     VM& vm = exec->vm();
1940     NativeCallFrameTracer tracer(&vm, exec);
1941     JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorCell);
1942     JSString* propertyName = enumerator->propertyNameAtIndex(index);
1943     return JSValue::encode(propertyName ? propertyName : jsNull());
1944 }
1945
1946 JSCell* JIT_OPERATION operationToIndexString(ExecState* exec, int32_t index)
1947 {
1948     VM& vm = exec->vm();
1949     NativeCallFrameTracer tracer(&vm, exec);
1950     return jsString(exec, Identifier::from(exec, index).string());
1951 }
1952
1953 void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec)
1954 {
1955     exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside baseline JIT"));
1956 }
1957
1958 } // extern "C"
1959
1960 // Note: getHostCallReturnValueWithExecState() needs to be placed before the
1961 // definition of getHostCallReturnValue() below because the Windows build
1962 // requires it.
1963 extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
1964 {
1965     if (!exec)
1966         return JSValue::encode(JSValue());
1967     return JSValue::encode(exec->vm().hostCallReturnValue);
1968 }
1969
1970 #if COMPILER(GCC_OR_CLANG) && CPU(X86_64)
1971 asm (
1972 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1973 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1974 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1975     "mov %rbp, %rdi\n"
1976     "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1977 );
1978
1979 #elif COMPILER(GCC_OR_CLANG) && CPU(X86)
1980 asm (
1981 ".text" "\n" \
1982 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1983 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1984 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1985     "push %ebp\n"
1986     "leal -4(%esp), %esp\n"
1987     "push %ebp\n"
1988     "call " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1989     "leal 8(%esp), %esp\n"
1990     "pop %ebp\n"
1991     "ret\n"
1992 );
1993
1994 #elif COMPILER(GCC_OR_CLANG) && CPU(ARM_THUMB2)
1995 asm (
1996 ".text" "\n"
1997 ".align 2" "\n"
1998 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1999 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2000 ".thumb" "\n"
2001 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
2002 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2003     "mov r0, r7" "\n"
2004     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2005 );
2006
2007 #elif COMPILER(GCC_OR_CLANG) && CPU(ARM_TRADITIONAL)
2008 asm (
2009 ".text" "\n"
2010 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2011 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2012 INLINE_ARM_FUNCTION(getHostCallReturnValue)
2013 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2014     "mov r0, r11" "\n"
2015     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2016 );
2017
2018 #elif CPU(ARM64)
2019 asm (
2020 ".text" "\n"
2021 ".align 2" "\n"
2022 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2023 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2024 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2025      "mov x0, x29" "\n"
2026      "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2027 );
2028
2029 #elif COMPILER(GCC_OR_CLANG) && CPU(MIPS)
2030
2031 #if WTF_MIPS_PIC
2032 #define LOAD_FUNCTION_TO_T9(function) \
2033         ".set noreorder" "\n" \
2034         ".cpload $25" "\n" \
2035         ".set reorder" "\n" \
2036         "la $t9, " LOCAL_REFERENCE(function) "\n"
2037 #else
2038 #define LOAD_FUNCTION_TO_T9(function) "" "\n"
2039 #endif
2040
2041 asm (
2042 ".text" "\n"
2043 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2044 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2045 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2046     LOAD_FUNCTION_TO_T9(getHostCallReturnValueWithExecState)
2047     "move $a0, $fp" "\n"
2048     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2049 );
2050
2051 #elif COMPILER(GCC_OR_CLANG) && CPU(SH4)
2052
2053 #define SH4_SCRATCH_REGISTER "r11"
2054
2055 asm (
2056 ".text" "\n"
2057 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2058 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2059 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2060     "mov r14, r4" "\n"
2061     "mov.l 2f, " SH4_SCRATCH_REGISTER "\n"
2062     "braf " SH4_SCRATCH_REGISTER "\n"
2063     "nop" "\n"
2064     "1: .balign 4" "\n"
2065     "2: .long " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "-1b\n"
2066 );
2067
2068 #elif COMPILER(MSVC) && CPU(X86)
2069 extern "C" {
2070     __declspec(naked) EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue()
2071     {
2072         __asm mov [esp + 4], ebp;
2073         __asm jmp getHostCallReturnValueWithExecState
2074     }
2075 }
2076 #endif
2077
2078 } // namespace JSC
2079
2080 #endif // ENABLE(JIT)