Title: [228518] branches/safari-605-branch/Source

Diff

Modified: branches/safari-605-branch/Source/_javascript_Core/ChangeLog (228517 => 228518)


--- branches/safari-605-branch/Source/_javascript_Core/ChangeLog	2018-02-15 17:30:18 UTC (rev 228517)
+++ branches/safari-605-branch/Source/_javascript_Core/ChangeLog	2018-02-15 17:30:21 UTC (rev 228518)
@@ -1,5 +1,40 @@
 2018-02-15  Jason Marcell  <[email protected]>
 
+        Cherry-pick r228481. rdar://problem/37570863
+
+    2018-02-14  Michael Saboff  <[email protected]>
+
+            REGRESSION(225695) : com.apple.WebKit.WebContent at com.apple._javascript_Core: JSC::RegExp::match + 630 :: stack overflow
+            https://bugs.webkit.org/show_bug.cgi?id=182705
+
+            Reviewed by Mark Lam.
+
+            Moved the pattern context buffer used by YARR JIT'ed code from a stack local to a lazily allocated
+            buffer on the VM.  Exposed when the buffer is needed to reduce likelihood that we'd allocated it.
+            Guarded use of the buffer with a lock since the DFG compiler may call into YARR JIT'ed code on a
+            compilation thread.
+
+            * runtime/RegExpInlines.h:
+            (JSC::RegExp::matchInline):
+            * runtime/VM.cpp:
+            (JSC::VM::~VM):
+            (JSC::VM::acquireRegExpPatternContexBuffer):
+            (JSC::VM::releaseRegExpPatternContexBuffer):
+            * runtime/VM.h:
+            * yarr/YarrJIT.cpp:
+            (JSC::Yarr::YarrGenerator::generate):
+            (JSC::Yarr::YarrGenerator::backtrack):
+            (JSC::Yarr::YarrGenerator::opCompileParenthesesSubpattern):
+            (JSC::Yarr::YarrGenerator::generateEnter):
+            (JSC::Yarr::YarrGenerator::generateReturn):
+            (JSC::Yarr::YarrGenerator::YarrGenerator):
+            (JSC::Yarr::YarrGenerator::compile):
+            * yarr/YarrJIT.h:
+            (JSC::Yarr::YarrCodeBlock::usesPatternContextBuffer):
+            (JSC::Yarr::YarrCodeBlock::setUsesPaternContextBuffer):
+
+2018-02-15  Jason Marcell  <[email protected]>
+
         Cherry-pick r228488. rdar://problem/37570860
 
     2018-02-14  Saam Barati  <[email protected]>

Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/RegExpInlines.h (228517 => 228518)


--- branches/safari-605-branch/Source/_javascript_Core/runtime/RegExpInlines.h	2018-02-15 17:30:18 UTC (rev 228517)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/RegExpInlines.h	2018-02-15 17:30:21 UTC (rev 228518)
@@ -85,6 +85,39 @@
     return false;
 }
 
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+class PatternContextBufferHolder {
+public:
+    PatternContextBufferHolder(VM& vm, bool needBuffer)
+        : m_vm(vm)
+        , m_needBuffer(needBuffer)
+    {
+        if (m_needBuffer) {
+            m_buffer = m_vm.acquireRegExpPatternContexBuffer();
+            m_size = VM::patternContextBufferSize;
+        } else {
+            m_buffer = nullptr;
+            m_size = 0;
+        }
+    }
+
+    ~PatternContextBufferHolder()
+    {
+        if (m_needBuffer)
+            m_vm.releaseRegExpPatternContexBuffer();
+    }
+
+    void* buffer() { return m_buffer; }
+    unsigned size() { return m_size; }
+
+private:
+    VM& m_vm;
+    bool m_needBuffer;
+    void* m_buffer;
+    unsigned m_size;
+};
+#endif
+
 ALWAYS_INLINE void RegExp::compileIfNecessary(VM& vm, Yarr::YarrCharSize charSize)
 {
     if (hasCodeFor(charSize))
@@ -110,19 +143,24 @@
 
     int result;
 #if ENABLE(YARR_JIT)
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
-    char patternContextBuffer[patternContextBufferSize];
-#define EXTRA_JIT_PARAMS  , patternContextBuffer, patternContextBufferSize
+    if (m_state == JITCode) {
+        {
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+            PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode.usesPatternContextBuffer());
+
+#define EXTRA_JIT_PARAMS  , patternContextBufferHolder.buffer(), patternContextBufferHolder.size()
 #else
 #define EXTRA_JIT_PARAMS
 #endif
 
-    if (m_state == JITCode) {
-        if (s.is8Bit())
-            result = m_regExpJITCode.execute(s.characters8(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start;
-        else
-            result = m_regExpJITCode.execute(s.characters16(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start;
+            if (s.is8Bit())
+                result = m_regExpJITCode.execute(s.characters8(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start;
+            else
+                result = m_regExpJITCode.execute(s.characters16(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start;
 
+#undef EXTRA_JIT_PARAMS
+        }
+
         if (result == Yarr::JSRegExpJITCodeFailure) {
             // JIT'ed code couldn't handle _expression_, so punt back to the interpreter.
             byteCodeCompileIfNecessary(&vm);
@@ -213,20 +251,25 @@
     compileIfNecessaryMatchOnly(vm, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
 
 #if ENABLE(YARR_JIT)
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
-    char patternContextBuffer[patternContextBufferSize];
-#define EXTRA_JIT_PARAMS  , patternContextBuffer, patternContextBufferSize
+    MatchResult result;
+
+    if (m_state == JITCode) {
+        {
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+            PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode.usesPatternContextBuffer());
+
+#define EXTRA_JIT_PARAMS  , patternContextBufferHolder.buffer(), patternContextBufferHolder.size()
 #else
 #define EXTRA_JIT_PARAMS
 #endif
 
-    MatchResult result;
+            if (s.is8Bit())
+                result = m_regExpJITCode.execute(s.characters8(), startOffset, s.length() EXTRA_JIT_PARAMS);
+            else
+                result = m_regExpJITCode.execute(s.characters16(), startOffset, s.length() EXTRA_JIT_PARAMS);
 
-    if (m_state == JITCode) {
-        if (s.is8Bit())
-            result = m_regExpJITCode.execute(s.characters8(), startOffset, s.length() EXTRA_JIT_PARAMS);
-        else
-            result = m_regExpJITCode.execute(s.characters16(), startOffset, s.length() EXTRA_JIT_PARAMS);
+#undef EXTRA_JIT_PARAMS
+        }
 
 #if ENABLE(REGEXP_TRACING)
         if (!result)

Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/VM.cpp (228517 => 228518)


--- branches/safari-605-branch/Source/_javascript_Core/runtime/VM.cpp	2018-02-15 17:30:18 UTC (rev 228517)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/VM.cpp	2018-02-15 17:30:21 UTC (rev 228518)
@@ -532,6 +532,12 @@
 
     delete clientData;
     delete m_regExpCache;
+
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+    if (m_regExpPatternContexBuffer)
+        delete[] m_regExpPatternContexBuffer;
+#endif
+
 #if ENABLE(REGEXP_TRACING)
     delete m_rtTraceList;
 #endif
@@ -896,6 +902,25 @@
     }
 }
 
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+char* VM::acquireRegExpPatternContexBuffer()
+{
+    ASSERT(!m_regExpPatternContextLock.isLocked());
+
+    m_regExpPatternContextLock.lock();
+    if (!m_regExpPatternContexBuffer)
+        m_regExpPatternContexBuffer = new char[VM::patternContextBufferSize];
+    return m_regExpPatternContexBuffer;
+}
+
+void VM::releaseRegExpPatternContexBuffer()
+{
+    ASSERT(m_regExpPatternContextLock.isLocked());
+
+    m_regExpPatternContextLock.unlock();
+}
+#endif
+
 #if ENABLE(REGEXP_TRACING)
 void VM::addRegExpToTrace(RegExp* regExp)
 {

Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/VM.h (228517 => 228518)


--- branches/safari-605-branch/Source/_javascript_Core/runtime/VM.h	2018-02-15 17:30:18 UTC (rev 228517)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/VM.h	2018-02-15 17:30:21 UTC (rev 228518)
@@ -685,6 +685,15 @@
     BumpPointerAllocator m_regExpAllocator;
     ConcurrentJSLock m_regExpAllocatorLock;
 
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+    static constexpr size_t patternContextBufferSize = 8192; // Space allocated to save nested parenthesis context
+    char* m_regExpPatternContexBuffer { nullptr };
+    Lock m_regExpPatternContextLock;
+    char* acquireRegExpPatternContexBuffer();
+    void releaseRegExpPatternContexBuffer();
+#endif
+
+
     std::unique_ptr<HasOwnPropertyCache> m_hasOwnPropertyCache;
     ALWAYS_INLINE HasOwnPropertyCache* hasOwnPropertyCache() { return m_hasOwnPropertyCache.get(); }
     HasOwnPropertyCache* ensureHasOwnPropertyCache();

Modified: branches/safari-605-branch/Source/_javascript_Core/yarr/YarrJIT.cpp (228517 => 228518)


--- branches/safari-605-branch/Source/_javascript_Core/yarr/YarrJIT.cpp	2018-02-15 17:30:18 UTC (rev 228517)
+++ branches/safari-605-branch/Source/_javascript_Core/yarr/YarrJIT.cpp	2018-02-15 17:30:21 UTC (rev 228518)
@@ -156,7 +156,7 @@
 #define JIT_UNICODE_EXPRESSIONS
 #endif
 
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
     struct ParenContextSizes {
         size_t m_numSubpatterns;
         size_t m_frameSlots;
@@ -2173,7 +2173,7 @@
             //
             // These nodes support generic subpatterns.
             case OpParenthesesSubpatternBegin: {
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
                 PatternTerm* term = op.m_term;
                 unsigned parenthesesFrameLocation = term->frameLocation;
 
@@ -2230,13 +2230,13 @@
                     } else
                         setSubpatternStart(index, term->parentheses.subpatternId);
                 }
-#else // !JIT_ALL_PARENS_EXPRESSIONS
+#else // !YARR_JIT_ALL_PARENS_EXPRESSIONS
                 RELEASE_ASSERT_NOT_REACHED();
 #endif
                 break;
             }
             case OpParenthesesSubpatternEnd: {
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
                 PatternTerm* term = op.m_term;
                 unsigned parenthesesFrameLocation = term->frameLocation;
 
@@ -2288,7 +2288,7 @@
                     YarrOp& beginOp = m_ops[op.m_previousOp];
                     beginOp.m_jumps.link(this);
                 }
-#else // !JIT_ALL_PARENS_EXPRESSIONS
+#else // !YARR_JIT_ALL_PARENS_EXPRESSIONS
                 RELEASE_ASSERT_NOT_REACHED();
 #endif
                 break;
@@ -2837,7 +2837,7 @@
             // out of the start of the parentheses, or jump back to the forwards
             // matching start, depending of whether the match is Greedy or NonGreedy.
             case OpParenthesesSubpatternBegin: {
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
                 PatternTerm* term = op.m_term;
                 unsigned parenthesesFrameLocation = term->frameLocation;
 
@@ -2880,13 +2880,13 @@
 
                     m_backtrackingState.fallthrough();
                 }
-#else // !JIT_ALL_PARENS_EXPRESSIONS
+#else // !YARR_JIT_ALL_PARENS_EXPRESSIONS
                 RELEASE_ASSERT_NOT_REACHED();
 #endif
                 break;
             }
             case OpParenthesesSubpatternEnd: {
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
                 PatternTerm* term = op.m_term;
 
                 if (term->quantityType != QuantifierFixedCount) {
@@ -2917,7 +2917,7 @@
                 }
 
                 m_backtrackingState.append(op.m_jumps);
-#else // !JIT_ALL_PARENS_EXPRESSIONS
+#else // !YARR_JIT_ALL_PARENS_EXPRESSIONS
                 RELEASE_ASSERT_NOT_REACHED();
 #endif
                 break;
@@ -3024,7 +3024,7 @@
             parenthesesBeginOpCode = OpParenthesesSubpatternTerminalBegin;
             parenthesesEndOpCode = OpParenthesesSubpatternTerminalEnd;
         } else {
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
             // We only handle generic parenthesis with greedy counts.
             if (term->quantityType != QuantifierGreedy) {
                 // This subpattern is not supported by the JIT.
@@ -3275,7 +3275,7 @@
         if (m_pattern.m_saveInitialStartValue)
             push(X86Registers::ebx);
 
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
         if (m_containsNestedSubpatterns) {
 #if OS(WINDOWS)
             push(X86Registers::edi);
@@ -3361,7 +3361,7 @@
             pop(X86Registers::r13);
         }
 
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
         if (m_containsNestedSubpatterns) {
             pop(X86Registers::r12);
 #if OS(WINDOWS)
@@ -3401,7 +3401,7 @@
         , m_decodeSurrogatePairs(m_charSize == Char16 && m_pattern.unicode())
         , m_unicodeIgnoreCase(m_pattern.unicode() && m_pattern.ignoreCase())
         , m_canonicalMode(m_pattern.unicode() ? CanonicalMode::Unicode : CanonicalMode::UCS2)
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
         , m_containsNestedSubpatterns(false)
         , m_parenContextSizes(compileMode == IncludeSubpatterns ? m_pattern.m_numSubpatterns : 0, m_pattern.m_body->m_callFrameSize)
 #endif
@@ -3417,6 +3417,11 @@
         }
 #endif
 
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+        if (m_containsNestedSubpatterns)
+            jitObject.setUsesPaternContextBuffer();
+#endif
+
         // We need to compile before generating code since we set flags based on compilation that
         // are used during generation.
         opCompileBody(m_pattern.m_body);
@@ -3432,7 +3437,7 @@
         generateFailReturn();
         hasInput.link(this);
 
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
         if (m_containsNestedSubpatterns)
             move(TrustedImm32(matchLimit), remainingMatchCount);
 #endif
@@ -3447,7 +3452,7 @@
 
         initCallFrame();
 
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
         if (m_containsNestedSubpatterns)
             initParenContextFreeList();
 #endif
@@ -3510,7 +3515,7 @@
     bool m_decodeSurrogatePairs;
     bool m_unicodeIgnoreCase;
     CanonicalMode m_canonicalMode;
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
     bool m_containsNestedSubpatterns;
     ParenContextSizes m_parenContextSizes;
 #endif

Modified: branches/safari-605-branch/Source/_javascript_Core/yarr/YarrJIT.h (228517 => 228518)


--- branches/safari-605-branch/Source/_javascript_Core/yarr/YarrJIT.h	2018-02-15 17:30:18 UTC (rev 228517)
+++ branches/safari-605-branch/Source/_javascript_Core/yarr/YarrJIT.h	2018-02-15 17:30:21 UTC (rev 228518)
@@ -38,8 +38,7 @@
 #define YARR_CALL
 #endif
 
-#if CPU(ARM64) || (CPU(X86_64) && !OS(WINDOWS))
-#define JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
 constexpr size_t patternContextBufferSize = 8192; // Space caller allocates to save nested parenthesis context
 #endif
 
@@ -52,7 +51,7 @@
 
 class YarrCodeBlock {
 #if CPU(X86_64) || CPU(ARM64)
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
     typedef MatchResult (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
     typedef MatchResult (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
     typedef MatchResult (*YarrJITCodeMatchOnly8)(const LChar* input, unsigned start, unsigned length, void*, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
@@ -93,7 +92,10 @@
     void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; }
     void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; }
 
-#ifdef JIT_ALL_PARENS_EXPRESSIONS
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+    bool usesPatternContextBuffer() { return m_usesPatternContextBuffer; }
+    void setUsesPaternContextBuffer() { m_usesPatternContextBuffer = true; }
+
     MatchResult execute(const LChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize)
     {
         ASSERT(has8BitCode());
@@ -197,6 +199,9 @@
     MacroAssemblerCodeRef m_matchOnly8;
     MacroAssemblerCodeRef m_matchOnly16;
     bool m_needFallBack;
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+    bool m_usesPatternContextBuffer;
+#endif
 };
 
 enum YarrJITCompileMode {

Modified: branches/safari-605-branch/Source/WTF/ChangeLog (228517 => 228518)


--- branches/safari-605-branch/Source/WTF/ChangeLog	2018-02-15 17:30:18 UTC (rev 228517)
+++ branches/safari-605-branch/Source/WTF/ChangeLog	2018-02-15 17:30:21 UTC (rev 228518)
@@ -1,3 +1,19 @@
+2018-02-15  Jason Marcell  <[email protected]>
+
+        Cherry-pick r228481. rdar://problem/37570863
+
+    2018-02-14  Michael Saboff  <[email protected]>
+
+            REGRESSION(225695) : com.apple.WebKit.WebContent at com.apple._javascript_Core: JSC::RegExp::match + 630 :: stack overflow
+            https://bugs.webkit.org/show_bug.cgi?id=182705
+
+            Reviewed by Mark Lam.
+
+            Moved the setting of ENABLE_YARR_JIT_ALL_PARENS_EXPRESSIONS to Platform.h since more than just the YARR
+            code needs to know if that feature is enabled.
+
+            * wtf/Platform.h:
+
 2018-02-06  Jason Marcell  <[email protected]>
 
         Cherry-pick r228001. rdar://problem/37264547

Modified: branches/safari-605-branch/Source/WTF/wtf/Platform.h (228517 => 228518)


--- branches/safari-605-branch/Source/WTF/wtf/Platform.h	2018-02-15 17:30:18 UTC (rev 228517)
+++ branches/safari-605-branch/Source/WTF/wtf/Platform.h	2018-02-15 17:30:21 UTC (rev 228518)
@@ -982,6 +982,13 @@
 #define ENABLE_YARR_JIT_DEBUG 0
 #endif
 
+#if ENABLE(YARR_JIT)
+#if CPU(ARM64) || (CPU(X86_64) && !OS(WINDOWS))
+/* Enable JIT'ing Regular Expressions that have nested parenthesis. */
+#define ENABLE_YARR_JIT_ALL_PARENS_EXPRESSIONS 1
+#endif
+#endif
+
 /* If either the JIT or the RegExp JIT is enabled, then the Assembler must be
    enabled as well: */
 #if ENABLE(JIT) || ENABLE(YARR_JIT)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to