Changeset 174359 in webkit


Ignore:
Timestamp:
Oct 6, 2014 12:29:27 PM (10 years ago)
Author:
oliver@apple.com
Message:

REGRESSION(r174226): [JSC] Crash when running the perf test Speedometer/Full.html
https://bugs.webkit.org/show_bug.cgi?id=137404

Reviewed by Michael Saboff.

Update the Arguments object to recognise that it must always have an
environment record if the referenced callee has one, and if such is not
present it should not try to extract one from the callframe, as that
path leads to madness.

Happily this makes some of the other code more sensible, and removes a
bunch of unnecessary and icky logic.

  • interpreter/Interpreter.cpp:

(JSC::unwindCallFrame):

  • jit/JITOperations.cpp:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • runtime/Arguments.cpp:

(JSC::Arguments::tearOff):
(JSC::Arguments::didTearOffActivation): Deleted.

  • runtime/Arguments.h:

(JSC::Arguments::argument):
(JSC::Arguments::finishCreation):

Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r174322 r174359  
     12014-10-06  Oliver Hunt  <oliver@apple.com>
     2
     3        REGRESSION(r174226): [JSC] Crash when running the perf test Speedometer/Full.html
     4        https://bugs.webkit.org/show_bug.cgi?id=137404
     5
     6        Reviewed by Michael Saboff.
     7
     8        Update the Arguments object to recognise that it must always have an
     9        environment record if the referenced callee has one, and if such is not
     10        present it should not try to extract one from the callframe, as that
     11        path leads to madness.
     12
     13        Happily this makes some of the other code more sensible, and removes a
     14        bunch of unnecessary and icky logic.
     15
     16        * interpreter/Interpreter.cpp:
     17        (JSC::unwindCallFrame):
     18        * jit/JITOperations.cpp:
     19        * llint/LLIntSlowPaths.cpp:
     20        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     21        * runtime/Arguments.cpp:
     22        (JSC::Arguments::tearOff):
     23        (JSC::Arguments::didTearOffActivation): Deleted.
     24        * runtime/Arguments.h:
     25        (JSC::Arguments::argument):
     26        (JSC::Arguments::finishCreation):
     27
    1282014-10-04  Brian J. Burg  <burg@cs.washington.edu>
    229
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r174226 r174359  
    449449    }
    450450
    451     JSValue lexicalEnvironment;
    452451    if (codeBlock->codeType() == FunctionCode && codeBlock->needsActivation()) {
    453452#if ENABLE(DFG_JIT)
     
    458457    if (codeBlock->codeType() == FunctionCode && codeBlock->usesArguments()) {
    459458        if (Arguments* arguments = visitor->existingArguments()) {
    460             if (lexicalEnvironment && lexicalEnvironment.isCell())
    461                 arguments->didTearOffActivation(callFrame, jsCast<JSLexicalEnvironment*>(lexicalEnvironment));
    462459#if ENABLE(DFG_JIT)
    463             else if (visitor->isInlinedFrame())
     460            if (visitor->isInlinedFrame())
    464461                arguments->tearOff(callFrame, visitor->inlineCallFrame());
    465462#endif
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r174226 r174359  
    15911591}
    15921592
    1593 void JIT_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell)
     1593void JIT_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell*)
    15941594{
    15951595    ASSERT(exec->codeBlock()->usesArguments());
    1596     if (activationCell) {
    1597         jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec, jsCast<JSLexicalEnvironment*>(activationCell));
    1598         return;
    1599     }
    16001596    jsCast<Arguments*>(argumentsCell)->tearOff(exec);
    16011597}
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r174294 r174359  
    12511251    ASSERT(exec->codeBlock()->usesArguments());
    12521252    Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(VirtualRegister(pc[1].u.operand).offset()).jsValue());
    1253     if (JSValue activationValue = LLINT_OP_C(2).jsValue())
    1254         arguments->didTearOffActivation(exec, jsCast<JSLexicalEnvironment*>(activationValue));
    1255     else
    1256         arguments->tearOff(exec);
     1253    arguments->tearOff(exec);
    12571254    LLINT_END();
    12581255}
  • trunk/Source/JavaScriptCore/runtime/Arguments.cpp

    r174226 r174359  
    373373void Arguments::tearOff(CallFrame* callFrame)
    374374{
     375    if (m_callee->jsExecutable()->needsActivation())
     376        RELEASE_ASSERT(m_lexicalEnvironment);
    375377    if (isTornOff())
    376378        return;
     
    392394}
    393395
    394 void Arguments::didTearOffActivation(ExecState* exec, JSLexicalEnvironment* lexicalEnvironment)
    395 {
    396     RELEASE_ASSERT(lexicalEnvironment);
    397     if (isTornOff())
    398         return;
    399 
    400     if (!m_numArguments)
    401         return;
    402    
    403     m_lexicalEnvironment.set(exec->vm(), this, lexicalEnvironment);
    404     tearOff(exec);
    405 }
    406 
    407396void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
    408397{
     398    RELEASE_ASSERT(!inlineCallFrame->baselineCodeBlock()->needsActivation());
    409399    if (isTornOff())
    410400        return;
  • trunk/Source/JavaScriptCore/runtime/Arguments.h

    r174226 r174359  
    8888    void tearOff(CallFrame*, InlineCallFrame*);
    8989    bool isTornOff() const { return m_registerArray.get(); }
    90     void didTearOffActivation(ExecState*, JSLexicalEnvironment*);
    9190
    9291    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     
    274273        return m_registers[index];
    275274
    276     JSLexicalEnvironment* lexicalEnvironment = m_lexicalEnvironment.get();
    277     if (!lexicalEnvironment)
    278         lexicalEnvironment = CallFrame::create(reinterpret_cast<Register*>(m_registers))->lexicalEnvironment();
    279     return lexicalEnvironment->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset());
     275    RELEASE_ASSERT(m_lexicalEnvironment);
     276    return m_lexicalEnvironment->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset());
    280277}
    281278
     
    308305                codeBlock->framePointerOffsetToGetActivationRegisters());
    309306        }
    310 
     307        if (codeBlock->needsActivation()) {
     308            RELEASE_ASSERT(callFrame->lexicalEnvironment());
     309            m_lexicalEnvironment.set(callFrame->vm(), this, callFrame->lexicalEnvironment());
     310        }
    311311        // The bytecode generator omits op_tear_off_lexical_environment in cases of no
    312312        // declared parameters, so we need to tear off immediately.
    313313        if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
    314314            tearOff(callFrame);
     315        break;
     316    }
     317       
     318    case FakeArgumentValuesCreationMode: {
     319        m_numArguments = 0;
     320        m_registers = nullptr;
     321        tearOff(callFrame);
     322        break;
     323    }
     324    }
     325}
     326
     327inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode)
     328{
     329    Base::finishCreation(callFrame->vm());
     330    ASSERT(inherits(info()));
     331
     332    JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
     333    m_callee.set(callFrame->vm(), this, callee);
     334    m_overrodeLength = false;
     335    m_overrodeCallee = false;
     336    m_overrodeCaller = false;
     337    m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
     338
     339    switch (mode) {
     340    case NormalArgumentsCreationMode: {
     341        m_numArguments = inlineCallFrame->arguments.size() - 1;
     342       
     343        if (m_numArguments) {
     344            int offsetForArgumentOne = inlineCallFrame->arguments[1].virtualRegister().offset();
     345            m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + offsetForArgumentOne - virtualRegisterForArgument(1).offset();
     346        } else
     347            m_registers = 0;
     348       
     349        ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->specializationKind())->slowArguments());
     350       
     351        // The bytecode generator omits op_tear_off_lexical_environment in cases of no
     352        // declared parameters, so we need to tear off immediately.
     353        if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
     354            tearOff(callFrame, inlineCallFrame);
    315355        break;
    316356    }
     
    322362        break;
    323363    } }
    324        
    325 }
    326 
    327 inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode)
    328 {
    329     Base::finishCreation(callFrame->vm());
    330     ASSERT(inherits(info()));
    331 
    332     JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
    333     m_callee.set(callFrame->vm(), this, callee);
    334     m_overrodeLength = false;
    335     m_overrodeCallee = false;
    336     m_overrodeCaller = false;
    337     m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
    338 
    339     switch (mode) {
    340     case NormalArgumentsCreationMode: {
    341         m_numArguments = inlineCallFrame->arguments.size() - 1;
    342        
    343         if (m_numArguments) {
    344             int offsetForArgumentOne = inlineCallFrame->arguments[1].virtualRegister().offset();
    345             m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + offsetForArgumentOne - virtualRegisterForArgument(1).offset();
    346         } else
    347             m_registers = 0;
    348        
    349         ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->specializationKind())->slowArguments());
    350        
    351         // The bytecode generator omits op_tear_off_lexical_environment in cases of no
    352         // declared parameters, so we need to tear off immediately.
    353         if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
    354             tearOff(callFrame, inlineCallFrame);
    355         break;
    356     }
    357        
    358     case FakeArgumentValuesCreationMode: {
    359         m_numArguments = 0;
    360         m_registers = nullptr;
    361         tearOff(callFrame);
    362         break;
    363     } }
    364364}
    365365
Note: See TracChangeset for help on using the changeset viewer.