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


Ignore:
Timestamp:
Oct 26, 2007, 3:43:03 PM (18 years ago)
Author:
ggaren
Message:

Reviewed by Maciej Stachowiak.


Switched ActivationImp to using a symbol table. For now, though, all
clients take the slow path.


Net .6% speedup on SunSpider.


Slowdowns:

  • ActivationImp now mallocs in its constructor
  • Local variable hits use an extra level of indirection to retrieve data
  • Local variable misses do two lookups

Speedups:

  • Fast initialization of local variables upon function entry


  • kjs/function.cpp: (KJS::ActivationImp::ActivationImp): Malloc a private structure to hold data that won't fit in a JSCell. (KJS::ActivationImp::argumentsGetter): Use slow symbol table path for lookup. (KJS::ActivationImp::getOwnPropertySlot): ditto (KJS::ActivationImp::deleteProperty): ditto (KJS::ActivationImp::put): ditto (KJS::ActivationImp::createArgumentsObject): ditto

(KJS::ActivationImp::mark): Call JSObject::mark first so that one of
our properties doesn't try to recursively mark us. (This caused a crash
in earlier testing. Not sure why we haven't run into it before.)

  • kjs/nodes.cpp: Functions now build a symbol table the first time they're called. (KJS::VarDeclNode::evaluate): (KJS::FunctionBodyNode::FunctionBodyNode): (KJS::FunctionBodyNode::initializeSymbolTable): (KJS::FunctionBodyNode::processDeclarations): (KJS::FunctionBodyNode::processDeclarationsForFunctionCode): (KJS::FunctionBodyNode::processDeclarationsForProgramCode):
  • kjs/nodes.h: (KJS::FunctionBodyNode::symbolTable):
  • wtf/Forward.h: Added Vector.
File:
1 edited

Legend:

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

    r27100 r27126  
    18351835            flags |= ReadOnly;
    18361836       
    1837         ASSERT(variableObject->getDirect(ident) || ident == exec->propertyNames().arguments);
     1837        ASSERT(variableObject->hasProperty(exec, ident));
    18381838        variableObject->put(exec, ident, val, flags);
    18391839    }
     
    25792579    , m_sourceId(Parser::sid)
    25802580    , m_initializedDeclarationStacks(false)
     2581    , m_initializedSymbolTable(false)
    25812582{
    25822583  setLoc(-1, -1);
     
    26072608}
    26082609
    2609 void FunctionBodyNode::processDeclarationsFunctionCode(ExecState* exec)
     2610void FunctionBodyNode::initializesymbolTable()
    26102611{
    26112612    size_t i, size;
    2612 
    2613     JSObject* variableObject = exec->variableObject();
    2614 
     2613    size_t count = 0;
     2614
     2615    // The order of additions here implicitly enforces the mutual exclusion described in ECMA 10.1.3.
     2616    for (i = 0, size = m_varStack.size(); i < size; ++i)
     2617        m_symbolTable.set(m_varStack[i]->ident, count++);
     2618
     2619    for (i = 0, size = m_parameters.size(); i < size; ++i)
     2620        m_symbolTable.set(m_parameters[i], count++);
     2621
     2622    for (i = 0, size = m_functionStack.size(); i < size; ++i)
     2623        m_symbolTable.set(m_functionStack[i]->ident, count++);
     2624
     2625    m_initializedSymbolTable = true;
     2626}
     2627
     2628void FunctionBodyNode::processDeclarations(ExecState* exec)
     2629{
     2630    if (!m_initializedDeclarationStacks)
     2631        initializeDeclarationStacks(exec);
     2632
     2633    if (exec->codeType() == FunctionCode)
     2634        processDeclarationsForFunctionCode(exec);
     2635    else
     2636        processDeclarationsForProgramCode(exec);
     2637}
     2638
     2639void FunctionBodyNode::processDeclarationsForFunctionCode(ExecState* exec)
     2640{
     2641    if (!m_initializedSymbolTable)
     2642        initializesymbolTable();
     2643
     2644    ASSERT(exec->variableObject()->isActivation());
     2645    ActivationImp::LocalStorage& localStorage = static_cast<ActivationImp*>(exec->variableObject())->localStorage();
     2646    localStorage.reserveCapacity(m_varStack.size() + m_parameters.size() + m_functionStack.size());
     2647   
    26152648    int minAttributes = Internal | DontDelete;
    2616 
    2617     // The order of additions to the variable object here implicitly enforces the mutual exclusion described in ECMA 10.1.3.
     2649   
     2650    size_t i, size;
     2651
     2652    // NOTE: Must match the order of addition in initializesymbolTable().
     2653
    26182654    for (i = 0, size = m_varStack.size(); i < size; ++i) {
    26192655        VarDeclNode* node = m_varStack[i];
     
    26212657        if (node->varType == VarDeclNode::Constant)
    26222658            attributes |= ReadOnly;
    2623         variableObject->put(exec, node->ident, jsUndefined(), attributes);
     2659        localStorage.append(ActivationImp::LocalStorageEntry(jsUndefined(), attributes));
    26242660    }
    26252661
    26262662    const List& args = *exec->arguments();
    26272663    for (i = 0, size = m_parameters.size(); i < size; ++i)
    2628         variableObject->put(exec, m_parameters[i], args[i], DontDelete);
     2664        localStorage.append(ActivationImp::LocalStorageEntry(args[i], DontDelete));
    26292665
    26302666    for (i = 0, size = m_functionStack.size(); i < size; ++i) {
    26312667        FuncDeclNode* node = m_functionStack[i];
    2632         variableObject->put(exec, node->ident, node->makeFunction(exec), minAttributes);
     2668        localStorage.append(ActivationImp::LocalStorageEntry(node->makeFunction(exec), minAttributes));
    26332669    }
    26342670}
    26352671
    2636 void FunctionBodyNode::processDeclarationsProgramCode(ExecState* exec)
     2672void FunctionBodyNode::processDeclarationsForProgramCode(ExecState* exec)
    26372673{
    26382674    size_t i, size;
     
    26782714}
    26792715
    2680 void FunctionBodyNode::processDeclarations(ExecState* exec)
    2681 {
    2682     if (!m_initializedDeclarationStacks)
    2683         initializeDeclarationStacks(exec);
    2684 
    2685     if (exec->codeType() == FunctionCode)
    2686         processDeclarationsFunctionCode(exec);
    2687     else
    2688         processDeclarationsProgramCode(exec);
    2689 }
    2690 
    26912716Completion FunctionBodyNode::execute(ExecState* exec)
    26922717{
Note: See TracChangeset for help on using the changeset viewer.