Fix endless OSR exits when creating a rope that contains an object that ToPrimitive...
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGGraph.h
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 #ifndef DFGGraph_h
27 #define DFGGraph_h
28
29 #if ENABLE(DFG_JIT)
30
31 #include "AssemblyHelpers.h"
32 #include "BytecodeLivenessAnalysisInlines.h"
33 #include "CodeBlock.h"
34 #include "DFGArgumentPosition.h"
35 #include "DFGBasicBlock.h"
36 #include "DFGFrozenValue.h"
37 #include "DFGLongLivedState.h"
38 #include "DFGNode.h"
39 #include "DFGNodeAllocator.h"
40 #include "DFGPlan.h"
41 #include "DFGPropertyTypeKey.h"
42 #include "DFGScannable.h"
43 #include "FullBytecodeLiveness.h"
44 #include "JSStack.h"
45 #include "MethodOfGettingAValueProfile.h"
46 #include <unordered_map>
47 #include <wtf/BitVector.h>
48 #include <wtf/HashMap.h>
49 #include <wtf/Vector.h>
50 #include <wtf/StdLibExtras.h>
51
52 namespace JSC {
53
54 class CodeBlock;
55 class ExecState;
56
57 namespace DFG {
58
59 class CFG;
60 class Dominators;
61 class NaturalLoops;
62 class PrePostNumbering;
63
64 #define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do {            \
65         Node* _node = (node);                                           \
66         if (_node->flags() & NodeHasVarArgs) {                          \
67             for (unsigned _childIdx = _node->firstChild();              \
68                 _childIdx < _node->firstChild() + _node->numChildren(); \
69                 _childIdx++) {                                          \
70                 if (!!(graph).m_varArgChildren[_childIdx])              \
71                     thingToDo(_node, (graph).m_varArgChildren[_childIdx]); \
72             }                                                           \
73         } else {                                                        \
74             if (!_node->child1()) {                                     \
75                 ASSERT(                                                 \
76                     !_node->child2()                                    \
77                     && !_node->child3());                               \
78                 break;                                                  \
79             }                                                           \
80             thingToDo(_node, _node->child1());                          \
81                                                                         \
82             if (!_node->child2()) {                                     \
83                 ASSERT(!_node->child3());                               \
84                 break;                                                  \
85             }                                                           \
86             thingToDo(_node, _node->child2());                          \
87                                                                         \
88             if (!_node->child3())                                       \
89                 break;                                                  \
90             thingToDo(_node, _node->child3());                          \
91         }                                                               \
92     } while (false)
93
94 #define DFG_ASSERT(graph, node, assertion) do {                         \
95         if (!!(assertion))                                              \
96             break;                                                      \
97         (graph).handleAssertionFailure(                                 \
98             (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
99     } while (false)
100
101 #define DFG_CRASH(graph, node, reason) do {                             \
102         (graph).handleAssertionFailure(                                 \
103             (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, (reason)); \
104     } while (false)
105
106 struct InlineVariableData {
107     InlineCallFrame* inlineCallFrame;
108     unsigned argumentPositionStart;
109     VariableAccessData* calleeVariable;
110 };
111
112 enum AddSpeculationMode {
113     DontSpeculateInt32,
114     SpeculateInt32AndTruncateConstants,
115     SpeculateInt32
116 };
117
118 //
119 // === Graph ===
120 //
121 // The order may be significant for nodes with side-effects (property accesses, value conversions).
122 // Nodes that are 'dead' remain in the vector with refCount 0.
123 class Graph : public virtual Scannable {
124 public:
125     Graph(VM&, Plan&, LongLivedState&);
126     ~Graph();
127     
128     void changeChild(Edge& edge, Node* newNode)
129     {
130         edge.setNode(newNode);
131     }
132     
133     void changeEdge(Edge& edge, Edge newEdge)
134     {
135         edge = newEdge;
136     }
137     
138     void compareAndSwap(Edge& edge, Node* oldNode, Node* newNode)
139     {
140         if (edge.node() != oldNode)
141             return;
142         changeChild(edge, newNode);
143     }
144     
145     void compareAndSwap(Edge& edge, Edge oldEdge, Edge newEdge)
146     {
147         if (edge != oldEdge)
148             return;
149         changeEdge(edge, newEdge);
150     }
151     
152     void performSubstitution(Node* node)
153     {
154         if (node->flags() & NodeHasVarArgs) {
155             for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++)
156                 performSubstitutionForEdge(m_varArgChildren[childIdx]);
157         } else {
158             performSubstitutionForEdge(node->child1());
159             performSubstitutionForEdge(node->child2());
160             performSubstitutionForEdge(node->child3());
161         }
162     }
163     
164     void performSubstitutionForEdge(Edge& child)
165     {
166         // Check if this operand is actually unused.
167         if (!child)
168             return;
169         
170         // Check if there is any replacement.
171         Node* replacement = child->replacement();
172         if (!replacement)
173             return;
174         
175         child.setNode(replacement);
176         
177         // There is definitely a replacement. Assert that the replacement does not
178         // have a replacement.
179         ASSERT(!child->replacement());
180     }
181     
182     template<typename... Params>
183     Node* addNode(SpeculatedType type, Params... params)
184     {
185         Node* node = new (m_allocator) Node(params...);
186         node->predict(type);
187         return node;
188     }
189
190     void dethread();
191     
192     FrozenValue* freeze(JSValue); // We use weak freezing by default.
193     FrozenValue* freezeStrong(JSValue); // Shorthand for freeze(value)->strengthenTo(StrongValue).
194     
195     void convertToConstant(Node* node, FrozenValue* value);
196     void convertToConstant(Node* node, JSValue value);
197     void convertToStrongConstant(Node* node, JSValue value);
198     
199     StructureRegistrationResult registerStructure(Structure* structure);
200     void assertIsRegistered(Structure* structure);
201     
202     // CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
203     void dump(PrintStream& = WTF::dataFile(), DumpContext* = 0);
204     
205     bool terminalsAreValid();
206     
207     enum PhiNodeDumpMode { DumpLivePhisOnly, DumpAllPhis };
208     void dumpBlockHeader(PrintStream&, const char* prefix, BasicBlock*, PhiNodeDumpMode, DumpContext*);
209     void dump(PrintStream&, Edge);
210     void dump(PrintStream&, const char* prefix, Node*, DumpContext* = 0);
211     static int amountOfNodeWhiteSpace(Node*);
212     static void printNodeWhiteSpace(PrintStream&, Node*);
213
214     // Dump the code origin of the given node as a diff from the code origin of the
215     // preceding node. Returns true if anything was printed.
216     bool dumpCodeOrigin(PrintStream&, const char* prefix, Node*& previousNode, Node* currentNode, DumpContext*);
217
218     AddSpeculationMode addSpeculationMode(Node* add, bool leftShouldSpeculateInt32, bool rightShouldSpeculateInt32, PredictionPass pass)
219     {
220         ASSERT(add->op() == ValueAdd || add->op() == ArithAdd || add->op() == ArithSub);
221         
222         RareCaseProfilingSource source = add->sourceFor(pass);
223         
224         Node* left = add->child1().node();
225         Node* right = add->child2().node();
226         
227         if (left->hasConstant())
228             return addImmediateShouldSpeculateInt32(add, rightShouldSpeculateInt32, right, left, source);
229         if (right->hasConstant())
230             return addImmediateShouldSpeculateInt32(add, leftShouldSpeculateInt32, left, right, source);
231         
232         return (leftShouldSpeculateInt32 && rightShouldSpeculateInt32 && add->canSpeculateInt32(source)) ? SpeculateInt32 : DontSpeculateInt32;
233     }
234     
235     AddSpeculationMode valueAddSpeculationMode(Node* add, PredictionPass pass)
236     {
237         return addSpeculationMode(
238             add,
239             add->child1()->shouldSpeculateInt32OrBooleanExpectingDefined(),
240             add->child2()->shouldSpeculateInt32OrBooleanExpectingDefined(),
241             pass);
242     }
243     
244     AddSpeculationMode arithAddSpeculationMode(Node* add, PredictionPass pass)
245     {
246         return addSpeculationMode(
247             add,
248             add->child1()->shouldSpeculateInt32OrBooleanForArithmetic(),
249             add->child2()->shouldSpeculateInt32OrBooleanForArithmetic(),
250             pass);
251     }
252     
253     AddSpeculationMode addSpeculationMode(Node* add, PredictionPass pass)
254     {
255         if (add->op() == ValueAdd)
256             return valueAddSpeculationMode(add, pass);
257         
258         return arithAddSpeculationMode(add, pass);
259     }
260     
261     bool addShouldSpeculateInt32(Node* add, PredictionPass pass)
262     {
263         return addSpeculationMode(add, pass) != DontSpeculateInt32;
264     }
265     
266     bool addShouldSpeculateMachineInt(Node* add)
267     {
268         if (!enableInt52())
269             return false;
270         
271         Node* left = add->child1().node();
272         Node* right = add->child2().node();
273
274         bool speculation = Node::shouldSpeculateMachineInt(left, right);
275         return speculation && !hasExitSite(add, Int52Overflow);
276     }
277     
278     bool mulShouldSpeculateInt32(Node* mul, PredictionPass pass)
279     {
280         ASSERT(mul->op() == ArithMul);
281         
282         Node* left = mul->child1().node();
283         Node* right = mul->child2().node();
284         
285         return Node::shouldSpeculateInt32OrBooleanForArithmetic(left, right)
286             && mul->canSpeculateInt32(mul->sourceFor(pass));
287     }
288     
289     bool mulShouldSpeculateMachineInt(Node* mul, PredictionPass pass)
290     {
291         ASSERT(mul->op() == ArithMul);
292         
293         if (!enableInt52())
294             return false;
295         
296         Node* left = mul->child1().node();
297         Node* right = mul->child2().node();
298
299         return Node::shouldSpeculateMachineInt(left, right)
300             && mul->canSpeculateInt52(pass)
301             && !hasExitSite(mul, Int52Overflow);
302     }
303     
304     bool negateShouldSpeculateInt32(Node* negate, PredictionPass pass)
305     {
306         ASSERT(negate->op() == ArithNegate);
307         return negate->child1()->shouldSpeculateInt32OrBooleanForArithmetic()
308             && negate->canSpeculateInt32(pass);
309     }
310     
311     bool negateShouldSpeculateMachineInt(Node* negate, PredictionPass pass)
312     {
313         ASSERT(negate->op() == ArithNegate);
314         if (!enableInt52())
315             return false;
316         return negate->child1()->shouldSpeculateMachineInt()
317             && !hasExitSite(negate, Int52Overflow)
318             && negate->canSpeculateInt52(pass);
319     }
320
321     bool canOptimizeStringObjectAccess(const CodeOrigin&);
322
323     bool roundShouldSpeculateInt32(Node* arithRound, PredictionPass pass)
324     {
325         ASSERT(arithRound->op() == ArithRound);
326         return arithRound->canSpeculateInt32(pass) && !hasExitSite(arithRound->origin.semantic, Overflow) && !hasExitSite(arithRound->origin.semantic, NegativeZero);
327     }
328     
329     static const char *opName(NodeType);
330     
331     StructureSet* addStructureSet(const StructureSet& structureSet)
332     {
333         for (Structure* structure : structureSet)
334             registerStructure(structure);
335         m_structureSet.append(structureSet);
336         return &m_structureSet.last();
337     }
338     
339     JSGlobalObject* globalObjectFor(CodeOrigin codeOrigin)
340     {
341         return m_codeBlock->globalObjectFor(codeOrigin);
342     }
343     
344     JSObject* globalThisObjectFor(CodeOrigin codeOrigin)
345     {
346         JSGlobalObject* object = globalObjectFor(codeOrigin);
347         return jsCast<JSObject*>(object->methodTable()->toThis(object, object->globalExec(), NotStrictMode));
348     }
349     
350     ScriptExecutable* executableFor(InlineCallFrame* inlineCallFrame)
351     {
352         if (!inlineCallFrame)
353             return m_codeBlock->ownerScriptExecutable();
354         
355         return inlineCallFrame->baselineCodeBlock->ownerScriptExecutable();
356     }
357     
358     ScriptExecutable* executableFor(const CodeOrigin& codeOrigin)
359     {
360         return executableFor(codeOrigin.inlineCallFrame);
361     }
362     
363     CodeBlock* baselineCodeBlockFor(InlineCallFrame* inlineCallFrame)
364     {
365         if (!inlineCallFrame)
366             return m_profiledBlock;
367         return baselineCodeBlockForInlineCallFrame(inlineCallFrame);
368     }
369     
370     CodeBlock* baselineCodeBlockFor(const CodeOrigin& codeOrigin)
371     {
372         return baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, m_profiledBlock);
373     }
374     
375     bool isStrictModeFor(CodeOrigin codeOrigin)
376     {
377         if (!codeOrigin.inlineCallFrame)
378             return m_codeBlock->isStrictMode();
379         return codeOrigin.inlineCallFrame->isStrictMode();
380     }
381     
382     ECMAMode ecmaModeFor(CodeOrigin codeOrigin)
383     {
384         return isStrictModeFor(codeOrigin) ? StrictMode : NotStrictMode;
385     }
386     
387     bool masqueradesAsUndefinedWatchpointIsStillValid(const CodeOrigin& codeOrigin)
388     {
389         return globalObjectFor(codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid();
390     }
391     
392     bool hasGlobalExitSite(const CodeOrigin& codeOrigin, ExitKind exitKind)
393     {
394         return baselineCodeBlockFor(codeOrigin)->hasExitSite(FrequentExitSite(exitKind));
395     }
396     
397     bool hasExitSite(const CodeOrigin& codeOrigin, ExitKind exitKind)
398     {
399         return baselineCodeBlockFor(codeOrigin)->hasExitSite(FrequentExitSite(codeOrigin.bytecodeIndex, exitKind));
400     }
401     
402     bool hasExitSite(Node* node, ExitKind exitKind)
403     {
404         return hasExitSite(node->origin.semantic, exitKind);
405     }
406     
407     VirtualRegister activationRegister()
408     {
409         return m_profiledBlock->activationRegister();
410     }
411     
412     VirtualRegister uncheckedActivationRegister()
413     {
414         return m_profiledBlock->uncheckedActivationRegister();
415     }
416     
417     VirtualRegister machineActivationRegister()
418     {
419         return m_profiledBlock->activationRegister();
420     }
421     
422     VirtualRegister uncheckedMachineActivationRegister()
423     {
424         return m_profiledBlock->uncheckedActivationRegister();
425     }
426     
427     ValueProfile* valueProfileFor(Node*);
428     MethodOfGettingAValueProfile methodOfGettingAValueProfileFor(Node*);
429     
430     BlockIndex numBlocks() const { return m_blocks.size(); }
431     BasicBlock* block(BlockIndex blockIndex) const { return m_blocks[blockIndex].get(); }
432     BasicBlock* lastBlock() const { return block(numBlocks() - 1); }
433
434     void appendBlock(PassRefPtr<BasicBlock> basicBlock)
435     {
436         basicBlock->index = m_blocks.size();
437         m_blocks.append(basicBlock);
438     }
439     
440     void killBlock(BlockIndex blockIndex)
441     {
442         m_blocks[blockIndex] = nullptr;
443     }
444     
445     void killBlock(BasicBlock* basicBlock)
446     {
447         killBlock(basicBlock->index);
448     }
449     
450     void killBlockAndItsContents(BasicBlock*);
451     
452     void killUnreachableBlocks();
453     
454     void determineReachability();
455     void resetReachability();
456     
457     void computeRefCounts();
458     
459     unsigned varArgNumChildren(Node* node)
460     {
461         ASSERT(node->flags() & NodeHasVarArgs);
462         return node->numChildren();
463     }
464     
465     unsigned numChildren(Node* node)
466     {
467         if (node->flags() & NodeHasVarArgs)
468             return varArgNumChildren(node);
469         return AdjacencyList::Size;
470     }
471     
472     Edge& varArgChild(Node* node, unsigned index)
473     {
474         ASSERT(node->flags() & NodeHasVarArgs);
475         return m_varArgChildren[node->firstChild() + index];
476     }
477     
478     Edge& child(Node* node, unsigned index)
479     {
480         if (node->flags() & NodeHasVarArgs)
481             return varArgChild(node, index);
482         return node->children.child(index);
483     }
484     
485     void voteNode(Node* node, unsigned ballot, float weight = 1)
486     {
487         switch (node->op()) {
488         case ValueToInt32:
489         case UInt32ToNumber:
490             node = node->child1().node();
491             break;
492         default:
493             break;
494         }
495         
496         if (node->op() == GetLocal)
497             node->variableAccessData()->vote(ballot, weight);
498     }
499     
500     void voteNode(Edge edge, unsigned ballot, float weight = 1)
501     {
502         voteNode(edge.node(), ballot, weight);
503     }
504     
505     void voteChildren(Node* node, unsigned ballot, float weight = 1)
506     {
507         if (node->flags() & NodeHasVarArgs) {
508             for (unsigned childIdx = node->firstChild();
509                 childIdx < node->firstChild() + node->numChildren();
510                 childIdx++) {
511                 if (!!m_varArgChildren[childIdx])
512                     voteNode(m_varArgChildren[childIdx], ballot, weight);
513             }
514             return;
515         }
516         
517         if (!node->child1())
518             return;
519         voteNode(node->child1(), ballot, weight);
520         if (!node->child2())
521             return;
522         voteNode(node->child2(), ballot, weight);
523         if (!node->child3())
524             return;
525         voteNode(node->child3(), ballot, weight);
526     }
527     
528     template<typename T> // T = Node* or Edge
529     void substitute(BasicBlock& block, unsigned startIndexInBlock, T oldThing, T newThing)
530     {
531         for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
532             Node* node = block[indexInBlock];
533             if (node->flags() & NodeHasVarArgs) {
534                 for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); ++childIdx) {
535                     if (!!m_varArgChildren[childIdx])
536                         compareAndSwap(m_varArgChildren[childIdx], oldThing, newThing);
537                 }
538                 continue;
539             }
540             if (!node->child1())
541                 continue;
542             compareAndSwap(node->children.child1(), oldThing, newThing);
543             if (!node->child2())
544                 continue;
545             compareAndSwap(node->children.child2(), oldThing, newThing);
546             if (!node->child3())
547                 continue;
548             compareAndSwap(node->children.child3(), oldThing, newThing);
549         }
550     }
551     
552     // Use this if you introduce a new GetLocal and you know that you introduced it *before*
553     // any GetLocals in the basic block.
554     // FIXME: it may be appropriate, in the future, to generalize this to handle GetLocals
555     // introduced anywhere in the basic block.
556     void substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, Node* newGetLocal);
557     
558     void invalidateCFG();
559     
560     void clearFlagsOnAllNodes(NodeFlags);
561     
562     void clearReplacements();
563     void clearEpochs();
564     void initializeNodeOwners();
565     
566     BlockList blocksInPreOrder();
567     BlockList blocksInPostOrder();
568     
569     class NaturalBlockIterable {
570     public:
571         NaturalBlockIterable()
572             : m_graph(nullptr)
573         {
574         }
575         
576         NaturalBlockIterable(Graph& graph)
577             : m_graph(&graph)
578         {
579         }
580         
581         class iterator {
582         public:
583             iterator()
584                 : m_graph(nullptr)
585                 , m_index(0)
586             {
587             }
588             
589             iterator(Graph& graph, BlockIndex index)
590                 : m_graph(&graph)
591                 , m_index(findNext(index))
592             {
593             }
594             
595             BasicBlock *operator*()
596             {
597                 return m_graph->block(m_index);
598             }
599             
600             iterator& operator++()
601             {
602                 m_index = findNext(m_index + 1);
603                 return *this;
604             }
605             
606             bool operator==(const iterator& other) const
607             {
608                 return m_index == other.m_index;
609             }
610             
611             bool operator!=(const iterator& other) const
612             {
613                 return !(*this == other);
614             }
615             
616         private:
617             BlockIndex findNext(BlockIndex index)
618             {
619                 while (index < m_graph->numBlocks() && !m_graph->block(index))
620                     index++;
621                 return index;
622             }
623             
624             Graph* m_graph;
625             BlockIndex m_index;
626         };
627         
628         iterator begin()
629         {
630             return iterator(*m_graph, 0);
631         }
632         
633         iterator end()
634         {
635             return iterator(*m_graph, m_graph->numBlocks());
636         }
637         
638     private:
639         Graph* m_graph;
640     };
641     
642     NaturalBlockIterable blocksInNaturalOrder()
643     {
644         return NaturalBlockIterable(*this);
645     }
646     
647     template<typename ChildFunctor>
648     void doToChildrenWithNode(Node* node, const ChildFunctor& functor)
649     {
650         DFG_NODE_DO_TO_CHILDREN(*this, node, functor);
651     }
652     
653     template<typename ChildFunctor>
654     void doToChildren(Node* node, const ChildFunctor& functor)
655     {
656         doToChildrenWithNode(
657             node,
658             [&functor] (Node*, Edge& edge) {
659                 functor(edge);
660             });
661     }
662     
663     bool uses(Node* node, Node* child)
664     {
665         bool result = false;
666         doToChildren(node, [&] (Edge edge) { result |= edge == child; });
667         return result;
668     }
669     
670     Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
671     
672     DesiredIdentifiers& identifiers() { return m_plan.identifiers; }
673     DesiredWatchpoints& watchpoints() { return m_plan.watchpoints; }
674     
675     // Returns false if the key is already invalid or unwatchable. If this is a Presence condition,
676     // this also makes it cheap to query if the condition holds. Also makes sure that the GC knows
677     // what's going on.
678     bool watchCondition(const ObjectPropertyCondition&);
679
680     // Checks if it's known that loading from the given object at the given offset is fine. This is
681     // computed by tracking which conditions we track with watchCondition().
682     bool isSafeToLoad(JSObject* base, PropertyOffset);
683
684     void registerInferredType(const InferredType::Descriptor& type)
685     {
686         if (type.structure())
687             registerStructure(type.structure());
688     }
689
690     // Tells us what inferred type we are able to prove the property to have now and in the future.
691     InferredType::Descriptor inferredTypeFor(const PropertyTypeKey&);
692     InferredType::Descriptor inferredTypeForProperty(Structure* structure, UniquedStringImpl* uid)
693     {
694         return inferredTypeFor(PropertyTypeKey(structure, uid));
695     }
696
697     AbstractValue inferredValueForProperty(
698         const StructureSet& base, UniquedStringImpl* uid, StructureClobberState = StructuresAreWatched);
699
700     // This uses either constant property inference or property type inference to derive a good abstract
701     // value for some property accessed with the given abstract value base.
702     AbstractValue inferredValueForProperty(
703         const AbstractValue& base, UniquedStringImpl* uid, PropertyOffset, StructureClobberState);
704     
705     FullBytecodeLiveness& livenessFor(CodeBlock*);
706     FullBytecodeLiveness& livenessFor(InlineCallFrame*);
707     
708     // Quickly query if a single local is live at the given point. This is faster than calling
709     // forAllLiveInBytecode() if you will only query one local. But, if you want to know all of the
710     // locals live, then calling this for each local is much slower than forAllLiveInBytecode().
711     bool isLiveInBytecode(VirtualRegister, CodeOrigin);
712     
713     // Quickly get all of the non-argument locals live at the given point. This doesn't give you
714     // any arguments because those are all presumed live. You can call forAllLiveInBytecode() to
715     // also get the arguments. This is much faster than calling isLiveInBytecode() for each local.
716     template<typename Functor>
717     void forAllLocalsLiveInBytecode(CodeOrigin codeOrigin, const Functor& functor)
718     {
719         // Support for not redundantly reporting arguments. Necessary because in case of a varargs
720         // call, only the callee knows that arguments are live while in the case of a non-varargs
721         // call, both callee and caller will see the variables live.
722         VirtualRegister exclusionStart;
723         VirtualRegister exclusionEnd;
724
725         CodeOrigin* codeOriginPtr = &codeOrigin;
726         
727         for (;;) {
728             InlineCallFrame* inlineCallFrame = codeOriginPtr->inlineCallFrame;
729             VirtualRegister stackOffset(inlineCallFrame ? inlineCallFrame->stackOffset : 0);
730             
731             if (inlineCallFrame) {
732                 if (inlineCallFrame->isClosureCall)
733                     functor(stackOffset + JSStack::Callee);
734                 if (inlineCallFrame->isVarargs())
735                     functor(stackOffset + JSStack::ArgumentCount);
736             }
737             
738             CodeBlock* codeBlock = baselineCodeBlockFor(inlineCallFrame);
739             FullBytecodeLiveness& fullLiveness = livenessFor(codeBlock);
740             const FastBitVector& liveness = fullLiveness.getLiveness(codeOriginPtr->bytecodeIndex);
741             for (unsigned relativeLocal = codeBlock->m_numCalleeRegisters; relativeLocal--;) {
742                 VirtualRegister reg = stackOffset + virtualRegisterForLocal(relativeLocal);
743                 
744                 // Don't report if our callee already reported.
745                 if (reg >= exclusionStart && reg < exclusionEnd)
746                     continue;
747                 
748                 if (liveness.get(relativeLocal))
749                     functor(reg);
750             }
751             
752             if (!inlineCallFrame)
753                 break;
754
755             // Arguments are always live. This would be redundant if it wasn't for our
756             // op_call_varargs inlining. See the comment above.
757             exclusionStart = stackOffset + CallFrame::argumentOffsetIncludingThis(0);
758             exclusionEnd = stackOffset + CallFrame::argumentOffsetIncludingThis(inlineCallFrame->arguments.size());
759             
760             // We will always have a "this" argument and exclusionStart should be a smaller stack
761             // offset than exclusionEnd.
762             ASSERT(exclusionStart < exclusionEnd);
763
764             for (VirtualRegister reg = exclusionStart; reg < exclusionEnd; reg += 1)
765                 functor(reg);
766             
767             codeOriginPtr = inlineCallFrame->getCallerSkippingTailCalls();
768
769             // The first inline call frame could be an inline tail call
770             if (!codeOriginPtr)
771                 break;
772         }
773     }
774     
775     // Get a BitVector of all of the non-argument locals live right now. This is mostly useful if
776     // you want to compare two sets of live locals from two different CodeOrigins.
777     BitVector localsLiveInBytecode(CodeOrigin);
778     
779     // Tells you all of the arguments and locals live at the given CodeOrigin. This is a small
780     // extension to forAllLocalsLiveInBytecode(), since all arguments are always presumed live.
781     template<typename Functor>
782     void forAllLiveInBytecode(CodeOrigin codeOrigin, const Functor& functor)
783     {
784         forAllLocalsLiveInBytecode(codeOrigin, functor);
785         
786         // Report all arguments as being live.
787         for (unsigned argument = block(0)->variablesAtHead.numberOfArguments(); argument--;)
788             functor(virtualRegisterForArgument(argument));
789     }
790     
791     BytecodeKills& killsFor(CodeBlock*);
792     BytecodeKills& killsFor(InlineCallFrame*);
793     
794     unsigned frameRegisterCount();
795     unsigned stackPointerOffset();
796     unsigned requiredRegisterCountForExit();
797     unsigned requiredRegisterCountForExecutionAndExit();
798     
799     JSValue tryGetConstantProperty(JSValue base, const StructureSet&, PropertyOffset);
800     JSValue tryGetConstantProperty(JSValue base, Structure*, PropertyOffset);
801     JSValue tryGetConstantProperty(JSValue base, const StructureAbstractValue&, PropertyOffset);
802     JSValue tryGetConstantProperty(const AbstractValue&, PropertyOffset);
803     
804     JSValue tryGetConstantClosureVar(JSValue base, ScopeOffset);
805     JSValue tryGetConstantClosureVar(const AbstractValue&, ScopeOffset);
806     JSValue tryGetConstantClosureVar(Node*, ScopeOffset);
807     
808     JSArrayBufferView* tryGetFoldableView(JSValue);
809     JSArrayBufferView* tryGetFoldableView(JSValue, ArrayMode arrayMode);
810     
811     void registerFrozenValues();
812     
813     virtual void visitChildren(SlotVisitor&) override;
814     
815     NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
816         std::nullptr_t, const char* file, int line, const char* function,
817         const char* assertion);
818     NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
819         Node*, const char* file, int line, const char* function,
820         const char* assertion);
821     NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
822         BasicBlock*, const char* file, int line, const char* function,
823         const char* assertion);
824
825     bool hasDebuggerEnabled() const { return m_hasDebuggerEnabled; }
826
827     void ensureDominators();
828     void ensurePrePostNumbering();
829     void ensureNaturalLoops();
830
831     VM& m_vm;
832     Plan& m_plan;
833     CodeBlock* m_codeBlock;
834     CodeBlock* m_profiledBlock;
835     
836     NodeAllocator& m_allocator;
837
838     Vector< RefPtr<BasicBlock> , 8> m_blocks;
839     Vector<Edge, 16> m_varArgChildren;
840
841     HashMap<EncodedJSValue, FrozenValue*, EncodedJSValueHash, EncodedJSValueHashTraits> m_frozenValueMap;
842     Bag<FrozenValue> m_frozenValues;
843
844     Vector<uint32_t> m_uint32ValuesInUse;
845     
846     Bag<StorageAccessData> m_storageAccessData;
847     
848     // In CPS, this is all of the SetArgument nodes for the arguments in the machine code block
849     // that survived DCE. All of them except maybe "this" will survive DCE, because of the Flush
850     // nodes.
851     //
852     // In SSA, this is all of the GetStack nodes for the arguments in the machine code block that
853     // may have some speculation in the prologue and survived DCE. Note that to get the speculation
854     // for an argument in SSA, you must use m_argumentFormats, since we still have to speculate
855     // even if the argument got killed. For example:
856     //
857     //     function foo(x) {
858     //        var tmp = x + 1;
859     //     }
860     //
861     // Assume that x is always int during profiling. The ArithAdd for "x + 1" will be dead and will
862     // have a proven check for the edge to "x". So, we will not insert a Check node and we will
863     // kill the GetStack for "x". But, we must do the int check in the progolue, because that's the
864     // thing we used to allow DCE of ArithAdd. Otherwise the add could be impure:
865     //
866     //     var o = {
867     //         valueOf: function() { do side effects; }
868     //     };
869     //     foo(o);
870     //
871     // If we DCE the ArithAdd and we remove the int check on x, then this won't do the side
872     // effects.
873     Vector<Node*, 8> m_arguments;
874     
875     // In CPS, this is meaningless. In SSA, this is the argument speculation that we've locked in.
876     Vector<FlushFormat> m_argumentFormats;
877     
878     SegmentedVector<VariableAccessData, 16> m_variableAccessData;
879     SegmentedVector<ArgumentPosition, 8> m_argumentPositions;
880     SegmentedVector<StructureSet, 16> m_structureSet;
881     Bag<Transition> m_transitions;
882     SegmentedVector<NewArrayBufferData, 4> m_newArrayBufferData;
883     Bag<BranchData> m_branchData;
884     Bag<SwitchData> m_switchData;
885     Bag<MultiGetByOffsetData> m_multiGetByOffsetData;
886     Bag<MultiPutByOffsetData> m_multiPutByOffsetData;
887     Bag<ObjectMaterializationData> m_objectMaterializationData;
888     Bag<CallVarargsData> m_callVarargsData;
889     Bag<LoadVarargsData> m_loadVarargsData;
890     Bag<StackAccessData> m_stackAccessData;
891     Vector<InlineVariableData, 4> m_inlineVariableData;
892     HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>> m_bytecodeLiveness;
893     HashMap<CodeBlock*, std::unique_ptr<BytecodeKills>> m_bytecodeKills;
894     HashSet<std::pair<JSObject*, PropertyOffset>> m_safeToLoad;
895     HashMap<PropertyTypeKey, InferredType::Descriptor> m_inferredTypes;
896     std::unique_ptr<Dominators> m_dominators;
897     std::unique_ptr<PrePostNumbering> m_prePostNumbering;
898     std::unique_ptr<NaturalLoops> m_naturalLoops;
899     std::unique_ptr<CFG> m_cfg;
900     unsigned m_localVars;
901     unsigned m_nextMachineLocal;
902     unsigned m_parameterSlots;
903
904 #if USE(JSVALUE32_64)
905     std::unordered_map<int64_t, double*> m_doubleConstantsMap;
906     std::unique_ptr<Bag<double>> m_doubleConstants;
907 #endif
908     
909     OptimizationFixpointState m_fixpointState;
910     StructureRegistrationState m_structureRegistrationState;
911     GraphForm m_form;
912     UnificationState m_unificationState;
913     PlanStage m_planStage { PlanStage::Initial };
914     RefCountState m_refCountState;
915     bool m_hasDebuggerEnabled;
916     bool m_hasExceptionHandlers { false };
917 private:
918
919     bool isStringPrototypeMethodSane(JSObject* stringPrototype, Structure* stringPrototypeStructure, UniquedStringImpl*);
920
921     void handleSuccessor(Vector<BasicBlock*, 16>& worklist, BasicBlock*, BasicBlock* successor);
922     
923     AddSpeculationMode addImmediateShouldSpeculateInt32(Node* add, bool variableShouldSpeculateInt32, Node* operand, Node*immediate, RareCaseProfilingSource source)
924     {
925         ASSERT(immediate->hasConstant());
926         
927         JSValue immediateValue = immediate->asJSValue();
928         if (!immediateValue.isNumber() && !immediateValue.isBoolean())
929             return DontSpeculateInt32;
930         
931         if (!variableShouldSpeculateInt32)
932             return DontSpeculateInt32;
933
934         // Integer constants can be typed Double if they are written like a double in the source code (e.g. 42.0).
935         // In that case, we stay conservative unless the other operand was explicitly typed as integer.
936         NodeFlags operandResultType = operand->result();
937         if (operandResultType != NodeResultInt32 && immediateValue.isDouble())
938             return DontSpeculateInt32;
939         
940         if (immediateValue.isBoolean() || jsNumber(immediateValue.asNumber()).isInt32())
941             return add->canSpeculateInt32(source) ? SpeculateInt32 : DontSpeculateInt32;
942         
943         double doubleImmediate = immediateValue.asDouble();
944         const double twoToThe48 = 281474976710656.0;
945         if (doubleImmediate < -twoToThe48 || doubleImmediate > twoToThe48)
946             return DontSpeculateInt32;
947         
948         return bytecodeCanTruncateInteger(add->arithNodeFlags()) ? SpeculateInt32AndTruncateConstants : DontSpeculateInt32;
949     }
950 };
951
952 } } // namespace JSC::DFG
953
954 #endif
955 #endif