Changeset 42065 in webkit for trunk/JavaScriptCore/parser


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.

Location:
trunk/JavaScriptCore/parser
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/parser/Grammar.y

    r39554 r42065  
    19261926    ASSERT(func.m_node->isDotAccessorNode());
    19271927    DotAccessorNode* dot = static_cast<DotAccessorNode*>(func.m_node);
    1928     FunctionCallDotNode* node = new FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
     1928    FunctionCallDotNode* node;
     1929    if (dot->identifier() == GLOBAL_DATA->propertyNames->call)
     1930        node = new CallFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
     1931    else
     1932        node = new FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
    19291933    node->setSubexpressionInfo(dot->divot(), dot->endOffset());
    19301934    return createNodeInfo<ExpressionNode*>(node, features, numConstants);
  • 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
  • trunk/JavaScriptCore/parser/Nodes.h

    r41343 r42065  
    764764        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    765765
    766     private:
     766    protected:
    767767        RefPtr<ExpressionNode> m_base;
    768768        Identifier m_ident;
    769769        RefPtr<ArgumentsNode> m_args;
     770    };
     771
     772    class CallFunctionCallDotNode : public FunctionCallDotNode {
     773    public:
     774        CallFunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
     775            : FunctionCallDotNode(globalData, base, ident, args, divot, startOffset, endOffset)
     776        {
     777        }
     778        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    770779    };
    771780
Note: See TracChangeset for help on using the changeset viewer.