Modernize for loops in JSC
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGStructureRegistrationPhase.cpp
1 /*
2  * Copyright (C) 2014-2016 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 "DFGStructureRegistrationPhase.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGBasicBlockInlines.h"
32 #include "DFGGraph.h"
33 #include "DFGPhase.h"
34 #include "JSCInlines.h"
35
36 namespace JSC { namespace DFG {
37
38 class StructureRegistrationPhase : public Phase {
39 public:
40     StructureRegistrationPhase(Graph& graph)
41         : Phase(graph, "structure registration")
42     {
43     }
44     
45     bool run()
46     {
47         // FIXME: This phase shouldn't exist. We should have registered all structures by now, since
48         // we may already have done optimizations that rely on structures having been registered.
49         // Currently, we still have places where we don't register structures prior to this phase,
50         // but structures don't end up being used for optimization prior to this phase. That's a
51         // pretty fragile situation and we should fix it eventually.
52         // https://bugs.webkit.org/show_bug.cgi?id=147889
53         
54         // We need to set this before this phase finishes. This phase doesn't do anything
55         // conditioned on this field, except for assertIsRegistered() below. We intend for that
56         // method to behave as if the phase was already finished. So, we set this up here.
57         m_graph.m_structureRegistrationState = AllStructuresAreRegistered;
58         
59         // These are pretty dumb, but needed to placate subsequent assertions. We don't actually
60         // have to watch these because there is no way to transition away from it, but they are
61         // watchable and so we will assert if they aren't watched.
62         registerStructure(m_graph.m_vm.structureStructure.get());
63         registerStructure(m_graph.m_vm.stringStructure.get());
64         registerStructure(m_graph.m_vm.symbolStructure.get());
65         
66         for (FrozenValue* value : m_graph.m_frozenValues)
67             assertIsRegistered(value->structure());
68         
69         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
70             BasicBlock* block = m_graph.block(blockIndex);
71             if (!block)
72                 continue;
73         
74             for (auto* node : *block) {
75                 switch (node->op()) {
76                 case CheckStructure:
77                     assertAreRegistered(node->structureSet());
78                     break;
79                 
80                 case NewObject:
81                 case ArrayifyToStructure:
82                 case NewStringObject:
83                     registerStructure(node->structure());
84                     break;
85                 
86                 case PutStructure:
87                 case AllocatePropertyStorage:
88                 case ReallocatePropertyStorage:
89                     registerStructure(node->transition()->previous);
90                     registerStructure(node->transition()->next);
91                     break;
92
93                 case GetGetterSetterByOffset:
94                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->getterSetterStructure());
95                     break;
96
97                 case MultiGetByOffset:
98                     for (const MultiGetByOffsetCase& getCase : node->multiGetByOffsetData().cases)
99                         registerStructures(getCase.set());
100                     break;
101                     
102                 case MultiPutByOffset:
103                     for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
104                         PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
105                         registerStructures(variant.oldStructure());
106                         if (variant.kind() == PutByIdVariant::Transition)
107                             registerStructure(variant.newStructure());
108                     }
109                     break;
110                     
111                 case NewArray:
112                 case NewArrayBuffer:
113                 case NewArrayWithSize: {
114                     JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
115                     registerStructure(globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
116                     registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
117                     break;
118                 }
119
120                 case NewArrayWithSpread: {
121                     JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
122                     if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
123                         // We've compiled assuming we're not having a bad time, so to be consistent
124                         // with AI we must say we produce an original array allocation structure.
125                         registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous));
126                     } else
127                         registerStructure(globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous));
128                     break;
129                 }
130
131                 case Spread: {
132                     registerStructure(m_graph.m_vm.fixedArrayStructure.get());
133                     break;
134                 }
135
136                 case CreateRest: {
137                     if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
138                         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
139                         registerStructure(globalObject->restParameterStructure());
140                     }
141                     break;
142                 }
143                     
144                 case NewTypedArray:
145                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructureConcurrently(node->typedArrayType()));
146                     break;
147                     
148                 case ToString:
149                 case CallStringConstructor:
150                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
151                     break;
152                     
153                 case CreateActivation:
154                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->activationStructure());
155                     break;
156                     
157                 case CreateDirectArguments:
158                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->directArgumentsStructure());
159                     break;
160                     
161                 case CreateScopedArguments:
162                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
163                     break;
164
165                 case CreateClonedArguments:
166                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->clonedArgumentsStructure());
167                     break;
168
169                 case NewRegexp:
170                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
171                     break;
172                 case NewFunction:
173                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure());
174                     break;
175                 case NewGeneratorFunction:
176                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->generatorFunctionStructure());
177                     break;
178                 case NewAsyncFunction:
179                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->asyncFunctionStructure());
180                     break;
181
182                 default:
183                     break;
184                 }
185             }
186         }
187         
188         return true;
189     }
190
191 private:
192     void registerStructures(const StructureSet& set)
193     {
194         for (Structure* structure : set)
195             registerStructure(structure);
196     }
197     
198     void registerStructure(Structure* structure)
199     {
200         if (structure)
201             m_graph.registerStructure(structure);
202     }
203
204     void assertAreRegistered(const StructureSet& set)
205     {
206         for (Structure* structure : set)
207             assertIsRegistered(structure);
208     }
209
210     void assertIsRegistered(Structure* structure)
211     {
212         if (structure)
213             m_graph.assertIsRegistered(structure);
214     }
215 };
216
217 bool performStructureRegistration(Graph& graph)
218 {
219     return runPhase<StructureRegistrationPhase>(graph);
220 }
221
222 } } // namespace JSC::DFG
223
224 #endif // ENABLE(DFG_JIT)
225