Ignore:
Timestamp:
Feb 28, 2006, 11:19:54 PM (19 years ago)
Author:
ggaren
Message:

Reviewed by Darin.

  • Fixed <rdar://problem/4448098> Switch PropertyMap deleted entry placeholder to -1 from UString::Rep::null

This turned out to be only a small speedup (.12%). That's within the
margin of error for super accurate JS iBench, but Shark confirms the
same, so I think it's worth landing.

FYI, I also confirmed that the single entry optimization in
PropertyMap is a 3.2% speedup.

  • kjs/property_map.cpp: (KJS::PropertyMap::~PropertyMap): (KJS::PropertyMap::clear): (KJS::PropertyMap::put): (KJS::PropertyMap::insert): (KJS::PropertyMap::rehash): (KJS::PropertyMap::remove): (KJS::PropertyMap::addSparseArrayPropertiesToReferenceList): (KJS::PropertyMap::checkConsistency):
  • kjs/property_map.h: (KJS::PropertyMap::deletedSentinel):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/property_map.cpp

    r12523 r13066  
    3737#define USE_SINGLE_ENTRY 1
    3838
    39 // At the time I added USE_SINGLE_ENTRY, the optimization still gave a 1.5%
    40 // performance boost to the iBench JavaScript benchmark so I didn't remove it.
     39// 2/28/2006 ggaren: super accurate JS iBench says that USE_SINGLE_ENTRY is a
     40// 3.2% performance boost.
    4141
    4242// FIXME: _singleEntry.index is unused.
     
    100100// Algorithm concepts from Algorithms in C++, Sedgewick.
    101101
     102// This is a method rather than a variable to work around <rdar://problem/4462053>
     103static inline UString::Rep* deletedSentinel() { return reinterpret_cast<UString::Rep*>(-1); }
     104
    102105PropertyMap::~PropertyMap()
    103106{
     
    115118    for (int i = 0; i < minimumKeysToProcess; i++) {
    116119        UString::Rep *key = entries[i].key;
    117         if (key)
     120        if (key && key != deletedSentinel())
    118121            key->deref();
    119         else
     122        else if (key != deletedSentinel())
    120123            ++minimumKeysToProcess;
    121124    }
     
    140143    for (int i = 0; i < size; i++) {
    141144        UString::Rep *key = entries[i].key;
    142         if (key) {
     145        if (key && key != deletedSentinel()) {
    143146            key->deref();
    144147            entries[i].key = 0;
     
    343346        }
    344347        // If we find the deleted-element sentinel, remember it for use later.
    345         if (key == &UString::Rep::null && !foundDeletedElement) {
     348        if (key == deletedSentinel() && !foundDeletedElement) {
    346349            foundDeletedElement = true;
    347350            deletedElementIndex = i;
     
    358361    if (foundDeletedElement) {
    359362        i = deletedElementIndex;
    360         entries[i].key->deref();
    361363        --_table->sentinelCount;
    362364    }
     
    387389#endif
    388390    while (entries[i].key) {
    389         assert(entries[i].key != &UString::Rep::null);
     391        assert(entries[i].key != deletedSentinel());
    390392        if (k == 0)
    391393            k = 1 | (h % sizeMask);
     
    447449        if (key) {
    448450            // Don't copy deleted-element sentinels.
    449             if (key == &UString::Rep::null)
    450                 key->deref();
    451             else {
     451            if (key != deletedSentinel()) {
    452452                int index = entry.index;
    453453                lastIndexUsed = max(index, lastIndexUsed);
     
    509509        return;
    510510   
    511     // Replace this one element with the deleted sentinel,
    512     // &UString::Rep::null; also set value to 0 and attributes to DontEnum
     511    // Replace this one element with the deleted sentinel. Also set value to 0 and attributes to DontEnum
    513512    // to help callers that iterate all keys not have to check for the sentinel.
    514513    key->deref();
    515     key = &UString::Rep::null;
    516     key->ref();
     514    key = deletedSentinel();
    517515    entries[i].key = key;
    518516    entries[i].value = 0;
     
    634632    for (int i = 0; i != size; ++i) {
    635633        UString::Rep *key = entries[i].key;
    636         if (key && key != &UString::Rep::null) {
     634        if (key && key != deletedSentinel()) {
    637635            UString k(key);
    638636            bool fitsInUInt32;
     
    730728        if (!rep)
    731729            continue;
    732         if (rep == &UString::Rep::null) {
     730        if (rep == deletedSentinel()) {
    733731            ++sentinelCount;
    734732            continue;
Note: See TracChangeset for help on using the changeset viewer.