Ignore:
Timestamp:
Oct 8, 2009, 4:24:55 PM (16 years ago)
Author:
[email protected]
Message:

Migrated some code that didn't belong out of Structure.

Patch by Geoffrey Garen <[email protected]> on 2009-10-08
Reviewed by Sam Weinig.

SunSpider says maybe 1.03x faster.

  • runtime/JSCell.h: Nixed Structure::markAggregate, and made marking of

a Structure's prototype the direct responsility of the object using it.
(Giving Structure a mark function was misleading because it implied that
all live structures get marked during GC, when they don't.)

  • runtime/JSGlobalObject.cpp:

(JSC::markIfNeeded):
(JSC::JSGlobalObject::markChildren): Added code to mark prototypes stored
on the global object. Maybe this wasn't necessary, but now we don't have
to wonder.

  • runtime/JSObject.cpp:

(JSC::JSObject::getPropertyNames):
(JSC::JSObject::getOwnPropertyNames):
(JSC::JSObject::getEnumerableNamesFromClassInfoTable):

  • runtime/JSObject.h:

(JSC::JSObject::markChildrenDirect):

  • runtime/PropertyNameArray.h:
  • runtime/Structure.cpp:
  • runtime/Structure.h:

(JSC::Structure::setEnumerationCache):
(JSC::Structure::enumerationCache): Moved property name gathering code
from Structure to JSObject because having a Structure iterate its JSObject
was a layering violation. A JSObject is implemented using a Structure; not
the other way around.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/JSObject.cpp

    r49328 r49331  
    4343ASSERT_CLASS_FITS_IN_CELL(JSObject);
    4444
     45static inline void getEnumerablePropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames)
     46{
     47    // Add properties from the static hashtables of properties
     48    for (; classInfo; classInfo = classInfo->parentClass) {
     49        const HashTable* table = classInfo->propHashTable(exec);
     50        if (!table)
     51            continue;
     52        table->initializeIfNeeded(exec);
     53        ASSERT(table->table);
     54
     55        int hashSizeMask = table->compactSize - 1;
     56        const HashEntry* entry = table->table;
     57        for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
     58            if (entry->key() && !(entry->attributes() & DontEnum))
     59                propertyNames.add(entry->key());
     60        }
     61    }
     62}
     63
    4564void JSObject::markChildren(MarkStack& markStack)
    4665{
     
    425444void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    426445{
    427     m_structure->getEnumerablePropertyNames(exec, propertyNames, this);
     446    bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || m_structure->isDictionary());
     447
     448    if (shouldCache) {
     449        if (PropertyNameArrayData* data = m_structure->enumerationCache()) {
     450            if (data->cachedPrototypeChain() == m_structure->prototypeChain(exec)) {
     451                propertyNames.setData(data);
     452                return;
     453            }
     454
     455            m_structure->clearEnumerationCache();
     456        }
     457    }
     458
     459    getOwnPropertyNames(exec, propertyNames);
     460
     461    if (prototype().isObject()) {
     462        propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly.
     463        JSObject* prototype = asObject(this->prototype());
     464        while(1) {
     465            if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) {
     466                prototype->getPropertyNames(exec, propertyNames);
     467                break;
     468            }
     469            prototype->getOwnPropertyNames(exec, propertyNames);
     470            JSValue nextProto = prototype->prototype();
     471            if (!nextProto.isObject())
     472                break;
     473            prototype = asObject(nextProto);
     474        }
     475    }
     476
     477    if (shouldCache) {
     478        StructureChain* protoChain = m_structure->prototypeChain(exec);
     479        if (!protoChain->isCacheable())
     480            return;
     481        RefPtr<PropertyNameArrayData> data = propertyNames.data();
     482        data->setCachedPrototypeChain(protoChain);
     483        data->setCachedStructure(m_structure);
     484        m_structure->setEnumerationCache(data.release());
     485    }
    428486}
    429487
    430488void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    431489{
    432     m_structure->getOwnEnumerablePropertyNames(exec, propertyNames, this);
     490    m_structure->getEnumerablePropertyNames(propertyNames);
     491    getEnumerablePropertyNames(exec, classInfo(), propertyNames);
    433492}
    434493
Note: See TracChangeset for help on using the changeset viewer.