Changeset 37381 in webkit for trunk/JavaScriptCore/kjs/PropertyMap.cpp
- Timestamp:
- Oct 7, 2008, 11:17:37 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/PropertyMap.cpp
r37370 r37381 78 78 #if !DO_PROPERTYMAP_CONSTENCY_CHECK 79 79 80 inline void PropertyMap::checkConsistency( )80 inline void PropertyMap::checkConsistency(PropertyStorage&) 81 81 { 82 82 } … … 98 98 } 99 99 100 m_deletedOffsets = other.m_deletedOffsets;101 100 m_getterSetterFlag = other.m_getterSetterFlag; 102 101 return *this; … … 116 115 } 117 116 118 size_t PropertyMap::put(const Identifier& propertyName, unsigned attributes)117 size_t PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage) 119 118 { 120 119 ASSERT(!propertyName.isNull()); 121 ASSERT( get(propertyName) == WTF::notFound);122 123 checkConsistency( );120 ASSERT(value); 121 122 checkConsistency(propertyStorage); 124 123 125 124 UString::Rep* rep = propertyName._ustring.rep(); 126 125 127 126 if (!m_table) 128 createTable();127 expand(propertyStorage); 129 128 130 129 // FIXME: Consider a fast case for tables with no deleted sentinels. … … 144 143 break; 145 144 146 if (entryIndex == deletedSentinelIndex) { 145 if (m_table->entries()[entryIndex - 1].key == rep) { 146 if (checkReadOnly && (m_table->entries()[entryIndex - 1].attributes & ReadOnly)) 147 return WTF::notFound; 148 // Put a new value in an existing hash table entry. 149 propertyStorage[entryIndex - 2] = value; 150 // Attributes are intentionally not updated. 151 slot.setExistingProperty(slotBase, entryIndex - 2); 152 return entryIndex - 2; 153 } else if (entryIndex == deletedSentinelIndex) { 147 154 // If we find a deleted-element sentinel, remember it for use later. 148 155 if (!foundDeletedElement) { … … 187 194 m_table->entries()[entryIndex - 1].attributes = attributes; 188 195 m_table->entries()[entryIndex - 1].index = ++m_table->lastIndexUsed; 189 190 unsigned newOffset;191 if (!m_deletedOffsets.isEmpty()) {192 newOffset = m_deletedOffsets.last();193 m_deletedOffsets.removeLast();194 } else195 newOffset = m_table->keyCount + m_table->deletedSentinelCount;196 m_table->entries()[entryIndex - 1].offset = newOffset;197 198 196 ++m_table->keyCount; 199 197 198 propertyStorage[entryIndex - 2] = value; 199 200 200 if ((m_table->keyCount + m_table->deletedSentinelCount) * 2 >= m_table->size) 201 expand(); 202 203 checkConsistency(); 204 return newOffset; 205 } 206 207 size_t PropertyMap::remove(const Identifier& propertyName) 201 expand(propertyStorage); 202 203 checkConsistency(propertyStorage); 204 slot.setNewProperty(slotBase, entryIndex - 2); 205 return entryIndex - 2; 206 } 207 208 void PropertyMap::remove(const Identifier& propertyName, PropertyStorage& propertyStorage) 208 209 { 209 210 ASSERT(!propertyName.isNull()); 210 211 211 checkConsistency( );212 checkConsistency(propertyStorage); 212 213 213 214 UString::Rep* rep = propertyName._ustring.rep(); 214 215 215 216 if (!m_table) 216 return WTF::notFound; 217 217 return; 218 218 219 219 #if DUMP_PROPERTYMAP_STATS … … 230 230 entryIndex = m_table->entryIndices[i & m_table->sizeMask]; 231 231 if (entryIndex == emptyEntryIndex) 232 return WTF::notFound;232 return; 233 233 234 234 key = m_table->entries()[entryIndex - 1].key; … … 253 253 // the entry so we can iterate all the entries as needed. 254 254 m_table->entryIndices[i & m_table->sizeMask] = deletedSentinelIndex; 255 256 size_t offset = m_table->entries()[entryIndex - 1].offset;257 258 255 key->deref(); 259 256 m_table->entries()[entryIndex - 1].key = 0; 260 257 m_table->entries()[entryIndex - 1].attributes = 0; 261 m_table->entries()[entryIndex - 1].offset = 0; 262 m_deletedOffsets.append(offset);258 259 propertyStorage[entryIndex - 2] = jsUndefined(); 263 260 264 261 ASSERT(m_table->keyCount >= 1); … … 267 264 268 265 if (m_table->deletedSentinelCount * 4 >= m_table->size) 269 rehash(); 270 271 checkConsistency(); 272 return offset; 273 } 274 275 size_t PropertyMap::get(const Identifier& propertyName, unsigned& attributes) 266 rehash(propertyStorage); 267 268 checkConsistency(propertyStorage); 269 } 270 271 size_t PropertyMap::getOffset(const Identifier& propertyName, unsigned& attributes) 276 272 { 277 273 ASSERT(!propertyName.isNull()); … … 294 290 if (rep == m_table->entries()[entryIndex - 1].key) { 295 291 attributes = m_table->entries()[entryIndex - 1].attributes; 296 return m_table->entries()[entryIndex - 1].offset;292 return entryIndex - 2; 297 293 } 298 294 … … 316 312 if (rep == m_table->entries()[entryIndex - 1].key) { 317 313 attributes = m_table->entries()[entryIndex - 1].attributes; 318 return m_table->entries()[entryIndex - 1].offset;319 } 320 } 321 } 322 323 void PropertyMap::insert(const Entry& entry )314 return entryIndex - 2; 315 } 316 } 317 } 318 319 void PropertyMap::insert(const Entry& entry, JSValue* value, PropertyStorage& propertyStorage) 324 320 { 325 321 ASSERT(m_table); … … 355 351 m_table->entries()[entryIndex - 1] = entry; 356 352 353 propertyStorage[entryIndex - 2] = value; 354 357 355 ++m_table->keyCount; 358 356 } 359 357 360 void PropertyMap::expand() 358 void PropertyMap::expand(PropertyStorage& propertyStorage) 359 { 360 if (!m_table) 361 createTable(propertyStorage); 362 else 363 rehash(m_table->size * 2, propertyStorage); 364 } 365 366 void PropertyMap::rehash(PropertyStorage& propertyStorage) 361 367 { 362 368 ASSERT(m_table); 363 rehash(m_table->size * 2); 364 } 365 366 void PropertyMap::createTable() 369 ASSERT(m_table->size); 370 rehash(m_table->size, propertyStorage); 371 } 372 373 void PropertyMap::createTable(PropertyStorage& propertyStorage) 367 374 { 368 375 const unsigned newTableSize = 16; … … 370 377 ASSERT(!m_table); 371 378 372 checkConsistency( );379 checkConsistency(propertyStorage); 373 380 374 381 m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize))); … … 376 383 m_table->sizeMask = newTableSize - 1; 377 384 378 checkConsistency( );379 } 380 381 void PropertyMap::rehash( )385 checkConsistency(propertyStorage); 386 } 387 388 void PropertyMap::rehash(unsigned newTableSize, PropertyStorage& propertyStorage) 382 389 { 383 390 ASSERT(m_table); 384 ASSERT(m_table->size); 385 rehash(m_table->size); 386 } 387 388 void PropertyMap::rehash(unsigned newTableSize) 389 { 390 ASSERT(m_table); 391 392 checkConsistency(); 391 392 checkConsistency(propertyStorage); 393 393 394 394 Table* oldTable = m_table; 395 JSValue** oldPropertStorage = propertyStorage; 395 396 396 397 m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize))); 397 398 m_table->size = newTableSize; 398 399 m_table->sizeMask = newTableSize - 1; 400 401 propertyStorage = new JSValue*[m_table->size]; 399 402 400 403 unsigned lastIndexUsed = 0; … … 403 406 if (oldTable->entries()[i].key) { 404 407 lastIndexUsed = max(oldTable->entries()[i].index, lastIndexUsed); 405 insert(oldTable->entries()[i] );408 insert(oldTable->entries()[i], oldPropertStorage[i - 1], propertyStorage); 406 409 } 407 410 } … … 409 412 410 413 fastFree(oldTable); 411 412 checkConsistency(); 414 delete [] oldPropertStorage; 415 416 checkConsistency(propertyStorage); 413 417 } 414 418 … … 482 486 #if DO_PROPERTYMAP_CONSTENCY_CHECK 483 487 484 void PropertyMap::checkConsistency( )488 void PropertyMap::checkConsistency(PropertyStorage& propertyStorage) 485 489 { 486 490 if (!m_table) … … 522 526 for (unsigned c = 1; c <= m_table->keyCount + m_table->deletedSentinelCount; ++c) { 523 527 UString::Rep* rep = m_table->entries()[c].key; 524 if (!rep) 528 if (!rep) { 529 ASSERT(propertyStorage[c - 1]->isUndefined()); 525 530 continue; 531 } 526 532 ++nonEmptyEntryCount; 527 533 unsigned i = rep->computedHash();
Note:
See TracChangeset
for help on using the changeset viewer.