Ignore:
Timestamp:
Jan 1, 2008, 11:35:37 AM (17 years ago)
Author:
Darin Adler
Message:

Reviewed by Geoff.

Also included one other speed-up -- remove the call to reserveCapacity from
FunctionBodyNode::processDeclarations in all but the most unusual cases.

Together these make SunSpider 1.016x as fast.

  • JavaScriptCore.exp: Updated.
  • kjs/ExecState.cpp: (KJS::globalEmptyList): Added. Called only when creating global ExecState instances. (KJS::ExecState::ExecState): Broke constructor up into three separate functions, for the three separate node types. Also went through each of the three and streamlined as much as possible, removing dead code. This prevents us from having to access the global in the function body version of the constructor.
  • kjs/ExecState.h: Added emptyList(). Replaced the constructor with a set of three that are specific to the different node types that can create new execution state objects.
  • kjs/array_object.cpp: (KJS::ArrayProtoFuncToLocaleString::callAsFunction): Use exec->emptyList() instead of List::empty(). (KJS::ArrayProtoFuncConcat::callAsFunction): Ditto. (KJS::ArrayProtoFuncSlice::callAsFunction): Ditto. (KJS::ArrayProtoFuncSplice::callAsFunction): Ditto. (KJS::ArrayProtoFuncFilter::callAsFunction): Ditto.
  • kjs/function.cpp: (KJS::FunctionImp::callAsFunction): Updated to call new ExecState constructor. (KJS::GlobalFuncImp::callAsFunction): Ditto (for eval).
  • kjs/function_object.cpp: (FunctionObjectImp::construct): Use exec->emptyList() instead of List::empty().
  • kjs/list.cpp: Removed List::empty.
  • kjs/list.h: Ditto.
  • kjs/nodes.cpp: (KJS::ElementNode::evaluate): Use exec->emptyList() instead of List::empty(). (KJS::ArrayNode::evaluate): Ditto. (KJS::ObjectLiteralNode::evaluate): Ditto. (KJS::PropertyListNode::evaluate): Ditto. (KJS::FunctionBodyNode::processDeclarations): Another speed-up. Check the capacity before calling reserveCapacity, because it doesn't get inlined the local storage vector is almost always big enough -- saving the function call overhead is a big deal. (KJS::FuncDeclNode::makeFunction): Use exec->emptyList() instead of List::empty(). (KJS::FuncExprNode::evaluate): Ditto.
  • kjs/object.cpp: (KJS::tryGetAndCallProperty): Ditto.
  • kjs/property_slot.cpp: (KJS::PropertySlot::functionGetter): Ditto.
  • kjs/string_object.cpp: (KJS::StringProtoFuncSplit::callAsFunction): Ditto.
File:
1 edited

Legend:

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

    r28884 r29067  
    3232namespace KJS {
    3333
     34static inline List* globalEmptyList()
     35{
     36    static List staticEmptyList;
     37    return &staticEmptyList;
     38}
     39
    3440// ECMA 10.2
    35 ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisV,
    36                      ScopeNode* scopeNode, CodeType type, ExecState* callingExec, ExecState* currentExec,
    37                      FunctionImp* func, const List* args)
     41
     42ExecState::ExecState(JSGlobalObject* globalObject, JSObject* /*thisObject*/, ProgramNode* programNode)
    3843    : m_globalObject(globalObject)
    3944    , m_exception(0)
    4045    , m_propertyNames(CommonIdentifiers::shared())
    41     , m_callingExec(callingExec)
    42     , m_savedExec(currentExec)
    43     , m_scopeNode(scopeNode)
    44     , m_function(func)
    45     , m_arguments(args)
     46    , m_emptyList(globalEmptyList())
     47    , m_callingExec(0)
     48    , m_savedExec(0)
     49    , m_scopeNode(programNode)
     50    , m_function(0)
     51    , m_arguments(0)
     52    , m_activation(0)
     53    , m_localStorage(&globalObject->localStorage())
     54    , m_variableObject(globalObject)
     55    , m_thisVal(globalObject)
    4656    , m_iterationDepth(0)
    4757    , m_switchDepth(0)
    48     , m_codeType(type)
     58    , m_codeType(GlobalCode)
    4959{
    50     // create and initialize activation object (ECMA 10.1.6)
    51     if (type == FunctionCode) {
    52         m_activation = new ActivationImp(this);
    53         m_variableObject = m_activation;
    54     } else {
    55         m_activation = 0;
    56         m_variableObject = globalObject;
    57     }
    58    
    59     // ECMA 10.2
    60     switch(type) {
    61     case EvalCode:
    62         if (m_callingExec) {
    63             m_scopeChain = m_callingExec->scopeChain();
    64             m_variableObject = m_callingExec->variableObject();
    65             m_thisVal = m_callingExec->thisValue();
    66             break;
    67         } // else same as GlobalCode
    68     case GlobalCode:
    69         m_scopeChain.push(globalObject);
    70         m_thisVal = globalObject;
    71         break;
    72     case FunctionCode:
    73         m_scopeChain = func->scope();
    74         m_scopeChain.push(m_activation);
    75         m_variableObject = m_activation;
    76         m_thisVal = thisV;
    77         break;
    78     }
    79    
    80     m_localStorage = &m_variableObject->localStorage();
     60    // FIXME: This function ignores the "thisObject" parameter, which means that the API for evaluating
     61    // a script with a this object that's not the same as the global object is broken, and probably
     62    // has been for some time.
     63    m_scopeChain.push(globalObject);
     64    if (programNode)
     65        globalObject->setCurrentExec(this);
     66}
    8167
    82     if (scopeNode)
    83         m_globalObject->setCurrentExec(this);
     68ExecState::ExecState(JSGlobalObject* globalObject, EvalNode* evalNode, ExecState* callingExec)
     69    : m_globalObject(globalObject)
     70    , m_exception(0)
     71    , m_propertyNames(callingExec->m_propertyNames)
     72    , m_emptyList(callingExec->m_emptyList)
     73    , m_callingExec(callingExec)
     74    , m_savedExec(globalObject->currentExec())
     75    , m_scopeNode(evalNode)
     76    , m_function(0)
     77    , m_arguments(0)
     78    , m_activation(0)
     79    , m_localStorage(callingExec->m_localStorage)
     80    , m_scopeChain(callingExec->m_scopeChain)
     81    , m_variableObject(callingExec->m_variableObject)
     82    , m_thisVal(callingExec->m_thisVal)
     83    , m_iterationDepth(0)
     84    , m_switchDepth(0)
     85    , m_codeType(EvalCode)
     86{   
     87    globalObject->setCurrentExec(this);
     88}
     89
     90ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject,
     91                     FunctionBodyNode* functionBodyNode, ExecState* callingExec,
     92                     FunctionImp* func, const List& args)
     93    : m_globalObject(globalObject)
     94    , m_exception(0)
     95    , m_propertyNames(callingExec->m_propertyNames)
     96    , m_emptyList(callingExec->m_emptyList)
     97    , m_callingExec(callingExec)
     98    , m_savedExec(globalObject->currentExec())
     99    , m_scopeNode(functionBodyNode)
     100    , m_function(func)
     101    , m_arguments(&args)
     102    , m_scopeChain(func->scope())
     103    , m_thisVal(thisObject)
     104    , m_iterationDepth(0)
     105    , m_switchDepth(0)
     106    , m_codeType(FunctionCode)
     107{
     108    ActivationImp* activation = new ActivationImp(this);
     109    m_activation = activation;
     110    m_localStorage = &activation->localStorage();
     111    m_variableObject = activation;
     112    m_scopeChain.push(activation);
     113    globalObject->setCurrentExec(this);
    84114}
    85115
Note: See TracChangeset for help on using the changeset viewer.