Ignore:
Timestamp:
Jan 21, 2008, 10:18:10 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

Reviewed by Maciej Stachowiak.


Fixed http://bugs.webkit.org/show_bug.cgi?id=16909
REGRESSION: Amazon.com crash (ActivationImp)


(and a bunch of other crashes)


Plus, a .7% SunSpider speedup to boot.


Replaced the buggy currentExec and savedExec mechanisms with an
explicit ExecState stack.

  • kjs/collector.cpp: (KJS::Collector::collect): Explicitly mark the ExecState stack.

(KJS::Collector::reportOutOfMemoryToAllExecStates): Slight change in
behavior: We no longer throw an exception in any global ExecStates,
since global ExecStates are more like pseudo-ExecStates, and aren't
used for script execution. (It's unclear what would happen if you left
an exception waiting around in a global ExecState, but it probably
wouldn't be good.)

WebCore:

Reviewed by Maciej Stachowiak.

Adapted WebCore to the fix for http://bugs.webkit.org/show_bug.cgi?id=16909
REGRESSION: Amazon.com crash (ActivationImp)

  • bindings/js/kjs_proxy.cpp: (WebCore::KJSProxy::~KJSProxy): No convenient way to make this assertion anymore. (It wasn't firing for anyone, anyway, so it's no big loss.)
  • bindings/objc/WebScriptObject.mm: (+[WebScriptObject throwException:]): Use the ExecState stack, instead of currentExec. (-[WebScriptObject setException:]): ditto. Also, a slight change in behavior: If no ExecStates are active, we no longer throw an exception in the global ExecState. The JavaScriptCore ChangeLog explains why. This also matches the behavior of +throwException.

LayoutTests:

Layout test for http://bugs.webkit.org/show_bug.cgi?id=16909
REGRESSION: Amazon.com crash (ActivationImp)

  • fast/js/exec-state-marking-expected.txt: Added.
  • fast/js/exec-state-marking.html: Added.
File:
1 edited

Legend:

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

    r29542 r29710  
    4242// ECMA 10.2
    4343
     44// The constructor for the globalExec pseudo-ExecState
     45ExecState::ExecState(JSGlobalObject* globalObject)
     46    : m_globalObject(globalObject)
     47    , m_exception(0)
     48    , m_propertyNames(CommonIdentifiers::shared())
     49    , m_emptyList(globalEmptyList())
     50    , m_callingExec(0)
     51    , m_scopeNode(0)
     52    , m_function(0)
     53    , m_arguments(0)
     54    , m_activation(0)
     55    , m_localStorage(&globalObject->localStorage())
     56    , m_variableObject(globalObject)
     57    , m_thisVal(globalObject)
     58    , m_iterationDepth(0)
     59    , m_switchDepth(0)
     60    , m_codeType(GlobalCode)
     61{
     62    m_scopeChain.push(globalObject);
     63}
     64
    4465ExecState::ExecState(JSGlobalObject* globalObject, JSObject* /*thisObject*/, ProgramNode* programNode)
    4566    : m_globalObject(globalObject)
     
    4869    , m_emptyList(globalEmptyList())
    4970    , m_callingExec(0)
    50     , m_savedExec(0)
    5171    , m_scopeNode(programNode)
    5272    , m_function(0)
     
    6383    // a script with a this object that's not the same as the global object is broken, and probably
    6484    // has been for some time.
     85    ASSERT(m_scopeNode);
     86    activeExecStates().append(this);
    6587    m_scopeChain.push(globalObject);
    66     if (programNode)
    67         globalObject->setCurrentExec(this);
    6888}
    6989
     
    7494    , m_emptyList(callingExec->m_emptyList)
    7595    , m_callingExec(callingExec)
    76     , m_savedExec(globalObject->currentExec())
    7796    , m_scopeNode(evalNode)
    7897    , m_function(0)
     
    87106    , m_codeType(EvalCode)
    88107{   
    89     globalObject->setCurrentExec(this);
     108    ASSERT(m_scopeNode);
     109    activeExecStates().append(this);
    90110}
    91111
     
    98118    , m_emptyList(callingExec->m_emptyList)
    99119    , m_callingExec(callingExec)
    100     , m_savedExec(globalObject->currentExec())
    101120    , m_scopeNode(functionBodyNode)
    102121    , m_function(func)
     
    108127    , m_codeType(FunctionCode)
    109128{
     129    ASSERT(m_scopeNode);
     130    activeExecStates().append(this);
     131
    110132    ActivationImp* activation = globalObject->pushActivation(this);
    111133    m_activation = activation;
     
    113135    m_variableObject = activation;
    114136    m_scopeChain.push(activation);
    115     globalObject->setCurrentExec(this);
    116137}
    117138
    118139ExecState::~ExecState()
    119140{
    120     if (m_codeType == FunctionCode && m_activation->needsPop())
     141    ASSERT(m_scopeNode && activeExecStates().last() == this || !m_scopeNode);
     142    if (m_scopeNode)
     143        activeExecStates().removeLast();
     144
     145    if (m_activation && m_activation->needsPop())
    121146        m_globalObject->popActivation();
    122    
    123     m_globalObject->setCurrentExec(m_savedExec);
    124 }
    125 
    126 void ExecState::mark()
    127 {
    128     for (ExecState* exec = this; exec; exec = exec->m_callingExec) {
    129         exec->m_scopeChain.mark();
    130 
    131         if (exec->m_savedExec != exec->m_callingExec && exec->m_savedExec)
    132             exec->m_savedExec->mark();
    133     }
    134147}
    135148
     
    146159}
    147160
     161void ExecState::markActiveExecStates()
     162{
     163    ExecStateStack::const_iterator end = activeExecStates().end();
     164    for (ExecStateStack::const_iterator it = activeExecStates().begin(); it != end; ++it)
     165        (*it)->m_scopeChain.mark();
     166}
     167
     168ExecStateStack& ExecState::activeExecStates()
     169{
     170    static ExecStateStack staticActiveExecStates;
     171    return staticActiveExecStates;
     172}
     173
    148174} // namespace KJS
Note: See TracChangeset for help on using the changeset viewer.