[JSC][FTL] FTL should support Arrayify
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLLowerDFGToB3.cpp
1 /*
2  * Copyright (C) 2013-2017 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 "FTLLowerDFGToB3.h"
28
29 #if ENABLE(FTL_JIT)
30
31 #include "AirGenerationContext.h"
32 #include "AllowMacroScratchRegisterUsage.h"
33 #include "AtomicsObject.h"
34 #include "B3CheckValue.h"
35 #include "B3FenceValue.h"
36 #include "B3PatchpointValue.h"
37 #include "B3SlotBaseValue.h"
38 #include "B3StackmapGenerationParams.h"
39 #include "B3ValueInlines.h"
40 #include "CallFrameShuffler.h"
41 #include "CodeBlockWithJITType.h"
42 #include "DFGAbstractInterpreterInlines.h"
43 #include "DFGCapabilities.h"
44 #include "DFGDominators.h"
45 #include "DFGInPlaceAbstractState.h"
46 #include "DFGOSRAvailabilityAnalysisPhase.h"
47 #include "DFGOSRExitFuzz.h"
48 #include "DOMJITPatchpoint.h"
49 #include "DirectArguments.h"
50 #include "FTLAbstractHeapRepository.h"
51 #include "FTLAvailableRecovery.h"
52 #include "FTLDOMJITPatchpointParams.h"
53 #include "FTLExceptionTarget.h"
54 #include "FTLForOSREntryJITCode.h"
55 #include "FTLFormattedValue.h"
56 #include "FTLLazySlowPathCall.h"
57 #include "FTLLoweredNodeValue.h"
58 #include "FTLOperations.h"
59 #include "FTLOutput.h"
60 #include "FTLPatchpointExceptionHandle.h"
61 #include "FTLThunks.h"
62 #include "FTLWeightedTarget.h"
63 #include "JITAddGenerator.h"
64 #include "JITBitAndGenerator.h"
65 #include "JITBitOrGenerator.h"
66 #include "JITBitXorGenerator.h"
67 #include "JITDivGenerator.h"
68 #include "JITInlineCacheGenerator.h"
69 #include "JITLeftShiftGenerator.h"
70 #include "JITMathIC.h"
71 #include "JITMulGenerator.h"
72 #include "JITRightShiftGenerator.h"
73 #include "JITSubGenerator.h"
74 #include "JSCInlines.h"
75 #include "JSGeneratorFunction.h"
76 #include "JSLexicalEnvironment.h"
77 #include "JSMap.h"
78 #include "OperandsInlines.h"
79 #include "ScopedArguments.h"
80 #include "ScopedArgumentsTable.h"
81 #include "ScratchRegisterAllocator.h"
82 #include "SetupVarargsFrame.h"
83 #include "ShadowChicken.h"
84 #include "StructureStubInfo.h"
85 #include "VirtualRegister.h"
86 #include "Watchdog.h"
87 #include <atomic>
88 #if !OS(WINDOWS)
89 #include <dlfcn.h>
90 #endif
91 #include <unordered_set>
92 #include <wtf/Box.h>
93 #include <wtf/ProcessID.h>
94
95 namespace JSC { namespace FTL {
96
97 using namespace B3;
98 using namespace DFG;
99
100 namespace {
101
102 std::atomic<int> compileCounter;
103
104 #if !ASSERT_DISABLED
105 NO_RETURN_DUE_TO_CRASH static void ftlUnreachable(
106     CodeBlock* codeBlock, BlockIndex blockIndex, unsigned nodeIndex)
107 {
108     dataLog("Crashing in thought-to-be-unreachable FTL-generated code for ", pointerDump(codeBlock), " at basic block #", blockIndex);
109     if (nodeIndex != UINT_MAX)
110         dataLog(", node @", nodeIndex);
111     dataLog(".\n");
112     CRASH();
113 }
114 #endif
115
116 // Using this instead of typeCheck() helps to reduce the load on B3, by creating
117 // significantly less dead code.
118 #define FTL_TYPE_CHECK_WITH_EXIT_KIND(exitKind, lowValue, highValue, typesPassedThrough, failCondition) do { \
119         FormattedValue _ftc_lowValue = (lowValue);                      \
120         Edge _ftc_highValue = (highValue);                              \
121         SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough);  \
122         if (!m_interpreter.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \
123             break;                                                      \
124         typeCheck(_ftc_lowValue, _ftc_highValue, _ftc_typesPassedThrough, (failCondition), exitKind); \
125     } while (false)
126
127 #define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) \
128     FTL_TYPE_CHECK_WITH_EXIT_KIND(BadType, lowValue, highValue, typesPassedThrough, failCondition)
129
130 class LowerDFGToB3 {
131     WTF_MAKE_NONCOPYABLE(LowerDFGToB3);
132 public:
133     LowerDFGToB3(State& state)
134         : m_graph(state.graph)
135         , m_ftlState(state)
136         , m_out(state)
137         , m_proc(*state.proc)
138         , m_availabilityCalculator(m_graph)
139         , m_state(state.graph)
140         , m_interpreter(state.graph, m_state)
141     {
142     }
143     
144     void lower()
145     {
146         State* state = &m_ftlState;
147         
148         CString name;
149         if (verboseCompilationEnabled()) {
150             name = toCString(
151                 "jsBody_", ++compileCounter, "_", codeBlock()->inferredName(),
152                 "_", codeBlock()->hash());
153         } else
154             name = "jsBody";
155         
156         m_graph.ensureDominators();
157
158         if (verboseCompilationEnabled())
159             dataLog("Function ready, beginning lowering.\n");
160
161         m_out.initialize(m_heaps);
162
163         // We use prologue frequency for all of the initialization code.
164         m_out.setFrequency(1);
165         
166         m_prologue = m_out.newBlock();
167         m_handleExceptions = m_out.newBlock();
168
169         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
170             m_highBlock = m_graph.block(blockIndex);
171             if (!m_highBlock)
172                 continue;
173             m_out.setFrequency(m_highBlock->executionCount);
174             m_blocks.add(m_highBlock, m_out.newBlock());
175         }
176
177         // Back to prologue frequency for any bocks that get sneakily created in the initialization code.
178         m_out.setFrequency(1);
179         
180         m_out.appendTo(m_prologue, m_handleExceptions);
181         m_out.initializeConstants(m_proc, m_prologue);
182         createPhiVariables();
183
184         size_t sizeOfCaptured = sizeof(JSValue) * m_graph.m_nextMachineLocal;
185         B3::SlotBaseValue* capturedBase = m_out.lockedStackSlot(sizeOfCaptured);
186         m_captured = m_out.add(capturedBase, m_out.constIntPtr(sizeOfCaptured));
187         state->capturedValue = capturedBase->slot();
188
189         auto preOrder = m_graph.blocksInPreOrder();
190
191         m_callFrame = m_out.framePointer();
192         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
193         m_tagMask = m_out.constInt64(TagMask);
194
195         // Make sure that B3 knows that we really care about the mask registers. This forces the
196         // constants to be materialized in registers.
197         m_proc.addFastConstant(m_tagTypeNumber->key());
198         m_proc.addFastConstant(m_tagMask->key());
199         
200         // We don't want the CodeBlock to have a weak pointer to itself because
201         // that would cause it to always get collected.
202         m_out.storePtr(m_out.constIntPtr(bitwise_cast<intptr_t>(codeBlock())), addressFor(CallFrameSlot::codeBlock));
203
204         VM* vm = &this->vm();
205
206         // Stack Overflow Check.
207         unsigned exitFrameSize = m_graph.requiredRegisterCountForExit() * sizeof(Register);
208         MacroAssembler::AbsoluteAddress addressOfStackLimit(vm->addressOfSoftStackLimit());
209         PatchpointValue* stackOverflowHandler = m_out.patchpoint(Void);
210         CallSiteIndex callSiteIndex = callSiteIndexForCodeOrigin(m_ftlState, CodeOrigin(0));
211         stackOverflowHandler->appendSomeRegister(m_callFrame);
212         stackOverflowHandler->clobber(RegisterSet::macroScratchRegisters());
213         stackOverflowHandler->numGPScratchRegisters = 1;
214         stackOverflowHandler->setGenerator(
215             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
216                 AllowMacroScratchRegisterUsage allowScratch(jit);
217                 GPRReg fp = params[0].gpr();
218                 GPRReg scratch = params.gpScratch(0);
219
220                 unsigned ftlFrameSize = params.proc().frameSize();
221
222                 jit.addPtr(MacroAssembler::TrustedImm32(-std::max(exitFrameSize, ftlFrameSize)), fp, scratch);
223                 MacroAssembler::Jump stackOverflow = jit.branchPtr(MacroAssembler::Above, addressOfStackLimit, scratch);
224
225                 params.addLatePath([=] (CCallHelpers& jit) {
226                     AllowMacroScratchRegisterUsage allowScratch(jit);
227
228                     stackOverflow.link(&jit);
229                     jit.store32(
230                         MacroAssembler::TrustedImm32(callSiteIndex.bits()),
231                         CCallHelpers::tagFor(VirtualRegister(CallFrameSlot::argumentCount)));
232                     jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm);
233
234                     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
235                     jit.move(CCallHelpers::TrustedImmPtr(jit.codeBlock()), GPRInfo::argumentGPR1);
236                     CCallHelpers::Call throwCall = jit.call();
237
238                     jit.move(CCallHelpers::TrustedImmPtr(vm), GPRInfo::argumentGPR0);
239                     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
240                     CCallHelpers::Call lookupExceptionHandlerCall = jit.call();
241                     jit.jumpToExceptionHandler(*vm);
242
243                     jit.addLinkTask(
244                         [=] (LinkBuffer& linkBuffer) {
245                             linkBuffer.link(throwCall, FunctionPtr(operationThrowStackOverflowError));
246                             linkBuffer.link(lookupExceptionHandlerCall, FunctionPtr(lookupExceptionHandlerFromCallerFrame));
247                     });
248                 });
249             });
250
251         LBasicBlock firstDFGBasicBlock = lowBlock(m_graph.block(0));
252         // Check Arguments.
253         availabilityMap().clear();
254         availabilityMap().m_locals = Operands<Availability>(codeBlock()->numParameters(), 0);
255         for (unsigned i = codeBlock()->numParameters(); i--;) {
256             availabilityMap().m_locals.argument(i) =
257                 Availability(FlushedAt(FlushedJSValue, virtualRegisterForArgument(i)));
258         }
259         m_node = nullptr;
260         m_origin = NodeOrigin(CodeOrigin(0), CodeOrigin(0), true);
261         for (unsigned i = codeBlock()->numParameters(); i--;) {
262             Node* node = m_graph.m_arguments[i];
263             m_out.setOrigin(node);
264             VirtualRegister operand = virtualRegisterForArgument(i);
265             
266             LValue jsValue = m_out.load64(addressFor(operand));
267             
268             if (node) {
269                 DFG_ASSERT(m_graph, node, operand == node->stackAccessData()->machineLocal);
270                 
271                 // This is a hack, but it's an effective one. It allows us to do CSE on the
272                 // primordial load of arguments. This assumes that the GetLocal that got put in
273                 // place of the original SetArgument doesn't have any effects before it. This
274                 // should hold true.
275                 m_loadedArgumentValues.add(node, jsValue);
276             }
277             
278             switch (m_graph.m_argumentFormats[i]) {
279             case FlushedInt32:
280                 speculate(BadType, jsValueValue(jsValue), node, isNotInt32(jsValue));
281                 break;
282             case FlushedBoolean:
283                 speculate(BadType, jsValueValue(jsValue), node, isNotBoolean(jsValue));
284                 break;
285             case FlushedCell:
286                 speculate(BadType, jsValueValue(jsValue), node, isNotCell(jsValue));
287                 break;
288             case FlushedJSValue:
289                 break;
290             default:
291                 DFG_CRASH(m_graph, node, "Bad flush format for argument");
292                 break;
293             }
294         }
295         m_out.jump(firstDFGBasicBlock);
296
297         m_out.appendTo(m_handleExceptions, firstDFGBasicBlock);
298         Box<CCallHelpers::Label> exceptionHandler = state->exceptionHandler;
299         m_out.patchpoint(Void)->setGenerator(
300             [=] (CCallHelpers& jit, const StackmapGenerationParams&) {
301                 CCallHelpers::Jump jump = jit.jump();
302                 jit.addLinkTask(
303                     [=] (LinkBuffer& linkBuffer) {
304                         linkBuffer.link(jump, linkBuffer.locationOf(*exceptionHandler));
305                     });
306             });
307         m_out.unreachable();
308
309         for (DFG::BasicBlock* block : preOrder)
310             compileBlock(block);
311
312         // Make sure everything is decorated. This does a bunch of deferred decorating. This has
313         // to happen last because our abstract heaps are generated lazily. They have to be
314         // generated lazily because we have an infiniten number of numbered, indexed, and
315         // absolute heaps. We only become aware of the ones we actually mention while lowering.
316         m_heaps.computeRangesAndDecorateInstructions();
317
318         // We create all Phi's up front, but we may then decide not to compile the basic block
319         // that would have contained one of them. So this creates orphans, which triggers B3
320         // validation failures. Calling this fixes the issue.
321         //
322         // Note that you should avoid the temptation to make this call conditional upon
323         // validation being enabled. B3 makes no guarantees of any kind of correctness when
324         // dealing with IR that would have failed validation. For example, it would be valid to
325         // write a B3 phase that so aggressively assumes the lack of orphans that it would crash
326         // if any orphans were around. We might even have such phases already.
327         m_proc.deleteOrphans();
328
329         // We put the blocks into the B3 procedure in a super weird order. Now we reorder them.
330         m_out.applyBlockOrder();
331     }
332
333 private:
334     
335     void createPhiVariables()
336     {
337         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
338             DFG::BasicBlock* block = m_graph.block(blockIndex);
339             if (!block)
340                 continue;
341             for (unsigned nodeIndex = block->size(); nodeIndex--;) {
342                 Node* node = block->at(nodeIndex);
343                 if (node->op() != DFG::Phi)
344                     continue;
345                 LType type;
346                 switch (node->flags() & NodeResultMask) {
347                 case NodeResultDouble:
348                     type = Double;
349                     break;
350                 case NodeResultInt32:
351                     type = Int32;
352                     break;
353                 case NodeResultInt52:
354                     type = Int64;
355                     break;
356                 case NodeResultBoolean:
357                     type = Int32;
358                     break;
359                 case NodeResultJS:
360                     type = Int64;
361                     break;
362                 default:
363                     DFG_CRASH(m_graph, node, "Bad Phi node result type");
364                     break;
365                 }
366                 m_phis.add(node, m_proc.add<Value>(B3::Phi, type, Origin(node)));
367             }
368         }
369     }
370     
371     void compileBlock(DFG::BasicBlock* block)
372     {
373         if (!block)
374             return;
375         
376         if (verboseCompilationEnabled())
377             dataLog("Compiling block ", *block, "\n");
378         
379         m_highBlock = block;
380         
381         // Make sure that any blocks created while lowering code in the high block have the frequency of
382         // the high block. This is appropriate because B3 doesn't need precise frequencies. It just needs
383         // something roughly approximate for things like register allocation.
384         m_out.setFrequency(m_highBlock->executionCount);
385         
386         LBasicBlock lowBlock = m_blocks.get(m_highBlock);
387         
388         m_nextHighBlock = 0;
389         for (BlockIndex nextBlockIndex = m_highBlock->index + 1; nextBlockIndex < m_graph.numBlocks(); ++nextBlockIndex) {
390             m_nextHighBlock = m_graph.block(nextBlockIndex);
391             if (m_nextHighBlock)
392                 break;
393         }
394         m_nextLowBlock = m_nextHighBlock ? m_blocks.get(m_nextHighBlock) : 0;
395         
396         // All of this effort to find the next block gives us the ability to keep the
397         // generated IR in roughly program order. This ought not affect the performance
398         // of the generated code (since we expect B3 to reorder things) but it will
399         // make IR dumps easier to read.
400         m_out.appendTo(lowBlock, m_nextLowBlock);
401         
402         if (Options::ftlCrashes())
403             m_out.trap();
404         
405         if (!m_highBlock->cfaHasVisited) {
406             if (verboseCompilationEnabled())
407                 dataLog("Bailing because CFA didn't reach.\n");
408             crash(m_highBlock, nullptr);
409             return;
410         }
411         
412         m_availabilityCalculator.beginBlock(m_highBlock);
413         
414         m_state.reset();
415         m_state.beginBasicBlock(m_highBlock);
416         
417         for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex) {
418             if (!compileNode(m_nodeIndex))
419                 break;
420         }
421     }
422
423     void safelyInvalidateAfterTermination()
424     {
425         if (verboseCompilationEnabled())
426             dataLog("Bailing.\n");
427         crash();
428
429         // Invalidate dominated blocks. Under normal circumstances we would expect
430         // them to be invalidated already. But you can have the CFA become more
431         // precise over time because the structures of objects change on the main
432         // thread. Failing to do this would result in weird crashes due to a value
433         // being used but not defined. Race conditions FTW!
434         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
435             DFG::BasicBlock* target = m_graph.block(blockIndex);
436             if (!target)
437                 continue;
438             if (m_graph.m_dominators->dominates(m_highBlock, target)) {
439                 if (verboseCompilationEnabled())
440                     dataLog("Block ", *target, " will bail also.\n");
441                 target->cfaHasVisited = false;
442             }
443         }
444     }
445
446     bool compileNode(unsigned nodeIndex)
447     {
448         if (!m_state.isValid()) {
449             safelyInvalidateAfterTermination();
450             return false;
451         }
452         
453         m_node = m_highBlock->at(nodeIndex);
454         m_origin = m_node->origin;
455         m_out.setOrigin(m_node);
456         
457         if (verboseCompilationEnabled())
458             dataLog("Lowering ", m_node, "\n");
459         
460         m_availableRecoveries.resize(0);
461         
462         m_interpreter.startExecuting();
463         m_interpreter.executeKnownEdgeTypes(m_node);
464         
465         switch (m_node->op()) {
466         case DFG::Upsilon:
467             compileUpsilon();
468             break;
469         case DFG::Phi:
470             compilePhi();
471             break;
472         case JSConstant:
473             break;
474         case DoubleConstant:
475             compileDoubleConstant();
476             break;
477         case Int52Constant:
478             compileInt52Constant();
479             break;
480         case LazyJSConstant:
481             compileLazyJSConstant();
482             break;
483         case DoubleRep:
484             compileDoubleRep();
485             break;
486         case DoubleAsInt32:
487             compileDoubleAsInt32();
488             break;
489         case DFG::ValueRep:
490             compileValueRep();
491             break;
492         case Int52Rep:
493             compileInt52Rep();
494             break;
495         case ValueToInt32:
496             compileValueToInt32();
497             break;
498         case BooleanToNumber:
499             compileBooleanToNumber();
500             break;
501         case ExtractOSREntryLocal:
502             compileExtractOSREntryLocal();
503             break;
504         case GetStack:
505             compileGetStack();
506             break;
507         case PutStack:
508             compilePutStack();
509             break;
510         case DFG::Check:
511             compileNoOp();
512             break;
513         case CallObjectConstructor:
514             compileCallObjectConstructor();
515             break;
516         case ToThis:
517             compileToThis();
518             break;
519         case ValueAdd:
520             compileValueAdd();
521             break;
522         case StrCat:
523             compileStrCat();
524             break;
525         case ArithAdd:
526         case ArithSub:
527             compileArithAddOrSub();
528             break;
529         case ArithClz32:
530             compileArithClz32();
531             break;
532         case ArithMul:
533             compileArithMul();
534             break;
535         case ArithDiv:
536             compileArithDiv();
537             break;
538         case ArithMod:
539             compileArithMod();
540             break;
541         case ArithMin:
542         case ArithMax:
543             compileArithMinOrMax();
544             break;
545         case ArithAbs:
546             compileArithAbs();
547             break;
548         case ArithSin:
549             compileArithSin();
550             break;
551         case ArithCos:
552             compileArithCos();
553             break;
554         case ArithTan:
555             compileArithTan();
556             break;
557         case ArithPow:
558             compileArithPow();
559             break;
560         case ArithRandom:
561             compileArithRandom();
562             break;
563         case ArithRound:
564             compileArithRound();
565             break;
566         case ArithFloor:
567             compileArithFloor();
568             break;
569         case ArithCeil:
570             compileArithCeil();
571             break;
572         case ArithTrunc:
573             compileArithTrunc();
574             break;
575         case ArithSqrt:
576             compileArithSqrt();
577             break;
578         case ArithLog:
579             compileArithLog();
580             break;
581         case ArithFRound:
582             compileArithFRound();
583             break;
584         case ArithNegate:
585             compileArithNegate();
586             break;
587         case DFG::BitAnd:
588             compileBitAnd();
589             break;
590         case DFG::BitOr:
591             compileBitOr();
592             break;
593         case DFG::BitXor:
594             compileBitXor();
595             break;
596         case BitRShift:
597             compileBitRShift();
598             break;
599         case BitLShift:
600             compileBitLShift();
601             break;
602         case BitURShift:
603             compileBitURShift();
604             break;
605         case UInt32ToNumber:
606             compileUInt32ToNumber();
607             break;
608         case CheckStructure:
609             compileCheckStructure();
610             break;
611         case CheckCell:
612             compileCheckCell();
613             break;
614         case CheckNotEmpty:
615             compileCheckNotEmpty();
616             break;
617         case CheckBadCell:
618             compileCheckBadCell();
619             break;
620         case CheckStringIdent:
621             compileCheckStringIdent();
622             break;
623         case GetExecutable:
624             compileGetExecutable();
625             break;
626         case Arrayify:
627         case ArrayifyToStructure:
628             compileArrayify();
629             break;
630         case PutStructure:
631             compilePutStructure();
632             break;
633         case TryGetById:
634             compileGetById(AccessType::TryGet);
635             break;
636         case GetById:
637         case GetByIdFlush:
638             compileGetById(AccessType::Get);
639             break;
640         case GetByIdWithThis:
641             compileGetByIdWithThis();
642             break;
643         case In:
644             compileIn();
645             break;
646         case HasOwnProperty:
647             compileHasOwnProperty();
648             break;
649         case PutById:
650         case PutByIdDirect:
651         case PutByIdFlush:
652             compilePutById();
653             break;
654         case PutByIdWithThis:
655             compilePutByIdWithThis();
656             break;
657         case PutGetterById:
658         case PutSetterById:
659             compilePutAccessorById();
660             break;
661         case PutGetterSetterById:
662             compilePutGetterSetterById();
663             break;
664         case PutGetterByVal:
665         case PutSetterByVal:
666             compilePutAccessorByVal();
667             break;
668         case GetButterfly:
669             compileGetButterfly();
670             break;
671         case ConstantStoragePointer:
672             compileConstantStoragePointer();
673             break;
674         case GetIndexedPropertyStorage:
675             compileGetIndexedPropertyStorage();
676             break;
677         case CheckArray:
678             compileCheckArray();
679             break;
680         case GetArrayLength:
681             compileGetArrayLength();
682             break;
683         case CheckInBounds:
684             compileCheckInBounds();
685             break;
686         case GetByVal:
687             compileGetByVal();
688             break;
689         case GetMyArgumentByVal:
690         case GetMyArgumentByValOutOfBounds:
691             compileGetMyArgumentByVal();
692             break;
693         case GetByValWithThis:
694             compileGetByValWithThis();
695             break;
696         case PutByVal:
697         case PutByValAlias:
698         case PutByValDirect:
699             compilePutByVal();
700             break;
701         case PutByValWithThis:
702             compilePutByValWithThis();
703             break;
704         case AtomicsAdd:
705         case AtomicsAnd:
706         case AtomicsCompareExchange:
707         case AtomicsExchange:
708         case AtomicsLoad:
709         case AtomicsOr:
710         case AtomicsStore:
711         case AtomicsSub:
712         case AtomicsXor:
713             compileAtomicsReadModifyWrite();
714             break;
715         case AtomicsIsLockFree:
716             compileAtomicsIsLockFree();
717             break;
718         case DefineDataProperty:
719             compileDefineDataProperty();
720             break;
721         case DefineAccessorProperty:
722             compileDefineAccessorProperty();
723             break;
724         case ArrayPush:
725             compileArrayPush();
726             break;
727         case ArrayPop:
728             compileArrayPop();
729             break;
730         case ArraySlice:
731             compileArraySlice();
732             break;
733         case CreateActivation:
734             compileCreateActivation();
735             break;
736         case NewFunction:
737         case NewGeneratorFunction:
738         case NewAsyncFunction:
739             compileNewFunction();
740             break;
741         case CreateDirectArguments:
742             compileCreateDirectArguments();
743             break;
744         case CreateScopedArguments:
745             compileCreateScopedArguments();
746             break;
747         case CreateClonedArguments:
748             compileCreateClonedArguments();
749             break;
750         case NewObject:
751             compileNewObject();
752             break;
753         case NewArray:
754             compileNewArray();
755             break;
756         case NewArrayWithSpread:
757             compileNewArrayWithSpread();
758             break;
759         case Spread:
760             compileSpread();
761             break;
762         case NewArrayBuffer:
763             compileNewArrayBuffer();
764             break;
765         case NewArrayWithSize:
766             compileNewArrayWithSize();
767             break;
768         case NewTypedArray:
769             compileNewTypedArray();
770             break;
771         case GetTypedArrayByteOffset:
772             compileGetTypedArrayByteOffset();
773             break;
774         case AllocatePropertyStorage:
775             compileAllocatePropertyStorage();
776             break;
777         case ReallocatePropertyStorage:
778             compileReallocatePropertyStorage();
779             break;
780         case NukeStructureAndSetButterfly:
781             compileNukeStructureAndSetButterfly();
782             break;
783         case ToNumber:
784             compileToNumber();
785             break;
786         case ToString:
787         case CallStringConstructor:
788             compileToStringOrCallStringConstructor();
789             break;
790         case ToPrimitive:
791             compileToPrimitive();
792             break;
793         case MakeRope:
794             compileMakeRope();
795             break;
796         case StringCharAt:
797             compileStringCharAt();
798             break;
799         case StringCharCodeAt:
800             compileStringCharCodeAt();
801             break;
802         case StringFromCharCode:
803             compileStringFromCharCode();
804             break;
805         case GetByOffset:
806         case GetGetterSetterByOffset:
807             compileGetByOffset();
808             break;
809         case GetGetter:
810             compileGetGetter();
811             break;
812         case GetSetter:
813             compileGetSetter();
814             break;
815         case MultiGetByOffset:
816             compileMultiGetByOffset();
817             break;
818         case PutByOffset:
819             compilePutByOffset();
820             break;
821         case MultiPutByOffset:
822             compileMultiPutByOffset();
823             break;
824         case GetGlobalVar:
825         case GetGlobalLexicalVariable:
826             compileGetGlobalVariable();
827             break;
828         case PutGlobalVariable:
829             compilePutGlobalVariable();
830             break;
831         case NotifyWrite:
832             compileNotifyWrite();
833             break;
834         case GetCallee:
835             compileGetCallee();
836             break;
837         case GetArgumentCountIncludingThis:
838             compileGetArgumentCountIncludingThis();
839             break;
840         case GetScope:
841             compileGetScope();
842             break;
843         case SkipScope:
844             compileSkipScope();
845             break;
846         case GetGlobalObject:
847             compileGetGlobalObject();
848             break;
849         case GetClosureVar:
850             compileGetClosureVar();
851             break;
852         case PutClosureVar:
853             compilePutClosureVar();
854             break;
855         case GetFromArguments:
856             compileGetFromArguments();
857             break;
858         case PutToArguments:
859             compilePutToArguments();
860             break;
861         case GetArgument:
862             compileGetArgument();
863             break;
864         case CompareEq:
865             compileCompareEq();
866             break;
867         case CompareStrictEq:
868             compileCompareStrictEq();
869             break;
870         case CompareLess:
871             compileCompareLess();
872             break;
873         case CompareLessEq:
874             compileCompareLessEq();
875             break;
876         case CompareGreater:
877             compileCompareGreater();
878             break;
879         case CompareGreaterEq:
880             compileCompareGreaterEq();
881             break;
882         case CompareEqPtr:
883             compileCompareEqPtr();
884             break;
885         case LogicalNot:
886             compileLogicalNot();
887             break;
888         case Call:
889         case TailCallInlinedCaller:
890         case Construct:
891             compileCallOrConstruct();
892             break;
893         case DirectCall:
894         case DirectTailCallInlinedCaller:
895         case DirectConstruct:
896         case DirectTailCall:
897             compileDirectCallOrConstruct();
898             break;
899         case TailCall:
900             compileTailCall();
901             break;
902         case CallVarargs:
903         case CallForwardVarargs:
904         case TailCallVarargs:
905         case TailCallVarargsInlinedCaller:
906         case TailCallForwardVarargs:
907         case TailCallForwardVarargsInlinedCaller:
908         case ConstructVarargs:
909         case ConstructForwardVarargs:
910             compileCallOrConstructVarargs();
911             break;
912         case CallEval:
913             compileCallEval();
914             break;
915         case LoadVarargs:
916             compileLoadVarargs();
917             break;
918         case ForwardVarargs:
919             compileForwardVarargs();
920             break;
921         case DFG::Jump:
922             compileJump();
923             break;
924         case DFG::Branch:
925             compileBranch();
926             break;
927         case DFG::Switch:
928             compileSwitch();
929             break;
930         case DFG::Return:
931             compileReturn();
932             break;
933         case ForceOSRExit:
934             compileForceOSRExit();
935             break;
936         case Throw:
937         case ThrowStaticError:
938             compileThrow();
939             break;
940         case InvalidationPoint:
941             compileInvalidationPoint();
942             break;
943         case IsEmpty:
944             compileIsEmpty();
945             break;
946         case IsUndefined:
947             compileIsUndefined();
948             break;
949         case IsBoolean:
950             compileIsBoolean();
951             break;
952         case IsNumber:
953             compileIsNumber();
954             break;
955         case IsCellWithType:
956             compileIsCellWithType();
957             break;
958         case MapHash:
959             compileMapHash();
960             break;
961         case GetMapBucket:
962             compileGetMapBucket();
963             break;
964         case LoadFromJSMapBucket:
965             compileLoadFromJSMapBucket();
966             break;
967         case IsNonEmptyMapBucket:
968             compileIsNonEmptyMapBucket();
969             break;
970         case IsObject:
971             compileIsObject();
972             break;
973         case IsObjectOrNull:
974             compileIsObjectOrNull();
975             break;
976         case IsFunction:
977             compileIsFunction();
978             break;
979         case IsTypedArrayView:
980             compileIsTypedArrayView();
981             break;
982         case ParseInt:
983             compileParseInt();
984             break;
985         case TypeOf:
986             compileTypeOf();
987             break;
988         case CheckTypeInfoFlags:
989             compileCheckTypeInfoFlags();
990             break;
991         case OverridesHasInstance:
992             compileOverridesHasInstance();
993             break;
994         case InstanceOf:
995             compileInstanceOf();
996             break;
997         case InstanceOfCustom:
998             compileInstanceOfCustom();
999             break;
1000         case CountExecution:
1001             compileCountExecution();
1002             break;
1003         case StoreBarrier:
1004         case FencedStoreBarrier:
1005             compileStoreBarrier();
1006             break;
1007         case HasIndexedProperty:
1008             compileHasIndexedProperty();
1009             break;
1010         case HasGenericProperty:
1011             compileHasGenericProperty();
1012             break;
1013         case HasStructureProperty:
1014             compileHasStructureProperty();
1015             break;
1016         case GetDirectPname:
1017             compileGetDirectPname();
1018             break;
1019         case GetEnumerableLength:
1020             compileGetEnumerableLength();
1021             break;
1022         case GetPropertyEnumerator:
1023             compileGetPropertyEnumerator();
1024             break;
1025         case GetEnumeratorStructurePname:
1026             compileGetEnumeratorStructurePname();
1027             break;
1028         case GetEnumeratorGenericPname:
1029             compileGetEnumeratorGenericPname();
1030             break;
1031         case ToIndexString:
1032             compileToIndexString();
1033             break;
1034         case CheckStructureImmediate:
1035             compileCheckStructureImmediate();
1036             break;
1037         case MaterializeNewObject:
1038             compileMaterializeNewObject();
1039             break;
1040         case MaterializeCreateActivation:
1041             compileMaterializeCreateActivation();
1042             break;
1043         case CheckTraps:
1044             if (Options::usePollingTraps())
1045                 compileCheckTraps();
1046             break;
1047         case CreateRest:
1048             compileCreateRest();
1049             break;
1050         case GetRestLength:
1051             compileGetRestLength();
1052             break;
1053         case RegExpExec:
1054             compileRegExpExec();
1055             break;
1056         case RegExpTest:
1057             compileRegExpTest();
1058             break;
1059         case NewRegexp:
1060             compileNewRegexp();
1061             break;
1062         case SetFunctionName:
1063             compileSetFunctionName();
1064             break;
1065         case StringReplace:
1066         case StringReplaceRegExp:
1067             compileStringReplace();
1068             break;
1069         case GetRegExpObjectLastIndex:
1070             compileGetRegExpObjectLastIndex();
1071             break;
1072         case SetRegExpObjectLastIndex:
1073             compileSetRegExpObjectLastIndex();
1074             break;
1075         case LogShadowChickenPrologue:
1076             compileLogShadowChickenPrologue();
1077             break;
1078         case LogShadowChickenTail:
1079             compileLogShadowChickenTail();
1080             break;
1081         case RecordRegExpCachedResult:
1082             compileRecordRegExpCachedResult();
1083             break;
1084         case ResolveScopeForHoistingFuncDeclInEval:
1085             compileResolveScopeForHoistingFuncDeclInEval();
1086             break;
1087         case ResolveScope:
1088             compileResolveScope();
1089             break;
1090         case GetDynamicVar:
1091             compileGetDynamicVar();
1092             break;
1093         case PutDynamicVar:
1094             compilePutDynamicVar();
1095             break;
1096         case Unreachable:
1097             compileUnreachable();
1098             break;
1099         case ToLowerCase:
1100             compileToLowerCase();
1101             break;
1102         case NumberToStringWithRadix:
1103             compileNumberToStringWithRadix();
1104             break;
1105         case CheckDOM:
1106             compileCheckDOM();
1107             break;
1108         case CallDOM:
1109             compileCallDOM();
1110             break;
1111         case CallDOMGetter:
1112             compileCallDOMGetter();
1113             break;
1114
1115         case PhantomLocal:
1116         case LoopHint:
1117         case MovHint:
1118         case ZombieHint:
1119         case ExitOK:
1120         case PhantomNewObject:
1121         case PhantomNewFunction:
1122         case PhantomNewGeneratorFunction:
1123         case PhantomNewAsyncFunction:
1124         case PhantomCreateActivation:
1125         case PhantomDirectArguments:
1126         case PhantomCreateRest:
1127         case PhantomSpread:
1128         case PhantomNewArrayWithSpread:
1129         case PhantomClonedArguments:
1130         case PutHint:
1131         case BottomValue:
1132         case KillStack:
1133             break;
1134         default:
1135             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
1136             break;
1137         }
1138         
1139         if (m_node->isTerminal())
1140             return false;
1141         
1142         if (!m_state.isValid()) {
1143             safelyInvalidateAfterTermination();
1144             return false;
1145         }
1146
1147         m_availabilityCalculator.executeNode(m_node);
1148         m_interpreter.executeEffects(nodeIndex);
1149         
1150         return true;
1151     }
1152
1153     void compileUpsilon()
1154     {
1155         LValue upsilonValue = nullptr;
1156         switch (m_node->child1().useKind()) {
1157         case DoubleRepUse:
1158             upsilonValue = lowDouble(m_node->child1());
1159             break;
1160         case Int32Use:
1161         case KnownInt32Use:
1162             upsilonValue = lowInt32(m_node->child1());
1163             break;
1164         case Int52RepUse:
1165             upsilonValue = lowInt52(m_node->child1());
1166             break;
1167         case BooleanUse:
1168         case KnownBooleanUse:
1169             upsilonValue = lowBoolean(m_node->child1());
1170             break;
1171         case CellUse:
1172         case KnownCellUse:
1173             upsilonValue = lowCell(m_node->child1());
1174             break;
1175         case UntypedUse:
1176             upsilonValue = lowJSValue(m_node->child1());
1177             break;
1178         default:
1179             DFG_CRASH(m_graph, m_node, "Bad use kind");
1180             break;
1181         }
1182         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
1183         LValue phiNode = m_phis.get(m_node->phi());
1184         m_out.addIncomingToPhi(phiNode, upsilon);
1185     }
1186     
1187     void compilePhi()
1188     {
1189         LValue phi = m_phis.get(m_node);
1190         m_out.m_block->append(phi);
1191
1192         switch (m_node->flags() & NodeResultMask) {
1193         case NodeResultDouble:
1194             setDouble(phi);
1195             break;
1196         case NodeResultInt32:
1197             setInt32(phi);
1198             break;
1199         case NodeResultInt52:
1200             setInt52(phi);
1201             break;
1202         case NodeResultBoolean:
1203             setBoolean(phi);
1204             break;
1205         case NodeResultJS:
1206             setJSValue(phi);
1207             break;
1208         default:
1209             DFG_CRASH(m_graph, m_node, "Bad use kind");
1210             break;
1211         }
1212     }
1213     
1214     void compileDoubleConstant()
1215     {
1216         setDouble(m_out.constDouble(m_node->asNumber()));
1217     }
1218     
1219     void compileInt52Constant()
1220     {
1221         int64_t value = m_node->asAnyInt();
1222         
1223         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1224         setStrictInt52(m_out.constInt64(value));
1225     }
1226
1227     void compileLazyJSConstant()
1228     {
1229         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1230         LazyJSValue value = m_node->lazyJSValue();
1231         patchpoint->setGenerator(
1232             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1233                 value.emit(jit, JSValueRegs(params[0].gpr()));
1234             });
1235         patchpoint->effects = Effects::none();
1236         setJSValue(patchpoint);
1237     }
1238
1239     void compileDoubleRep()
1240     {
1241         switch (m_node->child1().useKind()) {
1242         case RealNumberUse: {
1243             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1244             
1245             LValue doubleValue = unboxDouble(value);
1246             
1247             LBasicBlock intCase = m_out.newBlock();
1248             LBasicBlock continuation = m_out.newBlock();
1249             
1250             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1251             m_out.branch(
1252                 m_out.doubleEqual(doubleValue, doubleValue),
1253                 usually(continuation), rarely(intCase));
1254             
1255             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1256
1257             FTL_TYPE_CHECK(
1258                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1259                 isNotInt32(value, provenType(m_node->child1()) & ~SpecDoubleReal));
1260             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1261             m_out.jump(continuation);
1262             
1263             m_out.appendTo(continuation, lastNext);
1264             
1265             setDouble(m_out.phi(Double, fastResult, slowResult));
1266             return;
1267         }
1268             
1269         case NotCellUse:
1270         case NumberUse: {
1271             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1272             
1273             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1274
1275             LBasicBlock intCase = m_out.newBlock();
1276             LBasicBlock doubleTesting = m_out.newBlock();
1277             LBasicBlock doubleCase = m_out.newBlock();
1278             LBasicBlock nonDoubleCase = m_out.newBlock();
1279             LBasicBlock continuation = m_out.newBlock();
1280             
1281             m_out.branch(
1282                 isNotInt32(value, provenType(m_node->child1())),
1283                 unsure(doubleTesting), unsure(intCase));
1284             
1285             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1286             
1287             ValueFromBlock intToDouble = m_out.anchor(
1288                 m_out.intToDouble(unboxInt32(value)));
1289             m_out.jump(continuation);
1290             
1291             m_out.appendTo(doubleTesting, doubleCase);
1292             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1293             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1294
1295             m_out.appendTo(doubleCase, nonDoubleCase);
1296             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1297             m_out.jump(continuation);
1298
1299             if (shouldConvertNonNumber) {
1300                 LBasicBlock undefinedCase = m_out.newBlock();
1301                 LBasicBlock testNullCase = m_out.newBlock();
1302                 LBasicBlock nullCase = m_out.newBlock();
1303                 LBasicBlock testBooleanTrueCase = m_out.newBlock();
1304                 LBasicBlock convertBooleanTrueCase = m_out.newBlock();
1305                 LBasicBlock convertBooleanFalseCase = m_out.newBlock();
1306
1307                 m_out.appendTo(nonDoubleCase, undefinedCase);
1308                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1309                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1310
1311                 m_out.appendTo(undefinedCase, testNullCase);
1312                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1313                 m_out.jump(continuation);
1314
1315                 m_out.appendTo(testNullCase, nullCase);
1316                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1317                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1318
1319                 m_out.appendTo(nullCase, testBooleanTrueCase);
1320                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1321                 m_out.jump(continuation);
1322
1323                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1324                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1325                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1326
1327                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1328                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1329                 m_out.jump(continuation);
1330
1331                 m_out.appendTo(convertBooleanFalseCase, continuation);
1332
1333                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1334                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCell, valueIsNotBooleanFalse);
1335                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1336                 m_out.jump(continuation);
1337
1338                 m_out.appendTo(continuation, lastNext);
1339                 setDouble(m_out.phi(Double, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1340                 return;
1341             }
1342             m_out.appendTo(nonDoubleCase, continuation);
1343             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1344             m_out.unreachable();
1345
1346             m_out.appendTo(continuation, lastNext);
1347
1348             setDouble(m_out.phi(Double, intToDouble, unboxedDouble));
1349             return;
1350         }
1351             
1352         case Int52RepUse: {
1353             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1354             return;
1355         }
1356             
1357         default:
1358             DFG_CRASH(m_graph, m_node, "Bad use kind");
1359         }
1360     }
1361
1362     void compileDoubleAsInt32()
1363     {
1364         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1365         setInt32(integerValue);
1366     }
1367
1368     void compileValueRep()
1369     {
1370         switch (m_node->child1().useKind()) {
1371         case DoubleRepUse: {
1372             LValue value = lowDouble(m_node->child1());
1373             
1374             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1375                 value = m_out.select(
1376                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1377             }
1378             
1379             setJSValue(boxDouble(value));
1380             return;
1381         }
1382             
1383         case Int52RepUse: {
1384             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1385             return;
1386         }
1387             
1388         default:
1389             DFG_CRASH(m_graph, m_node, "Bad use kind");
1390         }
1391     }
1392     
1393     void compileInt52Rep()
1394     {
1395         switch (m_node->child1().useKind()) {
1396         case Int32Use:
1397             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1398             return;
1399             
1400         case AnyIntUse:
1401             setStrictInt52(
1402                 jsValueToStrictInt52(
1403                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1404             return;
1405             
1406         case DoubleRepAnyIntUse:
1407             setStrictInt52(
1408                 doubleToStrictInt52(
1409                     m_node->child1(), lowDouble(m_node->child1())));
1410             return;
1411             
1412         default:
1413             RELEASE_ASSERT_NOT_REACHED();
1414         }
1415     }
1416     
1417     void compileValueToInt32()
1418     {
1419         switch (m_node->child1().useKind()) {
1420         case Int52RepUse:
1421             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1422             break;
1423             
1424         case DoubleRepUse:
1425             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1426             break;
1427             
1428         case NumberUse:
1429         case NotCellUse: {
1430             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1431             if (isValid(value)) {
1432                 setInt32(value.value());
1433                 break;
1434             }
1435             
1436             value = m_jsValueValues.get(m_node->child1().node());
1437             if (isValid(value)) {
1438                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1439                 break;
1440             }
1441             
1442             // We'll basically just get here for constants. But it's good to have this
1443             // catch-all since we often add new representations into the mix.
1444             setInt32(
1445                 numberOrNotCellToInt32(
1446                     m_node->child1(),
1447                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1448             break;
1449         }
1450             
1451         default:
1452             DFG_CRASH(m_graph, m_node, "Bad use kind");
1453             break;
1454         }
1455     }
1456     
1457     void compileBooleanToNumber()
1458     {
1459         switch (m_node->child1().useKind()) {
1460         case BooleanUse: {
1461             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), Int32));
1462             return;
1463         }
1464             
1465         case UntypedUse: {
1466             LValue value = lowJSValue(m_node->child1());
1467             
1468             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1469                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1470                 return;
1471             }
1472             
1473             LBasicBlock booleanCase = m_out.newBlock();
1474             LBasicBlock continuation = m_out.newBlock();
1475             
1476             ValueFromBlock notBooleanResult = m_out.anchor(value);
1477             m_out.branch(
1478                 isBoolean(value, provenType(m_node->child1())),
1479                 unsure(booleanCase), unsure(continuation));
1480             
1481             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1482             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1483                 m_out.zeroExt(unboxBoolean(value), Int64), m_tagTypeNumber));
1484             m_out.jump(continuation);
1485             
1486             m_out.appendTo(continuation, lastNext);
1487             setJSValue(m_out.phi(Int64, booleanResult, notBooleanResult));
1488             return;
1489         }
1490             
1491         default:
1492             RELEASE_ASSERT_NOT_REACHED();
1493             return;
1494         }
1495     }
1496
1497     void compileExtractOSREntryLocal()
1498     {
1499         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1500             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1501         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1502     }
1503     
1504     void compileGetStack()
1505     {
1506         // GetLocals arise only for captured variables and arguments. For arguments, we might have
1507         // already loaded it.
1508         if (LValue value = m_loadedArgumentValues.get(m_node)) {
1509             setJSValue(value);
1510             return;
1511         }
1512         
1513         StackAccessData* data = m_node->stackAccessData();
1514         AbstractValue& value = m_state.variables().operand(data->local);
1515         
1516         DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
1517         DFG_ASSERT(m_graph, m_node, data->format != FlushedDouble); // This just happens to not arise for GetStacks, right now. It would be trivial to support.
1518         
1519         if (isInt32Speculation(value.m_type))
1520             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1521         else
1522             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1523     }
1524     
1525     void compilePutStack()
1526     {
1527         StackAccessData* data = m_node->stackAccessData();
1528         switch (data->format) {
1529         case FlushedJSValue: {
1530             LValue value = lowJSValue(m_node->child1());
1531             m_out.store64(value, addressFor(data->machineLocal));
1532             break;
1533         }
1534             
1535         case FlushedDouble: {
1536             LValue value = lowDouble(m_node->child1());
1537             m_out.storeDouble(value, addressFor(data->machineLocal));
1538             break;
1539         }
1540             
1541         case FlushedInt32: {
1542             LValue value = lowInt32(m_node->child1());
1543             m_out.store32(value, payloadFor(data->machineLocal));
1544             break;
1545         }
1546             
1547         case FlushedInt52: {
1548             LValue value = lowInt52(m_node->child1());
1549             m_out.store64(value, addressFor(data->machineLocal));
1550             break;
1551         }
1552             
1553         case FlushedCell: {
1554             LValue value = lowCell(m_node->child1());
1555             m_out.store64(value, addressFor(data->machineLocal));
1556             break;
1557         }
1558             
1559         case FlushedBoolean: {
1560             speculateBoolean(m_node->child1());
1561             m_out.store64(
1562                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1563                 addressFor(data->machineLocal));
1564             break;
1565         }
1566             
1567         default:
1568             DFG_CRASH(m_graph, m_node, "Bad flush format");
1569             break;
1570         }
1571     }
1572     
1573     void compileNoOp()
1574     {
1575         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1576     }
1577
1578     void compileCallObjectConstructor()
1579     {
1580         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1581         LValue value = lowJSValue(m_node->child1());
1582
1583         LBasicBlock isCellCase = m_out.newBlock();
1584         LBasicBlock slowCase = m_out.newBlock();
1585         LBasicBlock continuation = m_out.newBlock();
1586
1587         m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1588
1589         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1590         ValueFromBlock fastResult = m_out.anchor(value);
1591         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1592
1593         m_out.appendTo(slowCase, continuation);
1594         ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationObjectConstructor), m_callFrame, weakPointer(globalObject), value));
1595         m_out.jump(continuation);
1596
1597         m_out.appendTo(continuation, lastNext);
1598         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1599     }
1600     
1601     void compileToThis()
1602     {
1603         LValue value = lowJSValue(m_node->child1());
1604         
1605         LBasicBlock isCellCase = m_out.newBlock();
1606         LBasicBlock slowCase = m_out.newBlock();
1607         LBasicBlock continuation = m_out.newBlock();
1608         
1609         m_out.branch(
1610             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1611         
1612         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1613         ValueFromBlock fastResult = m_out.anchor(value);
1614         m_out.branch(
1615             m_out.testIsZero32(
1616                 m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
1617                 m_out.constInt32(OverridesToThis)),
1618             usually(continuation), rarely(slowCase));
1619         
1620         m_out.appendTo(slowCase, continuation);
1621         J_JITOperation_EJ function;
1622         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1623             function = operationToThisStrict;
1624         else
1625             function = operationToThis;
1626         ValueFromBlock slowResult = m_out.anchor(
1627             vmCall(Int64, m_out.operation(function), m_callFrame, value));
1628         m_out.jump(continuation);
1629         
1630         m_out.appendTo(continuation, lastNext);
1631         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1632     }
1633
1634     void compileValueAdd()
1635     {
1636         ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1637         JITAddIC* addIC = codeBlock()->addJITAddIC(arithProfile);
1638         auto repatchingFunction = operationValueAddOptimize;
1639         auto nonRepatchingFunction = operationValueAdd;
1640         compileMathIC(addIC, repatchingFunction, nonRepatchingFunction);
1641     }
1642
1643     template <typename Generator>
1644     void compileMathIC(JITUnaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
1645     {
1646         Node* node = m_node;
1647
1648         LValue operand = lowJSValue(node->child1());
1649
1650         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1651         patchpoint->appendSomeRegister(operand);
1652         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1653         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1654         RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
1655         patchpoint->numGPScratchRegisters = 1;
1656         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1657         State* state = &m_ftlState;
1658         patchpoint->setGenerator(
1659             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1660                 AllowMacroScratchRegisterUsage allowScratch(jit);
1661
1662                 Box<CCallHelpers::JumpList> exceptions =
1663                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1664
1665 #if ENABLE(MATH_IC_STATS)
1666                 auto inlineStart = jit.label();
1667 #endif
1668
1669                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1670                 mathIC->m_generator = Generator(JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()), params.gpScratch(0));
1671
1672                 bool shouldEmitProfiling = false;
1673                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1674
1675                 if (generatedInline) {
1676                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1677                     auto done = jit.label();
1678                     params.addLatePath([=] (CCallHelpers& jit) {
1679                         AllowMacroScratchRegisterUsage allowScratch(jit);
1680                         mathICGenerationState->slowPathJumps.link(&jit);
1681                         mathICGenerationState->slowPathStart = jit.label();
1682 #if ENABLE(MATH_IC_STATS)
1683                         auto slowPathStart = jit.label();
1684 #endif
1685
1686                         if (mathICGenerationState->shouldSlowPathRepatch) {
1687                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1688                                 repatchingFunction, params[0].gpr(), params[1].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1689                             mathICGenerationState->slowPathCall = call.call();
1690                         } else {
1691                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1692                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1693                             mathICGenerationState->slowPathCall = call.call();
1694                         }
1695                         jit.jump().linkTo(done, &jit);
1696
1697                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1698                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1699                         });
1700
1701 #if ENABLE(MATH_IC_STATS)
1702                         auto slowPathEnd = jit.label();
1703                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1704                             size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
1705                             mathIC->m_generatedCodeSize += size;
1706                         });
1707 #endif
1708                     });
1709                 } else {
1710                     callOperation(
1711                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1712                         nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1713                 }
1714
1715 #if ENABLE(MATH_IC_STATS)
1716                 auto inlineEnd = jit.label();
1717                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1718                     size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
1719                     mathIC->m_generatedCodeSize += size;
1720                 });
1721 #endif
1722             });
1723
1724         setJSValue(patchpoint);
1725     }
1726
1727     template <typename Generator>
1728     void compileMathIC(JITBinaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
1729     {
1730         Node* node = m_node;
1731         
1732         LValue left = lowJSValue(node->child1());
1733         LValue right = lowJSValue(node->child2());
1734
1735         SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
1736         SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
1737             
1738         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1739         patchpoint->appendSomeRegister(left);
1740         patchpoint->appendSomeRegister(right);
1741         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1742         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1743         RefPtr<PatchpointExceptionHandle> exceptionHandle =
1744             preparePatchpointForExceptions(patchpoint);
1745         patchpoint->numGPScratchRegisters = 1;
1746         patchpoint->numFPScratchRegisters = 2;
1747         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1748         State* state = &m_ftlState;
1749         patchpoint->setGenerator(
1750             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1751                 AllowMacroScratchRegisterUsage allowScratch(jit);
1752
1753                 Box<CCallHelpers::JumpList> exceptions =
1754                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1755
1756 #if ENABLE(MATH_IC_STATS)
1757                 auto inlineStart = jit.label();
1758 #endif
1759
1760                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1761                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
1762                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
1763                     params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
1764
1765                 bool shouldEmitProfiling = false;
1766                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1767
1768                 if (generatedInline) {
1769                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1770                     auto done = jit.label();
1771                     params.addLatePath([=] (CCallHelpers& jit) {
1772                         AllowMacroScratchRegisterUsage allowScratch(jit);
1773                         mathICGenerationState->slowPathJumps.link(&jit);
1774                         mathICGenerationState->slowPathStart = jit.label();
1775 #if ENABLE(MATH_IC_STATS)
1776                         auto slowPathStart = jit.label();
1777 #endif
1778
1779                         if (mathICGenerationState->shouldSlowPathRepatch) {
1780                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1781                                 repatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1782                             mathICGenerationState->slowPathCall = call.call();
1783                         } else {
1784                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1785                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1786                             mathICGenerationState->slowPathCall = call.call();
1787                         }
1788                         jit.jump().linkTo(done, &jit);
1789
1790                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1791                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1792                         });
1793
1794 #if ENABLE(MATH_IC_STATS)
1795                         auto slowPathEnd = jit.label();
1796                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1797                             size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
1798                             mathIC->m_generatedCodeSize += size;
1799                         });
1800 #endif
1801                     });
1802                 } else {
1803                     callOperation(
1804                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1805                         nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1806                 }
1807
1808 #if ENABLE(MATH_IC_STATS)
1809                 auto inlineEnd = jit.label();
1810                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1811                     size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
1812                     mathIC->m_generatedCodeSize += size;
1813                 });
1814 #endif
1815             });
1816
1817         setJSValue(patchpoint);
1818     }
1819     
1820     void compileStrCat()
1821     {
1822         LValue result;
1823         if (m_node->child3()) {
1824             result = vmCall(
1825                 Int64, m_out.operation(operationStrCat3), m_callFrame,
1826                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1827                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
1828                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
1829         } else {
1830             result = vmCall(
1831                 Int64, m_out.operation(operationStrCat2), m_callFrame,
1832                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1833                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
1834         }
1835         setJSValue(result);
1836     }
1837     
1838     void compileArithAddOrSub()
1839     {
1840         bool isSub =  m_node->op() == ArithSub;
1841         switch (m_node->binaryUseKind()) {
1842         case Int32Use: {
1843             LValue left = lowInt32(m_node->child1());
1844             LValue right = lowInt32(m_node->child2());
1845
1846             if (!shouldCheckOverflow(m_node->arithMode())) {
1847                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
1848                 break;
1849             }
1850
1851             CheckValue* result =
1852                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1853             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1854             setInt32(result);
1855             break;
1856         }
1857             
1858         case Int52RepUse: {
1859             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
1860                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
1861                 Int52Kind kind;
1862                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
1863                 LValue right = lowInt52(m_node->child2(), kind);
1864                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
1865                 break;
1866             }
1867
1868             LValue left = lowInt52(m_node->child1());
1869             LValue right = lowInt52(m_node->child2());
1870             CheckValue* result =
1871                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1872             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1873             setInt52(result);
1874             break;
1875         }
1876             
1877         case DoubleRepUse: {
1878             LValue C1 = lowDouble(m_node->child1());
1879             LValue C2 = lowDouble(m_node->child2());
1880
1881             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
1882             break;
1883         }
1884
1885         case UntypedUse: {
1886             if (!isSub) {
1887                 DFG_CRASH(m_graph, m_node, "Bad use kind");
1888                 break;
1889             }
1890
1891             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1892             JITSubIC* subIC = codeBlock()->addJITSubIC(arithProfile);
1893             auto repatchingFunction = operationValueSubOptimize;
1894             auto nonRepatchingFunction = operationValueSub;
1895             compileMathIC(subIC, repatchingFunction, nonRepatchingFunction);
1896             break;
1897         }
1898
1899         default:
1900             DFG_CRASH(m_graph, m_node, "Bad use kind");
1901             break;
1902         }
1903     }
1904
1905     void compileArithClz32()
1906     {
1907         if (m_node->child1().useKind() == Int32Use || m_node->child1().useKind() == KnownInt32Use) {
1908             LValue operand = lowInt32(m_node->child1());
1909             setInt32(m_out.ctlz32(operand));
1910             return;
1911         }
1912         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
1913         LValue argument = lowJSValue(m_node->child1());
1914         LValue result = vmCall(Int32, m_out.operation(operationArithClz32), m_callFrame, argument);
1915         setInt32(result);
1916     }
1917     
1918     void compileArithMul()
1919     {
1920         switch (m_node->binaryUseKind()) {
1921         case Int32Use: {
1922             LValue left = lowInt32(m_node->child1());
1923             LValue right = lowInt32(m_node->child2());
1924             
1925             LValue result;
1926
1927             if (!shouldCheckOverflow(m_node->arithMode()))
1928                 result = m_out.mul(left, right);
1929             else {
1930                 CheckValue* speculation = m_out.speculateMul(left, right);
1931                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
1932                 result = speculation;
1933             }
1934             
1935             if (shouldCheckNegativeZero(m_node->arithMode())) {
1936                 LBasicBlock slowCase = m_out.newBlock();
1937                 LBasicBlock continuation = m_out.newBlock();
1938                 
1939                 m_out.branch(
1940                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
1941                 
1942                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1943                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
1944                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
1945                 m_out.jump(continuation);
1946                 m_out.appendTo(continuation, lastNext);
1947             }
1948             
1949             setInt32(result);
1950             break;
1951         }
1952             
1953         case Int52RepUse: {
1954             Int52Kind kind;
1955             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1956             LValue right = lowInt52(m_node->child2(), opposite(kind));
1957
1958             CheckValue* result = m_out.speculateMul(left, right);
1959             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1960
1961             if (shouldCheckNegativeZero(m_node->arithMode())) {
1962                 LBasicBlock slowCase = m_out.newBlock();
1963                 LBasicBlock continuation = m_out.newBlock();
1964                 
1965                 m_out.branch(
1966                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
1967                 
1968                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1969                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
1970                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
1971                 m_out.jump(continuation);
1972                 m_out.appendTo(continuation, lastNext);
1973             }
1974             
1975             setInt52(result);
1976             break;
1977         }
1978             
1979         case DoubleRepUse: {
1980             setDouble(
1981                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1982             break;
1983         }
1984
1985         case UntypedUse: {
1986             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1987             JITMulIC* mulIC = codeBlock()->addJITMulIC(arithProfile);
1988             auto repatchingFunction = operationValueMulOptimize;
1989             auto nonRepatchingFunction = operationValueMul;
1990             compileMathIC(mulIC, repatchingFunction, nonRepatchingFunction);
1991             break;
1992         }
1993
1994         default:
1995             DFG_CRASH(m_graph, m_node, "Bad use kind");
1996             break;
1997         }
1998     }
1999
2000     void compileArithDiv()
2001     {
2002         switch (m_node->binaryUseKind()) {
2003         case Int32Use: {
2004             LValue numerator = lowInt32(m_node->child1());
2005             LValue denominator = lowInt32(m_node->child2());
2006
2007             if (shouldCheckNegativeZero(m_node->arithMode())) {
2008                 LBasicBlock zeroNumerator = m_out.newBlock();
2009                 LBasicBlock numeratorContinuation = m_out.newBlock();
2010
2011                 m_out.branch(
2012                     m_out.isZero32(numerator),
2013                     rarely(zeroNumerator), usually(numeratorContinuation));
2014
2015                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
2016
2017                 speculate(
2018                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
2019
2020                 m_out.jump(numeratorContinuation);
2021
2022                 m_out.appendTo(numeratorContinuation, innerLastNext);
2023             }
2024             
2025             if (shouldCheckOverflow(m_node->arithMode())) {
2026                 LBasicBlock unsafeDenominator = m_out.newBlock();
2027                 LBasicBlock continuation = m_out.newBlock();
2028
2029                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2030                 m_out.branch(
2031                     m_out.above(adjustedDenominator, m_out.int32One),
2032                     usually(continuation), rarely(unsafeDenominator));
2033
2034                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2035                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2036                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2037                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2038                 m_out.jump(continuation);
2039
2040                 m_out.appendTo(continuation, lastNext);
2041                 LValue result = m_out.div(numerator, denominator);
2042                 speculate(
2043                     Overflow, noValue(), 0,
2044                     m_out.notEqual(m_out.mul(result, denominator), numerator));
2045                 setInt32(result);
2046             } else
2047                 setInt32(m_out.chillDiv(numerator, denominator));
2048
2049             break;
2050         }
2051             
2052         case DoubleRepUse: {
2053             setDouble(m_out.doubleDiv(
2054                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2055             break;
2056         }
2057
2058         case UntypedUse: {
2059             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
2060             break;
2061         }
2062
2063         default:
2064             DFG_CRASH(m_graph, m_node, "Bad use kind");
2065             break;
2066         }
2067     }
2068     
2069     void compileArithMod()
2070     {
2071         switch (m_node->binaryUseKind()) {
2072         case Int32Use: {
2073             LValue numerator = lowInt32(m_node->child1());
2074             LValue denominator = lowInt32(m_node->child2());
2075
2076             LValue remainder;
2077             if (shouldCheckOverflow(m_node->arithMode())) {
2078                 LBasicBlock unsafeDenominator = m_out.newBlock();
2079                 LBasicBlock continuation = m_out.newBlock();
2080
2081                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2082                 m_out.branch(
2083                     m_out.above(adjustedDenominator, m_out.int32One),
2084                     usually(continuation), rarely(unsafeDenominator));
2085
2086                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2087                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2088                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2089                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2090                 m_out.jump(continuation);
2091
2092                 m_out.appendTo(continuation, lastNext);
2093                 LValue result = m_out.mod(numerator, denominator);
2094                 remainder = result;
2095             } else
2096                 remainder = m_out.chillMod(numerator, denominator);
2097
2098             if (shouldCheckNegativeZero(m_node->arithMode())) {
2099                 LBasicBlock negativeNumerator = m_out.newBlock();
2100                 LBasicBlock numeratorContinuation = m_out.newBlock();
2101
2102                 m_out.branch(
2103                     m_out.lessThan(numerator, m_out.int32Zero),
2104                     unsure(negativeNumerator), unsure(numeratorContinuation));
2105
2106                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
2107
2108                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
2109
2110                 m_out.jump(numeratorContinuation);
2111
2112                 m_out.appendTo(numeratorContinuation, innerLastNext);
2113             }
2114
2115             setInt32(remainder);
2116             break;
2117         }
2118             
2119         case DoubleRepUse: {
2120             setDouble(
2121                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2122             break;
2123         }
2124             
2125         default:
2126             DFG_CRASH(m_graph, m_node, "Bad use kind");
2127             break;
2128         }
2129     }
2130
2131     void compileArithMinOrMax()
2132     {
2133         switch (m_node->binaryUseKind()) {
2134         case Int32Use: {
2135             LValue left = lowInt32(m_node->child1());
2136             LValue right = lowInt32(m_node->child2());
2137             
2138             setInt32(
2139                 m_out.select(
2140                     m_node->op() == ArithMin
2141                         ? m_out.lessThan(left, right)
2142                         : m_out.lessThan(right, left),
2143                     left, right));
2144             break;
2145         }
2146             
2147         case DoubleRepUse: {
2148             LValue left = lowDouble(m_node->child1());
2149             LValue right = lowDouble(m_node->child2());
2150             
2151             LBasicBlock notLessThan = m_out.newBlock();
2152             LBasicBlock continuation = m_out.newBlock();
2153             
2154             Vector<ValueFromBlock, 2> results;
2155             
2156             results.append(m_out.anchor(left));
2157             m_out.branch(
2158                 m_node->op() == ArithMin
2159                     ? m_out.doubleLessThan(left, right)
2160                     : m_out.doubleGreaterThan(left, right),
2161                 unsure(continuation), unsure(notLessThan));
2162             
2163             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
2164             results.append(m_out.anchor(m_out.select(
2165                 m_node->op() == ArithMin
2166                     ? m_out.doubleGreaterThanOrEqual(left, right)
2167                     : m_out.doubleLessThanOrEqual(left, right),
2168                 right, m_out.constDouble(PNaN))));
2169             m_out.jump(continuation);
2170             
2171             m_out.appendTo(continuation, lastNext);
2172             setDouble(m_out.phi(Double, results));
2173             break;
2174         }
2175             
2176         default:
2177             DFG_CRASH(m_graph, m_node, "Bad use kind");
2178             break;
2179         }
2180     }
2181     
2182     void compileArithAbs()
2183     {
2184         switch (m_node->child1().useKind()) {
2185         case Int32Use: {
2186             LValue value = lowInt32(m_node->child1());
2187
2188             LValue mask = m_out.aShr(value, m_out.constInt32(31));
2189             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
2190
2191             if (shouldCheckOverflow(m_node->arithMode()))
2192                 speculate(Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2193
2194             setInt32(result);
2195             break;
2196         }
2197             
2198         case DoubleRepUse: {
2199             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
2200             break;
2201         }
2202             
2203         default: {
2204             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2205             LValue argument = lowJSValue(m_node->child1());
2206             LValue result = vmCall(Double, m_out.operation(operationArithAbs), m_callFrame, argument);
2207             setDouble(result);
2208             break;
2209         }
2210         }
2211     }
2212
2213     void compileArithSin()
2214     {
2215         if (m_node->child1().useKind() == DoubleRepUse) {
2216             setDouble(m_out.doubleSin(lowDouble(m_node->child1())));
2217             return;
2218         }
2219         LValue argument = lowJSValue(m_node->child1());
2220         LValue result = vmCall(Double, m_out.operation(operationArithSin), m_callFrame, argument);
2221         setDouble(result);
2222     }
2223
2224     void compileArithCos()
2225     {
2226         if (m_node->child1().useKind() == DoubleRepUse) {
2227             setDouble(m_out.doubleCos(lowDouble(m_node->child1())));
2228             return;
2229         }
2230         LValue argument = lowJSValue(m_node->child1());
2231         LValue result = vmCall(Double, m_out.operation(operationArithCos), m_callFrame, argument);
2232         setDouble(result);
2233     }
2234
2235     void compileArithTan()
2236     {
2237         if (m_node->child1().useKind() == DoubleRepUse) {
2238             setDouble(m_out.doubleTan(lowDouble(m_node->child1())));
2239             return;
2240         }
2241         LValue argument = lowJSValue(m_node->child1());
2242         LValue result = vmCall(Double, m_out.operation(operationArithTan), m_callFrame, argument);
2243         setDouble(result);
2244     }
2245
2246     void compileArithPow()
2247     {
2248         if (m_node->child2().useKind() == Int32Use)
2249             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
2250         else {
2251             LValue base = lowDouble(m_node->child1());
2252             LValue exponent = lowDouble(m_node->child2());
2253
2254             LBasicBlock integerExponentIsSmallBlock = m_out.newBlock();
2255             LBasicBlock integerExponentPowBlock = m_out.newBlock();
2256             LBasicBlock doubleExponentPowBlockEntry = m_out.newBlock();
2257             LBasicBlock nanExceptionBaseIsOne = m_out.newBlock();
2258             LBasicBlock nanExceptionExponentIsInfinity = m_out.newBlock();
2259             LBasicBlock testExponentIsOneHalf = m_out.newBlock();
2260             LBasicBlock handleBaseZeroExponentIsOneHalf = m_out.newBlock();
2261             LBasicBlock handleInfinityForExponentIsOneHalf = m_out.newBlock();
2262             LBasicBlock exponentIsOneHalfNormal = m_out.newBlock();
2263             LBasicBlock exponentIsOneHalfInfinity = m_out.newBlock();
2264             LBasicBlock testExponentIsNegativeOneHalf = m_out.newBlock();
2265             LBasicBlock testBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2266             LBasicBlock handleBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2267             LBasicBlock handleInfinityForExponentIsNegativeOneHalf = m_out.newBlock();
2268             LBasicBlock exponentIsNegativeOneHalfNormal = m_out.newBlock();
2269             LBasicBlock exponentIsNegativeOneHalfInfinity = m_out.newBlock();
2270             LBasicBlock powBlock = m_out.newBlock();
2271             LBasicBlock nanExceptionResultIsNaN = m_out.newBlock();
2272             LBasicBlock continuation = m_out.newBlock();
2273
2274             LValue integerExponent = m_out.doubleToInt(exponent);
2275             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
2276             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
2277             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
2278
2279             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
2280             LValue integerExponentBelowMax = m_out.belowOrEqual(integerExponent, m_out.constInt32(maxExponentForIntegerMathPow));
2281             m_out.branch(integerExponentBelowMax, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
2282
2283             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
2284             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
2285             m_out.jump(continuation);
2286
2287             // If y is NaN, the result is NaN.
2288             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionBaseIsOne);
2289             LValue exponentIsNaN;
2290             if (provenType(m_node->child2()) & SpecDoubleNaN)
2291                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
2292             else
2293                 exponentIsNaN = m_out.booleanFalse;
2294             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionBaseIsOne));
2295
2296             // If abs(x) is 1 and y is +infinity, the result is NaN.
2297             // If abs(x) is 1 and y is -infinity, the result is NaN.
2298
2299             //     Test if base == 1.
2300             m_out.appendTo(nanExceptionBaseIsOne, nanExceptionExponentIsInfinity);
2301             LValue absoluteBase = m_out.doubleAbs(base);
2302             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
2303             m_out.branch(absoluteBaseIsOne, rarely(nanExceptionExponentIsInfinity), usually(testExponentIsOneHalf));
2304
2305             //     Test if abs(y) == Infinity.
2306             m_out.appendTo(nanExceptionExponentIsInfinity, testExponentIsOneHalf);
2307             LValue absoluteExponent = m_out.doubleAbs(exponent);
2308             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
2309             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionResultIsNaN), usually(testExponentIsOneHalf));
2310
2311             // If y == 0.5 or y == -0.5, handle it through SQRT.
2312             // We have be carefuly with -0 and -Infinity.
2313
2314             //     Test if y == 0.5
2315             m_out.appendTo(testExponentIsOneHalf, handleBaseZeroExponentIsOneHalf);
2316             LValue exponentIsOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(0.5));
2317             m_out.branch(exponentIsOneHalf, rarely(handleBaseZeroExponentIsOneHalf), usually(testExponentIsNegativeOneHalf));
2318
2319             //     Handle x == -0.
2320             m_out.appendTo(handleBaseZeroExponentIsOneHalf, handleInfinityForExponentIsOneHalf);
2321             LValue baseIsZeroExponentIsOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2322             ValueFromBlock zeroResultExponentIsOneHalf = m_out.anchor(m_out.doubleZero);
2323             m_out.branch(baseIsZeroExponentIsOneHalf, rarely(continuation), usually(handleInfinityForExponentIsOneHalf));
2324
2325             //     Test if abs(x) == Infinity.
2326             m_out.appendTo(handleInfinityForExponentIsOneHalf, exponentIsOneHalfNormal);
2327             LValue absoluteBaseIsInfinityOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2328             m_out.branch(absoluteBaseIsInfinityOneHalf, rarely(exponentIsOneHalfInfinity), usually(exponentIsOneHalfNormal));
2329
2330             //     The exponent is 0.5, the base is finite or NaN, we can use SQRT.
2331             m_out.appendTo(exponentIsOneHalfNormal, exponentIsOneHalfInfinity);
2332             ValueFromBlock sqrtResult = m_out.anchor(m_out.doubleSqrt(base));
2333             m_out.jump(continuation);
2334
2335             //     The exponent is 0.5, the base is infinite, the result is always infinite.
2336             m_out.appendTo(exponentIsOneHalfInfinity, testExponentIsNegativeOneHalf);
2337             ValueFromBlock sqrtInfinityResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2338             m_out.jump(continuation);
2339
2340             //     Test if y == -0.5
2341             m_out.appendTo(testExponentIsNegativeOneHalf, testBaseZeroExponentIsNegativeOneHalf);
2342             LValue exponentIsNegativeOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(-0.5));
2343             m_out.branch(exponentIsNegativeOneHalf, rarely(testBaseZeroExponentIsNegativeOneHalf), usually(powBlock));
2344
2345             //     Handle x == -0.
2346             m_out.appendTo(testBaseZeroExponentIsNegativeOneHalf, handleBaseZeroExponentIsNegativeOneHalf);
2347             LValue baseIsZeroExponentIsNegativeOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2348             m_out.branch(baseIsZeroExponentIsNegativeOneHalf, rarely(handleBaseZeroExponentIsNegativeOneHalf), usually(handleInfinityForExponentIsNegativeOneHalf));
2349
2350             m_out.appendTo(handleBaseZeroExponentIsNegativeOneHalf, handleInfinityForExponentIsNegativeOneHalf);
2351             ValueFromBlock oneOverSqrtZeroResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2352             m_out.jump(continuation);
2353
2354             //     Test if abs(x) == Infinity.
2355             m_out.appendTo(handleInfinityForExponentIsNegativeOneHalf, exponentIsNegativeOneHalfNormal);
2356             LValue absoluteBaseIsInfinityNegativeOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2357             m_out.branch(absoluteBaseIsInfinityNegativeOneHalf, rarely(exponentIsNegativeOneHalfInfinity), usually(exponentIsNegativeOneHalfNormal));
2358
2359             //     The exponent is -0.5, the base is finite or NaN, we can use 1/SQRT.
2360             m_out.appendTo(exponentIsNegativeOneHalfNormal, exponentIsNegativeOneHalfInfinity);
2361             LValue sqrtBase = m_out.doubleSqrt(base);
2362             ValueFromBlock oneOverSqrtResult = m_out.anchor(m_out.div(m_out.constDouble(1.), sqrtBase));
2363             m_out.jump(continuation);
2364
2365             //     The exponent is -0.5, the base is infinite, the result is always zero.
2366             m_out.appendTo(exponentIsNegativeOneHalfInfinity, powBlock);
2367             ValueFromBlock oneOverSqrtInfinityResult = m_out.anchor(m_out.doubleZero);
2368             m_out.jump(continuation);
2369
2370             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
2371             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
2372             m_out.jump(continuation);
2373
2374             m_out.appendTo(nanExceptionResultIsNaN, continuation);
2375             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
2376             m_out.jump(continuation);
2377
2378             m_out.appendTo(continuation, lastNext);
2379             setDouble(m_out.phi(Double, powDoubleIntResult, zeroResultExponentIsOneHalf, sqrtResult, sqrtInfinityResult, oneOverSqrtZeroResult, oneOverSqrtResult, oneOverSqrtInfinityResult, powResult, pureNan));
2380         }
2381     }
2382
2383     void compileArithRandom()
2384     {
2385         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
2386
2387         // Inlined WeakRandom::advance().
2388         // uint64_t x = m_low;
2389         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
2390         LValue low = m_out.load64(m_out.absolute(lowAddress));
2391         // uint64_t y = m_high;
2392         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
2393         LValue high = m_out.load64(m_out.absolute(highAddress));
2394         // m_low = y;
2395         m_out.store64(high, m_out.absolute(lowAddress));
2396
2397         // x ^= x << 23;
2398         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
2399
2400         // x ^= x >> 17;
2401         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
2402
2403         // x ^= y ^ (y >> 26);
2404         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
2405
2406         // m_high = x;
2407         m_out.store64(phase3, m_out.absolute(highAddress));
2408
2409         // return x + y;
2410         LValue random64 = m_out.add(phase3, high);
2411
2412         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
2413         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
2414
2415         LValue double53Integer = m_out.intToDouble(random53);
2416
2417         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
2418         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
2419         static const double scale = 1.0 / (1ULL << 53);
2420
2421         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
2422         // It just reduces the exp part of the given 53bit double integer.
2423         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
2424         // Now we get 53bit precision random double value in [0, 1).
2425         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
2426
2427         setDouble(result);
2428     }
2429
2430     void compileArithRound()
2431     {
2432         if (m_node->child1().useKind() == DoubleRepUse) {
2433             LValue result = nullptr;
2434             if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
2435                 LValue value = lowDouble(m_node->child1());
2436                 result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
2437             } else {
2438                 LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
2439                 LBasicBlock continuation = m_out.newBlock();
2440
2441                 LValue value = lowDouble(m_node->child1());
2442                 LValue integerValue = m_out.doubleCeil(value);
2443                 ValueFromBlock integerValueResult = m_out.anchor(integerValue);
2444
2445                 LValue realPart = m_out.doubleSub(integerValue, value);
2446
2447                 m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
2448
2449                 LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
2450                 LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
2451                 ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
2452                 m_out.jump(continuation);
2453                 m_out.appendTo(continuation, lastNext);
2454
2455                 result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
2456             }
2457
2458             if (producesInteger(m_node->arithRoundingMode())) {
2459                 LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
2460                 setInt32(integerValue);
2461             } else
2462                 setDouble(result);
2463             return;
2464         }
2465
2466         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2467         LValue argument = lowJSValue(m_node->child1());
2468         setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
2469     }
2470
2471     void compileArithFloor()
2472     {
2473         if (m_node->child1().useKind() == DoubleRepUse) {
2474             LValue value = lowDouble(m_node->child1());
2475             LValue integerValue = m_out.doubleFloor(value);
2476             if (producesInteger(m_node->arithRoundingMode()))
2477                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2478             else
2479                 setDouble(integerValue);
2480             return;
2481         }
2482         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2483         LValue argument = lowJSValue(m_node->child1());
2484         setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
2485     }
2486
2487     void compileArithCeil()
2488     {
2489         if (m_node->child1().useKind() == DoubleRepUse) {
2490             LValue value = lowDouble(m_node->child1());
2491             LValue integerValue = m_out.doubleCeil(value);
2492             if (producesInteger(m_node->arithRoundingMode()))
2493                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2494             else
2495                 setDouble(integerValue);
2496             return;
2497         }
2498         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2499         LValue argument = lowJSValue(m_node->child1());
2500         setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
2501     }
2502
2503     void compileArithTrunc()
2504     {
2505         if (m_node->child1().useKind() == DoubleRepUse) {
2506             LValue value = lowDouble(m_node->child1());
2507             LValue result = m_out.doubleTrunc(value);
2508             if (producesInteger(m_node->arithRoundingMode()))
2509                 setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2510             else
2511                 setDouble(result);
2512             return;
2513         }
2514         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2515         LValue argument = lowJSValue(m_node->child1());
2516         setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
2517     }
2518
2519     void compileArithSqrt()
2520     {
2521         if (m_node->child1().useKind() == DoubleRepUse) {
2522             setDouble(m_out.doubleSqrt(lowDouble(m_node->child1())));
2523             return;
2524         }
2525         LValue argument = lowJSValue(m_node->child1());
2526         LValue result = vmCall(Double, m_out.operation(operationArithSqrt), m_callFrame, argument);
2527         setDouble(result);
2528     }
2529
2530     void compileArithLog()
2531     {
2532         if (m_node->child1().useKind() == DoubleRepUse) {
2533             setDouble(m_out.doubleLog(lowDouble(m_node->child1())));
2534             return;
2535         }
2536         LValue argument = lowJSValue(m_node->child1());
2537         LValue result = vmCall(Double, m_out.operation(operationArithLog), m_callFrame, argument);
2538         setDouble(result);
2539     }
2540     
2541     void compileArithFRound()
2542     {
2543         if (m_node->child1().useKind() == DoubleRepUse) {
2544             setDouble(m_out.fround(lowDouble(m_node->child1())));
2545             return;
2546         }
2547         LValue argument = lowJSValue(m_node->child1());
2548         LValue result = vmCall(Double, m_out.operation(operationArithFRound), m_callFrame, argument);
2549         setDouble(result);
2550     }
2551     
2552     void compileArithNegate()
2553     {
2554         switch (m_node->child1().useKind()) {
2555         case Int32Use: {
2556             LValue value = lowInt32(m_node->child1());
2557             
2558             LValue result;
2559             if (!shouldCheckOverflow(m_node->arithMode()))
2560                 result = m_out.neg(value);
2561             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
2562                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
2563                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
2564                 result = check;
2565             } else {
2566                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
2567                 result = m_out.neg(value);
2568             }
2569
2570             setInt32(result);
2571             break;
2572         }
2573             
2574         case Int52RepUse: {
2575             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
2576                 Int52Kind kind;
2577                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
2578                 LValue result = m_out.neg(value);
2579                 if (shouldCheckNegativeZero(m_node->arithMode()))
2580                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2581                 setInt52(result, kind);
2582                 break;
2583             }
2584             
2585             LValue value = lowInt52(m_node->child1());
2586             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
2587             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2588             if (shouldCheckNegativeZero(m_node->arithMode()))
2589                 speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2590             setInt52(result);
2591             break;
2592         }
2593             
2594         case DoubleRepUse: {
2595             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2596             break;
2597         }
2598             
2599         default:
2600             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2601             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2602             JITNegIC* negIC = codeBlock()->addJITNegIC(arithProfile);
2603             auto repatchingFunction = operationArithNegateOptimize;
2604             auto nonRepatchingFunction = operationArithNegate;
2605             compileMathIC(negIC, repatchingFunction, nonRepatchingFunction);
2606             break;
2607         }
2608     }
2609     
2610     void compileBitAnd()
2611     {
2612         if (m_node->isBinaryUseKind(UntypedUse)) {
2613             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2614             return;
2615         }
2616         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2617     }
2618     
2619     void compileBitOr()
2620     {
2621         if (m_node->isBinaryUseKind(UntypedUse)) {
2622             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2623             return;
2624         }
2625         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2626     }
2627     
2628     void compileBitXor()
2629     {
2630         if (m_node->isBinaryUseKind(UntypedUse)) {
2631             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2632             return;
2633         }
2634         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2635     }
2636     
2637     void compileBitRShift()
2638     {
2639         if (m_node->isBinaryUseKind(UntypedUse)) {
2640             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2641             return;
2642         }
2643         setInt32(m_out.aShr(
2644             lowInt32(m_node->child1()),
2645             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2646     }
2647     
2648     void compileBitLShift()
2649     {
2650         if (m_node->isBinaryUseKind(UntypedUse)) {
2651             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2652             return;
2653         }
2654         setInt32(m_out.shl(
2655             lowInt32(m_node->child1()),
2656             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2657     }
2658     
2659     void compileBitURShift()
2660     {
2661         if (m_node->isBinaryUseKind(UntypedUse)) {
2662             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2663             return;
2664         }
2665         setInt32(m_out.lShr(
2666             lowInt32(m_node->child1()),
2667             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2668     }
2669     
2670     void compileUInt32ToNumber()
2671     {
2672         LValue value = lowInt32(m_node->child1());
2673
2674         if (doesOverflow(m_node->arithMode())) {
2675             setStrictInt52(m_out.zeroExtPtr(value));
2676             return;
2677         }
2678
2679         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2680         setInt32(value);
2681     }
2682     
2683     void compileCheckStructure()
2684     {
2685         ExitKind exitKind;
2686         if (m_node->child1()->hasConstant())
2687             exitKind = BadConstantCache;
2688         else
2689             exitKind = BadCache;
2690
2691         switch (m_node->child1().useKind()) {
2692         case CellUse:
2693         case KnownCellUse: {
2694             LValue cell = lowCell(m_node->child1());
2695             
2696             checkStructure(
2697                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2698                 exitKind, m_node->structureSet(),
2699                 [&] (RegisteredStructure structure) {
2700                     return weakStructureID(structure);
2701                 });
2702             return;
2703         }
2704
2705         case CellOrOtherUse: {
2706             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2707
2708             LBasicBlock cellCase = m_out.newBlock();
2709             LBasicBlock notCellCase = m_out.newBlock();
2710             LBasicBlock continuation = m_out.newBlock();
2711
2712             m_out.branch(
2713                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2714
2715             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2716             checkStructure(
2717                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2718                 exitKind, m_node->structureSet(),
2719                 [&] (RegisteredStructure structure) {
2720                     return weakStructureID(structure);
2721                 });
2722             m_out.jump(continuation);
2723
2724             m_out.appendTo(notCellCase, continuation);
2725             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2726             m_out.jump(continuation);
2727
2728             m_out.appendTo(continuation, lastNext);
2729             return;
2730         }
2731
2732         default:
2733             DFG_CRASH(m_graph, m_node, "Bad use kind");
2734             return;
2735         }
2736     }
2737     
2738     void compileCheckCell()
2739     {
2740         LValue cell = lowCell(m_node->child1());
2741         
2742         speculate(
2743             BadCell, jsValueValue(cell), m_node->child1().node(),
2744             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2745     }
2746     
2747     void compileCheckBadCell()
2748     {
2749         terminate(BadCell);
2750     }
2751
2752     void compileCheckNotEmpty()
2753     {
2754         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2755     }
2756
2757     void compileCheckStringIdent()
2758     {
2759         UniquedStringImpl* uid = m_node->uidOperand();
2760         LValue stringImpl = lowStringIdent(m_node->child1());
2761         speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2762     }
2763
2764     void compileGetExecutable()
2765     {
2766         LValue cell = lowCell(m_node->child1());
2767         speculateFunction(m_node->child1(), cell);
2768         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2769     }
2770     
2771     void compileArrayify()
2772     {
2773         LValue cell = lowCell(m_node->child1());
2774         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2775         
2776         LBasicBlock unexpectedStructure = m_out.newBlock();
2777         LBasicBlock continuation = m_out.newBlock();
2778         
2779         auto isUnexpectedArray = [&] (LValue cell) {
2780             if (m_node->op() == Arrayify)
2781                 return m_out.logicalNot(isArrayTypeForArrayify(cell, m_node->arrayMode()));
2782
2783             ASSERT(m_node->op() == ArrayifyToStructure);
2784             return m_out.notEqual(m_out.load32(cell, m_heaps.JSCell_structureID), weakStructureID(m_node->structure()));
2785         };
2786
2787         m_out.branch(isUnexpectedArray(cell), rarely(unexpectedStructure), usually(continuation));
2788
2789         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2790         
2791         if (property) {
2792             switch (m_node->arrayMode().type()) {
2793             case Array::Int32:
2794             case Array::Double:
2795             case Array::Contiguous:
2796                 speculate(
2797                     Uncountable, noValue(), 0,
2798                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2799                 break;
2800             default:
2801                 break;
2802             }
2803         }
2804         
2805         switch (m_node->arrayMode().type()) {
2806         case Array::Int32:
2807             vmCall(Void, m_out.operation(operationEnsureInt32), m_callFrame, cell);
2808             break;
2809         case Array::Double:
2810             vmCall(Void, m_out.operation(operationEnsureDouble), m_callFrame, cell);
2811             break;
2812         case Array::Contiguous:
2813             vmCall(Void, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2814             break;
2815         case Array::ArrayStorage:
2816         case Array::SlowPutArrayStorage:
2817             vmCall(Void, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2818             break;
2819         default:
2820             DFG_CRASH(m_graph, m_node, "Bad array type");
2821             break;
2822         }
2823         
2824         speculate(BadIndexingType, jsValueValue(cell), 0, isUnexpectedArray(cell));
2825         m_out.jump(continuation);
2826         
2827         m_out.appendTo(continuation, lastNext);
2828     }
2829     
2830     void compilePutStructure()
2831     {
2832         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2833         
2834         RegisteredStructure oldStructure = m_node->transition()->previous;
2835         RegisteredStructure newStructure = m_node->transition()->next;
2836         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2837         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2838         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2839
2840         LValue cell = lowCell(m_node->child1()); 
2841         m_out.store32(
2842             weakStructureID(newStructure),
2843             cell, m_heaps.JSCell_structureID);
2844     }
2845     
2846     void compileGetById(AccessType type)
2847     {
2848         ASSERT(type == AccessType::Get || type == AccessType::TryGet);
2849         switch (m_node->child1().useKind()) {
2850         case CellUse: {
2851             setJSValue(getById(lowCell(m_node->child1()), type));
2852             return;
2853         }
2854             
2855         case UntypedUse: {
2856             // This is pretty weird, since we duplicate the slow path both here and in the
2857             // code generated by the IC. We should investigate making this less bad.
2858             // https://bugs.webkit.org/show_bug.cgi?id=127830
2859             LValue value = lowJSValue(m_node->child1());
2860             
2861             LBasicBlock cellCase = m_out.newBlock();
2862             LBasicBlock notCellCase = m_out.newBlock();
2863             LBasicBlock continuation = m_out.newBlock();
2864             
2865             m_out.branch(
2866                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2867             
2868             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2869             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
2870             m_out.jump(continuation);
2871
2872             J_JITOperation_EJI getByIdFunction;
2873             if (type == AccessType::Get)
2874                 getByIdFunction = operationGetByIdGeneric;
2875             else
2876                 getByIdFunction = operationTryGetByIdGeneric;
2877
2878             m_out.appendTo(notCellCase, continuation);
2879             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2880                 Int64, m_out.operation(getByIdFunction),
2881                 m_callFrame, value,
2882                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2883             m_out.jump(continuation);
2884             
2885             m_out.appendTo(continuation, lastNext);
2886             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
2887             return;
2888         }
2889             
2890         default:
2891             DFG_CRASH(m_graph, m_node, "Bad use kind");
2892             return;
2893         }
2894     }
2895
2896     void compileGetByIdWithThis()
2897     {
2898         if (m_node->child1().useKind() == CellUse && m_node->child2().useKind() == CellUse)
2899             setJSValue(getByIdWithThis(lowCell(m_node->child1()), lowCell(m_node->child2())));
2900         else {
2901             LValue base = lowJSValue(m_node->child1());
2902             LValue thisValue = lowJSValue(m_node->child2());
2903             
2904             LBasicBlock baseCellCase = m_out.newBlock();
2905             LBasicBlock notCellCase = m_out.newBlock();
2906             LBasicBlock thisValueCellCase = m_out.newBlock();
2907             LBasicBlock continuation = m_out.newBlock();
2908             
2909             m_out.branch(
2910                 isCell(base, provenType(m_node->child1())), unsure(baseCellCase), unsure(notCellCase));
2911             
2912             LBasicBlock lastNext = m_out.appendTo(baseCellCase, thisValueCellCase);
2913             
2914             m_out.branch(
2915                 isCell(thisValue, provenType(m_node->child2())), unsure(thisValueCellCase), unsure(notCellCase));
2916             
2917             m_out.appendTo(thisValueCellCase, notCellCase);
2918             ValueFromBlock cellResult = m_out.anchor(getByIdWithThis(base, thisValue));
2919             m_out.jump(continuation);
2920
2921             m_out.appendTo(notCellCase, continuation);
2922             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2923                 Int64, m_out.operation(operationGetByIdWithThis),
2924                 m_callFrame, base, thisValue,
2925                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2926             m_out.jump(continuation);
2927             
2928             m_out.appendTo(continuation, lastNext);
2929             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
2930         }
2931         
2932     }
2933
2934     void compileGetByValWithThis()
2935     {
2936         LValue base = lowJSValue(m_node->child1());
2937         LValue thisValue = lowJSValue(m_node->child2());
2938         LValue subscript = lowJSValue(m_node->child3());
2939
2940         LValue result = vmCall(Int64, m_out.operation(operationGetByValWithThis), m_callFrame, base, thisValue, subscript);
2941         setJSValue(result);
2942     }
2943
2944     void compilePutByIdWithThis()
2945     {
2946         LValue base = lowJSValue(m_node->child1());
2947         LValue thisValue = lowJSValue(m_node->child2());
2948         LValue value = lowJSValue(m_node->child3());
2949
2950         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByIdWithThisStrict : operationPutByIdWithThis),
2951             m_callFrame, base, thisValue, value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2952     }
2953
2954     void compilePutByValWithThis()
2955     {
2956         LValue base = lowJSValue(m_graph.varArgChild(m_node, 0));
2957         LValue thisValue = lowJSValue(m_graph.varArgChild(m_node, 1));
2958         LValue property = lowJSValue(m_graph.varArgChild(m_node, 2));
2959         LValue value = lowJSValue(m_graph.varArgChild(m_node, 3));
2960
2961         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis),
2962             m_callFrame, base, thisValue, property, value);
2963     }
2964     
2965     void compileAtomicsReadModifyWrite()
2966     {
2967         TypedArrayType type = m_node->arrayMode().typedArrayType();
2968         unsigned numExtraArgs = numExtraAtomicsArgs(m_node->op());
2969         Edge baseEdge = m_graph.child(m_node, 0);
2970         Edge indexEdge = m_graph.child(m_node, 1);
2971         Edge argEdges[maxNumExtraAtomicsArgs];
2972         for (unsigned i = numExtraArgs; i--;)
2973             argEdges[i] = m_graph.child(m_node, 2 + i);
2974         Edge storageEdge = m_graph.child(m_node, 2 + numExtraArgs);
2975         
2976         auto operation = [&] () -> LValue {
2977             switch (m_node->op()) {
2978             case AtomicsAdd:
2979                 return m_out.operation(operationAtomicsAdd);
2980             case AtomicsAnd:
2981                 return m_out.operation(operationAtomicsAnd);
2982             case AtomicsCompareExchange:
2983                 return m_out.operation(operationAtomicsCompareExchange);
2984             case AtomicsExchange:
2985                 return m_out.operation(operationAtomicsExchange);
2986             case AtomicsLoad:
2987                 return m_out.operation(operationAtomicsLoad);
2988             case AtomicsOr:
2989                 return m_out.operation(operationAtomicsOr);
2990             case AtomicsStore:
2991                 return m_out.operation(operationAtomicsStore);
2992             case AtomicsSub:
2993                 return m_out.operation(operationAtomicsSub);
2994             case AtomicsXor:
2995                 return m_out.operation(operationAtomicsXor);
2996             default:
2997                 RELEASE_ASSERT_NOT_REACHED();
2998                 break;
2999             }
3000         };
3001         
3002         if (!storageEdge) {
3003             Vector<LValue> args;
3004             args.append(m_callFrame);
3005             args.append(lowJSValue(baseEdge));
3006             args.append(lowJSValue(indexEdge));
3007             for (unsigned i = 0; i < numExtraArgs; ++i)
3008                 args.append(lowJSValue(argEdges[i]));
3009             LValue result = vmCall(Int64, operation(), args);
3010             setJSValue(result);
3011             return;
3012         }
3013         
3014         LValue index = lowInt32(indexEdge);
3015         LValue args[2];
3016         for (unsigned i = numExtraArgs; i--;)
3017             args[i] = getIntTypedArrayStoreOperand(argEdges[i]);
3018         LValue storage = lowStorage(storageEdge);
3019         
3020         TypedPointer pointer = pointerIntoTypedArray(storage, index, type);
3021         Width width = widthForBytes(elementSize(type));
3022         
3023         LValue atomicValue;
3024         LValue result;
3025         
3026         auto sanitizeResult = [&] (LValue value) -> LValue {
3027             if (isSigned(type)) {
3028                 switch (elementSize(type)) {
3029                 case 1:
3030                     value = m_out.bitAnd(value, m_out.constInt32(0xff));
3031                     break;
3032                 case 2:
3033                     value = m_out.bitAnd(value, m_out.constInt32(0xffff));
3034                     break;
3035                 case 4:
3036                     break;
3037                 default:
3038                     RELEASE_ASSERT_NOT_REACHED();
3039                     break;
3040                 }
3041             }
3042             return value;
3043         };
3044         
3045         switch (m_node->op()) {
3046         case AtomicsAdd:
3047             atomicValue = m_out.atomicXchgAdd(args[0], pointer, width);
3048             result = sanitizeResult(atomicValue);
3049             break;
3050         case AtomicsAnd:
3051             atomicValue = m_out.atomicXchgAnd(args[0], pointer, width);
3052             result = sanitizeResult(atomicValue);
3053             break;
3054         case AtomicsCompareExchange:
3055             atomicValue = m_out.atomicStrongCAS(args[0], args[1], pointer, width);
3056             result = sanitizeResult(atomicValue);
3057             break;
3058         case AtomicsExchange:
3059             atomicValue = m_out.atomicXchg(args[0], pointer, width);
3060             result = sanitizeResult(atomicValue);
3061             break;
3062         case AtomicsLoad:
3063             atomicValue = loadFromIntTypedArray(pointer, type);
3064             result = sanitizeResult(atomicValue);
3065             break;
3066         case AtomicsOr:
3067             atomicValue = m_out.atomicXchgOr(args[0], pointer, width);
3068             result = sanitizeResult(atomicValue);
3069             break;
3070         case AtomicsStore:
3071             atomicValue = m_out.store(args[0], pointer, storeType(type));
3072             result = args[0];
3073             break;
3074         case AtomicsSub:
3075             atomicValue = m_out.atomicXchgSub(args[0], pointer, width);
3076             result = sanitizeResult(atomicValue);
3077             break;
3078         case AtomicsXor:
3079             atomicValue = m_out.atomicXchgXor(args[0], pointer, width);
3080             result = sanitizeResult(atomicValue);
3081             break;
3082         default:
3083             RELEASE_ASSERT_NOT_REACHED();
3084             break;
3085         }
3086         // Signify that the state against which the atomic operations are serialized is confined to just
3087         // the typed array storage, since that's as precise of an abstraction as we can have of shared
3088         // array buffer storage.
3089         m_heaps.decorateFencedAccess(&m_heaps.typedArrayProperties, atomicValue);
3090         
3091         setIntTypedArrayLoadResult(result, type);
3092     }
3093     
3094     void compileAtomicsIsLockFree()
3095     {
3096         if (m_node->child1().useKind() != Int32Use) {
3097             setJSValue(vmCall(Int64, m_out.operation(operationAtomicsIsLockFree), m_callFrame, lowJSValue(m_node->child1())));
3098             return;
3099         }
3100         
3101         LValue bytes = lowInt32(m_node->child1());
3102         
3103         LBasicBlock trueCase = m_out.newBlock();
3104         LBasicBlock falseCase = m_out.newBlock();
3105         LBasicBlock continuation = m_out.newBlock();
3106         
3107         LBasicBlock lastNext = m_out.insertNewBlocksBefore(trueCase);
3108         
3109         Vector<SwitchCase> cases;
3110         cases.append(SwitchCase(m_out.constInt32(1), trueCase, Weight()));
3111         cases.append(SwitchCase(m_out.constInt32(2), trueCase, Weight()));
3112         cases.append(SwitchCase(m_out.constInt32(4), trueCase, Weight()));
3113         m_out.switchInstruction(bytes, cases, falseCase, Weight());
3114         
3115         m_out.appendTo(trueCase, falseCase);
3116         ValueFromBlock trueValue = m_out.anchor(m_out.booleanTrue);
3117         m_out.jump(continuation);
3118         m_out.appendTo(falseCase, continuation);
3119         ValueFromBlock falseValue = m_out.anchor(m_out.booleanFalse);
3120         m_out.jump(continuation);
3121         
3122         m_out.appendTo(continuation, lastNext);
3123         setBoolean(m_out.phi(Int32, trueValue, falseValue));
3124     }
3125
3126     void compileDefineDataProperty()
3127     {
3128         LValue base = lowCell(m_graph.varArgChild(m_node, 0));
3129         LValue value  = lowJSValue(m_graph.varArgChild(m_node, 2));
3130         LValue attributes = lowInt32(m_graph.varArgChild(m_node, 3));
3131         Edge& propertyEdge = m_graph.varArgChild(m_node, 1);
3132         switch (propertyEdge.useKind()) {
3133         case StringUse: {
3134             LValue property = lowString(propertyEdge);
3135             vmCall(Void, m_out.operation(operationDefineDataPropertyString), m_callFrame, base, property, value, attributes);
3136             break;
3137         }
3138         case StringIdentUse: {
3139             LValue property = lowStringIdent(propertyEdge);
3140             vmCall(Void, m_out.operation(operationDefineDataPropertyStringIdent), m_callFrame, base, property, value, attributes);
3141             break;
3142         }
3143         case SymbolUse: {
3144             LValue property = lowSymbol(propertyEdge);
3145             vmCall(Void, m_out.operation(operationDefineDataPropertySymbol), m_callFrame, base, property, value, attributes);
3146             break;
3147         }
3148         case UntypedUse: {
3149