Changeset 49734 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Oct 16, 2009, 10:52:20 PM (16 years ago)
Author:
[email protected]
Message:

Rolled back in r49717 with the build maybe working now?

Location:
trunk/JavaScriptCore/runtime
Files:
15 edited

Legend:

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

    r49726 r49734  
    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 
    123115    inline JSCell::JSCell(Structure* structure)
    124116        : m_structure(structure)
  • trunk/JavaScriptCore/runtime/JSObject.cpp

    r49726 r49734  
    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 
    459446    getOwnPropertyNames(exec, propertyNames);
    460447
    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());
     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);
    485462    }
    486463}
  • trunk/JavaScriptCore/runtime/JSPropertyNameIterator.cpp

    r49726 r49734  
    3030#include "JSPropertyNameIterator.h"
    3131
     32#include "JSGlobalObject.h"
     33
    3234namespace JSC {
    3335
    3436ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator);
    3537
    36 JSPropertyNameIterator::~JSPropertyNameIterator()
     38JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o)
    3739{
     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
     68JSValue 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;
    3877}
    3978
    4079void JSPropertyNameIterator::markChildren(MarkStack& markStack)
    4180{
    42     JSCell::markChildren(markStack);
    43     if (m_object)
    44         markStack.append(m_object);
    45 }
    46 
    47 void JSPropertyNameIterator::invalidate()
    48 {
    49     ASSERT(m_position == m_end);
    50     m_object = 0;
    51     m_data.clear();
     81    markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues);
    5282}
    5383
  • trunk/JavaScriptCore/runtime/JSPropertyNameIterator.h

    r49726 r49734  
    3232#include "JSObject.h"
    3333#include "JSString.h"
     34#include "Operations.h"
    3435#include "PropertyNameArray.h"
    3536
     
    4041
    4142    class JSPropertyNameIterator : public JSCell {
     43        friend class JIT;
     44
    4245    public:
    43         static JSPropertyNameIterator* create(ExecState*, JSValue);
    44 
    45         virtual ~JSPropertyNameIterator();
    46 
    47         virtual void markChildren(MarkStack&);
    48 
    49         JSValue next(ExecState*);
    50         void invalidate();
     46        static JSPropertyNameIterator* create(ExecState*, JSObject*);
    5147       
    5248        static PassRefPtr<Structure> createStructure(JSValue prototype)
     
    5450            return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren));
    5551        }
     52
     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
    5664    private:
    57         JSPropertyNameIterator(ExecState*);
    58         JSPropertyNameIterator(ExecState*, JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData);
     65        JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData);
    5966
    60         JSObject* m_object;
    61         RefPtr<PropertyNameArrayData> m_data;
    62         PropertyNameArrayData::const_iterator m_position;
    63         PropertyNameArrayData::const_iterator m_end;
     67        Structure* m_cachedStructure;
     68        RefPtr<StructureChain> m_cachedPrototypeChain;
     69        size_t m_jsStringsSize;
     70        OwnArrayPtr<JSValue> m_jsStrings;
    6471    };
    6572
    66 inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec)
     73inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData)
    6774    : JSCell(exec->globalData().propertyNameIteratorStructure.get())
    68     , m_object(0)
    69     , m_position(0)
    70     , m_end(0)
     75    , m_cachedStructure(0)
     76    , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
     77    , m_jsStrings(new JSValue[m_jsStringsSize])
    7178{
     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());
    7282}
    7383
    74 inline 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())
     84inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache)
    8085{
    81 }
    82 
    83 inline 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 
    94 inline 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();
     86    ASSERT(!isDictionary());
     87    m_enumerationCache = enumerationCache;
    10988}
    11089
  • trunk/JavaScriptCore/runtime/JSValue.h

    r49726 r49734  
    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
    376384    ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
    377385    {
  • trunk/JavaScriptCore/runtime/MarkStack.h

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

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

    r49726 r49734  
    225225    }
    226226
    227     inline size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValue baseValue, const PropertySlot& slot)
    228     {
    229         JSCell* cell = asCell(baseValue);
     227    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase)
     228    {
     229        JSCell* cell = asCell(base);
    230230        size_t count = 0;
    231231
    232         while (slot.slotBase() != cell) {
     232        while (slotBase != cell) {
    233233            JSValue v = cell->structure()->prototypeForLookup(callFrame);
    234234
    235             // If we didn't find slotBase in baseValue's prototype chain, then baseValue
     235            // If we didn't find slotBase in base's prototype chain, then base
    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        }
    253272    }
    254273
  • trunk/JavaScriptCore/runtime/PropertyNameArray.cpp

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

    r49726 r49734  
    2525#include "Identifier.h"
    2626#include <wtf/HashSet.h>
     27#include <wtf/OwnArrayPtr.h>
    2728#include <wtf/Vector.h>
    2829
     
    3233    class StructureChain;
    3334
     35    // FIXME: Rename to PropertyNameArray.
    3436    class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> {
    3537    public:
    3638        typedef Vector<Identifier, 20> PropertyNameVector;
    37         typedef PropertyNameVector::const_iterator const_iterator;
    3839
    3940        static PassRefPtr<PropertyNameArrayData> create() { return adoptRef(new PropertyNameArrayData); }
    4041
    41         const_iterator begin() const { return m_propertyNameVector.begin(); }
    42         const_iterator end() const { return m_propertyNameVector.end(); }
    43 
    4442        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(); }
    5143
    5244    private:
    5345        PropertyNameArrayData()
    54             : m_cachedStructure(0)
    5546        {
    5647        }
    5748
    5849        PropertyNameVector m_propertyNameVector;
    59         Structure* m_cachedStructure;
    60         RefPtr<StructureChain> m_cachedPrototypeChain;
    6150    };
    6251
     52    // FIXME: Rename to PropertyNameArrayBuilder.
    6353    class PropertyNameArray {
    6454    public:
    65         typedef PropertyNameArrayData::const_iterator const_iterator;
    66 
    6755        PropertyNameArray(JSGlobalData* globalData)
    6856            : m_data(PropertyNameArrayData::create())
     
    8573        void addKnownUnique(UString::Rep* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); }
    8674
    87         size_t size() const { return m_data->propertyNameVector().size(); }
    88 
    8975        Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
    9076        const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; }
    9177
    92         const_iterator begin() const { return m_data->begin(); }
    93         const_iterator end() const { return m_data->end(); }
    94 
    9578        void setData(PassRefPtr<PropertyNameArrayData> data) { m_data = data; }
    9679        PropertyNameArrayData* data() { return m_data.get(); }
    97 
    9880        PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); }
    9981
    100         void setShouldCache(bool shouldCache) { m_shouldCache = shouldCache; }
    101         bool shouldCache() const { return m_shouldCache; }
     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(); }
    10287
    10388    private:
  • trunk/JavaScriptCore/runtime/Protect.h

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

    r49726 r49734  
    2929#include "Identifier.h"
    3030#include "JSObject.h"
     31#include "JSPropertyNameIterator.h"
     32#include "Lookup.h"
    3133#include "PropertyNameArray.h"
    3234#include "StructureChain.h"
    33 #include "Lookup.h"
    3435#include <wtf/RefCountedLeakCounter.h>
    3536#include <wtf/RefPtr.h>
     
    160161
    161162    }
    162 
    163     if (m_cachedPropertyNameArrayData)
    164         m_cachedPropertyNameArrayData->setCachedStructure(0);
     163   
     164    if (m_enumerationCache)
     165        m_enumerationCache->setCachedStructure(0);
    165166
    166167    if (m_propertyTable) {
     
    281282        insertIntoPropertyMapHashTable(entry);
    282283    }
    283 }
    284 
    285 void Structure::clearEnumerationCache()
    286 {
    287     if (m_cachedPropertyNameArrayData)
    288         m_cachedPropertyNameArrayData->setCachedStructure(0);
    289     m_cachedPropertyNameArrayData.clear();
    290284}
    291285
     
    553547size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
    554548{
     549    ASSERT(!m_enumerationCache);
    555550    materializePropertyMapIfNecessary();
    556551
     
    559554    if (propertyStorageSize() > propertyStorageCapacity())
    560555        growPropertyStorageCapacity();
    561     clearEnumerationCache();
    562556    return offset;
    563557}
     
    566560{
    567561    ASSERT(isUncacheableDictionary());
     562    ASSERT(!m_enumerationCache);
    568563
    569564    materializePropertyMapIfNecessary();
     
    571566    m_isPinnedPropertyTable = true;
    572567    size_t offset = remove(propertyName);
    573     clearEnumerationCache();
    574568    return offset;
    575569}
  • trunk/JavaScriptCore/runtime/Structure.h

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

    r49726 r49734  
    4747}
    4848
    49 bool 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 
    6349} // namespace JSC
  • trunk/JavaScriptCore/runtime/StructureChain.h

    r49726 r49734  
    3737
    3838    class StructureChain : public RefCounted<StructureChain> {
     39        friend class JIT;
     40
    3941    public:
    4042        static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); }
    4143        RefPtr<Structure>* head() { return m_vector.get(); }
    42         bool isCacheable() const;
    4344
    4445    private:
Note: See TracChangeset for help on using the changeset viewer.