Changeset 36304 in webkit for trunk/JavaScriptCore/kjs/PropertyMap.cpp
- Timestamp:
- Sep 9, 2008, 4:42:47 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/PropertyMap.cpp
r36285 r36304 118 118 } 119 119 120 JSValue* PropertyMap::get(const Identifier& propertyName, unsigned& attributes, const PropertyStorage& propertyStorage) const121 {122 ASSERT(!propertyName.isNull());123 124 UString::Rep* rep = propertyName._ustring.rep();125 126 if (!m_table)127 return 0;128 129 unsigned i = rep->computedHash();130 131 #if DUMP_PROPERTYMAP_STATS132 ++numProbes;133 #endif134 135 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask];136 if (entryIndex == emptyEntryIndex)137 return 0;138 139 if (rep == m_table->entries()[entryIndex - 1].key) {140 attributes = m_table->entries()[entryIndex - 1].attributes;141 return propertyStorage[entryIndex - 1];142 }143 144 #if DUMP_PROPERTYMAP_STATS145 ++numCollisions;146 #endif147 148 unsigned k = 1 | doubleHash(rep->computedHash());149 150 while (1) {151 i += k;152 153 #if DUMP_PROPERTYMAP_STATS154 ++numRehashes;155 #endif156 157 entryIndex = m_table->entryIndices[i & m_table->sizeMask];158 if (entryIndex == emptyEntryIndex)159 return 0;160 161 if (rep == m_table->entries()[entryIndex - 1].key) {162 attributes = m_table->entries()[entryIndex - 1].attributes;163 return propertyStorage[entryIndex - 1];164 }165 }166 }167 168 JSValue* PropertyMap::get(const Identifier& propertyName, const PropertyStorage& propertyStorage) const169 {170 ASSERT(!propertyName.isNull());171 172 UString::Rep* rep = propertyName._ustring.rep();173 174 if (!m_table)175 return 0;176 177 unsigned i = rep->computedHash();178 179 #if DUMP_PROPERTYMAP_STATS180 ++numProbes;181 #endif182 183 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask];184 if (entryIndex == emptyEntryIndex)185 return 0;186 187 if (rep == m_table->entries()[entryIndex - 1].key)188 return propertyStorage[entryIndex - 1];189 190 #if DUMP_PROPERTYMAP_STATS191 ++numCollisions;192 #endif193 194 unsigned k = 1 | doubleHash(rep->computedHash());195 196 while (1) {197 i += k;198 199 #if DUMP_PROPERTYMAP_STATS200 ++numRehashes;201 #endif202 203 entryIndex = m_table->entryIndices[i & m_table->sizeMask];204 if (entryIndex == emptyEntryIndex)205 return 0;206 207 if (rep == m_table->entries()[entryIndex - 1].key)208 return propertyStorage[entryIndex - 1];209 }210 }211 212 JSValue** PropertyMap::getLocation(const Identifier& propertyName, const PropertyStorage& propertyStorage)213 {214 ASSERT(!propertyName.isNull());215 216 UString::Rep* rep = propertyName._ustring.rep();217 218 if (!m_table)219 return 0;220 221 unsigned i = rep->computedHash();222 223 #if DUMP_PROPERTYMAP_STATS224 ++numProbes;225 #endif226 227 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask];228 if (entryIndex == emptyEntryIndex)229 return 0;230 231 if (rep == m_table->entries()[entryIndex - 1].key)232 return &propertyStorage[entryIndex - 1];233 234 #if DUMP_PROPERTYMAP_STATS235 ++numCollisions;236 #endif237 238 unsigned k = 1 | doubleHash(rep->computedHash());239 240 while (1) {241 i += k;242 243 #if DUMP_PROPERTYMAP_STATS244 ++numRehashes;245 #endif246 247 entryIndex = m_table->entryIndices[i & m_table->sizeMask];248 if (entryIndex == emptyEntryIndex)249 return 0;250 251 if (rep == m_table->entries()[entryIndex - 1].key)252 return &propertyStorage[entryIndex - 1];253 }254 }255 256 JSValue** PropertyMap::getLocation(const Identifier& propertyName, bool& isWriteable, const PropertyStorage& propertyStorage)257 {258 ASSERT(!propertyName.isNull());259 260 UString::Rep* rep = propertyName._ustring.rep();261 262 if (!m_table)263 return 0;264 265 unsigned i = rep->computedHash();266 267 #if DUMP_PROPERTYMAP_STATS268 ++numProbes;269 #endif270 271 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask];272 if (entryIndex == emptyEntryIndex)273 return 0;274 275 if (rep == m_table->entries()[entryIndex - 1].key) {276 isWriteable = !(m_table->entries()[entryIndex - 1].attributes & ReadOnly);277 return &propertyStorage[entryIndex - 1];278 }279 280 #if DUMP_PROPERTYMAP_STATS281 ++numCollisions;282 #endif283 284 unsigned k = 1 | doubleHash(rep->computedHash());285 286 while (1) {287 i += k;288 289 #if DUMP_PROPERTYMAP_STATS290 ++numRehashes;291 #endif292 293 entryIndex = m_table->entryIndices[i & m_table->sizeMask];294 if (entryIndex == emptyEntryIndex)295 return 0;296 297 if (rep == m_table->entries()[entryIndex - 1].key) {298 isWriteable = !(m_table->entries()[entryIndex - 1].attributes & ReadOnly);299 return &propertyStorage[entryIndex - 1];300 }301 }302 }303 304 120 void PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage) 305 121 { … … 392 208 } 393 209 394 size_t PropertyMap::getOffset(const Identifier& propertyName)395 {396 ASSERT(!propertyName.isNull());397 398 if (!m_table)399 return WTF::notFound;400 401 UString::Rep* rep = propertyName._ustring.rep();402 403 unsigned i = rep->computedHash();404 405 #if DUMP_PROPERTYMAP_STATS406 ++numProbes;407 #endif408 409 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask];410 if (entryIndex == emptyEntryIndex)411 return WTF::notFound;412 413 if (rep == m_table->entries()[entryIndex - 1].key)414 return entryIndex - 1;415 416 #if DUMP_PROPERTYMAP_STATS417 ++numCollisions;418 #endif419 420 unsigned k = 1 | doubleHash(rep->computedHash());421 422 while (1) {423 i += k;424 425 #if DUMP_PROPERTYMAP_STATS426 ++numRehashes;427 #endif428 429 entryIndex = m_table->entryIndices[i & m_table->sizeMask];430 if (entryIndex == emptyEntryIndex)431 return WTF::notFound;432 433 if (rep == m_table->entries()[entryIndex - 1].key)434 return entryIndex - 1;435 }436 }437 438 size_t PropertyMap::getOffset(const Identifier& propertyName, bool& isWriteable)439 {440 ASSERT(!propertyName.isNull());441 442 if (!m_table)443 return WTF::notFound;444 445 UString::Rep* rep = propertyName._ustring.rep();446 447 unsigned i = rep->computedHash();448 449 #if DUMP_PROPERTYMAP_STATS450 ++numProbes;451 #endif452 453 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask];454 if (entryIndex == emptyEntryIndex)455 return WTF::notFound;456 457 if (rep == m_table->entries()[entryIndex - 1].key) {458 isWriteable = !(m_table->entries()[entryIndex - 1].attributes & ReadOnly);459 return entryIndex - 1;460 }461 462 #if DUMP_PROPERTYMAP_STATS463 ++numCollisions;464 #endif465 466 unsigned k = 1 | doubleHash(rep->computedHash());467 468 while (1) {469 i += k;470 471 #if DUMP_PROPERTYMAP_STATS472 ++numRehashes;473 #endif474 475 entryIndex = m_table->entryIndices[i & m_table->sizeMask];476 if (entryIndex == emptyEntryIndex)477 return WTF::notFound;478 479 if (rep == m_table->entries()[entryIndex - 1].key) {480 isWriteable = !(m_table->entries()[entryIndex - 1].attributes & ReadOnly);481 return entryIndex - 1;482 }483 }484 }485 486 void PropertyMap::insert(const Entry& entry, JSValue* value, PropertyStorage& propertyStorage)487 {488 ASSERT(m_table);489 490 unsigned i = entry.key->computedHash();491 unsigned k = 0;492 493 #if DUMP_PROPERTYMAP_STATS494 ++numProbes;495 #endif496 497 while (1) {498 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask];499 if (entryIndex == emptyEntryIndex)500 break;501 502 if (k == 0) {503 k = 1 | doubleHash(entry.key->computedHash());504 #if DUMP_PROPERTYMAP_STATS505 ++numCollisions;506 #endif507 }508 509 i += k;510 511 #if DUMP_PROPERTYMAP_STATS512 ++numRehashes;513 #endif514 }515 516 unsigned entryIndex = m_table->keyCount + 2;517 m_table->entryIndices[i & m_table->sizeMask] = entryIndex;518 m_table->entries()[entryIndex - 1] = entry;519 520 propertyStorage[entryIndex - 1] = value;521 522 ++m_table->keyCount;523 }524 525 void PropertyMap::expand(PropertyStorage& propertyStorage)526 {527 if (!m_table)528 createTable(propertyStorage);529 else530 rehash(m_table->size * 2, propertyStorage);531 }532 533 void PropertyMap::rehash(PropertyStorage& propertyStorage)534 {535 ASSERT(m_table);536 ASSERT(m_table->size);537 rehash(m_table->size, propertyStorage);538 }539 540 void PropertyMap::createTable(PropertyStorage& propertyStorage)541 {542 const unsigned newTableSize = 16;543 544 ASSERT(!m_table);545 546 checkConsistency(propertyStorage);547 548 m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize)));549 m_table->size = newTableSize;550 m_table->sizeMask = newTableSize - 1;551 552 propertyStorage.set(new JSValue*[m_table->size]);553 554 checkConsistency(propertyStorage);555 }556 557 void PropertyMap::rehash(unsigned newTableSize, PropertyStorage& propertyStorage)558 {559 ASSERT(m_table);560 561 checkConsistency(propertyStorage);562 563 Table* oldTable = m_table;564 JSValue** oldPropertStorage = propertyStorage.release();565 566 m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize)));567 m_table->size = newTableSize;568 m_table->sizeMask = newTableSize - 1;569 570 propertyStorage.set(new JSValue*[m_table->size]);571 572 unsigned lastIndexUsed = 0;573 unsigned entryCount = oldTable->keyCount + oldTable->deletedSentinelCount;574 for (unsigned i = 1; i <= entryCount; ++i) {575 if (oldTable->entries()[i].key) {576 lastIndexUsed = max(oldTable->entries()[i].index, lastIndexUsed);577 insert(oldTable->entries()[i], oldPropertStorage[i], propertyStorage);578 }579 }580 m_table->lastIndexUsed = lastIndexUsed;581 582 fastFree(oldTable);583 delete [] oldPropertStorage;584 585 checkConsistency(propertyStorage);586 }587 588 void PropertyMap::resizePropertyStorage(PropertyStorage& propertyStorage, unsigned oldSize)589 {590 ASSERT(m_table);591 592 if (propertyStorage) {593 JSValue** oldPropertStorage = propertyStorage.release();594 propertyStorage.set(new JSValue*[m_table->size]);595 596 // FIXME: this can probalby use memcpy597 for (unsigned i = 1; i <= oldSize; ++i)598 propertyStorage[i] = oldPropertStorage[i];599 600 delete [] oldPropertStorage;601 } else602 propertyStorage.set(new JSValue*[m_table->size]);603 604 checkConsistency(propertyStorage);605 }606 607 210 void PropertyMap::remove(const Identifier& propertyName, PropertyStorage& propertyStorage) 608 211 { … … 664 267 if (m_table->deletedSentinelCount * 4 >= m_table->size) 665 268 rehash(propertyStorage); 269 270 checkConsistency(propertyStorage); 271 } 272 273 size_t PropertyMap::getOffset(const Identifier& propertyName) 274 { 275 ASSERT(!propertyName.isNull()); 276 277 if (!m_table) 278 return WTF::notFound; 279 280 UString::Rep* rep = propertyName._ustring.rep(); 281 282 unsigned i = rep->computedHash(); 283 284 #if DUMP_PROPERTYMAP_STATS 285 ++numProbes; 286 #endif 287 288 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask]; 289 if (entryIndex == emptyEntryIndex) 290 return WTF::notFound; 291 292 if (rep == m_table->entries()[entryIndex - 1].key) 293 return entryIndex - 1; 294 295 #if DUMP_PROPERTYMAP_STATS 296 ++numCollisions; 297 #endif 298 299 unsigned k = 1 | doubleHash(rep->computedHash()); 300 301 while (1) { 302 i += k; 303 304 #if DUMP_PROPERTYMAP_STATS 305 ++numRehashes; 306 #endif 307 308 entryIndex = m_table->entryIndices[i & m_table->sizeMask]; 309 if (entryIndex == emptyEntryIndex) 310 return WTF::notFound; 311 312 if (rep == m_table->entries()[entryIndex - 1].key) 313 return entryIndex - 1; 314 } 315 } 316 317 size_t PropertyMap::getOffset(const Identifier& propertyName, unsigned& attributes) 318 { 319 ASSERT(!propertyName.isNull()); 320 321 if (!m_table) 322 return WTF::notFound; 323 324 UString::Rep* rep = propertyName._ustring.rep(); 325 326 unsigned i = rep->computedHash(); 327 328 #if DUMP_PROPERTYMAP_STATS 329 ++numProbes; 330 #endif 331 332 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask]; 333 if (entryIndex == emptyEntryIndex) 334 return WTF::notFound; 335 336 if (rep == m_table->entries()[entryIndex - 1].key) { 337 attributes = m_table->entries()[entryIndex - 1].attributes; 338 return entryIndex - 1; 339 } 340 341 #if DUMP_PROPERTYMAP_STATS 342 ++numCollisions; 343 #endif 344 345 unsigned k = 1 | doubleHash(rep->computedHash()); 346 347 while (1) { 348 i += k; 349 350 #if DUMP_PROPERTYMAP_STATS 351 ++numRehashes; 352 #endif 353 354 entryIndex = m_table->entryIndices[i & m_table->sizeMask]; 355 if (entryIndex == emptyEntryIndex) 356 return WTF::notFound; 357 358 if (rep == m_table->entries()[entryIndex - 1].key) { 359 attributes = m_table->entries()[entryIndex - 1].attributes; 360 return entryIndex - 1; 361 } 362 } 363 } 364 365 size_t PropertyMap::getOffset(const Identifier& propertyName, bool& isWriteable) 366 { 367 ASSERT(!propertyName.isNull()); 368 369 if (!m_table) 370 return WTF::notFound; 371 372 UString::Rep* rep = propertyName._ustring.rep(); 373 374 unsigned i = rep->computedHash(); 375 376 #if DUMP_PROPERTYMAP_STATS 377 ++numProbes; 378 #endif 379 380 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask]; 381 if (entryIndex == emptyEntryIndex) 382 return WTF::notFound; 383 384 if (rep == m_table->entries()[entryIndex - 1].key) { 385 isWriteable = !(m_table->entries()[entryIndex - 1].attributes & ReadOnly); 386 return entryIndex - 1; 387 } 388 389 #if DUMP_PROPERTYMAP_STATS 390 ++numCollisions; 391 #endif 392 393 unsigned k = 1 | doubleHash(rep->computedHash()); 394 395 while (1) { 396 i += k; 397 398 #if DUMP_PROPERTYMAP_STATS 399 ++numRehashes; 400 #endif 401 402 entryIndex = m_table->entryIndices[i & m_table->sizeMask]; 403 if (entryIndex == emptyEntryIndex) 404 return WTF::notFound; 405 406 if (rep == m_table->entries()[entryIndex - 1].key) { 407 isWriteable = !(m_table->entries()[entryIndex - 1].attributes & ReadOnly); 408 return entryIndex - 1; 409 } 410 } 411 } 412 413 void PropertyMap::insert(const Entry& entry, JSValue* value, PropertyStorage& propertyStorage) 414 { 415 ASSERT(m_table); 416 417 unsigned i = entry.key->computedHash(); 418 unsigned k = 0; 419 420 #if DUMP_PROPERTYMAP_STATS 421 ++numProbes; 422 #endif 423 424 while (1) { 425 unsigned entryIndex = m_table->entryIndices[i & m_table->sizeMask]; 426 if (entryIndex == emptyEntryIndex) 427 break; 428 429 if (k == 0) { 430 k = 1 | doubleHash(entry.key->computedHash()); 431 #if DUMP_PROPERTYMAP_STATS 432 ++numCollisions; 433 #endif 434 } 435 436 i += k; 437 438 #if DUMP_PROPERTYMAP_STATS 439 ++numRehashes; 440 #endif 441 } 442 443 unsigned entryIndex = m_table->keyCount + 2; 444 m_table->entryIndices[i & m_table->sizeMask] = entryIndex; 445 m_table->entries()[entryIndex - 1] = entry; 446 447 propertyStorage[entryIndex - 1] = value; 448 449 ++m_table->keyCount; 450 } 451 452 void PropertyMap::expand(PropertyStorage& propertyStorage) 453 { 454 if (!m_table) 455 createTable(propertyStorage); 456 else 457 rehash(m_table->size * 2, propertyStorage); 458 } 459 460 void PropertyMap::rehash(PropertyStorage& propertyStorage) 461 { 462 ASSERT(m_table); 463 ASSERT(m_table->size); 464 rehash(m_table->size, propertyStorage); 465 } 466 467 void PropertyMap::createTable(PropertyStorage& propertyStorage) 468 { 469 const unsigned newTableSize = 16; 470 471 ASSERT(!m_table); 472 473 checkConsistency(propertyStorage); 474 475 m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize))); 476 m_table->size = newTableSize; 477 m_table->sizeMask = newTableSize - 1; 478 479 propertyStorage.set(new JSValue*[m_table->size]); 480 481 checkConsistency(propertyStorage); 482 } 483 484 void PropertyMap::rehash(unsigned newTableSize, PropertyStorage& propertyStorage) 485 { 486 ASSERT(m_table); 487 488 checkConsistency(propertyStorage); 489 490 Table* oldTable = m_table; 491 JSValue** oldPropertStorage = propertyStorage.release(); 492 493 m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize))); 494 m_table->size = newTableSize; 495 m_table->sizeMask = newTableSize - 1; 496 497 propertyStorage.set(new JSValue*[m_table->size]); 498 499 unsigned lastIndexUsed = 0; 500 unsigned entryCount = oldTable->keyCount + oldTable->deletedSentinelCount; 501 for (unsigned i = 1; i <= entryCount; ++i) { 502 if (oldTable->entries()[i].key) { 503 lastIndexUsed = max(oldTable->entries()[i].index, lastIndexUsed); 504 insert(oldTable->entries()[i], oldPropertStorage[i], propertyStorage); 505 } 506 } 507 m_table->lastIndexUsed = lastIndexUsed; 508 509 fastFree(oldTable); 510 delete [] oldPropertStorage; 511 512 checkConsistency(propertyStorage); 513 } 514 515 void PropertyMap::resizePropertyStorage(PropertyStorage& propertyStorage, unsigned oldSize) 516 { 517 ASSERT(m_table); 518 519 if (propertyStorage) { 520 JSValue** oldPropertStorage = propertyStorage.release(); 521 propertyStorage.set(new JSValue*[m_table->size]); 522 523 // FIXME: this can probalby use memcpy 524 for (unsigned i = 1; i <= oldSize; ++i) 525 propertyStorage[i] = oldPropertStorage[i]; 526 527 delete [] oldPropertStorage; 528 } else 529 propertyStorage.set(new JSValue*[m_table->size]); 666 530 667 531 checkConsistency(propertyStorage);
Note:
See TracChangeset
for help on using the changeset viewer.