Improve function.apply performance
Reviewed by Geoff Garen.
Jump through a few hoops to improve performance of function.apply in the general case.
In the case of zero or one arguments, or if there are only two arguments and the
second is an array literal we treat function.apply as function.call.
Otherwise we use the new opcodes op_load_varargs and op_call_varargs to do the .apply call
without re-entering the virtual machine.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@42337 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp
index ea4b4f0..74bd8ff 100644
--- a/JavaScriptCore/runtime/Arguments.cpp
+++ b/JavaScriptCore/runtime/Arguments.cpp
@@ -69,6 +69,41 @@
d->activation->mark();
}
+void Arguments::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize)
+{
+ if (UNLIKELY(d->overrodeLength)) {
+ unsigned length = min(get(exec, exec->propertyNames().length).toUInt32(exec), maxSize);
+ for (unsigned i = 0; i < length; i++)
+ buffer[i] = get(exec, i);
+ return;
+ }
+
+ if (LIKELY(!d->deletedArguments)) {
+ unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
+ unsigned i = 0;
+ for (; i < parametersLength; ++i)
+ buffer[i] = d->registers[d->firstParameterIndex + i].jsValue(exec);
+ for (; i < d->numArguments; ++i)
+ buffer[i] = d->extraArguments[i - d->numParameters].jsValue(exec);
+ return;
+ }
+
+ unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
+ unsigned i = 0;
+ for (; i < parametersLength; ++i) {
+ if (!d->deletedArguments[i])
+ buffer[i] = d->registers[d->firstParameterIndex + i].jsValue(exec);
+ else
+ buffer[i] = get(exec, i);
+ }
+ for (; i < d->numArguments; ++i) {
+ if (!d->deletedArguments[i])
+ buffer[i] = d->extraArguments[i - d->numParameters].jsValue(exec);
+ else
+ buffer[i] = get(exec, i);
+ }
+}
+
void Arguments::fillArgList(ExecState* exec, ArgList& args)
{
if (UNLIKELY(d->overrodeLength)) {
@@ -76,7 +111,7 @@
for (unsigned i = 0; i < length; i++)
args.append(get(exec, i));
return;
- }
+ }
if (LIKELY(!d->deletedArguments)) {
if (LIKELY(!d->numParameters)) {