Revision: 10412
Author:   [email protected]
Date:     Mon Jan 16 07:21:38 2012
Log: Fast path for string.replace that replaces a single character by a string.

BUG=
TEST=

Review URL: http://codereview.chromium.org/9213002
http://code.google.com/p/v8/source/detail?r=10412

Modified:
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/src/string.js

=======================================
--- /branches/bleeding_edge/src/heap.cc Mon Jan 16 04:38:59 2012
+++ /branches/bleeding_edge/src/heap.cc Mon Jan 16 07:21:38 2012
@@ -3011,7 +3011,7 @@
                                      int end,
                                      PretenureFlag pretenure) {
   int length = end - start;
-  if (length == 0) {
+  if (length <= 0) {
     return empty_string();
   } else if (length == 1) {
     return LookupSingleCharacterStringFromCode(buffer->Get(start));
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Mon Jan 16 04:38:59 2012
+++ /branches/bleeding_edge/src/runtime.cc      Mon Jan 16 07:21:38 2012
@@ -3231,6 +3231,59 @@
                                        replacement,
                                        last_match_info);
 }
+
+
+Handle<String> Runtime::StringReplaceOneCharWithString(Isolate* isolate,
+ Handle<String> subject, + Handle<String> search, + Handle<String> replace,
+                                                       bool* found) {
+  if (subject->IsConsString()) {
+    ConsString* cons = ConsString::cast(*subject);
+    Handle<String> first = Handle<String>(cons->first());
+    Handle<String> second = Handle<String>(cons->second());
+    Handle<String> new_first = StringReplaceOneCharWithString(isolate,
+                                                              first,
+                                                              search,
+                                                              replace,
+                                                              found);
+    if (*found) {
+      return isolate->factory()->NewConsString(new_first, second);
+    } else {
+      Handle<String> new_second = StringReplaceOneCharWithString(isolate,
+                                                                 second,
+                                                                 search,
+                                                                 replace,
+                                                                 found);
+      return isolate->factory()->NewConsString(first, new_second);
+    }
+  } else {
+    int index = StringMatch(isolate, subject, search, 0);
+    if (index == -1) return subject;
+    *found = true;
+ Handle<String> first = isolate->factory()->NewSubString(subject, 0, index); + Handle<String> cons1 = isolate->factory()->NewConsString(first, replace);
+    Handle<String> second =
+ isolate->factory()->NewSubString(subject, index + 1, subject->length());
+    return isolate->factory()->NewConsString(cons1, second);
+  }
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) {
+  ASSERT(args.length() == 3);
+  HandleScope scope(isolate);
+  CONVERT_ARG_CHECKED(String, subject, 0);
+  CONVERT_ARG_CHECKED(String, search, 1);
+  CONVERT_ARG_CHECKED(String, replace, 2);
+  bool found = false;
+
+  return *(Runtime::StringReplaceOneCharWithString(isolate,
+                                                   subject,
+                                                   search,
+                                                   replace,
+                                                   &found));
+}


 // Perform string match of pattern on subject, starting at start index.
=======================================
--- /branches/bleeding_edge/src/runtime.h       Wed Dec 28 07:14:33 2011
+++ /branches/bleeding_edge/src/runtime.h       Mon Jan 16 07:21:38 2012
@@ -197,6 +197,7 @@
   F(StringLocaleCompare, 2, 1) \
   F(SubString, 3, 1) \
   F(StringReplaceRegExpWithString, 4, 1) \
+  F(StringReplaceOneCharWithString, 3, 1) \
   F(StringMatch, 3, 1) \
   F(StringTrim, 3, 1) \
   F(StringToArray, 2, 1) \
@@ -629,6 +630,12 @@
   // Get the intrinsic function with the given FunctionId.
   static const Function* FunctionForId(FunctionId id);

+  static Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
+ Handle<String> subject, + Handle<String> search, + Handle<String> replace,
+                                                       bool* found);
+
   // General-purpose helper functions for runtime system.
   static int StringMatch(Isolate* isolate,
                          Handle<String> sub,
=======================================
--- /branches/bleeding_edge/src/string.js       Mon Nov 28 04:11:00 2011
+++ /branches/bleeding_edge/src/string.js       Mon Jan 16 07:21:38 2012
@@ -244,6 +244,11 @@

   // Convert the search argument to a string and search for it.
   search = TO_STRING_INLINE(search);
+  if (search.length == 1 &&
+      IS_STRING(replace) &&
+      %StringIndexOf(replace, '$', 0) < 0) {
+    return %StringReplaceOneCharWithString(subject, search, replace);
+  }
   var start = %StringIndexOf(subject, search, 0);
   if (start < 0) return subject;
   var end = start + search.length;

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to