Ignore:
Timestamp:
Mar 27, 2009, 8:50:39 PM (16 years ago)
Author:
[email protected]
Message:

Improve performance of Function.prototype.call
<https://bugs.webkit.org/show_bug.cgi?id=24907>

Reviewed by Gavin Barraclough

Optimistically assume that expression.call(..) is going to be a call to
Function.prototype.call, and handle it specially to attempt to reduce the
degree of VM reentrancy.

When everything goes right this removes the vm reentry improving .call()
by around a factor of 10.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/parser/Nodes.cpp

    r41806 r42065  
    693693    RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
    694694    return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     695}
     696
     697RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     698{
     699    RefPtr<Label> realCall = generator.newLabel();
     700    RefPtr<Label> end = generator.newLabel();
     701    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
     702    generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     703    RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
     704    RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
     705    generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
     706    {
     707        RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
     708        RefPtr<RegisterID> thisRegister = generator.newTemporary();
     709        RefPtr<ArgumentListNode> oldList = m_args->m_listNode;
     710        if (m_args->m_listNode && m_args->m_listNode->m_expr) {
     711            generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr.get());
     712            m_args->m_listNode = m_args->m_listNode->m_next;
     713        } else {
     714            generator.emitLoad(thisRegister.get(), jsNull());
     715        }
     716        generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     717        generator.emitJump(end.get());
     718        m_args->m_listNode = oldList;
     719    }
     720    generator.emitLabel(realCall.get());
     721    {
     722        RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
     723        generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     724    }
     725    generator.emitLabel(end.get());
     726    return finalDestination.get();
    695727}
    696728
Note: See TracChangeset for help on using the changeset viewer.