Changeset 28973 in webkit for trunk/JavaScriptCore/kjs/nodes.cpp


Ignore:
Timestamp:
Dec 24, 2007, 2:13:00 AM (17 years ago)
Author:
[email protected]
Message:

Reviewed by Eric.


3.5% speedup on SunSpider.

var statements now result in either assignments or empty statements.


This allows a couple of optimization opportunities:

  • No need to branch at runtime to check if there is an initializer
  • EmptyStatementNodes can be removed entirely (also done in this patch)
  • Assignment expressions get properly optimized for local variables


This patch also includes some code cleanup:

  • Most of the old VarStatement/VarDecl logic is now only used for const declarations, thus it is renamed appropriately
  • AssignExprNode is gone


  • JavaScriptCore.exp:
  • kjs/NodeInfo.h:
  • kjs/grammar.y:
  • kjs/nodes.cpp: (KJS::SourceElements::append): (KJS::ConstDeclNode::ConstDeclNode): (KJS::ConstDeclNode::optimizeVariableAccess): (KJS::ConstDeclNode::handleSlowCase): (KJS::ConstDeclNode::evaluateSingle): (KJS::ConstDeclNode::evaluate): (KJS::ConstStatementNode::optimizeVariableAccess): (KJS::ConstStatementNode::execute): (KJS::VarStatementNode::optimizeVariableAccess): (KJS::VarStatementNode::execute): (KJS::ForInNode::ForInNode): (KJS::ForInNode::optimizeVariableAccess): (KJS::ForInNode::execute): (KJS::FunctionBodyNode::initializeSymbolTable): (KJS::ProgramNode::initializeSymbolTable): (KJS::FunctionBodyNode::processDeclarations): (KJS::ProgramNode::processDeclarations): (KJS::EvalNode::processDeclarations):
  • kjs/nodes.h: (KJS::DeclarationStacks::): (KJS::StatementNode::): (KJS::ConstDeclNode::): (KJS::ConstStatementNode::): (KJS::EmptyStatementNode::): (KJS::VarStatementNode::): (KJS::ForNode::):
  • kjs/nodes2string.cpp: (KJS::ConstDeclNode::streamTo): (KJS::ConstStatementNode::streamTo): (KJS::ScopeNode::streamTo): (KJS::VarStatementNode::streamTo): (KJS::ForNode::streamTo): (KJS::ForInNode::streamTo):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r28937 r28973  
    381381void SourceElements::append(PassRefPtr<StatementNode> statement)
    382382{
     383    if (statement->isEmptyStatement())
     384        return;
     385
    383386    if (Debugger::debuggersPresent)
    384387        m_statements.append(new BreakpointCheckStatement(statement));
     
    34203423}
    34213424
    3422 // ------------------------------ AssignExprNode -------------------------------
    3423 
    3424 void AssignExprNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
    3425 {
    3426     nodeStack.append(expr.get());
    3427 }
    3428 
    3429 // ECMA 12.2
    3430 JSValue* AssignExprNode::evaluate(ExecState* exec)
    3431 {
    3432     return expr->evaluate(exec);
    3433 }
    3434 
    3435 bool AssignExprNode::evaluateToBoolean(ExecState* exec)
    3436 {
    3437     return expr->evaluateToBoolean(exec);
    3438 }
    3439 
    3440 double AssignExprNode::evaluateToNumber(ExecState* exec)
    3441 {
    3442     return expr->evaluateToNumber(exec);
    3443 }
    3444 
    3445 int32_t AssignExprNode::evaluateToInt32(ExecState* exec)
    3446 {
    3447     return expr->evaluateToInt32(exec);
    3448 }
    3449 
    3450 uint32_t AssignExprNode::evaluateToUInt32(ExecState* exec)
    3451 {
    3452     return expr->evaluateToInt32(exec);
    3453 }
    3454 
    3455 // ------------------------------ VarDeclNode ----------------------------------
    3456 
    3457 VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in, Type t)
    3458     : varType(t)
    3459     , ident(id)
     3425// ------------------------------ ConstDeclNode ----------------------------------
     3426
     3427ConstDeclNode::ConstDeclNode(const Identifier& id, ExpressionNode* in)
     3428    : ident(id)
    34603429    , init(in)
    34613430{
    34623431}
    34633432
    3464 void VarDeclNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3433void ConstDeclNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
    34653434{
    34663435    if (next)
     
    34703439}
    34713440
    3472 void VarDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val)
     3441void ConstDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val)
    34733442{
    34743443    ScopeChainIterator iter = chain.begin();
     
    34913460    unsigned flags = 0;
    34923461    base->getPropertyAttributes(ident, flags);
    3493     if (varType == VarDeclNode::Constant)
    3494         flags |= ReadOnly;
     3462    flags |= ReadOnly;
    34953463   
    34963464    base->put(exec, ident, val, flags);
     
    34983466
    34993467// ECMA 12.2
    3500 inline void VarDeclNode::evaluateSingle(ExecState* exec)
     3468inline void ConstDeclNode::evaluateSingle(ExecState* exec)
    35013469{
    35023470    ASSERT(exec->variableObject()->hasOwnProperty(exec, ident) || exec->codeType() == EvalCode); // Guaranteed by processDeclarations.
     
    35143482            if (exec->codeType() != EvalCode)
    35153483                flags |= DontDelete;
    3516             if (varType == VarDeclNode::Constant)
    3517                 flags |= ReadOnly;
     3484            flags |= ReadOnly;
    35183485            variableObject->put(exec, ident, val, flags);
    35193486        } else {
     
    35293496            unsigned flags = 0;
    35303497            variableObject->getPropertyAttributes(ident, flags);
    3531             if (varType == VarDeclNode::Constant)
    3532                 flags |= ReadOnly;
     3498            flags |= ReadOnly;
    35333499           
    35343500            variableObject->put(exec, ident, val, flags);
     
    35373503}
    35383504
    3539 JSValue* VarDeclNode::evaluate(ExecState* exec)
     3505JSValue* ConstDeclNode::evaluate(ExecState* exec)
    35403506{
    35413507    evaluateSingle(exec);
    35423508
    3543     if (VarDeclNode* n = next.get()) {
     3509    if (ConstDeclNode* n = next.get()) {
    35443510        do {
    35453511            n->evaluateSingle(exec);
     
    35513517}
    35523518
    3553 // ------------------------------ VarStatementNode -----------------------------
    3554 
    3555 void VarStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3519// ------------------------------ ConstStatementNode -----------------------------
     3520
     3521void ConstStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
    35563522{
    35573523    ASSERT(next);
     
    35603526
    35613527// ECMA 12.2
    3562 JSValue* VarStatementNode::execute(ExecState* exec)
     3528JSValue* ConstStatementNode::execute(ExecState* exec)
    35633529{
    35643530    next->evaluate(exec);
     
    36553621}
    36563622
     3623// ------------------------------ VarStatementNode ----------------------------
     3624
     3625void VarStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3626{
     3627    ASSERT(expr);
     3628    nodeStack.append(expr.get());
     3629}
     3630
     3631JSValue* VarStatementNode::execute(ExecState* exec)
     3632{
     3633    expr->evaluate(exec);
     3634    KJS_CHECKEXCEPTION
     3635
     3636    return exec->setNormalCompletion();
     3637}
     3638
    36573639// ------------------------------ IfNode ---------------------------------------
    36583640
     
    38273809
    38283810ForInNode::ForInNode(ExpressionNode* l, ExpressionNode* e, StatementNode* s)
    3829   : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
    3830 {
    3831 }
    3832 
    3833 ForInNode::ForInNode(const Identifier& i, AssignExprNode* in, ExpressionNode* e, StatementNode* s)
    3834   : ident(i), init(in), expr(e), statement(s)
    3835 {
     3811    : init(0L), lexpr(l), expr(e), statement(s), identIsVarDecl(false)
     3812{
     3813}
     3814
     3815ForInNode::ForInNode(const Identifier& i, ExpressionNode* in, ExpressionNode* e, StatementNode* s)
     3816    : ident(i), lexpr(new ResolveNode(i)), expr(e), statement(s), identIsVarDecl(true)
     3817{
     3818  if (in)
     3819      init = new AssignResolveNode(i, in);
    38363820  // for( var foo = bar in baz )
    3837   varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable);
    3838   lexpr = new ResolveNode(ident);
    38393821}
    38403822
     
    38443826    nodeStack.append(expr.get());
    38453827    nodeStack.append(lexpr.get());
    3846     if (varDecl)
    3847         nodeStack.append(varDecl.get());
     3828    if (init)
     3829        nodeStack.append(init.get());
    38483830}
    38493831
     
    38533835  JSValue* value = 0;
    38543836
    3855   if (varDecl) {
    3856     varDecl->evaluate(exec);
     3837  if (init) {
     3838    init->evaluate(exec);
    38573839    KJS_CHECKEXCEPTION
    38583840  }
     
    42684250
    42694251    for (size_t i = 0, size = m_varStack.size(); i < size; ++i, ++localStorageIndex) {
    4270         Identifier& ident = m_varStack[i]->ident;
     4252        Identifier& ident = m_varStack[i].first;
    42714253        if (ident == exec->propertyNames().arguments)
    42724254            continue;
     
    43024284    m_varIndexes.resize(size);
    43034285    for (size_t i = 0; i < size; ++i) {
    4304         const Identifier& ident = m_varStack[i]->ident;
     4286        const Identifier& ident = m_varStack[i].first;
    43054287        if (variableObject->getDirect(ident)) {
    43064288            m_varIndexes[i] = missingSymbolMarker(); // Signal not to initialize this declaration.
     
    43694351
    43704352    for (size_t i = 0, size = m_varStack.size(); i < size; ++i) {
    4371         VarDeclNode* node = m_varStack[i];
     4353        bool isConstant = m_varStack[i].second & DeclarationStacks::IsConstant;
    43724354        int attributes = minAttributes;
    4373         if (node->varType == VarDeclNode::Constant)
     4355        if (isConstant)
    43744356            attributes |= ReadOnly;
    43754357        localStorage.uncheckedAppend(LocalStorageEntry(jsUndefined(), attributes));
     
    44214403            continue;
    44224404
    4423         VarDeclNode* node = m_varStack[i];
     4405        bool isConstant = m_varStack[i].second & DeclarationStacks::IsConstant;
    44244406        int attributes = minAttributes;
    4425         if (node->varType == VarDeclNode::Constant)
     4407        if (isConstant)
    44264408            attributes |= ReadOnly;
    44274409        LocalStorageEntry entry = LocalStorageEntry(jsUndefined(), attributes);
     
    44444426
    44454427    for (i = 0, size = m_varStack.size(); i < size; ++i) {
    4446         VarDeclNode* node = m_varStack[i];
    4447         if (variableObject->hasOwnProperty(exec, node->ident))
     4428        Identifier& ident = m_varStack[i].first;
     4429        bool isConstant = m_varStack[i].second & DeclarationStacks::IsConstant;
     4430        if (variableObject->hasOwnProperty(exec, ident))
    44484431            continue;
    44494432        int attributes = minAttributes;
    4450         if (node->varType == VarDeclNode::Constant)
     4433        if (isConstant)
    44514434            attributes |= ReadOnly;
    4452         variableObject->put(exec, node->ident, jsUndefined(), attributes);
     4435        variableObject->put(exec, ident, jsUndefined(), attributes);
    44534436    }
    44544437
Note: See TracChangeset for help on using the changeset viewer.