[JSC] Add support for GetByVal on arrays of Undecided shape
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGByteCodeParser.cpp
1 /*
2  * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DFGByteCodeParser.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "ArrayConstructor.h"
32 #include "BasicBlockLocation.h"
33 #include "CallLinkStatus.h"
34 #include "CodeBlock.h"
35 #include "CodeBlockWithJITType.h"
36 #include "DFGArrayMode.h"
37 #include "DFGCapabilities.h"
38 #include "DFGGraph.h"
39 #include "DFGJITCode.h"
40 #include "GetByIdStatus.h"
41 #include "Heap.h"
42 #include "JSLexicalEnvironment.h"
43 #include "JSCInlines.h"
44 #include "PreciseJumpTargets.h"
45 #include "PutByIdStatus.h"
46 #include "StackAlignment.h"
47 #include "StringConstructor.h"
48 #include "Watchdog.h"
49 #include <wtf/CommaPrinter.h>
50 #include <wtf/HashMap.h>
51 #include <wtf/MathExtras.h>
52 #include <wtf/StdLibExtras.h>
53
54 namespace JSC { namespace DFG {
55
56 static const bool verbose = false;
57
58 class ConstantBufferKey {
59 public:
60     ConstantBufferKey()
61         : m_codeBlock(0)
62         , m_index(0)
63     {
64     }
65     
66     ConstantBufferKey(WTF::HashTableDeletedValueType)
67         : m_codeBlock(0)
68         , m_index(1)
69     {
70     }
71     
72     ConstantBufferKey(CodeBlock* codeBlock, unsigned index)
73         : m_codeBlock(codeBlock)
74         , m_index(index)
75     {
76     }
77     
78     bool operator==(const ConstantBufferKey& other) const
79     {
80         return m_codeBlock == other.m_codeBlock
81             && m_index == other.m_index;
82     }
83     
84     unsigned hash() const
85     {
86         return WTF::PtrHash<CodeBlock*>::hash(m_codeBlock) ^ m_index;
87     }
88     
89     bool isHashTableDeletedValue() const
90     {
91         return !m_codeBlock && m_index;
92     }
93     
94     CodeBlock* codeBlock() const { return m_codeBlock; }
95     unsigned index() const { return m_index; }
96     
97 private:
98     CodeBlock* m_codeBlock;
99     unsigned m_index;
100 };
101
102 struct ConstantBufferKeyHash {
103     static unsigned hash(const ConstantBufferKey& key) { return key.hash(); }
104     static bool equal(const ConstantBufferKey& a, const ConstantBufferKey& b)
105     {
106         return a == b;
107     }
108     
109     static const bool safeToCompareToEmptyOrDeleted = true;
110 };
111
112 } } // namespace JSC::DFG
113
114 namespace WTF {
115
116 template<typename T> struct DefaultHash;
117 template<> struct DefaultHash<JSC::DFG::ConstantBufferKey> {
118     typedef JSC::DFG::ConstantBufferKeyHash Hash;
119 };
120
121 template<typename T> struct HashTraits;
122 template<> struct HashTraits<JSC::DFG::ConstantBufferKey> : SimpleClassHashTraits<JSC::DFG::ConstantBufferKey> { };
123
124 } // namespace WTF
125
126 namespace JSC { namespace DFG {
127
128 // === ByteCodeParser ===
129 //
130 // This class is used to compile the dataflow graph from a CodeBlock.
131 class ByteCodeParser {
132 public:
133     ByteCodeParser(Graph& graph)
134         : m_vm(&graph.m_vm)
135         , m_codeBlock(graph.m_codeBlock)
136         , m_profiledBlock(graph.m_profiledBlock)
137         , m_graph(graph)
138         , m_currentBlock(0)
139         , m_currentIndex(0)
140         , m_constantUndefined(graph.freeze(jsUndefined()))
141         , m_constantNull(graph.freeze(jsNull()))
142         , m_constantNaN(graph.freeze(jsNumber(PNaN)))
143         , m_constantOne(graph.freeze(jsNumber(1)))
144         , m_numArguments(m_codeBlock->numParameters())
145         , m_numLocals(m_codeBlock->m_numCalleeRegisters)
146         , m_parameterSlots(0)
147         , m_numPassedVarArgs(0)
148         , m_inlineStackTop(0)
149         , m_currentInstruction(0)
150         , m_hasDebuggerEnabled(graph.hasDebuggerEnabled())
151     {
152         ASSERT(m_profiledBlock);
153     }
154     
155     // Parse a full CodeBlock of bytecode.
156     bool parse();
157     
158 private:
159     struct InlineStackEntry;
160
161     // Just parse from m_currentIndex to the end of the current CodeBlock.
162     void parseCodeBlock();
163     
164     void ensureLocals(unsigned newNumLocals)
165     {
166         if (newNumLocals <= m_numLocals)
167             return;
168         m_numLocals = newNumLocals;
169         for (size_t i = 0; i < m_graph.numBlocks(); ++i)
170             m_graph.block(i)->ensureLocals(newNumLocals);
171     }
172
173     // Helper for min and max.
174     template<typename ChecksFunctor>
175     bool handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis, const ChecksFunctor& insertChecks);
176     
177     // Handle calls. This resolves issues surrounding inlining and intrinsics.
178     void handleCall(
179         int result, NodeType op, InlineCallFrame::Kind, unsigned instructionSize,
180         Node* callTarget, int argCount, int registerOffset, CallLinkStatus,
181         SpeculatedType prediction);
182     void handleCall(
183         int result, NodeType op, InlineCallFrame::Kind, unsigned instructionSize,
184         Node* callTarget, int argCount, int registerOffset, CallLinkStatus);
185     void handleCall(int result, NodeType op, CodeSpecializationKind, unsigned instructionSize, int callee, int argCount, int registerOffset);
186     void handleCall(Instruction* pc, NodeType op, CodeSpecializationKind);
187     void handleVarargsCall(Instruction* pc, NodeType op, CodeSpecializationKind);
188     void emitFunctionChecks(CallVariant, Node* callTarget, VirtualRegister thisArgumnt);
189     void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis);
190     unsigned inliningCost(CallVariant, int argumentCountIncludingThis, CodeSpecializationKind); // Return UINT_MAX if it's not an inlining candidate. By convention, intrinsics have a cost of 1.
191     // Handle inlining. Return true if it succeeded, false if we need to plant a call.
192     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);
193     enum CallerLinkability { CallerDoesNormalLinking, CallerLinksManually };
194     template<typename ChecksFunctor>
195     bool attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, CallerLinkability, SpeculatedType prediction, unsigned& inliningBalance, const ChecksFunctor& insertChecks);
196     template<typename ChecksFunctor>
197     void inlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, CallerLinkability, const ChecksFunctor& insertChecks);
198     void cancelLinkingForBlock(InlineStackEntry*, BasicBlock*); // Only works when the given block is the last one to have been added for that inline stack entry.
199     // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
200     template<typename ChecksFunctor>
201     bool handleIntrinsic(int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
202     template<typename ChecksFunctor>
203     bool handleTypedArrayConstructor(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, TypedArrayType, const ChecksFunctor& insertChecks);
204     template<typename ChecksFunctor>
205     bool handleConstantInternalFunction(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind, const ChecksFunctor& insertChecks);
206     Node* handlePutByOffset(Node* base, unsigned identifier, PropertyOffset, Node* value);
207     Node* handleGetByOffset(SpeculatedType, Node* base, unsigned identifierNumber, PropertyOffset, NodeType = GetByOffset);
208     Node* handleGetByOffset(SpeculatedType, Node* base, UniquedStringImpl*, PropertyOffset, NodeType = GetByOffset);
209
210     // Create a presence ObjectPropertyCondition based on some known offset and structure set. Does not
211     // check the validity of the condition, but it may return a null one if it encounters a contradiction.
212     ObjectPropertyCondition presenceLike(
213         JSObject* knownBase, UniquedStringImpl*, PropertyOffset, const StructureSet&);
214     
215     // Attempt to watch the presence of a property. It will watch that the property is present in the same
216     // way as in all of the structures in the set. It may emit code instead of just setting a watchpoint.
217     // Returns true if this all works out.
218     bool checkPresenceLike(JSObject* knownBase, UniquedStringImpl*, PropertyOffset, const StructureSet&);
219     void checkPresenceLike(Node* base, UniquedStringImpl*, PropertyOffset, const StructureSet&);
220     
221     // Works with both GetByIdVariant and the setter form of PutByIdVariant.
222     template<typename VariantType>
223     Node* load(SpeculatedType, Node* base, unsigned identifierNumber, const VariantType&);
224
225     Node* store(Node* base, unsigned identifier, const PutByIdVariant&, Node* value);
226         
227     void handleGetById(
228         int destinationOperand, SpeculatedType, Node* base, unsigned identifierNumber,
229         const GetByIdStatus&);
230     void emitPutById(
231         Node* base, unsigned identifierNumber, Node* value,  const PutByIdStatus&, bool isDirect);
232     void handlePutById(
233         Node* base, unsigned identifierNumber, Node* value, const PutByIdStatus&,
234         bool isDirect);
235     
236     // Either register a watchpoint or emit a check for this condition. Returns false if the
237     // condition no longer holds, and therefore no reasonable check can be emitted.
238     bool check(const ObjectPropertyCondition&);
239     
240     GetByOffsetMethod promoteToConstant(GetByOffsetMethod);
241     
242     // Either register a watchpoint or emit a check for this condition. It must be a Presence
243     // condition. It will attempt to promote a Presence condition to an Equivalence condition.
244     // Emits code for the loaded value that the condition guards, and returns a node containing
245     // the loaded value. Returns null if the condition no longer holds.
246     GetByOffsetMethod planLoad(const ObjectPropertyCondition&);
247     Node* load(SpeculatedType, unsigned identifierNumber, const GetByOffsetMethod&, NodeType = GetByOffset);
248     Node* load(SpeculatedType, const ObjectPropertyCondition&, NodeType = GetByOffset);
249     
250     // Calls check() for each condition in the set: that is, it either emits checks or registers
251     // watchpoints (or a combination of the two) to make the conditions hold. If any of those
252     // conditions are no longer checkable, returns false.
253     bool check(const ObjectPropertyConditionSet&);
254     
255     // Calls check() for those conditions that aren't the slot base, and calls load() for the slot
256     // base. Does a combination of watchpoint registration and check emission to guard the
257     // conditions, and emits code to load the value from the slot base. Returns a node containing
258     // the loaded value. Returns null if any of the conditions were no longer checkable.
259     GetByOffsetMethod planLoad(const ObjectPropertyConditionSet&);
260     Node* load(SpeculatedType, const ObjectPropertyConditionSet&, NodeType = GetByOffset);
261
262     void prepareToParseBlock();
263     void clearCaches();
264
265     // Parse a single basic block of bytecode instructions.
266     bool parseBlock(unsigned limit);
267     // Link block successors.
268     void linkBlock(BasicBlock*, Vector<BasicBlock*>& possibleTargets);
269     void linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BasicBlock*>& possibleTargets);
270     
271     VariableAccessData* newVariableAccessData(VirtualRegister operand)
272     {
273         ASSERT(!operand.isConstant());
274         
275         m_graph.m_variableAccessData.append(VariableAccessData(operand));
276         return &m_graph.m_variableAccessData.last();
277     }
278     
279     // Get/Set the operands/result of a bytecode instruction.
280     Node* getDirect(VirtualRegister operand)
281     {
282         ASSERT(!operand.isConstant());
283
284         // Is this an argument?
285         if (operand.isArgument())
286             return getArgument(operand);
287
288         // Must be a local.
289         return getLocal(operand);
290     }
291
292     Node* get(VirtualRegister operand)
293     {
294         if (operand.isConstant()) {
295             unsigned constantIndex = operand.toConstantIndex();
296             unsigned oldSize = m_constants.size();
297             if (constantIndex >= oldSize || !m_constants[constantIndex]) {
298                 const CodeBlock& codeBlock = *m_inlineStackTop->m_codeBlock;
299                 JSValue value = codeBlock.getConstant(operand.offset());
300                 SourceCodeRepresentation sourceCodeRepresentation = codeBlock.constantSourceCodeRepresentation(operand.offset());
301                 if (constantIndex >= oldSize) {
302                     m_constants.grow(constantIndex + 1);
303                     for (unsigned i = oldSize; i < m_constants.size(); ++i)
304                         m_constants[i] = nullptr;
305                 }
306
307                 Node* constantNode = nullptr;
308                 if (sourceCodeRepresentation == SourceCodeRepresentation::Double)
309                     constantNode = addToGraph(DoubleConstant, OpInfo(m_graph.freezeStrong(jsDoubleNumber(value.asNumber()))));
310                 else
311                     constantNode = addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(value)));
312                 m_constants[constantIndex] = constantNode;
313             }
314             ASSERT(m_constants[constantIndex]);
315             return m_constants[constantIndex];
316         }
317         
318         if (inlineCallFrame()) {
319             if (!inlineCallFrame()->isClosureCall) {
320                 JSFunction* callee = inlineCallFrame()->calleeConstant();
321                 if (operand.offset() == JSStack::Callee)
322                     return weakJSConstant(callee);
323             }
324         } else if (operand.offset() == JSStack::Callee) {
325             // We have to do some constant-folding here because this enables CreateThis folding. Note
326             // that we don't have such watchpoint-based folding for inlined uses of Callee, since in that
327             // case if the function is a singleton then we already know it.
328             if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(m_codeBlock->ownerExecutable())) {
329                 InferredValue* singleton = executable->singletonFunction();
330                 if (JSValue value = singleton->inferredValue()) {
331                     m_graph.watchpoints().addLazily(singleton);
332                     JSFunction* function = jsCast<JSFunction*>(value);
333                     return weakJSConstant(function);
334                 }
335             }
336             return addToGraph(GetCallee);
337         }
338         
339         return getDirect(m_inlineStackTop->remapOperand(operand));
340     }
341     
342     enum SetMode {
343         // A normal set which follows a two-phase commit that spans code origins. During
344         // the current code origin it issues a MovHint, and at the start of the next
345         // code origin there will be a SetLocal. If the local needs flushing, the second
346         // SetLocal will be preceded with a Flush.
347         NormalSet,
348         
349         // A set where the SetLocal happens immediately and there is still a Flush. This
350         // is relevant when assigning to a local in tricky situations for the delayed
351         // SetLocal logic but where we know that we have not performed any side effects
352         // within this code origin. This is a safe replacement for NormalSet anytime we
353         // know that we have not yet performed side effects in this code origin.
354         ImmediateSetWithFlush,
355         
356         // A set where the SetLocal happens immediately and we do not Flush it even if
357         // this is a local that is marked as needing it. This is relevant when
358         // initializing locals at the top of a function.
359         ImmediateNakedSet
360     };
361     Node* setDirect(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
362     {
363         addToGraph(MovHint, OpInfo(operand.offset()), value);
364
365         DelayedSetLocal delayed(currentCodeOrigin(), operand, value);
366         
367         if (setMode == NormalSet) {
368             m_setLocalQueue.append(delayed);
369             return 0;
370         }
371         
372         return delayed.execute(this, setMode);
373     }
374     
375     void processSetLocalQueue()
376     {
377         for (unsigned i = 0; i < m_setLocalQueue.size(); ++i)
378             m_setLocalQueue[i].execute(this);
379         m_setLocalQueue.resize(0);
380     }
381
382     Node* set(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
383     {
384         return setDirect(m_inlineStackTop->remapOperand(operand), value, setMode);
385     }
386     
387     Node* injectLazyOperandSpeculation(Node* node)
388     {
389         ASSERT(node->op() == GetLocal);
390         ASSERT(node->origin.semantic.bytecodeIndex == m_currentIndex);
391         ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
392         LazyOperandValueProfileKey key(m_currentIndex, node->local());
393         SpeculatedType prediction = m_inlineStackTop->m_lazyOperands.prediction(locker, key);
394         node->variableAccessData()->predict(prediction);
395         return node;
396     }
397
398     // Used in implementing get/set, above, where the operand is a local variable.
399     Node* getLocal(VirtualRegister operand)
400     {
401         unsigned local = operand.toLocal();
402
403         Node* node = m_currentBlock->variablesAtTail.local(local);
404         
405         // This has two goals: 1) link together variable access datas, and 2)
406         // try to avoid creating redundant GetLocals. (1) is required for
407         // correctness - no other phase will ensure that block-local variable
408         // access data unification is done correctly. (2) is purely opportunistic
409         // and is meant as an compile-time optimization only.
410         
411         VariableAccessData* variable;
412         
413         if (node) {
414             variable = node->variableAccessData();
415             
416             switch (node->op()) {
417             case GetLocal:
418                 return node;
419             case SetLocal:
420                 return node->child1().node();
421             default:
422                 break;
423             }
424         } else
425             variable = newVariableAccessData(operand);
426         
427         node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
428         m_currentBlock->variablesAtTail.local(local) = node;
429         return node;
430     }
431
432     Node* setLocal(const CodeOrigin& semanticOrigin, VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
433     {
434         CodeOrigin oldSemanticOrigin = m_currentSemanticOrigin;
435         m_currentSemanticOrigin = semanticOrigin;
436
437         unsigned local = operand.toLocal();
438         
439         if (setMode != ImmediateNakedSet) {
440             ArgumentPosition* argumentPosition = findArgumentPositionForLocal(operand);
441             if (argumentPosition)
442                 flushDirect(operand, argumentPosition);
443             else if (m_hasDebuggerEnabled && operand == m_codeBlock->scopeRegister())
444                 flush(operand);
445         }
446
447         VariableAccessData* variableAccessData = newVariableAccessData(operand);
448         variableAccessData->mergeStructureCheckHoistingFailed(
449             m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadCache));
450         variableAccessData->mergeCheckArrayHoistingFailed(
451             m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadIndexingType));
452         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
453         m_currentBlock->variablesAtTail.local(local) = node;
454
455         m_currentSemanticOrigin = oldSemanticOrigin;
456         return node;
457     }
458
459     // Used in implementing get/set, above, where the operand is an argument.
460     Node* getArgument(VirtualRegister operand)
461     {
462         unsigned argument = operand.toArgument();
463         ASSERT(argument < m_numArguments);
464         
465         Node* node = m_currentBlock->variablesAtTail.argument(argument);
466
467         VariableAccessData* variable;
468         
469         if (node) {
470             variable = node->variableAccessData();
471             
472             switch (node->op()) {
473             case GetLocal:
474                 return node;
475             case SetLocal:
476                 return node->child1().node();
477             default:
478                 break;
479             }
480         } else
481             variable = newVariableAccessData(operand);
482         
483         node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
484         m_currentBlock->variablesAtTail.argument(argument) = node;
485         return node;
486     }
487     Node* setArgument(const CodeOrigin& semanticOrigin, VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
488     {
489         CodeOrigin oldSemanticOrigin = m_currentSemanticOrigin;
490         m_currentSemanticOrigin = semanticOrigin;
491
492         unsigned argument = operand.toArgument();
493         ASSERT(argument < m_numArguments);
494         
495         VariableAccessData* variableAccessData = newVariableAccessData(operand);
496
497         // Always flush arguments, except for 'this'. If 'this' is created by us,
498         // then make sure that it's never unboxed.
499         if (argument) {
500             if (setMode != ImmediateNakedSet)
501                 flushDirect(operand);
502         } else if (m_codeBlock->specializationKind() == CodeForConstruct)
503             variableAccessData->mergeShouldNeverUnbox(true);
504         
505         variableAccessData->mergeStructureCheckHoistingFailed(
506             m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadCache));
507         variableAccessData->mergeCheckArrayHoistingFailed(
508             m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadIndexingType));
509         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
510         m_currentBlock->variablesAtTail.argument(argument) = node;
511
512         m_currentSemanticOrigin = oldSemanticOrigin;
513         return node;
514     }
515     
516     ArgumentPosition* findArgumentPositionForArgument(int argument)
517     {
518         InlineStackEntry* stack = m_inlineStackTop;
519         while (stack->m_inlineCallFrame)
520             stack = stack->m_caller;
521         return stack->m_argumentPositions[argument];
522     }
523     
524     ArgumentPosition* findArgumentPositionForLocal(VirtualRegister operand)
525     {
526         for (InlineStackEntry* stack = m_inlineStackTop; ; stack = stack->m_caller) {
527             InlineCallFrame* inlineCallFrame = stack->m_inlineCallFrame;
528             if (!inlineCallFrame)
529                 break;
530             if (operand.offset() < static_cast<int>(inlineCallFrame->stackOffset + JSStack::CallFrameHeaderSize))
531                 continue;
532             if (operand.offset() == inlineCallFrame->stackOffset + CallFrame::thisArgumentOffset())
533                 continue;
534             if (operand.offset() >= static_cast<int>(inlineCallFrame->stackOffset + CallFrame::thisArgumentOffset() + inlineCallFrame->arguments.size()))
535                 continue;
536             int argument = VirtualRegister(operand.offset() - inlineCallFrame->stackOffset).toArgument();
537             return stack->m_argumentPositions[argument];
538         }
539         return 0;
540     }
541     
542     ArgumentPosition* findArgumentPosition(VirtualRegister operand)
543     {
544         if (operand.isArgument())
545             return findArgumentPositionForArgument(operand.toArgument());
546         return findArgumentPositionForLocal(operand);
547     }
548
549     void flush(VirtualRegister operand)
550     {
551         flushDirect(m_inlineStackTop->remapOperand(operand));
552     }
553     
554     void flushDirect(VirtualRegister operand)
555     {
556         flushDirect(operand, findArgumentPosition(operand));
557     }
558     
559     void flushDirect(VirtualRegister operand, ArgumentPosition* argumentPosition)
560     {
561         ASSERT(!operand.isConstant());
562         
563         Node* node = m_currentBlock->variablesAtTail.operand(operand);
564         
565         VariableAccessData* variable;
566         
567         if (node)
568             variable = node->variableAccessData();
569         else
570             variable = newVariableAccessData(operand);
571         
572         node = addToGraph(Flush, OpInfo(variable));
573         m_currentBlock->variablesAtTail.operand(operand) = node;
574         if (argumentPosition)
575             argumentPosition->addVariable(variable);
576     }
577     
578     void flush(InlineStackEntry* inlineStackEntry)
579     {
580         int numArguments;
581         if (InlineCallFrame* inlineCallFrame = inlineStackEntry->m_inlineCallFrame) {
582             ASSERT(!m_hasDebuggerEnabled);
583             numArguments = inlineCallFrame->arguments.size();
584             if (inlineCallFrame->isClosureCall)
585                 flushDirect(inlineStackEntry->remapOperand(VirtualRegister(JSStack::Callee)));
586             if (inlineCallFrame->isVarargs())
587                 flushDirect(inlineStackEntry->remapOperand(VirtualRegister(JSStack::ArgumentCount)));
588         } else
589             numArguments = inlineStackEntry->m_codeBlock->numParameters();
590         for (unsigned argument = numArguments; argument-- > 1;)
591             flushDirect(inlineStackEntry->remapOperand(virtualRegisterForArgument(argument)));
592         if (m_hasDebuggerEnabled)
593             flush(m_codeBlock->scopeRegister());
594     }
595
596     void flushForTerminal()
597     {
598         for (InlineStackEntry* inlineStackEntry = m_inlineStackTop; inlineStackEntry; inlineStackEntry = inlineStackEntry->m_caller)
599             flush(inlineStackEntry);
600     }
601
602     void flushForReturn()
603     {
604         flush(m_inlineStackTop);
605     }
606     
607     void flushIfTerminal(SwitchData& data)
608     {
609         if (data.fallThrough.bytecodeIndex() > m_currentIndex)
610             return;
611         
612         for (unsigned i = data.cases.size(); i--;) {
613             if (data.cases[i].target.bytecodeIndex() > m_currentIndex)
614                 return;
615         }
616         
617         flushForTerminal();
618     }
619
620     // Assumes that the constant should be strongly marked.
621     Node* jsConstant(JSValue constantValue)
622     {
623         return addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(constantValue)));
624     }
625
626     Node* weakJSConstant(JSValue constantValue)
627     {
628         return addToGraph(JSConstant, OpInfo(m_graph.freeze(constantValue)));
629     }
630
631     // Helper functions to get/set the this value.
632     Node* getThis()
633     {
634         return get(m_inlineStackTop->m_codeBlock->thisRegister());
635     }
636
637     void setThis(Node* value)
638     {
639         set(m_inlineStackTop->m_codeBlock->thisRegister(), value);
640     }
641
642     InlineCallFrame* inlineCallFrame()
643     {
644         return m_inlineStackTop->m_inlineCallFrame;
645     }
646
647     CodeOrigin currentCodeOrigin()
648     {
649         return CodeOrigin(m_currentIndex, inlineCallFrame());
650     }
651
652     NodeOrigin currentNodeOrigin()
653     {
654         // FIXME: We should set the forExit origin only on those nodes that can exit.
655         // https://bugs.webkit.org/show_bug.cgi?id=145204
656         if (m_currentSemanticOrigin.isSet())
657             return NodeOrigin(m_currentSemanticOrigin, currentCodeOrigin());
658         return NodeOrigin(currentCodeOrigin());
659     }
660     
661     BranchData* branchData(unsigned taken, unsigned notTaken)
662     {
663         // We assume that branches originating from bytecode always have a fall-through. We
664         // use this assumption to avoid checking for the creation of terminal blocks.
665         ASSERT((taken > m_currentIndex) || (notTaken > m_currentIndex));
666         BranchData* data = m_graph.m_branchData.add();
667         *data = BranchData::withBytecodeIndices(taken, notTaken);
668         return data;
669     }
670     
671     Node* addToGraph(Node* node)
672     {
673         if (Options::verboseDFGByteCodeParsing())
674             dataLog("        appended ", node, " ", Graph::opName(node->op()), "\n");
675         m_currentBlock->append(node);
676         return node;
677     }
678     
679     Node* addToGraph(NodeType op, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
680     {
681         Node* result = m_graph.addNode(
682             SpecNone, op, currentNodeOrigin(), Edge(child1), Edge(child2),
683             Edge(child3));
684         return addToGraph(result);
685     }
686     Node* addToGraph(NodeType op, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
687     {
688         Node* result = m_graph.addNode(
689             SpecNone, op, currentNodeOrigin(), child1, child2, child3);
690         return addToGraph(result);
691     }
692     Node* addToGraph(NodeType op, OpInfo info, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
693     {
694         Node* result = m_graph.addNode(
695             SpecNone, op, currentNodeOrigin(), info, Edge(child1), Edge(child2),
696             Edge(child3));
697         return addToGraph(result);
698     }
699     Node* addToGraph(NodeType op, OpInfo info1, OpInfo info2, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
700     {
701         Node* result = m_graph.addNode(
702             SpecNone, op, currentNodeOrigin(), info1, info2,
703             Edge(child1), Edge(child2), Edge(child3));
704         return addToGraph(result);
705     }
706     
707     Node* addToGraph(Node::VarArgTag, NodeType op, OpInfo info1, OpInfo info2)
708     {
709         Node* result = m_graph.addNode(
710             SpecNone, Node::VarArg, op, currentNodeOrigin(), info1, info2,
711             m_graph.m_varArgChildren.size() - m_numPassedVarArgs, m_numPassedVarArgs);
712         addToGraph(result);
713         
714         m_numPassedVarArgs = 0;
715         
716         return result;
717     }
718     
719     void addVarArgChild(Node* child)
720     {
721         m_graph.m_varArgChildren.append(Edge(child));
722         m_numPassedVarArgs++;
723     }
724     
725     Node* addCallWithoutSettingResult(
726         NodeType op, OpInfo opInfo, Node* callee, int argCount, int registerOffset,
727         SpeculatedType prediction)
728     {
729         addVarArgChild(callee);
730         size_t parameterSlots = JSStack::CallFrameHeaderSize - JSStack::CallerFrameAndPCSize + argCount;
731         if (parameterSlots > m_parameterSlots)
732             m_parameterSlots = parameterSlots;
733
734         for (int i = 0; i < argCount; ++i)
735             addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
736
737         return addToGraph(Node::VarArg, op, opInfo, OpInfo(prediction));
738     }
739     
740     Node* addCall(
741         int result, NodeType op, OpInfo opInfo, Node* callee, int argCount, int registerOffset,
742         SpeculatedType prediction)
743     {
744         Node* call = addCallWithoutSettingResult(
745             op, opInfo, callee, argCount, registerOffset, prediction);
746         VirtualRegister resultReg(result);
747         if (resultReg.isValid())
748             set(resultReg, call);
749         return call;
750     }
751     
752     Node* cellConstantWithStructureCheck(JSCell* object, Structure* structure)
753     {
754         // FIXME: This should route to emitPropertyCheck, not the other way around. But currently,
755         // this gets no profit from using emitPropertyCheck() since we'll non-adaptively watch the
756         // object's structure as soon as we make it a weakJSCosntant.
757         Node* objectNode = weakJSConstant(object);
758         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), objectNode);
759         return objectNode;
760     }
761     
762     SpeculatedType getPredictionWithoutOSRExit(unsigned bytecodeIndex)
763     {
764         ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
765         return m_inlineStackTop->m_profiledBlock->valueProfilePredictionForBytecodeOffset(locker, bytecodeIndex);
766     }
767
768     SpeculatedType getPrediction(unsigned bytecodeIndex)
769     {
770         SpeculatedType prediction = getPredictionWithoutOSRExit(bytecodeIndex);
771         
772         if (prediction == SpecNone) {
773             // We have no information about what values this node generates. Give up
774             // on executing this code, since we're likely to do more damage than good.
775             addToGraph(ForceOSRExit);
776         }
777         
778         return prediction;
779     }
780     
781     SpeculatedType getPredictionWithoutOSRExit()
782     {
783         return getPredictionWithoutOSRExit(m_currentIndex);
784     }
785     
786     SpeculatedType getPrediction()
787     {
788         return getPrediction(m_currentIndex);
789     }
790     
791     ArrayMode getArrayMode(ArrayProfile* profile, Array::Action action)
792     {
793         ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
794         profile->computeUpdatedPrediction(locker, m_inlineStackTop->m_profiledBlock);
795         bool makeSafe = profile->outOfBounds(locker);
796         return ArrayMode::fromObserved(locker, profile, action, makeSafe);
797     }
798     
799     ArrayMode getArrayMode(ArrayProfile* profile)
800     {
801         return getArrayMode(profile, Array::Read);
802     }
803     
804     Node* makeSafe(Node* node)
805     {
806         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
807             node->mergeFlags(NodeMayOverflowInDFG);
808         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
809             node->mergeFlags(NodeMayNegZeroInDFG);
810         
811         if (!isX86() && node->op() == ArithMod)
812             return node;
813
814         if (!m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex))
815             return node;
816         
817         switch (node->op()) {
818         case UInt32ToNumber:
819         case ArithAdd:
820         case ArithSub:
821         case ValueAdd:
822         case ArithMod: // for ArithMod "MayOverflow" means we tried to divide by zero, or we saw double.
823             node->mergeFlags(NodeMayOverflowInBaseline);
824             break;
825             
826         case ArithNegate:
827             // Currently we can't tell the difference between a negation overflowing
828             // (i.e. -(1 << 31)) or generating negative zero (i.e. -0). If it took slow
829             // path then we assume that it did both of those things.
830             node->mergeFlags(NodeMayOverflowInBaseline);
831             node->mergeFlags(NodeMayNegZeroInBaseline);
832             break;
833
834         case ArithMul:
835             // FIXME: We should detect cases where we only overflowed but never created
836             // negative zero.
837             // https://bugs.webkit.org/show_bug.cgi?id=132470
838             if (m_inlineStackTop->m_profiledBlock->likelyToTakeDeepestSlowCase(m_currentIndex)
839                 || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
840                 node->mergeFlags(NodeMayOverflowInBaseline | NodeMayNegZeroInBaseline);
841             else if (m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex)
842                 || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
843                 node->mergeFlags(NodeMayNegZeroInBaseline);
844             break;
845             
846         default:
847             RELEASE_ASSERT_NOT_REACHED();
848             break;
849         }
850         
851         return node;
852     }
853     
854     Node* makeDivSafe(Node* node)
855     {
856         ASSERT(node->op() == ArithDiv);
857         
858         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
859             node->mergeFlags(NodeMayOverflowInDFG);
860         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
861             node->mergeFlags(NodeMayNegZeroInDFG);
862         
863         // The main slow case counter for op_div in the old JIT counts only when
864         // the operands are not numbers. We don't care about that since we already
865         // have speculations in place that take care of that separately. We only
866         // care about when the outcome of the division is not an integer, which
867         // is what the special fast case counter tells us.
868         
869         if (!m_inlineStackTop->m_profiledBlock->couldTakeSpecialFastCase(m_currentIndex))
870             return node;
871         
872         // FIXME: It might be possible to make this more granular.
873         node->mergeFlags(NodeMayOverflowInBaseline | NodeMayNegZeroInBaseline);
874         
875         return node;
876     }
877     
878     void noticeArgumentsUse()
879     {
880         // All of the arguments in this function need to be formatted as JSValues because we will
881         // load from them in a random-access fashion and we don't want to have to switch on
882         // format.
883         
884         for (ArgumentPosition* argument : m_inlineStackTop->m_argumentPositions)
885             argument->mergeShouldNeverUnbox(true);
886     }
887     
888     VM* m_vm;
889     CodeBlock* m_codeBlock;
890     CodeBlock* m_profiledBlock;
891     Graph& m_graph;
892
893     // The current block being generated.
894     BasicBlock* m_currentBlock;
895     // The bytecode index of the current instruction being generated.
896     unsigned m_currentIndex;
897     // The semantic origin of the current node if different from the current Index.
898     CodeOrigin m_currentSemanticOrigin;
899
900     FrozenValue* m_constantUndefined;
901     FrozenValue* m_constantNull;
902     FrozenValue* m_constantNaN;
903     FrozenValue* m_constantOne;
904     Vector<Node*, 16> m_constants;
905
906     // The number of arguments passed to the function.
907     unsigned m_numArguments;
908     // The number of locals (vars + temporaries) used in the function.
909     unsigned m_numLocals;
910     // The number of slots (in units of sizeof(Register)) that we need to
911     // preallocate for arguments to outgoing calls from this frame. This
912     // number includes the CallFrame slots that we initialize for the callee
913     // (but not the callee-initialized CallerFrame and ReturnPC slots).
914     // This number is 0 if and only if this function is a leaf.
915     unsigned m_parameterSlots;
916     // The number of var args passed to the next var arg node.
917     unsigned m_numPassedVarArgs;
918
919     HashMap<ConstantBufferKey, unsigned> m_constantBufferCache;
920     
921     struct InlineStackEntry {
922         ByteCodeParser* m_byteCodeParser;
923         
924         CodeBlock* m_codeBlock;
925         CodeBlock* m_profiledBlock;
926         InlineCallFrame* m_inlineCallFrame;
927         
928         ScriptExecutable* executable() { return m_codeBlock->ownerExecutable(); }
929         
930         QueryableExitProfile m_exitProfile;
931         
932         // Remapping of identifier and constant numbers from the code block being
933         // inlined (inline callee) to the code block that we're inlining into
934         // (the machine code block, which is the transitive, though not necessarily
935         // direct, caller).
936         Vector<unsigned> m_identifierRemap;
937         Vector<unsigned> m_constantBufferRemap;
938         Vector<unsigned> m_switchRemap;
939         
940         // Blocks introduced by this code block, which need successor linking.
941         // May include up to one basic block that includes the continuation after
942         // the callsite in the caller. These must be appended in the order that they
943         // are created, but their bytecodeBegin values need not be in order as they
944         // are ignored.
945         Vector<UnlinkedBlock> m_unlinkedBlocks;
946         
947         // Potential block linking targets. Must be sorted by bytecodeBegin, and
948         // cannot have two blocks that have the same bytecodeBegin.
949         Vector<BasicBlock*> m_blockLinkingTargets;
950         
951         // If the callsite's basic block was split into two, then this will be
952         // the head of the callsite block. It needs its successors linked to the
953         // m_unlinkedBlocks, but not the other way around: there's no way for
954         // any blocks in m_unlinkedBlocks to jump back into this block.
955         BasicBlock* m_callsiteBlockHead;
956         
957         // Does the callsite block head need linking? This is typically true
958         // but will be false for the machine code block's inline stack entry
959         // (since that one is not inlined) and for cases where an inline callee
960         // did the linking for us.
961         bool m_callsiteBlockHeadNeedsLinking;
962         
963         VirtualRegister m_returnValue;
964         
965         // Speculations about variable types collected from the profiled code block,
966         // which are based on OSR exit profiles that past DFG compilatins of this
967         // code block had gathered.
968         LazyOperandValueProfileParser m_lazyOperands;
969         
970         CallLinkInfoMap m_callLinkInfos;
971         StubInfoMap m_stubInfos;
972         ByValInfoMap m_byValInfos;
973         
974         // Did we see any returns? We need to handle the (uncommon but necessary)
975         // case where a procedure that does not return was inlined.
976         bool m_didReturn;
977         
978         // Did we have any early returns?
979         bool m_didEarlyReturn;
980         
981         // Pointers to the argument position trackers for this slice of code.
982         Vector<ArgumentPosition*> m_argumentPositions;
983         
984         InlineStackEntry* m_caller;
985         
986         InlineStackEntry(
987             ByteCodeParser*,
988             CodeBlock*,
989             CodeBlock* profiledBlock,
990             BasicBlock* callsiteBlockHead,
991             JSFunction* callee, // Null if this is a closure call.
992             VirtualRegister returnValueVR,
993             VirtualRegister inlineCallFrameStart,
994             int argumentCountIncludingThis,
995             InlineCallFrame::Kind);
996         
997         ~InlineStackEntry()
998         {
999             m_byteCodeParser->m_inlineStackTop = m_caller;
1000         }
1001         
1002         VirtualRegister remapOperand(VirtualRegister operand) const
1003         {
1004             if (!m_inlineCallFrame)
1005                 return operand;
1006             
1007             ASSERT(!operand.isConstant());
1008
1009             return VirtualRegister(operand.offset() + m_inlineCallFrame->stackOffset);
1010         }
1011     };
1012     
1013     InlineStackEntry* m_inlineStackTop;
1014     
1015     struct DelayedSetLocal {
1016         CodeOrigin m_origin;
1017         VirtualRegister m_operand;
1018         Node* m_value;
1019         
1020         DelayedSetLocal() { }
1021         DelayedSetLocal(const CodeOrigin& origin, VirtualRegister operand, Node* value)
1022             : m_origin(origin)
1023             , m_operand(operand)
1024             , m_value(value)
1025         {
1026         }
1027         
1028         Node* execute(ByteCodeParser* parser, SetMode setMode = NormalSet)
1029         {
1030             if (m_operand.isArgument())
1031                 return parser->setArgument(m_origin, m_operand, m_value, setMode);
1032             return parser->setLocal(m_origin, m_operand, m_value, setMode);
1033         }
1034     };
1035     
1036     Vector<DelayedSetLocal, 2> m_setLocalQueue;
1037
1038     CodeBlock* m_dfgCodeBlock;
1039     CallLinkStatus::ContextMap m_callContextMap;
1040     StubInfoMap m_dfgStubInfos;
1041     
1042     Instruction* m_currentInstruction;
1043     bool m_hasDebuggerEnabled;
1044 };
1045
1046 #define NEXT_OPCODE(name) \
1047     m_currentIndex += OPCODE_LENGTH(name); \
1048     continue
1049
1050 #define LAST_OPCODE(name) \
1051     m_currentIndex += OPCODE_LENGTH(name); \
1052     return shouldContinueParsing
1053
1054 void ByteCodeParser::handleCall(Instruction* pc, NodeType op, CodeSpecializationKind kind)
1055 {
1056     ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct));
1057     handleCall(
1058         pc[1].u.operand, op, kind, OPCODE_LENGTH(op_call),
1059         pc[2].u.operand, pc[3].u.operand, -pc[4].u.operand);
1060 }
1061
1062 void ByteCodeParser::handleCall(
1063     int result, NodeType op, CodeSpecializationKind kind, unsigned instructionSize,
1064     int callee, int argumentCountIncludingThis, int registerOffset)
1065 {
1066     Node* callTarget = get(VirtualRegister(callee));
1067     
1068     CallLinkStatus callLinkStatus = CallLinkStatus::computeFor(
1069         m_inlineStackTop->m_profiledBlock, currentCodeOrigin(),
1070         m_inlineStackTop->m_callLinkInfos, m_callContextMap);
1071     
1072     handleCall(
1073         result, op, InlineCallFrame::kindFor(kind), instructionSize, callTarget,
1074         argumentCountIncludingThis, registerOffset, callLinkStatus);
1075 }
1076     
1077 void ByteCodeParser::handleCall(
1078     int result, NodeType op, InlineCallFrame::Kind kind, unsigned instructionSize,
1079     Node* callTarget, int argumentCountIncludingThis, int registerOffset,
1080     CallLinkStatus callLinkStatus)
1081 {
1082     handleCall(
1083         result, op, kind, instructionSize, callTarget, argumentCountIncludingThis,
1084         registerOffset, callLinkStatus, getPrediction());
1085 }
1086
1087 void ByteCodeParser::handleCall(
1088     int result, NodeType op, InlineCallFrame::Kind kind, unsigned instructionSize,
1089     Node* callTarget, int argumentCountIncludingThis, int registerOffset,
1090     CallLinkStatus callLinkStatus, SpeculatedType prediction)
1091 {
1092     ASSERT(registerOffset <= 0);
1093     
1094     if (callTarget->isCellConstant())
1095         callLinkStatus.setProvenConstantCallee(CallVariant(callTarget->asCell()));
1096     
1097     if (Options::verboseDFGByteCodeParsing())
1098         dataLog("    Handling call at ", currentCodeOrigin(), ": ", callLinkStatus, "\n");
1099     
1100     if (!callLinkStatus.canOptimize()) {
1101         // Oddly, this conflates calls that haven't executed with calls that behaved sufficiently polymorphically
1102         // that we cannot optimize them.
1103         
1104         addCall(result, op, OpInfo(), callTarget, argumentCountIncludingThis, registerOffset, prediction);
1105         return;
1106     }
1107     
1108     unsigned nextOffset = m_currentIndex + instructionSize;
1109     
1110     OpInfo callOpInfo;
1111     
1112     if (handleInlining(callTarget, result, callLinkStatus, registerOffset, virtualRegisterForArgument(0, registerOffset), VirtualRegister(), 0, argumentCountIncludingThis, nextOffset, op, kind, prediction)) {
1113         if (m_graph.compilation())
1114             m_graph.compilation()->noticeInlinedCall();
1115         return;
1116     }
1117     
1118     addCall(result, op, callOpInfo, callTarget, argumentCountIncludingThis, registerOffset, prediction);
1119 }
1120
1121 void ByteCodeParser::handleVarargsCall(Instruction* pc, NodeType op, CodeSpecializationKind kind)
1122 {
1123     ASSERT(OPCODE_LENGTH(op_call_varargs) == OPCODE_LENGTH(op_construct_varargs));
1124     
1125     int result = pc[1].u.operand;
1126     int callee = pc[2].u.operand;
1127     int thisReg = pc[3].u.operand;
1128     int arguments = pc[4].u.operand;
1129     int firstFreeReg = pc[5].u.operand;
1130     int firstVarArgOffset = pc[6].u.operand;
1131     
1132     SpeculatedType prediction = getPrediction();
1133     
1134     Node* callTarget = get(VirtualRegister(callee));
1135     
1136     CallLinkStatus callLinkStatus = CallLinkStatus::computeFor(
1137         m_inlineStackTop->m_profiledBlock, currentCodeOrigin(),
1138         m_inlineStackTop->m_callLinkInfos, m_callContextMap);
1139     if (callTarget->isCellConstant())
1140         callLinkStatus.setProvenConstantCallee(CallVariant(callTarget->asCell()));
1141     
1142     if (Options::verboseDFGByteCodeParsing())
1143         dataLog("    Varargs call link status at ", currentCodeOrigin(), ": ", callLinkStatus, "\n");
1144     
1145     if (callLinkStatus.canOptimize()
1146         && handleInlining(callTarget, result, callLinkStatus, firstFreeReg, VirtualRegister(thisReg), VirtualRegister(arguments), firstVarArgOffset, 0, m_currentIndex + OPCODE_LENGTH(op_call_varargs), op, InlineCallFrame::varargsKindFor(kind), prediction)) {
1147         if (m_graph.compilation())
1148             m_graph.compilation()->noticeInlinedCall();
1149         return;
1150     }
1151     
1152     CallVarargsData* data = m_graph.m_callVarargsData.add();
1153     data->firstVarArgOffset = firstVarArgOffset;
1154     
1155     Node* thisChild = get(VirtualRegister(thisReg));
1156     
1157     Node* call = addToGraph(op, OpInfo(data), OpInfo(prediction), callTarget, get(VirtualRegister(arguments)), thisChild);
1158     VirtualRegister resultReg(result);
1159     if (resultReg.isValid())
1160         set(resultReg, call);
1161 }
1162
1163 void ByteCodeParser::emitFunctionChecks(CallVariant callee, Node* callTarget, VirtualRegister thisArgumentReg)
1164 {
1165     Node* thisArgument;
1166     if (thisArgumentReg.isValid())
1167         thisArgument = get(thisArgumentReg);
1168     else
1169         thisArgument = 0;
1170
1171     JSCell* calleeCell;
1172     Node* callTargetForCheck;
1173     if (callee.isClosureCall()) {
1174         calleeCell = callee.executable();
1175         callTargetForCheck = addToGraph(GetExecutable, callTarget);
1176     } else {
1177         calleeCell = callee.nonExecutableCallee();
1178         callTargetForCheck = callTarget;
1179     }
1180     
1181     ASSERT(calleeCell);
1182     addToGraph(CheckCell, OpInfo(m_graph.freeze(calleeCell)), callTargetForCheck, thisArgument);
1183 }
1184
1185 void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis)
1186 {
1187     for (int i = 0; i < argumentCountIncludingThis; ++i)
1188         addToGraph(Phantom, get(virtualRegisterForArgument(i, registerOffset)));
1189 }
1190
1191 unsigned ByteCodeParser::inliningCost(CallVariant callee, int argumentCountIncludingThis, CodeSpecializationKind kind)
1192 {
1193     if (verbose)
1194         dataLog("Considering inlining ", callee, " into ", currentCodeOrigin(), "\n");
1195     
1196     if (m_hasDebuggerEnabled) {
1197         if (verbose)
1198             dataLog("    Failing because the debugger is in use.\n");
1199         return UINT_MAX;
1200     }
1201
1202     FunctionExecutable* executable = callee.functionExecutable();
1203     if (!executable) {
1204         if (verbose)
1205             dataLog("    Failing because there is no function executable.\n");
1206         return UINT_MAX;
1207     }
1208     
1209     // Does the number of arguments we're passing match the arity of the target? We currently
1210     // inline only if the number of arguments passed is greater than or equal to the number
1211     // arguments expected.
1212     if (static_cast<int>(executable->parameterCount()) + 1 > argumentCountIncludingThis) {
1213         if (verbose)
1214             dataLog("    Failing because of arity mismatch.\n");
1215         return UINT_MAX;
1216     }
1217     
1218     // Do we have a code block, and does the code block's size match the heuristics/requirements for
1219     // being an inline candidate? We might not have a code block (1) if code was thrown away,
1220     // (2) if we simply hadn't actually made this call yet or (3) code is a builtin function and
1221     // specialization kind is construct. In the former 2 cases, we could still theoretically attempt
1222     // to inline it if we had a static proof of what was being called; this might happen for example
1223     // if you call a global function, where watchpointing gives us static information. Overall,
1224     // it's a rare case because we expect that any hot callees would have already been compiled.
1225     CodeBlock* codeBlock = executable->baselineCodeBlockFor(kind);
1226     if (!codeBlock) {
1227         if (verbose)
1228             dataLog("    Failing because no code block available.\n");
1229         return UINT_MAX;
1230     }
1231     CapabilityLevel capabilityLevel = inlineFunctionForCapabilityLevel(
1232         codeBlock, kind, callee.isClosureCall());
1233     if (verbose) {
1234         dataLog("    Kind: ", kind, "\n");
1235         dataLog("    Is closure call: ", callee.isClosureCall(), "\n");
1236         dataLog("    Capability level: ", capabilityLevel, "\n");
1237         dataLog("    Might inline function: ", mightInlineFunctionFor(codeBlock, kind), "\n");
1238         dataLog("    Might compile function: ", mightCompileFunctionFor(codeBlock, kind), "\n");
1239         dataLog("    Is supported for inlining: ", isSupportedForInlining(codeBlock), "\n");
1240         dataLog("    Needs activation: ", codeBlock->ownerExecutable()->needsActivation(), "\n");
1241         dataLog("    Is inlining candidate: ", codeBlock->ownerExecutable()->isInliningCandidate(), "\n");
1242     }
1243     if (!canInline(capabilityLevel)) {
1244         if (verbose)
1245             dataLog("    Failing because the function is not inlineable.\n");
1246         return UINT_MAX;
1247     }
1248     
1249     // Check if the caller is already too large. We do this check here because that's just
1250     // where we happen to also have the callee's code block, and we want that for the
1251     // purpose of unsetting SABI.
1252     if (!isSmallEnoughToInlineCodeInto(m_codeBlock)) {
1253         codeBlock->m_shouldAlwaysBeInlined = false;
1254         if (verbose)
1255             dataLog("    Failing because the caller is too large.\n");
1256         return UINT_MAX;
1257     }
1258     
1259     // FIXME: this should be better at predicting how much bloat we will introduce by inlining
1260     // this function.
1261     // https://bugs.webkit.org/show_bug.cgi?id=127627
1262     
1263     // FIXME: We currently inline functions that have run in LLInt but not in Baseline. These
1264     // functions have very low fidelity profiling, and presumably they weren't very hot if they
1265     // haven't gotten to Baseline yet. Consider not inlining these functions.
1266     // https://bugs.webkit.org/show_bug.cgi?id=145503
1267     
1268     // Have we exceeded inline stack depth, or are we trying to inline a recursive call to
1269     // too many levels? If either of these are detected, then don't inline. We adjust our
1270     // heuristics if we are dealing with a function that cannot otherwise be compiled.
1271     
1272     unsigned depth = 0;
1273     unsigned recursion = 0;
1274     
1275     for (InlineStackEntry* entry = m_inlineStackTop; entry; entry = entry->m_caller) {
1276         ++depth;
1277         if (depth >= Options::maximumInliningDepth()) {
1278             if (verbose)
1279                 dataLog("    Failing because depth exceeded.\n");
1280             return UINT_MAX;
1281         }
1282         
1283         if (entry->executable() == executable) {
1284             ++recursion;
1285             if (recursion >= Options::maximumInliningRecursion()) {
1286                 if (verbose)
1287                     dataLog("    Failing because recursion detected.\n");
1288                 return UINT_MAX;
1289             }
1290         }
1291     }
1292     
1293     if (verbose)
1294         dataLog("    Inlining should be possible.\n");
1295     
1296     // It might be possible to inline.
1297     return codeBlock->instructionCount();
1298 }
1299
1300 template<typename ChecksFunctor>
1301 void ByteCodeParser::inlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, CallerLinkability callerLinkability, const ChecksFunctor& insertChecks)
1302 {
1303     CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
1304     
1305     ASSERT(inliningCost(callee, argumentCountIncludingThis, specializationKind) != UINT_MAX);
1306     
1307     CodeBlock* codeBlock = callee.functionExecutable()->baselineCodeBlockFor(specializationKind);
1308     insertChecks(codeBlock);
1309
1310     // FIXME: Don't flush constants!
1311     
1312     int inlineCallFrameStart = m_inlineStackTop->remapOperand(VirtualRegister(registerOffset)).offset() + JSStack::CallFrameHeaderSize;
1313     
1314     ensureLocals(
1315         VirtualRegister(inlineCallFrameStart).toLocal() + 1 +
1316         JSStack::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters);
1317     
1318     size_t argumentPositionStart = m_graph.m_argumentPositions.size();
1319
1320     VirtualRegister resultReg(resultOperand);
1321     if (resultReg.isValid())
1322         resultReg = m_inlineStackTop->remapOperand(resultReg);
1323     
1324     InlineStackEntry inlineStackEntry(
1325         this, codeBlock, codeBlock, m_graph.lastBlock(), callee.function(), resultReg,
1326         (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind);
1327     
1328     // This is where the actual inlining really happens.
1329     unsigned oldIndex = m_currentIndex;
1330     m_currentIndex = 0;
1331
1332     InlineVariableData inlineVariableData;
1333     inlineVariableData.inlineCallFrame = m_inlineStackTop->m_inlineCallFrame;
1334     inlineVariableData.argumentPositionStart = argumentPositionStart;
1335     inlineVariableData.calleeVariable = 0;
1336     
1337     RELEASE_ASSERT(
1338         m_inlineStackTop->m_inlineCallFrame->isClosureCall
1339         == callee.isClosureCall());
1340     if (callee.isClosureCall()) {
1341         VariableAccessData* calleeVariable =
1342             set(VirtualRegister(JSStack::Callee), callTargetNode, ImmediateNakedSet)->variableAccessData();
1343         
1344         calleeVariable->mergeShouldNeverUnbox(true);
1345         
1346         inlineVariableData.calleeVariable = calleeVariable;
1347     }
1348     
1349     m_graph.m_inlineVariableData.append(inlineVariableData);
1350     
1351     parseCodeBlock();
1352     clearCaches(); // Reset our state now that we're back to the outer code.
1353     
1354     m_currentIndex = oldIndex;
1355     
1356     // If the inlined code created some new basic blocks, then we have linking to do.
1357     if (inlineStackEntry.m_callsiteBlockHead != m_graph.lastBlock()) {
1358         
1359         ASSERT(!inlineStackEntry.m_unlinkedBlocks.isEmpty());
1360         if (inlineStackEntry.m_callsiteBlockHeadNeedsLinking)
1361             linkBlock(inlineStackEntry.m_callsiteBlockHead, inlineStackEntry.m_blockLinkingTargets);
1362         else
1363             ASSERT(inlineStackEntry.m_callsiteBlockHead->isLinked);
1364         
1365         if (callerLinkability == CallerDoesNormalLinking)
1366             cancelLinkingForBlock(inlineStackEntry.m_caller, inlineStackEntry.m_callsiteBlockHead);
1367         
1368         linkBlocks(inlineStackEntry.m_unlinkedBlocks, inlineStackEntry.m_blockLinkingTargets);
1369     } else
1370         ASSERT(inlineStackEntry.m_unlinkedBlocks.isEmpty());
1371     
1372     BasicBlock* lastBlock = m_graph.lastBlock();
1373     // If there was a return, but no early returns, then we're done. We allow parsing of
1374     // the caller to continue in whatever basic block we're in right now.
1375     if (!inlineStackEntry.m_didEarlyReturn && inlineStackEntry.m_didReturn) {
1376         if (Options::verboseDFGByteCodeParsing())
1377             dataLog("    Allowing parsing to continue in last inlined block.\n");
1378         
1379         ASSERT(lastBlock->isEmpty() || !lastBlock->terminal());
1380         
1381         // If we created new blocks then the last block needs linking, but in the
1382         // caller. It doesn't need to be linked to, but it needs outgoing links.
1383         if (!inlineStackEntry.m_unlinkedBlocks.isEmpty()) {
1384             // For debugging purposes, set the bytecodeBegin. Note that this doesn't matter
1385             // for release builds because this block will never serve as a potential target
1386             // in the linker's binary search.
1387             if (Options::verboseDFGByteCodeParsing())
1388                 dataLog("        Repurposing last block from ", lastBlock->bytecodeBegin, " to ", m_currentIndex, "\n");
1389             lastBlock->bytecodeBegin = m_currentIndex;
1390             if (callerLinkability == CallerDoesNormalLinking) {
1391                 if (verbose)
1392                     dataLog("Adding unlinked block ", RawPointer(m_graph.lastBlock()), " (one return)\n");
1393                 m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.lastBlock()));
1394             }
1395         }
1396         
1397         m_currentBlock = m_graph.lastBlock();
1398         return;
1399     }
1400     
1401     if (Options::verboseDFGByteCodeParsing())
1402         dataLog("    Creating new block after inlining.\n");
1403
1404     // If we get to this point then all blocks must end in some sort of terminals.
1405     ASSERT(lastBlock->terminal());
1406
1407     // Need to create a new basic block for the continuation at the caller.
1408     RefPtr<BasicBlock> block = adoptRef(new BasicBlock(nextOffset, m_numArguments, m_numLocals, PNaN));
1409
1410     // Link the early returns to the basic block we're about to create.
1411     for (size_t i = 0; i < inlineStackEntry.m_unlinkedBlocks.size(); ++i) {
1412         if (!inlineStackEntry.m_unlinkedBlocks[i].m_needsEarlyReturnLinking)
1413             continue;
1414         BasicBlock* blockToLink = inlineStackEntry.m_unlinkedBlocks[i].m_block;
1415         ASSERT(!blockToLink->isLinked);
1416         Node* node = blockToLink->terminal();
1417         ASSERT(node->op() == Jump);
1418         ASSERT(!node->targetBlock());
1419         node->targetBlock() = block.get();
1420         inlineStackEntry.m_unlinkedBlocks[i].m_needsEarlyReturnLinking = false;
1421         if (verbose)
1422             dataLog("Marking ", RawPointer(blockToLink), " as linked (jumps to return)\n");
1423         blockToLink->didLink();
1424     }
1425     
1426     m_currentBlock = block.get();
1427     ASSERT(m_inlineStackTop->m_caller->m_blockLinkingTargets.isEmpty() || m_inlineStackTop->m_caller->m_blockLinkingTargets.last()->bytecodeBegin < nextOffset);
1428     if (verbose)
1429         dataLog("Adding unlinked block ", RawPointer(block.get()), " (many returns)\n");
1430     if (callerLinkability == CallerDoesNormalLinking) {
1431         m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(block.get()));
1432         m_inlineStackTop->m_caller->m_blockLinkingTargets.append(block.get());
1433     }
1434     m_graph.appendBlock(block);
1435     prepareToParseBlock();
1436 }
1437
1438 void ByteCodeParser::cancelLinkingForBlock(InlineStackEntry* inlineStackEntry, BasicBlock* block)
1439 {
1440     // It's possible that the callsite block head is not owned by the caller.
1441     if (!inlineStackEntry->m_unlinkedBlocks.isEmpty()) {
1442         // It's definitely owned by the caller, because the caller created new blocks.
1443         // Assert that this all adds up.
1444         ASSERT_UNUSED(block, inlineStackEntry->m_unlinkedBlocks.last().m_block == block);
1445         ASSERT(inlineStackEntry->m_unlinkedBlocks.last().m_needsNormalLinking);
1446         inlineStackEntry->m_unlinkedBlocks.last().m_needsNormalLinking = false;
1447     } else {
1448         // It's definitely not owned by the caller. Tell the caller that he does not
1449         // need to link his callsite block head, because we did it for him.
1450         ASSERT(inlineStackEntry->m_callsiteBlockHeadNeedsLinking);
1451         ASSERT_UNUSED(block, inlineStackEntry->m_callsiteBlockHead == block);
1452         inlineStackEntry->m_callsiteBlockHeadNeedsLinking = false;
1453     }
1454 }
1455
1456 template<typename ChecksFunctor>
1457 bool ByteCodeParser::attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, CallerLinkability callerLinkability, SpeculatedType prediction, unsigned& inliningBalance, const ChecksFunctor& insertChecks)
1458 {
1459     CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
1460     
1461     if (!inliningBalance)
1462         return false;
1463     
1464     bool didInsertChecks = false;
1465     auto insertChecksWithAccounting = [&] () {
1466         insertChecks(nullptr);
1467         didInsertChecks = true;
1468     };
1469     
1470     if (verbose)
1471         dataLog("    Considering callee ", callee, "\n");
1472     
1473     // Intrinsics and internal functions can only be inlined if we're not doing varargs. This is because
1474     // we currently don't have any way of getting profiling information for arguments to non-JS varargs
1475     // calls. The prediction propagator won't be of any help because LoadVarargs obscures the data flow,
1476     // and there are no callsite value profiles and native function won't have callee value profiles for
1477     // those arguments. Even worse, if the intrinsic decides to exit, it won't really have anywhere to
1478     // exit to: LoadVarargs is effectful and it's part of the op_call_varargs, so we can't exit without
1479     // calling LoadVarargs twice.
1480     if (!InlineCallFrame::isVarargs(kind)) {
1481         if (InternalFunction* function = callee.internalFunction()) {
1482             if (handleConstantInternalFunction(resultOperand, function, registerOffset, argumentCountIncludingThis, specializationKind, insertChecksWithAccounting)) {
1483                 RELEASE_ASSERT(didInsertChecks);
1484                 addToGraph(Phantom, callTargetNode);
1485                 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
1486                 inliningBalance--;
1487                 return true;
1488             }
1489             RELEASE_ASSERT(!didInsertChecks);
1490             return false;
1491         }
1492     
1493         Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
1494         if (intrinsic != NoIntrinsic) {
1495             if (handleIntrinsic(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
1496                 RELEASE_ASSERT(didInsertChecks);
1497                 addToGraph(Phantom, callTargetNode);
1498                 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
1499                 inliningBalance--;
1500                 return true;
1501             }
1502             RELEASE_ASSERT(!didInsertChecks);
1503             return false;
1504         }
1505     }
1506     
1507     unsigned myInliningCost = inliningCost(callee, argumentCountIncludingThis, specializationKind);
1508     if (myInliningCost > inliningBalance)
1509         return false;
1510
1511     Instruction* savedCurrentInstruction = m_currentInstruction;
1512     inlineCall(callTargetNode, resultOperand, callee, registerOffset, argumentCountIncludingThis, nextOffset, kind, callerLinkability, insertChecks);
1513     inliningBalance -= myInliningCost;
1514     m_currentInstruction = savedCurrentInstruction;
1515     return true;
1516 }
1517
1518 bool ByteCodeParser::handleInlining(
1519     Node* callTargetNode, int resultOperand, const CallLinkStatus& callLinkStatus,
1520     int registerOffsetOrFirstFreeReg, VirtualRegister thisArgument,
1521     VirtualRegister argumentsArgument, unsigned argumentsOffset, int argumentCountIncludingThis,
1522     unsigned nextOffset, NodeType callOp, InlineCallFrame::Kind kind, SpeculatedType prediction)
1523 {
1524     if (verbose) {
1525         dataLog("Handling inlining...\n");
1526         dataLog("Stack: ", currentCodeOrigin(), "\n");
1527     }
1528     CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
1529     
1530     if (!callLinkStatus.size()) {
1531         if (verbose)
1532             dataLog("Bailing inlining.\n");
1533         return false;
1534     }
1535     
1536     if (InlineCallFrame::isVarargs(kind)
1537         && callLinkStatus.maxNumArguments() > Options::maximumVarargsForInlining()) {
1538         if (verbose)
1539             dataLog("Bailing inlining because of varargs.\n");
1540         return false;
1541     }
1542         
1543     unsigned inliningBalance = Options::maximumFunctionForCallInlineCandidateInstructionCount();
1544     if (specializationKind == CodeForConstruct)
1545         inliningBalance = std::min(inliningBalance, Options::maximumFunctionForConstructInlineCandidateInstructionCount());
1546     if (callLinkStatus.isClosureCall())
1547         inliningBalance = std::min(inliningBalance, Options::maximumFunctionForClosureCallInlineCandidateInstructionCount());
1548     
1549     // First check if we can avoid creating control flow. Our inliner does some CFG
1550     // simplification on the fly and this helps reduce compile times, but we can only leverage
1551     // this in cases where we don't need control flow diamonds to check the callee.
1552     if (!callLinkStatus.couldTakeSlowPath() && callLinkStatus.size() == 1) {
1553         int registerOffset;
1554         
1555         // Only used for varargs calls.
1556         unsigned mandatoryMinimum = 0;
1557         unsigned maxNumArguments = 0;
1558
1559         if (InlineCallFrame::isVarargs(kind)) {
1560             if (FunctionExecutable* functionExecutable = callLinkStatus[0].functionExecutable())
1561                 mandatoryMinimum = functionExecutable->parameterCount();
1562             else
1563                 mandatoryMinimum = 0;
1564             
1565             // includes "this"
1566             maxNumArguments = std::max(
1567                 callLinkStatus.maxNumArguments(),
1568                 mandatoryMinimum + 1);
1569             
1570             // We sort of pretend that this *is* the number of arguments that were passed.
1571             argumentCountIncludingThis = maxNumArguments;
1572             
1573             registerOffset = registerOffsetOrFirstFreeReg + 1;
1574             registerOffset -= maxNumArguments; // includes "this"
1575             registerOffset -= JSStack::CallFrameHeaderSize;
1576             registerOffset = -WTF::roundUpToMultipleOf(
1577                 stackAlignmentRegisters(),
1578                 -registerOffset);
1579         } else
1580             registerOffset = registerOffsetOrFirstFreeReg;
1581         
1582         bool result = attemptToInlineCall(
1583             callTargetNode, resultOperand, callLinkStatus[0], registerOffset,
1584             argumentCountIncludingThis, nextOffset, kind, CallerDoesNormalLinking, prediction,
1585             inliningBalance, [&] (CodeBlock* codeBlock) {
1586                 emitFunctionChecks(callLinkStatus[0], callTargetNode, thisArgument);
1587
1588                 // If we have a varargs call, we want to extract the arguments right now.
1589                 if (InlineCallFrame::isVarargs(kind)) {
1590                     int remappedRegisterOffset =
1591                         m_inlineStackTop->remapOperand(VirtualRegister(registerOffset)).offset();
1592                     
1593                     ensureLocals(VirtualRegister(remappedRegisterOffset).toLocal());
1594                     
1595                     int argumentStart = registerOffset + JSStack::CallFrameHeaderSize;
1596                     int remappedArgumentStart =
1597                         m_inlineStackTop->remapOperand(VirtualRegister(argumentStart)).offset();
1598
1599                     LoadVarargsData* data = m_graph.m_loadVarargsData.add();
1600                     data->start = VirtualRegister(remappedArgumentStart + 1);
1601                     data->count = VirtualRegister(remappedRegisterOffset + JSStack::ArgumentCount);
1602                     data->offset = argumentsOffset;
1603                     data->limit = maxNumArguments;
1604                     data->mandatoryMinimum = mandatoryMinimum;
1605             
1606                     addToGraph(LoadVarargs, OpInfo(data), get(argumentsArgument));
1607
1608                     // LoadVarargs may OSR exit. Hence, we need to keep alive callTargetNode, thisArgument
1609                     // and argumentsArgument for the baseline JIT. However, we only need a Phantom for
1610                     // callTargetNode because the other 2 are still in use and alive at this point.
1611                     addToGraph(Phantom, callTargetNode);
1612
1613                     // In DFG IR before SSA, we cannot insert control flow between after the
1614                     // LoadVarargs and the last SetArgument. This isn't a problem once we get to DFG
1615                     // SSA. Fortunately, we also have other reasons for not inserting control flow
1616                     // before SSA.
1617             
1618                     VariableAccessData* countVariable = newVariableAccessData(
1619                         VirtualRegister(remappedRegisterOffset + JSStack::ArgumentCount));
1620                     // This is pretty lame, but it will force the count to be flushed as an int. This doesn't
1621                     // matter very much, since our use of a SetArgument and Flushes for this local slot is
1622                     // mostly just a formality.
1623                     countVariable->predict(SpecInt32);
1624                     countVariable->mergeIsProfitableToUnbox(true);
1625                     Node* setArgumentCount = addToGraph(SetArgument, OpInfo(countVariable));
1626                     m_currentBlock->variablesAtTail.setOperand(countVariable->local(), setArgumentCount);
1627
1628                     set(VirtualRegister(argumentStart), get(thisArgument), ImmediateNakedSet);
1629                     for (unsigned argument = 1; argument < maxNumArguments; ++argument) {
1630                         VariableAccessData* variable = newVariableAccessData(
1631                             VirtualRegister(remappedArgumentStart + argument));
1632                         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.
1633                         
1634                         // For a while it had been my intention to do things like this inside the
1635                         // prediction injection phase. But in this case it's really best to do it here,
1636                         // because it's here that we have access to the variable access datas for the
1637                         // inlining we're about to do.
1638                         //
1639                         // Something else that's interesting here is that we'd really love to get
1640                         // predictions from the arguments loaded at the callsite, rather than the
1641                         // arguments received inside the callee. But that probably won't matter for most
1642                         // calls.
1643                         if (codeBlock && argument < static_cast<unsigned>(codeBlock->numParameters())) {
1644                             ConcurrentJITLocker locker(codeBlock->m_lock);
1645                             if (ValueProfile* profile = codeBlock->valueProfileForArgument(argument))
1646                                 variable->predict(profile->computeUpdatedPrediction(locker));
1647                         }
1648                         
1649                         Node* setArgument = addToGraph(SetArgument, OpInfo(variable));
1650                         m_currentBlock->variablesAtTail.setOperand(variable->local(), setArgument);
1651                     }
1652                 }
1653             });
1654         if (verbose) {
1655             dataLog("Done inlining (simple).\n");
1656             dataLog("Stack: ", currentCodeOrigin(), "\n");
1657             dataLog("Result: ", result, "\n");
1658         }
1659         return result;
1660     }
1661     
1662     // We need to create some kind of switch over callee. For now we only do this if we believe that
1663     // we're in the top tier. We have two reasons for this: first, it provides us an opportunity to
1664     // do more detailed polyvariant/polymorphic profiling; and second, it reduces compile times in
1665     // the DFG. And by polyvariant profiling we mean polyvariant profiling of *this* call. Note that
1666     // we could improve that aspect of this by doing polymorphic inlining but having the profiling
1667     // also.
1668     if (!isFTL(m_graph.m_plan.mode) || !Options::enablePolymorphicCallInlining()
1669         || InlineCallFrame::isVarargs(kind)) {
1670         if (verbose) {
1671             dataLog("Bailing inlining (hard).\n");
1672             dataLog("Stack: ", currentCodeOrigin(), "\n");
1673         }
1674         return false;
1675     }
1676     
1677     unsigned oldOffset = m_currentIndex;
1678     
1679     bool allAreClosureCalls = true;
1680     bool allAreDirectCalls = true;
1681     for (unsigned i = callLinkStatus.size(); i--;) {
1682         if (callLinkStatus[i].isClosureCall())
1683             allAreDirectCalls = false;
1684         else
1685             allAreClosureCalls = false;
1686     }
1687     
1688     Node* thingToSwitchOn;
1689     if (allAreDirectCalls)
1690         thingToSwitchOn = callTargetNode;
1691     else if (allAreClosureCalls)
1692         thingToSwitchOn = addToGraph(GetExecutable, callTargetNode);
1693     else {
1694         // FIXME: We should be able to handle this case, but it's tricky and we don't know of cases
1695         // where it would be beneficial. It might be best to handle these cases as if all calls were
1696         // closure calls.
1697         // https://bugs.webkit.org/show_bug.cgi?id=136020
1698         if (verbose) {
1699             dataLog("Bailing inlining (mix).\n");
1700             dataLog("Stack: ", currentCodeOrigin(), "\n");
1701         }
1702         return false;
1703     }
1704     
1705     if (verbose) {
1706         dataLog("Doing hard inlining...\n");
1707         dataLog("Stack: ", currentCodeOrigin(), "\n");
1708     }
1709     
1710     int registerOffset = registerOffsetOrFirstFreeReg;
1711     
1712     // This makes me wish that we were in SSA all the time. We need to pick a variable into which to
1713     // store the callee so that it will be accessible to all of the blocks we're about to create. We
1714     // get away with doing an immediate-set here because we wouldn't have performed any side effects
1715     // yet.
1716     if (verbose)
1717         dataLog("Register offset: ", registerOffset);
1718     VirtualRegister calleeReg(registerOffset + JSStack::Callee);
1719     calleeReg = m_inlineStackTop->remapOperand(calleeReg);
1720     if (verbose)
1721         dataLog("Callee is going to be ", calleeReg, "\n");
1722     setDirect(calleeReg, callTargetNode, ImmediateSetWithFlush);
1723     
1724     SwitchData& data = *m_graph.m_switchData.add();
1725     data.kind = SwitchCell;
1726     addToGraph(Switch, OpInfo(&data), thingToSwitchOn);
1727     
1728     BasicBlock* originBlock = m_currentBlock;
1729     if (verbose)
1730         dataLog("Marking ", RawPointer(originBlock), " as linked (origin of poly inline)\n");
1731     originBlock->didLink();
1732     cancelLinkingForBlock(m_inlineStackTop, originBlock);
1733     
1734     // Each inlined callee will have a landing block that it returns at. They should all have jumps
1735     // to the continuation block, which we create last.
1736     Vector<BasicBlock*> landingBlocks;
1737     
1738     // We may force this true if we give up on inlining any of the edges.
1739     bool couldTakeSlowPath = callLinkStatus.couldTakeSlowPath();
1740     
1741     if (verbose)
1742         dataLog("About to loop over functions at ", currentCodeOrigin(), ".\n");
1743     
1744     for (unsigned i = 0; i < callLinkStatus.size(); ++i) {
1745         m_currentIndex = oldOffset;
1746         RefPtr<BasicBlock> block = adoptRef(new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, PNaN));
1747         m_currentBlock = block.get();
1748         m_graph.appendBlock(block);
1749         prepareToParseBlock();
1750         
1751         Node* myCallTargetNode = getDirect(calleeReg);
1752         
1753         bool inliningResult = attemptToInlineCall(
1754             myCallTargetNode, resultOperand, callLinkStatus[i], registerOffset,
1755             argumentCountIncludingThis, nextOffset, kind, CallerLinksManually, prediction,
1756             inliningBalance, [&] (CodeBlock*) { });
1757         
1758         if (!inliningResult) {
1759             // That failed so we let the block die. Nothing interesting should have been added to
1760             // the block. We also give up on inlining any of the (less frequent) callees.
1761             ASSERT(m_currentBlock == block.get());
1762             ASSERT(m_graph.m_blocks.last() == block);
1763             m_graph.killBlockAndItsContents(block.get());
1764             m_graph.m_blocks.removeLast();
1765             
1766             // The fact that inlining failed means we need a slow path.
1767             couldTakeSlowPath = true;
1768             break;
1769         }
1770         
1771         JSCell* thingToCaseOn;
1772         if (allAreDirectCalls)
1773             thingToCaseOn = callLinkStatus[i].nonExecutableCallee();
1774         else {
1775             ASSERT(allAreClosureCalls);
1776             thingToCaseOn = callLinkStatus[i].executable();
1777         }
1778         data.cases.append(SwitchCase(m_graph.freeze(thingToCaseOn), block.get()));
1779         m_currentIndex = nextOffset;
1780         processSetLocalQueue(); // This only comes into play for intrinsics, since normal inlined code will leave an empty queue.
1781         addToGraph(Jump);
1782         if (verbose)
1783             dataLog("Marking ", RawPointer(m_currentBlock), " as linked (tail of poly inlinee)\n");
1784         m_currentBlock->didLink();
1785         landingBlocks.append(m_currentBlock);
1786
1787         if (verbose)
1788             dataLog("Finished inlining ", callLinkStatus[i], " at ", currentCodeOrigin(), ".\n");
1789     }
1790     
1791     RefPtr<BasicBlock> slowPathBlock = adoptRef(
1792         new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, PNaN));
1793     m_currentIndex = oldOffset;
1794     data.fallThrough = BranchTarget(slowPathBlock.get());
1795     m_graph.appendBlock(slowPathBlock);
1796     if (verbose)
1797         dataLog("Marking ", RawPointer(slowPathBlock.get()), " as linked (slow path block)\n");
1798     slowPathBlock->didLink();
1799     prepareToParseBlock();
1800     m_currentBlock = slowPathBlock.get();
1801     Node* myCallTargetNode = getDirect(calleeReg);
1802     if (couldTakeSlowPath) {
1803         addCall(
1804             resultOperand, callOp, OpInfo(), myCallTargetNode, argumentCountIncludingThis,
1805             registerOffset, prediction);
1806     } else {
1807         addToGraph(CheckBadCell);
1808         addToGraph(Phantom, myCallTargetNode);
1809         emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
1810         
1811         set(VirtualRegister(resultOperand), addToGraph(BottomValue));
1812     }
1813
1814     m_currentIndex = nextOffset;
1815     processSetLocalQueue();
1816     addToGraph(Jump);
1817     landingBlocks.append(m_currentBlock);
1818     
1819     RefPtr<BasicBlock> continuationBlock = adoptRef(
1820         new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, PNaN));
1821     m_graph.appendBlock(continuationBlock);
1822     if (verbose)
1823         dataLog("Adding unlinked block ", RawPointer(continuationBlock.get()), " (continuation)\n");
1824     m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(continuationBlock.get()));
1825     prepareToParseBlock();
1826     m_currentBlock = continuationBlock.get();
1827     
1828     for (unsigned i = landingBlocks.size(); i--;)
1829         landingBlocks[i]->terminal()->targetBlock() = continuationBlock.get();
1830     
1831     m_currentIndex = oldOffset;
1832     
1833     if (verbose) {
1834         dataLog("Done inlining (hard).\n");
1835         dataLog("Stack: ", currentCodeOrigin(), "\n");
1836     }
1837     return true;
1838 }
1839
1840 template<typename ChecksFunctor>
1841 bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis, const ChecksFunctor& insertChecks)
1842 {
1843     if (argumentCountIncludingThis == 1) { // Math.min()
1844         insertChecks();
1845         set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
1846         return true;
1847     }
1848      
1849     if (argumentCountIncludingThis == 2) { // Math.min(x)
1850         insertChecks();
1851         Node* result = get(VirtualRegister(virtualRegisterForArgument(1, registerOffset)));
1852         addToGraph(Phantom, Edge(result, NumberUse));
1853         set(VirtualRegister(resultOperand), result);
1854         return true;
1855     }
1856     
1857     if (argumentCountIncludingThis == 3) { // Math.min(x, y)
1858         insertChecks();
1859         set(VirtualRegister(resultOperand), addToGraph(op, get(virtualRegisterForArgument(1, registerOffset)), get(virtualRegisterForArgument(2, registerOffset))));
1860         return true;
1861     }
1862     
1863     // Don't handle >=3 arguments for now.
1864     return false;
1865 }
1866
1867 template<typename ChecksFunctor>
1868 bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks)
1869 {
1870     switch (intrinsic) {
1871     case AbsIntrinsic: {
1872         if (argumentCountIncludingThis == 1) { // Math.abs()
1873             insertChecks();
1874             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
1875             return true;
1876         }
1877
1878         if (!MacroAssembler::supportsFloatingPointAbs())
1879             return false;
1880
1881         insertChecks();
1882         Node* node = addToGraph(ArithAbs, get(virtualRegisterForArgument(1, registerOffset)));
1883         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
1884             node->mergeFlags(NodeMayOverflowInDFG);
1885         set(VirtualRegister(resultOperand), node);
1886         return true;
1887     }
1888
1889     case MinIntrinsic:
1890         return handleMinMax(resultOperand, ArithMin, registerOffset, argumentCountIncludingThis, insertChecks);
1891         
1892     case MaxIntrinsic:
1893         return handleMinMax(resultOperand, ArithMax, registerOffset, argumentCountIncludingThis, insertChecks);
1894
1895     case SqrtIntrinsic:
1896     case CosIntrinsic:
1897     case SinIntrinsic:
1898     case LogIntrinsic: {
1899         if (argumentCountIncludingThis == 1) {
1900             insertChecks();
1901             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
1902             return true;
1903         }
1904         
1905         switch (intrinsic) {
1906         case SqrtIntrinsic:
1907             insertChecks();
1908             set(VirtualRegister(resultOperand), addToGraph(ArithSqrt, get(virtualRegisterForArgument(1, registerOffset))));
1909             return true;
1910             
1911         case CosIntrinsic:
1912             insertChecks();
1913             set(VirtualRegister(resultOperand), addToGraph(ArithCos, get(virtualRegisterForArgument(1, registerOffset))));
1914             return true;
1915             
1916         case SinIntrinsic:
1917             insertChecks();
1918             set(VirtualRegister(resultOperand), addToGraph(ArithSin, get(virtualRegisterForArgument(1, registerOffset))));
1919             return true;
1920
1921         case LogIntrinsic:
1922             insertChecks();
1923             set(VirtualRegister(resultOperand), addToGraph(ArithLog, get(virtualRegisterForArgument(1, registerOffset))));
1924             return true;
1925             
1926         default:
1927             RELEASE_ASSERT_NOT_REACHED();
1928             return false;
1929         }
1930     }
1931
1932     case PowIntrinsic: {
1933         if (argumentCountIncludingThis < 3) {
1934             // Math.pow() and Math.pow(x) return NaN.
1935             insertChecks();
1936             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
1937             return true;
1938         }
1939         insertChecks();
1940         VirtualRegister xOperand = virtualRegisterForArgument(1, registerOffset);
1941         VirtualRegister yOperand = virtualRegisterForArgument(2, registerOffset);
1942         set(VirtualRegister(resultOperand), addToGraph(ArithPow, get(xOperand), get(yOperand)));
1943         return true;
1944     }
1945         
1946     case ArrayPushIntrinsic: {
1947         if (argumentCountIncludingThis != 2)
1948             return false;
1949         
1950         ArrayMode arrayMode = getArrayMode(m_currentInstruction[OPCODE_LENGTH(op_call) - 2].u.arrayProfile);
1951         if (!arrayMode.isJSArray())
1952             return false;
1953         switch (arrayMode.type()) {
1954         case Array::Int32:
1955         case Array::Double:
1956         case Array::Contiguous:
1957         case Array::ArrayStorage: {
1958             insertChecks();
1959             Node* arrayPush = addToGraph(ArrayPush, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
1960             set(VirtualRegister(resultOperand), arrayPush);
1961             
1962             return true;
1963         }
1964             
1965         default:
1966             return false;
1967         }
1968     }
1969         
1970     case ArrayPopIntrinsic: {
1971         if (argumentCountIncludingThis != 1)
1972             return false;
1973         
1974         ArrayMode arrayMode = getArrayMode(m_currentInstruction[OPCODE_LENGTH(op_call) - 2].u.arrayProfile);
1975         if (!arrayMode.isJSArray())
1976             return false;
1977         switch (arrayMode.type()) {
1978         case Array::Int32:
1979         case Array::Double:
1980         case Array::Contiguous:
1981         case Array::ArrayStorage: {
1982             insertChecks();
1983             Node* arrayPop = addToGraph(ArrayPop, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)));
1984             set(VirtualRegister(resultOperand), arrayPop);
1985             return true;
1986         }
1987             
1988         default:
1989             return false;
1990         }
1991     }
1992
1993     case CharCodeAtIntrinsic: {
1994         if (argumentCountIncludingThis != 2)
1995             return false;
1996
1997         insertChecks();
1998         VirtualRegister thisOperand = virtualRegisterForArgument(0, registerOffset);
1999         VirtualRegister indexOperand = virtualRegisterForArgument(1, registerOffset);
2000         Node* charCode = addToGraph(StringCharCodeAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), get(indexOperand));
2001
2002         set(VirtualRegister(resultOperand), charCode);
2003         return true;
2004     }
2005
2006     case CharAtIntrinsic: {
2007         if (argumentCountIncludingThis != 2)
2008             return false;
2009
2010         insertChecks();
2011         VirtualRegister thisOperand = virtualRegisterForArgument(0, registerOffset);
2012         VirtualRegister indexOperand = virtualRegisterForArgument(1, registerOffset);
2013         Node* charCode = addToGraph(StringCharAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), get(indexOperand));
2014
2015         set(VirtualRegister(resultOperand), charCode);
2016         return true;
2017     }
2018     case Clz32Intrinsic: {
2019         insertChecks();
2020         if (argumentCountIncludingThis == 1)
2021             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_graph.freeze(jsNumber(32)))));
2022         else {
2023             Node* operand = get(virtualRegisterForArgument(1, registerOffset));
2024             set(VirtualRegister(resultOperand), addToGraph(ArithClz32, operand));
2025         }
2026         return true;
2027     }
2028     case FromCharCodeIntrinsic: {
2029         if (argumentCountIncludingThis != 2)
2030             return false;
2031
2032         insertChecks();
2033         VirtualRegister indexOperand = virtualRegisterForArgument(1, registerOffset);
2034         Node* charCode = addToGraph(StringFromCharCode, get(indexOperand));
2035
2036         set(VirtualRegister(resultOperand), charCode);
2037
2038         return true;
2039     }
2040
2041     case RegExpExecIntrinsic: {
2042         if (argumentCountIncludingThis != 2)
2043             return false;
2044         
2045         insertChecks();
2046         Node* regExpExec = addToGraph(RegExpExec, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
2047         set(VirtualRegister(resultOperand), regExpExec);
2048         
2049         return true;
2050     }
2051         
2052     case RegExpTestIntrinsic: {
2053         if (argumentCountIncludingThis != 2)
2054             return false;
2055         
2056         insertChecks();
2057         Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
2058         set(VirtualRegister(resultOperand), regExpExec);
2059         
2060         return true;
2061     }
2062     case RoundIntrinsic: {
2063         if (argumentCountIncludingThis == 1) {
2064             insertChecks();
2065             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
2066             return true;
2067         }
2068         if (argumentCountIncludingThis == 2) {
2069             insertChecks();
2070             Node* operand = get(virtualRegisterForArgument(1, registerOffset));
2071             Node* roundNode = addToGraph(ArithRound, OpInfo(0), OpInfo(prediction), operand);
2072             set(VirtualRegister(resultOperand), roundNode);
2073             return true;
2074         }
2075         return false;
2076     }
2077     case IMulIntrinsic: {
2078         if (argumentCountIncludingThis != 3)
2079             return false;
2080         insertChecks();
2081         VirtualRegister leftOperand = virtualRegisterForArgument(1, registerOffset);
2082         VirtualRegister rightOperand = virtualRegisterForArgument(2, registerOffset);
2083         Node* left = get(leftOperand);
2084         Node* right = get(rightOperand);
2085         set(VirtualRegister(resultOperand), addToGraph(ArithIMul, left, right));
2086         return true;
2087     }
2088         
2089     case FRoundIntrinsic: {
2090         if (argumentCountIncludingThis != 2)
2091             return false;
2092         insertChecks();
2093         VirtualRegister operand = virtualRegisterForArgument(1, registerOffset);
2094         set(VirtualRegister(resultOperand), addToGraph(ArithFRound, get(operand)));
2095         return true;
2096     }
2097         
2098     case DFGTrueIntrinsic: {
2099         insertChecks();
2100         set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
2101         return true;
2102     }
2103         
2104     case OSRExitIntrinsic: {
2105         insertChecks();
2106         addToGraph(ForceOSRExit);
2107         set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
2108         return true;
2109     }
2110         
2111     case IsFinalTierIntrinsic: {
2112         insertChecks();
2113         set(VirtualRegister(resultOperand),
2114             jsConstant(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
2115         return true;
2116     }
2117         
2118     case SetInt32HeapPredictionIntrinsic: {
2119         insertChecks();
2120         for (int i = 1; i < argumentCountIncludingThis; ++i) {
2121             Node* node = get(virtualRegisterForArgument(i, registerOffset));
2122             if (node->hasHeapPrediction())
2123                 node->setHeapPrediction(SpecInt32);
2124         }
2125         set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
2126         return true;
2127     }
2128         
2129     case CheckInt32Intrinsic: {
2130         insertChecks();
2131         for (int i = 1; i < argumentCountIncludingThis; ++i) {
2132             Node* node = get(virtualRegisterForArgument(i, registerOffset));
2133             addToGraph(Phantom, Edge(node, Int32Use));
2134         }
2135         set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
2136         return true;
2137     }
2138         
2139     case FiatInt52Intrinsic: {
2140         if (argumentCountIncludingThis != 2)
2141             return false;
2142         insertChecks();
2143         VirtualRegister operand = virtualRegisterForArgument(1, registerOffset);
2144         if (enableInt52())
2145             set(VirtualRegister(resultOperand), addToGraph(FiatInt52, get(operand)));
2146         else
2147             set(VirtualRegister(resultOperand), get(operand));
2148         return true;
2149     }
2150         
2151     default:
2152         return false;
2153     }
2154 }
2155
2156 template<typename ChecksFunctor>
2157 bool ByteCodeParser::handleTypedArrayConstructor(
2158     int resultOperand, InternalFunction* function, int registerOffset,
2159     int argumentCountIncludingThis, TypedArrayType type, const ChecksFunctor& insertChecks)
2160 {
2161     if (!isTypedView(type))
2162         return false;
2163     
2164     if (function->classInfo() != constructorClassInfoForType(type))
2165         return false;
2166     
2167     if (function->globalObject() != m_inlineStackTop->m_codeBlock->globalObject())
2168         return false;
2169     
2170     // We only have an intrinsic for the case where you say:
2171     //
2172     // new FooArray(blah);
2173     //
2174     // Of course, 'blah' could be any of the following:
2175     //
2176     // - Integer, indicating that you want to allocate an array of that length.
2177     //   This is the thing we're hoping for, and what we can actually do meaningful
2178     //   optimizations for.
2179     //
2180     // - Array buffer, indicating that you want to create a view onto that _entire_
2181     //   buffer.
2182     //
2183     // - Non-buffer object, indicating that you want to create a copy of that
2184     //   object by pretending that it quacks like an array.
2185     //
2186     // - Anything else, indicating that you want to have an exception thrown at
2187     //   you.
2188     //
2189     // The intrinsic, NewTypedArray, will behave as if it could do any of these
2190     // things up until we do Fixup. Thereafter, if child1 (i.e. 'blah') is
2191     // predicted Int32, then we lock it in as a normal typed array allocation.
2192     // Otherwise, NewTypedArray turns into a totally opaque function call that
2193     // may clobber the world - by virtue of it accessing properties on what could
2194     // be an object.
2195     //
2196     // Note that although the generic form of NewTypedArray sounds sort of awful,
2197     // it is actually quite likely to be more efficient than a fully generic
2198     // Construct. So, we might want to think about making NewTypedArray variadic,
2199     // or else making Construct not super slow.
2200     
2201     if (argumentCountIncludingThis != 2)
2202         return false;
2203
2204     insertChecks();
2205     set(VirtualRegister(resultOperand),
2206         addToGraph(NewTypedArray, OpInfo(type), get(virtualRegisterForArgument(1, registerOffset))));
2207     return true;
2208 }
2209
2210 template<typename ChecksFunctor>
2211 bool ByteCodeParser::handleConstantInternalFunction(
2212     int resultOperand, InternalFunction* function, int registerOffset,
2213     int argumentCountIncludingThis, CodeSpecializationKind kind, const ChecksFunctor& insertChecks)
2214 {
2215     if (verbose)
2216         dataLog("    Handling constant internal function ", JSValue(function), "\n");
2217     
2218     // If we ever find that we have a lot of internal functions that we specialize for,
2219     // then we should probably have some sort of hashtable dispatch, or maybe even
2220     // dispatch straight through the MethodTable of the InternalFunction. But for now,
2221     // it seems that this case is hit infrequently enough, and the number of functions
2222     // we know about is small enough, that having just a linear cascade of if statements
2223     // is good enough.
2224     
2225     if (function->classInfo() == ArrayConstructor::info()) {
2226         if (function->globalObject() != m_inlineStackTop->m_codeBlock->globalObject())
2227             return false;
2228         
2229         insertChecks();
2230         if (argumentCountIncludingThis == 2) {
2231             set(VirtualRegister(resultOperand),
2232                 addToGraph(NewArrayWithSize, OpInfo(ArrayWithUndecided), get(virtualRegisterForArgument(1, registerOffset))));
2233             return true;
2234         }
2235         
2236         // FIXME: Array constructor should use "this" as newTarget.
2237         for (int i = 1; i < argumentCountIncludingThis; ++i)
2238             addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
2239         set(VirtualRegister(resultOperand),
2240             addToGraph(Node::VarArg, NewArray, OpInfo(ArrayWithUndecided), OpInfo(0)));
2241         return true;
2242     }
2243     
2244     if (function->classInfo() == StringConstructor::info()) {
2245         insertChecks();
2246         
2247         Node* result;
2248         
2249         if (argumentCountIncludingThis <= 1)
2250             result = jsConstant(m_vm->smallStrings.emptyString());
2251         else
2252             result = addToGraph(CallStringConstructor, get(virtualRegisterForArgument(1, registerOffset)));
2253         
2254         if (kind == CodeForConstruct)
2255             result = addToGraph(NewStringObject, OpInfo(function->globalObject()->stringObjectStructure()), result);
2256         
2257         set(VirtualRegister(resultOperand), result);
2258         return true;
2259     }
2260     
2261     for (unsigned typeIndex = 0; typeIndex < NUMBER_OF_TYPED_ARRAY_TYPES; ++typeIndex) {
2262         bool result = handleTypedArrayConstructor(
2263             resultOperand, function, registerOffset, argumentCountIncludingThis,
2264             indexToTypedArrayType(typeIndex), insertChecks);
2265         if (result)
2266             return true;
2267     }
2268     
2269     return false;
2270 }
2271
2272 Node* ByteCodeParser::handleGetByOffset(SpeculatedType prediction, Node* base, unsigned identifierNumber, PropertyOffset offset, NodeType op)
2273 {
2274     Node* propertyStorage;
2275     if (isInlineOffset(offset))
2276         propertyStorage = base;
2277     else
2278         propertyStorage = addToGraph(GetButterfly, base);
2279     
2280     StorageAccessData* data = m_graph.m_storageAccessData.add();
2281     data->offset = offset;
2282     data->identifierNumber = identifierNumber;
2283     
2284     Node* getByOffset = addToGraph(op, OpInfo(data), OpInfo(prediction), propertyStorage, base);
2285
2286     return getByOffset;
2287 }
2288
2289 Node* ByteCodeParser::handlePutByOffset(Node* base, unsigned identifier, PropertyOffset offset, Node* value)
2290 {
2291     Node* propertyStorage;
2292     if (isInlineOffset(offset))
2293         propertyStorage = base;
2294     else
2295         propertyStorage = addToGraph(GetButterfly, base);
2296     
2297     StorageAccessData* data = m_graph.m_storageAccessData.add();
2298     data->offset = offset;
2299     data->identifierNumber = identifier;
2300     
2301     Node* result = addToGraph(PutByOffset, OpInfo(data), propertyStorage, base, value);
2302     
2303     return result;
2304 }
2305
2306 bool ByteCodeParser::check(const ObjectPropertyCondition& condition)
2307 {
2308     if (m_graph.watchCondition(condition))
2309         return true;
2310     
2311     Structure* structure = condition.object()->structure();
2312     if (!condition.structureEnsuresValidity(structure))
2313         return false;
2314     
2315     addToGraph(
2316         CheckStructure,
2317         OpInfo(m_graph.addStructureSet(structure)),
2318         weakJSConstant(condition.object()));
2319     return true;
2320 }
2321
2322 GetByOffsetMethod ByteCodeParser::promoteToConstant(GetByOffsetMethod method)
2323 {
2324     if (method.kind() == GetByOffsetMethod::LoadFromPrototype
2325         && method.prototype()->structure()->dfgShouldWatch()) {
2326         if (JSValue constant = m_graph.tryGetConstantProperty(method.prototype()->value(), method.prototype()->structure(), method.offset()))
2327             return GetByOffsetMethod::constant(m_graph.freeze(constant));
2328     }
2329     
2330     return method;
2331 }
2332
2333 GetByOffsetMethod ByteCodeParser::planLoad(const ObjectPropertyCondition& condition)
2334 {
2335     if (verbose)
2336         dataLog("Planning a load: ", condition, "\n");
2337     
2338     // We might promote this to Equivalence, and a later DFG pass might also do such promotion
2339     // even if we fail, but for simplicity this cannot be asked to load an equivalence condition.
2340     // None of the clients of this method will request a load of an Equivalence condition anyway,
2341     // and supporting it would complicate the heuristics below.
2342     RELEASE_ASSERT(condition.kind() == PropertyCondition::Presence);
2343     
2344     // Here's the ranking of how to handle this, from most preferred to least preferred:
2345     //
2346     // 1) Watchpoint on an equivalence condition and return a constant node for the loaded value.
2347     //    No other code is emitted, and the structure of the base object is never registered.
2348     //    Hence this results in zero code and we won't jettison this compilation if the object
2349     //    transitions, even if the structure is watchable right now.
2350     //
2351     // 2) Need to emit a load, and the current structure of the base is going to be watched by the
2352     //    DFG anyway (i.e. dfgShouldWatch). Watch the structure and emit the load. Don't watch the
2353     //    condition, since the act of turning the base into a constant in IR will cause the DFG to
2354     //    watch the structure anyway and doing so would subsume watching the condition.
2355     //
2356     // 3) Need to emit a load, and the current structure of the base is watchable but not by the
2357     //    DFG (i.e. transitionWatchpointSetIsStillValid() and !dfgShouldWatchIfPossible()). Watch
2358     //    the condition, and emit a load.
2359     //
2360     // 4) Need to emit a load, and the current structure of the base is not watchable. Emit a
2361     //    structure check, and emit a load.
2362     //
2363     // 5) The condition does not hold. Give up and return null.
2364     
2365     // First, try to promote Presence to Equivalence. We do this before doing anything else
2366     // because it's the most profitable. Also, there are cases where the presence is watchable but
2367     // we don't want to watch it unless it became an equivalence (see the relationship between
2368     // (1), (2), and (3) above).
2369     ObjectPropertyCondition equivalenceCondition = condition.attemptToMakeEquivalenceWithoutBarrier();
2370     if (m_graph.watchCondition(equivalenceCondition))
2371         return GetByOffsetMethod::constant(m_graph.freeze(equivalenceCondition.requiredValue()));
2372     
2373     // At this point, we'll have to materialize the condition's base as a constant in DFG IR. Once
2374     // we do this, the frozen value will have its own idea of what the structure is. Use that from
2375     // now on just because it's less confusing.
2376     FrozenValue* base = m_graph.freeze(condition.object());
2377     Structure* structure = base->structure();
2378     
2379     // Check if the structure that we've registered makes the condition hold. If not, just give
2380     // up. This is case (5) above.
2381     if (!condition.structureEnsuresValidity(structure))
2382         return GetByOffsetMethod();
2383     
2384     // If the structure is watched by the DFG already, then just use this fact to emit the load.
2385     // This is case (2) above.
2386     if (structure->dfgShouldWatch())
2387         return promoteToConstant(GetByOffsetMethod::loadFromPrototype(base, condition.offset()));
2388     
2389     // If we can watch the condition right now, then we can emit the load after watching it. This
2390     // is case (3) above.
2391     if (m_graph.watchCondition(condition))
2392         return promoteToConstant(GetByOffsetMethod::loadFromPrototype(base, condition.offset()));
2393     
2394     // We can't watch anything but we know that the current structure satisfies the condition. So,
2395     // check for that structure and then emit the load.
2396     addToGraph(
2397         CheckStructure, 
2398         OpInfo(m_graph.addStructureSet(structure)),
2399         addToGraph(JSConstant, OpInfo(base)));
2400     return promoteToConstant(GetByOffsetMethod::loadFromPrototype(base, condition.offset()));
2401 }
2402
2403 Node* ByteCodeParser::load(
2404     SpeculatedType prediction, unsigned identifierNumber, const GetByOffsetMethod& method,
2405     NodeType op)
2406 {
2407     switch (method.kind()) {
2408     case GetByOffsetMethod::Invalid:
2409         return nullptr;
2410     case GetByOffsetMethod::Constant:
2411         return addToGraph(JSConstant, OpInfo(method.constant()));
2412     case GetByOffsetMethod::LoadFromPrototype: {
2413         Node* baseNode = addToGraph(JSConstant, OpInfo(method.prototype()));
2414         return handleGetByOffset(prediction, baseNode, identifierNumber, method.offset(), op);
2415     }
2416     case GetByOffsetMethod::Load:
2417         // Will never see this from planLoad().
2418         RELEASE_ASSERT_NOT_REACHED();
2419         return nullptr;
2420     }
2421     
2422     RELEASE_ASSERT_NOT_REACHED();
2423     return nullptr;
2424 }
2425
2426 Node* ByteCodeParser::load(
2427     SpeculatedType prediction, const ObjectPropertyCondition& condition, NodeType op)
2428 {
2429     GetByOffsetMethod method = planLoad(condition);
2430     return load(prediction, m_graph.identifiers().ensure(condition.uid()), method, op);
2431 }
2432
2433 bool ByteCodeParser::check(const ObjectPropertyConditionSet& conditionSet)
2434 {
2435     for (const ObjectPropertyCondition condition : conditionSet) {
2436         if (!check(condition))
2437             return false;
2438     }
2439     return true;
2440 }
2441
2442 GetByOffsetMethod ByteCodeParser::planLoad(const ObjectPropertyConditionSet& conditionSet)
2443 {
2444     if (verbose)
2445         dataLog("conditionSet = ", conditionSet, "\n");
2446     
2447     GetByOffsetMethod result;
2448     for (const ObjectPropertyCondition condition : conditionSet) {
2449         switch (condition.kind()) {
2450         case PropertyCondition::Presence:
2451             RELEASE_ASSERT(!result); // Should only see exactly one of these.
2452             result = planLoad(condition);
2453             if (!result)
2454                 return GetByOffsetMethod();
2455             break;
2456         default:
2457             if (!check(condition))
2458                 return GetByOffsetMethod();
2459             break;
2460         }
2461     }
2462     RELEASE_ASSERT(!!result);
2463     return result;
2464 }
2465
2466 Node* ByteCodeParser::load(
2467     SpeculatedType prediction, const ObjectPropertyConditionSet& conditionSet, NodeType op)
2468 {
2469     GetByOffsetMethod method = planLoad(conditionSet);
2470     return load(
2471         prediction,
2472         m_graph.identifiers().ensure(conditionSet.slotBaseCondition().uid()),
2473         method, op);
2474 }
2475
2476 ObjectPropertyCondition ByteCodeParser::presenceLike(
2477     JSObject* knownBase, UniquedStringImpl* uid, PropertyOffset offset, const StructureSet& set)
2478 {
2479     if (set.isEmpty())
2480         return ObjectPropertyCondition();
2481     unsigned attributes;
2482     PropertyOffset firstOffset = set[0]->getConcurrently(uid, attributes);
2483     if (firstOffset != offset)
2484         return ObjectPropertyCondition();
2485     for (unsigned i = 1; i < set.size(); ++i) {
2486         unsigned otherAttributes;
2487         PropertyOffset otherOffset = set[i]->getConcurrently(uid, otherAttributes);
2488         if (otherOffset != offset || otherAttributes != attributes)
2489             return ObjectPropertyCondition();
2490     }
2491     return ObjectPropertyCondition::presenceWithoutBarrier(knownBase, uid, offset, attributes);
2492 }
2493
2494 bool ByteCodeParser::checkPresenceLike(
2495     JSObject* knownBase, UniquedStringImpl* uid, PropertyOffset offset, const StructureSet& set)
2496 {
2497     return check(presenceLike(knownBase, uid, offset, set));
2498 }
2499
2500 void ByteCodeParser::checkPresenceLike(
2501     Node* base, UniquedStringImpl* uid, PropertyOffset offset, const StructureSet& set)
2502 {
2503     if (JSObject* knownBase = base->dynamicCastConstant<JSObject*>()) {
2504         if (checkPresenceLike(knownBase, uid, offset, set))
2505             return;
2506     }
2507
2508     addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(set)), base);
2509 }
2510
2511 template<typename VariantType>
2512 Node* ByteCodeParser::load(
2513     SpeculatedType prediction, Node* base, unsigned identifierNumber, const VariantType& variant)
2514 {
2515     // Make sure backwards propagation knows that we've used base.
2516     addToGraph(Phantom, base);
2517     
2518     bool needStructureCheck = true;
2519     
2520     if (JSObject* knownBase = base->dynamicCastConstant<JSObject*>()) {
2521         // Try to optimize away the structure check. Note that it's not worth doing anything about this
2522         // if the base's structure is watched.
2523         Structure* structure = base->constant()->structure();
2524         if (!structure->dfgShouldWatch()) {
2525             UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
2526             
2527             if (!variant.conditionSet().isEmpty()) {
2528                 // This means that we're loading from a prototype. We expect the base not to have the
2529                 // property. We can only use ObjectPropertyCondition if all of the structures in the
2530                 // variant.structureSet() agree on the prototype (it would be hilariously rare if they
2531                 // didn't). Note that we are relying on structureSet() having at least one element. That
2532                 // will always be true here because of how GetByIdStatus/PutByIdStatus work.
2533                 JSObject* prototype = variant.structureSet()[0]->storedPrototypeObject();
2534                 bool allAgree = true;
2535                 for (unsigned i = 1; i < variant.structureSet().size(); ++i) {
2536                     if (variant.structureSet()[i]->storedPrototypeObject() != prototype) {
2537                         allAgree = false;
2538                         break;
2539                     }
2540                 }
2541                 if (allAgree) {
2542                     ObjectPropertyCondition condition = ObjectPropertyCondition::absenceWithoutBarrier(
2543                         knownBase, uid, prototype);
2544                     if (check(condition))
2545                         needStructureCheck = false;
2546                 }
2547             } else {
2548                 // This means we're loading directly from base. We can avoid all of the code that follows
2549                 // if we can prove that the property is a constant. Otherwise, we try to prove that the
2550                 // property is watchably present, in which case we get rid of the structure check.
2551
2552                 ObjectPropertyCondition presenceCondition =
2553                     presenceLike(knownBase, uid, variant.offset(), variant.structureSet());
2554
2555                 ObjectPropertyCondition equivalenceCondition =
2556                     presenceCondition.attemptToMakeEquivalenceWithoutBarrier();
2557                 if (m_graph.watchCondition(equivalenceCondition))
2558                     return weakJSConstant(equivalenceCondition.requiredValue());
2559
2560                 if (check(presenceCondition))
2561                     needStructureCheck = false;
2562             }
2563         }
2564     }
2565
2566     if (needStructureCheck)
2567         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), base);
2568     
2569     SpeculatedType loadPrediction;
2570     NodeType loadOp;
2571     if (variant.callLinkStatus()) {
2572         loadPrediction = SpecCellOther;
2573         loadOp = GetGetterSetterByOffset;
2574     } else {
2575         loadPrediction = prediction;
2576         loadOp = GetByOffset;
2577     }
2578     
2579     Node* loadedValue;
2580     if (!variant.conditionSet().isEmpty())
2581         loadedValue = load(loadPrediction, variant.conditionSet(), loadOp);
2582     else {
2583         if (needStructureCheck && base->hasConstant()) {
2584             // We did emit a structure check. That means that we have an opportunity to do constant folding
2585             // here, since we didn't do it above.
2586             JSValue constant = m_graph.tryGetConstantProperty(
2587                 base->asJSValue(), variant.structureSet(), variant.offset());
2588             if (constant)
2589                 return weakJSConstant(constant);
2590         }
2591         
2592         loadedValue = handleGetByOffset(
2593             loadPrediction, base, identifierNumber, variant.offset(), loadOp);
2594     }
2595
2596     return loadedValue;
2597 }
2598
2599 Node* ByteCodeParser::store(Node* base, unsigned identifier, const PutByIdVariant& variant, Node* value)
2600 {
2601     RELEASE_ASSERT(variant.kind() == PutByIdVariant::Replace);
2602
2603     checkPresenceLike(base, m_graph.identifiers()[identifier], variant.offset(), variant.structure());
2604     return handlePutByOffset(base, identifier, variant.offset(), value);
2605 }
2606
2607 void ByteCodeParser::handleGetById(
2608     int destinationOperand, SpeculatedType prediction, Node* base, unsigned identifierNumber,
2609     const GetByIdStatus& getByIdStatus)
2610 {
2611     NodeType getById = getByIdStatus.makesCalls() ? GetByIdFlush : GetById;
2612     
2613     if (!getByIdStatus.isSimple() || !getByIdStatus.numVariants() || !Options::enableAccessInlining()) {
2614         set(VirtualRegister(destinationOperand),
2615             addToGraph(getById, OpInfo(identifierNumber), OpInfo(prediction), base));
2616         return;
2617     }
2618     
2619     if (getByIdStatus.numVariants() > 1) {
2620         if (getByIdStatus.makesCalls() || !isFTL(m_graph.m_plan.mode)
2621             || !Options::enablePolymorphicAccessInlining()) {
2622             set(VirtualRegister(destinationOperand),
2623                 addToGraph(getById, OpInfo(identifierNumber), OpInfo(prediction), base));
2624             return;
2625         }
2626         
2627         Vector<MultiGetByOffsetCase, 2> cases;
2628         
2629         // 1) Emit prototype structure checks for all chains. This could sort of maybe not be
2630         //    optimal, if there is some rarely executed case in the chain that requires a lot
2631         //    of checks and those checks are not watchpointable.
2632         for (const GetByIdVariant& variant : getByIdStatus.variants()) {
2633             if (variant.conditionSet().isEmpty()) {
2634                 cases.append(
2635                     MultiGetByOffsetCase(
2636                         variant.structureSet(),
2637                         GetByOffsetMethod::load(variant.offset())));
2638                 continue;
2639             }
2640             
2641             GetByOffsetMethod method = planLoad(variant.conditionSet());
2642             if (!method) {
2643                 set(VirtualRegister(destinationOperand),
2644                     addToGraph(getById, OpInfo(identifierNumber), OpInfo(prediction), base));
2645                 return;
2646             }
2647             
2648             cases.append(MultiGetByOffsetCase(variant.structureSet(), method));
2649         }
2650
2651         if (m_graph.compilation())
2652             m_graph.compilation()->noticeInlinedGetById();
2653     
2654         // 2) Emit a MultiGetByOffset
2655         MultiGetByOffsetData* data = m_graph.m_multiGetByOffsetData.add();
2656         data->cases = cases;
2657         data->identifierNumber = identifierNumber;
2658         set(VirtualRegister(destinationOperand),
2659             addToGraph(MultiGetByOffset, OpInfo(data), OpInfo(prediction), base));
2660         return;
2661     }
2662     
2663     ASSERT(getByIdStatus.numVariants() == 1);
2664     GetByIdVariant variant = getByIdStatus[0];
2665                 
2666     Node* loadedValue = load(prediction, base, identifierNumber, variant);
2667     if (!loadedValue) {
2668         set(VirtualRegister(destinationOperand),
2669             addToGraph(getById, OpInfo(identifierNumber), OpInfo(prediction), base));
2670         return;
2671     }
2672
2673     if (m_graph.compilation())
2674         m_graph.compilation()->noticeInlinedGetById();
2675     
2676     if (!variant.callLinkStatus()) {
2677         set(VirtualRegister(destinationOperand), loadedValue);
2678         return;
2679     }
2680     
2681     Node* getter = addToGraph(GetGetter, loadedValue);
2682     
2683     // Make a call. We don't try to get fancy with using the smallest operand number because
2684     // the stack layout phase should compress the stack anyway.
2685     
2686     unsigned numberOfParameters = 0;
2687     numberOfParameters++; // The 'this' argument.
2688     numberOfParameters++; // True return PC.
2689     
2690     // Start with a register offset that corresponds to the last in-use register.
2691     int registerOffset = virtualRegisterForLocal(
2692         m_inlineStackTop->m_profiledBlock->m_numCalleeRegisters - 1).offset();
2693     registerOffset -= numberOfParameters;
2694     registerOffset -= JSStack::CallFrameHeaderSize;
2695     
2696     // Get the alignment right.
2697     registerOffset = -WTF::roundUpToMultipleOf(
2698         stackAlignmentRegisters(),
2699         -registerOffset);
2700     
2701     ensureLocals(
2702         m_inlineStackTop->remapOperand(
2703             VirtualRegister(registerOffset)).toLocal());
2704     
2705     // Issue SetLocals. This has two effects:
2706     // 1) That's how handleCall() sees the arguments.
2707     // 2) If we inline then this ensures that the arguments are flushed so that if you use
2708     //    the dreaded arguments object on the getter, the right things happen. Well, sort of -
2709     //    since we only really care about 'this' in this case. But we're not going to take that
2710     //    shortcut.
2711     int nextRegister = registerOffset + JSStack::CallFrameHeaderSize;
2712     set(VirtualRegister(nextRegister++), base, ImmediateNakedSet);
2713     
2714     handleCall(
2715         destinationOperand, Call, InlineCallFrame::GetterCall, OPCODE_LENGTH(op_get_by_id),
2716         getter, numberOfParameters - 1, registerOffset, *variant.callLinkStatus(), prediction);
2717 }
2718
2719 void ByteCodeParser::emitPutById(
2720     Node* base, unsigned identifierNumber, Node* value, const PutByIdStatus& putByIdStatus, bool isDirect)
2721 {
2722     if (isDirect)
2723         addToGraph(PutByIdDirect, OpInfo(identifierNumber), base, value);
2724     else
2725         addToGraph(putByIdStatus.makesCalls() ? PutByIdFlush : PutById, OpInfo(identifierNumber), base, value);
2726 }
2727
2728 void ByteCodeParser::handlePutById(
2729     Node* base, unsigned identifierNumber, Node* value,
2730     const PutByIdStatus& putByIdStatus, bool isDirect)
2731 {
2732     if (!putByIdStatus.isSimple() || !putByIdStatus.numVariants() || !Options::enableAccessInlining()) {
2733         if (!putByIdStatus.isSet())
2734             addToGraph(ForceOSRExit);
2735         emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
2736         return;
2737     }
2738     
2739     if (putByIdStatus.numVariants() > 1) {
2740         if (!isFTL(m_graph.m_plan.mode) || putByIdStatus.makesCalls()
2741             || !Options::enablePolymorphicAccessInlining()) {
2742             emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
2743             return;
2744         }
2745         
2746         if (!isDirect) {
2747             for (unsigned variantIndex = putByIdStatus.numVariants(); variantIndex--;) {
2748                 if (putByIdStatus[variantIndex].kind() != PutByIdVariant::Transition)
2749                     continue;
2750                 if (!check(putByIdStatus[variantIndex].conditionSet())) {
2751                     emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
2752                     return;
2753                 }
2754             }
2755         }
2756         
2757         if (m_graph.compilation())
2758             m_graph.compilation()->noticeInlinedPutById();
2759         
2760         MultiPutByOffsetData* data = m_graph.m_multiPutByOffsetData.add();
2761         data->variants = putByIdStatus.variants();
2762         data->identifierNumber = identifierNumber;
2763         addToGraph(MultiPutByOffset, OpInfo(data), base, value);
2764         return;
2765     }
2766     
2767     ASSERT(putByIdStatus.numVariants() == 1);
2768     const PutByIdVariant& variant = putByIdStatus[0];
2769     
2770     switch (variant.kind()) {
2771     case PutByIdVariant::Replace: {
2772         store(base, identifierNumber, variant, value);
2773         if (m_graph.compilation())
2774             m_graph.compilation()->noticeInlinedPutById();
2775         return;
2776     }
2777     
2778     case PutByIdVariant::Transition: {
2779         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.oldStructure())), base);
2780         if (!check(variant.conditionSet())) {
2781             emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
2782             return;
2783         }
2784
2785         ASSERT(variant.oldStructureForTransition()->transitionWatchpointSetHasBeenInvalidated());
2786     
2787         Node* propertyStorage;
2788         Transition* transition = m_graph.m_transitions.add(
2789             variant.oldStructureForTransition(), variant.newStructure());
2790
2791         if (variant.reallocatesStorage()) {
2792
2793             // If we're growing the property storage then it must be because we're
2794             // storing into the out-of-line storage.
2795             ASSERT(!isInlineOffset(variant.offset()));
2796
2797             if (!variant.oldStructureForTransition()->outOfLineCapacity()) {
2798                 propertyStorage = addToGraph(
2799                     AllocatePropertyStorage, OpInfo(transition), base);
2800             } else {
2801                 propertyStorage = addToGraph(
2802                     ReallocatePropertyStorage, OpInfo(transition),
2803                     base, addToGraph(GetButterfly, base));
2804             }
2805         } else {
2806             if (isInlineOffset(variant.offset()))
2807                 propertyStorage = base;
2808             else
2809                 propertyStorage = addToGraph(GetButterfly, base);
2810         }
2811
2812         StorageAccessData* data = m_graph.m_storageAccessData.add();
2813         data->offset = variant.offset();
2814         data->identifierNumber = identifierNumber;
2815         
2816         addToGraph(
2817             PutByOffset,
2818             OpInfo(data),
2819             propertyStorage,
2820             base,
2821             value);
2822
2823         // FIXME: PutStructure goes last until we fix either
2824         // https://bugs.webkit.org/show_bug.cgi?id=142921 or
2825         // https://bugs.webkit.org/show_bug.cgi?id=142924.
2826         addToGraph(PutStructure, OpInfo(transition), base);
2827
2828         if (m_graph.compilation())
2829             m_graph.compilation()->noticeInlinedPutById();
2830         return;
2831     }
2832         
2833     case PutByIdVariant::Setter: {
2834         Node* loadedValue = load(SpecCellOther, base, identifierNumber, variant);
2835         if (!loadedValue) {
2836             emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
2837             return;
2838         }
2839         
2840         Node* setter = addToGraph(GetSetter, loadedValue);
2841         
2842         // Make a call. We don't try to get fancy with using the smallest operand number because
2843         // the stack layout phase should compress the stack anyway.
2844     
2845         unsigned numberOfParameters = 0;
2846         numberOfParameters++; // The 'this' argument.
2847         numberOfParameters++; // The new value.
2848         numberOfParameters++; // True return PC.
2849     
2850         // Start with a register offset that corresponds to the last in-use register.
2851         int registerOffset = virtualRegisterForLocal(
2852             m_inlineStackTop->m_profiledBlock->m_numCalleeRegisters - 1).offset();
2853         registerOffset -= numberOfParameters;
2854         registerOffset -= JSStack::CallFrameHeaderSize;
2855     
2856         // Get the alignment right.
2857         registerOffset = -WTF::roundUpToMultipleOf(
2858             stackAlignmentRegisters(),
2859             -registerOffset);
2860     
2861         ensureLocals(
2862             m_inlineStackTop->remapOperand(
2863                 VirtualRegister(registerOffset)).toLocal());
2864     
2865         int nextRegister = registerOffset + JSStack::CallFrameHeaderSize;
2866         set(VirtualRegister(nextRegister++), base, ImmediateNakedSet);
2867         set(VirtualRegister(nextRegister++), value, ImmediateNakedSet);
2868     
2869         handleCall(
2870             VirtualRegister().offset(), Call, InlineCallFrame::SetterCall,
2871             OPCODE_LENGTH(op_put_by_id), setter, numberOfParameters - 1, registerOffset,
2872             *variant.callLinkStatus(), SpecOther);
2873         return;
2874     }
2875     
2876     default: {
2877         emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
2878         return;
2879     } }
2880 }
2881
2882 void ByteCodeParser::prepareToParseBlock()
2883 {
2884     clearCaches();
2885     ASSERT(m_setLocalQueue.isEmpty());
2886 }
2887
2888 void ByteCodeParser::clearCaches()
2889 {
2890     m_constants.resize(0);
2891 }
2892
2893 bool ByteCodeParser::parseBlock(unsigned limit)
2894 {
2895     bool shouldContinueParsing = true;
2896
2897     Interpreter* interpreter = m_vm->interpreter;
2898     Instruction* instructionsBegin = m_inlineStackTop->m_codeBlock->instructions().begin();
2899     unsigned blockBegin = m_currentIndex;
2900     
2901     // If we are the first basic block, introduce markers for arguments. This allows
2902     // us to track if a use of an argument may use the actual argument passed, as
2903     // opposed to using a value we set explicitly.
2904     if (m_currentBlock == m_graph.block(0) && !inlineCallFrame()) {
2905         m_graph.m_arguments.resize(m_numArguments);
2906         for (unsigned argument = 0; argument < m_numArguments; ++argument) {
2907             VariableAccessData* variable = newVariableAccessData(
2908                 virtualRegisterForArgument(argument));
2909             variable->mergeStructureCheckHoistingFailed(
2910                 m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
2911             variable->mergeCheckArrayHoistingFailed(
2912                 m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
2913             
2914             Node* setArgument = addToGraph(SetArgument, OpInfo(variable));
2915             m_graph.m_arguments[argument] = setArgument;
2916             m_currentBlock->variablesAtTail.setArgumentFirstTime(argument, setArgument);
2917         }
2918     }
2919
2920     while (true) {
2921         processSetLocalQueue();
2922         
2923         // Don't extend over jump destinations.
2924         if (m_currentIndex == limit) {
2925             // Ordinarily we want to plant a jump. But refuse to do this if the block is
2926             // empty. This is a special case for inlining, which might otherwise create
2927             // some empty blocks in some cases. When parseBlock() returns with an empty
2928             // block, it will get repurposed instead of creating a new one. Note that this
2929             // logic relies on every bytecode resulting in one or more nodes, which would
2930             // be true anyway except for op_loop_hint, which emits a Phantom to force this
2931             // to be true.
2932             if (!m_currentBlock->isEmpty())
2933                 addToGraph(Jump, OpInfo(m_currentIndex));
2934             return shouldContinueParsing;
2935         }
2936         
2937         // Switch on the current bytecode opcode.
2938         Instruction* currentInstruction = instructionsBegin + m_currentIndex;
2939         m_currentInstruction = currentInstruction; // Some methods want to use this, and we'd rather not thread it through calls.
2940         OpcodeID opcodeID = interpreter->getOpcodeID(currentInstruction->u.opcode);
2941         
2942         if (Options::verboseDFGByteCodeParsing())
2943             dataLog("    parsing ", currentCodeOrigin(), "\n");
2944         
2945         if (m_graph.compilation()) {
2946             addToGraph(CountExecution, OpInfo(m_graph.compilation()->executionCounterFor(
2947                 Profiler::OriginStack(*m_vm->m_perBytecodeProfiler, m_codeBlock, currentCodeOrigin()))));
2948         }
2949         
2950         switch (opcodeID) {
2951
2952         // === Function entry opcodes ===
2953
2954         case op_enter: {
2955             Node* undefined = addToGraph(JSConstant, OpInfo(m_constantUndefined));
2956             // Initialize all locals to undefined.
2957             for (int i = 0; i < m_inlineStackTop->m_codeBlock->m_numVars; ++i)
2958                 set(virtualRegisterForLocal(i), undefined, ImmediateNakedSet);
2959             NEXT_OPCODE(op_enter);
2960         }
2961             
2962         case op_to_this: {
2963             Node* op1 = getThis();
2964             if (op1->op() != ToThis) {
2965                 Structure* cachedStructure = currentInstruction[2].u.structure.get();
2966                 if (currentInstruction[2].u.toThisStatus != ToThisOK
2967                     || !cachedStructure
2968                     || cachedStructure->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis
2969                     || m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
2970                     || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
2971                     || (op1->op() == GetLocal && op1->variableAccessData()->structureCheckHoistingFailed())) {
2972                     setThis(addToGraph(ToThis, op1));
2973                 } else {
2974                     addToGraph(
2975                         CheckStructure,
2976                         OpInfo(m_graph.addStructureSet(cachedStructure)),
2977                         op1);
2978                 }
2979             }
2980             NEXT_OPCODE(op_to_this);
2981         }
2982
2983         case op_create_this: {
2984             int calleeOperand = currentInstruction[2].u.operand;
2985             Node* callee = get(VirtualRegister(calleeOperand));
2986
2987             JSFunction* function = callee->dynamicCastConstant<JSFunction*>();
2988             if (!function) {
2989                 JSCell* cachedFunction = currentInstruction[4].u.jsCell.unvalidatedGet();
2990                 if (cachedFunction
2991                     && cachedFunction != JSCell::seenMultipleCalleeObjects()
2992                     && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell)) {
2993                     ASSERT(cachedFunction->inherits(JSFunction::info()));
2994
2995                     FrozenValue* frozen = m_graph.freeze(cachedFunction);
2996                     addToGraph(CheckCell, OpInfo(frozen), callee);
2997                     set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(JSConstant, OpInfo(frozen)));
2998
2999                     function = static_cast<JSFunction*>(cachedFunction);
3000                 }
3001             }
3002
3003             bool alreadyEmitted = false;
3004             if (function) {
3005                 if (FunctionRareData* rareData = function->rareData()) {
3006                     if (Structure* structure = rareData->allocationStructure()) {
3007                         m_graph.freeze(rareData);
3008                         m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
3009                         // The callee is still live up to this point.
3010                         addToGraph(Phantom, callee);
3011                         set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewObject, OpInfo(structure)));
3012                         alreadyEmitted = true;
3013                     }
3014                 }
3015             }
3016             if (!alreadyEmitted) {
3017                 set(VirtualRegister(currentInstruction[1].u.operand),
3018                     addToGraph(CreateThis, OpInfo(currentInstruction[3].u.operand), callee));
3019             }
3020             NEXT_OPCODE(op_create_this);
3021         }
3022
3023         case op_new_object: {
3024             set(VirtualRegister(currentInstruction[1].u.operand),
3025                 addToGraph(NewObject,
3026                     OpInfo(currentInstruction[3].u.objectAllocationProfile->structure())));
3027             NEXT_OPCODE(op_new_object);
3028         }
3029             
3030         case op_new_array: {
3031             int startOperand = currentInstruction[2].u.operand;
3032             int numOperands = currentInstruction[3].u.operand;
3033             ArrayAllocationProfile* profile = currentInstruction[4].u.arrayAllocationProfile;
3034             for (int operandIdx = startOperand; operandIdx > startOperand - numOperands; --operandIdx)
3035                 addVarArgChild(get(VirtualRegister(operandIdx)));
3036             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(Node::VarArg, NewArray, OpInfo(profile->selectIndexingType()), OpInfo(0)));
3037             NEXT_OPCODE(op_new_array);
3038         }
3039             
3040         case op_new_array_with_size: {
3041             int lengthOperand = currentInstruction[2].u.operand;
3042             ArrayAllocationProfile* profile = currentInstruction[3].u.arrayAllocationProfile;
3043             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewArrayWithSize, OpInfo(profile->selectIndexingType()), get(VirtualRegister(lengthOperand))));
3044             NEXT_OPCODE(op_new_array_with_size);
3045         }
3046             
3047         case op_new_array_buffer: {
3048             int startConstant = currentInstruction[2].u.operand;
3049             int numConstants = currentInstruction[3].u.operand;
3050             ArrayAllocationProfile* profile = currentInstruction[4].u.arrayAllocationProfile;
3051             NewArrayBufferData data;
3052             data.startConstant = m_inlineStackTop->m_constantBufferRemap[startConstant];
3053             data.numConstants = numConstants;
3054             data.indexingType = profile->selectIndexingType();
3055
3056             // If this statement has never executed, we'll have the wrong indexing type in the profile.
3057             for (int i = 0; i < numConstants; ++i) {
3058                 data.indexingType =
3059                     leastUpperBoundOfIndexingTypeAndValue(
3060                         data.indexingType,
3061                         m_codeBlock->constantBuffer(data.startConstant)[i]);
3062             }
3063             
3064             m_graph.m_newArrayBufferData.append(data);
3065             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewArrayBuffer, OpInfo(&m_graph.m_newArrayBufferData.last())));
3066             NEXT_OPCODE(op_new_array_buffer);
3067         }
3068             
3069         case op_new_regexp: {
3070             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewRegexp, OpInfo(currentInstruction[2].u.operand)));
3071             NEXT_OPCODE(op_new_regexp);
3072         }
3073             
3074         // === Bitwise operations ===
3075
3076         case op_bitand: {
3077             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
3078             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
3079             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(BitAnd, op1, op2));
3080             NEXT_OPCODE(op_bitand);
3081         }
3082
3083         case op_bitor: {
3084             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
3085             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
3086             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(BitOr, op1, op2));
3087             NEXT_OPCODE(op_bitor);
3088         }
3089
3090         case op_bitxor: {
3091             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
3092             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
3093             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(BitXor, op1, op2));
3094             NEXT_OPCODE(op_bitxor);
3095         }
3096
3097         case op_rshift: {
3098             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
3099             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
3100             set(VirtualRegister(currentInstruction[1].u.operand),
3101                 addToGraph(BitRShift, op1, op2));
3102             NEXT_OPCODE(op_rshift);
3103         }
3104
3105         case op_lshift: {
3106             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
3107             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
3108             set(VirtualRegister(currentInstruction[1].u.operand),
3109                 addToGraph(BitLShift, op1, op2));
3110             NEXT_OPCODE(op_lshift);
3111         }
3112
3113         case op_urshift: {
3114             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
3115             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
3116             set(VirtualRegister(currentInstruction[1].u.operand),
3117                 addToGraph(BitURShift, op1, op2));
3118             NEXT_OPCODE(op_urshift);
3119         }
3120             
3121         case op_unsigned: {
3122             set(VirtualRegister(currentInstruction[1].u.operand),
3123                 makeSafe(addToGraph(UInt32ToNumber, get(VirtualRegister(currentInstruction[2].u.operand)))));
3124             NEXT_OPCODE(op_unsigned);
3125         }
3126
3127         // === Increment/Decrement opcodes ===
3128
3129         case op_inc: {
3130             int srcDst = currentInstruction[1].u.operand;
3131             VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
3132             Node* op = get(srcDstVirtualRegister);
3133             set(srcDstVirtualRegister, makeSafe(addToGraph(ArithAdd, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
3134             NEXT_OPCODE(op_inc);
3135         }
3136
3137         case op_dec: {
3138             int srcDst = currentInstruction[1].u.operand;
3139             VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
3140             Node* op = get(srcDstVirtualRegister);
3141             set(srcDstVirtualRegister, makeSafe(addToGraph(ArithSub, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
3142             NEXT_OPCODE(op_dec);
3143         }
3144
3145         // === Arithmetic operations ===
3146
3147         case op_add: {
3148             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
3149             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
3150             if (op1->hasNumberResult() && op2->hasNumberResult())
3151                 set(VirtualRegister(currentInstruction[1].u.operand), makeSafe(addToGraph(ArithAdd, op1, op2)));