DFG should have some facility for recognizing redundant CheckArrays and Arrayifies
[WebKit-https.git] / Source / JavaScriptCore / bytecode / StructureSet.h
1 /*
2  * Copyright (C) 2011 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 #ifndef StructureSet_h
27 #define StructureSet_h
28
29 #include "ArrayProfile.h"
30 #include "SpeculatedType.h"
31 #include "Structure.h"
32 #include <stdio.h>
33 #include <wtf/Vector.h>
34
35 namespace JSC {
36
37 namespace DFG {
38 class StructureAbstractValue;
39 }
40
41 class StructureSet {
42 public:
43     StructureSet() { }
44     
45     StructureSet(Structure* structure)
46     {
47         m_structures.append(structure);
48     }
49     
50     void clear()
51     {
52         m_structures.clear();
53     }
54     
55     void add(Structure* structure)
56     {
57         ASSERT(!contains(structure));
58         m_structures.append(structure);
59     }
60     
61     bool addAll(const StructureSet& other)
62     {
63         bool changed = false;
64         for (size_t i = 0; i < other.size(); ++i) {
65             if (contains(other[i]))
66                 continue;
67             add(other[i]);
68             changed = true;
69         }
70         return changed;
71     }
72     
73     void remove(Structure* structure)
74     {
75         for (size_t i = 0; i < m_structures.size(); ++i) {
76             if (m_structures[i] != structure)
77                 continue;
78             
79             m_structures[i] = m_structures.last();
80             m_structures.removeLast();
81             return;
82         }
83     }
84     
85     bool contains(Structure* structure) const
86     {
87         for (size_t i = 0; i < m_structures.size(); ++i) {
88             if (m_structures[i] == structure)
89                 return true;
90         }
91         return false;
92     }
93     
94     bool containsOnly(Structure* structure) const
95     {
96         if (size() != 1)
97             return false;
98         return singletonStructure() == structure;
99     }
100     
101     bool isSubsetOf(const StructureSet& other) const
102     {
103         for (size_t i = 0; i < m_structures.size(); ++i) {
104             if (!other.contains(m_structures[i]))
105                 return false;
106         }
107         return true;
108     }
109     
110     bool isSupersetOf(const StructureSet& other) const
111     {
112         return other.isSubsetOf(*this);
113     }
114     
115     size_t size() const { return m_structures.size(); }
116     
117     // Call this if you know that the structure set must consist of exactly
118     // one structure.
119     Structure* singletonStructure() const
120     {
121         ASSERT(m_structures.size() == 1);
122         return m_structures[0];
123     }
124     
125     Structure* at(size_t i) const { return m_structures.at(i); }
126     
127     Structure* operator[](size_t i) const { return at(i); }
128     
129     Structure* last() const { return m_structures.last(); }
130
131     SpeculatedType speculationFromStructures() const
132     {
133         SpeculatedType result = SpecNone;
134         
135         for (size_t i = 0; i < m_structures.size(); ++i)
136             mergeSpeculation(result, speculationFromStructure(m_structures[i]));
137         
138         return result;
139     }
140     
141     ArrayModes arrayModesFromStructures() const
142     {
143         ArrayModes result = 0;
144         
145         for (size_t i = 0; i < m_structures.size(); ++i)
146             mergeArrayModes(result, asArrayModes(m_structures[i]->indexingType()));
147         
148         return result;
149     }
150     
151     bool operator==(const StructureSet& other) const
152     {
153         if (m_structures.size() != other.m_structures.size())
154             return false;
155         
156         for (size_t i = 0; i < m_structures.size(); ++i) {
157             if (!other.contains(m_structures[i]))
158                 return false;
159         }
160         
161         return true;
162     }
163     
164     void dump(FILE* out)
165     {
166         fprintf(out, "[");
167         for (size_t i = 0; i < m_structures.size(); ++i) {
168             if (i)
169                 fprintf(out, ", ");
170             fprintf(out, "%p", m_structures[i]);
171         }
172         fprintf(out, "]");
173     }
174     
175 private:
176     friend class DFG::StructureAbstractValue;
177     
178     Vector<Structure*, 2> m_structures;
179 };
180
181 } // namespace JSC
182
183 #endif // StructureSet_h