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/bytecompiler/BytecodeGenerator.cpp

    r42068 r42337  
    702702    instructions().append(cond->index());
    703703    instructions().append(m_scopeChain->globalObject()->d()->callFunction);
     704    instructions().append(target->offsetFrom(instructions().size()));
     705    return target;
     706}
     707
     708PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
     709{
     710    emitOpcode(op_jneq_ptr);
     711    instructions().append(cond->index());
     712    instructions().append(m_scopeChain->globalObject()->d()->applyFunction);
    704713    instructions().append(target->offsetFrom(instructions().size()));
    705714    return target;
     
    13381347}
    13391348
     1349RegisterID* BytecodeGenerator::emitLoadVarargs(RegisterID* argCountDst, RegisterID* arguments)
     1350{
     1351    ASSERT(argCountDst->index() < arguments->index());
     1352    emitOpcode(op_load_varargs);
     1353    instructions().append(argCountDst->index());
     1354    instructions().append(arguments->index());
     1355    return argCountDst;
     1356}
     1357
     1358RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCountRegister, unsigned divot, unsigned startOffset, unsigned endOffset)
     1359{
     1360    ASSERT(func->refCount());
     1361    ASSERT(thisRegister->refCount());
     1362    ASSERT(dst != func);
     1363    if (m_shouldEmitProfileHooks) {
     1364        emitOpcode(op_profile_will_call);
     1365        instructions().append(func->index());
     1366       
     1367#if ENABLE(JIT)
     1368        m_codeBlock->addFunctionRegisterInfo(instructions().size(), func->index());
     1369#endif
     1370    }
     1371   
     1372    emitExpressionInfo(divot, startOffset, endOffset);
     1373   
     1374    // Emit call.
     1375    emitOpcode(op_call_varargs);
     1376    instructions().append(dst->index()); // dst
     1377    instructions().append(func->index()); // func
     1378    instructions().append(argCountRegister->index()); // arg count
     1379    instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset
     1380    if (m_shouldEmitProfileHooks) {
     1381        emitOpcode(op_profile_did_call);
     1382        instructions().append(func->index());
     1383    }
     1384    return dst;
     1385}
     1386
    13401387RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
    13411388{
Note: See TracChangeset for help on using the changeset viewer.