Ignore:
Timestamp:
Jun 28, 2008, 9:03:11 AM (17 years ago)
Author:
Darin Adler
Message:

2008-06-28 Darin Adler <Darin Adler>

Reviewed by Oliver.

SunSpider says 0.9% faster.

  • VM/CodeGenerator.h: (KJS::CodeGenerator::tempDestination): Create a new temporary for ignoredResult() too, just as we would for 0. (KJS::CodeGenerator::finalDestination): Use the temporary if the register passed in is ignoredResult() too, just as we would for 0. (KJS::CodeGenerator::destinationForAssignResult): Return 0 if the passed in register is ignoredResult(), just as we would for 0. (KJS::CodeGenerator::moveToDestinationIfNeeded): Return 0 if the register passed in is ignoredResult(). What matters is that we don't want to emit a move. The return value won't be looked at. (KJS::CodeGenerator::emitNode): Allow ignoredResult() and pass it through to the node's emitCode function.
  • VM/RegisterID.h: (KJS::ignoredResult): Added. Special value to indicate the result of a node will be ignored and need not be put in any register.
  • kjs/nodes.cpp: (KJS::NullNode::emitCode): Do nothing if dst == ignoredResult(). (KJS::BooleanNode::emitCode): Ditto. (KJS::NumberNode::emitCode): Ditto. (KJS::StringNode::emitCode): Ditto. (KJS::RegExpNode::emitCode): Ditto. (KJS::ThisNode::emitCode): Ditto. (KJS::ResolveNode::emitCode): Do nothing if dst == ignoredResult() and the identifier resolves to a local variable. (KJS::ObjectLiteralNode::emitCode): Do nothing if dst == ignoredResult() and the object is empty. (KJS::PostIncResolveNode::emitCode): If dst == ignoredResult(), then do nothing for the local constant case, and do a pre-increment in all the other cases. (KJS::PostDecResolveNode::emitCode): Ditto. (KJS::PostIncBracketNode::emitCode): Ditto. (KJS::PostDecBracketNode::emitCode): Ditto. (KJS::PostIncDotNode::emitCode): Ditto. (KJS::PostDecDotNode::emitCode): Ditto. (KJS::DeleteValueNode::emitCode): Pass ignoredResult() when evaluating the expression. (KJS::VoidNode::emitCode): Ditto. (KJS::TypeOfResolveNode::emitCode): If dst == ignoredResult(), do nothing if the identifier resolves to a local variable, and don't bother generating a typeof opcode in the other case. (KJS::TypeOfValueNode::emitCode): Ditto. (KJS::PreIncResolveNode::emitCode): Do nothing if dst == ignoredResult() and the identifier resolves to a local constant. (KJS::PreDecResolveNode::emitCode): Ditto. (KJS::AssignResolveNode::emitCode): Turn ignoredResult() into 0 in a couple places, because we need to put the result into a register so we can assign it. At other sites this is taken care of by functions like finalDestination. (KJS::CommaNode::emitCode): Pass ignoredResult() when evaluating the first expression. (KJS::ForNode::emitCode): Pass ignoredResult() when evaluating the first and third expressions. (KJS::ForInNode::emitCode): Pass ignoredResult() when evaluating the first expression.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/VM/CodeGenerator.h

    r34851 r34852  
    129129        // Functions for handling of dst register
    130130
    131         // Returns  a place to write intermediate values of an operation
     131        // Returns a place to write intermediate values of an operation
    132132        // which reuses dst if it is safe to do so.
    133 
    134         RegisterID* tempDestination(RegisterID* dst) { return (dst && dst->isTemporary()) ? dst : newTemporary(); }
     133        RegisterID* tempDestination(RegisterID* dst)
     134        {
     135            return (dst && dst != ignoredResult() && dst->isTemporary()) ? dst : newTemporary();
     136        }
    135137
    136138        // Returns the place to write the final output of an operation.
    137139        RegisterID* finalDestination(RegisterID* originalDst, RegisterID* tempDst = 0)
    138140        {
    139             if (originalDst)
     141            if (originalDst && originalDst != ignoredResult())
    140142                return originalDst;
     143            ASSERT(tempDst != ignoredResult());
    141144            if (tempDst && tempDst->isTemporary())
    142145                return tempDst;
     
    146149        RegisterID* destinationForAssignResult(RegisterID* dst)
    147150        {
    148             if (dst && m_codeBlock->needsFullScopeChain)
     151            if (dst && dst != ignoredResult() && m_codeBlock->needsFullScopeChain)
    149152                return dst->isTemporary() ? dst : newTemporary();
    150153            return 0;
    151154        }
    152155
    153         // moves src to dst if dst is not null and is different from src, otherwise just returns src
    154         RegisterID* moveToDestinationIfNeeded(RegisterID* dst, RegisterID* src) { return (dst && dst != src) ? emitMove(dst, src) : src; }
     156        // Moves src to dst if dst is not null and is different from src, otherwise just returns src.
     157        RegisterID* moveToDestinationIfNeeded(RegisterID* dst, RegisterID* src)
     158        {
     159            return dst == ignoredResult() ? 0 : (dst && dst != src) ? emitMove(dst, src) : src;
     160        }
    155161
    156162        PassRefPtr<LabelID> newLabel();
    157163
    158164        // The emitNode functions are just syntactic sugar for calling
    159         // Node::emitCode. They're the only functions that accept a NULL register.
     165        // Node::emitCode. These functions accept a 0 for the register,
     166        // meaning that the node should allocate a register, or ignoredResult(),
     167        // meaning that the node need not put the result in a register.
     168        // Other emit functions do not accept 0 or ignoredResult().
    160169        RegisterID* emitNode(RegisterID* dst, Node* n)
    161170        {
    162171            // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
    163             ASSERT(!dst || !dst->isTemporary() || dst->refCount());
     172            ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
    164173            if (!m_codeBlock->lineInfo.size() || m_codeBlock->lineInfo.last().lineNumber != n->lineNo()) {
    165174                LineInfo info = { instructions().size(), n->lineNo() };
Note: See TracChangeset for help on using the changeset viewer.