https://bugs.webkit.org/show_bug.cgi?id=172798
Reviewed by Sam Weinig.
JSTests:
* microbenchmarks/string-concat-convert.js: Added.
(test):
* microbenchmarks/string-concat-long-convert.js: Added.
(test):
* microbenchmarks/string-concat-long.js: Added.
(test):
* microbenchmarks/string-concat.js: Added.
(test):
Source/JavaScriptCore:
Since we have highly effective + operation for strings,
implementing String.prototype.concat in JS simplifies the
implementation and improves performance by using speculated
types.
Added microbenchmarks show performance improvement.
string-concat-long-convert 1063.2787+-12.9101 ^ 109.0855+-2.8083 ^ definitely 9.7472x faster
string-concat-convert 1111.1366+-12.2363 ^ 99.3402+-1.9874 ^ definitely 11.1852x faster
string-concat 131.7377+-3.8359 ^ 54.3949+-0.9580 ^ definitely 2.4219x faster
string-concat-long 79.4726+-1.9644 ^ 64.6301+-1.4941 ^ definitely 1.2297x faster
* builtins/StringPrototype.js:
(globalPrivate.stringConcatSlowPath):
(concat):
* runtime/StringPrototype.cpp:
(JSC::StringPrototype::finishCreation):
(JSC::stringProtoFuncConcat): Deleted.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@217648
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2017-05-31 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ [JSC] Implement String.prototype.concat in JS builtins
+ https://bugs.webkit.org/show_bug.cgi?id=172798
+
+ Reviewed by Sam Weinig.
+
+ * microbenchmarks/string-concat-convert.js: Added.
+ (test):
+ * microbenchmarks/string-concat-long-convert.js: Added.
+ (test):
+ * microbenchmarks/string-concat-long.js: Added.
+ (test):
+ * microbenchmarks/string-concat.js: Added.
+ (test):
+
2017-05-31 Oleksandr Skachkov <gskachkov@gmail.com>
Rolling out: Prevent async methods named 'function'
--- /dev/null
+function test(a, b, c, d, e)
+{
+ return a.concat(b).concat(c).concat(d).concat(e);
+}
+noInline(test);
+
+for (var i = 0; i < 1e6; ++i)
+ test(new String("Cocoa"), new String("Cappuccino"), new String("Matcha"), new String("Rize"), new String("Kilimanjaro"));
--- /dev/null
+function test(a, b, c, d, e)
+{
+ return a.concat(b, c, d, e);
+}
+noInline(test);
+
+for (var i = 0; i < 1e6; ++i)
+ test(new String("Cocoa"), new String("Cappuccino"), new String("Matcha"), new String("Rize"), new String("Kilimanjaro"));
--- /dev/null
+function test(a, b, c, d, e)
+{
+ return a.concat(b, c, d, e);
+}
+noInline(test);
+
+for (var i = 0; i < 1e6; ++i)
+ test("Cocoa", "Cappuccino", "Matcha", "Rize", "Kilimanjaro");
--- /dev/null
+function test(a, b, c, d, e)
+{
+ return a.concat(b).concat(c).concat(d).concat(e);
+}
+noInline(test);
+
+for (var i = 0; i < 1e6; ++i)
+ test("Cocoa", "Cappuccino", "Matcha", "Rize", "Kilimanjaro");
+2017-05-31 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ [JSC] Implement String.prototype.concat in JS builtins
+ https://bugs.webkit.org/show_bug.cgi?id=172798
+
+ Reviewed by Sam Weinig.
+
+ Since we have highly effective + operation for strings,
+ implementing String.prototype.concat in JS simplifies the
+ implementation and improves performance by using speculated
+ types.
+
+ Added microbenchmarks show performance improvement.
+
+ string-concat-long-convert 1063.2787+-12.9101 ^ 109.0855+-2.8083 ^ definitely 9.7472x faster
+ string-concat-convert 1111.1366+-12.2363 ^ 99.3402+-1.9874 ^ definitely 11.1852x faster
+ string-concat 131.7377+-3.8359 ^ 54.3949+-0.9580 ^ definitely 2.4219x faster
+ string-concat-long 79.4726+-1.9644 ^ 64.6301+-1.4941 ^ definitely 1.2297x faster
+
+ * builtins/StringPrototype.js:
+ (globalPrivate.stringConcatSlowPath):
+ (concat):
+ * runtime/StringPrototype.cpp:
+ (JSC::StringPrototype::finishCreation):
+ (JSC::stringProtoFuncConcat): Deleted.
+
2017-05-31 Mark Lam <mark.lam@apple.com>
Remove overrides of visitChildren() that do not add any functionality.
}
@globalPrivate
+function stringConcatSlowPath()
+{
+ "use strict";
+
+ var result = @toString(this);
+ for (var i = 0, length = arguments.length; i < length; ++i)
+ result += @toString(arguments[i]);
+ return result;
+}
+
+function concat(arg /* ... */)
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("String.prototype.concat requires that |this| not be null or undefined");
+
+ if (@argumentCount() === 1)
+ return @toString(this) + @toString(arg);
+ return @tailCallForwardArguments(@stringConcatSlowPath, this);
+}
+
+@globalPrivate
function createHTML(func, string, tag, attribute, value)
{
"use strict";
EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncCodePointAt(ExecState*);
-EncodedJSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncReplaceUsingRegExp(ExecState*);
/* Source for StringConstructor.lut.h
@begin stringPrototypeTable
+ concat JSBuiltin DontEnum|Function 1
match JSBuiltin DontEnum|Function 1
padStart JSBuiltin DontEnum|Function 1
padEnd JSBuiltin DontEnum|Function 1
JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("charAt", stringProtoFuncCharAt, DontEnum, 1, CharAtIntrinsic);
JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("charCodeAt", stringProtoFuncCharCodeAt, DontEnum, 1, CharCodeAtIntrinsic);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("codePointAt", stringProtoFuncCodePointAt, DontEnum, 1);
- JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("concat", stringProtoFuncConcat, DontEnum, 1);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("indexOf", stringProtoFuncIndexOf, DontEnum, 1);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("lastIndexOf", stringProtoFuncLastIndexOf, DontEnum, 1);
JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().replaceUsingRegExpPrivateName(), stringProtoFuncReplaceUsingRegExp, DontEnum, 2, StringPrototypeReplaceRegExpIntrinsic);
return JSValue::encode(jsUndefined());
}
-EncodedJSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec)
-{
- VM& vm = exec->vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
-
- JSValue thisValue = exec->thisValue();
- if (thisValue.isString() && exec->argumentCount() == 1) {
- JSString* str = exec->uncheckedArgument(0).toString(exec);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
- scope.release();
- return JSValue::encode(jsString(exec, asString(thisValue), str));
- }
-
- if (!checkObjectCoercible(thisValue))
- return throwVMTypeError(exec, scope);
- scope.release();
- return JSValue::encode(jsStringFromArguments(exec, thisValue));
-}
-
EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec)
{
VM& vm = exec->vm();