Changeset 49323 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Oct 8, 2009, 3:02:53 PM (16 years ago)
Author:
[email protected]
Message:

Take one branch instead of two to test for JSValue().

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

1.1% SunSpider speedup.

  • jit/JITCall.cpp:

(JSC::JIT::compileOpCall):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_to_jsnumber):
(JSC::JIT::emit_op_create_arguments):

  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_put_by_val): Test for the empty value tag, instead
of testing for the cell tag with a 0 payload.

  • runtime/JSValue.cpp:

(JSC::JSValue::description): Added support for dumping the new empty value,
and deleted values, in debug builds.

  • runtime/JSValue.h:

(JSC::JSValue::JSValue()): Construct JSValue() with the empty value tag.

(JSC::JSValue::JSValue(JSCell*)): Convert null pointer to the empty value
tag, to avoid having two different c++ versions of null / empty.

(JSC::JSValue::operator bool): Test for the empty value tag, instead
of testing for the cell tag with a 0 payload.

Location:
trunk/JavaScriptCore/runtime
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/JSCell.h

    r48068 r49323  
    343343    }
    344344
    345     inline void Structure::markAggregate(MarkStack& markStack)
    346     {
    347         markStack.append(m_prototype);
    348     }
    349 
    350345    inline Heap* Heap::heap(JSValue v)
    351346    {
  • trunk/JavaScriptCore/runtime/JSGlobalObject.cpp

    r48883 r49323  
    9090{
    9191    if (s)
    92         s->markAggregate(markStack);
     92        markIfNeeded(markStack, s->storedPrototype());
    9393}
    9494
     
    395395
    396396    markIfNeeded(markStack, d()->errorStructure);
     397    markIfNeeded(markStack, d()->argumentsStructure);
     398    markIfNeeded(markStack, d()->arrayStructure);
     399    markIfNeeded(markStack, d()->booleanObjectStructure);
     400    markIfNeeded(markStack, d()->callbackConstructorStructure);
     401    markIfNeeded(markStack, d()->callbackFunctionStructure);
     402    markIfNeeded(markStack, d()->callbackObjectStructure);
     403    markIfNeeded(markStack, d()->dateStructure);
     404    markIfNeeded(markStack, d()->emptyObjectStructure);
     405    markIfNeeded(markStack, d()->errorStructure);
     406    markIfNeeded(markStack, d()->functionStructure);
     407    markIfNeeded(markStack, d()->numberObjectStructure);
     408    markIfNeeded(markStack, d()->prototypeFunctionStructure);
     409    markIfNeeded(markStack, d()->regExpMatchesArrayStructure);
     410    markIfNeeded(markStack, d()->regExpStructure);
     411    markIfNeeded(markStack, d()->stringObjectStructure);
    397412
    398413    // No need to mark the other structures, because their prototypes are all
  • trunk/JavaScriptCore/runtime/JSObject.cpp

    r48774 r49323  
    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
  • trunk/JavaScriptCore/runtime/JSObject.h

    r48836 r49323  
    683683    JSCell::markChildren(markStack);
    684684
    685     m_structure->markAggregate(markStack);
     685    markStack.append(prototype());
    686686   
    687687    PropertyStorage storage = propertyStorage();
  • trunk/JavaScriptCore/runtime/PropertyNameArray.h

    r48836 r49323  
    2424#include "CallFrame.h"
    2525#include "Identifier.h"
    26 #include "Structure.h"
     26#include "StructureChain.h"
    2727#include <wtf/HashSet.h>
    2828#include <wtf/Vector.h>
    2929
    3030namespace JSC {
     31   
     32    class Structure;
    3133
    3234    class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> {
  • trunk/JavaScriptCore/runtime/Structure.cpp

    r48582 r49323  
    283283}
    284284
    285 void Structure::getOwnEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
    286 {
    287     getEnumerableNamesFromPropertyTable(propertyNames);
    288     getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames);
    289 }
    290 
    291 void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
    292 {
    293     bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary());
    294 
    295     if (shouldCache && m_cachedPropertyNameArrayData) {
    296         if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) {
    297             propertyNames.setData(m_cachedPropertyNameArrayData);
    298             return;
    299         }
    300         clearEnumerationCache();
    301     }
    302 
    303     baseObject->getOwnPropertyNames(exec, propertyNames);
    304 
    305     if (m_prototype.isObject()) {
    306         propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly.
    307         JSObject* prototype = asObject(m_prototype);
    308         while(1) {
    309             if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) {
    310                 prototype->getPropertyNames(exec, propertyNames);
    311                 break;
    312             }
    313             prototype->getOwnPropertyNames(exec, propertyNames);
    314             JSValue nextProto = prototype->prototype();
    315             if (!nextProto.isObject())
    316                 break;
    317             prototype = asObject(nextProto);
    318         }
    319     }
    320 
    321     if (shouldCache) {
    322         StructureChain* protoChain = prototypeChain(exec);
    323         m_cachedPropertyNameArrayData = propertyNames.data();
    324         if (!protoChain->isCacheable())
    325             return;
    326         m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain);
    327         m_cachedPropertyNameArrayData->setCachedStructure(this);
    328     }
    329 }
    330 
    331285void Structure::clearEnumerationCache()
    332286{
     
    10581012}
    10591013
    1060 void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyNames)
     1014void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames)
    10611015{
    10621016    materializePropertyMapIfNecessary();
     
    11121066        for (size_t i = 0; i < sortedEnumerables.size(); ++i)
    11131067            propertyNames.add(sortedEnumerables[i]->key);
    1114     }
    1115 }
    1116 
    1117 void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames)
    1118 {
    1119     // Add properties from the static hashtables of properties
    1120     for (; classInfo; classInfo = classInfo->parentClass) {
    1121         const HashTable* table = classInfo->propHashTable(exec);
    1122         if (!table)
    1123             continue;
    1124         table->initializeIfNeeded(exec);
    1125         ASSERT(table->table);
    1126 
    1127         int hashSizeMask = table->compactSize - 1;
    1128         const HashEntry* entry = table->table;
    1129         for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
    1130             if (entry->key() && !(entry->attributes() & DontEnum))
    1131                 propertyNames.add(entry->key());
    1132         }
    11331068    }
    11341069}
  • trunk/JavaScriptCore/runtime/Structure.h

    r48582 r49323  
    3131#include "JSValue.h"
    3232#include "PropertyMapHashTable.h"
     33#include "PropertyNameArray.h"
    3334#include "StructureChain.h"
    3435#include "StructureTransitionTable.h"
     
    7778        ~Structure();
    7879
    79         void markAggregate(MarkStack&);
    80 
    8180        // These should be used with caution. 
    8281        size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
     
    117116        }
    118117
    119         void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
    120         void getOwnEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
    121 
    122118        bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
    123119        void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; }
     
    127123        JSCell* specificValue() { return m_specificValueInPrevious; }
    128124        void despecifyDictionaryFunction(const Identifier& propertyName);
     125
     126        void setEnumerationCache(PassRefPtr<PropertyNameArrayData> data) { m_cachedPropertyNameArrayData = data; }
     127        PropertyNameArrayData* enumerationCache() { return m_cachedPropertyNameArrayData.get(); }
     128        void clearEnumerationCache();
     129        void getEnumerablePropertyNames(PropertyNameArray&);
    129130
    130131    private:
     
    141142        size_t remove(const Identifier& propertyName);
    142143        void addAnonymousSlots(unsigned slotCount);
    143         void getEnumerableNamesFromPropertyTable(PropertyNameArray&);
    144         void getEnumerableNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&);
    145144
    146145        void expandPropertyMapHashTable();
     
    162161            materializePropertyMap();
    163162        }
    164 
    165         void clearEnumerationCache();
    166163
    167164        signed char transitionCount() const
Note: See TracChangeset for help on using the changeset viewer.