Ignore:
Timestamp:
Mar 20, 2019, 2:04:10 PM (6 years ago)
Author:
[email protected]
Message:

JSC test crash: stress/dont-strength-reduce-regexp-with-compile-error.js.default
https://bugs.webkit.org/show_bug.cgi?id=195906

Reviewed by Mark Lam.

The problem here as that we may successfully parsed a RegExp without running out of stack,
but later run out of stack when trying to JIT compile the same expression.

Added a check for available stack space when we call into one of the parenthesis compilation
functions that recurse. When we don't have enough stack space to recurse, we fail the JIT
compilation and let the interpreter handle the expression.

From code inspection of the YARR interpreter it has the same issue, but I couldn't cause a failure.
Filed a new bug and added a FIXME comment for the Interpreter to have similar checks.
Given that we can reproduce a failure, this is sufficient for now.

This change is covered by the previously added failing test,
JSTests/stress/dont-strength-reduce-regexp-with-compile-error.js.

  • yarr/YarrInterpreter.cpp:

(JSC::Yarr::Interpreter::interpret):

  • yarr/YarrJIT.cpp:

(JSC::Yarr::YarrGenerator::opCompileParenthesesSubpattern):
(JSC::Yarr::YarrGenerator::opCompileParentheticalAssertion):
(JSC::Yarr::YarrGenerator::opCompileBody):
(JSC::Yarr::dumpCompileFailure):

  • yarr/YarrJIT.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp

    r242838 r243237  
    33873387        YarrOpCode alternativeEndOpCode = OpSimpleNestedAlternativeEnd;
    33883388
     3389        if (UNLIKELY(!m_vm->isSafeToRecurse())) {
     3390            m_failureReason = JITFailureReason::ParenthesisNestedTooDeep;
     3391            return;
     3392        }
     3393
    33893394        // We can currently only compile quantity 1 subpatterns that are
    33903395        // not copies. We generate a copy in the case of a range quantifier,
     
    34933498    void opCompileParentheticalAssertion(PatternTerm* term)
    34943499    {
     3500        if (UNLIKELY(!m_vm->isSafeToRecurse())) {
     3501            m_failureReason = JITFailureReason::ParenthesisNestedTooDeep;
     3502            return;
     3503        }
     3504
    34953505        size_t parenBegin = m_ops.size();
    34963506        m_ops.append(OpParentheticalAssertionBegin);
     
    35733583    void opCompileBody(PatternDisjunction* disjunction)
    35743584    {
     3585        if (UNLIKELY(!m_vm->isSafeToRecurse())) {
     3586            m_failureReason = JITFailureReason::ParenthesisNestedTooDeep;
     3587            return;
     3588        }
     3589       
    35753590        Vector<std::unique_ptr<PatternAlternative>>& alternatives = disjunction->m_alternatives;
    35763591        size_t currentAlternativeIndex = 0;
     
    42014216        dataLog("Can't JIT a pattern containing fixed count parenthesized subpatterns\n");
    42024217        break;
     4218    case JITFailureReason::ParenthesisNestedTooDeep:
     4219        dataLog("Can't JIT pattern due to parentheses nested too deeply\n");
     4220        break;
    42034221    case JITFailureReason::ExecutableMemoryAllocationFailure:
    42044222        dataLog("Can't JIT because of failure of allocation of executable memory\n");
Note: See TracChangeset for help on using the changeset viewer.