Ignore:
Timestamp:
Feb 25, 2009, 3:44:07 PM (16 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

2009-02-25 Geoffrey Garen <[email protected]>

Reviewed by Maciej Stachowiak.


Fixed <rdar://problem/6611174> REGRESSION (r36701): Unable to select
messages on hotmail (24052)


The bug was that for-in enumeration used a cached prototype chain without
validating that it was up-to-date.


This led me to refactor prototype chain caching so it was easier to work
with and harder to get wrong.


After a bit of inlining, this patch is performance-neutral on SunSpider
and the v8 benchmarks.

  • interpreter/Interpreter.cpp: (JSC::Interpreter::tryCachePutByID): (JSC::Interpreter::tryCacheGetByID):
  • jit/JITStubs.cpp: (JSC::JITStubs::tryCachePutByID): (JSC::JITStubs::tryCacheGetByID): (JSC::JITStubs::cti_op_get_by_id_proto_list): Use the new refactored goodness. See lines beginning with "-" and smile.
  • runtime/JSGlobalObject.h: (JSC::Structure::prototypeForLookup): A shout out to const.
  • runtime/JSPropertyNameIterator.h: (JSC::JSPropertyNameIterator::next): We can use a pointer comparison to see if our cached structure chain is equal to the object's structure chain, since in the case of a cache hit, we share references to the same structure chain.
  • runtime/Operations.h: (JSC::countPrototypeChainEntriesAndCheckForProxies): Use the new refactored goodness.
  • runtime/PropertyNameArray.h: (JSC::PropertyNameArray::PropertyNameArray): (JSC::PropertyNameArray::setShouldCache): (JSC::PropertyNameArray::shouldCache): Renamed "cacheable" to "shouldCache" to communicate that the client is specifying a recommendation, not a capability.


  • runtime/Structure.cpp: (JSC::Structure::Structure): No need to initialize a RefPtr. (JSC::Structure::getEnumerablePropertyNames): Moved some code into helper functions.

(JSC::Structure::prototypeChain): New centralized accessor for a prototype
chain. Revalidates on every access, since the objects in the prototype
chain may have mutated.

(JSC::Structure::isValid): Helper function for revalidating a cached
prototype chain.

(JSC::Structure::getEnumerableNamesFromPropertyTable):
(JSC::Structure::getEnumerableNamesFromClassInfoTable): Factored out of
getEnumerablePropertyNames.

  • runtime/Structure.h:
  • runtime/StructureChain.cpp: (JSC::StructureChain::StructureChain):
  • runtime/StructureChain.h: (JSC::StructureChain::create): No need for structureChainsAreEqual, since we use pointer equality now. Refactored StructureChain to make a little more sense and eliminate special cases for null prototypes.

LayoutTests:

2009-02-24 Geoffrey Garen <[email protected]>

Reviewed by Maciej Stachowiak.


Added a test for <rdar://problem/6611174> REGRESSION (r36701): Unable to
select messages on hotmail (24052)

  • fast/js/for-in-cached-expected.txt: Added.
  • fast/js/for-in-cached.html: Added.
  • fast/js/resources/for-in-cached.js: Added. (forIn):
File:
1 edited

Legend:

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

    r40046 r41232  
    8888
    8989        JSValuePtr storedPrototype() const { return m_prototype; }
    90         JSValuePtr prototypeForLookup(ExecState*);
     90        JSValuePtr prototypeForLookup(ExecState*) const;
     91        StructureChain* prototypeChain(ExecState*) const;
    9192
    9293        Structure* previousID() const { return m_previous.get(); }
    93 
    94         StructureChain* createCachedPrototypeChain();
    95         void setCachedPrototypeChain(PassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
    96         StructureChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.get(); }
    9794
    9895        void growPropertyStorageCapacity();
     
    114111        size_t put(const Identifier& propertyName, unsigned attributes);
    115112        size_t remove(const Identifier& propertyName);
    116         void getEnumerablePropertyNamesInternal(PropertyNameArray&);
     113        void getEnumerableNamesFromPropertyTable(PropertyNameArray&);
     114        void getEnumerableNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&);
    117115
    118116        void expandPropertyMapHashTable();
     
    145143            return m_offset == noOffset ? 0 : m_offset + 1;
    146144        }
     145       
     146        bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
    147147
    148148        static const unsigned emptyEntryIndex = 0;
     
    155155
    156156        JSValuePtr m_prototype;
    157         RefPtr<StructureChain> m_cachedPrototypeChain;
     157        mutable RefPtr<StructureChain> m_cachedPrototypeChain;
    158158
    159159        RefPtr<Structure> m_previous;
Note: See TracChangeset for help on using the changeset viewer.