87fd695553a32ee2014af1bedc1cd744a2bbbfc4
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGByteCodeParser.cpp
1 /*
2  * Copyright (C) 2011-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 "DFGByteCodeParser.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "ArithProfile.h"
32 #include "ArrayConstructor.h"
33 #include "BasicBlockLocation.h"
34 #include "BytecodeStructs.h"
35 #include "CallLinkStatus.h"
36 #include "CodeBlock.h"
37 #include "CodeBlockWithJITType.h"
38 #include "CommonSlowPaths.h"
39 #include "DFGAbstractHeap.h"
40 #include "DFGArrayMode.h"
41 #include "DFGCFG.h"
42 #include "DFGCapabilities.h"
43 #include "DFGClobberize.h"
44 #include "DFGClobbersExitState.h"
45 #include "DFGGraph.h"
46 #include "DFGJITCode.h"
47 #include "FunctionCodeBlock.h"
48 #include "GetByIdStatus.h"
49 #include "Heap.h"
50 #include "JSCInlines.h"
51 #include "JSModuleEnvironment.h"
52 #include "JSModuleNamespaceObject.h"
53 #include "NumberConstructor.h"
54 #include "ObjectConstructor.h"
55 #include "PreciseJumpTargets.h"
56 #include "PutByIdFlags.h"
57 #include "PutByIdStatus.h"
58 #include "RegExpPrototype.h"
59 #include "StackAlignment.h"
60 #include "StringConstructor.h"
61 #include "StructureStubInfo.h"
62 #include "Watchdog.h"
63 #include <wtf/CommaPrinter.h>
64 #include <wtf/HashMap.h>
65 #include <wtf/MathExtras.h>
66 #include <wtf/SetForScope.h>
67 #include <wtf/StdLibExtras.h>
68
69 namespace JSC { namespace DFG {
70
71 namespace DFGByteCodeParserInternal {
72 #ifdef NDEBUG
73 static const bool verbose = false;
74 #else
75 static const bool verbose = true;
76 #endif
77 } // namespace DFGByteCodeParserInternal
78
79 #define VERBOSE_LOG(...) do { \
80 if (DFGByteCodeParserInternal::verbose && Options::verboseDFGBytecodeParsing()) \
81 dataLog(__VA_ARGS__); \
82 } while (false)
83
84 class ConstantBufferKey {
85 public:
86     ConstantBufferKey()
87         : m_codeBlock(0)
88         , m_index(0)
89     {
90     }
91     
92     ConstantBufferKey(WTF::HashTableDeletedValueType)
93         : m_codeBlock(0)
94         , m_index(1)
95     {
96     }
97     
98     ConstantBufferKey(CodeBlock* codeBlock, unsigned index)
99         : m_codeBlock(codeBlock)
100         , m_index(index)
101     {
102     }
103     
104     bool operator==(const ConstantBufferKey& other) const
105     {
106         return m_codeBlock == other.m_codeBlock
107             && m_index == other.m_index;
108     }
109     
110     unsigned hash() const
111     {
112         return WTF::PtrHash<CodeBlock*>::hash(m_codeBlock) ^ m_index;
113     }
114     
115     bool isHashTableDeletedValue() const
116     {
117         return !m_codeBlock && m_index;
118     }
119     
120     CodeBlock* codeBlock() const { return m_codeBlock; }
121     unsigned index() const { return m_index; }
122     
123 private:
124     CodeBlock* m_codeBlock;
125     unsigned m_index;
126 };
127
128 struct ConstantBufferKeyHash {
129     static unsigned hash(const ConstantBufferKey& key) { return key.hash(); }
130     static bool equal(const ConstantBufferKey& a, const ConstantBufferKey& b)
131     {
132         return a == b;
133     }
134     
135     static const bool safeToCompareToEmptyOrDeleted = true;
136 };
137
138 } } // namespace JSC::DFG
139
140 namespace WTF {
141
142 template<typename T> struct DefaultHash;
143 template<> struct DefaultHash<JSC::DFG::ConstantBufferKey> {
144     typedef JSC::DFG::ConstantBufferKeyHash Hash;
145 };
146
147 template<typename T> struct HashTraits;
148 template<> struct HashTraits<JSC::DFG::ConstantBufferKey> : SimpleClassHashTraits<JSC::DFG::ConstantBufferKey> { };
149
150 } // namespace WTF
151
152 namespace JSC { namespace DFG {
153
154 // === ByteCodeParser ===
155 //
156 // This class is used to compile the dataflow graph from a CodeBlock.
157 class ByteCodeParser {
158 public:
159     ByteCodeParser(Graph& graph)
160         : m_vm(&graph.m_vm)
161         , m_codeBlock(graph.m_codeBlock)
162         , m_profiledBlock(graph.m_profiledBlock)
163         , m_graph(graph)
164         , m_currentBlock(0)
165         , m_currentIndex(0)
166         , m_constantUndefined(graph.freeze(jsUndefined()))
167         , m_constantNull(graph.freeze(jsNull()))
168         , m_constantNaN(graph.freeze(jsNumber(PNaN)))
169         , m_constantOne(graph.freeze(jsNumber(1)))
170         , m_numArguments(m_codeBlock->numParameters())
171         , m_numLocals(m_codeBlock->m_numCalleeLocals)
172         , m_parameterSlots(0)
173         , m_numPassedVarArgs(0)
174         , m_inlineStackTop(0)
175         , m_currentInstruction(0)
176         , m_hasDebuggerEnabled(graph.hasDebuggerEnabled())
177     {
178         ASSERT(m_profiledBlock);
179     }
180     
181     // Parse a full CodeBlock of bytecode.
182     void parse();
183     
184 private:
185     struct InlineStackEntry;
186
187     // Just parse from m_currentIndex to the end of the current CodeBlock.
188     void parseCodeBlock();
189     
190     void ensureLocals(unsigned newNumLocals)
191     {
192         VERBOSE_LOG("   ensureLocals: trying to raise m_numLocals from ", m_numLocals, " to ", newNumLocals, "\n");
193         if (newNumLocals <= m_numLocals)
194             return;
195         m_numLocals = newNumLocals;
196         for (size_t i = 0; i < m_graph.numBlocks(); ++i)
197             m_graph.block(i)->ensureLocals(newNumLocals);
198     }
199
200     // Helper for min and max.
201     template<typename ChecksFunctor>
202     bool handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis, const ChecksFunctor& insertChecks);
203     
204     void refineStatically(CallLinkStatus&, Node* callTarget);
205     // Blocks can either be targetable (i.e. in the m_blockLinkingTargets of one InlineStackEntry) with a well-defined bytecodeBegin,
206     // or they can be untargetable, with bytecodeBegin==UINT_MAX, to be managed manually and not by the linkBlock machinery.
207     // This is used most notably when doing polyvariant inlining (it requires a fair bit of control-flow with no bytecode analog).
208     // It is also used when doing an early return from an inlined callee: it is easier to fix the bytecode index later on if needed
209     // than to move the right index all the way to the treatment of op_ret.
210     BasicBlock* allocateTargetableBlock(unsigned bytecodeIndex);
211     BasicBlock* allocateUntargetableBlock();
212     // An untargetable block can be given a bytecodeIndex to be later managed by linkBlock, but only once, and it can never go in the other direction
213     void makeBlockTargetable(BasicBlock*, unsigned bytecodeIndex);
214     void addJumpTo(BasicBlock*);
215     void addJumpTo(unsigned bytecodeIndex);
216     // Handle calls. This resolves issues surrounding inlining and intrinsics.
217     enum Terminality { Terminal, NonTerminal };
218     Terminality handleCall(
219         int result, NodeType op, InlineCallFrame::Kind, unsigned instructionSize,
220         Node* callTarget, int argumentCountIncludingThis, int registerOffset, CallLinkStatus,
221         SpeculatedType prediction);
222     Terminality handleCall(Instruction* pc, NodeType op, CallMode);
223     Terminality handleVarargsCall(Instruction* pc, NodeType op, CallMode);
224     void emitFunctionChecks(CallVariant, Node* callTarget, VirtualRegister thisArgumnt);
225     void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis);
226     Node* getArgumentCount();
227     unsigned inliningCost(CallVariant, int argumentCountIncludingThis, InlineCallFrame::Kind); // Return UINT_MAX if it's not an inlining candidate. By convention, intrinsics have a cost of 1.
228     // Handle inlining. Return true if it succeeded, false if we need to plant a call.
229     bool handleInlining(Node* callTargetNode, int resultOperand, const CallLinkStatus&, int registerOffset, VirtualRegister thisArgument, VirtualRegister argumentsArgument, unsigned argumentsOffset, int argumentCountIncludingThis, unsigned nextOffset, NodeType callOp, InlineCallFrame::Kind, SpeculatedType prediction);
230     template<typename ChecksFunctor>
231     bool attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, SpeculatedType prediction, unsigned& inliningBalance, BasicBlock* continuationBlock, const ChecksFunctor& insertChecks);
232     template<typename ChecksFunctor>
233     void inlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, BasicBlock* continuationBlock, const ChecksFunctor& insertChecks);
234     void cancelLinkingForBlock(InlineStackEntry*, BasicBlock*); // Only works when the given block is the last one to have been added for that inline stack entry.
235     // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
236     template<typename ChecksFunctor>
237     bool handleIntrinsicCall(Node* callee, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
238     template<typename ChecksFunctor>
239     bool handleDOMJITCall(Node* callee, int resultOperand, const DOMJIT::Signature*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
240     template<typename ChecksFunctor>
241     bool handleIntrinsicGetter(int resultOperand, const GetByIdVariant& intrinsicVariant, Node* thisNode, const ChecksFunctor& insertChecks);
242     template<typename ChecksFunctor>
243     bool handleTypedArrayConstructor(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, TypedArrayType, const ChecksFunctor& insertChecks);
244     template<typename ChecksFunctor>
245     bool handleConstantInternalFunction(Node* callTargetNode, int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind, SpeculatedType, const ChecksFunctor& insertChecks);
246     Node* handlePutByOffset(Node* base, unsigned identifier, PropertyOffset, const InferredType::Descriptor&, Node* value);
247     Node* handleGetByOffset(SpeculatedType, Node* base, unsigned identifierNumber, PropertyOffset, const InferredType::Descriptor&, NodeType = GetByOffset);
248     bool handleDOMJITGetter(int resultOperand, const GetByIdVariant&, Node* thisNode, unsigned identifierNumber, SpeculatedType prediction);
249     bool handleModuleNamespaceLoad(int resultOperand, SpeculatedType, Node* base, GetByIdStatus);
250
251     // Create a presence ObjectPropertyCondition based on some known offset and structure set. Does not
252     // check the validity of the condition, but it may return a null one if it encounters a contradiction.
253     ObjectPropertyCondition presenceLike(
254         JSObject* knownBase, UniquedStringImpl*, PropertyOffset, const StructureSet&);
255     
256     // Attempt to watch the presence of a property. It will watch that the property is present in the same
257     // way as in all of the structures in the set. It may emit code instead of just setting a watchpoint.
258     // Returns true if this all works out.
259     bool checkPresenceLike(JSObject* knownBase, UniquedStringImpl*, PropertyOffset, const StructureSet&);
260     void checkPresenceLike(Node* base, UniquedStringImpl*, PropertyOffset, const StructureSet&);
261     
262     // Works with both GetByIdVariant and the setter form of PutByIdVariant.
263     template<typename VariantType>
264     Node* load(SpeculatedType, Node* base, unsigned identifierNumber, const VariantType&);
265
266     Node* store(Node* base, unsigned identifier, const PutByIdVariant&, Node* value);
267
268     void handleGetById(
269         int destinationOperand, SpeculatedType, Node* base, unsigned identifierNumber, GetByIdStatus, AccessType, unsigned instructionSize);
270     void emitPutById(
271         Node* base, unsigned identifierNumber, Node* value,  const PutByIdStatus&, bool isDirect);
272     void handlePutById(
273         Node* base, unsigned identifierNumber, Node* value, const PutByIdStatus&,
274         bool isDirect);
275     
276     // Either register a watchpoint or emit a check for this condition. Returns false if the
277     // condition no longer holds, and therefore no reasonable check can be emitted.
278     bool check(const ObjectPropertyCondition&);
279     
280     GetByOffsetMethod promoteToConstant(GetByOffsetMethod);
281     
282     // Either register a watchpoint or emit a check for this condition. It must be a Presence
283     // condition. It will attempt to promote a Presence condition to an Equivalence condition.
284     // Emits code for the loaded value that the condition guards, and returns a node containing
285     // the loaded value. Returns null if the condition no longer holds.
286     GetByOffsetMethod planLoad(const ObjectPropertyCondition&);
287     Node* load(SpeculatedType, unsigned identifierNumber, const GetByOffsetMethod&, NodeType = GetByOffset);
288     Node* load(SpeculatedType, const ObjectPropertyCondition&, NodeType = GetByOffset);
289     
290     // Calls check() for each condition in the set: that is, it either emits checks or registers
291     // watchpoints (or a combination of the two) to make the conditions hold. If any of those
292     // conditions are no longer checkable, returns false.
293     bool check(const ObjectPropertyConditionSet&);
294     
295     // Calls check() for those conditions that aren't the slot base, and calls load() for the slot
296     // base. Does a combination of watchpoint registration and check emission to guard the
297     // conditions, and emits code to load the value from the slot base. Returns a node containing
298     // the loaded value. Returns null if any of the conditions were no longer checkable.
299     GetByOffsetMethod planLoad(const ObjectPropertyConditionSet&);
300     Node* load(SpeculatedType, const ObjectPropertyConditionSet&, NodeType = GetByOffset);
301
302     void prepareToParseBlock();
303     void clearCaches();
304
305     // Parse a single basic block of bytecode instructions.
306     void parseBlock(unsigned limit);
307     // Link block successors.
308     void linkBlock(BasicBlock*, Vector<BasicBlock*>& possibleTargets);
309     void linkBlocks(Vector<BasicBlock*>& unlinkedBlocks, Vector<BasicBlock*>& possibleTargets);
310     
311     VariableAccessData* newVariableAccessData(VirtualRegister operand)
312     {
313         ASSERT(!operand.isConstant());
314         
315         m_graph.m_variableAccessData.append(VariableAccessData(operand));
316         return &m_graph.m_variableAccessData.last();
317     }
318     
319     // Get/Set the operands/result of a bytecode instruction.
320     Node* getDirect(VirtualRegister operand)
321     {
322         ASSERT(!operand.isConstant());
323
324         // Is this an argument?
325         if (operand.isArgument())
326             return getArgument(operand);
327
328         // Must be a local.
329         return getLocal(operand);
330     }
331
332     Node* get(VirtualRegister operand)
333     {
334         if (operand.isConstant()) {
335             unsigned constantIndex = operand.toConstantIndex();
336             unsigned oldSize = m_constants.size();
337             if (constantIndex >= oldSize || !m_constants[constantIndex]) {
338                 const CodeBlock& codeBlock = *m_inlineStackTop->m_codeBlock;
339                 JSValue value = codeBlock.getConstant(operand.offset());
340                 SourceCodeRepresentation sourceCodeRepresentation = codeBlock.constantSourceCodeRepresentation(operand.offset());
341                 if (constantIndex >= oldSize) {
342                     m_constants.grow(constantIndex + 1);
343                     for (unsigned i = oldSize; i < m_constants.size(); ++i)
344                         m_constants[i] = nullptr;
345                 }
346
347                 Node* constantNode = nullptr;
348                 if (sourceCodeRepresentation == SourceCodeRepresentation::Double)
349                     constantNode = addToGraph(DoubleConstant, OpInfo(m_graph.freezeStrong(jsDoubleNumber(value.asNumber()))));
350                 else
351                     constantNode = addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(value)));
352                 m_constants[constantIndex] = constantNode;
353             }
354             ASSERT(m_constants[constantIndex]);
355             return m_constants[constantIndex];
356         }
357         
358         if (inlineCallFrame()) {
359             if (!inlineCallFrame()->isClosureCall) {
360                 JSFunction* callee = inlineCallFrame()->calleeConstant();
361                 if (operand.offset() == CallFrameSlot::callee)
362                     return weakJSConstant(callee);
363             }
364         } else if (operand.offset() == CallFrameSlot::callee) {
365             // We have to do some constant-folding here because this enables CreateThis folding. Note
366             // that we don't have such watchpoint-based folding for inlined uses of Callee, since in that
367             // case if the function is a singleton then we already know it.
368             if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(*m_vm, m_codeBlock->ownerExecutable())) {
369                 InferredValue* singleton = executable->singletonFunction();
370                 if (JSValue value = singleton->inferredValue()) {
371                     m_graph.watchpoints().addLazily(singleton);
372                     JSFunction* function = jsCast<JSFunction*>(value);
373                     return weakJSConstant(function);
374                 }
375             }
376             return addToGraph(GetCallee);
377         }
378         
379         return getDirect(m_inlineStackTop->remapOperand(operand));
380     }
381     
382     enum SetMode {
383         // A normal set which follows a two-phase commit that spans code origins. During
384         // the current code origin it issues a MovHint, and at the start of the next
385         // code origin there will be a SetLocal. If the local needs flushing, the second
386         // SetLocal will be preceded with a Flush.
387         NormalSet,
388         
389         // A set where the SetLocal happens immediately and there is still a Flush. This
390         // is relevant when assigning to a local in tricky situations for the delayed
391         // SetLocal logic but where we know that we have not performed any side effects
392         // within this code origin. This is a safe replacement for NormalSet anytime we
393         // know that we have not yet performed side effects in this code origin.
394         ImmediateSetWithFlush,
395         
396         // A set where the SetLocal happens immediately and we do not Flush it even if
397         // this is a local that is marked as needing it. This is relevant when
398         // initializing locals at the top of a function.
399         ImmediateNakedSet
400     };
401     Node* setDirect(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
402     {
403         addToGraph(MovHint, OpInfo(operand.offset()), value);
404
405         // We can't exit anymore because our OSR exit state has changed.
406         m_exitOK = false;
407
408         DelayedSetLocal delayed(currentCodeOrigin(), operand, value, setMode);
409         
410         if (setMode == NormalSet) {
411             m_setLocalQueue.append(delayed);
412             return nullptr;
413         }
414         
415         return delayed.execute(this);
416     }
417     
418     void processSetLocalQueue()
419     {
420         for (unsigned i = 0; i < m_setLocalQueue.size(); ++i)
421             m_setLocalQueue[i].execute(this);
422         m_setLocalQueue.shrink(0);
423     }
424
425     Node* set(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
426     {
427         return setDirect(m_inlineStackTop->remapOperand(operand), value, setMode);
428     }
429     
430     Node* injectLazyOperandSpeculation(Node* node)
431     {
432         ASSERT(node->op() == GetLocal);
433         ASSERT(node->origin.semantic.bytecodeIndex == m_currentIndex);
434         ConcurrentJSLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
435         LazyOperandValueProfileKey key(m_currentIndex, node->local());
436         SpeculatedType prediction = m_inlineStackTop->m_lazyOperands.prediction(locker, key);
437         node->variableAccessData()->predict(prediction);
438         return node;
439     }
440
441     // Used in implementing get/set, above, where the operand is a local variable.
442     Node* getLocal(VirtualRegister operand)
443     {
444         unsigned local = operand.toLocal();
445
446         Node* node = m_currentBlock->variablesAtTail.local(local);
447         
448         // This has two goals: 1) link together variable access datas, and 2)
449         // try to avoid creating redundant GetLocals. (1) is required for
450         // correctness - no other phase will ensure that block-local variable
451         // access data unification is done correctly. (2) is purely opportunistic
452         // and is meant as an compile-time optimization only.
453         
454         VariableAccessData* variable;
455         
456         if (node) {
457             variable = node->variableAccessData();
458             
459             switch (node->op()) {
460             case GetLocal:
461                 return node;
462             case SetLocal:
463                 return node->child1().node();
464             default:
465                 break;
466             }
467         } else
468             variable = newVariableAccessData(operand);
469         
470         node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
471         m_currentBlock->variablesAtTail.local(local) = node;
472         return node;
473     }
474     Node* setLocal(const CodeOrigin& semanticOrigin, VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
475     {
476         SetForScope<CodeOrigin> originChange(m_currentSemanticOrigin, semanticOrigin);
477
478         unsigned local = operand.toLocal();
479         
480         if (setMode != ImmediateNakedSet) {
481             ArgumentPosition* argumentPosition = findArgumentPositionForLocal(operand);
482             if (argumentPosition)
483                 flushDirect(operand, argumentPosition);
484             else if (m_graph.needsScopeRegister() && operand == m_codeBlock->scopeRegister())
485                 flush(operand);
486         }
487
488         VariableAccessData* variableAccessData = newVariableAccessData(operand);
489         variableAccessData->mergeStructureCheckHoistingFailed(
490             m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadCache));
491         variableAccessData->mergeCheckArrayHoistingFailed(
492             m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadIndexingType));
493         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
494         m_currentBlock->variablesAtTail.local(local) = node;
495         return node;
496     }
497
498     // Used in implementing get/set, above, where the operand is an argument.
499     Node* getArgument(VirtualRegister operand)
500     {
501         unsigned argument = operand.toArgument();
502         ASSERT(argument < m_numArguments);
503         
504         Node* node = m_currentBlock->variablesAtTail.argument(argument);
505
506         VariableAccessData* variable;
507         
508         if (node) {
509             variable = node->variableAccessData();
510             
511             switch (node->op()) {
512             case GetLocal:
513                 return node;
514             case SetLocal:
515                 return node->child1().node();
516             default:
517                 break;
518             }
519         } else
520             variable = newVariableAccessData(operand);
521         
522         node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
523         m_currentBlock->variablesAtTail.argument(argument) = node;
524         return node;
525     }
526     Node* setArgument(const CodeOrigin& semanticOrigin, VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
527     {
528         SetForScope<CodeOrigin> originChange(m_currentSemanticOrigin, semanticOrigin);
529
530         unsigned argument = operand.toArgument();
531         ASSERT(argument < m_numArguments);
532         
533         VariableAccessData* variableAccessData = newVariableAccessData(operand);
534
535         // Always flush arguments, except for 'this'. If 'this' is created by us,
536         // then make sure that it's never unboxed.
537         if (argument || m_graph.needsFlushedThis()) {
538             if (setMode != ImmediateNakedSet)
539                 flushDirect(operand);
540         }
541         
542         if (!argument && m_codeBlock->specializationKind() == CodeForConstruct)
543             variableAccessData->mergeShouldNeverUnbox(true);
544         
545         variableAccessData->mergeStructureCheckHoistingFailed(
546             m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadCache));
547         variableAccessData->mergeCheckArrayHoistingFailed(
548             m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadIndexingType));
549         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
550         m_currentBlock->variablesAtTail.argument(argument) = node;
551         return node;
552     }
553     
554     ArgumentPosition* findArgumentPositionForArgument(int argument)
555     {
556         InlineStackEntry* stack = m_inlineStackTop;
557         while (stack->m_inlineCallFrame)
558             stack = stack->m_caller;
559         return stack->m_argumentPositions[argument];
560     }
561     
562     ArgumentPosition* findArgumentPositionForLocal(VirtualRegister operand)
563     {
564         for (InlineStackEntry* stack = m_inlineStackTop; ; stack = stack->m_caller) {
565             InlineCallFrame* inlineCallFrame = stack->m_inlineCallFrame;
566             if (!inlineCallFrame)
567                 break;
568             if (operand.offset() < static_cast<int>(inlineCallFrame->stackOffset + CallFrame::headerSizeInRegisters))
569                 continue;
570             if (operand.offset() == inlineCallFrame->stackOffset + CallFrame::thisArgumentOffset())
571                 continue;
572             if (operand.offset() >= static_cast<int>(inlineCallFrame->stackOffset + CallFrame::thisArgumentOffset() + inlineCallFrame->argumentsWithFixup.size()))
573                 continue;
574             int argument = VirtualRegister(operand.offset() - inlineCallFrame->stackOffset).toArgument();
575             return stack->m_argumentPositions[argument];
576         }
577         return 0;
578     }
579     
580     ArgumentPosition* findArgumentPosition(VirtualRegister operand)
581     {
582         if (operand.isArgument())
583             return findArgumentPositionForArgument(operand.toArgument());
584         return findArgumentPositionForLocal(operand);
585     }
586
587     void flush(VirtualRegister operand)
588     {
589         flushDirect(m_inlineStackTop->remapOperand(operand));
590     }
591     
592     void flushDirect(VirtualRegister operand)
593     {
594         flushDirect(operand, findArgumentPosition(operand));
595     }
596
597     void flushDirect(VirtualRegister operand, ArgumentPosition* argumentPosition)
598     {
599         addFlushOrPhantomLocal<Flush>(operand, argumentPosition);
600     }
601
602     template<NodeType nodeType>
603     void addFlushOrPhantomLocal(VirtualRegister operand, ArgumentPosition* argumentPosition)
604     {
605         ASSERT(!operand.isConstant());
606         
607         Node* node = m_currentBlock->variablesAtTail.operand(operand);
608         
609         VariableAccessData* variable;
610         
611         if (node)
612             variable = node->variableAccessData();
613         else
614             variable = newVariableAccessData(operand);
615         
616         node = addToGraph(nodeType, OpInfo(variable));
617         m_currentBlock->variablesAtTail.operand(operand) = node;
618         if (argumentPosition)
619             argumentPosition->addVariable(variable);
620     }
621
622     void phantomLocalDirect(VirtualRegister operand)
623     {
624         addFlushOrPhantomLocal<PhantomLocal>(operand, findArgumentPosition(operand));
625     }
626
627     void flush(InlineStackEntry* inlineStackEntry)
628     {
629         int numArguments;
630         if (InlineCallFrame* inlineCallFrame = inlineStackEntry->m_inlineCallFrame) {
631             ASSERT(!m_hasDebuggerEnabled);
632             numArguments = inlineCallFrame->argumentsWithFixup.size();
633             if (inlineCallFrame->isClosureCall)
634                 flushDirect(inlineStackEntry->remapOperand(VirtualRegister(CallFrameSlot::callee)));
635             if (inlineCallFrame->isVarargs())
636                 flushDirect(inlineStackEntry->remapOperand(VirtualRegister(CallFrameSlot::argumentCount)));
637         } else
638             numArguments = inlineStackEntry->m_codeBlock->numParameters();
639         for (unsigned argument = numArguments; argument-- > 1;)
640             flushDirect(inlineStackEntry->remapOperand(virtualRegisterForArgument(argument)));
641         if (!inlineStackEntry->m_inlineCallFrame && m_graph.needsFlushedThis())
642             flushDirect(virtualRegisterForArgument(0));
643
644         if (m_graph.needsScopeRegister())
645             flushDirect(m_codeBlock->scopeRegister());
646     }
647
648     void flushForTerminal()
649     {
650         CodeOrigin origin = currentCodeOrigin();
651         unsigned bytecodeIndex = origin.bytecodeIndex;
652
653         for (InlineStackEntry* inlineStackEntry = m_inlineStackTop; inlineStackEntry; inlineStackEntry = inlineStackEntry->m_caller) {
654             flush(inlineStackEntry);
655
656             ASSERT(origin.inlineCallFrame == inlineStackEntry->m_inlineCallFrame);
657             InlineCallFrame* inlineCallFrame = inlineStackEntry->m_inlineCallFrame;
658             CodeBlock* codeBlock = m_graph.baselineCodeBlockFor(inlineCallFrame);
659             FullBytecodeLiveness& fullLiveness = m_graph.livenessFor(codeBlock);
660             const FastBitVector& livenessAtBytecode = fullLiveness.getLiveness(bytecodeIndex);
661
662             for (unsigned local = codeBlock->m_numCalleeLocals; local--;) {
663                 if (livenessAtBytecode[local]) {
664                     VirtualRegister reg = virtualRegisterForLocal(local);
665                     if (inlineCallFrame)
666                         reg = inlineStackEntry->remapOperand(reg);
667                     phantomLocalDirect(reg);
668                 }
669             }
670
671             if (inlineCallFrame) {
672                 bytecodeIndex = inlineCallFrame->directCaller.bytecodeIndex;
673                 origin = inlineCallFrame->directCaller;
674             }
675         }
676     }
677
678     void flushForReturn()
679     {
680         flush(m_inlineStackTop);
681     }
682     
683     void flushIfTerminal(SwitchData& data)
684     {
685         if (data.fallThrough.bytecodeIndex() > m_currentIndex)
686             return;
687         
688         for (unsigned i = data.cases.size(); i--;) {
689             if (data.cases[i].target.bytecodeIndex() > m_currentIndex)
690                 return;
691         }
692         
693         flushForTerminal();
694     }
695
696     // Assumes that the constant should be strongly marked.
697     Node* jsConstant(JSValue constantValue)
698     {
699         return addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(constantValue)));
700     }
701
702     Node* weakJSConstant(JSValue constantValue)
703     {
704         return addToGraph(JSConstant, OpInfo(m_graph.freeze(constantValue)));
705     }
706
707     // Helper functions to get/set the this value.
708     Node* getThis()
709     {
710         return get(m_inlineStackTop->m_codeBlock->thisRegister());
711     }
712
713     void setThis(Node* value)
714     {
715         set(m_inlineStackTop->m_codeBlock->thisRegister(), value);
716     }
717
718     InlineCallFrame* inlineCallFrame()
719     {
720         return m_inlineStackTop->m_inlineCallFrame;
721     }
722
723     bool allInlineFramesAreTailCalls()
724     {
725         return !inlineCallFrame() || !inlineCallFrame()->getCallerSkippingTailCalls();
726     }
727
728     CodeOrigin currentCodeOrigin()
729     {
730         return CodeOrigin(m_currentIndex, inlineCallFrame());
731     }
732
733     NodeOrigin currentNodeOrigin()
734     {
735         CodeOrigin semantic;
736         CodeOrigin forExit;
737
738         if (m_currentSemanticOrigin.isSet())
739             semantic = m_currentSemanticOrigin;
740         else
741             semantic = currentCodeOrigin();
742
743         forExit = currentCodeOrigin();
744
745         return NodeOrigin(semantic, forExit, m_exitOK);
746     }
747     
748     BranchData* branchData(unsigned taken, unsigned notTaken)
749     {
750         // We assume that branches originating from bytecode always have a fall-through. We
751         // use this assumption to avoid checking for the creation of terminal blocks.
752         ASSERT((taken > m_currentIndex) || (notTaken > m_currentIndex));
753         BranchData* data = m_graph.m_branchData.add();
754         *data = BranchData::withBytecodeIndices(taken, notTaken);
755         return data;
756     }
757     
758     Node* addToGraph(Node* node)
759     {
760         VERBOSE_LOG("        appended ", node, " ", Graph::opName(node->op()), "\n");
761         m_currentBlock->append(node);
762         if (clobbersExitState(m_graph, node))
763             m_exitOK = false;
764         return node;
765     }
766     
767     Node* addToGraph(NodeType op, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
768     {
769         Node* result = m_graph.addNode(
770             op, currentNodeOrigin(), Edge(child1), Edge(child2),
771             Edge(child3));
772         return addToGraph(result);
773     }
774     Node* addToGraph(NodeType op, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
775     {
776         Node* result = m_graph.addNode(
777             op, currentNodeOrigin(), child1, child2, child3);
778         return addToGraph(result);
779     }
780     Node* addToGraph(NodeType op, OpInfo info, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
781     {
782         Node* result = m_graph.addNode(
783             op, currentNodeOrigin(), info, Edge(child1), Edge(child2),
784             Edge(child3));
785         return addToGraph(result);
786     }
787     Node* addToGraph(NodeType op, OpInfo info, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
788     {
789         Node* result = m_graph.addNode(op, currentNodeOrigin(), info, child1, child2, child3);
790         return addToGraph(result);
791     }
792     Node* addToGraph(NodeType op, OpInfo info1, OpInfo info2, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
793     {
794         Node* result = m_graph.addNode(
795             op, currentNodeOrigin(), info1, info2,
796             Edge(child1), Edge(child2), Edge(child3));
797         return addToGraph(result);
798     }
799     Node* addToGraph(NodeType op, OpInfo info1, OpInfo info2, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
800     {
801         Node* result = m_graph.addNode(
802             op, currentNodeOrigin(), info1, info2, child1, child2, child3);
803         return addToGraph(result);
804     }
805     
806     Node* addToGraph(Node::VarArgTag, NodeType op, OpInfo info1, OpInfo info2 = OpInfo())
807     {
808         Node* result = m_graph.addNode(
809             Node::VarArg, op, currentNodeOrigin(), info1, info2,
810             m_graph.m_varArgChildren.size() - m_numPassedVarArgs, m_numPassedVarArgs);
811         addToGraph(result);
812         
813         m_numPassedVarArgs = 0;
814         
815         return result;
816     }
817     
818     void addVarArgChild(Node* child)
819     {
820         m_graph.m_varArgChildren.append(Edge(child));
821         m_numPassedVarArgs++;
822     }
823     
824     Node* addCallWithoutSettingResult(
825         NodeType op, OpInfo opInfo, Node* callee, int argCount, int registerOffset,
826         OpInfo prediction)
827     {
828         addVarArgChild(callee);
829         size_t parameterSlots = Graph::parameterSlotsForArgCount(argCount);
830
831         if (parameterSlots > m_parameterSlots)
832             m_parameterSlots = parameterSlots;
833
834         for (int i = 0; i < argCount; ++i)
835             addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
836
837         return addToGraph(Node::VarArg, op, opInfo, prediction);
838     }
839     
840     Node* addCall(
841         int result, NodeType op, const DOMJIT::Signature* signature, Node* callee, int argCount, int registerOffset,
842         SpeculatedType prediction)
843     {
844         if (op == TailCall) {
845             if (allInlineFramesAreTailCalls())
846                 return addCallWithoutSettingResult(op, OpInfo(signature), callee, argCount, registerOffset, OpInfo());
847             op = TailCallInlinedCaller;
848         }
849
850
851         Node* call = addCallWithoutSettingResult(
852             op, OpInfo(signature), callee, argCount, registerOffset, OpInfo(prediction));
853         VirtualRegister resultReg(result);
854         if (resultReg.isValid())
855             set(resultReg, call);
856         return call;
857     }
858     
859     Node* cellConstantWithStructureCheck(JSCell* object, Structure* structure)
860     {
861         // FIXME: This should route to emitPropertyCheck, not the other way around. But currently,
862         // this gets no profit from using emitPropertyCheck() since we'll non-adaptively watch the
863         // object's structure as soon as we make it a weakJSCosntant.
864         Node* objectNode = weakJSConstant(object);
865         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), objectNode);
866         return objectNode;
867     }
868     
869     SpeculatedType getPredictionWithoutOSRExit(unsigned bytecodeIndex)
870     {
871         SpeculatedType prediction;
872         {
873             ConcurrentJSLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
874             prediction = m_inlineStackTop->m_profiledBlock->valueProfilePredictionForBytecodeOffset(locker, bytecodeIndex);
875         }
876
877         if (prediction != SpecNone)
878             return prediction;
879
880         // If we have no information about the values this
881         // node generates, we check if by any chance it is
882         // a tail call opcode. In that case, we walk up the
883         // inline frames to find a call higher in the call
884         // chain and use its prediction. If we only have
885         // inlined tail call frames, we use SpecFullTop
886         // to avoid a spurious OSR exit.
887         Instruction* instruction = m_inlineStackTop->m_profiledBlock->instructions().begin() + bytecodeIndex;
888         OpcodeID opcodeID = Interpreter::getOpcodeID(instruction->u.opcode);
889
890         switch (opcodeID) {
891         case op_tail_call:
892         case op_tail_call_varargs:
893         case op_tail_call_forward_arguments: {
894             // Things should be more permissive to us returning BOTTOM instead of TOP here.
895             // Currently, this will cause us to Force OSR exit. This is bad because returning
896             // TOP will cause anything that transitively touches this speculated type to
897             // also become TOP during prediction propagation.
898             // https://bugs.webkit.org/show_bug.cgi?id=164337
899             if (!inlineCallFrame())
900                 return SpecFullTop;
901
902             CodeOrigin* codeOrigin = inlineCallFrame()->getCallerSkippingTailCalls();
903             if (!codeOrigin)
904                 return SpecFullTop;
905
906             InlineStackEntry* stack = m_inlineStackTop;
907             while (stack->m_inlineCallFrame != codeOrigin->inlineCallFrame)
908                 stack = stack->m_caller;
909
910             bytecodeIndex = codeOrigin->bytecodeIndex;
911             CodeBlock* profiledBlock = stack->m_profiledBlock;
912             ConcurrentJSLocker locker(profiledBlock->m_lock);
913             return profiledBlock->valueProfilePredictionForBytecodeOffset(locker, bytecodeIndex);
914         }
915
916         default:
917             return SpecNone;
918         }
919
920         RELEASE_ASSERT_NOT_REACHED();
921         return SpecNone;
922     }
923
924     SpeculatedType getPrediction(unsigned bytecodeIndex)
925     {
926         SpeculatedType prediction = getPredictionWithoutOSRExit(bytecodeIndex);
927
928         if (prediction == SpecNone) {
929             // We have no information about what values this node generates. Give up
930             // on executing this code, since we're likely to do more damage than good.
931             addToGraph(ForceOSRExit);
932         }
933         
934         return prediction;
935     }
936     
937     SpeculatedType getPredictionWithoutOSRExit()
938     {
939         return getPredictionWithoutOSRExit(m_currentIndex);
940     }
941     
942     SpeculatedType getPrediction()
943     {
944         return getPrediction(m_currentIndex);
945     }
946     
947     ArrayMode getArrayMode(ArrayProfile* profile, Array::Action action)
948     {
949         ConcurrentJSLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
950         profile->computeUpdatedPrediction(locker, m_inlineStackTop->m_profiledBlock);
951         bool makeSafe = profile->outOfBounds(locker);
952         return ArrayMode::fromObserved(locker, profile, action, makeSafe);
953     }
954     
955     ArrayMode getArrayMode(ArrayProfile* profile)
956     {
957         return getArrayMode(profile, Array::Read);
958     }
959     
960     Node* makeSafe(Node* node)
961     {
962         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
963             node->mergeFlags(NodeMayOverflowInt32InDFG);
964         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
965             node->mergeFlags(NodeMayNegZeroInDFG);
966         
967         if (!isX86() && node->op() == ArithMod)
968             return node;
969
970         {
971             ArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->arithProfileForBytecodeOffset(m_currentIndex);
972             if (arithProfile) {
973                 switch (node->op()) {
974                 case ArithAdd:
975                 case ArithSub:
976                 case ValueAdd:
977                     if (arithProfile->didObserveDouble())
978                         node->mergeFlags(NodeMayHaveDoubleResult);
979                     if (arithProfile->didObserveNonNumber())
980                         node->mergeFlags(NodeMayHaveNonNumberResult);
981                     break;
982                 
983                 case ArithMul: {
984                     if (arithProfile->didObserveInt52Overflow())
985                         node->mergeFlags(NodeMayOverflowInt52);
986                     if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
987                         node->mergeFlags(NodeMayOverflowInt32InBaseline);
988                     if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
989                         node->mergeFlags(NodeMayNegZeroInBaseline);
990                     if (arithProfile->didObserveDouble())
991                         node->mergeFlags(NodeMayHaveDoubleResult);
992                     if (arithProfile->didObserveNonNumber())
993                         node->mergeFlags(NodeMayHaveNonNumberResult);
994                     break;
995                 }
996                 case ArithNegate: {
997                     ASSERT_WITH_MESSAGE(!arithProfile->didObserveNonNumber(), "op_negate starts with a toNumber() on the argument, it should only produce numbers.");
998
999                     if (arithProfile->lhsObservedType().sawNumber() || arithProfile->didObserveDouble())
1000                         node->mergeFlags(NodeMayHaveDoubleResult);
1001                     if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
1002                         node->mergeFlags(NodeMayNegZeroInBaseline);
1003                     if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
1004                         node->mergeFlags(NodeMayOverflowInt32InBaseline);
1005                     break;
1006                 }
1007                 
1008                 default:
1009                     break;
1010                 }
1011             }
1012         }
1013         
1014         if (m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex)) {
1015             switch (node->op()) {
1016             case UInt32ToNumber:
1017             case ArithAdd:
1018             case ArithSub:
1019             case ValueAdd:
1020             case ArithMod: // for ArithMod "MayOverflow" means we tried to divide by zero, or we saw double.
1021                 node->mergeFlags(NodeMayOverflowInt32InBaseline);
1022                 break;
1023                 
1024             default:
1025                 break;
1026             }
1027         }
1028         
1029         return node;
1030     }
1031     
1032     Node* makeDivSafe(Node* node)
1033     {
1034         ASSERT(node->op() == ArithDiv);
1035         
1036         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
1037             node->mergeFlags(NodeMayOverflowInt32InDFG);
1038         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
1039             node->mergeFlags(NodeMayNegZeroInDFG);
1040         
1041         // The main slow case counter for op_div in the old JIT counts only when
1042         // the operands are not numbers. We don't care about that since we already
1043         // have speculations in place that take care of that separately. We only
1044         // care about when the outcome of the division is not an integer, which
1045         // is what the special fast case counter tells us.
1046         
1047         if (!m_inlineStackTop->m_profiledBlock->couldTakeSpecialFastCase(m_currentIndex))
1048             return node;
1049         
1050         // FIXME: It might be possible to make this more granular.
1051         node->mergeFlags(NodeMayOverflowInt32InBaseline | NodeMayNegZeroInBaseline);
1052         
1053         return node;
1054     }
1055     
1056     void noticeArgumentsUse()
1057     {
1058         // All of the arguments in this function need to be formatted as JSValues because we will
1059         // load from them in a random-access fashion and we don't want to have to switch on
1060         // format.
1061         
1062         for (ArgumentPosition* argument : m_inlineStackTop->m_argumentPositions)
1063             argument->mergeShouldNeverUnbox(true);
1064     }
1065
1066     bool needsDynamicLookup(ResolveType, OpcodeID);
1067     
1068     VM* m_vm;
1069     CodeBlock* m_codeBlock;
1070     CodeBlock* m_profiledBlock;
1071     Graph& m_graph;
1072
1073     // The current block being generated.
1074     BasicBlock* m_currentBlock;
1075     // The bytecode index of the current instruction being generated.
1076     unsigned m_currentIndex;
1077     // The semantic origin of the current node if different from the current Index.
1078     CodeOrigin m_currentSemanticOrigin;
1079     // True if it's OK to OSR exit right now.
1080     bool m_exitOK { false };
1081
1082     FrozenValue* m_constantUndefined;
1083     FrozenValue* m_constantNull;
1084     FrozenValue* m_constantNaN;
1085     FrozenValue* m_constantOne;
1086     Vector<Node*, 16> m_constants;
1087
1088     // The number of arguments passed to the function.
1089     unsigned m_numArguments;
1090     // The number of locals (vars + temporaries) used in the function.
1091     unsigned m_numLocals;
1092     // The number of slots (in units of sizeof(Register)) that we need to
1093     // preallocate for arguments to outgoing calls from this frame. This
1094     // number includes the CallFrame slots that we initialize for the callee
1095     // (but not the callee-initialized CallerFrame and ReturnPC slots).
1096     // This number is 0 if and only if this function is a leaf.
1097     unsigned m_parameterSlots;
1098     // The number of var args passed to the next var arg node.
1099     unsigned m_numPassedVarArgs;
1100
1101     HashMap<ConstantBufferKey, unsigned> m_constantBufferCache;
1102     
1103     struct InlineStackEntry {
1104         ByteCodeParser* m_byteCodeParser;
1105         
1106         CodeBlock* m_codeBlock;
1107         CodeBlock* m_profiledBlock;
1108         InlineCallFrame* m_inlineCallFrame;
1109         
1110         ScriptExecutable* executable() { return m_codeBlock->ownerScriptExecutable(); }
1111         
1112         QueryableExitProfile m_exitProfile;
1113         
1114         // Remapping of identifier and constant numbers from the code block being
1115         // inlined (inline callee) to the code block that we're inlining into
1116         // (the machine code block, which is the transitive, though not necessarily
1117         // direct, caller).
1118         Vector<unsigned> m_identifierRemap;
1119         Vector<unsigned> m_constantBufferRemap;
1120         Vector<unsigned> m_switchRemap;
1121         
1122         // These are blocks whose terminal is a Jump, Branch or Switch, and whose target has not yet been linked.
1123         // Their terminal instead refers to a bytecode index, and the right BB can be found in m_blockLinkingTargets.
1124         Vector<BasicBlock*> m_unlinkedBlocks;
1125         
1126         // Potential block linking targets. Must be sorted by bytecodeBegin, and
1127         // cannot have two blocks that have the same bytecodeBegin.
1128         Vector<BasicBlock*> m_blockLinkingTargets;
1129
1130         // This is set by op_enter in parseBlock(), and indicates the first block of the function.
1131         BasicBlock* m_entryBlock;
1132
1133         // Optional: a continuation block for returns to jump to. It is set by early returns if it does not exist.
1134         BasicBlock* m_continuationBlock;
1135
1136         VirtualRegister m_returnValue;
1137         
1138         // Speculations about variable types collected from the profiled code block,
1139         // which are based on OSR exit profiles that past DFG compilations of this
1140         // code block had gathered.
1141         LazyOperandValueProfileParser m_lazyOperands;
1142         
1143         CallLinkInfoMap m_callLinkInfos;
1144         StubInfoMap m_stubInfos;
1145         ByValInfoMap m_byValInfos;
1146         
1147         // Pointers to the argument position trackers for this slice of code.
1148         Vector<ArgumentPosition*> m_argumentPositions;
1149         
1150         InlineStackEntry* m_caller;
1151         
1152         InlineStackEntry(
1153             ByteCodeParser*,
1154             CodeBlock*,
1155             CodeBlock* profiledBlock,
1156             JSFunction* callee, // Null if this is a closure call.
1157             VirtualRegister returnValueVR,
1158             VirtualRegister inlineCallFrameStart,
1159             int argumentCountIncludingThis,
1160             InlineCallFrame::Kind,
1161             BasicBlock* continuationBlock);
1162         
1163         ~InlineStackEntry()
1164         {
1165             m_byteCodeParser->m_inlineStackTop = m_caller;
1166         }
1167         
1168         VirtualRegister remapOperand(VirtualRegister operand) const
1169         {
1170             if (!m_inlineCallFrame)
1171                 return operand;
1172             
1173             ASSERT(!operand.isConstant());
1174
1175             return VirtualRegister(operand.offset() + m_inlineCallFrame->stackOffset);
1176         }
1177     };
1178     
1179     InlineStackEntry* m_inlineStackTop;
1180     
1181     struct DelayedSetLocal {
1182         CodeOrigin m_origin;
1183         VirtualRegister m_operand;
1184         Node* m_value;
1185         SetMode m_setMode;
1186         
1187         DelayedSetLocal() { }
1188         DelayedSetLocal(const CodeOrigin& origin, VirtualRegister operand, Node* value, SetMode setMode)
1189             : m_origin(origin)
1190             , m_operand(operand)
1191             , m_value(value)
1192             , m_setMode(setMode)
1193         {
1194             RELEASE_ASSERT(operand.isValid());
1195         }
1196         
1197         Node* execute(ByteCodeParser* parser)
1198         {
1199             if (m_operand.isArgument())
1200                 return parser->setArgument(m_origin, m_operand, m_value, m_setMode);
1201             return parser->setLocal(m_origin, m_operand, m_value, m_setMode);
1202         }
1203     };
1204     
1205     Vector<DelayedSetLocal, 2> m_setLocalQueue;
1206
1207     CodeBlock* m_dfgCodeBlock;
1208     CallLinkStatus::ContextMap m_callContextMap;
1209     StubInfoMap m_dfgStubInfos;
1210     
1211     Instruction* m_currentInstruction;
1212     bool m_hasDebuggerEnabled;
1213 };
1214
1215 BasicBlock* ByteCodeParser::allocateTargetableBlock(unsigned bytecodeIndex)
1216 {
1217     ASSERT(bytecodeIndex != UINT_MAX);
1218     Ref<BasicBlock> block = adoptRef(*new BasicBlock(bytecodeIndex, m_numArguments, m_numLocals, 1));
1219     BasicBlock* blockPtr = block.ptr();
1220     m_inlineStackTop->m_blockLinkingTargets.append(blockPtr);
1221     m_graph.appendBlock(WTFMove(block));
1222     return blockPtr;
1223 }
1224
1225 BasicBlock* ByteCodeParser::allocateUntargetableBlock()
1226 {
1227     Ref<BasicBlock> block = adoptRef(*new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, 1));
1228     BasicBlock* blockPtr = block.ptr();
1229     m_graph.appendBlock(WTFMove(block));
1230     return blockPtr;
1231 }
1232
1233 void ByteCodeParser::makeBlockTargetable(BasicBlock* block, unsigned bytecodeIndex)
1234 {
1235     ASSERT(block->bytecodeBegin == UINT_MAX);
1236     block->bytecodeBegin = bytecodeIndex;
1237     m_inlineStackTop->m_blockLinkingTargets.append(block);
1238 }
1239
1240 void ByteCodeParser::addJumpTo(BasicBlock* block)
1241 {
1242     ASSERT(!m_currentBlock->terminal());
1243     Node* jumpNode = addToGraph(Jump);
1244     jumpNode->targetBlock() = block;
1245     m_currentBlock->didLink();
1246 }
1247
1248 void ByteCodeParser::addJumpTo(unsigned bytecodeIndex)
1249 {
1250     ASSERT(!m_currentBlock->terminal());
1251     addToGraph(Jump, OpInfo(bytecodeIndex));
1252     m_inlineStackTop->m_unlinkedBlocks.append(m_currentBlock);
1253 }
1254
1255 ByteCodeParser::Terminality ByteCodeParser::handleCall(Instruction* pc, NodeType op, CallMode callMode)
1256 {
1257     static_assert(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct),
1258         "op_call, op_tail_call and op_construct should always have the same length");
1259     static_assert(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_tail_call),
1260         "op_call, op_tail_call and op_construct should always have the same length");
1261     
1262     int result = pc[1].u.operand;
1263     Node* callTarget = get(VirtualRegister(pc[2].u.operand));
1264     int argumentCountIncludingThis = pc[3].u.operand;
1265     int registerOffset = -pc[4].u.operand;
1266
1267     CallLinkStatus callLinkStatus = CallLinkStatus::computeFor(
1268         m_inlineStackTop->m_profiledBlock, currentCodeOrigin(),
1269         m_inlineStackTop->m_callLinkInfos, m_callContextMap);
1270
1271     InlineCallFrame::Kind kind = InlineCallFrame::kindFor(callMode);
1272
1273     return handleCall(result, op, kind, OPCODE_LENGTH(op_call), callTarget,
1274         argumentCountIncludingThis, registerOffset, callLinkStatus, getPrediction());
1275 }
1276
1277 void ByteCodeParser::refineStatically(CallLinkStatus& callLinkStatus, Node* callTarget)
1278 {
1279     if (callTarget->isCellConstant())
1280         callLinkStatus.setProvenConstantCallee(CallVariant(callTarget->asCell()));
1281 }
1282
1283 ByteCodeParser::Terminality ByteCodeParser::handleCall(
1284     int result, NodeType op, InlineCallFrame::Kind kind, unsigned instructionSize,
1285     Node* callTarget, int argumentCountIncludingThis, int registerOffset,
1286     CallLinkStatus callLinkStatus, SpeculatedType prediction)
1287 {
1288     ASSERT(registerOffset <= 0);
1289
1290     refineStatically(callLinkStatus, callTarget);
1291     
1292     VERBOSE_LOG("    Handling call at ", currentCodeOrigin(), ": ", callLinkStatus, "\n");
1293     
1294     // We first check that we have profiling information about this call, and that it did not behave too polymorphically.
1295     if (callLinkStatus.canOptimize()) {
1296         VirtualRegister thisArgument = virtualRegisterForArgument(0, registerOffset);
1297
1298         // Inlining is quite complex, and managed by a pipeline of functions:
1299         // handle(Varargs)Call -> handleInlining -> attemptToInlineCall -> inlineCall
1300         // - handleCall and handleVarargsCall deal with the case where no inlining happens, and do some sanity checks on their arguments
1301         // - handleInlining checks whether the call is polymorphic, and if so is responsible for inserting a switch on the callee
1302         // - attemptToInlineCall deals with special cases such as intrinsics, it also checks the inlining heuristic (through inliningCost)
1303         // - inlineCall finally does the actual inlining, after a complicated procedure to setup the stack correctly
1304         unsigned nextOffset = m_currentIndex + instructionSize;
1305         if (handleInlining(callTarget, result, callLinkStatus, registerOffset, thisArgument, VirtualRegister(), 0, argumentCountIncludingThis, nextOffset, op, kind, prediction)) {
1306             if (UNLIKELY(m_graph.compilation()))
1307                 m_graph.compilation()->noticeInlinedCall();
1308             return NonTerminal;
1309         }
1310     }
1311     
1312     Node* callNode = addCall(result, op, nullptr, callTarget, argumentCountIncludingThis, registerOffset, prediction);
1313     ASSERT(callNode->op() != TailCallVarargs && callNode->op() != TailCallForwardVarargs);
1314     return callNode->op() == TailCall ? Terminal : NonTerminal;
1315 }
1316
1317 ByteCodeParser::Terminality ByteCodeParser::handleVarargsCall(Instruction* pc, NodeType op, CallMode callMode)
1318 {
1319     static_assert(OPCODE_LENGTH(op_call_varargs) == OPCODE_LENGTH(op_construct_varargs),
1320         "op_call_varargs, op_tail_call_varargs and op_construct_varargs should always have the same length");
1321     static_assert(OPCODE_LENGTH(op_call_varargs) == OPCODE_LENGTH(op_tail_call_varargs),
1322         "op_call_varargs, op_tail_call_varargs and op_construct_varargs should always have the same length");
1323
1324     int result = pc[1].u.operand;
1325     int callee = pc[2].u.operand;
1326     int thisReg = pc[3].u.operand;
1327     int arguments = pc[4].u.operand;
1328     int firstFreeReg = pc[5].u.operand;
1329     int firstVarArgOffset = pc[6].u.operand;
1330     
1331     SpeculatedType prediction = getPrediction();
1332     
1333     Node* callTarget = get(VirtualRegister(callee));
1334     
1335     CallLinkStatus callLinkStatus = CallLinkStatus::computeFor(
1336         m_inlineStackTop->m_profiledBlock, currentCodeOrigin(),
1337         m_inlineStackTop->m_callLinkInfos, m_callContextMap);
1338     refineStatically(callLinkStatus, callTarget);
1339     
1340     VERBOSE_LOG("    Varargs call link status at ", currentCodeOrigin(), ": ", callLinkStatus, "\n");
1341     
1342     if (callLinkStatus.canOptimize()
1343         && handleInlining(callTarget, result, callLinkStatus, firstFreeReg, VirtualRegister(thisReg), VirtualRegister(arguments), firstVarArgOffset, 0, m_currentIndex + OPCODE_LENGTH(op_call_varargs), op, InlineCallFrame::varargsKindFor(callMode), prediction)) {
1344         if (UNLIKELY(m_graph.compilation()))
1345             m_graph.compilation()->noticeInlinedCall();
1346         return NonTerminal;
1347     }
1348     
1349     CallVarargsData* data = m_graph.m_callVarargsData.add();
1350     data->firstVarArgOffset = firstVarArgOffset;
1351     
1352     Node* thisChild = get(VirtualRegister(thisReg));
1353     Node* argumentsChild = nullptr;
1354     if (op != TailCallForwardVarargs)
1355         argumentsChild = get(VirtualRegister(arguments));
1356
1357     if (op == TailCallVarargs || op == TailCallForwardVarargs) {
1358         if (allInlineFramesAreTailCalls()) {
1359             addToGraph(op, OpInfo(data), OpInfo(), callTarget, thisChild, argumentsChild);
1360             return Terminal;
1361         }
1362         op = op == TailCallVarargs ? TailCallVarargsInlinedCaller : TailCallForwardVarargsInlinedCaller;
1363     }
1364
1365     Node* call = addToGraph(op, OpInfo(data), OpInfo(prediction), callTarget, thisChild, argumentsChild);
1366     VirtualRegister resultReg(result);
1367     if (resultReg.isValid())
1368         set(resultReg, call);
1369     return NonTerminal;
1370 }
1371
1372 void ByteCodeParser::emitFunctionChecks(CallVariant callee, Node* callTarget, VirtualRegister thisArgumentReg)
1373 {
1374     Node* thisArgument;
1375     if (thisArgumentReg.isValid())
1376         thisArgument = get(thisArgumentReg);
1377     else
1378         thisArgument = nullptr;
1379
1380     JSCell* calleeCell;
1381     Node* callTargetForCheck;
1382     if (callee.isClosureCall()) {
1383         calleeCell = callee.executable();
1384         callTargetForCheck = addToGraph(GetExecutable, callTarget);
1385     } else {
1386         calleeCell = callee.nonExecutableCallee();
1387         callTargetForCheck = callTarget;
1388     }
1389     
1390     ASSERT(calleeCell);
1391     addToGraph(CheckCell, OpInfo(m_graph.freeze(calleeCell)), callTargetForCheck);
1392     if (thisArgument)
1393         addToGraph(Phantom, thisArgument);
1394 }
1395
1396 Node* ByteCodeParser::getArgumentCount()
1397 {
1398     Node* argumentCount;
1399     if (m_inlineStackTop->m_inlineCallFrame) {
1400         if (m_inlineStackTop->m_inlineCallFrame->isVarargs())
1401             argumentCount = get(VirtualRegister(CallFrameSlot::argumentCount));
1402         else
1403             argumentCount = jsConstant(m_graph.freeze(jsNumber(m_inlineStackTop->m_inlineCallFrame->argumentCountIncludingThis))->value());
1404     } else
1405         argumentCount = addToGraph(GetArgumentCountIncludingThis, OpInfo(0), OpInfo(SpecInt32Only));
1406     return argumentCount;
1407 }
1408
1409 void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis)
1410 {
1411     for (int i = 0; i < argumentCountIncludingThis; ++i)
1412         addToGraph(Phantom, get(virtualRegisterForArgument(i, registerOffset)));
1413 }
1414
1415 unsigned ByteCodeParser::inliningCost(CallVariant callee, int argumentCountIncludingThis, InlineCallFrame::Kind kind)
1416 {
1417     CallMode callMode = InlineCallFrame::callModeFor(kind);
1418     CodeSpecializationKind specializationKind = specializationKindFor(callMode);
1419     VERBOSE_LOG("Considering inlining ", callee, " into ", currentCodeOrigin(), "\n");
1420     
1421     if (m_hasDebuggerEnabled) {
1422         VERBOSE_LOG("    Failing because the debugger is in use.\n");
1423         return UINT_MAX;
1424     }
1425
1426     FunctionExecutable* executable = callee.functionExecutable();
1427     if (!executable) {
1428         VERBOSE_LOG("    Failing because there is no function executable.\n");
1429         return UINT_MAX;
1430     }
1431     
1432     // Do we have a code block, and does the code block's size match the heuristics/requirements for
1433     // being an inline candidate? We might not have a code block (1) if code was thrown away,
1434     // (2) if we simply hadn't actually made this call yet or (3) code is a builtin function and
1435     // specialization kind is construct. In the former 2 cases, we could still theoretically attempt
1436     // to inline it if we had a static proof of what was being called; this might happen for example
1437     // if you call a global function, where watchpointing gives us static information. Overall,
1438     // it's a rare case because we expect that any hot callees would have already been compiled.
1439     CodeBlock* codeBlock = executable->baselineCodeBlockFor(specializationKind);
1440     if (!codeBlock) {
1441         VERBOSE_LOG("    Failing because no code block available.\n");
1442         return UINT_MAX;
1443     }
1444
1445     if (!Options::useArityFixupInlining()) {
1446         if (codeBlock->numParameters() > argumentCountIncludingThis) {
1447             VERBOSE_LOG("    Failing because of arity mismatch.\n");
1448             return UINT_MAX;
1449         }
1450     }
1451
1452     CapabilityLevel capabilityLevel = inlineFunctionForCapabilityLevel(
1453         codeBlock, specializationKind, callee.isClosureCall());
1454     VERBOSE_LOG("    Call mode: ", callMode, "\n");
1455     VERBOSE_LOG("    Is closure call: ", callee.isClosureCall(), "\n");
1456     VERBOSE_LOG("    Capability level: ", capabilityLevel, "\n");
1457     VERBOSE_LOG("    Might inline function: ", mightInlineFunctionFor(codeBlock, specializationKind), "\n");
1458     VERBOSE_LOG("    Might compile function: ", mightCompileFunctionFor(codeBlock, specializationKind), "\n");
1459     VERBOSE_LOG("    Is supported for inlining: ", isSupportedForInlining(codeBlock), "\n");
1460     VERBOSE_LOG("    Is inlining candidate: ", codeBlock->ownerScriptExecutable()->isInliningCandidate(), "\n");
1461     if (!canInline(capabilityLevel)) {
1462         VERBOSE_LOG("    Failing because the function is not inlineable.\n");
1463         return UINT_MAX;
1464     }
1465     
1466     // Check if the caller is already too large. We do this check here because that's just
1467     // where we happen to also have the callee's code block, and we want that for the
1468     // purpose of unsetting SABI.
1469     if (!isSmallEnoughToInlineCodeInto(m_codeBlock)) {
1470         codeBlock->m_shouldAlwaysBeInlined = false;
1471         VERBOSE_LOG("    Failing because the caller is too large.\n");
1472         return UINT_MAX;
1473     }
1474     
1475     // FIXME: this should be better at predicting how much bloat we will introduce by inlining
1476     // this function.
1477     // https://bugs.webkit.org/show_bug.cgi?id=127627
1478     
1479     // FIXME: We currently inline functions that have run in LLInt but not in Baseline. These
1480     // functions have very low fidelity profiling, and presumably they weren't very hot if they
1481     // haven't gotten to Baseline yet. Consider not inlining these functions.
1482     // https://bugs.webkit.org/show_bug.cgi?id=145503
1483     
1484     // Have we exceeded inline stack depth, or are we trying to inline a recursive call to
1485     // too many levels? If either of these are detected, then don't inline. We adjust our
1486     // heuristics if we are dealing with a function that cannot otherwise be compiled.
1487     
1488     unsigned depth = 0;
1489     unsigned recursion = 0;
1490     
1491     for (InlineStackEntry* entry = m_inlineStackTop; entry; entry = entry->m_caller) {
1492         ++depth;
1493         if (depth >= Options::maximumInliningDepth()) {
1494             VERBOSE_LOG("    Failing because depth exceeded.\n");
1495             return UINT_MAX;
1496         }
1497         
1498         if (entry->executable() == executable) {
1499             ++recursion;
1500             if (recursion >= Options::maximumInliningRecursion()) {
1501                 VERBOSE_LOG("    Failing because recursion detected.\n");
1502                 return UINT_MAX;
1503             }
1504         }
1505     }
1506     
1507     VERBOSE_LOG("    Inlining should be possible.\n");
1508     
1509     // It might be possible to inline.
1510     return codeBlock->instructionCount();
1511 }
1512
1513 template<typename ChecksFunctor>
1514 void ByteCodeParser::inlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, BasicBlock* continuationBlock, const ChecksFunctor& insertChecks)
1515 {
1516     CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
1517     
1518     ASSERT(inliningCost(callee, argumentCountIncludingThis, kind) != UINT_MAX);
1519     
1520     CodeBlock* codeBlock = callee.functionExecutable()->baselineCodeBlockFor(specializationKind);
1521     insertChecks(codeBlock);
1522
1523     // FIXME: Don't flush constants!
1524
1525     // arityFixupCount and numberOfStackPaddingSlots are different. While arityFixupCount does not consider about stack alignment,
1526     // numberOfStackPaddingSlots consider alignment. Consider the following case,
1527     //
1528     // before: [ ... ][arg0][header]
1529     // after:  [ ... ][ext ][arg1][arg0][header]
1530     //
1531     // In the above case, arityFixupCount is 1. But numberOfStackPaddingSlots is 2 because the stack needs to be aligned.
1532     // We insert extra slots to align stack.
1533     int arityFixupCount = std::max<int>(codeBlock->numParameters() - argumentCountIncludingThis, 0);
1534     int numberOfStackPaddingSlots = CommonSlowPaths::numberOfStackPaddingSlots(codeBlock, argumentCountIncludingThis);
1535     ASSERT(!(numberOfStackPaddingSlots % stackAlignmentRegisters()));
1536     int registerOffsetAfterFixup = registerOffset - numberOfStackPaddingSlots;
1537     
1538     int inlineCallFrameStart = m_inlineStackTop->remapOperand(VirtualRegister(registerOffsetAfterFixup)).offset() + CallFrame::headerSizeInRegisters;
1539     
1540     ensureLocals(
1541         VirtualRegister(inlineCallFrameStart).toLocal() + 1 +
1542         CallFrame::headerSizeInRegisters + codeBlock->m_numCalleeLocals);
1543     
1544     size_t argumentPositionStart = m_graph.m_argumentPositions.size();
1545
1546     VirtualRegister resultReg(resultOperand);
1547     if (resultReg.isValid())
1548         resultReg = m_inlineStackTop->remapOperand(resultReg);
1549
1550     VariableAccessData* calleeVariable = nullptr;
1551     if (callee.isClosureCall()) {
1552         Node* calleeSet = set(
1553             VirtualRegister(registerOffsetAfterFixup + CallFrameSlot::callee), callTargetNode, ImmediateNakedSet);
1554         
1555         calleeVariable = calleeSet->variableAccessData();
1556         calleeVariable->mergeShouldNeverUnbox(true);
1557     }
1558
1559     if (arityFixupCount) {
1560         // Note: we do arity fixup in two phases:
1561         // 1. We get all the values we need and MovHint them to the expected locals.
1562         // 2. We SetLocal them inside the callee's CodeOrigin. This way, if we exit, the callee's
1563         //    frame is already set up. If any SetLocal exits, we have a valid exit state.
1564         //    This is required because if we didn't do this in two phases, we may exit in
1565         //    the middle of arity fixup from the caller's CodeOrigin. This is unsound because if
1566         //    we did the SetLocals in the caller's frame, the memcpy may clobber needed parts
1567         //    of the frame right before exiting. For example, consider if we need to pad two args:
1568         //    [arg3][arg2][arg1][arg0]
1569         //    [fix ][fix ][arg3][arg2][arg1][arg0]
1570         //    We memcpy starting from arg0 in the direction of arg3. If we were to exit at a type check
1571         //    for arg3's SetLocal in the caller's CodeOrigin, we'd exit with a frame like so:
1572         //    [arg3][arg2][arg1][arg2][arg1][arg0]
1573         //    And the caller would then just end up thinking its argument are:
1574         //    [arg3][arg2][arg1][arg2]
1575         //    which is incorrect.
1576
1577         Node* undefined = addToGraph(JSConstant, OpInfo(m_constantUndefined));
1578         // The stack needs to be aligned due to the JS calling convention. Thus, we have a hole if the count of arguments is not aligned.
1579         // We call this hole "extra slot". Consider the following case, the number of arguments is 2. If this argument
1580         // count does not fulfill the stack alignment requirement, we already inserted extra slots.
1581         //
1582         // before: [ ... ][ext ][arg1][arg0][header]
1583         //
1584         // In the above case, one extra slot is inserted. If the code's parameter count is 3, we will fixup arguments.
1585         // At that time, we can simply use this extra slots. So the fixuped stack is the following.
1586         //
1587         // before: [ ... ][ext ][arg1][arg0][header]
1588         // after:  [ ... ][arg2][arg1][arg0][header]
1589         //
1590         // In such cases, we do not need to move frames.
1591         if (registerOffsetAfterFixup != registerOffset) {
1592             for (int index = 0; index < argumentCountIncludingThis; ++index) {
1593                 Node* value = get(virtualRegisterForArgument(index, registerOffset));
1594                 VirtualRegister argumentToSet = m_inlineStackTop->remapOperand(virtualRegisterForArgument(index, registerOffsetAfterFixup));
1595                 addToGraph(MovHint, OpInfo(argumentToSet.offset()), value);
1596                 m_setLocalQueue.append(DelayedSetLocal { currentCodeOrigin(), argumentToSet, value, ImmediateNakedSet });
1597             }
1598         }
1599         for (int index = 0; index < arityFixupCount; ++index) {
1600             VirtualRegister argumentToSet = m_inlineStackTop->remapOperand(virtualRegisterForArgument(argumentCountIncludingThis + index, registerOffsetAfterFixup));
1601             addToGraph(MovHint, OpInfo(argumentToSet.offset()), undefined);
1602             m_setLocalQueue.append(DelayedSetLocal { currentCodeOrigin(), argumentToSet, undefined, ImmediateNakedSet });
1603         }
1604
1605         // At this point, it's OK to OSR exit because we finished setting up
1606         // our callee's frame. We emit an ExitOK below from the callee's CodeOrigin.
1607     }
1608
1609     InlineStackEntry inlineStackEntry(this, codeBlock, codeBlock, callee.function(), resultReg,
1610         (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind, continuationBlock);
1611
1612     // This is where the actual inlining really happens.
1613     unsigned oldIndex = m_currentIndex;
1614     m_currentIndex = 0;
1615
1616     // At this point, it's again OK to OSR exit.
1617     m_exitOK = true;
1618     addToGraph(ExitOK);
1619
1620     processSetLocalQueue();
1621
1622     InlineVariableData inlineVariableData;
1623     inlineVariableData.inlineCallFrame = m_inlineStackTop->m_inlineCallFrame;
1624     inlineVariableData.argumentPositionStart = argumentPositionStart;
1625     inlineVariableData.calleeVariable = 0;
1626     
1627     RELEASE_ASSERT(
1628         m_inlineStackTop->m_inlineCallFrame->isClosureCall
1629         == callee.isClosureCall());
1630     if (callee.isClosureCall()) {
1631         RELEASE_ASSERT(calleeVariable);
1632         inlineVariableData.calleeVariable = calleeVariable;
1633     }
1634     
1635     m_graph.m_inlineVariableData.append(inlineVariableData);
1636
1637     parseCodeBlock();
1638     clearCaches(); // Reset our state now that we're back to the outer code.
1639     
1640     m_currentIndex = oldIndex;
1641     m_exitOK = false;
1642
1643     linkBlocks(inlineStackEntry.m_unlinkedBlocks, inlineStackEntry.m_blockLinkingTargets);
1644     
1645     // If the callee returned at least once, it prepared a continuation block for us.
1646     if (inlineStackEntry.m_continuationBlock)
1647         m_currentBlock = inlineStackEntry.m_continuationBlock;
1648     else {
1649         // We are in the case where the callee never returns (for example it loops forever).
1650         // In that case, all blocks should end in a terminal.
1651         ASSERT(m_graph.lastBlock()->terminal());
1652         // We then allocate a new block to continue in.
1653         m_currentBlock = allocateTargetableBlock(nextOffset);
1654     }
1655     ASSERT(m_currentBlock);
1656     ASSERT(!m_currentBlock->terminal());
1657
1658     prepareToParseBlock();
1659 }
1660
1661 template<typename ChecksFunctor>
1662 bool ByteCodeParser::attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, SpeculatedType prediction, unsigned& inliningBalance, BasicBlock* continuationBlock, const ChecksFunctor& insertChecks)
1663 {
1664     CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
1665     
1666     if (!inliningBalance)
1667         return false;
1668     
1669     VERBOSE_LOG("    Considering callee ", callee, "\n");
1670     
1671     // Intrinsics and internal functions can only be inlined if we're not doing varargs. This is because
1672     // we currently don't have any way of getting profiling information for arguments to non-JS varargs
1673     // calls. The prediction propagator won't be of any help because LoadVarargs obscures the data flow,
1674     // and there are no callsite value profiles and native function won't have callee value profiles for
1675     // those arguments. Even worse, if the intrinsic decides to exit, it won't really have anywhere to
1676     // exit to: LoadVarargs is effectful and it's part of the op_call_varargs, so we can't exit without
1677     // calling LoadVarargs twice.
1678     if (!InlineCallFrame::isVarargs(kind)) {
1679
1680         bool didInsertChecks = false;
1681         auto insertChecksWithAccounting = [&] () {
1682             insertChecks(nullptr);
1683             didInsertChecks = true;
1684         };
1685
1686         auto endSpecialCase = [&] () {
1687             RELEASE_ASSERT(didInsertChecks);
1688             addToGraph(Phantom, callTargetNode);
1689             emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
1690             inliningBalance--;
1691             if (continuationBlock) {
1692                 m_currentIndex = nextOffset;
1693                 m_exitOK = true;
1694                 processSetLocalQueue();
1695                 addJumpTo(continuationBlock);
1696             }
1697         };
1698     
1699         if (InternalFunction* function = callee.internalFunction()) {
1700             if (handleConstantInternalFunction(callTargetNode, resultOperand, function, registerOffset, argumentCountIncludingThis, specializationKind, prediction, insertChecksWithAccounting)) {
1701                 endSpecialCase();
1702                 return true;
1703             }
1704             RELEASE_ASSERT(!didInsertChecks);
1705             return false;
1706         }
1707     
1708         Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
1709         if (intrinsic != NoIntrinsic) {
1710             if (handleIntrinsicCall(callTargetNode, resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
1711                 endSpecialCase();
1712                 return true;
1713             }
1714
1715             RELEASE_ASSERT(!didInsertChecks);
1716             // We might still try to inline the Intrinsic because it might be a builtin JS function.
1717         }
1718
1719         if (Options::useDOMJIT()) {
1720             if (const DOMJIT::Signature* signature = callee.signatureFor(specializationKind)) {
1721                 if (handleDOMJITCall(callTargetNode, resultOperand, signature, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
1722                     endSpecialCase();
1723                     return true;
1724                 }
1725                 RELEASE_ASSERT(!didInsertChecks);
1726             }
1727         }
1728     }
1729     
1730     unsigned myInliningCost = inliningCost(callee, argumentCountIncludingThis, kind);
1731     if (myInliningCost > inliningBalance)
1732         return false;
1733
1734     Instruction* savedCurrentInstruction = m_currentInstruction;
1735     inlineCall(callTargetNode, resultOperand, callee, registerOffset, argumentCountIncludingThis, nextOffset, kind, continuationBlock, insertChecks);
1736     inliningBalance -= myInliningCost;
1737     m_currentInstruction = savedCurrentInstruction;
1738     return true;
1739 }
1740
1741 bool ByteCodeParser::handleInlining(
1742     Node* callTargetNode, int resultOperand, const CallLinkStatus& callLinkStatus,
1743     int registerOffsetOrFirstFreeReg, VirtualRegister thisArgument,
1744     VirtualRegister argumentsArgument, unsigned argumentsOffset, int argumentCountIncludingThis,
1745     unsigned nextOffset, NodeType callOp, InlineCallFrame::Kind kind, SpeculatedType prediction)
1746 {
1747     VERBOSE_LOG("Handling inlining...\nStack: ", currentCodeOrigin(), "\n");
1748     CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
1749     
1750     if (!callLinkStatus.size()) {
1751         VERBOSE_LOG("Bailing inlining.\n");
1752         return false;
1753     }
1754     
1755     if (InlineCallFrame::isVarargs(kind)
1756         && callLinkStatus.maxNumArguments() > Options::maximumVarargsForInlining()) {
1757         VERBOSE_LOG("Bailing inlining because of varargs.\n");
1758         return false;
1759     }
1760         
1761     unsigned inliningBalance = Options::maximumFunctionForCallInlineCandidateInstructionCount();
1762     if (specializationKind == CodeForConstruct)
1763         inliningBalance = std::min(inliningBalance, Options::maximumFunctionForConstructInlineCandidateInstructionCount());
1764     if (callLinkStatus.isClosureCall())
1765         inliningBalance = std::min(inliningBalance, Options::maximumFunctionForClosureCallInlineCandidateInstructionCount());
1766     
1767     // First check if we can avoid creating control flow. Our inliner does some CFG
1768     // simplification on the fly and this helps reduce compile times, but we can only leverage
1769     // this in cases where we don't need control flow diamonds to check the callee.
1770     if (!callLinkStatus.couldTakeSlowPath() && callLinkStatus.size() == 1) {
1771         int registerOffset;
1772         
1773         // Only used for varargs calls.
1774         unsigned mandatoryMinimum = 0;
1775         unsigned maxNumArguments = 0;
1776
1777         if (InlineCallFrame::isVarargs(kind)) {
1778             if (FunctionExecutable* functionExecutable = callLinkStatus[0].functionExecutable())
1779                 mandatoryMinimum = functionExecutable->parameterCount();
1780             else
1781                 mandatoryMinimum = 0;
1782             
1783             // includes "this"
1784             maxNumArguments = std::max(
1785                 callLinkStatus.maxNumArguments(),
1786                 mandatoryMinimum + 1);
1787             
1788             // We sort of pretend that this *is* the number of arguments that were passed.
1789             argumentCountIncludingThis = maxNumArguments;
1790             
1791             registerOffset = registerOffsetOrFirstFreeReg + 1;
1792             registerOffset -= maxNumArguments; // includes "this"
1793             registerOffset -= CallFrame::headerSizeInRegisters;
1794             registerOffset = -WTF::roundUpToMultipleOf(
1795                 stackAlignmentRegisters(),
1796                 -registerOffset);
1797         } else
1798             registerOffset = registerOffsetOrFirstFreeReg;
1799         
1800         bool result = attemptToInlineCall(
1801             callTargetNode, resultOperand, callLinkStatus[0], registerOffset,
1802             argumentCountIncludingThis, nextOffset, kind, prediction,
1803             inliningBalance, nullptr, [&] (CodeBlock* codeBlock) {
1804                 emitFunctionChecks(callLinkStatus[0], callTargetNode, thisArgument);
1805
1806                 // If we have a varargs call, we want to extract the arguments right now.
1807                 if (InlineCallFrame::isVarargs(kind)) {
1808                     int remappedRegisterOffset =
1809                         m_inlineStackTop->remapOperand(VirtualRegister(registerOffset)).offset();
1810                     
1811                     ensureLocals(VirtualRegister(remappedRegisterOffset).toLocal());
1812                     
1813                     int argumentStart = registerOffset + CallFrame::headerSizeInRegisters;
1814                     int remappedArgumentStart =
1815                         m_inlineStackTop->remapOperand(VirtualRegister(argumentStart)).offset();
1816
1817                     LoadVarargsData* data = m_graph.m_loadVarargsData.add();
1818                     data->start = VirtualRegister(remappedArgumentStart + 1);
1819                     data->count = VirtualRegister(remappedRegisterOffset + CallFrameSlot::argumentCount);
1820                     data->offset = argumentsOffset;
1821                     data->limit = maxNumArguments;
1822                     data->mandatoryMinimum = mandatoryMinimum;
1823
1824                     if (callOp == TailCallForwardVarargs)
1825                         addToGraph(ForwardVarargs, OpInfo(data));
1826                     else
1827                         addToGraph(LoadVarargs, OpInfo(data), get(argumentsArgument));
1828
1829                     // LoadVarargs may OSR exit. Hence, we need to keep alive callTargetNode, thisArgument
1830                     // and argumentsArgument for the baseline JIT. However, we only need a Phantom for
1831                     // callTargetNode because the other 2 are still in use and alive at this point.
1832                     addToGraph(Phantom, callTargetNode);
1833
1834                     // In DFG IR before SSA, we cannot insert control flow between after the
1835                     // LoadVarargs and the last SetArgument. This isn't a problem once we get to DFG
1836                     // SSA. Fortunately, we also have other reasons for not inserting control flow
1837                     // before SSA.
1838             
1839                     VariableAccessData* countVariable = newVariableAccessData(
1840                         VirtualRegister(remappedRegisterOffset + CallFrameSlot::argumentCount));
1841                     // This is pretty lame, but it will force the count to be flushed as an int. This doesn't
1842                     // matter very much, since our use of a SetArgument and Flushes for this local slot is
1843                     // mostly just a formality.
1844                     countVariable->predict(SpecInt32Only);
1845                     countVariable->mergeIsProfitableToUnbox(true);
1846                     Node* setArgumentCount = addToGraph(SetArgument, OpInfo(countVariable));
1847                     m_currentBlock->variablesAtTail.setOperand(countVariable->local(), setArgumentCount);
1848
1849                     set(VirtualRegister(argumentStart), get(thisArgument), ImmediateNakedSet);
1850                     for (unsigned argument = 1; argument < maxNumArguments; ++argument) {
1851                         VariableAccessData* variable = newVariableAccessData(
1852                             VirtualRegister(remappedArgumentStart + argument));
1853                         variable->mergeShouldNeverUnbox(true); // We currently have nowhere to put the type check on the LoadVarargs. LoadVarargs is effectful, so after it finishes, we cannot exit.
1854                         
1855                         // For a while it had been my intention to do things like this inside the
1856                         // prediction injection phase. But in this case it's really best to do it here,
1857                         // because it's here that we have access to the variable access datas for the
1858                         // inlining we're about to do.
1859                         //
1860                         // Something else that's interesting here is that we'd really love to get
1861                         // predictions from the arguments loaded at the callsite, rather than the
1862                         // arguments received inside the callee. But that probably won't matter for most
1863                         // calls.
1864                         if (codeBlock && argument < static_cast<unsigned>(codeBlock->numParameters())) {
1865                             ConcurrentJSLocker locker(codeBlock->m_lock);
1866                             ValueProfile& profile = codeBlock->valueProfileForArgument(argument);
1867                             variable->predict(profile.computeUpdatedPrediction(locker));
1868                         }
1869                         
1870                         Node* setArgument = addToGraph(SetArgument, OpInfo(variable));
1871                         m_currentBlock->variablesAtTail.setOperand(variable->local(), setArgument);
1872                     }
1873                 }
1874             });
1875         VERBOSE_LOG("Done inlining (simple).\nStack: ", currentCodeOrigin(), "\nResult: ", result, "\n");
1876         return result;
1877     }
1878     
1879     // We need to create some kind of switch over callee. For now we only do this if we believe that
1880     // we're in the top tier. We have two reasons for this: first, it provides us an opportunity to
1881     // do more detailed polyvariant/polymorphic profiling; and second, it reduces compile times in
1882     // the DFG. And by polyvariant profiling we mean polyvariant profiling of *this* call. Note that
1883     // we could improve that aspect of this by doing polymorphic inlining but having the profiling
1884     // also.
1885     if (!isFTL(m_graph.m_plan.mode) || !Options::usePolymorphicCallInlining()
1886         || InlineCallFrame::isVarargs(kind)) {
1887         VERBOSE_LOG("Bailing inlining (hard).\nStack: ", currentCodeOrigin(), "\n");
1888         return false;
1889     }
1890     
1891     // If the claim is that this did not originate from a stub, then we don't want to emit a switch
1892     // statement. Whenever the non-stub profiling says that it could take slow path, it really means that
1893     // it has no idea.
1894     if (!Options::usePolymorphicCallInliningForNonStubStatus()
1895         && !callLinkStatus.isBasedOnStub()) {
1896         VERBOSE_LOG("Bailing inlining (non-stub polymorphism).\nStack: ", currentCodeOrigin(), "\n");
1897         return false;
1898     }
1899
1900     bool allAreClosureCalls = true;
1901     bool allAreDirectCalls = true;
1902     for (unsigned i = callLinkStatus.size(); i--;) {
1903         if (callLinkStatus[i].isClosureCall())
1904             allAreDirectCalls = false;
1905         else
1906             allAreClosureCalls = false;
1907     }
1908
1909     Node* thingToSwitchOn;
1910     if (allAreDirectCalls)
1911         thingToSwitchOn = callTargetNode;
1912     else if (allAreClosureCalls)
1913         thingToSwitchOn = addToGraph(GetExecutable, callTargetNode);
1914     else {
1915         // FIXME: We should be able to handle this case, but it's tricky and we don't know of cases
1916         // where it would be beneficial. It might be best to handle these cases as if all calls were
1917         // closure calls.
1918         // https://bugs.webkit.org/show_bug.cgi?id=136020
1919         VERBOSE_LOG("Bailing inlining (mix).\nStack: ", currentCodeOrigin(), "\n");
1920         return false;
1921     }
1922
1923     VERBOSE_LOG("Doing hard inlining...\nStack: ", currentCodeOrigin(), "\n");
1924
1925     int registerOffset = registerOffsetOrFirstFreeReg;
1926
1927     // This makes me wish that we were in SSA all the time. We need to pick a variable into which to
1928     // store the callee so that it will be accessible to all of the blocks we're about to create. We
1929     // get away with doing an immediate-set here because we wouldn't have performed any side effects
1930     // yet.
1931     VERBOSE_LOG("Register offset: ", registerOffset);
1932     VirtualRegister calleeReg(registerOffset + CallFrameSlot::callee);
1933     calleeReg = m_inlineStackTop->remapOperand(calleeReg);
1934     VERBOSE_LOG("Callee is going to be ", calleeReg, "\n");
1935     setDirect(calleeReg, callTargetNode, ImmediateSetWithFlush);
1936
1937     // It's OK to exit right now, even though we set some locals. That's because those locals are not
1938     // user-visible.
1939     m_exitOK = true;
1940     addToGraph(ExitOK);
1941     
1942     SwitchData& data = *m_graph.m_switchData.add();
1943     data.kind = SwitchCell;
1944     addToGraph(Switch, OpInfo(&data), thingToSwitchOn);
1945     m_currentBlock->didLink();
1946     
1947     BasicBlock* continuationBlock = allocateUntargetableBlock();
1948     VERBOSE_LOG("Adding untargetable block ", RawPointer(continuationBlock), " (continuation)\n");
1949     
1950     // We may force this true if we give up on inlining any of the edges.
1951     bool couldTakeSlowPath = callLinkStatus.couldTakeSlowPath();
1952     
1953     VERBOSE_LOG("About to loop over functions at ", currentCodeOrigin(), ".\n");
1954
1955     unsigned oldOffset = m_currentIndex;
1956     for (unsigned i = 0; i < callLinkStatus.size(); ++i) {
1957         m_currentIndex = oldOffset;
1958         BasicBlock* calleeEntryBlock = allocateUntargetableBlock();
1959         m_currentBlock = calleeEntryBlock;
1960         prepareToParseBlock();
1961         
1962         Node* myCallTargetNode = getDirect(calleeReg);
1963         
1964         bool inliningResult = attemptToInlineCall(
1965             myCallTargetNode, resultOperand, callLinkStatus[i], registerOffset,
1966             argumentCountIncludingThis, nextOffset, kind, prediction,
1967             inliningBalance, continuationBlock, [&] (CodeBlock*) { });
1968         
1969         if (!inliningResult) {
1970             // That failed so we let the block die. Nothing interesting should have been added to
1971             // the block. We also give up on inlining any of the (less frequent) callees.
1972             ASSERT(m_graph.m_blocks.last() == m_currentBlock);
1973             m_graph.killBlockAndItsContents(m_currentBlock);
1974             m_graph.m_blocks.removeLast();
1975             VERBOSE_LOG("Inlining of a poly call failed, we will have to go through a slow path\n");
1976
1977             // The fact that inlining failed means we need a slow path.
1978             couldTakeSlowPath = true;
1979             break;
1980         }
1981         
1982         JSCell* thingToCaseOn;
1983         if (allAreDirectCalls)
1984             thingToCaseOn = callLinkStatus[i].nonExecutableCallee();
1985         else {
1986             ASSERT(allAreClosureCalls);
1987             thingToCaseOn = callLinkStatus[i].executable();
1988         }
1989         data.cases.append(SwitchCase(m_graph.freeze(thingToCaseOn), calleeEntryBlock));
1990         VERBOSE_LOG("Finished inlining ", callLinkStatus[i], " at ", currentCodeOrigin(), ".\n");
1991     }
1992
1993     // Slow path block
1994     m_currentBlock = allocateUntargetableBlock();
1995     m_currentIndex = oldOffset;
1996     m_exitOK = true;
1997     data.fallThrough = BranchTarget(m_currentBlock);
1998     prepareToParseBlock();
1999     Node* myCallTargetNode = getDirect(calleeReg);
2000     if (couldTakeSlowPath) {
2001         addCall(
2002             resultOperand, callOp, nullptr, myCallTargetNode, argumentCountIncludingThis,
2003             registerOffset, prediction);
2004         VERBOSE_LOG("We added a call in the slow path\n");
2005     } else {
2006         addToGraph(CheckBadCell);
2007         addToGraph(Phantom, myCallTargetNode);
2008         emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
2009         
2010         set(VirtualRegister(resultOperand), addToGraph(BottomValue));
2011         VERBOSE_LOG("couldTakeSlowPath was false\n");
2012     }
2013
2014     m_currentIndex = nextOffset;
2015     m_exitOK = true; // Origin changed, so it's fine to exit again.
2016     processSetLocalQueue();
2017
2018     if (Node* terminal = m_currentBlock->terminal())
2019         ASSERT_UNUSED(terminal, terminal->op() == TailCall || terminal->op() == TailCallVarargs || terminal->op() == TailCallForwardVarargs);
2020     else {
2021         addJumpTo(continuationBlock);
2022     }
2023
2024     prepareToParseBlock();
2025     
2026     m_currentIndex = oldOffset;
2027     m_currentBlock = continuationBlock;
2028     m_exitOK = true;
2029     
2030     VERBOSE_LOG("Done inlining (hard).\nStack: ", currentCodeOrigin(), "\n");
2031     return true;
2032 }
2033
2034 template<typename ChecksFunctor>
2035 bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis, const ChecksFunctor& insertChecks)
2036 {
2037     ASSERT(op == ArithMin || op == ArithMax);
2038
2039     if (argumentCountIncludingThis == 1) {
2040         insertChecks();
2041         double result = op == ArithMax ? -std::numeric_limits<double>::infinity() : +std::numeric_limits<double>::infinity();
2042         set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_graph.freeze(jsDoubleNumber(result)))));
2043         return true;
2044     }
2045      
2046     if (argumentCountIncludingThis == 2) {
2047         insertChecks();
2048         Node* result = get(VirtualRegister(virtualRegisterForArgument(1, registerOffset)));
2049         addToGraph(Phantom, Edge(result, NumberUse));
2050         set(VirtualRegister(resultOperand), result);
2051         return true;
2052     }
2053     
2054     if (argumentCountIncludingThis == 3) {
2055         insertChecks();
2056         set(VirtualRegister(resultOperand), addToGraph(op, get(virtualRegisterForArgument(1, registerOffset)), get(virtualRegisterForArgument(2, registerOffset))));
2057         return true;
2058     }
2059     
2060     // Don't handle >=3 arguments for now.
2061     return false;
2062 }
2063
2064 template<typename ChecksFunctor>
2065 bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks)
2066 {
2067     VERBOSE_LOG("       The intrinsic is ", intrinsic, "\n");
2068     
2069     // It so happens that the code below doesn't handle the invalid result case. We could fix that, but
2070     // it would only benefit intrinsics called as setters, like if you do:
2071     //
2072     //     o.__defineSetter__("foo", Math.pow)
2073     //
2074     // Which is extremely amusing, but probably not worth optimizing.
2075     if (!VirtualRegister(resultOperand).isValid())
2076         return false;
2077     
2078     switch (intrinsic) {
2079
2080     // Intrinsic Functions:
2081
2082     case AbsIntrinsic: {
2083         if (argumentCountIncludingThis == 1) { // Math.abs()
2084             insertChecks();
2085             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
2086             return true;
2087         }
2088
2089         if (!MacroAssembler::supportsFloatingPointAbs())
2090             return false;
2091
2092         insertChecks();
2093         Node* node = addToGraph(ArithAbs, get(virtualRegisterForArgument(1, registerOffset)));
2094         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
2095             node->mergeFlags(NodeMayOverflowInt32InDFG);
2096         set(VirtualRegister(resultOperand), node);
2097         return true;
2098     }
2099
2100     case MinIntrinsic:
2101         return handleMinMax(resultOperand, ArithMin, registerOffset, argumentCountIncludingThis, insertChecks);
2102         
2103     case MaxIntrinsic:
2104         return handleMinMax(resultOperand, ArithMax, registerOffset, argumentCountIncludingThis, insertChecks);
2105
2106 #define DFG_ARITH_UNARY(capitalizedName, lowerName) \
2107     case capitalizedName##Intrinsic:
2108     FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
2109 #undef DFG_ARITH_UNARY
2110     {
2111         if (argumentCountIncludingThis == 1) {
2112             insertChecks();
2113             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
2114             return true;
2115         }
2116         Arith::UnaryType type = Arith::UnaryType::Sin;
2117         switch (intrinsic) {
2118 #define DFG_ARITH_UNARY(capitalizedName, lowerName) \
2119         case capitalizedName##Intrinsic: \
2120             type = Arith::UnaryType::capitalizedName; \
2121             break;
2122     FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
2123 #undef DFG_ARITH_UNARY
2124         default:
2125             RELEASE_ASSERT_NOT_REACHED();
2126         }
2127         insertChecks();
2128         set(VirtualRegister(resultOperand), addToGraph(ArithUnary, OpInfo(static_cast<std::underlying_type<Arith::UnaryType>::type>(type)), get(virtualRegisterForArgument(1, registerOffset))));
2129         return true;
2130     }
2131
2132     case FRoundIntrinsic:
2133     case SqrtIntrinsic: {
2134         if (argumentCountIncludingThis == 1) {
2135             insertChecks();
2136             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
2137             return true;
2138         }
2139
2140         NodeType nodeType = Unreachable;
2141         switch (intrinsic) {
2142         case FRoundIntrinsic:
2143             nodeType = ArithFRound;
2144             break;
2145         case SqrtIntrinsic:
2146             nodeType = ArithSqrt;
2147             break;
2148         default:
2149             RELEASE_ASSERT_NOT_REACHED();
2150         }
2151         insertChecks();
2152         set(VirtualRegister(resultOperand), addToGraph(nodeType, get(virtualRegisterForArgument(1, registerOffset))));
2153         return true;
2154     }
2155
2156     case PowIntrinsic: {
2157         if (argumentCountIncludingThis < 3) {
2158             // Math.pow() and Math.pow(x) return NaN.
2159             insertChecks();
2160             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
2161             return true;
2162         }
2163         insertChecks();
2164         VirtualRegister xOperand = virtualRegisterForArgument(1, registerOffset);
2165         VirtualRegister yOperand = virtualRegisterForArgument(2, registerOffset);
2166         set(VirtualRegister(resultOperand), addToGraph(ArithPow, get(xOperand), get(yOperand)));
2167         return true;
2168     }
2169         
2170     case ArrayPushIntrinsic: {
2171 #if USE(JSVALUE32_64)
2172         if (isX86() || isMIPS()) {
2173             if (argumentCountIncludingThis > 2)
2174                 return false;
2175         }
2176 #endif
2177
2178         if (static_cast<unsigned>(argumentCountIncludingThis) >= MIN_SPARSE_ARRAY_INDEX)
2179             return false;
2180         
2181         ArrayMode arrayMode = getArrayMode(m_currentInstruction[OPCODE_LENGTH(op_call) - 2].u.arrayProfile);
2182         if (!arrayMode.isJSArray())
2183             return false;
2184         switch (arrayMode.type()) {
2185         case Array::Int32:
2186         case Array::Double:
2187         case Array::Contiguous:
2188         case Array::ArrayStorage: {
2189             insertChecks();
2190
2191             addVarArgChild(nullptr); // For storage.
2192             for (int i = 0; i < argumentCountIncludingThis; ++i)
2193                 addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
2194             Node* arrayPush = addToGraph(Node::VarArg, ArrayPush, OpInfo(arrayMode.asWord()), OpInfo(prediction));
2195             set(VirtualRegister(resultOperand), arrayPush);
2196             
2197             return true;
2198         }
2199             
2200         default:
2201             return false;
2202         }
2203     }
2204
2205     case ArraySliceIntrinsic: {
2206 #if USE(JSVALUE32_64)
2207         if (isX86() || isMIPS()) {
2208             // There aren't enough registers for this to be done easily.
2209             return false;
2210         }
2211 #endif
2212         if (argumentCountIncludingThis < 2)
2213             return false;
2214
2215         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantCache)
2216             || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache))
2217             return false;
2218
2219         ArrayMode arrayMode = getArrayMode(m_currentInstruction[OPCODE_LENGTH(op_call) - 2].u.arrayProfile);
2220         if (!arrayMode.isJSArray())
2221             return false;
2222
2223         if (arrayMode.arrayClass() != Array::OriginalArray)
2224             return false;
2225
2226         switch (arrayMode.type()) {
2227         case Array::Double:
2228         case Array::Int32:
2229         case Array::Contiguous: {
2230             JSGlobalObject* globalObject = m_graph.globalObjectFor(currentNodeOrigin().semantic);
2231
2232             InlineWatchpointSet& objectPrototypeTransition = globalObject->objectPrototype()->structure()->transitionWatchpointSet();
2233             InlineWatchpointSet& arrayPrototypeTransition = globalObject->arrayPrototype()->structure()->transitionWatchpointSet();
2234
2235             // FIXME: We could easily relax the Array/Object.prototype transition as long as we OSR exitted if we saw a hole.
2236             // https://bugs.webkit.org/show_bug.cgi?id=173171
2237             if (globalObject->arraySpeciesWatchpoint().state() == IsWatched
2238                 && globalObject->havingABadTimeWatchpoint()->isStillValid()
2239                 && arrayPrototypeTransition.isStillValid()
2240                 && objectPrototypeTransition.isStillValid()
2241                 && globalObject->arrayPrototypeChainIsSane()) {
2242
2243                 m_graph.watchpoints().addLazily(globalObject->arraySpeciesWatchpoint());
2244                 m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
2245                 m_graph.watchpoints().addLazily(arrayPrototypeTransition);
2246                 m_graph.watchpoints().addLazily(objectPrototypeTransition);
2247
2248                 insertChecks();
2249
2250                 Node* array = get(virtualRegisterForArgument(0, registerOffset));
2251                 // We do a few things here to prove that we aren't skipping doing side-effects in an observable way:
2252                 // 1. We ensure that the "constructor" property hasn't been changed (because the observable
2253                 // effects of slice require that we perform a Get(array, "constructor") and we can skip
2254                 // that if we're an original array structure. (We can relax this in the future by using
2255                 // TryGetById and CheckCell).
2256                 //
2257                 // 2. We check that the array we're calling slice on has the same global object as the lexical
2258                 // global object that this code is running in. This requirement is necessary because we setup the
2259                 // watchpoints above on the lexical global object. This means that code that calls slice on
2260                 // arrays produced by other global objects won't get this optimization. We could relax this
2261                 // requirement in the future by checking that the watchpoint hasn't fired at runtime in the code
2262                 // we generate instead of registering it as a watchpoint that would invalidate the compilation.
2263                 //
2264                 // 3. By proving we're an original array structure, we guarantee that the incoming array
2265                 // isn't a subclass of Array.
2266
2267                 StructureSet structureSet;
2268                 structureSet.add(globalObject->originalArrayStructureForIndexingType(ArrayWithInt32));
2269                 structureSet.add(globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous));
2270                 structureSet.add(globalObject->originalArrayStructureForIndexingType(ArrayWithDouble));
2271                 addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structureSet)), array);
2272
2273                 addVarArgChild(array);
2274                 addVarArgChild(get(virtualRegisterForArgument(1, registerOffset))); // Start index.
2275                 if (argumentCountIncludingThis >= 3)
2276                     addVarArgChild(get(virtualRegisterForArgument(2, registerOffset))); // End index.
2277                 addVarArgChild(addToGraph(GetButterfly, array));
2278
2279                 Node* arraySlice = addToGraph(Node::VarArg, ArraySlice, OpInfo(), OpInfo());
2280                 set(VirtualRegister(resultOperand), arraySlice);
2281                 return true;
2282             }
2283
2284             return false;
2285         }
2286         default:
2287             return false;
2288         }
2289
2290         RELEASE_ASSERT_NOT_REACHED();
2291         return false;
2292     }
2293
2294     case ArrayIndexOfIntrinsic: {
2295         if (argumentCountIncludingThis < 2)
2296             return false;
2297
2298         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType)
2299             || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantCache)
2300             || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
2301             || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
2302             return false;
2303
2304         ArrayMode arrayMode = getArrayMode(m_currentInstruction[OPCODE_LENGTH(op_call) - 2].u.arrayProfile);
2305         if (!arrayMode.isJSArray())
2306             return false;
2307
2308         if (arrayMode.arrayClass() != Array::OriginalArray)
2309             return false;
2310
2311         // We do not want to convert arrays into one type just to perform indexOf.
2312         if (arrayMode.doesConversion())
2313             return false;
2314
2315         switch (arrayMode.type()) {
2316         case Array::Double:
2317         case Array::Int32:
2318         case Array::Contiguous: {
2319             JSGlobalObject* globalObject = m_graph.globalObjectFor(currentNodeOrigin().semantic);
2320
2321             InlineWatchpointSet& objectPrototypeTransition = globalObject->objectPrototype()->structure()->transitionWatchpointSet();
2322             InlineWatchpointSet& arrayPrototypeTransition = globalObject->arrayPrototype()->structure()->transitionWatchpointSet();
2323
2324             // FIXME: We could easily relax the Array/Object.prototype transition as long as we OSR exitted if we saw a hole.
2325             // https://bugs.webkit.org/show_bug.cgi?id=173171
2326             if (globalObject->havingABadTimeWatchpoint()->isStillValid()
2327                 && arrayPrototypeTransition.isStillValid()
2328                 && objectPrototypeTransition.isStillValid()
2329                 && globalObject->arrayPrototypeChainIsSane()) {
2330
2331                 m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
2332                 m_graph.watchpoints().addLazily(arrayPrototypeTransition);
2333                 m_graph.watchpoints().addLazily(objectPrototypeTransition);
2334
2335                 insertChecks();
2336
2337                 Node* array = get(virtualRegisterForArgument(0, registerOffset));
2338                 addVarArgChild(array);
2339                 addVarArgChild(get(virtualRegisterForArgument(1, registerOffset))); // Search element.
2340                 if (argumentCountIncludingThis >= 3)
2341                     addVarArgChild(get(virtualRegisterForArgument(2, registerOffset))); // Start index.
2342                 addVarArgChild(nullptr);
2343
2344                 Node* node = addToGraph(Node::VarArg, ArrayIndexOf, OpInfo(arrayMode.asWord()), OpInfo());
2345                 set(VirtualRegister(resultOperand), node);
2346                 return true;
2347             }
2348
2349             return false;
2350         }
2351         default:
2352             return false;
2353         }
2354
2355         RELEASE_ASSERT_NOT_REACHED();
2356         return false;
2357
2358     }
2359         
2360     case ArrayPopIntrinsic: {
2361         if (argumentCountIncludingThis != 1)
2362             return false;
2363         
2364         ArrayMode arrayMode = getArrayMode(m_currentInstruction[OPCODE_LENGTH(op_call) - 2].u.arrayProfile);
2365         if (!arrayMode.isJSArray())
2366             return false;
2367         switch (arrayMode.type()) {
2368         case Array::Int32:
2369         case Array::Double:
2370         case Array::Contiguous:
2371         case Array::ArrayStorage: {
2372             insertChecks();
2373             Node* arrayPop = addToGraph(ArrayPop, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)));
2374             set(VirtualRegister(resultOperand), arrayPop);
2375             return true;
2376         }
2377             
2378         default:
2379             return false;
2380         }
2381     }
2382         
2383     case AtomicsAddIntrinsic:
2384     case AtomicsAndIntrinsic:
2385     case AtomicsCompareExchangeIntrinsic:
2386     case AtomicsExchangeIntrinsic:
2387     case AtomicsIsLockFreeIntrinsic:
2388     case AtomicsLoadIntrinsic:
2389     case AtomicsOrIntrinsic:
2390     case AtomicsStoreIntrinsic:
2391     case AtomicsSubIntrinsic:
2392     case AtomicsXorIntrinsic: {
2393         if (!is64Bit())
2394             return false;
2395         
2396         NodeType op = LastNodeType;
2397         unsigned numArgs = 0; // Number of actual args; we add one for the backing store pointer.
2398         switch (intrinsic) {
2399         case AtomicsAddIntrinsic:
2400             op = AtomicsAdd;
2401             numArgs = 3;
2402             break;
2403         case AtomicsAndIntrinsic:
2404             op = AtomicsAnd;
2405             numArgs = 3;
2406             break;
2407         case AtomicsCompareExchangeIntrinsic:
2408             op = AtomicsCompareExchange;
2409             numArgs = 4;
2410             break;
2411         case AtomicsExchangeIntrinsic:
2412             op = AtomicsExchange;
2413             numArgs = 3;
2414             break;
2415         case AtomicsIsLockFreeIntrinsic:
2416             // This gets no backing store, but we need no special logic for this since this also does
2417             // not need varargs.
2418             op = AtomicsIsLockFree;
2419             numArgs = 1;
2420             break;
2421         case AtomicsLoadIntrinsic:
2422             op = AtomicsLoad;
2423             numArgs = 2;
2424             break;
2425         case AtomicsOrIntrinsic:
2426             op = AtomicsOr;
2427             numArgs = 3;
2428             break;
2429         case AtomicsStoreIntrinsic:
2430             op = AtomicsStore;
2431             numArgs = 3;
2432             break;
2433         case AtomicsSubIntrinsic:
2434             op = AtomicsSub;
2435             numArgs = 3;
2436             break;
2437         case AtomicsXorIntrinsic:
2438             op = AtomicsXor;
2439             numArgs = 3;
2440             break;
2441         default:
2442             RELEASE_ASSERT_NOT_REACHED();
2443             break;
2444         }
2445         
2446         if (static_cast<unsigned>(argumentCountIncludingThis) < 1 + numArgs)
2447             return false;
2448         
2449         insertChecks();
2450         
2451         Vector<Node*, 3> args;
2452         for (unsigned i = 0; i < numArgs; ++i)
2453             args.append(get(virtualRegisterForArgument(1 + i, registerOffset)));
2454         
2455         Node* result;
2456         if (numArgs + 1 <= 3) {
2457             while (args.size() < 3)
2458                 args.append(nullptr);
2459             result = addToGraph(op, OpInfo(ArrayMode(Array::SelectUsingPredictions).asWord()), OpInfo(prediction), args[0], args[1], args[2]);
2460         } else {
2461             for (Node* node : args)
2462                 addVarArgChild(node);
2463             addVarArgChild(nullptr);
2464             result = addToGraph(Node::VarArg, op, OpInfo(ArrayMode(Array::SelectUsingPredictions).asWord()), OpInfo(prediction));
2465         }
2466         
2467         set(VirtualRegister(resultOperand), result);
2468         return true;
2469     }
2470
2471     case ParseIntIntrinsic: {
2472         if (argumentCountIncludingThis < 2)
2473             return false;
2474
2475         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell) || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
2476             return false;
2477
2478         insertChecks();
2479         VirtualRegister valueOperand = virtualRegisterForArgument(1, registerOffset);
2480         Node* parseInt;
2481         if (argumentCountIncludingThis == 2)
2482             parseInt = addToGraph(ParseInt, OpInfo(), OpInfo(prediction), get(valueOperand));
2483         else {
2484             ASSERT(argumentCountIncludingThis > 2);
2485             VirtualRegister radixOperand = virtualRegisterForArgument(2, registerOffset);
2486             parseInt = addToGraph(ParseInt, OpInfo(), OpInfo(prediction), get(valueOperand), get(radixOperand));
2487         }
2488         set(VirtualRegister(resultOperand), parseInt);
2489         return true;
2490     }
2491
2492     case CharCodeAtIntrinsic: {
2493         if (argumentCountIncludingThis != 2)
2494             return false;
2495
2496         insertChecks();
2497         VirtualRegister thisOperand = virtualRegisterForArgument(0, registerOffset);
2498         VirtualRegister indexOperand = virtualRegisterForArgument(1, registerOffset);
2499         Node* charCode = addToGraph(StringCharCodeAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), get(indexOperand));
2500
2501         set(VirtualRegister(resultOperand), charCode);
2502         return true;
2503     }
2504
2505     case CharAtIntrinsic: {
2506         if (argumentCountIncludingThis != 2)
2507             return false;
2508
2509         insertChecks();
2510         VirtualRegister thisOperand = virtualRegisterForArgument(0, registerOffset);
2511         VirtualRegister indexOperand = virtualRegisterForArgument(1, registerOffset);
2512         Node* charCode = addToGraph(StringCharAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), get(indexOperand));
2513
2514         set(VirtualRegister(resultOperand), charCode);
2515         return true;
2516     }
2517     case Clz32Intrinsic: {
2518         insertChecks();
2519         if (argumentCountIncludingThis == 1)
2520             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_graph.freeze(jsNumber(32)))));
2521         else {
2522             Node* operand = get(virtualRegisterForArgument(1, registerOffset));
2523             set(VirtualRegister(resultOperand), addToGraph(ArithClz32, operand));
2524         }
2525         return true;
2526     }
2527     case FromCharCodeIntrinsic: {
2528         if (argumentCountIncludingThis != 2)
2529             return false;
2530
2531         insertChecks();
2532         VirtualRegister indexOperand = virtualRegisterForArgument(1, registerOffset);
2533         Node* charCode = addToGraph(StringFromCharCode, get(indexOperand));
2534
2535         set(VirtualRegister(resultOperand), charCode);
2536
2537         return true;
2538     }
2539
2540     case RegExpExecIntrinsic: {
2541         if (argumentCountIncludingThis != 2)
2542             return false;
2543         
2544         insertChecks();
2545         Node* regExpExec = addToGraph(RegExpExec, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
2546         set(VirtualRegister(resultOperand), regExpExec);
2547         
2548         return true;
2549     }
2550         
2551     case RegExpTestIntrinsic:
2552     case RegExpTestFastIntrinsic: {
2553         if (argumentCountIncludingThis != 2)
2554             return false;
2555
2556         if (intrinsic == RegExpTestIntrinsic) {
2557             // Don't inline intrinsic if we exited due to one of the primordial RegExp checks failing.
2558             if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell))
2559                 return false;
2560
2561             JSGlobalObject* globalObject = m_inlineStackTop->m_codeBlock->globalObject();
2562             Structure* regExpStructure = globalObject->regExpStructure();
2563             m_graph.registerStructure(regExpStructure);
2564             ASSERT(regExpStructure->storedPrototype().isObject());
2565             ASSERT(regExpStructure->storedPrototype().asCell()->classInfo(*m_vm) == RegExpPrototype::info());
2566
2567             FrozenValue* regExpPrototypeObjectValue = m_graph.freeze(regExpStructure->storedPrototype());
2568             Structure* regExpPrototypeStructure = regExpPrototypeObjectValue->structure();
2569
2570             auto isRegExpPropertySame = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
2571                 JSValue currentProperty;
2572                 if (!m_graph.getRegExpPrototypeProperty(regExpStructure->storedPrototypeObject(), regExpPrototypeStructure, propertyUID, currentProperty))
2573                     return false;
2574                 
2575                 return currentProperty == primordialProperty;
2576             };
2577
2578             // Check that RegExp.exec is still the primordial RegExp.prototype.exec
2579             if (!isRegExpPropertySame(globalObject->regExpProtoExecFunction(), m_vm->propertyNames->exec.impl()))
2580                 return false;
2581
2582             // Check that regExpObject is actually a RegExp object.
2583             Node* regExpObject = get(virtualRegisterForArgument(0, registerOffset));
2584             addToGraph(Check, Edge(regExpObject, RegExpObjectUse));
2585
2586             // Check that regExpObject's exec is actually the primodial RegExp.prototype.exec.
2587             UniquedStringImpl* execPropertyID = m_vm->propertyNames->exec.impl();
2588             unsigned execIndex = m_graph.identifiers().ensure(execPropertyID);
2589             Node* actualProperty = addToGraph(TryGetById, OpInfo(execIndex), OpInfo(SpecFunction), Edge(regExpObject, CellUse));
2590             FrozenValue* regExpPrototypeExec = m_graph.freeze(globalObject->regExpProtoExecFunction());
2591             addToGraph(CheckCell, OpInfo(regExpPrototypeExec), Edge(actualProperty, CellUse));
2592         }
2593
2594         insertChecks();
2595         Node* regExpObject = get(virtualRegisterForArgument(0, registerOffset));
2596         Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), regExpObject, get(virtualRegisterForArgument(1, registerOffset)));
2597         set(VirtualRegister(resultOperand), regExpExec);
2598         
2599         return true;
2600     }
2601
2602     case IsTypedArrayViewIntrinsic: {
2603         ASSERT(argumentCountIncludingThis == 2);
2604
2605         insertChecks();
2606         set(VirtualRegister(resultOperand), addToGraph(IsTypedArrayView, OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset))));
2607         return true;
2608     }
2609
2610     case StringPrototypeReplaceIntrinsic: {
2611         if (argumentCountIncludingThis != 3)
2612             return false;
2613
2614         // Don't inline intrinsic if we exited due to "search" not being a RegExp or String object.
2615         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
2616             return false;
2617
2618         // Don't inline intrinsic if we exited due to one of the primordial RegExp checks failing.
2619         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell))
2620             return false;
2621
2622         JSGlobalObject* globalObject = m_inlineStackTop->m_codeBlock->globalObject();
2623         Structure* regExpStructure = globalObject->regExpStructure();
2624         m_graph.registerStructure(regExpStructure);
2625         ASSERT(regExpStructure->storedPrototype().isObject());
2626         ASSERT(regExpStructure->storedPrototype().asCell()->classInfo(*m_vm) == RegExpPrototype::info());
2627
2628         FrozenValue* regExpPrototypeObjectValue = m_graph.freeze(regExpStructure->storedPrototype());
2629         Structure* regExpPrototypeStructure = regExpPrototypeObjectValue->structure();
2630
2631         auto isRegExpPropertySame = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
2632             JSValue currentProperty;
2633             if (!m_graph.getRegExpPrototypeProperty(regExpStructure->storedPrototypeObject(), regExpPrototypeStructure, propertyUID, currentProperty))
2634                 return false;
2635
2636             return currentProperty == primordialProperty;
2637         };
2638
2639         // Check that searchRegExp.exec is still the primordial RegExp.prototype.exec
2640         if (!isRegExpPropertySame(globalObject->regExpProtoExecFunction(), m_vm->propertyNames->exec.impl()))
2641             return false;
2642
2643         // Check that searchRegExp.global is still the primordial RegExp.prototype.global
2644         if (!isRegExpPropertySame(globalObject->regExpProtoGlobalGetter(), m_vm->propertyNames->global.impl()))
2645             return false;
2646
2647         // Check that searchRegExp.unicode is still the primordial RegExp.prototype.unicode
2648         if (!isRegExpPropertySame(globalObject->regExpProtoUnicodeGetter(), m_vm->propertyNames->unicode.impl()))
2649             return false;
2650
2651         // Check that searchRegExp[Symbol.match] is still the primordial RegExp.prototype[Symbol.replace]
2652         if (!isRegExpPropertySame(globalObject->regExpProtoSymbolReplaceFunction(), m_vm->propertyNames->replaceSymbol.impl()))
2653             return false;
2654
2655         insertChecks();
2656
2657         Node* result = addToGraph(StringReplace, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)), get(virtualRegisterForArgument(2, registerOffset)));
2658         set(VirtualRegister(resultOperand), result);
2659         return true;
2660     }
2661         
2662     case StringPrototypeReplaceRegExpIntrinsic: {
2663         if (argumentCountIncludingThis != 3)
2664             return false;
2665         
2666         insertChecks();
2667         Node* result = addToGraph(StringReplaceRegExp, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)), get(virtualRegisterForArgument(2, registerOffset)));
2668         set(VirtualRegister(resultOperand), result);
2669         return true;
2670     }
2671         
2672     case RoundIntrinsic:
2673     case FloorIntrinsic:
2674     case CeilIntrinsic:
2675     case TruncIntrinsic: {
2676         if (argumentCountIncludingThis == 1) {
2677             insertChecks();
2678             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
2679             return true;
2680         }
2681         insertChecks();
2682         Node* operand = get(virtualRegisterForArgument(1, registerOffset));
2683         NodeType op;
2684         if (intrinsic == RoundIntrinsic)
2685             op = ArithRound;
2686         else if (intrinsic == FloorIntrinsic)
2687             op = ArithFloor;
2688         else if (intrinsic == CeilIntrinsic)
2689             op = ArithCeil;
2690         else {
2691             ASSERT(intrinsic == TruncIntrinsic);
2692             op = ArithTrunc;
2693         }
2694         Node* roundNode = addToGraph(op, OpInfo(0), OpInfo(prediction), operand);
2695         set(VirtualRegister(resultOperand), roundNode);
2696         return true;
2697     }
2698     case IMulIntrinsic: {
2699         if (argumentCountIncludingThis != 3)
2700             return false;
2701         insertChecks();
2702         VirtualRegister leftOperand = virtualRegisterForArgument(1, registerOffset);
2703         VirtualRegister rightOperand = virtualRegisterForArgument(2, registerOffset);
2704         Node* left = get(leftOperand);
2705         Node* right = get(rightOperand);
2706         set(VirtualRegister(resultOperand), addToGraph(ArithIMul, left, right));
2707         return true;
2708     }
2709
2710     case RandomIntrinsic: {
2711         if (argumentCountIncludingThis != 1)
2712             return false;
2713         insertChecks();
2714         set(VirtualRegister(resultOperand), addToGraph(ArithRandom));
2715         return true;
2716     }
2717         
2718     case DFGTrueIntrinsic: {
2719         insertChecks();
2720         set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
2721         return true;
2722     }
2723         
2724     case OSRExitIntrinsic: {
2725         insertChecks();
2726         addToGraph(ForceOSRExit);
2727         set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
2728         return true;
2729     }
2730         
2731     case IsFinalTierIntrinsic: {
2732         insertChecks();
2733         set(VirtualRegister(resultOperand),
2734             jsConstant(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
2735         return true;
2736     }
2737         
2738     case SetInt32HeapPredictionIntrinsic: {
2739         insertChecks();
2740         for (int i = 1; i < argumentCountIncludingThis; ++i) {
2741             Node* node = get(virtualRegisterForArgument(i, registerOffset));
2742             if (node->hasHeapPrediction())
2743                 node->setHeapPrediction(SpecInt32Only);
2744         }
2745         set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
2746         return true;
2747     }
2748         
2749     case CheckInt32Intrinsic: {
2750         insertChecks();
2751         for (int i = 1; i < argumentCountIncludingThis; ++i) {
2752             Node* node = get(virtualRegisterForArgument(i, registerOffset));
2753             addToGraph(Phantom, Edge(node, Int32Use));
2754         }
2755         set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
2756         return true;
2757     }
2758         
2759     case FiatInt52Intrinsic: {
2760         if (argumentCountIncludingThis != 2)
2761             return false;
2762         insertChecks();
2763         VirtualRegister operand = virtualRegisterForArgument(1, registerOffset);
2764         if (enableInt52())
2765             set(VirtualRegister(resultOperand), addToGraph(FiatInt52, get(operand)));
2766         else
2767             set(VirtualRegister(resultOperand), get(operand));
2768         return true;
2769     }
2770
2771     case JSMapGetIntrinsic: {
2772         if (argumentCountIncludingThis != 2)
2773             return false;
2774
2775         insertChecks();
2776         Node* map = get(virtualRegisterForArgument(0, registerOffset));
2777         Node* key = get(virtualRegisterForArgument(1, registerOffset));
2778         Node* hash = addToGraph(MapHash, key);
2779         Node* bucket = addToGraph(GetMapBucket, Edge(map, MapObjectUse), Edge(key), Edge(hash));
2780         Node* result = addToGraph(LoadValueFromMapBucket, OpInfo(), OpInfo(prediction), bucket);
2781         set(VirtualRegister(resultOperand), result);
2782         return true;
2783     }
2784
2785     case JSSetHasIntrinsic:
2786     case JSMapHasIntrinsic: {
2787         if (argumentCountIncludingThis != 2)
2788             return false;
2789
2790         insertChecks();
2791         Node* mapOrSet = get(virtualRegisterForArgument(0, registerOffset));
2792         Node* key = get(virtualRegisterForArgument(1, registerOffset));
2793         Node* hash = addToGraph(MapHash, key);
2794         UseKind useKind = intrinsic == JSSetHasIntrinsic ? SetObjectUse : MapObjectUse;
2795         Node* bucket = addToGraph(GetMapBucket, OpInfo(0), Edge(mapOrSet, useKind), Edge(key), Edge(hash));
2796         JSCell* sentinel = nullptr;
2797         if (intrinsic == JSMapHasIntrinsic)
2798             sentinel = m_vm->sentinelMapBucket.get();
2799         else
2800             sentinel = m_vm->sentinelSetBucket.get();
2801
2802         FrozenValue* frozenPointer = m_graph.freeze(sentinel);
2803         Node* invertedResult = addToGraph(CompareEqPtr, OpInfo(frozenPointer), bucket);
2804         Node* result = addToGraph(LogicalNot, invertedResult);
2805         set(VirtualRegister(resultOperand), result);
2806         return true;
2807     }
2808
2809     case JSSetBucketHeadIntrinsic:
2810     case JSMapBucketHeadIntrinsic: {
2811         ASSERT(argumentCountIncludingThis == 2);
2812
2813         insertChecks();
2814         Node* map = get(virtualRegisterForArgument(1, registerOffset));
2815         UseKind useKind = intrinsic == JSSetBucketHeadIntrinsic ? SetObjectUse : MapObjectUse;
2816         Node* result = addToGraph(GetMapBucketHead, Edge(map, useKind));
2817         set(VirtualRegister(resultOperand), result);
2818         return true;
2819     }
2820
2821     case JSSetBucketNextIntrinsic:
2822     case JSMapBucketNextIntrinsic: {
2823         ASSERT(argumentCountIncludingThis == 2);
2824
2825         insertChecks();
2826         Node* bucket = get(virtualRegisterForArgument(1, registerOffset));
2827         BucketOwnerType type = intrinsic == JSSetBucketNextIntrinsic ? BucketOwnerType::Set : BucketOwnerType::Map;
2828         Node* result = addToGraph(GetMapBucketNext, OpInfo(type), bucket);
2829         set(VirtualRegister(resultOperand), result);
2830         return true;
2831     }
2832
2833     case JSSetBucketKeyIntrinsic:
2834     case JSMapBucketKeyIntrinsic: {
2835         ASSERT(argumentCountIncludingThis == 2);
2836
2837         insertChecks();
2838         Node* bucket = get(virtualRegisterForArgument(1, registerOffset));
2839         Node* result = addToGraph(LoadKeyFromMapBucket, OpInfo(), OpInfo(prediction), bucket);
2840         set(VirtualRegister(resultOperand), result);
2841         return true;
2842     }
2843
2844     case JSMapBucketValueIntrinsic: {
2845         ASSERT(argumentCountIncludingThis == 2);
2846
2847         insertChecks();
2848         Node* bucket = get(virtualRegisterForArgument(1, registerOffset));
2849         Node* result = addToGraph(LoadValueFromMapBucket, OpInfo(), OpInfo(prediction), bucket);
2850         set(VirtualRegister(resultOperand), result);
2851         return true;
2852     }
2853
2854     case JSWeakMapGetIntrinsic: {
2855         if (argumentCountIncludingThis != 2)
2856             return false;
2857
2858         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
2859             return false;
2860
2861         insertChecks();
2862         Node* map = get(virtualRegisterForArgument(0, registerOffset));
2863         Node* key = get(virtualRegisterForArgument(1, registerOffset));
2864         Node* hash = addToGraph(MapHash, key);
2865         Node* result = addToGraph(WeakMapGet, OpInfo(), OpInfo(prediction), map, key, hash);
2866         set(VirtualRegister(resultOperand), result);
2867         return true;
2868     }
2869
2870     case HasOwnPropertyIntrinsic: {
2871         if (argumentCountIncludingThis != 2)
2872             return false;
2873
2874         // This can be racy, that's fine. We know that once we observe that this is created,
2875         // that it will never be destroyed until the VM is destroyed. It's unlikely that
2876         // we'd ever get to the point where we inline this as an intrinsic without the
2877         // cache being created, however, it's possible if we always throw exceptions inside
2878         // hasOwnProperty.
2879         if (!m_vm->hasOwnPropertyCache())
2880             return false;
2881
2882         insertChecks();
2883         Node* object = get(virtualRegisterForArgument(0, registerOffset));
2884         Node* key = get(virtualRegisterForArgument(1, registerOffset));
2885         Node* result = addToGraph(HasOwnProperty, object, key);
2886         set(VirtualRegister(resultOperand), result);
2887         return true;
2888     }
2889
2890     case StringPrototypeToLowerCaseIntrinsic: {
2891         if (argumentCountIncludingThis != 1)
2892             return false;
2893
2894         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
2895             return false;
2896
2897         insertChecks();
2898         Node* thisString = get(virtualRegisterForArgument(0, registerOffset));
2899         Node* result = addToGraph(ToLowerCase, thisString);
2900         set(VirtualRegister(resultOperand), result);
2901         return true;
2902     }
2903
2904     case NumberPrototypeToStringIntrinsic: {
2905         if (argumentCountIncludingThis != 1 && argumentCountIncludingThis != 2)
2906             return false;
2907
2908         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
2909             return false;
2910
2911         insertChecks();
2912         Node* thisNumber = get(virtualRegisterForArgument(0, registerOffset));
2913         if (argumentCountIncludingThis == 1) {
2914             Node* result = addToGraph(ToString, thisNumber);
2915             set(VirtualRegister(resultOperand), result);
2916         } else {
2917             Node* radix = get(virtualRegisterForArgument(1, registerOffset));
2918             Node* result = addToGraph(NumberToStringWithRadix, thisNumber, radix);
2919             set(VirtualRegister(resultOperand), result);
2920         }
2921         return true;
2922     }
2923
2924     default:
2925         return false;
2926     }
2927 }
2928
2929 template<typename ChecksFunctor>
2930 bool ByteCodeParser::handleDOMJITCall(Node* callTarget, int resultOperand, const DOMJIT::Signature* signature, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks)
2931 {
2932     if (argumentCountIncludingThis != static_cast<int>(1 + signature->argumentCount))
2933         return false;
2934     if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
2935         return false;
2936
2937     // FIXME: Currently, we only support functions which arguments are up to 2.
2938     // Eventually, we should extend this. But possibly, 2 or 3 can cover typical use cases.
2939     // https://bugs.webkit.org/show_bug.cgi?id=164346
2940     ASSERT_WITH_MESSAGE(argumentCountIncludingThis <= JSC_DOMJIT_SIGNATURE_MAX_ARGUMENTS_INCLUDING_THIS, "Currently CallDOM does not support an arbitrary length arguments.");
2941
2942     insertChecks();
2943     addCall(resultOperand, Call, signature, callTarget, argumentCountIncludingThis, registerOffset, prediction);
2944     return true;
2945 }
2946
2947
2948 template<typename ChecksFunctor>
2949 bool ByteCodeParser::handleIntrinsicGetter(int resultOperand, const GetByIdVariant& variant, Node* thisNode, const ChecksFunctor& insertChecks)
2950 {
2951     switch (variant.intrinsic()) {
2952     case TypedArrayByteLengthIntrinsic: {
2953         insertChecks();
2954
2955         TypedArrayType type = (*variant.structureSet().begin())->classInfo()->typedArrayStorageType;
2956         Array::Type arrayType = toArrayType(type);
2957         size_t logSize = logElementSize(type);
2958
2959         variant.structureSet().forEach([&] (Structure* structure) {
2960             TypedArrayType curType = structure->classInfo()->typedArrayStorageType;
2961             ASSERT(logSize == logElementSize(curType));
2962             arrayType = refineTypedArrayType(arrayType, curType);
2963             ASSERT(arrayType != Array::Generic);
2964         });
2965
2966         Node* lengthNode = addToGraph(GetArrayLength, OpInfo(ArrayMode(arrayType).asWord()), thisNode);
2967
2968         if (!logSize) {
2969             set(VirtualRegister(resultOperand), lengthNode);
2970             return true;
2971         }
2972
2973         // We can use a BitLShift here because typed arrays will never have a byteLength
2974         // that overflows int32.
2975         Node* shiftNode = jsConstant(jsNumber(logSize));
2976         set(VirtualRegister(resultOperand), addToGraph(BitLShift, lengthNode, shiftNode));
2977
2978         return true;
2979     }
2980
2981     case TypedArrayLengthIntrinsic: {
2982         insertChecks();
2983
2984         TypedArrayType type = (*variant.structureSet().begin())->classInfo()->typedArrayStorageType;
2985         Array::Type arrayType = toArrayType(type);
2986
2987         variant.structureSet().forEach([&] (Structure* structure) {
2988             TypedArrayType curType = structure->classInfo()->typedArrayStorageType;
2989             arrayType = refineTypedArrayType(arrayType, curType);
2990             ASSERT(arrayType != Array::Generic);
2991         });
2992
2993         set(VirtualRegister(resultOperand), addToGraph(GetArrayLength, OpInfo(ArrayMode(arrayType).asWord()), thisNode));
2994
2995         return true;
2996
2997     }
2998
2999     case TypedArrayByteOffsetIntrinsic: {
3000         insertChecks();
3001
3002         TypedArrayType type = (*variant.structureSet().begin())->classInfo()->typedArrayStorageType;
3003         Array::Type arrayType = toArrayType(type);
3004
3005         variant.structureSet().forEach([&] (Structure* structure) {
3006             TypedArrayType curType = structure->classInfo()->typedArrayStorageType;
3007             arrayType = refineTypedArrayType(arrayType, curType);
3008             ASSERT(arrayType != Array::Generic);
3009         });
3010
3011         set(VirtualRegister(resultOperand), addToGraph(GetTypedArrayByteOffset, OpInfo(ArrayMode(arrayType).asWord()), thisNode));
3012
3013         return true;
3014     }
3015
3016     default:
3017         return false;
3018     }
3019     RELEASE_ASSERT_NOT_REACHED();
3020 }
3021
3022 static void blessCallDOMGetter(Node* node)
3023 {
3024     DOMJIT::CallDOMGetterSnippet* snippet = node->callDOMGetterData()->snippet;
3025     if (snippet && !snippet->effect.mustGenerate())
3026         node->clearFlags(NodeMustGenerate);
3027 }
3028
3029 bool ByteCodeParser::handleDOMJITGetter(int resultOperand, const GetByIdVariant& variant, Node* thisNode, unsigned identifierNumber, SpeculatedType prediction)
3030 {
3031     if (!variant.domAttribute())
3032         return false;
3033
3034     auto domAttribute = variant.domAttribute().value();
3035
3036     // We do not need to actually look up CustomGetterSetter here. Checking Structures or registering watchpoints are enough,
3037     // since replacement of CustomGetterSetter always incurs Structure transition.
3038     if (!check(variant.conditionSet()))
3039         return false;
3040     addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), thisNode);
3041
3042     // We do not need to emit CheckCell thingy here. When the custom accessor is replaced to different one, Structure transition occurs.
3043     addToGraph(CheckSubClass, OpInfo(domAttribute.classInfo), thisNode);
3044
3045     CallDOMGetterData* callDOMGetterData = m_graph.m_callDOMGetterData.add();
3046     callDOMGetterData->customAccessorGetter = variant.customAccessorGetter();
3047     ASSERT(callDOMGetterData->customAccessorGetter);
3048
3049     if (const auto* domJIT = domAttribute.domJIT) {
3050         callDOMGetterData->domJIT = domJIT;
3051         Ref<DOMJIT::CallDOMGetterSnippet> snippet = domJIT->compiler()();
3052         callDOMGetterData->snippet = snippet.ptr();
3053         m_graph.m_domJITSnippets.append(WTFMove(snippet));
3054     }
3055     DOMJIT::CallDOMGetterSnippet* callDOMGetterSnippet = callDOMGetterData->snippet;
3056     callDOMGetterData->identifierNumber = identifierNumber;
3057
3058     Node* callDOMGetterNode = nullptr;
3059     // GlobalObject of thisNode is always used to create a DOMWrapper.
3060     if (callDOMGetterSnippet && callDOMGetterSnippet->requireGlobalObject) {
3061         Node* globalObject = addToGraph(GetGlobalObject, thisNode);
3062         callDOMGetterNode = addToGraph(CallDOMGetter, OpInfo(callDOMGetterData), OpInfo(prediction), thisNode, globalObject);
3063     } else
3064         callDOMGetterNode = addToGraph(CallDOMGetter, OpInfo(callDOMGetterData), OpInfo(prediction), thisNode);
3065     blessCallDOMGetter(callDOMGetterNode);
3066     set(VirtualRegister(resultOperand), callDOMGetterNode);
3067     return true;
3068 }
3069
3070 bool ByteCodeParser::handleModuleNamespaceLoad(int resultOperand, SpeculatedType prediction, Node* base, GetByIdStatus getById)
3071 {
3072     if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell))
3073         return false;
3074     addToGraph(CheckCell, OpInfo(m_graph.freeze(getById.moduleNamespaceObject())), Edge(base, CellUse));
3075
3076     // Ideally we wouldn't have to do this Phantom. But:
3077     //
3078     // For the constant case: we must do it because otherwise we would have no way of knowing
3079     // that the scope is live at OSR here.
3080     //
3081     // For the non-constant case: GetClosureVar could be DCE'd, but baseline's implementation
3082     // won't be able to handle an Undefined scope.
3083     addToGraph(Phantom, base);
3084
3085     // Constant folding in the bytecode parser is important for performance. This may not
3086     // have executed yet. If it hasn't, then we won't have a prediction. Lacking a
3087     // prediction, we'd otherwise think that it has to exit. Then when it did execute, we
3088     // would recompile. But if we can fold it here, we avoid the exit.
3089     m_graph.freeze(getById.moduleEnvironment());
3090     if (JSValue value = m_graph.tryGetConstantClosureVar(getById.moduleEnvironment(), getById.scopeOffset())) {
3091         set(VirtualRegister(resultOperand), weakJSConstant(value));
3092         return true;
3093     }
3094     set(VirtualRegister(resultOperand), addToGraph(GetClosureVar, OpInfo(getById.scopeOffset().offset()), OpInfo(prediction), weakJSConstant(getById.moduleEnvironment())));
3095     return true;
3096 }
3097
3098 template<typename ChecksFunctor>
3099 bool ByteCodeParser::handleTypedArrayConstructor(
3100     int resultOperand, InternalFunction* function, int registerOffset,
3101     int argumentCountIncludingThis, TypedArrayType type, const ChecksFunctor& insertChecks)
3102 {
3103     if (!isTypedView(type))
3104         return false;
3105     
3106     if (function->classInfo() != constructorClassInfoForType(type))
3107         return false;
3108     
3109     if (function->globalObject() != m_inlineStackTop->m_codeBlock->globalObject())
3110         return false;
3111     
3112     // We only have an intrinsic for the case where you say:
3113     //
3114     // new FooArray(blah);
3115     //
3116     // Of course, 'blah' could be any of the following:
3117     //
3118     // - Integer, indicating that you want to allocate an array of that length.
3119     //   This is the thing we're hoping for, and what we can actually do meaningful
3120     //   optimizations for.
3121     //
3122     // - Array buffer, indicating that you want to create a view onto that _entire_
3123     //   buffer.
3124     //
3125     // - Non-buffer object, indicating that you want to create a copy of that
3126     //   object by pretending that it quacks like an array.
3127     //
3128     // - Anything else, indicating that you want to have an exception thrown at
3129     //   you.
3130     //
3131     // The intrinsic, NewTypedArray, will behave as if it could do any of these
3132     // things up until we do Fixup. Thereafter, if child1 (i.e. 'blah') is
3133     // predicted Int32, then we lock it in as a normal typed array allocation.
3134     // Otherwise, NewTypedArray turns into a totally opaque function call that
3135     // may clobber the world - by virtue of it accessing properties on what could
3136     // be an object.
3137     //
3138     // Note that although the generic form of NewTypedArray sounds sort of awful,
3139     // it is actually quite likely to be more efficient than a fully generic
3140     // Construct. So, we might want to think about making NewTypedArray variadic,
3141     // or else making Construct not super slow.
3142     
3143     if (argumentCountIncludingThis != 2)
3144         return false;
3145     
3146     if (!function->globalObject()->typedArrayStructureConcurrently(type))
3147         return false;
3148
3149     insertChecks();
3150     set(VirtualRegister(resultOperand),
3151         addToGraph(NewTypedArray, OpInfo(type), get(virtualRegisterForArgument(1, registerOffset))));
3152     return true;
3153 }
3154
3155 template<typename ChecksFunctor>
3156 bool ByteCodeParser::handleConstantInternalFunction(
3157     Node* callTargetNode, int resultOperand, InternalFunction* function, int registerOffset,
3158     int argumentCountIncludingThis, CodeSpecializationKind kind, SpeculatedType prediction, const ChecksFunctor& insertChecks)
3159 {
3160     VERBOSE_LOG("    Handling constant internal function ", JSValue(function), "\n");
3161     
3162     // It so happens that the code below assumes that the result operand is valid. It's extremely
3163     // unlikely that the result operand would be invalid - you'd have to call this via a setter call.
3164     if (!VirtualRegister(resultOperand).isValid())
3165         return false;
3166
3167     if (kind == CodeForConstruct) {
3168         Node* newTargetNode = get(virtualRegisterForArgument(0, registerOffset));
3169         // We cannot handle the case where new.target != callee (i.e. a construct from a super call) because we
3170         // don't know what the prototype of the constructed object will be.
3171         // FIXME: If we have inlined super calls up to the call site, however, we should be able to figure out the structure. https://bugs.webkit.org/show_bug.cgi?id=152700
3172         if (newTargetNode != callTargetNode)
3173             return false;
3174     }
3175
3176     if (function->classInfo() == ArrayConstructor::info()) {
3177         if (function->globalObject() != m_inlineStackTop->m_codeBlock->globalObject())
3178             return false;
3179         
3180         insertChecks();
3181         if (argumentCountIncludingThis == 2) {
3182             set(VirtualRegister(resultOperand),
3183                 addToGraph(NewArrayWithSize, OpInfo(ArrayWithUndecided), get(virtualRegisterForArgument(1, registerOffset))));
3184             return true;
3185         }
3186         
3187         for (int i = 1; i < argumentCountIncludingThis; ++i)
3188             addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
3189         set(VirtualRegister(resultOperand),
3190             addToGraph(Node::VarArg, NewArray, OpInfo(ArrayWithUndecided), OpInfo(0)));
3191         return true;
3192     }
3193
3194     if (function->classInfo() == NumberConstructor::info()) {
3195         if (kind == CodeForConstruct)
3196             return false;
3197
3198         insertChecks();
3199         if (argumentCountIncludingThis <= 1)
3200             set(VirtualRegister(resultOperand), jsConstant(jsNumber(0)));
3201         else
3202             set(VirtualRegister(resultOperand), addToGraph(ToNumber, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset))));
3203
3204         return true;
3205     }
3206     
3207     if (function->classInfo() == StringConstructor::info()) {
3208         insertChecks();
3209         
3210         Node* result;
3211         
3212         if (argumentCountIncludingThis <= 1)
3213             result = jsConstant(m_vm->smallStrings.emptyString());
3214         else
3215             result = addToGraph(CallStringConstructor, get(virtualRegisterForArgument(1, registerOffset)));
3216         
3217         if (kind == CodeForConstruct)
3218             result = addToGraph(NewStringObject, OpInfo(m_graph.registerStructure(function->globalObject()->stringObjectStructure())), result);
3219         
3220         set(VirtualRegister(resultOperand), result);
3221         return true;
3222     }
3223
3224     // FIXME: This should handle construction as well. https://bugs.webkit.org/show_bug.cgi?id=155591
3225     if (function->classInfo() == ObjectConstructor::info() && kind == CodeForCall) {
3226         insertChecks();
3227
3228         Node* result;
3229         if (argumentCountIncludingThis <= 1)
3230             result = addToGraph(NewObject, OpInfo(m_graph.registerStructure(function->globalObject()->objectStructureForObjectConstructor())));
3231         else
3232             result = addToGraph(CallObjectConstructor, get(virtualRegisterForArgument(1, registerOffset)));
3233         set(VirtualRegister(resultOperand), result);
3234         return true;
3235     }
3236
3237     for (unsigned typeIndex = 0; typeIndex < NUMBER_OF_TYPED_ARRAY_TYPES; ++typeIndex) {
3238         bool result = handleTypedArrayConstructor(
3239             resultOperand, function, registerOffset, argumentCountIncludingThis,
3240             indexToTypedArrayType(typeIndex), insertChecks);
3241         if (result)
3242             return true;
3243     }
3244     
3245     return false;
3246 }
3247
3248 Node* ByteCodeParser::handleGetByOffset(
3249     SpeculatedType prediction, Node* base, unsigned identifierNumber, PropertyOffset offset,
3250     const InferredType::Descriptor& inferredType, NodeType op)
3251 {
3252     Node* propertyStorage;
3253     if (isInlineOffset(offset))
3254         propertyStorage = base;
3255     else
3256         propertyStorage = addToGraph(GetButterfly, base);
3257     
3258     StorageAccessData* data = m_graph.m_storageAccessData.add();
3259     data->offset = offset;
3260     data->identifierNumber = identifierNumber;
3261     data->inferredType = inferredType;
3262     m_graph.registerInferredType(inferredType);
3263     
3264     Node* getByOffset = addToGraph(op, OpInfo(data), OpInfo(prediction), propertyStorage, base);
3265
3266     return getByOffset;
3267 }
3268
3269 Node* ByteCodeParser::handlePutByOffset(
3270     Node* base, unsigned identifier, PropertyOffset offset, const InferredType::Descriptor& inferredType,
3271     Node* value)
3272 {
3273     Node* propertyStorage;
3274     if (isInlineOffset(offset))
3275         propertyStorage = base;
3276     else
3277         propertyStorage = addToGraph(GetButterfly, base);
3278     
3279     StorageAccessData* data = m_graph.m_storageAccessData.add();
3280     data->offset = offset;
3281     data->identifierNumber = identifier;
3282     data->inferredType = inferredType;
3283     m_graph.registerInferredType(inferredType);
3284     
3285     Node* result = addToGraph(PutByOffset, OpInfo(data), propertyStorage, base, value);
3286     
3287     return result;
3288 }
3289
3290 bool ByteCodeParser::check(const ObjectPropertyCondition& condition)
3291 {
3292     if (!condition)
3293         return false;
3294     
3295     if (m_graph.watchCondition(condition))
3296         return true;
3297     
3298     Structure* structure = condition.object()->structure();
3299     if (!condition.structureEnsuresValidity(structure))
3300         return false;
3301     
3302     addToGraph(
3303         CheckStructure,
3304         OpInfo(m_graph.addStructureSet(structure)),
3305         weakJSConstant(condition.object()));
3306     return true;
3307 }
3308
3309 GetByOffsetMethod ByteCodeParser::promoteToConstant(GetByOffsetMethod method)
3310 {
3311     if (method.kind() == GetByOffsetMethod::LoadFromPrototype
3312         && method.prototype()->structure()->dfgShouldWatch()) {
3313         if (JSValue constant = m_graph.tryGetConstantProperty(method.prototype()->value(), method.prototype()->structure(), method.offset()))
3314             return GetByOffsetMethod::constant(m_graph.freeze(constant));
3315     }
3316     
3317     return method;
3318 }
3319
3320 bool ByteCodeParser::needsDynamicLookup(ResolveType type, OpcodeID opcode)
3321 {
3322     ASSERT(opcode == op_resolve_scope || opcode == op_get_from_scope || opcode == op_put_to_scope);
3323
3324     JSGlobalObject* globalObject = m_inlineStackTop->m_codeBlock->globalObject();
3325     if (needsVarInjectionChecks(type) && globalObject->varInjectionWatchpoint()->hasBeenInvalidated())
3326         return true;
3327
3328     switch (type) {
3329     case GlobalProperty:
3330     case GlobalVar:
3331     case GlobalLexicalVar:
3332     case ClosureVar:
3333     case LocalClosureVar:
3334     case ModuleVar:
3335         return false;
3336
3337     case UnresolvedProperty:
3338     case UnresolvedPropertyWithVarInjectionChecks: {
3339         // The heuristic for UnresolvedProperty scope accesses is we will ForceOSRExit if we
3340         // haven't exited from from this access before to let the baseline JIT try to better
3341         // cache the access. If we've already exited from this operation, it's unlikely that
3342         // the baseline will come up with a better ResolveType and instead we will compile
3343         // this as a dynamic scope access.
3344
3345         // We only track our heuristic through resolve_scope since resolve_scope will
3346         // dominate unresolved gets/puts on that scope.
3347         if (opcode != op_resolve_scope)
3348             return true;
3349
3350         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, InadequateCoverage)) {
3351             // We've already exited so give up on getting better ResolveType information.
3352             return true;
3353         }
3354
3355         // We have not exited yet, so let's have the baseline get better ResolveType information for us.
3356         // This type of code is often seen when we tier up in a loop but haven't executed the part
3357         // of a function that comes after the loop.
3358         return false;
3359     }
3360
3361     case Dynamic:
3362         return true;
3363
3364     case GlobalPropertyWithVarInjectionChecks:
3365     case GlobalVarWithVarInjectionChecks:
3366     case GlobalLexicalVarWithVarInjectionChecks:
3367     case ClosureVarWithVarInjectionChecks:
3368         return false;
3369     }
3370
3371     ASSERT_NOT_REACHED();
3372     return false;
3373 }
3374
3375 GetByOffsetMethod ByteCodeParser::planLoad(const ObjectPropertyCondition& condition)
3376 {
3377     VERBOSE_LOG("Planning a load: ", condition, "\n");
3378     
3379     // We might promote this to Equivalence, and a later DFG pass might also do such promotion
3380     // even if we fail, but for simplicity this cannot be asked to load an equivalence condition.
3381     // None of the clients of this method will request a load of an Equivalence condition anyway,
3382     // and supporting it would complicate the heuristics below.
3383     RELEASE_ASSERT(condition.kind() == PropertyCondition::Presence);
3384     
3385     // Here's the ranking of how to handle this, from most preferred to least preferred:
3386     //
3387     // 1) Watchpoint on an equivalence condition and return a constant node for the loaded value.
3388     //    No other code is emitted, and the structure of the base object is never registered.
3389     //    Hence this results in zero code and we won't jettison this compilation if the object
3390     //    transitions, even if the structure is watchable right now.
3391     //
3392     // 2) Need to emit a load, and the current structure of the base is going to be watched by the
3393     //    DFG anyway (i.e. dfgShouldWatch). Watch the structure and emit the load. Don't watch the
3394     //    condition, since the act of turning the base into a constant in IR will cause the DFG to
3395     //    watch the structure anyway and doing so would subsume watching the condition.
3396     //
3397     // 3) Need to emit a load, and the current structure of the base is watchable but not by the
3398     //    DFG (i.e. transitionWatchpointSetIsStillValid() and !dfgShouldWatchIfPossible()). Watch
3399     //    the condition, and emit a load.
3400     //
3401     // 4) Need to emit a load, and the current structure of the base is not watchable. Emit a
3402     //    structure check, and emit a load.
3403     //
3404     // 5) The condition does not hold. Give up and return null.
3405     
3406     // First, try to promote Presence to Equivalence. We do this before doing anything else
3407     // because it's the most profitable. Also, there are cases where the presence is watchable but
3408     // we don't want to watch it unless it became an equivalence (see the relationship between
3409     // (1), (2), and (3) above).
3410     ObjectPropertyCondition equivalenceCondition = condition.attemptToMakeEquivalenceWithoutBarrier(*m_vm);
3411     if (m_graph.watchCondition(equivalenceCondition))
3412         return GetByOffsetMethod::constant(m_graph.freeze(equivalenceCondition.requiredValue()));
3413     
3414     // At this point, we'll have to materialize the condition's base as a constant in DFG IR. Once
3415     // we do this, the frozen value will have its own idea of what the structure is. Use that from
3416     // now on just because it's less confusing.
3417     FrozenValue* base = m_graph.freeze(condition.object());
3418     Structure* structure = base->structure();
3419     
3420     // Check if the structure that we've registered makes the condition hold. If not, just give
3421     // up. This is case (5) above.
3422     if (!condition.structureEnsuresValidity(structure))
3423         return GetByOffsetMethod();
3424     
3425     // If the structure is watched by the DFG already, then just use this fact to emit the load.
3426     // This is case (2) above.
3427     if (structure->dfgShouldWatch())
3428         return promoteToConstant(GetByOffsetMethod::loadFromPrototype(base, condition.offset()));
3429     
3430     // If we can watch the condition right now, then we can emit the load after watching it. This
3431     // is case (3) above.
3432     if (m_graph.watchCondition(condition))
3433         return promoteToConstant(GetByOffsetMethod::loadFromPrototype(base, condition.offset()));
3434     
3435     // We can't watch anything but we know that the current structure satisfies the condition. So,
3436     // check for that structure and then emit the load.
3437     addToGraph(
3438         CheckStructure, 
3439         OpInfo(m_graph.addStructureSet(structure)),
3440         addToGraph(JSConstant, OpInfo(base)));
3441     return promoteToConstant(GetByOffsetMethod::loadFromPrototype(base, condition.offset()));
3442 }
3443
3444 Node* ByteCodeParser::load(
3445     SpeculatedType prediction, unsigned identifierNumber, const GetByOffsetMethod& method,
3446     NodeType op)
3447 {
3448     switch (method.kind()) {
3449     case GetByOffsetMethod::Invalid:
3450         return nullptr;
3451     case GetByOffsetMethod::Constant:
3452         return addToGraph(JSConstant, OpInfo(method.constant()));
3453     case GetByOffsetMethod::LoadFromPrototype: {
3454         Node* baseNode = addToGraph(JSConstant, OpInfo(method.prototype()));
3455         return handleGetByOffset(
3456             prediction, baseNode, identifierNumber, method.offset(), InferredType::Top, op);
3457     }
3458     case GetByOffsetMethod::Load:
3459         // Will never see this from planLoad().
3460         RELEASE_ASSERT_NOT_REACHED();
3461         return nullptr;
3462     }
3463     
3464     RELEASE_ASSERT_NOT_REACHED();
3465     return nullptr;
3466 }
3467
3468 Node* ByteCodeParser::load(
3469     SpeculatedType prediction, const ObjectPropertyCondition& condition, NodeType op)
3470 {
3471     GetByOffsetMethod method = planLoad(condition);
3472     return load(prediction, m_graph.identifiers().ensure(condition.uid()), method, op);
3473 }
3474
3475 bool ByteCodeParser::check(const ObjectPropertyConditionSet& conditionSet)
3476 {
3477     for (const ObjectPropertyCondition& condition : conditionSet) {
3478         if (!check(condition))
3479             return false;
3480     }
3481     return true;
3482 }
3483
3484 GetByOffsetMethod ByteCodeParser::planLoad(const ObjectPropertyConditionSet& conditionSet)
3485 {
3486     VERBOSE_LOG("conditionSet = ", conditionSet, "\n");
3487     
3488     GetByOffsetMethod result;
3489     for (const ObjectPropertyCondition& condition : conditionSet) {
3490         switch (condition.kind()) {
3491         case PropertyCondition::Presence:
3492             RELEASE_ASSERT(!result); // Should only see exactly one of these.
3493             result = planLoad(condition);
3494             if (!result)
3495                 return GetByOffsetMethod();
3496             break;
3497         default:
3498             if (!check(condition))
3499                 return GetByOffsetMethod();
3500             break;
3501         }
3502     }
3503     if (!result) {
3504         // We have a unset property.
3505         ASSERT(!conditionSet.numberOfConditionsWithKind(PropertyCondition::Presence));
3506         return GetByOffsetMethod::constant(m_constantUndefined);
3507     }
3508     return result;
3509 }
3510
3511 Node* ByteCodeParser::load(
3512     SpeculatedType prediction, const ObjectPropertyConditionSet& conditionSet, NodeType op)
3513 {
3514     GetByOffsetMethod method = planLoad(conditionSet);
3515     return load(
3516         prediction,
3517         m_graph.identifiers().ensure(conditionSet.slotBaseCondition().uid()),
3518         method, op);
3519 }
3520
3521 ObjectPropertyCondition ByteCodeParser::presenceLike(
3522     JSObject* knownBase, UniquedStringImpl* uid, PropertyOffset offset, const StructureSet& set)
3523 {
3524     if (set.isEmpty())
3525         return ObjectPropertyCondition();
3526     unsigned attributes;
3527     PropertyOffset firstOffset = set[0]->getConcurrently(uid, attributes);
3528     if (firstOffset != offset)
3529         return ObjectPropertyCondition();
3530     for (unsigned i = 1; i < set.size(); ++i) {
3531         unsigned otherAttributes;
3532         PropertyOffset otherOffset = set[i]->getConcurrently(uid, otherAttributes);
3533         if (otherOffset != offset || otherAttributes != attributes)
3534             return ObjectPropertyCondition();
3535     }
3536     return ObjectPropertyCondition::presenceWithoutBarrier(knownBase, uid, offset, attributes);
3537 }
3538
3539 bool ByteCodeParser::checkPresenceLike(
3540     JSObject* knownBase, UniquedStringImpl* uid, PropertyOffset offset, const StructureSet& set)
3541 {
3542     return check(presenceLike(knownBase, uid, offset, set));
3543 }
3544
3545 void ByteCodeParser::checkPresenceLike(
3546     Node* base, UniquedStringImpl* uid, PropertyOffset offset, const StructureSet& set)
3547 {
3548     if (JSObject* knownBase = base->dynamicCastConstant<JSObject*>(*m_vm)) {
3549         if (checkPresenceLike(knownBase, uid, offset, set))
3550             return;
3551     }
3552
3553     addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(set)), base);
3554 }
3555
3556 template<typename VariantType>
3557 Node* ByteCodeParser::load(
3558     SpeculatedType prediction, Node* base, unsigned identifierNumber, const VariantType& variant)
3559 {
3560     // Make sure backwards propagation knows that we've used base.
3561     addToGraph(Phantom, base);
3562     
3563     bool needStructureCheck = true;
3564     
3565     UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
3566     
3567     if (JSObject* knownBase = base->dynamicCastConstant<JSObject*>(*m_vm)) {
3568         // Try to optimize away the structure check. Note that it's not worth doing anything about this
3569         // if the base's structure is watched.
3570         Structure* structure = base->constant()->structure();
3571         if (!structure->dfgShouldWatch()) {
3572             if (!variant.conditionSet().isEmpty()) {
3573                 // This means that we're loading from a prototype or we have a property miss. We expect
3574                 // the base not to have the property. We can only use ObjectPropertyCondition if all of
3575                 // the structures in the variant.structureSet() agree on the prototype (it would be
3576                 // hilariously rare if they didn't). Note that we are relying on structureSet() having
3577                 // at least one element. That will always be true here because of how GetByIdStatus/PutByIdStatus work.
3578
3579                 // FIXME: right now, if we have an OPCS, we have mono proto. However, this will
3580                 // need to be changed in the future once we have a hybrid data structure for
3581                 // poly proto:
3582                 // https://bugs.webkit.org/show_bug.cgi?id=177339
3583                 JSObject* prototype = variant.structureSet()[0]->storedPrototypeObject();
3584                 bool allAgree = true;
3585                 for (unsigned i = 1; i < variant.structureSet().size(); ++i) {
3586                     if (variant.structureSet()[i]->storedPrototypeObject() != prototype) {
3587                         allAgree = false;
3588                         break;
3589                     }
3590                 }
3591                 if (allAgree) {
3592                     ObjectPropertyCondition condition = ObjectPropertyCondition::absenceWithoutBarrier(
3593                         knownBase, uid, prototype);
3594                     if (check(condition))
3595                         needStructureCheck = false;
3596                 }
3597             } else {
3598                 // This means we're loading directly from base. We can avoid all of the code that follows
3599                 // if we can prove that the property is a constant. Otherwise, we try to prove that the
3600                 // property is watchably present, in which case we get rid of the structure check.
3601
3602                 ObjectPropertyCondition presenceCondition =
3603                     presenceLike(knownBase, uid, variant.offset(), variant.structureSet());
3604                 if (presenceCondition) {
3605                     ObjectPropertyCondition equivalenceCondition =
3606                         presenceCondition.attemptToMakeEquivalenceWithoutBarrier(*m_vm);
3607                     if (m_graph.watchCondition(equivalenceCondition))
3608                         return weakJSConstant(equivalenceCondition.requiredValue());
3609                     
3610                     if (check(presenceCondition))
3611                         needStructureCheck = false;
3612                 }
3613             }
3614         }
3615     }
3616
3617     if (needStructureCheck)
3618         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), base);
3619
3620     if (variant.isPropertyUnset()) {
3621         if (m_graph.watchConditions(variant.conditionSet()))
3622             return jsConstant(jsUndefined());
3623         return nullptr;
3624     }
3625
3626     SpeculatedType loadPrediction;
3627     NodeType loadOp;
3628     if (variant.callLinkStatus() || variant.intrinsic() != NoIntrinsic) {
3629         loadPrediction = SpecCellOther;
3630         loadOp = GetGetterSetterByOffset;
3631     } else {
3632         loadPrediction = prediction;
3633         loadOp = GetByOffset;
3634     }
3635     
3636     Node* loadedValue;
3637     if (!variant.conditionSet().isEmpty())
3638         loadedValue = load(loadPrediction, variant.conditionSet(), loadOp);
3639     else {
3640         if (needStructureCheck && base->hasConstant()) {
3641             // We did emit a structure check. That means that we have an opportunity to do constant folding
3642             // here, since we didn't do it above.
3643             JSValue constant = m_graph.tryGetConstantProperty(