Ignore:
Timestamp:
Jan 29, 2018, 2:43:13 AM (7 years ago)
Author:
Yusuke Suzuki
Message:

JSC Sampling Profiler: Detect tester and testee when sampling in RegExp JIT
https://bugs.webkit.org/show_bug.cgi?id=152729

Reviewed by Saam Barati.

JSTests:

  • stress/sampling-profiler-regexp.js: Added.

(platformSupportsSamplingProfiler.test):
(platformSupportsSamplingProfiler.baz):
(platformSupportsSamplingProfiler):

Source/JavaScriptCore:

This patch extends SamplingProfiler to recognize JIT RegExp execution. We record
executing RegExp in VM so that SamplingProfiler can detect it. This is better
than the previous VM::isExecutingInRegExpJIT flag approach since

  1. isExecutingInRegExpJIT is set after starting executing JIT RegExp code. Thus,

if we suspend the thread just before executing this flag, or just after clearing
this flag, SamplingProfiler gets invalid frame, and frame validation fails. We
should set such a flag before and after executing JIT RegExp code.

  1. This removes VM dependency from YarrJIT which is not essential one.

We add ExecutionContext enum to RegExp::matchInline not to mark execution if it
is done in non JS thread.

  • bytecode/BytecodeDumper.cpp:

(JSC::regexpName):
(JSC::BytecodeDumper<Block>::dumpRegExps):
(JSC::regexpToSourceString): Deleted.

  • heap/Heap.cpp:

(JSC::Heap::addCoreConstraints):

  • runtime/RegExp.cpp:

(JSC::RegExp::compile):
(JSC::RegExp::match):
(JSC::RegExp::matchConcurrently):
(JSC::RegExp::compileMatchOnly):
(JSC::RegExp::toSourceString const):

  • runtime/RegExp.h:
  • runtime/RegExpInlines.h:

(JSC::RegExp::matchInline):

  • runtime/RegExpMatchesArray.h:

(JSC::createRegExpMatchesArray):

  • runtime/SamplingProfiler.cpp:

(JSC::SamplingProfiler::SamplingProfiler):
(JSC::SamplingProfiler::timerLoop):
(JSC::SamplingProfiler::takeSample):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
(JSC::SamplingProfiler::StackFrame::nameFromCallee):
(JSC::SamplingProfiler::StackFrame::displayName):
(JSC::SamplingProfiler::StackFrame::displayNameForJSONTests):
(JSC::SamplingProfiler::StackFrame::functionStartLine):
(JSC::SamplingProfiler::StackFrame::functionStartColumn):
(JSC::SamplingProfiler::StackFrame::sourceID):
(JSC::SamplingProfiler::StackFrame::url):
(WTF::printInternal):
(JSC::SamplingProfiler::~SamplingProfiler): Deleted.

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

(JSC::Yarr::YarrGenerator::generateEnter):
(JSC::Yarr::YarrGenerator::generateReturn):
(JSC::Yarr::YarrGenerator::YarrGenerator):
(JSC::Yarr::jitCompile):

  • yarr/YarrJIT.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/RegExp.cpp

    r227469 r227725  
    308308#if ENABLE(YARR_JIT)
    309309    if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && VM::canUseRegExpJIT()) {
    310         Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode);
     310        Yarr::jitCompile(pattern, charSize, m_regExpJITCode);
    311311        if (!m_regExpJITCode.failureReason()) {
    312312            m_state = JITCode;
     
    327327int RegExp::match(VM& vm, const String& s, unsigned startOffset, Vector<int>& ovector)
    328328{
    329     return matchInline(vm, s, startOffset, ovector);
     329    return matchInline(vm, Concurrency::MainThread, s, startOffset, ovector);
    330330}
    331331
     
    338338        return false;
    339339
    340     position = match(vm, s, startOffset, ovector);
     340    position = matchInline(vm, Concurrency::Concurrent, s, startOffset, ovector);
    341341    return true;
    342342}
     
    364364#if ENABLE(YARR_JIT)
    365365    if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && VM::canUseRegExpJIT()) {
    366         Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode, Yarr::MatchOnly);
     366        Yarr::jitCompile(pattern, charSize, m_regExpJITCode, Yarr::MatchOnly);
    367367        if (!m_regExpJITCode.failureReason()) {
    368368            m_state = JITCode;
     
    383383MatchResult RegExp::match(VM& vm, const String& s, unsigned startOffset)
    384384{
    385     return matchInline(vm, s, startOffset);
     385    return matchInline(vm, Concurrency::MainThread, s, startOffset);
    386386}
    387387
     
    393393        return false;
    394394
    395     result = match(vm, s, startOffset);
     395    result = matchInline(vm, Concurrency::Concurrent, s, startOffset);
    396396    return true;
    397397}
     
    408408#endif
    409409    m_regExpBytecode = nullptr;
     410}
     411
     412String RegExp::toSourceString() const
     413{
     414    char postfix[8] = { '/', 0, 0, 0, 0, 0, 0, 0 };
     415    int index = 1;
     416    if (global())
     417        postfix[index++] = 'g';
     418    if (ignoreCase())
     419        postfix[index++] = 'i';
     420    if (multiline())
     421        postfix[index++] = 'm';
     422    if (dotAll())
     423        postfix[index++] = 's';
     424    if (unicode())
     425        postfix[index++] = 'u';
     426    if (sticky())
     427        postfix[index++] = 'y';
     428
     429    return makeString("/", pattern(), postfix);
    410430}
    411431
Note: See TracChangeset for help on using the changeset viewer.