Ignore:
Timestamp:
Aug 20, 2009, 3:36:36 PM (16 years ago)
Author:
[email protected]
Message:

REGRESSION: significant slowdown on Celtic Kane "AJAX declaration" subtest
https://bugs.webkit.org/show_bug.cgi?id=28332

Reviewed by Gavin Barraclough.

The method check optimisation made transitions aware of the value being
assigned when a transition was assigning a function. This had the side
effect of making every assignment of a function expression result in a
new transition, and thus a new Structure. The net result of this is that
the common JS idiom of

function MyObject() {

this.myFunction = function(...){...};

}
new MyObject();

Will produce a unique structure on every iteration, meaning that all
caching is defeated and there is a significant amount of structure churn.

The fix is to return the transition to its original form where it is
keyed off a property name + attributes tuple, but have each transition
support an optional transition on a specific value.

File:
1 edited

Legend:

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

    r47022 r47601  
    106106            return get(propertyName._ustring.rep(), attributes, specificValue);
    107107        }
     108        bool transitionedFor(const JSCell* specificValue)
     109        {
     110            return m_specificValueInPrevious == specificValue;
     111        }
     112        bool hasTransition(UString::Rep* rep, unsigned attributes);
     113        bool hasTransition(const Identifier& propertyName, unsigned attributes)
     114        {
     115            return hasTransition(propertyName._ustring.rep(), attributes);
     116        }
    108117
    109118        void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
     
    167176        RefPtr<Structure> m_previous;
    168177        RefPtr<UString::Rep> m_nameInPrevious;
     178        JSCell* m_specificValueInPrevious;
    169179
    170180        union {
     
    172182            StructureTransitionTable* table;
    173183        } m_transitions;
    174         JSCell* m_specificValueInPrevious;
    175184
    176185        RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
     
    232241        }
    233242    }
    234 
     243   
     244    bool StructureTransitionTable::contains(const StructureTransitionTableHash::Key& key, JSCell* specificValue)
     245    {
     246        const TransitionTable::iterator find = m_table.find(key);
     247        if (find == m_table.end()) {
     248            ASSERT(!m_table.contains(key));
     249            return false;
     250        }
     251        return find->second.first || find->second.second->transitionedFor(specificValue);
     252    }
     253
     254    Structure* StructureTransitionTable::get(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const
     255    {
     256        Transition transition = m_table.get(key);
     257        if (transition.second && transition.second->transitionedFor(specificValue))
     258            return transition.second;
     259        return transition.first;
     260    }
    235261} // namespace JSC
    236262
Note: See TracChangeset for help on using the changeset viewer.