[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

barraclough at apple.com barraclough at apple.com
Thu Apr 8 00:32:11 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 81b0e0f4e600d3a55b2f4b8f64fdff93ab7846a0
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Dec 11 02:07:42 2009 +0000

    https://bugs.webkit.org/show_bug.cgi?id=32400
    Switch remaining cases of string addition to use ropes.
    
    Reviewed by Oliver Hunt.
    
    ~1% progression on Sunspidey.
    
    * jit/JITStubs.cpp:
    (JSC::DEFINE_STUB_FUNCTION):
    * runtime/JSString.h:
    (JSC::JSString::JSString):
    (JSC::JSString::appendStringInConstruct):
    * runtime/Operations.cpp:
    (JSC::jsAddSlowCase):
    * runtime/Operations.h:
    (JSC::jsString):
    (JSC::jsAdd):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51975 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 8ce6f84..f1b176a 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,23 @@
+2009-12-10  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=32400
+        Switch remaining cases of string addition to use ropes.
+
+        ~1% progression on Sunspidey.
+
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION):
+        * runtime/JSString.h:
+        (JSC::JSString::JSString):
+        (JSC::JSString::appendStringInConstruct):
+        * runtime/Operations.cpp:
+        (JSC::jsAddSlowCase):
+        * runtime/Operations.h:
+        (JSC::jsString):
+        (JSC::jsAdd):
+
 2009-12-10  Kent Hansen  <kent.hansen at nokia.com>
 
         Reviewed by Geoffrey Garen.
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index fdf3d48..1a7f57f 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1031,34 +1031,19 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add)
 
     JSValue v1 = stackFrame.args[0].jsValue();
     JSValue v2 = stackFrame.args[1].jsValue();
-
-    double left;
-    double right = 0.0;
-
-    bool rightIsNumber = v2.getNumber(right);
-    if (rightIsNumber && v1.getNumber(left))
-        return JSValue::encode(jsNumber(stackFrame.globalData, left + right));
-    
     CallFrame* callFrame = stackFrame.callFrame;
 
-    bool leftIsString = v1.isString();
-    if (leftIsString && v2.isString()) {
-        JSValue result = jsString(callFrame, asString(v1), asString(v2));
+    if (v1.isString()) {
+        JSValue result = v2.isString()
+            ? jsString(callFrame, asString(v1), asString(v2))
+            : jsString(callFrame, asString(v1), v2.toString(callFrame));
         CHECK_FOR_EXCEPTION_AT_END();
         return JSValue::encode(result);
     }
 
-    if (rightIsNumber & leftIsString) {
-        RefPtr<UString::Rep> value = v2.isInt32() ?
-            concatenate(asString(v1)->value(callFrame).rep(), v2.asInt32()) :
-            concatenate(asString(v1)->value(callFrame).rep(), right);
-
-        if (UNLIKELY(!value)) {
-            throwOutOfMemoryError(callFrame);
-            VM_THROW_EXCEPTION();
-        }
-        return JSValue::encode(jsString(stackFrame.globalData, value.release()));
-    }
+    double left = 0.0, right;
+    if (v1.getNumber(left) && v2.getNumber(right))
+        return JSValue::encode(jsNumber(stackFrame.globalData, left + right));
 
     // All other cases are pretty uncommon
     JSValue result = jsAddSlowCase(callFrame, v1, v2);
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index 93b11f1..1867b17 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -203,6 +203,32 @@ namespace JSC {
             appendStringInConstruct(index, s2);
             ASSERT(ropeLength == index);
         }
+        // This constructor constructs a new string by concatenating s1 & s2.
+        // This should only be called with ropeLength <= 3.
+        JSString(JSGlobalData* globalData, unsigned ropeLength, JSString* s1, const UString& u2)
+            : JSCell(globalData->stringStructure.get())
+            , m_stringLength(s1->length() + u2.size())
+            , m_ropeLength(ropeLength)
+        {
+            ASSERT(ropeLength <= s_maxInternalRopeLength);
+            unsigned index = 0;
+            appendStringInConstruct(index, s1);
+            appendStringInConstruct(index, u2);
+            ASSERT(ropeLength == index);
+        }
+        // This constructor constructs a new string by concatenating s1 & s2.
+        // This should only be called with ropeLength <= 3.
+        JSString(JSGlobalData* globalData, unsigned ropeLength, const UString& u1, JSString* s2)
+            : JSCell(globalData->stringStructure.get())
+            , m_stringLength(u1.size() + s2->length())
+            , m_ropeLength(ropeLength)
+        {
+            ASSERT(ropeLength <= s_maxInternalRopeLength);
+            unsigned index = 0;
+            appendStringInConstruct(index, u1);
+            appendStringInConstruct(index, s2);
+            ASSERT(ropeLength == index);
+        }
         // This constructor constructs a new string by concatenating v1, v2 & v3.
         // This should only be called with ropeLength <= 3 ... which since every
         // value must require a ropeLength of at least one implies that the length
@@ -258,13 +284,18 @@ namespace JSC {
 
         void resolveRope(ExecState*) const;
 
+        void appendStringInConstruct(unsigned& index, const UString& string)
+        {
+            m_fibers[index++] = Rope::Fiber(string.rep()->ref());
+        }
+
         void appendStringInConstruct(unsigned& index, JSString* jsString)
         {
             if (jsString->isRope()) {
                 for (unsigned i = 0; i < jsString->m_ropeLength; ++i)
                     m_fibers[index++] = jsString->m_fibers[i].ref();
             } else
-                m_fibers[index++] = Rope::Fiber(jsString->string().rep()->ref());
+                appendStringInConstruct(index, jsString->string());
         }
 
         void appendValueInConstructAndIncrementLength(ExecState* exec, unsigned& index, JSValue v)
@@ -311,6 +342,8 @@ namespace JSC {
         unsigned ropeLength() { return m_ropeLength ? m_ropeLength : 1; }
 
         friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2);
+        friend JSValue jsString(ExecState* exec, const UString& u1, JSString* s2);
+        friend JSValue jsString(ExecState* exec, JSString* s1, const UString& u2);
         friend JSValue jsString(ExecState* exec, Register* strings, unsigned count);
     };
 
diff --git a/JavaScriptCore/runtime/Operations.cpp b/JavaScriptCore/runtime/Operations.cpp
index 139c7b8..0e1887c 100644
--- a/JavaScriptCore/runtime/Operations.cpp
+++ b/JavaScriptCore/runtime/Operations.cpp
@@ -54,12 +54,13 @@ NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
     JSValue p1 = v1.toPrimitive(callFrame);
     JSValue p2 = v2.toPrimitive(callFrame);
 
-    if (p1.isString() || p2.isString()) {
-        RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
-        if (!value)
-            return throwOutOfMemoryError(callFrame);
-        return jsString(callFrame, value.release());
+    if (p1.isString()) {
+        return p2.isString()
+            ? jsString(callFrame, asString(p1), asString(p2))
+            : jsString(callFrame, asString(p1), p2.toString(callFrame));
     }
+    if (p2.isString())
+        return jsString(callFrame, p1.toString(callFrame), asString(p2));
 
     return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
 }
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
index 1cab06d..0289ac2 100644
--- a/JavaScriptCore/runtime/Operations.h
+++ b/JavaScriptCore/runtime/Operations.h
@@ -37,6 +37,11 @@ namespace JSC {
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
     {
+        if (!s1->length())
+            return s2;
+        if (!s2->length())
+            return s1;
+
         unsigned ropeLength = s1->ropeLength() + s2->ropeLength();
         JSGlobalData* globalData = &exec->globalData();
 
@@ -53,6 +58,42 @@ namespace JSC {
         return new (globalData) JSString(globalData, rope.release());
     }
 
+    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2)
+    {
+        unsigned ropeLength = 1 + s2->ropeLength();
+        JSGlobalData* globalData = &exec->globalData();
+
+        if (ropeLength <= JSString::s_maxInternalRopeLength)
+            return new (globalData) JSString(globalData, ropeLength, u1, s2);
+
+        unsigned index = 0;
+        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+        if (UNLIKELY(!rope))
+            return throwOutOfMemoryError(exec);
+        rope->append(index, u1);
+        rope->append(index, s2);
+        ASSERT(index == ropeLength);
+        return new (globalData) JSString(globalData, rope.release());
+    }
+
+    ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2)
+    {
+        unsigned ropeLength = s1->ropeLength() + 1;
+        JSGlobalData* globalData = &exec->globalData();
+
+        if (ropeLength <= JSString::s_maxInternalRopeLength)
+            return new (globalData) JSString(globalData, ropeLength, s1, u2);
+
+        unsigned index = 0;
+        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+        if (UNLIKELY(!rope))
+            return throwOutOfMemoryError(exec);
+        rope->append(index, s1);
+        rope->append(index, u2);
+        ASSERT(index == ropeLength);
+        return new (globalData) JSString(globalData, rope.release());
+    }
+
     ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
     {
         ASSERT(count >= 3);
@@ -247,30 +288,14 @@ namespace JSC {
 
     ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
     {
-        double left;
-        double right = 0.0;
-
-        bool rightIsNumber = v2.getNumber(right);
-        if (rightIsNumber && v1.getNumber(left))
+        double left = 0.0, right;
+        if (v1.getNumber(left), v2.getNumber(right))
             return jsNumber(callFrame, left + right);
         
-        bool leftIsString = v1.isString();
-        if (leftIsString && v2.isString()) {
-            if (!asString(v1)->length())
-                return asString(v2);
-            if (!asString(v2)->length())
-                return asString(v1);
-            return jsString(callFrame, asString(v1), asString(v2));
-        }
-
-        if (rightIsNumber & leftIsString) {
-            RefPtr<UString::Rep> value = v2.isInt32() ?
-                concatenate(asString(v1)->value(callFrame).rep(), v2.asInt32()) :
-                concatenate(asString(v1)->value(callFrame).rep(), right);
-
-            if (!value)
-                return throwOutOfMemoryError(callFrame);
-            return jsString(callFrame, value.release());
+        if (v1.isString()) {
+            return v2.isString()
+                ? jsString(callFrame, asString(v1), asString(v2))
+                : jsString(callFrame, asString(v1), v2.toString(callFrame));
         }
 
         // All other cases are pretty uncommon

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list