Reviewed by Darin and Adam.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 5 Aug 2007 05:20:35 +0000 (05:20 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 5 Aug 2007 05:20:35 +0000 (05:20 +0000)
        <rdar://problem/5368990> REGRESSION: newsgator.com sign-on 6x slower than Safari 3 beta due to GC changes (14808)

        * kjs/string_object.cpp:
        (KJS::replace): if the string didn't change (very common in some cases) reuse the original string value.
        (KJS::StringProtoFunc::callAsFunction): Pass in the StringImp* when replacing, not just the UString.
        * kjs/string_object.h:
        (KJS::StringInstance::internalValue): covariant override to return StringImp for convenience

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

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

index 22603a4..72ee3b8 100644 (file)
@@ -1,3 +1,15 @@
+2007-08-04  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin and Adam.
+        
+        <rdar://problem/5368990> REGRESSION: newsgator.com sign-on 6x slower than Safari 3 beta due to GC changes (14808)
+
+        * kjs/string_object.cpp:
+        (KJS::replace): if the string didn't change (very common in some cases) reuse the original string value.
+        (KJS::StringProtoFunc::callAsFunction): Pass in the StringImp* when replacing, not just the UString.
+        * kjs/string_object.h:
+        (KJS::StringInstance::internalValue): covariant override to return StringImp for convenience
+
 2007-08-04  Mark Rowe  <mrowe@apple.com>
 
         Reviewed by Oliver Hunt.
index 5affa19..bfa723e 100644 (file)
@@ -313,8 +313,9 @@ static inline int localeCompare(const UString& a, const UString& b)
 #endif
 }
 
-static JSValue *replace(ExecState *exec, const UString &source, JSValue *pattern, JSValue *replacement)
+static JSValue *replace(ExecState *exec, StringImp* sourceVal, JSValue *pattern, JSValue *replacement)
 {
+  UString source = sourceVal->value();
   JSObject *replacementFunction = 0;
   UString replacementString;
 
@@ -365,7 +366,7 @@ static JSValue *replace(ExecState *exec, const UString &source, JSValue *pattern
           }
           
           args.append(jsNumber(completeMatchStart));
-          args.append(jsString(source));
+          args.append(sourceVal);
 
           substitutedReplacement = replacementFunction->call(exec, exec->dynamicInterpreter()->globalObject(), 
                                                              args)->toString(exec);
@@ -389,12 +390,16 @@ static JSValue *replace(ExecState *exec, const UString &source, JSValue *pattern
       pushSourceRange(sourceRanges, sourceRangeCount, sourceRangeCapacity, UString::Range(lastIndex, source.size() - lastIndex));
 
     UString result;
+
     if (sourceRanges)
         result = source.spliceSubstringsWithSeparators(sourceRanges, sourceRangeCount, replacements, replacementCount);
 
     delete [] sourceRanges;
     delete [] replacements;
 
+    if (result == source)
+      return sourceVal;
+
     return jsString(result);
   }
   
@@ -404,14 +409,14 @@ static JSValue *replace(ExecState *exec, const UString &source, JSValue *pattern
   int matchLen = patternString.size();
   // Do the replacement
   if (matchPos == -1)
-    return jsString(source);
+    return sourceVal;
   
   if (replacementFunction) {
       List args;
       
       args.append(jsString(source.substr(matchPos, matchLen)));
       args.append(jsNumber(matchPos));
-      args.append(jsString(source));
+      args.append(sourceVal);
       
       replacementString = replacementFunction->call(exec, exec->dynamicInterpreter()->globalObject(), 
                                                     args)->toString(exec);
@@ -562,7 +567,11 @@ JSValue* StringProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, con
     break;
   }
   case Replace:
-    result = replace(exec, s, a0, a1);
+    StringImp* sVal = thisObj->inherits(&StringInstance::info) ?
+      static_cast<StringInstance*>(thisObj)->internalValue() :
+      static_cast<StringImp*>(jsString(s));
+
+    result = replace(exec, sVal, a0, a1);
     break;
   case Slice:
     {
index 9f07cf1..a583e48 100644 (file)
@@ -41,6 +41,9 @@ namespace KJS {
 
     virtual const ClassInfo *classInfo() const { return &info; }
     static const ClassInfo info;
+
+    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);