Ignore:
Timestamp:
Jun 12, 2008, 9:53:56 PM (17 years ago)
Author:
Darin Adler
Message:

2008-06-12 Darin Adler <Darin Adler>

Reviewed by Maciej.

Speeds up SunSpider by 1.1%.

Optimized code path for getting built-in properties from strings -- avoid
boxing with a string object in that case. We can make further changes to avoid
even more boxing, but this change alone is a win.

  • API/JSCallbackObjectFunctions.h: (KJS::JSCallbackObject::staticValueGetter): Use isObject instead of inherits in asssert, since the type of slotBase() is now JSValue, not JSObject. (KJS::JSCallbackObject::staticFunctionGetter): Ditto. (KJS::JSCallbackObject::callbackGetter): Ditto.
  • kjs/internal.cpp: (KJS::StringImp::getPrimitiveNumber): Updated for change of data member name. (KJS::StringImp::toBoolean): Ditto. (KJS::StringImp::toNumber): Ditto. (KJS::StringImp::toString): Ditto. (KJS::StringInstance::create): Added; avoids a bit of cut and paste code. (KJS::StringImp::toObject): Use StringInstance::create. (KJS::StringImp::toThisObject): Ditto. (KJS::StringImp::lengthGetter): Added. Replaces the getter that used to live in the StringInstance class. (KJS::StringImp::indexGetter): Ditto. (KJS::StringImp::indexNumericPropertyGetter): Ditto. (KJS::StringImp::getOwnPropertySlot): Added. Deals with built in properties of the string class without creating a StringInstance.
  • kjs/internal.h: (KJS::StringImp::getStringPropertySlot): Added. To be used by both the string and string object getOwnPropertySlot function.
  • kjs/lookup.h: (KJS::staticFunctionGetter): Updated since slotBase() is now a JSValue rather than a JSObject.
  • kjs/object.h: Removed PropertySlot::slotBase() function, which can now move back into property_slot.h where it belongs since it doesn't have to cast to JSObject*.
  • kjs/property_slot.cpp: (KJS::PropertySlot::functionGetter): Updated since slot.slotBase() is now a JSValue* instead of JSObject*. setGetterSlot still guarantees the base is a JSObject*.
  • kjs/property_slot.h: (KJS::PropertySlot::PropertySlot): Changed base to JSValue* intead of JSCell*. (KJS::PropertySlot::setStaticEntry): Ditto. (KJS::PropertySlot::setCustom): Ditto. (KJS::PropertySlot::setCustomIndex): Ditto. (KJS::PropertySlot::setCustomNumeric): Ditto. (KJS::PropertySlot::slotBase): Moved inline here since it no longer involves a downcast to JSObject*. (KJS::PropertySlot::setBase): Changed to JSValue*.
  • kjs/string_object.cpp: (KJS::StringInstance::getOwnPropertySlot): Changed to use getStringPropertySlot instead of coding the properties here. This allows sharing the code with StringImp.
  • kjs/string_object.h: Removed inlineGetOwnPropertySlot, lengthGetter, and indexGetter. Made one of the constructors protected.
  • kjs/value.h: Made getOwnPropertySlot private in the JSCell class -- this is better since it's not the real JSObject getOwnPropertySlot semantic and most callers shouldn't use it.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/internal.cpp

    r34355 r34518  
    6060{
    6161    value = this;
    62     number = val.toDouble();
    63     return false;
    64 }
    65 
    66 bool StringImp::toBoolean(ExecState *) const
    67 {
    68   return (val.size() > 0);
    69 }
    70 
    71 double StringImp::toNumber(ExecState *) const
    72 {
    73   return val.toDouble();
    74 }
    75 
    76 UString StringImp::toString(ExecState *) const
    77 {
    78   return val;
    79 }
    80 
    81 JSObject* StringImp::toObject(ExecState *exec) const
    82 {
    83     return new StringInstance(exec->lexicalGlobalObject()->stringPrototype(), const_cast<StringImp*>(this));
     62    number = m_value.toDouble();
     63    return false;
     64}
     65
     66bool StringImp::toBoolean(ExecState*) const
     67{
     68    return !m_value.isEmpty();
     69}
     70
     71double StringImp::toNumber(ExecState*) const
     72{
     73    return m_value.toDouble();
     74}
     75
     76UString StringImp::toString(ExecState*) const
     77{
     78    return m_value;
     79}
     80
     81inline StringInstance* StringInstance::create(ExecState* exec, StringImp* string)
     82{
     83    return new StringInstance(exec->lexicalGlobalObject()->stringPrototype(), string);
     84}
     85
     86JSObject* StringImp::toObject(ExecState* exec) const
     87{
     88    return StringInstance::create(exec, const_cast<StringImp*>(this));
    8489}
    8590
    8691JSObject* StringImp::toThisObject(ExecState* exec) const
    8792{
    88     return new StringInstance(exec->lexicalGlobalObject()->stringPrototype(), const_cast<StringImp*>(this));
     93    return StringInstance::create(exec, const_cast<StringImp*>(this));
     94}
     95
     96JSValue* StringImp::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
     97{
     98    return jsNumber(static_cast<StringImp*>(slot.slotBase())->value().size());
     99}
     100
     101JSValue* StringImp::indexGetter(ExecState*, const Identifier&, const PropertySlot& slot)
     102{
     103    return jsString(static_cast<StringImp*>(slot.slotBase())->value().substr(slot.index(), 1));
     104}
     105
     106JSValue* StringImp::indexNumericPropertyGetter(ExecState*, unsigned index, const PropertySlot& slot)
     107{
     108    return jsString(static_cast<StringImp*>(slot.slotBase())->value().substr(index, 1));
     109}
     110
     111bool StringImp::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
     112{
     113    // The semantics here are really getPropertySlot, not getOwnPropertySlot.
     114    // This function should only be called by JSValue::get.
     115    if (getStringPropertySlot(exec, propertyName, slot))
     116        return true;
     117    JSObject* object = StringInstance::create(exec, this);
     118    slot.setBase(object);
     119    if (object->JSObject::getOwnPropertySlot(exec, propertyName, slot))
     120        return true;
     121    while (true) {
     122        JSValue* proto = object->prototype();
     123        if (!proto->isObject()) {
     124            slot.setUndefined();
     125            return true;
     126        }
     127        object = static_cast<JSObject*>(proto);
     128        if (object->getOwnPropertySlot(exec, propertyName, slot))
     129            return true;
     130    }
     131}
     132
     133bool StringImp::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
     134{
     135    // The semantics here are really getPropertySlot, not getOwnPropertySlot.
     136    // This function should only be called by JSValue::get.
     137    if (getStringPropertySlot(propertyName, slot))
     138        return true;
     139    return StringImp::getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
    89140}
    90141
Note: See TracChangeset for help on using the changeset viewer.