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