Changeset 245586 in webkit


Ignore:
Timestamp:
May 21, 2019 10:57:11 AM (5 years ago)
Author:
keith_miller@apple.com
Message:

Cleanup Yarr regexp code around paren contexts.
https://bugs.webkit.org/show_bug.cgi?id=198063

Reviewed by Yusuke Suzuki.

JSTests:

  • stress/regexp-many-named-sequential-capture-groups.js: Added.

(i.s):

  • stress/regexp-many-unnamed-sequential-capture-groups.js: Added.

Source/JavaScriptCore:

There are three refactoring changes around paren contexts:

  1. Make EncodedMatchResult the same type as MatchResult on X86_64 and arm64 and uint64_t elsewhere.
  2. All function pointer types for Yarr JIT generated code reserve space for paren contexts.
  3. initParenContextFreeList should bail based on VM::patternContextBufferSize as that's the buffer size anyway.
  • runtime/MatchResult.h:

(JSC::MatchResult::MatchResult):

  • runtime/RegExpInlines.h:

(JSC::PatternContextBufferHolder::PatternContextBufferHolder):
(JSC::PatternContextBufferHolder::~PatternContextBufferHolder):
(JSC::PatternContextBufferHolder::size):
(JSC::RegExp::matchInline):

  • runtime/VM.h:
  • yarr/YarrJIT.cpp:

(JSC::Yarr::YarrGenerator::initParenContextFreeList):

  • yarr/YarrJIT.h:

(JSC::Yarr::YarrCodeBlock::execute):

Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r245496 r245586  
     12019-05-20  Keith Miller  <keith_miller@apple.com>
     2
     3        Cleanup Yarr regexp code around paren contexts.
     4        https://bugs.webkit.org/show_bug.cgi?id=198063
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * stress/regexp-many-named-sequential-capture-groups.js: Added.
     9        (i.s):
     10        * stress/regexp-many-unnamed-sequential-capture-groups.js: Added.
     11
    1122019-05-17  Justin Michaud  <justin_michaud@apple.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r245564 r245586  
     12019-05-20  Keith Miller  <keith_miller@apple.com>
     2
     3        Cleanup Yarr regexp code around paren contexts.
     4        https://bugs.webkit.org/show_bug.cgi?id=198063
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        There are three refactoring changes around paren contexts:
     9        1. Make EncodedMatchResult the same type as MatchResult on X86_64 and arm64 and uint64_t elsewhere.
     10        2. All function pointer types for Yarr JIT generated code reserve space for paren contexts.
     11        3. initParenContextFreeList should bail based on VM::patternContextBufferSize as that's the buffer size anyway.
     12
     13        * runtime/MatchResult.h:
     14        (JSC::MatchResult::MatchResult):
     15        * runtime/RegExpInlines.h:
     16        (JSC::PatternContextBufferHolder::PatternContextBufferHolder):
     17        (JSC::PatternContextBufferHolder::~PatternContextBufferHolder):
     18        (JSC::PatternContextBufferHolder::size):
     19        (JSC::RegExp::matchInline):
     20        * runtime/VM.h:
     21        * yarr/YarrJIT.cpp:
     22        (JSC::Yarr::YarrGenerator::initParenContextFreeList):
     23        * yarr/YarrJIT.h:
     24        (JSC::Yarr::YarrCodeBlock::execute):
     25
    1262019-05-20  Tadeu Zagallo  <tzagallo@apple.com>
    227
  • trunk/Source/JavaScriptCore/runtime/MatchResult.h

    r218794 r245586  
    3131namespace JSC {
    3232
    33 typedef uint64_t EncodedMatchResult;
     33struct MatchResult;
     34#if CPU(ARM64) || CPU(X86_64)
     35using EncodedMatchResult = MatchResult;
     36#else
     37using EncodedMatchResult = uint64_t;
     38#endif
    3439
    3540struct MatchResult {
     
    4651    }
    4752
    48     explicit ALWAYS_INLINE MatchResult(EncodedMatchResult encoded)
     53#if !(CPU(ARM64) || CPU(X86_64))
     54    ALWAYS_INLINE MatchResult(EncodedMatchResult match)
     55        : start(bitwise_cast<MatchResult>(match).start)
     56        , end(bitwise_cast<MatchResult>(match).end)
    4957    {
    50         union u {
    51             uint64_t encoded;
    52             struct s {
    53                 size_t start;
    54                 size_t end;
    55             } split;
    56         } value;
    57         value.encoded = encoded;
    58         start = value.split.start;
    59         end = value.split.end;
    6058    }
     59#endif
    6160
    6261    ALWAYS_INLINE static MatchResult failed()
     
    8180};
    8281
     82static_assert(sizeof(MatchResult) == sizeof(EncodedMatchResult), "Match result and EncodedMatchResult should be the same size");
     83
    8384} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/RegExpInlines.h

    r243642 r245586  
    8787}
    8888
    89 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
    9089class PatternContextBufferHolder {
     90    WTF_FORBID_HEAP_ALLOCATION;
    9191public:
    9292    PatternContextBufferHolder(VM& vm, bool needBuffer)
    9393        : m_vm(vm)
    94         , m_needBuffer(needBuffer)
    9594    {
    96         if (m_needBuffer) {
     95#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
     96        if (needBuffer)
    9797            m_buffer = m_vm.acquireRegExpPatternContexBuffer();
    98             m_size = VM::patternContextBufferSize;
    99         } else {
    100             m_buffer = nullptr;
    101             m_size = 0;
    102         }
     98#endif
     99
    103100    }
    104101
    105102    ~PatternContextBufferHolder()
    106103    {
    107         if (m_needBuffer)
     104#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
     105        if (buffer())
    108106            m_vm.releaseRegExpPatternContexBuffer();
     107#else
     108        UNUSED_PARAM(m_vm);
     109#endif
    109110    }
    110111
    111112    void* buffer() { return m_buffer; }
    112     unsigned size() { return m_size; }
     113    unsigned size() { return buffer() ? VM::patternContextBufferSize : 0; }
    113114
    114115private:
    115116    VM& m_vm;
    116     bool m_needBuffer;
    117117    void* m_buffer;
    118     unsigned m_size;
    119118};
    120 #endif
    121119
    122120ALWAYS_INLINE void RegExp::compileIfNecessary(VM& vm, Yarr::YarrCharSize charSize)
     
    159157        {
    160158            ASSERT(m_regExpJITCode);
    161 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
    162159            PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode->usesPatternContextBuffer());
    163160
    164 #define EXTRA_JIT_PARAMS  , patternContextBufferHolder.buffer(), patternContextBufferHolder.size()
    165 #else
    166 #define EXTRA_JIT_PARAMS
    167 #endif
    168 
    169161            if (s.is8Bit())
    170                 result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start;
     162                result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), offsetVector, patternContextBufferHolder.buffer(), patternContextBufferHolder.size()).start;
    171163            else
    172                 result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start;
    173 
    174 #undef EXTRA_JIT_PARAMS
     164                result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), offsetVector, patternContextBufferHolder.buffer(), patternContextBufferHolder.size()).start;
    175165        }
    176166
     
    285275        {
    286276            ASSERT(m_regExpJITCode);
    287 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
    288277            PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode->usesPatternContextBuffer());
    289 
    290 #define EXTRA_JIT_PARAMS  , patternContextBufferHolder.buffer(), patternContextBufferHolder.size()
    291 #else
    292 #define EXTRA_JIT_PARAMS
    293 #endif
    294 
    295278            if (s.is8Bit())
    296                 result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length() EXTRA_JIT_PARAMS);
     279                result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), patternContextBufferHolder.buffer(), patternContextBufferHolder.size());
    297280            else
    298                 result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length() EXTRA_JIT_PARAMS);
    299 
    300 #undef EXTRA_JIT_PARAMS
     281                result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), patternContextBufferHolder.buffer(), patternContextBufferHolder.size());
    301282        }
    302283
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r244505 r245586  
    800800    char* acquireRegExpPatternContexBuffer();
    801801    void releaseRegExpPatternContexBuffer();
     802#else
     803    static constexpr size_t patternContextBufferSize = 0; // Space allocated to save nested parenthesis context
    802804#endif
    803805
  • trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp

    r244286 r245586  
    230230
    231231        // Check that the paren context is a reasonable size.
    232         if (parenContextSize > INT16_MAX)
     232        if (parenContextSize > VM::patternContextBufferSize)
    233233            m_abortExecution.append(jump());
    234234
  • trunk/Source/JavaScriptCore/yarr/YarrJIT.h

    r243237 r245586  
    3939#endif
    4040
    41 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
    42 constexpr size_t patternContextBufferSize = 8192; // Space caller allocates to save nested parenthesis context
    43 #endif
    44 
    4541namespace JSC {
    4642
     
    6258
    6359class YarrCodeBlock {
    64 #if CPU(X86_64) || CPU(ARM64)
    65 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
    66     typedef MatchResult (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
    67     typedef MatchResult (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
    68     typedef MatchResult (*YarrJITCodeMatchOnly8)(const LChar* input, unsigned start, unsigned length, void*, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
    69     typedef MatchResult (*YarrJITCodeMatchOnly16)(const UChar* input, unsigned start, unsigned length, void*, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
    70 #else
    71     typedef MatchResult (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
    72     typedef MatchResult (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
    73     typedef MatchResult (*YarrJITCodeMatchOnly8)(const LChar* input, unsigned start, unsigned length) YARR_CALL;
    74     typedef MatchResult (*YarrJITCodeMatchOnly16)(const UChar* input, unsigned start, unsigned length) YARR_CALL;
    75 #endif
    76 #else
    77     typedef EncodedMatchResult (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
    78     typedef EncodedMatchResult (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
    79     typedef EncodedMatchResult (*YarrJITCodeMatchOnly8)(const LChar* input, unsigned start, unsigned length) YARR_CALL;
    80     typedef EncodedMatchResult (*YarrJITCodeMatchOnly16)(const UChar* input, unsigned start, unsigned length) YARR_CALL;
    81 #endif
     60    // Technically freeParenContext and parenContextSize are only used if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS) is set. Fortunately, all the calling conventions we support have caller save argument registers.
     61    using YarrJITCode8 = EncodedMatchResult (*)(const LChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
     62    using YarrJITCode16 = EncodedMatchResult (*)(const UChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
     63    using YarrJITCodeMatchOnly8 = EncodedMatchResult (*)(const LChar* input, unsigned start, unsigned length, void*, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
     64    using YarrJITCodeMatchOnly16 = EncodedMatchResult (*)(const UChar* input, unsigned start, unsigned length, void*, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
    8265
    8366public:
     
    9780    void set16BitCodeMatchOnly(MacroAssemblerCodeRef<YarrMatchOnly16BitPtrTag> matchOnly) { m_matchOnly16 = matchOnly; }
    9881
     82    bool usesPatternContextBuffer() { return m_usesPatternContextBuffer; }
    9983#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
    100     bool usesPatternContextBuffer() { return m_usesPatternContextBuffer; }
    10184    void setUsesPatternContextBuffer() { m_usesPatternContextBuffer = true; }
     85#endif
    10286
    10387    MatchResult execute(const LChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize)
     
    124108        return MatchResult(untagCFunctionPtr<YarrJITCodeMatchOnly16, YarrMatchOnly16BitPtrTag>(m_matchOnly16.code().executableAddress())(input, start, length, 0, freeParenContext, parenContextSize));
    125109    }
    126 #else
    127     MatchResult execute(const LChar* input, unsigned start, unsigned length, int* output)
    128     {
    129         ASSERT(has8BitCode());
    130         return MatchResult(reinterpret_cast<YarrJITCode8>(m_ref8.code().executableAddress())(input, start, length, output));
    131     }
    132 
    133     MatchResult execute(const UChar* input, unsigned start, unsigned length, int* output)
    134     {
    135         ASSERT(has16BitCode());
    136         return MatchResult(reinterpret_cast<YarrJITCode16>(m_ref16.code().executableAddress())(input, start, length, output));
    137     }
    138 
    139     MatchResult execute(const LChar* input, unsigned start, unsigned length)
    140     {
    141         ASSERT(has8BitCodeMatchOnly());
    142         return MatchResult(reinterpret_cast<YarrJITCodeMatchOnly8>(m_matchOnly8.code().executableAddress())(input, start, length));
    143     }
    144 
    145     MatchResult execute(const UChar* input, unsigned start, unsigned length)
    146     {
    147         ASSERT(has16BitCodeMatchOnly());
    148         return MatchResult(reinterpret_cast<YarrJITCodeMatchOnly16>(m_matchOnly16.code().executableAddress())(input, start, length));
    149     }
    150 #endif
    151110
    152111#if ENABLE(REGEXP_TRACING)
     
    203162    MacroAssemblerCodeRef<YarrMatchOnly8BitPtrTag> m_matchOnly8;
    204163    MacroAssemblerCodeRef<YarrMatchOnly16BitPtrTag> m_matchOnly16;
    205 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
    206     bool m_usesPatternContextBuffer;
    207 #endif
     164    bool m_usesPatternContextBuffer { false };
    208165    Optional<JITFailureReason> m_failureReason;
    209166};
Note: See TracChangeset for help on using the changeset viewer.