Title: [92540] trunk/Source/_javascript_Core
Revision
92540
Author
[email protected]
Date
2011-08-05 19:17:55 -0700 (Fri, 05 Aug 2011)

Log Message

String replace with the empty string means string removal
https://bugs.webkit.org/show_bug.cgi?id=65799

Reviewed by Sam Weinig.

Optimization for String.prototype.replace([RegExp], ""), this improves v8-regexp by ~3%.

* runtime/StringPrototype.cpp:
(JSC::jsSpliceSubstrings):
(JSC::stringProtoFuncReplace):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (92539 => 92540)


--- trunk/Source/_javascript_Core/ChangeLog	2011-08-06 02:07:55 UTC (rev 92539)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-08-06 02:17:55 UTC (rev 92540)
@@ -1,3 +1,16 @@
+2011-08-05  Gavin Barraclough  <[email protected]>
+
+        String replace with the empty string means string removal
+        https://bugs.webkit.org/show_bug.cgi?id=65799
+
+        Reviewed by Sam Weinig.
+
+        Optimization for String.prototype.replace([RegExp], ""), this improves v8-regexp by ~3%.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::jsSpliceSubstrings):
+        (JSC::stringProtoFuncReplace):
+
 2011-08-05  Noel Gordon  <[email protected]>
 
         [Chromium] Remove JSZombie references from gyp project files.

Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (92539 => 92540)


--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp	2011-08-06 02:07:55 UTC (rev 92539)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp	2011-08-06 02:17:55 UTC (rev 92540)
@@ -248,6 +248,41 @@
     int length;
 };
 
+static ALWAYS_INLINE JSValue jsSpliceSubstrings(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount)
+{
+    if (rangeCount == 1) {
+        int sourceSize = source.length();
+        int position = substringRanges[0].position;
+        int length = substringRanges[0].length;
+        if (position <= 0 && length >= sourceSize)
+            return sourceVal;
+        // We could call UString::substr, but this would result in redundant checks
+        return jsString(exec, StringImpl::create(source.impl(), max(0, position), min(sourceSize, length)));
+    }
+
+    int totalLength = 0;
+    for (int i = 0; i < rangeCount; i++)
+        totalLength += substringRanges[i].length;
+
+    if (!totalLength)
+        return jsString(exec, "");
+
+    UChar* buffer;
+    RefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
+    if (!impl)
+        return throwOutOfMemoryError(exec);
+
+    int bufferPos = 0;
+    for (int i = 0; i < rangeCount; i++) {
+        if (int srcLen = substringRanges[i].length) {
+            StringImpl::copyChars(buffer + bufferPos, source.characters() + substringRanges[i].position, srcLen);
+            bufferPos += srcLen;
+        }
+    }
+
+    return jsString(exec, impl.release());
+}
+
 static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount, const UString* separators, int separatorCount)
 {
     if (rangeCount == 1 && separatorCount == 0) {
@@ -266,11 +301,11 @@
     for (int i = 0; i < separatorCount; i++)
         totalLength += separators[i].length();
 
-    if (totalLength == 0)
+    if (!totalLength)
         return jsString(exec, "");
 
     UChar* buffer;
-    PassRefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
+    RefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
     if (!impl)
         return throwOutOfMemoryError(exec);
 
@@ -291,7 +326,7 @@
         }
     }
 
-    return jsString(exec, impl);
+    return jsString(exec, impl.release());
 }
 
 EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
@@ -320,6 +355,44 @@
 
         RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
 
+        // Optimization for substring removal (replace with empty).
+        if (global && callType == CallTypeNone && !replacementString.length()) {
+            int lastIndex = 0;
+            unsigned startPosition = 0;
+
+            Vector<StringRange, 16> sourceRanges;
+
+            while (true) {
+                int matchIndex;
+                int matchLen = 0;
+                int* ovector;
+                regExpConstructor->performMatch(*globalData, reg, source, startPosition, matchIndex, matchLen, &ovector);
+                if (matchIndex < 0)
+                    break;
+
+                if (lastIndex < matchIndex)
+                    sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
+
+                lastIndex = matchIndex + matchLen;
+                startPosition = lastIndex;
+
+                // special case of empty match
+                if (!matchLen) {
+                    startPosition++;
+                    if (startPosition > sourceLen)
+                        break;
+                }
+            }
+
+            if (!lastIndex)
+                return JSValue::encode(sourceVal);
+
+            if (static_cast<unsigned>(lastIndex) < sourceLen)
+                sourceRanges.append(StringRange(lastIndex, sourceLen - lastIndex));
+
+            return JSValue::encode(jsSpliceSubstrings(exec, sourceVal, source, sourceRanges.data(), sourceRanges.size()));
+        }
+
         int lastIndex = 0;
         unsigned startPosition = 0;
 
@@ -372,7 +445,7 @@
                 startPosition = lastIndex;
 
                 // special case of empty match
-                if (matchLen == 0) {
+                if (!matchLen) {
                     startPosition++;
                     if (startPosition > sourceLen)
                         break;
@@ -425,7 +498,7 @@
                 startPosition = lastIndex;
 
                 // special case of empty match
-                if (matchLen == 0) {
+                if (!matchLen) {
                     startPosition++;
                     if (startPosition > sourceLen)
                         break;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to