2008-06-12  Darin Adler  <darin@apple.com>

        Reviewed by Maciej.

        - https://bugs.webkit.org/show_bug.cgi?id=19434
          speed up SunSpider by avoiding some string boxing

        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.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34518 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/kjs/string_object.cpp b/JavaScriptCore/kjs/string_object.cpp
index f456b5e..628eb8d 100644
--- a/JavaScriptCore/kjs/string_object.cpp
+++ b/JavaScriptCore/kjs/string_object.cpp
@@ -58,47 +58,17 @@
   setInternalValue(jsString(string));
 }
 
-JSValue *StringInstance::lengthGetter(ExecState*, const Identifier&, const PropertySlot &slot)
-{
-    return jsNumber(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().size());
-}
-
-JSValue* StringInstance::indexGetter(ExecState*, const Identifier&, const PropertySlot& slot)
-{
-    return jsString(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().substr(slot.index(), 1));
-}
-
-static JSValue* stringInstanceNumericPropertyGetter(ExecState*, unsigned index, const PropertySlot& slot)
-{
-    return jsString(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().substr(index, 1));
-}
-
 bool StringInstance::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 {
-    if (propertyName == exec->propertyNames().length) {
-        slot.setCustom(this, lengthGetter);
+    if (internalValue()->getStringPropertySlot(exec, propertyName, slot))
         return true;
-    }
-
-    bool isStrictUInt32;
-    unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
-    unsigned length = internalValue()->value().size();
-    if (isStrictUInt32 && i < length) {
-        slot.setCustomIndex(this, i, indexGetter);
-        return true;
-    }
-    
     return JSObject::getOwnPropertySlot(exec, propertyName, slot);
 }
     
 bool StringInstance::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
 {
-    unsigned length = internalValue()->value().size();
-    if (propertyName < length) {
-        slot.setCustomNumeric(this, stringInstanceNumericPropertyGetter);
-        return true;
-    }
-    
+    if (internalValue()->getStringPropertySlot(propertyName, slot))
+        return true;    
     return JSObject::getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
 }