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,
|
int end,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
int length = end - start;
|
int length = end - start;
|
||||||
if (length == 0) {
|
if (length <= 0) {
|
||||||
return empty_string();
|
return empty_string();
|
||||||
} else if (length == 1) {
|
} else if (length == 1) {
|
||||||
return LookupSingleCharacterStringFromCode(buffer->Get(start));
|
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.
|
// Perform string match of pattern on subject, starting at start index.
|
||||||
// Caller must ensure that 0 <= start_index <= sub->length(),
|
// Caller must ensure that 0 <= start_index <= sub->length(),
|
||||||
// and should check that pat->length() + 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(StringLocaleCompare, 2, 1) \
|
||||||
F(SubString, 3, 1) \
|
F(SubString, 3, 1) \
|
||||||
F(StringReplaceRegExpWithString, 4, 1) \
|
F(StringReplaceRegExpWithString, 4, 1) \
|
||||||
|
F(StringReplaceOneCharWithString, 3, 1) \
|
||||||
F(StringMatch, 3, 1) \
|
F(StringMatch, 3, 1) \
|
||||||
F(StringTrim, 3, 1) \
|
F(StringTrim, 3, 1) \
|
||||||
F(StringToArray, 2, 1) \
|
F(StringToArray, 2, 1) \
|
||||||
@ -629,6 +630,12 @@ class Runtime : public AllStatic {
|
|||||||
// Get the intrinsic function with the given FunctionId.
|
// Get the intrinsic function with the given FunctionId.
|
||||||
static const Function* FunctionForId(FunctionId id);
|
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.
|
// General-purpose helper functions for runtime system.
|
||||||
static int StringMatch(Isolate* isolate,
|
static int StringMatch(Isolate* isolate,
|
||||||
Handle<String> sub,
|
Handle<String> sub,
|
||||||
|
@ -244,6 +244,11 @@ function StringReplace(search, replace) {
|
|||||||
|
|
||||||
// Convert the search argument to a string and search for it.
|
// Convert the search argument to a string and search for it.
|
||||||
search = TO_STRING_INLINE(search);
|
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);
|
var start = %StringIndexOf(subject, search, 0);
|
||||||
if (start < 0) return subject;
|
if (start < 0) return subject;
|
||||||
var end = start + search.length;
|
var end = start + search.length;
|
||||||
|
Loading…
Reference in New Issue
Block a user