Changeset 49726 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Oct 16, 2009, 7:31:42 PM (16 years ago)
Author:
[email protected]
Message:

Roll out r49717 as it broke the build.

Location:
trunk/JavaScriptCore/runtime
Files:
15 edited

Legend:

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

    r49717 r49726  
    113113    };
    114114
     115    // FIXME: We should deprecate this and just use JSValue::asCell() instead.
     116    JSCell* asCell(JSValue);
     117
     118    inline JSCell* asCell(JSValue value)
     119    {
     120        return value.asCell();
     121    }
     122
    115123    inline JSCell::JSCell(Structure* structure)
    116124        : m_structure(structure)
  • trunk/JavaScriptCore/runtime/JSObject.cpp

    r49717 r49726  
    444444void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    445445{
     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
    446459    getOwnPropertyNames(exec, propertyNames);
    447460
    448     if (prototype().isNull())
    449         return;
    450 
    451     JSObject* prototype = asObject(this->prototype());
    452     while(1) {
    453         if (prototype->structure()->typeInfo().overridesGetPropertyNames()) {
    454             prototype->getPropertyNames(exec, propertyNames);
    455             break;
    456         }
    457         prototype->getOwnPropertyNames(exec, propertyNames);
    458         JSValue nextProto = prototype->prototype();
    459         if (nextProto.isNull())
    460             break;
    461         prototype = asObject(nextProto);
     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().overridesGetPropertyNames()) {
     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());
    462485    }
    463486}
  • trunk/JavaScriptCore/runtime/JSPropertyNameIterator.cpp

    r49717 r49726  
    3030#include "JSPropertyNameIterator.h"
    3131
    32 #include "JSGlobalObject.h"
    33 
    3432namespace JSC {
    3533
    3634ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator);
    3735
    38 JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o)
     36JSPropertyNameIterator::~JSPropertyNameIterator()
    3937{
    40     ASSERT(!o->structure()->enumerationCache() ||
    41             o->structure()->enumerationCache()->cachedStructure() != o->structure() ||
    42             o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec));
    43 
    44     PropertyNameArray propertyNames(exec);
    45     o->getPropertyNames(exec, propertyNames);
    46     JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data());
    47 
    48     if (o->structure()->isDictionary())
    49         return jsPropertyNameIterator;
    50 
    51     if (o->structure()->typeInfo().overridesGetPropertyNames())
    52         return jsPropertyNameIterator;
    53    
    54     size_t count = normalizePrototypeChain(exec, o);
    55     StructureChain* structureChain = o->structure()->prototypeChain(exec);
    56     RefPtr<Structure>* structure = structureChain->head();
    57     for (size_t i = 0; i < count; ++i) {
    58         if (structure[i]->typeInfo().overridesGetPropertyNames())
    59             return jsPropertyNameIterator;
    60     }
    61 
    62     jsPropertyNameIterator->setCachedPrototypeChain(structureChain);
    63     jsPropertyNameIterator->setCachedStructure(o->structure());
    64     o->structure()->setEnumerationCache(jsPropertyNameIterator);
    65     return jsPropertyNameIterator;
    66 }
    67 
    68 JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
    69 {
    70     JSValue& identifier = m_jsStrings[i];
    71     if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec))
    72         return identifier;
    73 
    74     if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value())))
    75         return JSValue();
    76     return identifier;
    7738}
    7839
    7940void JSPropertyNameIterator::markChildren(MarkStack& markStack)
    8041{
    81     markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues);
     42    JSCell::markChildren(markStack);
     43    if (m_object)
     44        markStack.append(m_object);
     45}
     46
     47void JSPropertyNameIterator::invalidate()
     48{
     49    ASSERT(m_position == m_end);
     50    m_object = 0;
     51    m_data.clear();
    8252}
    8353
  • trunk/JavaScriptCore/runtime/JSPropertyNameIterator.h

    r49717 r49726  
    3232#include "JSObject.h"
    3333#include "JSString.h"
    34 #include "Operations.h"
    3534#include "PropertyNameArray.h"
    3635
     
    4140
    4241    class JSPropertyNameIterator : public JSCell {
    43         friend class JIT;
     42    public:
     43        static JSPropertyNameIterator* create(ExecState*, JSValue);
    4444
    45     public:
    46         static JSPropertyNameIterator* create(ExecState*, JSObject*);
     45        virtual ~JSPropertyNameIterator();
     46
     47        virtual void markChildren(MarkStack&);
     48
     49        JSValue next(ExecState*);
     50        void invalidate();
    4751       
    4852        static PassRefPtr<Structure> createStructure(JSValue prototype)
     
    5054            return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren));
    5155        }
     56    private:
     57        JSPropertyNameIterator(ExecState*);
     58        JSPropertyNameIterator(ExecState*, JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData);
    5259
    53         virtual void markChildren(MarkStack&);
    54 
    55         JSValue get(ExecState*, JSObject*, size_t i);
    56         size_t size() { return m_jsStringsSize; }
    57 
    58         void setCachedStructure(Structure* structure) { m_cachedStructure = structure; }
    59         Structure* cachedStructure() { return m_cachedStructure; }
    60 
    61         void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
    62         StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
    63 
    64     private:
    65         JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData);
    66 
    67         Structure* m_cachedStructure;
    68         RefPtr<StructureChain> m_cachedPrototypeChain;
    69         size_t m_jsStringsSize;
    70         OwnArrayPtr<JSValue> m_jsStrings;
     60        JSObject* m_object;
     61        RefPtr<PropertyNameArrayData> m_data;
     62        PropertyNameArrayData::const_iterator m_position;
     63        PropertyNameArrayData::const_iterator m_end;
    7164    };
    7265
    73 inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData)
     66inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec)
    7467    : JSCell(exec->globalData().propertyNameIteratorStructure.get())
    75     , m_cachedStructure(0)
    76     , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
    77     , m_jsStrings(new JSValue[m_jsStringsSize])
     68    , m_object(0)
     69    , m_position(0)
     70    , m_end(0)
    7871{
    79     PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
    80     for (size_t i = 0; i < m_jsStringsSize; ++i)
    81         m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring());
    8272}
    8373
    84 inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache)
     74inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, JSObject* object, PassRefPtr<PropertyNameArrayData> propertyNameArrayData)
     75    : JSCell(exec->globalData().propertyNameIteratorStructure.get())
     76    , m_object(object)
     77    , m_data(propertyNameArrayData)
     78    , m_position(m_data->begin())
     79    , m_end(m_data->end())
    8580{
    86     ASSERT(!isDictionary());
    87     m_enumerationCache = enumerationCache;
     81}
     82
     83inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue v)
     84{
     85    if (v.isUndefinedOrNull())
     86        return new (exec) JSPropertyNameIterator(exec);
     87
     88    JSObject* o = v.toObject(exec);
     89    PropertyNameArray propertyNames(exec);
     90    o->getPropertyNames(exec, propertyNames);
     91    return new (exec) JSPropertyNameIterator(exec, o, propertyNames.releaseData());
     92}
     93
     94inline JSValue JSPropertyNameIterator::next(ExecState* exec)
     95{
     96    if (m_position == m_end)
     97        return JSValue();
     98
     99    if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec))
     100        return jsOwnedString(exec, (*m_position++).ustring());
     101
     102    do {
     103        if (m_object->hasProperty(exec, *m_position))
     104            return jsOwnedString(exec, (*m_position++).ustring());
     105        m_position++;
     106    } while (m_position != m_end);
     107
     108    return JSValue();
    88109}
    89110
  • trunk/JavaScriptCore/runtime/JSValue.h

    r49717 r49726  
    374374    }
    375375
    376     // FIXME: We should deprecate this and just use JSValue::asCell() instead.
    377     JSCell* asCell(JSValue);
    378 
    379     inline JSCell* asCell(JSValue value)
    380     {
    381         return value.asCell();
    382     }
    383 
    384376    ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
    385377    {
  • trunk/JavaScriptCore/runtime/MarkStack.h

    r49717 r49726  
    4848
    4949        ALWAYS_INLINE void append(JSValue);
    50         void append(JSCell*);
     50        ALWAYS_INLINE void append(JSCell*);
    5151       
    5252        ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues)
  • trunk/JavaScriptCore/runtime/ObjectConstructor.cpp

    r49717 r49726  
    126126}
    127127
    128 // FIXME: Use the enumeration cache.
    129128JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, const ArgList& args)
    130129{
  • trunk/JavaScriptCore/runtime/Operations.h

    r49717 r49726  
    225225    }
    226226
    227     inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase)
    228     {
    229         JSCell* cell = asCell(base);
     227    inline size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValue baseValue, const PropertySlot& slot)
     228    {
     229        JSCell* cell = asCell(baseValue);
    230230        size_t count = 0;
    231231
    232         while (slotBase != cell) {
     232        while (slot.slotBase() != cell) {
    233233            JSValue v = cell->structure()->prototypeForLookup(callFrame);
    234234
    235             // If we didn't find slotBase in base's prototype chain, then base
     235            // If we didn't find slotBase in baseValue's prototype chain, then baseValue
    236236            // must be a proxy for another object.
    237237
     
    251251        ASSERT(count);
    252252        return count;
    253     }
    254 
    255     inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base)
    256     {
    257         size_t count = 0;
    258         while (1) {
    259             JSValue v = base->structure()->prototypeForLookup(callFrame);
    260             if (v.isNull())
    261                 return count;
    262 
    263             base = asCell(v);
    264 
    265             // Since we're accessing a prototype in a loop, it's a good bet that it
    266             // should not be treated as a dictionary.
    267             if (base->structure()->isDictionary())
    268                 asObject(base)->setStructure(Structure::fromDictionaryTransition(base->structure()));
    269 
    270             ++count;
    271         }
    272253    }
    273254
  • trunk/JavaScriptCore/runtime/PropertyNameArray.cpp

    r49717 r49726  
    4848    }
    4949
    50     addKnownUnique(identifier);
     50    m_data->propertyNameVector().append(Identifier(m_globalData, identifier));
    5151}
    5252
  • trunk/JavaScriptCore/runtime/PropertyNameArray.h

    r49717 r49726  
    2525#include "Identifier.h"
    2626#include <wtf/HashSet.h>
    27 #include <wtf/OwnArrayPtr.h>
    2827#include <wtf/Vector.h>
    2928
     
    3332    class StructureChain;
    3433
    35     // FIXME: Rename to PropertyNameArray.
    3634    class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> {
    3735    public:
    3836        typedef Vector<Identifier, 20> PropertyNameVector;
     37        typedef PropertyNameVector::const_iterator const_iterator;
    3938
    4039        static PassRefPtr<PropertyNameArrayData> create() { return adoptRef(new PropertyNameArrayData); }
    4140
     41        const_iterator begin() const { return m_propertyNameVector.begin(); }
     42        const_iterator end() const { return m_propertyNameVector.end(); }
     43
    4244        PropertyNameVector& propertyNameVector() { return m_propertyNameVector; }
     45
     46        void setCachedStructure(Structure* structure) { m_cachedStructure = structure; }
     47        Structure* cachedStructure() const { return m_cachedStructure; }
     48
     49        void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
     50        StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
    4351
    4452    private:
    4553        PropertyNameArrayData()
     54            : m_cachedStructure(0)
    4655        {
    4756        }
    4857
    4958        PropertyNameVector m_propertyNameVector;
     59        Structure* m_cachedStructure;
     60        RefPtr<StructureChain> m_cachedPrototypeChain;
    5061    };
    5162
    52     // FIXME: Rename to PropertyNameArrayBuilder.
    5363    class PropertyNameArray {
    5464    public:
     65        typedef PropertyNameArrayData::const_iterator const_iterator;
     66
    5567        PropertyNameArray(JSGlobalData* globalData)
    5668            : m_data(PropertyNameArrayData::create())
     
    7385        void addKnownUnique(UString::Rep* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); }
    7486
     87        size_t size() const { return m_data->propertyNameVector().size(); }
     88
    7589        Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
    7690        const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; }
    7791
     92        const_iterator begin() const { return m_data->begin(); }
     93        const_iterator end() const { return m_data->end(); }
     94
    7895        void setData(PassRefPtr<PropertyNameArrayData> data) { m_data = data; }
    7996        PropertyNameArrayData* data() { return m_data.get(); }
     97
    8098        PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); }
    8199
    82         // FIXME: Remove these functions.
    83         typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator;
    84         size_t size() const { return m_data->propertyNameVector().size(); }
    85         const_iterator begin() const { return m_data->propertyNameVector().begin(); }
    86         const_iterator end() const { return m_data->propertyNameVector().end(); }
     100        void setShouldCache(bool shouldCache) { m_shouldCache = shouldCache; }
     101        bool shouldCache() const { return m_shouldCache; }
    87102
    88103    private:
  • trunk/JavaScriptCore/runtime/Protect.h

    r49717 r49726  
    2323#define Protect_h
    2424
     25#include "JSCell.h"
    2526#include "Collector.h"
    26 #include "JSValue.h"
    2727
    2828namespace JSC {
  • trunk/JavaScriptCore/runtime/Structure.cpp

    r49717 r49726  
    2929#include "Identifier.h"
    3030#include "JSObject.h"
    31 #include "JSPropertyNameIterator.h"
    32 #include "Lookup.h"
    3331#include "PropertyNameArray.h"
    3432#include "StructureChain.h"
     33#include "Lookup.h"
    3534#include <wtf/RefCountedLeakCounter.h>
    3635#include <wtf/RefPtr.h>
     
    161160
    162161    }
    163    
    164     if (m_enumerationCache)
    165         m_enumerationCache->setCachedStructure(0);
     162
     163    if (m_cachedPropertyNameArrayData)
     164        m_cachedPropertyNameArrayData->setCachedStructure(0);
    166165
    167166    if (m_propertyTable) {
     
    282281        insertIntoPropertyMapHashTable(entry);
    283282    }
     283}
     284
     285void Structure::clearEnumerationCache()
     286{
     287    if (m_cachedPropertyNameArrayData)
     288        m_cachedPropertyNameArrayData->setCachedStructure(0);
     289    m_cachedPropertyNameArrayData.clear();
    284290}
    285291
     
    547553size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
    548554{
    549     ASSERT(!m_enumerationCache);
    550555    materializePropertyMapIfNecessary();
    551556
     
    554559    if (propertyStorageSize() > propertyStorageCapacity())
    555560        growPropertyStorageCapacity();
     561    clearEnumerationCache();
    556562    return offset;
    557563}
     
    560566{
    561567    ASSERT(isUncacheableDictionary());
    562     ASSERT(!m_enumerationCache);
    563568
    564569    materializePropertyMapIfNecessary();
     
    566571    m_isPinnedPropertyTable = true;
    567572    size_t offset = remove(propertyName);
     573    clearEnumerationCache();
    568574    return offset;
    569575}
  • trunk/JavaScriptCore/runtime/Structure.h

    r49717 r49726  
    3232#include "PropertyMapHashTable.h"
    3333#include "PropertyNameArray.h"
    34 #include "Protect.h"
    3534#include "StructureChain.h"
    3635#include "StructureTransitionTable.h"
     
    125124        void despecifyDictionaryFunction(const Identifier& propertyName);
    126125
    127         void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
    128         JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); }
     126        void setEnumerationCache(PassRefPtr<PropertyNameArrayData> data) { m_cachedPropertyNameArrayData = data; }
     127        PropertyNameArrayData* enumerationCache() { return m_cachedPropertyNameArrayData.get(); }
     128        void clearEnumerationCache();
    129129        void getEnumerablePropertyNames(PropertyNameArray&);
    130130
     
    187187        StructureTransitionTable table;
    188188
    189         ProtectedPtr<JSPropertyNameIterator> m_enumerationCache;
     189        RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
    190190
    191191        PropertyMapHashTable* m_propertyTable;
  • trunk/JavaScriptCore/runtime/StructureChain.cpp

    r49717 r49726  
    4747}
    4848
     49bool StructureChain::isCacheable() const
     50{
     51    uint32_t i = 0;
     52   
     53    while (m_vector[i]) {
     54        // Both classes of dictionary structure may change arbitrarily so we can't cache them
     55        if (m_vector[i]->isDictionary())
     56            return false;
     57        if (m_vector[i++]->typeInfo().overridesGetPropertyNames())
     58            return false;
     59    }
     60    return true;
     61}
     62
    4963} // namespace JSC
  • trunk/JavaScriptCore/runtime/StructureChain.h

    r49717 r49726  
    3737
    3838    class StructureChain : public RefCounted<StructureChain> {
    39         friend class JIT;
    40 
    4139    public:
    4240        static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); }
    4341        RefPtr<Structure>* head() { return m_vector.get(); }
     42        bool isCacheable() const;
    4443
    4544    private:
Note: See TracChangeset for help on using the changeset viewer.