2007-10-29 Eric Seidel <eric@webkit.org>
authoreseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Oct 2007 07:55:34 +0000 (07:55 +0000)
committereseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Oct 2007 07:55:34 +0000 (07:55 +0000)
        Reviewed by darin.

        Give StringInstance a getOwnPropertySlot(ExecState, unsigned, PropertySlot) fastpath, just like Arrays.
        Make it a compile time error to use toString(ExecState) on a StringInstance

        SunSpider claims this was a 6.6% speedup overall (22% on string-base64)

        * kjs/internal.h:
        (KJS::StringImp::getLength):
        * kjs/string_object.cpp:
        (KJS::StringInstance::lengthGetter):
        (KJS::StringInstance::inlineGetOwnPropertySlot):
        (KJS::StringInstance::getOwnPropertySlot):
        * kjs/string_object.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@27218 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/internal.h
JavaScriptCore/kjs/string_object.cpp
JavaScriptCore/kjs/string_object.h

index 0d13cf0..b44c7d8 100644 (file)
@@ -1,3 +1,20 @@
+2007-10-29  Eric Seidel  <eric@webkit.org>
+
+        Reviewed by darin.
+        
+        Give StringInstance a getOwnPropertySlot(ExecState, unsigned, PropertySlot) fastpath, just like Arrays.
+        Make it a compile time error to use toString(ExecState) on a StringInstance
+        
+        SunSpider claims this was a 6.6% speedup overall (22% on string-base64)
+
+        * kjs/internal.h:
+        (KJS::StringImp::getLength):
+        * kjs/string_object.cpp:
+        (KJS::StringInstance::lengthGetter):
+        (KJS::StringInstance::inlineGetOwnPropertySlot):
+        (KJS::StringInstance::getOwnPropertySlot):
+        * kjs/string_object.h:
+
 2007-10-28  Oliver Hunt  <oliver@apple.com>
 
         Reviewed by Darin.
index 7a01085..584cefc 100644 (file)
@@ -49,18 +49,18 @@ namespace KJS {
     StringImp(const UString& v) : val(v) { Collector::reportExtraMemoryCost(v.cost()); }
     enum HasOtherOwnerType { HasOtherOwner };
     StringImp(const UString& value, HasOtherOwnerType) : val(value) { }
-    UString value() const { return val; }
+    const UString& value() const { return val; }
 
+  private:
     virtual JSType type() const { return StringType; }
 
     virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
     virtual bool getPrimitiveNumber(ExecState*, double& number) const;
     virtual bool toBoolean(ExecState *exec) const;
     virtual double toNumber(ExecState *exec) const;
-    virtual UString toString(ExecState *exec) const;
     virtual JSObject *toObject(ExecState *exec) const;
-
-  private:
+    virtual UString toString(ExecState*) const;
+    
     UString val;
   };
 
index 303675c..f07f7a6 100644 (file)
@@ -63,36 +63,44 @@ StringInstance::StringInstance(JSObject *proto, const UString &string)
   setInternalValue(jsString(string));
 }
 
-JSValue *StringInstance::lengthGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot &slot)
+JSValue *StringInstance::lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot &slot)
 {
-    return jsNumber(static_cast<StringInstance*>(slot.slotBase())->internalValue()->toString(exec).size());
+    return jsNumber(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().size());
 }
 
-JSValue *StringInstance::indexGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot &slot)
+JSValue *StringInstance::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot &slot)
 {
-    const UChar c = static_cast<StringInstance *>(slot.slotBase())->internalValue()->toString(exec)[slot.index()];
+    const UChar c = static_cast<StringInstance*>(slot.slotBase())->internalValue()->value()[slot.index()];
     return jsString(UString(&c, 1));
 }
 
-bool StringInstance::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
+bool StringInstance::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 {
-  if (propertyName == exec->propertyNames().length) {
-    slot.setCustom(this, lengthGetter);
-    return true;
-  }
-
-  bool ok;
-  const unsigned index = propertyName.toArrayIndex(&ok);
-  if (ok) {
-    const UString s = internalValue()->toString(exec);
-    const unsigned length = s.size();
-    if (index < length) {
-    slot.setCustomIndex(this, index, indexGetter);
-    return true;
+    if (propertyName == exec->propertyNames().length) {
+        slot.setCustom(this, lengthGetter);
+        return true;
     }
-  }
 
-  return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+    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.setCustomIndex(this, propertyName, indexGetter);
+        return true;
+    }
+    
+    return JSObject::getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
 }
 
 void StringInstance::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
index a583e48..6c4c800 100644 (file)
@@ -31,11 +31,13 @@ namespace KJS {
   class StringInstance : public JSWrapperObject {
   public:
     StringInstance(JSObject *proto);
-    StringInstance(JSObject *proto, StringImp* string);
-    StringInstance(JSObject *proto, const UString &string);
+    StringInstance(JSObject *proto, StringImp*);
+    StringInstance(JSObject *proto, const UString&);
 
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-    virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr = None);
+    virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+
+    virtual void put(ExecState* exec, const Identifier& propertyName, JSValue*, int attr = None);
     virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName);
     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
@@ -45,8 +47,10 @@ namespace KJS {
     StringImp* internalValue() const { return static_cast<StringImp*>(JSWrapperObject::internalValue());}
 
   private:
-    static JSValue *lengthGetter(ExecState *exec, JSObject *, const Identifier&, const PropertySlot &slot);
-    static JSValue *indexGetter(ExecState *exec, JSObject *, const Identifier&, const PropertySlot &slot);
+    bool inlineGetOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
+
+    static JSValue* lengthGetter(ExecState*, JSObject *, const Identifier&, const PropertySlot&);
+    static JSValue* indexGetter(ExecState*, JSObject *, const Identifier&, const PropertySlot&);
   };
 
   // WebCore uses this to make style.filter undetectable