a636636577bd53d934211a74c0fed6f5d86a47e8
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGWatchpointCollectionPhase.cpp
1 /*
2  * Copyright (C) 2013 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
28 #if ENABLE(DFG_JIT)
29
30 #include "DFGWatchpointCollectionPhase.h"
31
32 #include "ArrayPrototype.h"
33 #include "DFGClobberize.h"
34 #include "DFGGraph.h"
35 #include "DFGPhase.h"
36 #include "JSCInlines.h"
37
38 namespace JSC { namespace DFG {
39
40 class WatchpointCollectionPhase : public Phase {
41     static const bool verbose = false;
42     
43 public:
44     WatchpointCollectionPhase(Graph& graph)
45         : Phase(graph, "watchpoint collection")
46     {
47     }
48     
49     bool run()
50     {
51         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
52             BasicBlock* block = m_graph.block(blockIndex);
53             if (!block)
54                 continue;
55             
56             for (unsigned nodeIndex = block->size(); nodeIndex--;) {
57                 m_node = block->at(nodeIndex);
58                 handle();
59             }
60         }
61         
62         return true;
63     }
64
65 private:
66     void handle()
67     {
68         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, handleEdge);
69         
70         switch (m_node->op()) {
71         case CompareEqConstant:
72         case IsUndefined:
73             handleMasqueradesAsUndefined();
74             break;
75             
76         case CompareEq:
77             if (m_node->isBinaryUseKind(ObjectUse)
78                 || (m_node->child1().useKind() == ObjectUse && m_node->child2().useKind() == ObjectOrOtherUse)
79                 || (m_node->child1().useKind() == ObjectOrOtherUse && m_node->child2().useKind() == ObjectUse))
80                 handleMasqueradesAsUndefined();
81             break;
82             
83         case LogicalNot:
84         case Branch:
85             if (m_node->child1().useKind() == ObjectOrOtherUse)
86                 handleMasqueradesAsUndefined();
87             break;
88             
89         case GetByVal:
90             if (m_node->arrayMode().type() == Array::Double
91                 && m_node->arrayMode().isSaneChain()) {
92                 addLazily(globalObject()->arrayPrototype()->structure()->transitionWatchpointSet());
93                 addLazily(globalObject()->objectPrototype()->structure()->transitionWatchpointSet());
94             }
95             
96             if (m_node->arrayMode().type() == Array::String)
97                 handleStringGetByVal();
98
99             if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node))
100                 addLazily(view);
101             break;
102             
103         case PutByVal:
104             if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node))
105                 addLazily(view);
106             break;
107             
108         case StringCharAt:
109             handleStringGetByVal();
110             break;
111             
112         case NewArray:
113         case NewArrayWithSize:
114         case NewArrayBuffer:
115             if (!globalObject()->isHavingABadTime() && !hasArrayStorage(m_node->indexingType()))
116                 addLazily(globalObject()->havingABadTimeWatchpoint());
117             break;
118             
119         case AllocationProfileWatchpoint:
120             addLazily(jsCast<JSFunction*>(m_node->function())->allocationProfileWatchpointSet());
121             break;
122             
123         case StructureTransitionWatchpoint:
124             m_graph.watchpoints().addLazily(
125                 m_node->origin.semantic,
126                 m_node->child1()->op() == WeakJSConstant ? BadWeakConstantCacheWatchpoint : BadCacheWatchpoint,
127                 m_node->structure()->transitionWatchpointSet());
128             break;
129             
130         case VariableWatchpoint:
131             addLazily(m_node->variableWatchpointSet());
132             break;
133             
134         case VarInjectionWatchpoint:
135             addLazily(globalObject()->varInjectionWatchpoint());
136             break;
137             
138         case FunctionReentryWatchpoint:
139             addLazily(m_node->symbolTable()->m_functionEnteredOnce);
140             break;
141             
142         case TypedArrayWatchpoint:
143             addLazily(m_node->typedArray());
144             break;
145             
146         default:
147             break;
148         }
149     }
150     
151     void handleEdge(Node*, Edge edge)
152     {
153         switch (edge.useKind()) {
154         case StringObjectUse:
155         case StringOrStringObjectUse: {
156             Structure* stringObjectStructure = globalObject()->stringObjectStructure();
157             Structure* stringPrototypeStructure = stringObjectStructure->storedPrototype().asCell()->structure();
158             ASSERT(m_graph.watchpoints().isValidOrMixed(stringPrototypeStructure->transitionWatchpointSet()));
159             
160             m_graph.watchpoints().addLazily(
161                 m_node->origin.semantic, NotStringObject,
162                 stringPrototypeStructure->transitionWatchpointSet());
163             break;
164         }
165             
166         default:
167             break;
168         }
169     }
170     
171     void handleMasqueradesAsUndefined()
172     {
173         if (m_graph.masqueradesAsUndefinedWatchpointIsStillValid(m_node->origin.semantic))
174             addLazily(globalObject()->masqueradesAsUndefinedWatchpoint());
175     }
176     
177     void handleStringGetByVal()
178     {
179         if (!m_node->arrayMode().isOutOfBounds())
180             return;
181         if (!globalObject()->stringPrototypeChainIsSane())
182             return;
183         addLazily(globalObject()->stringPrototype()->structure()->transitionWatchpointSet());
184         addLazily(globalObject()->objectPrototype()->structure()->transitionWatchpointSet());
185     }
186
187     void addLazily(WatchpointSet* set)
188     {
189         m_graph.watchpoints().addLazily(set);
190     }
191     void addLazily(InlineWatchpointSet& set)
192     {
193         m_graph.watchpoints().addLazily(set);
194     }
195     void addLazily(JSArrayBufferView* view)
196     {
197         m_graph.watchpoints().addLazily(view);
198     }
199     
200     JSGlobalObject* globalObject()
201     {
202         return m_graph.globalObjectFor(m_node->origin.semantic);
203     }
204     
205     Node* m_node;
206 };
207
208 bool performWatchpointCollection(Graph& graph)
209 {
210     SamplingRegion samplingRegion("DFG Watchpoint Collection Phase");
211     return runPhase<WatchpointCollectionPhase>(graph);
212 }
213
214 } } // namespace JSC::DFG
215
216 #endif // ENABLE(DFG_JIT)
217