Ignore:
Timestamp:
Feb 2, 2008, 4:20:34 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

Reviewed by Geoff Garen.

PLT speedup related to <rdar://problem/5659272> REGRESSION: PLT .4%
slower due to r28884 (global variable symbol table optimization)

Geoff's theory is that the slowdown was due to copying hash tables when
putting things into the back/forward cache. If that's true, then this
should fix the problem.


(According to Geoff's measurements, in a PLT that exaggerates the
importance of symbol table saving during cached page creation, this
patch is a ~3X speedup in cached page creation, and a 9% speedup overall.)

  • kjs/JSVariableObject.cpp: (KJS::JSVariableObject::saveLocalStorage): Updated for changes to SavedProperty, which has been revised to avoid initializing each SavedProperty twice when building the array. Store the property names too, so we don't have to store the symbol table separately. Do this by iterating the symbol table instead of the local storage vector. (KJS::JSVariableObject::restoreLocalStorage): Ditto. Restore the symbol table as well as the local storage vector.
  • kjs/JSVariableObject.h: Removed save/restoreSymbolTable and do that work inside save/restoreLocalStorage instead. Made restoreLocalStorage a non-const member function that takes a const reference to a SavedProperties object.
  • kjs/LocalStorage.h: Changed attributes to be unsigned instead of int to match other declarations of attributes elsewhere.
  • kjs/property_map.cpp: (KJS::SavedProperties::SavedProperties): Updated for data member name change. (KJS::PropertyMap::save): Updated for data member name change and to use the new inline init function instead of setting the fields directly. This allows us to skip initializing the SavedProperty objects when first allocating the array, and just do it when we're actually setting up the individual elements. (KJS::PropertyMap::restore): Updated for SavedProperty changes.
  • kjs/property_map.h: Changed SavedProperty from a struct to a class. Set it up so it does not get initialized at construction time to avoid initializing twice when creating an array of SavedProperty. Removed the m_ prefixes from the members of the SavedProperties struct. Generally we use m_ for class members and not struct.

WebCore:

Reviewed by Geoff Garen.

PLT speedup related to <rdar://problem/5659272> REGRESSION: PLT .4%
slower due to r28884 (global variable symbol table optimization)

  • history/CachedPage.cpp: (WebCore::CachedPage::CachedPage): Removed saveSymbolTable call. (WebCore::CachedPage::restore): Removed restoreSymbolTable call. (WebCore::CachedPage::clear): Removed clear of m_windowSymbolTable.
  • history/CachedPage.h: Removed m_windowSymbolTable, since save/restoreLocalStorage now takes care of the symbol table. Also removed many unnecessary includes.
File:
1 edited

Legend:

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

    r28884 r29943  
    11/*
    2  *  Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     2 *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
    33 *
    44 *  This library is free software; you can redistribute it and/or
     
    127127
    128128SavedProperties::SavedProperties()
    129     : m_count(0)
     129    : count(0)
    130130{
    131131}
     
    717717}
    718718
    719 void PropertyMap::save(SavedProperties &p) const
     719void PropertyMap::save(SavedProperties& s) const
    720720{
    721721    unsigned count = 0;
     
    733733    }
    734734
    735     p.m_properties.clear();
    736     p.m_count = count;
     735    s.properties.clear();
     736    s.count = count;
    737737
    738738    if (count == 0)
    739739        return;
    740740   
    741     p.m_properties.set(new SavedProperty [count]);
    742    
    743     SavedProperty* prop = p.m_properties.get();
    744    
    745     if (!m_usingTable) {
    746 #if USE_SINGLE_ENTRY
    747         if (m_singleEntryKey && !(m_singleEntryAttributes & (ReadOnly | Function))) {
    748             prop->key = Identifier(m_singleEntryKey);
    749             prop->value = m_u.singleEntryValue;
    750             prop->attributes = m_singleEntryAttributes;
    751             ++prop;
    752         }
    753 #endif
    754     } else {
    755         // Save in the right order so we don't lose the order.
    756         // Another possibility would be to save the indices.
    757 
    758         // Allocate a buffer to use to sort the keys.
    759         Vector<Entry*, smallMapThreshold> sortedEntries(count);
    760 
    761         // Get pointers to the entries in the buffer.
    762         Entry** p = sortedEntries.data();
    763         unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount;
    764         for (unsigned i = 1; i <= entryCount; ++i) {
    765             if (m_u.table->entries()[i].key && !(m_u.table->entries()[i].attributes & (ReadOnly | Function)))
    766                 *p++ = &m_u.table->entries()[i];
    767         }
    768         ASSERT(p == sortedEntries.data() + count);
    769 
    770         // Sort the entries by index.
    771         qsort(sortedEntries.data(), p - sortedEntries.data(), sizeof(Entry*), comparePropertyMapEntryIndices);
    772 
    773         // Put the sorted entries into the saved properties list.
    774         for (Entry** q = sortedEntries.data(); q != p; ++q, ++prop) {
    775             Entry* e = *q;
    776             prop->key = Identifier(e->key);
    777             prop->value = e->value;
    778             prop->attributes = e->attributes;
    779         }
    780     }
    781 }
    782 
    783 void PropertyMap::restore(const SavedProperties &p)
    784 {
    785     for (unsigned i = 0; i != p.m_count; ++i)
    786         put(p.m_properties[i].key, p.m_properties[i].value, p.m_properties[i].attributes);
     741    s.properties.set(new SavedProperty[count]);
     742   
     743    SavedProperty* prop = s.properties.get();
     744   
     745#if USE_SINGLE_ENTRY
     746    if (!m_usingTable) {
     747        prop->init(m_singleEntryKey, m_u.singleEntryValue, m_singleEntryAttributes);
     748        return;
     749    }
     750#endif
     751
     752    // Save in the right order so we don't lose the order.
     753    // Another possibility would be to save the indices.
     754
     755    // Allocate a buffer to use to sort the keys.
     756    Vector<Entry*, smallMapThreshold> sortedEntries(count);
     757
     758    // Get pointers to the entries in the buffer.
     759    Entry** p = sortedEntries.data();
     760    unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount;
     761    for (unsigned i = 1; i <= entryCount; ++i) {
     762        if (m_u.table->entries()[i].key && !(m_u.table->entries()[i].attributes & (ReadOnly | Function)))
     763            *p++ = &m_u.table->entries()[i];
     764    }
     765    ASSERT(p == sortedEntries.data() + count);
     766
     767    // Sort the entries by index.
     768    qsort(sortedEntries.data(), p - sortedEntries.data(), sizeof(Entry*), comparePropertyMapEntryIndices);
     769
     770    // Put the sorted entries into the saved properties list.
     771    for (Entry** q = sortedEntries.data(); q != p; ++q, ++prop) {
     772        Entry* e = *q;
     773        prop->init(e->key, e->value, e->attributes);
     774    }
     775}
     776
     777void PropertyMap::restore(const SavedProperties& p)
     778{
     779    for (unsigned i = 0; i != p.count; ++i)
     780        put(Identifier(p.properties[i].name()), p.properties[i].value(), p.properties[i].attributes());
    787781}
    788782
Note: See TracChangeset for help on using the changeset viewer.