+2012-04-12 Benjamin Poulain <bpoulain@apple.com>
+
+ Improve replaceUsingStringSearch() for case of a single character searchValue
+ https://bugs.webkit.org/show_bug.cgi?id=83738
+
+ Reviewed by Geoffrey Garen.
+
+ This patch improves replaceUsingStringSearch() with the following:
+ -Add a special case for single character search, taking advantage of the faster WTF::find().
+ -Inline replaceUsingStringSearch().
+ -Use StringImpl::create() instead of UString::substringSharingImpl() since we know we are in the bounds
+ by definition.
+
+ This gives less than 1% improvement for the multicharacter replace.
+ The single character search show about 9% improvement.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::replaceUsingStringSearch):
+
2012-04-12 Michael Saboff <msaboff@apple.com>
StructureStubInfo::reset() causes leaks of PolymorphicAccessStructureList and ExecutableMemoryHandle objects
return JSValue::encode(jsSpliceSubstringsWithSeparators(exec, string, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size()));
}
-static NEVER_INLINE EncodedJSValue replaceUsingStringSearch(ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
+static inline EncodedJSValue replaceUsingStringSearch(ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
{
const UString& string = jsString->value(exec);
- UString searchString = searchValue.toString(exec)->value(exec);
+ UString searchString = searchValue.toUString(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
- size_t matchStart = string.find(searchString);
+ size_t searchStringLength = searchString.length();
+
+ size_t matchStart;
+ if (searchStringLength == 1) {
+ StringImpl* searchStringImpl = searchString.impl();
+ UChar searchCharacter;
+ if (searchStringImpl->is8Bit())
+ searchCharacter = searchStringImpl->characters8()[0];
+ else
+ searchCharacter = searchStringImpl->characters16()[0];
+
+ matchStart = string.find(searchCharacter);
+ } else
+ matchStart = string.find(searchString);
+
if (matchStart == notFound)
return JSValue::encode(jsString);
CallType callType = getCallData(replaceValue, callData);
if (callType != CallTypeNone) {
MarkedArgumentBuffer args;
- args.append(jsSubstring(exec, string, matchStart, searchString.length()));
+ args.append(jsSubstring(exec, string, matchStart, searchStringLength));
args.append(jsNumber(matchStart));
args.append(jsString);
replaceValue = call(exec, replaceValue, callType, callData, jsUndefined(), args);
return JSValue::encode(jsUndefined());
}
- UString replaceString = replaceValue.toString(exec)->value(exec);
+ UString replaceString = replaceValue.toUString(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
- size_t matchEnd = matchStart + searchString.length();
+ StringImpl* stringImpl = string.impl();
+ UString leftPart(StringImpl::create(stringImpl, 0, matchStart));
+
+ size_t matchEnd = matchStart + searchStringLength;
int ovector[2] = { matchStart, matchEnd};
- return JSValue::encode(JSC::jsString(exec, string.substringSharingImpl(0, matchStart), substituteBackreferences(replaceString, string, ovector, 0), string.substringSharingImpl(matchEnd)));
+ UString middlePart = substituteBackreferences(replaceString, string, ovector, 0);
+
+ size_t leftLength = stringImpl->length() - matchEnd;
+ UString rightPart(StringImpl::create(stringImpl, matchEnd, leftLength));
+ return JSValue::encode(JSC::jsString(exec, leftPart, middlePart, rightPart));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)