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