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