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