Changeset 48264 in webkit for trunk/JavaScriptCore/runtime
- Timestamp:
- Sep 10, 2009, 1:01:57 PM (16 years ago)
- Location:
- trunk/JavaScriptCore/runtime
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/Structure.cpp
r47605 r48264 131 131 , m_isPinnedPropertyTable(false) 132 132 , m_hasGetterSetterProperties(false) 133 , m_usingSingleTransitionSlot(true)134 133 , m_attributesInPrevious(0) 135 134 { 136 135 ASSERT(m_prototype); 137 136 ASSERT(m_prototype.isObject() || m_prototype.isNull()); 138 139 m_transitions.singleTransition = 0;140 137 141 138 #ifndef NDEBUG … … 156 153 Structure::~Structure() 157 154 { 158 if (m_previous) { 159 if (m_previous->m_usingSingleTransitionSlot) { 160 m_previous->m_transitions.singleTransition = 0; 161 } else { 162 ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious)); 163 m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious); 164 } 165 } 155 if (m_previous) 156 m_previous->table.remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious); 166 157 167 158 if (m_cachedPropertyNameArrayData) 168 159 m_cachedPropertyNameArrayData->setCachedStructure(0); 169 170 if (!m_usingSingleTransitionSlot)171 delete m_transitions.table;172 160 173 161 if (m_propertyTable) { … … 382 370 ASSERT(structure->typeInfo().type() == ObjectType); 383 371 384 if (structure->m_usingSingleTransitionSlot) { 385 Structure* existingTransition = structure->m_transitions.singleTransition; 386 if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep() 387 && existingTransition->m_attributesInPrevious == attributes 388 && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0)) { 389 390 ASSERT(structure->m_transitions.singleTransition->m_offset != noOffset); 391 offset = structure->m_transitions.singleTransition->m_offset; 392 return existingTransition; 393 } 394 } else { 395 if (Structure* existingTransition = structure->m_transitions.table->get(make_pair(propertyName.ustring().rep(), attributes), specificValue)) { 396 ASSERT(existingTransition->m_offset != noOffset); 397 offset = existingTransition->m_offset; 398 return existingTransition; 399 } 372 if (Structure* existingTransition = structure->table.get(make_pair(propertyName.ustring().rep(), attributes), specificValue)) { 373 ASSERT(existingTransition->m_offset != noOffset); 374 offset = existingTransition->m_offset; 375 return existingTransition; 400 376 } 401 377 … … 448 424 transition->m_offset = offset; 449 425 450 if (structure->m_usingSingleTransitionSlot) { 451 if (!structure->m_transitions.singleTransition) { 452 structure->m_transitions.singleTransition = transition.get(); 453 return transition.release(); 454 } 455 456 Structure* existingTransition = structure->m_transitions.singleTransition; 457 structure->m_usingSingleTransitionSlot = false; 458 StructureTransitionTable* transitionTable = new StructureTransitionTable; 459 structure->m_transitions.table = transitionTable; 460 transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious); 461 } 462 structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get(), specificValue); 426 structure->table.add(make_pair(propertyName.ustring().rep(), attributes), transition.get(), specificValue); 463 427 return transition.release(); 464 428 } … … 559 523 size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) 560 524 { 561 ASSERT(!m_transitions.singleTransition);562 563 525 materializePropertyMapIfNecessary(); 564 526 … … 573 535 size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName) 574 536 { 575 ASSERT(!m_transitions.singleTransition);576 537 ASSERT(m_isDictionary); 577 538 … … 830 791 bool Structure::hasTransition(UString::Rep* rep, unsigned attributes) 831 792 { 832 if (m_usingSingleTransitionSlot) { 833 return m_transitions.singleTransition 834 && m_transitions.singleTransition->m_nameInPrevious == rep 835 && m_transitions.singleTransition->m_attributesInPrevious == attributes; 836 } 837 return m_transitions.table->hasTransition(make_pair(rep, attributes)); 793 return table.hasTransition(make_pair(rep, attributes)); 838 794 } 839 795 -
trunk/JavaScriptCore/runtime/Structure.h
r48207 r48264 53 53 public: 54 54 friend class JIT; 55 friend class StructureTransitionTable; 55 56 static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo) 56 57 { … … 175 176 JSCell* m_specificValueInPrevious; 176 177 177 union { 178 Structure* singleTransition; 179 StructureTransitionTable* table; 180 } m_transitions; 178 StructureTransitionTable table; 181 179 182 180 RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData; … … 190 188 bool m_isPinnedPropertyTable : 1; 191 189 bool m_hasGetterSetterProperties : 1; 192 bool m_usingSingleTransitionSlot : 1;193 190 unsigned m_attributesInPrevious : 7; 194 191 }; … … 241 238 bool StructureTransitionTable::contains(const StructureTransitionTableHash::Key& key, JSCell* specificValue) 242 239 { 243 TransitionTable::iterator find = m_table.find(key); 244 if (find == m_table.end()) 240 if (usingSingleTransitionSlot()) { 241 Structure* existingTransition = singleTransition(); 242 return existingTransition && existingTransition->m_nameInPrevious.get() == key.first 243 && existingTransition->m_attributesInPrevious == key.second 244 && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0); 245 } 246 TransitionTable::iterator find = table()->find(key); 247 if (find == table()->end()) 245 248 return false; 246 249 … … 250 253 Structure* StructureTransitionTable::get(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const 251 254 { 252 Transition transition = m_table.get(key); 255 if (usingSingleTransitionSlot()) { 256 Structure* existingTransition = singleTransition(); 257 if (existingTransition && existingTransition->m_nameInPrevious.get() == key.first 258 && existingTransition->m_attributesInPrevious == key.second 259 && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0)) 260 return existingTransition; 261 return 0; 262 } 263 264 Transition transition = table()->get(key); 253 265 if (transition.second && transition.second->transitionedFor(specificValue)) 254 266 return transition.second; 255 267 return transition.first; 256 268 } 269 270 bool StructureTransitionTable::hasTransition(const StructureTransitionTableHash::Key& key) const 271 { 272 if (usingSingleTransitionSlot()) { 273 Structure* transition = singleTransition(); 274 return transition && transition->m_nameInPrevious == key.first 275 && transition->m_attributesInPrevious == key.second; 276 } 277 return table()->contains(key); 278 } 279 280 void StructureTransitionTable::reifySingleTransition() 281 { 282 ASSERT(usingSingleTransitionSlot()); 283 Structure* existingTransition = singleTransition(); 284 ASSERT(existingTransition); 285 TransitionTable* transitionTable = new TransitionTable; 286 setTransitionTable(transitionTable); 287 add(make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious); 288 } 257 289 } // namespace JSC 258 290 -
trunk/JavaScriptCore/runtime/StructureTransitionTable.h
r47605 r48264 31 31 #include <wtf/HashMap.h> 32 32 #include <wtf/HashTraits.h> 33 #include <wtf/PtrAndFlags.h> 33 34 #include <wtf/RefPtr.h> 34 35 … … 70 71 typedef HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> TransitionTable; 71 72 public: 73 StructureTransitionTable() { 74 m_transitions.m_singleTransition.set(0); 75 m_transitions.m_singleTransition.setFlag(0); 76 } 77 78 ~StructureTransitionTable() { 79 if (!usingSingleTransitionSlot()) 80 delete table(); 81 } 82 72 83 // The contains and get methods accept imprecise matches, so if an unspecialised transition exists 73 84 // for the given key they will consider that transition to be a match. If a specialised transition … … 75 86 inline bool contains(const StructureTransitionTableHash::Key&, JSCell* specificValue); 76 87 inline Structure* get(const StructureTransitionTableHash::Key&, JSCell* specificValue) const; 77 bool hasTransition(const StructureTransitionTableHash::Key& key) 78 { 79 return m_table.contains(key); 80 } 88 inline bool hasTransition(const StructureTransitionTableHash::Key& key) const; 81 89 void remove(const StructureTransitionTableHash::Key& key, JSCell* specificValue) 82 90 { 83 TransitionTable::iterator find = m_table.find(key); 91 if (usingSingleTransitionSlot()) { 92 ASSERT(contains(key, specificValue)); 93 setSingleTransition(0); 94 return; 95 } 96 TransitionTable::iterator find = table()->find(key); 84 97 if (!specificValue) 85 98 find->second.first = 0; … … 87 100 find->second.second = 0; 88 101 if (!find->second.first && !find->second.second) 89 m_table.remove(find);102 table()->remove(find); 90 103 } 91 104 void add(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue) 92 105 { 106 if (usingSingleTransitionSlot()) { 107 if (!singleTransition()) { 108 setSingleTransition(structure); 109 return; 110 } 111 reifySingleTransition(); 112 } 93 113 if (!specificValue) { 94 TransitionTable::iterator find = m_table.find(key);95 if (find == m_table.end())96 m_table.add(key, Transition(structure, 0));114 TransitionTable::iterator find = table()->find(key); 115 if (find == table()->end()) 116 table()->add(key, Transition(structure, 0)); 97 117 else 98 118 find->second.first = structure; … … 100 120 // If we're adding a transition to a specific value, then there cannot be 101 121 // an existing transition 102 ASSERT(! m_table.contains(key));103 m_table.add(key, Transition(0, structure));122 ASSERT(!table()->contains(key)); 123 table()->add(key, Transition(0, structure)); 104 124 } 105 106 125 } 107 126 private: 108 TransitionTable m_table; 127 TransitionTable* table() const { ASSERT(!usingSingleTransitionSlot()); return m_transitions.m_table; } 128 Structure* singleTransition() const { 129 ASSERT(usingSingleTransitionSlot()); 130 return m_transitions.m_singleTransition.get(); 131 } 132 bool usingSingleTransitionSlot() const { return m_transitions.m_singleTransition.isFlagSet(0); } 133 void setSingleTransition(Structure* structure) 134 { 135 ASSERT(usingSingleTransitionSlot()); 136 m_transitions.m_singleTransition.set(structure); 137 } 138 139 void setTransitionTable(TransitionTable* table) 140 { 141 ASSERT(usingSingleTransitionSlot()); 142 #ifndef NDEBUG 143 setSingleTransition(0); 144 #endif 145 m_transitions.m_table = table; 146 // This implicitly clears the flag that indicates we're using a single transition 147 ASSERT(!usingSingleTransitionSlot()); 148 } 149 inline void reifySingleTransition(); 150 151 // Last bit indicates whether we are using the single transition optimisation 152 union { 153 TransitionTable* m_table; 154 PtrAndFlagsBase<Structure, bool> m_singleTransition; 155 } m_transitions; 109 156 }; 110 157
Note:
See TracChangeset
for help on using the changeset viewer.