Unreviewed, rolling out r172940.
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGStructureRegistrationPhase.cpp
1 /*
2  * Copyright (C) 2014 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         // These are pretty dumb, but needed to placate subsequent assertions. We don't actually
48         // have to watch these because there is no way to transition away from it, but they are
49         // watchable and so we will assert if they aren't watched.
50         registerStructure(m_graph.m_vm.stringStructure.get());
51         registerStructure(m_graph.m_vm.getterSetterStructure.get());
52         
53         for (FrozenValue* value : m_graph.m_frozenValues)
54             registerStructure(value->structure());
55         
56         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
57             BasicBlock* block = m_graph.block(blockIndex);
58             if (!block)
59                 continue;
60         
61             for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
62                 Node* node = block->at(nodeIndex);
63             
64                 switch (node->op()) {
65                 case CheckExecutable:
66                     registerStructure(node->executable()->structure());
67                     break;
68                 
69                 case CheckStructure:
70                     registerStructures(node->structureSet());
71                     break;
72                 
73                 case NewObject:
74                 case ArrayifyToStructure:
75                 case NewStringObject:
76                     registerStructure(node->structure());
77                     break;
78                 
79                 case PutStructure:
80                 case AllocatePropertyStorage:
81                 case ReallocatePropertyStorage:
82                     registerStructure(node->transition()->previous);
83                     registerStructure(node->transition()->next);
84                     break;
85                     
86                 case MultiGetByOffset:
87                     for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
88                         GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
89                         registerStructures(variant.structureSet());
90                         // Don't need to watch anything in the structure chain because that would
91                         // have been decomposed into CheckStructure's. Don't need to watch the
92                         // callLinkStatus because we wouldn't use MultiGetByOffset if any of the
93                         // variants did that.
94                         ASSERT(!variant.callLinkStatus());
95                     }
96                     break;
97                     
98                 case MultiPutByOffset:
99                     for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
100                         PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
101                         registerStructures(variant.oldStructure());
102                         if (variant.kind() == PutByIdVariant::Transition)
103                             registerStructure(variant.newStructure());
104                     }
105                     break;
106                     
107                 case NewArray:
108                 case NewArrayBuffer:
109                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
110                     break;
111                     
112                 case NewTypedArray:
113                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(node->typedArrayType()));
114                     break;
115                     
116                 case ToString:
117                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
118                     break;
119                     
120                 case CreateActivation:
121                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->activationStructure());
122                     break;
123                     
124                 case NewRegexp:
125                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
126                     break;
127                     
128                 case NewFunctionExpression:
129                 case NewFunctionNoCheck:
130                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure());
131                     break;
132                     
133                 default:
134                     break;
135                 }
136             }
137         }
138         
139         m_graph.m_structureRegistrationState = AllStructuresAreRegistered;
140         
141         return true;
142     }
143
144 private:
145     void registerStructures(const StructureSet& set)
146     {
147         for (unsigned i = set.size(); i--;)
148             registerStructure(set[i]);
149     }
150     
151     void registerStructure(Structure* structure)
152     {
153         if (structure)
154             m_graph.registerStructure(structure);
155     }
156 };
157
158 bool performStructureRegistration(Graph& graph)
159 {
160     SamplingRegion samplingRegion("DFG Structure Registration Phase");
161     return runPhase<StructureRegistrationPhase>(graph);
162 }
163
164 } } // namespace JSC::DFG
165
166 #endif // ENABLE(DFG_JIT)
167