https://bugs.webkit.org/show_bug.cgi?id=154871
Reviewed by Michael Saboff.
This is a simple and hugely profitable change. If we do a string.replace(/things/, ""), then
this calls directly into StringPrototype's replace-with-empty-string logic instead of going
through stuff that does checks before reaching that same conclusion.
This speeds up Octane/regexp by about 6-10%. It also speeds up the attached microbenchmark by
about 7%.
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileStringReplace):
* runtime/StringPrototype.cpp:
(JSC::jsSpliceSubstringsWithSeparators):
(JSC::removeUsingRegExpSearch):
(JSC::replaceUsingRegExpSearch):
(JSC::operationStringProtoFuncReplaceRegExpEmptyStr):
(JSC::operationStringProtoFuncReplaceRegExpString):
* runtime/StringPrototype.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@197416
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
(function() {
var result;
for (var i = 0; i < 400000; ++i) {
- result = "foo".replace(/f/, "b");
+ result = "foo".replace(/f/g, "b");
}
if (result != "boo")
throw "Error: bad result: "+ result;
+2016-03-01 Filip Pizlo <fpizlo@apple.com>
+
+ FTL should simplify StringReplace with an empty replacement string
+ https://bugs.webkit.org/show_bug.cgi?id=154871
+
+ Reviewed by Michael Saboff.
+
+ This is a simple and hugely profitable change. If we do a string.replace(/things/, ""), then
+ this calls directly into StringPrototype's replace-with-empty-string logic instead of going
+ through stuff that does checks before reaching that same conclusion.
+
+ This speeds up Octane/regexp by about 6-10%. It also speeds up the attached microbenchmark by
+ about 7%.
+
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileStringReplace):
+ * runtime/StringPrototype.cpp:
+ (JSC::jsSpliceSubstringsWithSeparators):
+ (JSC::removeUsingRegExpSearch):
+ (JSC::replaceUsingRegExpSearch):
+ (JSC::operationStringProtoFuncReplaceRegExpEmptyStr):
+ (JSC::operationStringProtoFuncReplaceRegExpString):
+ * runtime/StringPrototype.h:
+
2016-03-01 Alex Christensen <achristensen@webkit.org>
Reduce size of internal windows build output
if (m_node->child1().useKind() == StringUse
&& m_node->child2().useKind() == RegExpObjectUse
&& m_node->child3().useKind() == StringUse) {
+
+ if (JSString* replace = m_node->child3()->dynamicCastConstant<JSString*>()) {
+ if (!replace->length()) {
+ LValue string = lowString(m_node->child1());
+ LValue regExp = lowCell(m_node->child2());
+ speculateRegExpObject(m_node->child2(), regExp);
+
+ LValue result = vmCall(
+ Int64, m_out.operation(operationStringProtoFuncReplaceRegExpEmptyStr),
+ m_callFrame, string, regExp);
+
+ setJSValue(result);
+ return;
+ }
+ }
LValue string = lowString(m_node->child1());
LValue regExp = lowCell(m_node->child2());
return jsString(exec, impl.release());
}
-static NEVER_INLINE EncodedJSValue removeUsingRegExpSearch(ExecState* exec, JSString* string, const String& source, RegExp* regExp)
+static ALWAYS_INLINE EncodedJSValue removeUsingRegExpSearch(ExecState* exec, JSString* string, const String& source, RegExp* regExp)
{
size_t lastIndex = 0;
unsigned startPosition = 0;
return removeUsingRegExpSearch(exec, string, source, regExp);
}
+ // FIXME: This is wrong because we may be called directly from the FTL.
+ // https://bugs.webkit.org/show_bug.cgi?id=154874
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
size_t lastIndex = 0;
return JSValue::encode(jsSpliceSubstringsWithSeparators(exec, string, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size()));
}
+EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
+ ExecState* exec, JSString* thisValue, RegExpObject* searchValue)
+{
+ RegExp* regExp = searchValue->regExp();
+ if (regExp->global()) {
+ // ES5.1 15.5.4.10 step 8.a.
+ searchValue->setLastIndex(exec, 0);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ return removeUsingRegExpSearch(exec, thisValue, thisValue->value(exec), regExp);
+ }
+
+ CallData callData;
+ String replacementString = emptyString();
+ return replaceUsingRegExpSearch(
+ exec, thisValue, searchValue, callData, CallTypeNone, replacementString, JSValue());
+}
+
EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
ExecState* exec, JSString* thisValue, RegExpObject* searchValue, JSString* replaceString)
{
};
EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceGeneric(
- ExecState* exec, EncodedJSValue thisValue, EncodedJSValue searchValue,
- EncodedJSValue replaceValue);
+ ExecState*, EncodedJSValue thisValue, EncodedJSValue searchValue, EncodedJSValue replaceValue);
+
+EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
+ ExecState*, JSString* thisValue, RegExpObject* searchValue);
EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
- ExecState* exec, JSString* thisValue, RegExpObject* searchValue, JSString* replaceValue);
+ ExecState*, JSString* thisValue, RegExpObject* searchValue, JSString* replaceValue);
} // namespace JSC