Changeset 35806 in webkit


Ignore:
Timestamp:
Aug 17, 2008 12:57:39 AM (16 years ago)
Author:
ggaren@apple.com
Message:

2007-08-16 Geoffrey Garen <ggaren@apple.com>

Reviewed by Oliver Hunt.


Sped up property access for array.length and string.length by adding a
mechanism for returning a temporary value directly instead of returning
a pointer to a function that retrieves the value.


Also removed some unused cruft from PropertySlot.


SunSpider says 0.5% - 1.2% faster.

NOTE: This optimization is not a good idea in general, because it's
actually a pessimization in the case of resolve for assignment,
and it may get in the way of other optimizations in the future.

Location:
trunk/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r35805 r35806  
     12008-08-16  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4       
     5        Sped up property access for array.length and string.length by adding a
     6        mechanism for returning a temporary value directly instead of returning
     7        a pointer to a function that retrieves the value.
     8       
     9        Also removed some unused cruft from PropertySlot.
     10       
     11        SunSpider says 0.5% - 1.2% faster.
     12
     13        NOTE: This optimization is not a good idea in general, because it's
     14        actually a pessimization in the case of resolve for assignment,
     15        and it may get in the way of other optimizations in the future.
     16       
    1172008-08-16  Dan Bernstein  <mitz@apple.com>
    218
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r35777 r35806  
    104104__ZN3KJS12JSGlobalData6createEv
    105105__ZN3KJS12JSGlobalDataD1Ev
    106 __ZN3KJS12PropertySlot15undefinedGetterEPNS_9ExecStateERKNS_10IdentifierERKS0_
    107106__ZN3KJS12SamplingTool4dumpEPNS_9ExecStateE
    108107__ZN3KJS12SamplingTool4stopEv
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r35805 r35806  
    16261626                        projectDirPath = "";
    16271627                        projectRoot = "";
    1628                         projectRoots = (
    1629                                 "",
    1630                         );
    16311628                        targets = (
    16321629                                932F5BE30822A1C700736975 /* All */,
  • trunk/JavaScriptCore/kjs/JSArray.cpp

    r35691 r35806  
    174174}
    175175
    176 JSValue* JSArray::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    177 {
    178     return jsNumber(exec, static_cast<JSArray*>(slot.slotBase())->m_length);
    179 }
    180 
    181176bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
    182177{
     
    211206{
    212207    if (propertyName == exec->propertyNames().length) {
    213         slot.setCustom(this, lengthGetter);
     208        slot.setValue(jsNumber(exec, getLength()));
    214209        return true;
    215210    }
  • trunk/JavaScriptCore/kjs/JSArray.h

    r35291 r35806  
    8282        virtual const ClassInfo* classInfo() const { return &info; }
    8383
    84         static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    85 
    8684        bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
    8785        void putSlowCase(ExecState*, unsigned propertyName, JSValue*);
  • trunk/JavaScriptCore/kjs/JSString.cpp

    r35027 r35806  
    8383}
    8484
    85 JSValue* JSString::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    86 {
    87     return jsNumber(exec, static_cast<JSString*>(slot.slotBase())->value().size());
    88 }
    89 
    90 JSValue* JSString::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    91 {
    92     return jsString(exec, static_cast<JSString*>(slot.slotBase())->value().substr(slot.index(), 1));
    93 }
    94 
    95 JSValue* JSString::indexNumericPropertyGetter(ExecState* exec, unsigned index, const PropertySlot& slot)
    96 {
    97     return jsString(exec, static_cast<JSString*>(slot.slotBase())->value().substr(index, 1));
    98 }
    99 
    10085bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    10186{
     
    120105    // The semantics here are really getPropertySlot, not getOwnPropertySlot.
    121106    // This function should only be called by JSValue::get.
    122     if (getStringPropertySlot(propertyName, slot))
     107    if (getStringPropertySlot(exec, propertyName, slot))
    123108        return true;
    124109    return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
  • trunk/JavaScriptCore/kjs/JSString.h

    r35203 r35806  
    2828#include "ExecState.h"
    2929#include "JSCell.h"
     30#include "JSNumberCell.h"
    3031#include "PropertySlot.h"
    3132#include "identifier.h"
     
    5152
    5253        bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
    53         bool getStringPropertySlot(unsigned propertyName, PropertySlot&);
     54        bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    5455
    5556        bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
     
    7879        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    7980
    80         static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    81         static JSValue* indexGetter(ExecState*, const Identifier&, const PropertySlot&);
    82         static JSValue* indexNumericPropertyGetter(ExecState*, unsigned, const PropertySlot&);
    83 
    8481        UString m_value;
    8582    };
     
    9693    {
    9794        if (propertyName == exec->propertyNames().length) {
    98             slot.setCustom(this, lengthGetter);
     95            slot.setValue(jsNumber(exec, value().size()));
    9996            return true;
    10097        }
     
    103100        unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
    104101        if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
    105             slot.setCustomIndex(this, i, indexGetter);
     102            slot.setValue(jsString(exec, value().substr(i, 1)));
    106103            return true;
    107104        }
     
    110107    }
    111108       
    112     ALWAYS_INLINE bool JSString::getStringPropertySlot(unsigned propertyName, PropertySlot& slot)
     109    ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
    113110    {
    114111        if (propertyName < static_cast<unsigned>(m_value.size())) {
    115             slot.setCustomNumeric(this, indexNumericPropertyGetter);
     112            slot.setValue(jsString(exec, value().substr(propertyName, 1)));
    116113            return true;
    117114        }
  • trunk/JavaScriptCore/kjs/PropertySlot.cpp

    r35242 r35806  
    2828namespace KJS {
    2929
    30 JSValue* PropertySlot::undefinedGetter(ExecState*, const Identifier&, const PropertySlot&)
    31 {
    32     return jsUndefined();
    33 }
    34 
    3530JSValue* PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    3631{
  • trunk/JavaScriptCore/kjs/PropertySlot.h

    r35291 r35806  
    3535#define KJS_VALUE_SLOT_MARKER 0
    3636#define KJS_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1)
    37 #define KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER reinterpret_cast<GetValueFunc>(2)
    3837
    3938    class PropertySlot {
     
    4241        {
    4342            clearBase();
     43            clearValue();
    4444        }
    4545
     
    4747            : m_slotBase(base)
    4848        {
     49            clearValue();
    4950        }
    5051
    5152        typedef JSValue* (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
    52         typedef JSValue* (*GetValueNumericFunc)(ExecState*, unsigned index, const PropertySlot&);
    5353
    5454        JSValue* getValue(ExecState* exec, const Identifier& propertyName) const
     
    5858            if (m_getValue == KJS_REGISTER_SLOT_MARKER)
    5959                return (*m_data.registerSlot).jsValue(exec);
    60             ASSERT(m_getValue != KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER);
    6160            return m_getValue(exec, propertyName, *this);
    6261        }
     
    6665            if (m_getValue == KJS_VALUE_SLOT_MARKER)
    6766                return *m_data.valueSlot;
    68             if (m_getValue == KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER)
    69                 return m_data.numericFunc(exec, propertyName, *this);
    7067            if (m_getValue == KJS_REGISTER_SLOT_MARKER)
    7168                return (*m_data.registerSlot).jsValue(exec);
     
    9188        }
    9289       
     90        void setValue(JSValue* value)
     91        {
     92            ASSERT(value);
     93            m_getValue = KJS_VALUE_SLOT_MARKER;
     94            clearBase();
     95            m_value = value;
     96            m_data.valueSlot = &m_value;
     97        }
     98
    9399        void setRegisterSlot(Register* registerSlot)
    94100        {
     
    126132        }
    127133       
    128         void setCustomNumeric(JSValue* slotBase, GetValueNumericFunc getValue)
    129         {
    130             ASSERT(slotBase);
    131             ASSERT(getValue);
    132             m_slotBase = slotBase;
    133             m_getValue = KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER;
    134             m_data.numericFunc = getValue;
    135         }
    136        
    137134        void setGetterSlot(JSObject* getterFunc)
    138135        {
     
    145142        {
    146143            clearBase();
    147             m_getValue = undefinedGetter;
     144            setValue(jsUndefined());
    148145        }
    149146
     
    168165        }
    169166
     167        void clearValue()
     168        {
     169#ifndef NDEBUG
     170            m_value = 0;
     171#endif
     172        }
     173
    170174        const HashEntry* staticEntry() const { return m_data.staticEntry; }
    171175        unsigned index() const { return m_data.index; }
    172176
    173177    private:
    174         static JSValue* undefinedGetter(ExecState*, const Identifier&, const PropertySlot&);
    175178        static JSValue* functionGetter(ExecState*, const Identifier&, const PropertySlot&);
    176179
    177180        GetValueFunc m_getValue;
     181       
     182        JSValue* m_value;
    178183
    179184        JSValue* m_slotBase;
     
    184189            const HashEntry* staticEntry;
    185190            unsigned index;
    186             GetValueNumericFunc numericFunc;
    187191        } m_data;
    188192    };
  • trunk/JavaScriptCore/kjs/StringObject.cpp

    r35027 r35806  
    5555bool StringObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
    5656{
    57     if (internalValue()->getStringPropertySlot(propertyName, slot))
     57    if (internalValue()->getStringPropertySlot(exec, propertyName, slot))
    5858        return true;   
    5959    return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
Note: See TracChangeset for help on using the changeset viewer.