Ignore:
Timestamp:
Apr 8, 2009, 4:08:28 PM (16 years ago)
Author:
[email protected]
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/Arguments.cpp

    r41028 r42337  
    7070}
    7171
     72void Arguments::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize)
     73{
     74    if (UNLIKELY(d->overrodeLength)) {
     75        unsigned length = min(get(exec, exec->propertyNames().length).toUInt32(exec), maxSize);
     76        for (unsigned i = 0; i < length; i++)
     77            buffer[i] = get(exec, i);
     78        return;
     79    }
     80
     81    if (LIKELY(!d->deletedArguments)) {
     82        unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
     83        unsigned i = 0;
     84        for (; i < parametersLength; ++i)
     85            buffer[i] = d->registers[d->firstParameterIndex + i].jsValue(exec);
     86        for (; i < d->numArguments; ++i)
     87            buffer[i] = d->extraArguments[i - d->numParameters].jsValue(exec);
     88        return;
     89    }
     90   
     91    unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
     92    unsigned i = 0;
     93    for (; i < parametersLength; ++i) {
     94        if (!d->deletedArguments[i])
     95            buffer[i] = d->registers[d->firstParameterIndex + i].jsValue(exec);
     96        else
     97            buffer[i] = get(exec, i);
     98    }
     99    for (; i < d->numArguments; ++i) {
     100        if (!d->deletedArguments[i])
     101            buffer[i] = d->extraArguments[i - d->numParameters].jsValue(exec);
     102        else
     103            buffer[i] = get(exec, i);
     104    }
     105}
     106
    72107void Arguments::fillArgList(ExecState* exec, ArgList& args)
    73108{
     
    77112            args.append(get(exec, i));
    78113        return;
    79    }
     114    }
    80115
    81116    if (LIKELY(!d->deletedArguments)) {
Note: See TracChangeset for help on using the changeset viewer.