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