Fast path for string.replace that replaces a single character by a string.
BUG= TEST= Review URL: http://codereview.chromium.org/9213002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10412 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
7370cf6f9d
commit
a97cebe292
@ -3011,7 +3011,7 @@ MaybeObject* Heap::AllocateSubString(String* buffer,
|
||||
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));
|
||||
|
@ -3233,6 +3233,59 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) {
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
// Caller must ensure that 0 <= start_index <= sub->length(),
|
||||
// and should check that pat->length() + start_index <= sub->length().
|
||||
|
@ -197,6 +197,7 @@ namespace internal {
|
||||
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 @@ class Runtime : public AllStatic {
|
||||
// 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,
|
||||
|
@ -244,6 +244,11 @@ function StringReplace(search, replace) {
|
||||
|
||||
// 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;
|
||||
|
Loading…
Reference in New Issue
Block a user