1/* 2 * Copyright (C) 2011, 2012, 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 DFGStructureAbstractValue_h 27#define DFGStructureAbstractValue_h 28 29#include <wtf/Platform.h> 30 31#if ENABLE(DFG_JIT) 32 33#include "JSCell.h" 34#include "SpeculatedType.h" 35#include "StructureSet.h" 36 37namespace JSC { namespace DFG { 38 39class StructureAbstractValue { 40public: 41 StructureAbstractValue() 42 : m_structure(0) 43 { 44 } 45 46 StructureAbstractValue(Structure* structure) 47 : m_structure(structure) 48 { 49 } 50 51 StructureAbstractValue(const StructureSet& set) 52 { 53 switch (set.size()) { 54 case 0: 55 m_structure = 0; 56 break; 57 58 case 1: 59 m_structure = set[0]; 60 break; 61 62 default: 63 m_structure = topValue(); 64 break; 65 } 66 } 67 68 void clear() 69 { 70 m_structure = 0; 71 } 72 73 void makeTop() 74 { 75 m_structure = topValue(); 76 } 77 78 static StructureAbstractValue top() 79 { 80 StructureAbstractValue value; 81 value.makeTop(); 82 return value; 83 } 84 85 void add(Structure* structure) 86 { 87 ASSERT(!contains(structure) && !isTop()); 88 if (m_structure) 89 makeTop(); 90 else 91 m_structure = structure; 92 } 93 94 bool addAll(const StructureSet& other) 95 { 96 if (isTop() || !other.size()) 97 return false; 98 if (other.size() > 1) { 99 makeTop(); 100 return true; 101 } 102 if (!m_structure) { 103 m_structure = other[0]; 104 return true; 105 } 106 if (m_structure == other[0]) 107 return false; 108 makeTop(); 109 return true; 110 } 111 112 bool addAll(const StructureAbstractValue& other) 113 { 114 if (!other.m_structure) 115 return false; 116 if (isTop()) 117 return false; 118 if (other.isTop()) { 119 makeTop(); 120 return true; 121 } 122 if (m_structure) { 123 if (m_structure == other.m_structure) 124 return false; 125 makeTop(); 126 return true; 127 } 128 m_structure = other.m_structure; 129 return true; 130 } 131 132 bool contains(Structure* structure) const 133 { 134 if (isTop()) 135 return true; 136 if (m_structure == structure) 137 return true; 138 return false; 139 } 140 141 bool isSubsetOf(const StructureSet& other) const 142 { 143 if (isTop()) 144 return false; 145 if (!m_structure) 146 return true; 147 return other.contains(m_structure); 148 } 149 150 bool doesNotContainAnyOtherThan(Structure* structure) const 151 { 152 if (isTop()) 153 return false; 154 if (!m_structure) 155 return true; 156 return m_structure == structure; 157 } 158 159 bool isSupersetOf(const StructureSet& other) const 160 { 161 if (isTop()) 162 return true; 163 if (!other.size()) 164 return true; 165 if (other.size() > 1) 166 return false; 167 return m_structure == other[0]; 168 } 169 170 bool isSubsetOf(const StructureAbstractValue& other) const 171 { 172 if (other.isTop()) 173 return true; 174 if (isTop()) 175 return false; 176 if (m_structure) { 177 if (other.m_structure) 178 return m_structure == other.m_structure; 179 return false; 180 } 181 return true; 182 } 183 184 bool isSupersetOf(const StructureAbstractValue& other) const 185 { 186 return other.isSubsetOf(*this); 187 } 188 189 void filter(const StructureSet& other) 190 { 191 if (!m_structure) 192 return; 193 194 if (isTop()) { 195 switch (other.size()) { 196 case 0: 197 m_structure = 0; 198 return; 199 200 case 1: 201 m_structure = other[0]; 202 return; 203 204 default: 205 return; 206 } 207 } 208 209 if (other.contains(m_structure)) 210 return; 211 212 m_structure = 0; 213 } 214 215 void filter(const StructureAbstractValue& other) 216 { 217 if (isTop()) { 218 m_structure = other.m_structure; 219 return; 220 } 221 if (m_structure == other.m_structure) 222 return; 223 if (other.isTop()) 224 return; 225 m_structure = 0; 226 } 227 228 void filter(SpeculatedType other) 229 { 230 if (!(other & SpecCell)) { 231 clear(); 232 return; 233 } 234 235 if (isClearOrTop()) 236 return; 237 238 if (!(speculationFromStructure(m_structure) & other)) 239 m_structure = 0; 240 } 241 242 bool isClear() const 243 { 244 return !m_structure; 245 } 246 247 bool isTop() const { return m_structure == topValue(); } 248 249 bool isClearOrTop() const { return m_structure <= topValue(); } 250 bool isNeitherClearNorTop() const { return !isClearOrTop(); } 251 252 size_t size() const 253 { 254 ASSERT(!isTop()); 255 return !!m_structure; 256 } 257 258 Structure* at(size_t i) const 259 { 260 ASSERT(!isTop()); 261 ASSERT(m_structure); 262 ASSERT_UNUSED(i, !i); 263 return m_structure; 264 } 265 266 Structure* operator[](size_t i) const 267 { 268 return at(i); 269 } 270 271 Structure* last() const 272 { 273 return at(0); 274 } 275 276 SpeculatedType speculationFromStructures() const 277 { 278 if (isTop()) 279 return SpecCell; 280 if (isClear()) 281 return SpecNone; 282 return speculationFromStructure(m_structure); 283 } 284 285 bool hasSingleton() const 286 { 287 return isNeitherClearNorTop(); 288 } 289 290 Structure* singleton() const 291 { 292 ASSERT(isNeitherClearNorTop()); 293 return m_structure; 294 } 295 296 bool operator==(const StructureAbstractValue& other) const 297 { 298 return m_structure == other.m_structure; 299 } 300 301 void dump(PrintStream& out) const 302 { 303 if (isTop()) { 304 out.print("TOP"); 305 return; 306 } 307 308 out.print("["); 309 if (m_structure) 310 out.print(RawPointer(m_structure), "(", m_structure->classInfo()->className, ")"); 311 out.print("]"); 312 } 313 314private: 315 static Structure* topValue() { return reinterpret_cast<Structure*>(1); } 316 317 // NB. This must have a trivial destructor. 318 319 // This can only remember one structure at a time. 320 Structure* m_structure; 321}; 322 323} } // namespace JSC::DFG 324 325#endif // ENABLE(DFG_JIT) 326 327#endif // DFGStructureAbstractValue_h 328 329 330