Changeset 27028 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Oct 25, 2007, 1:11:31 AM (18 years ago)
Author:
ggaren
Message:

Reviewed by Maciej Stachowiak.


Make a fast path for declaration processing inside Function Code.


Lifted declaration processing code up from individual declaration nodes
and into processDeclarations.


Broke out processDeclarations into two cases, depending on the type of
code. This eliminates 2 branches, and facilitates more radical
divergeance in the future.


2.5% SunSpider speedup.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • kjs/nodes.cpp: (KJS::FunctionBodyNode::initializeDeclarationStacks): (KJS::FunctionBodyNode::processDeclarationsFunctionCode): (KJS::FunctionBodyNode::processDeclarationsProgramCode): (KJS::FunctionBodyNode::execute): (KJS::FuncDeclNode::makeFunction):
  • kjs/nodes.h: (KJS::):
Location:
trunk/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r27027 r27028  
     12007-10-25  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Maciej Stachowiak.
     4       
     5        Make a fast path for declaration processing inside Function Code.
     6       
     7        Lifted declaration processing code up from individual declaration nodes
     8        and into processDeclarations.
     9       
     10        Broke out processDeclarations into two cases, depending on the type of
     11        code. This eliminates 2 branches, and facilitates more radical
     12        divergeance in the future.
     13       
     14        2.5% SunSpider speedup.
     15
     16        * JavaScriptCore.xcodeproj/project.pbxproj:
     17        * kjs/nodes.cpp:
     18        (KJS::FunctionBodyNode::initializeDeclarationStacks):
     19        (KJS::FunctionBodyNode::processDeclarationsFunctionCode):
     20        (KJS::FunctionBodyNode::processDeclarationsProgramCode):
     21        (KJS::FunctionBodyNode::execute):
     22        (KJS::FuncDeclNode::makeFunction):
     23        * kjs/nodes.h:
     24        (KJS::):
     25
    1262007-10-25  Maciej Stachowiak  <[email protected]>
    227
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r27026 r27028  
    13801380                        isa = PBXProject;
    13811381                        buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */;
     1382                        compatibilityVersion = "Xcode 2.4";
    13821383                        hasScannedForEncodings = 1;
    13831384                        mainGroup = 0867D691FE84028FC02AAC07 /* JavaScriptCore */;
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r27027 r27028  
    18501850}
    18511851
    1852 void VarDeclNode::processDeclaration(ExecState* exec)
    1853 {
    1854   Context* context = exec->context();
    1855   JSObject* variable = context->variableObject();
    1856 
    1857   if (context->codeType() != FunctionCode)
    1858     if (variable->hasProperty(exec, ident))
    1859         return;
    1860 
    1861   int flags = Internal;
    1862   if (context->codeType() != EvalCode)
    1863     flags |= DontDelete;
    1864   if (varType == VarDeclNode::Constant)
    1865     flags |= ReadOnly;
    1866   variable->put(exec, ident, jsUndefined(), flags);
    1867 }
    1868 
    18691852// ------------------------------ VarDeclListNode ------------------------------
    18701853
     
    26282611}
    26292612
    2630 void FunctionBodyNode::processDeclarations(ExecState* exec)
    2631 {
    2632     if (!m_initializedDeclarationStacks)
    2633         initializeDeclarationStacks(exec);
    2634 
     2613void FunctionBodyNode::processDeclarationsFunctionCode(ExecState* exec)
     2614{
    26352615    size_t i, size;
    26362616
    2637     JSObject* variableObject = exec->context()->variableObject();
    2638     const List& args = *exec->context()->arguments();
     2617    Context* context = exec->context();
     2618    JSObject* variableObject = context->variableObject();
    26392619
    26402620    // The order of additions to the variable object here implicitly enforces the mutual exclusion described in ECMA 10.1.3.
    2641     for (i = 0, size = m_varStack.size(); i < size; ++i)
    2642         m_varStack[i]->processDeclaration(exec);
    2643 
     2621    for (i = 0, size = m_varStack.size(); i < size; ++i) {
     2622        VarDeclNode* node = m_varStack[i];
     2623        int flags = Internal | DontDelete;
     2624        if (node->varType == VarDeclNode::Constant)
     2625            flags |= ReadOnly;
     2626        variableObject->put(exec, node->ident, jsUndefined(), flags);
     2627    }
     2628
     2629    const List& args = *context->arguments();
    26442630    for (i = 0, size = m_parameters.size(); i < size; ++i)
    26452631        variableObject->put(exec, m_parameters[i], args[i], DontDelete);
    26462632
    2647     for (i = 0, size = m_functionStack.size(); i < size; ++i)
    2648         m_functionStack[i]->processDeclaration(exec);
     2633    for (i = 0, size = m_functionStack.size(); i < size; ++i) {
     2634        FuncDeclNode* node = m_functionStack[i];
     2635        variableObject->put(exec, node->ident, node->makeFunction(exec), Internal | DontDelete);
     2636    }
     2637}
     2638
     2639void FunctionBodyNode::processDeclarationsProgramCode(ExecState* exec)
     2640{
     2641    size_t i, size;
     2642
     2643    Context* context = exec->context();
     2644    JSObject* variableObject = context->variableObject();
     2645
     2646    // The order of additions to the variable object here implicitly enforces the mutual exclusion described in ECMA 10.1.3.
     2647    for (i = 0, size = m_varStack.size(); i < size; ++i) {
     2648        VarDeclNode* node = m_varStack[i];
     2649        if (!variableObject->hasProperty(exec, node->ident)) {
     2650            int flags = Internal;
     2651            if (context->codeType() != EvalCode)
     2652                flags |= DontDelete;
     2653            if (node->varType == VarDeclNode::Constant)
     2654                flags |= ReadOnly;
     2655            variableObject->put(exec, node->ident, jsUndefined(), flags);
     2656        }
     2657    }
     2658   
     2659    const List& args = *context->arguments();
     2660    for (i = 0, size = m_parameters.size(); i < size; ++i)
     2661        variableObject->put(exec, m_parameters[i], args[i], DontDelete);
     2662
     2663    for (i = 0, size = m_functionStack.size(); i < size; ++i) {
     2664        FuncDeclNode* node = m_functionStack[i];
     2665        variableObject->put(exec, node->ident, node->makeFunction(exec), Internal | (context->codeType() == EvalCode ? 0 : DontDelete));
     2666    }
    26492667}
    26502668
     
    26672685}
    26682686
     2687void FunctionBodyNode::processDeclarations(ExecState* exec)
     2688{
     2689    if (!m_initializedDeclarationStacks)
     2690        initializeDeclarationStacks(exec);
     2691
     2692    if (exec->context()->codeType() == FunctionCode)
     2693        processDeclarationsFunctionCode(exec);
     2694    else
     2695        processDeclarationsProgramCode(exec);
     2696}
     2697
    26692698Completion FunctionBodyNode::execute(ExecState* exec)
    26702699{
     
    26862715}
    26872716
    2688 void FuncDeclNode::processDeclaration(ExecState* exec)
    2689 {
    2690   Context *context = exec->context();
    2691 
    2692   // TODO: let this be an object with [[Class]] property "Function"
    2693   FunctionImp *func = new FunctionImp(exec, ident, body.get(), context->scopeChain());
     2717FunctionImp* FuncDeclNode::makeFunction(ExecState* exec)
     2718{
     2719  FunctionImp *func = new FunctionImp(exec, ident, body.get(), exec->context()->scopeChain());
    26942720
    26952721  JSObject *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
     
    26982724
    26992725  func->put(exec, exec->propertyNames().length, jsNumber(body->numParams()), ReadOnly|DontDelete|DontEnum);
    2700 
    2701   // ECMA 10.2.2
    2702   context->variableObject()->put(exec, ident, func, Internal | (context->codeType() == EvalCode ? 0 : DontDelete));
     2726  return func;
    27032727}
    27042728
  • trunk/JavaScriptCore/kjs/nodes.h

    r27025 r27028  
    10051005    JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    10061006    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1007     ALWAYS_INLINE void processDeclaration(ExecState*) KJS_FAST_CALL;
    10081007    virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
    1009   private:
    1010     JSValue* handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL KJS_NO_INLINE;
    10111008    Type varType;
    10121009    Identifier ident;
     1010  private:
     1011    JSValue* handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL KJS_NO_INLINE;
    10131012    RefPtr<AssignExprNode> init;
    10141013  };
     
    12421241    UString paramString() const KJS_FAST_CALL;
    12431242    Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
    1244     ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
     1243    ALWAYS_INLINE void processDeclarations(ExecState*);
     1244    ALWAYS_INLINE void processDeclarationsFunctionCode(ExecState*);
     1245    ALWAYS_INLINE void processDeclarationsProgramCode(ExecState*);
    12451246  private:
    12461247    UString m_sourceURL;
     
    12501251    bool m_initializedDeclarationStacks;
    12511252
     1253    // Properties that will go into the ActivationImp's symbol table. (Used for initializing the ActivationImp.)
    12521254    DeclarationStacks::VarStack m_varStack;
    12531255    DeclarationStacks::FunctionStack m_functionStack;
     
    12791281    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    12801282    virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
    1281     ALWAYS_INLINE void processDeclaration(ExecState*) KJS_FAST_CALL;
     1283    ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
     1284    Identifier ident;
    12821285  private:
    12831286    void addParams() KJS_FAST_CALL;
    1284     Identifier ident;
    12851287    RefPtr<ParameterNode> param;
    12861288    RefPtr<FunctionBodyNode> body;
Note: See TracChangeset for help on using the changeset viewer.