diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/RegExp.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/RegExp.cpp | 100 |
1 files changed, 63 insertions, 37 deletions
diff --git a/Source/JavaScriptCore/runtime/RegExp.cpp b/Source/JavaScriptCore/runtime/RegExp.cpp index d27bc1eb1..26750b3c7 100644 --- a/Source/JavaScriptCore/runtime/RegExp.cpp +++ b/Source/JavaScriptCore/runtime/RegExp.cpp @@ -24,21 +24,23 @@ #include "RegExp.h" #include "Lexer.h" -#include "Operations.h" +#include "JSCInlines.h" #include "RegExpCache.h" #include "Yarr.h" #include "YarrJIT.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <wtf/Assertions.h> -#include <wtf/OwnArrayPtr.h> #define REGEXP_FUNC_TEST_DATA_GEN 0 +#if REGEXP_FUNC_TEST_DATA_GEN +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#endif + namespace JSC { -const ClassInfo RegExp::s_info = { "RegExp", 0, 0, 0, CREATE_METHOD_TABLE(RegExp) }; +const ClassInfo RegExp::s_info = { "RegExp", 0, 0, CREATE_METHOD_TABLE(RegExp) }; RegExpFlags regExpFlags(const String& string) { @@ -111,7 +113,7 @@ RegExpFunctionalTestCollector* RegExpFunctionalTestCollector::get() return s_instance; } -void RegExpFunctionalTestCollector::outputOneTest(RegExp* regExp, String s, int startOffset, int* ovector, int result) +void RegExpFunctionalTestCollector::outputOneTest(RegExp* regExp, const String& s, int startOffset, int* ovector, int result) { if ((!m_lastRegExp) || (m_lastRegExp != regExp)) { m_lastRegExp = regExp; @@ -225,6 +227,10 @@ RegExp::RegExp(VM& vm, const String& patternString, RegExpFlags flags) , m_constructionError(0) , m_numSubpatterns(0) #if ENABLE(REGEXP_TRACING) + , m_rtMatchOnlyTotalSubjectStringLen(0.0) + , m_rtMatchTotalSubjectStringLen(0.0) + , m_rtMatchOnlyCallCount(0) + , m_rtMatchOnlyFoundCount(0) , m_rtMatchCallCount(0) , m_rtMatchFoundCount(0) #endif @@ -250,6 +256,16 @@ void RegExp::destroy(JSCell* cell) thisObject->RegExp::~RegExp(); } +size_t RegExp::estimatedSize(JSCell* cell) +{ + RegExp* thisObject = static_cast<RegExp*>(cell); + size_t regexDataSize = thisObject->m_regExpBytecode ? thisObject->m_regExpBytecode->estimatedSizeInBytes() : 0; +#if ENABLE(YARR_JIT) + regexDataSize += thisObject->m_regExpJITCode.size(); +#endif + return Base::estimatedSize(cell) + regexDataSize; +} + RegExp* RegExp::createWithoutCaching(VM& vm, const String& patternString, RegExpFlags flags) { RegExp* regExp = new (NotNull, allocateCell<RegExp>(vm.heap)) RegExp(vm, patternString, flags); @@ -267,8 +283,10 @@ void RegExp::compile(VM* vm, Yarr::YarrCharSize charSize) Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError); if (m_constructionError) { RELEASE_ASSERT_NOT_REACHED(); +#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE) m_state = ParseError; return; +#endif } ASSERT(m_numSubpatterns == pattern.m_numSubpatterns); @@ -279,24 +297,18 @@ void RegExp::compile(VM* vm, Yarr::YarrCharSize charSize) } #if ENABLE(YARR_JIT) - if (!pattern.m_containsBackreferences && vm->canUseRegExpJIT()) { + if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && vm->canUseRegExpJIT()) { Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode); -#if ENABLE(YARR_JIT_DEBUG) - if (!m_regExpJITCode.isFallBack()) - m_state = JITCode; - else - m_state = ByteCode; -#else if (!m_regExpJITCode.isFallBack()) { m_state = JITCode; return; } -#endif } #else UNUSED_PARAM(charSize); #endif + m_state = ByteCode; m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator); } @@ -322,6 +334,7 @@ int RegExp::match(VM& vm, const String& s, unsigned startOffset, Vector<int, 32> { #if ENABLE(REGEXP_TRACING) m_rtMatchCallCount++; + m_rtMatchTotalSubjectStringLen += (double)(s.length() - startOffset); #endif ASSERT(m_state != ParseError); @@ -350,8 +363,8 @@ int RegExp::match(VM& vm, const String& s, unsigned startOffset, Vector<int, 32> // The offset vector handling needs to change as well. // Right now we convert a match where the offsets overflowed into match failure. // There are two places in WebCore that call the interpreter directly that need to - // have their offsets changed to int as well. They are platform/text/RegularExpression.cpp - // and inspector/ContentSearchUtils.cpp. + // have their offsets changed to int as well. They are yarr/RegularExpression.cpp + // and inspector/ContentSearchUtilities.cpp if (s.length() > INT_MAX) { bool overflowed = false; @@ -389,8 +402,10 @@ void RegExp::compileMatchOnly(VM* vm, Yarr::YarrCharSize charSize) Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError); if (m_constructionError) { RELEASE_ASSERT_NOT_REACHED(); +#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE) m_state = ParseError; return; +#endif } ASSERT(m_numSubpatterns == pattern.m_numSubpatterns); @@ -401,24 +416,18 @@ void RegExp::compileMatchOnly(VM* vm, Yarr::YarrCharSize charSize) } #if ENABLE(YARR_JIT) - if (!pattern.m_containsBackreferences && vm->canUseRegExpJIT()) { + if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && vm->canUseRegExpJIT()) { Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode, Yarr::MatchOnly); -#if ENABLE(YARR_JIT_DEBUG) - if (!m_regExpJITCode.isFallBack()) - m_state = JITCode; - else - m_state = ByteCode; -#else if (!m_regExpJITCode.isFallBack()) { m_state = JITCode; return; } -#endif } #else UNUSED_PARAM(charSize); #endif + m_state = ByteCode; m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator); } @@ -443,7 +452,8 @@ void RegExp::compileIfNecessaryMatchOnly(VM& vm, Yarr::YarrCharSize charSize) MatchResult RegExp::match(VM& vm, const String& s, unsigned startOffset) { #if ENABLE(REGEXP_TRACING) - m_rtMatchCallCount++; + m_rtMatchOnlyCallCount++; + m_rtMatchOnlyTotalSubjectStringLen += (double)(s.length() - startOffset); #endif ASSERT(m_state != ParseError); @@ -456,7 +466,7 @@ MatchResult RegExp::match(VM& vm, const String& s, unsigned startOffset) m_regExpJITCode.execute(s.characters16(), startOffset, s.length()); #if ENABLE(REGEXP_TRACING) if (!result) - m_rtMatchFoundCount++; + m_rtMatchOnlyFoundCount++; #endif return result; } @@ -474,7 +484,7 @@ MatchResult RegExp::match(VM& vm, const String& s, unsigned startOffset) if (r >= 0) { #if ENABLE(REGEXP_TRACING) - m_rtMatchFoundCount++; + m_rtMatchOnlyFoundCount++; #endif return MatchResult(r, reinterpret_cast<unsigned*>(offsetVector)[1]); } @@ -482,7 +492,7 @@ MatchResult RegExp::match(VM& vm, const String& s, unsigned startOffset) return MatchResult::failed(); } -void RegExp::invalidateCode() +void RegExp::deleteCode() { if (!hasCode()) return; @@ -490,7 +500,7 @@ void RegExp::invalidateCode() #if ENABLE(YARR_JIT) m_regExpJITCode.clear(); #endif - m_regExpBytecode.clear(); + m_regExpBytecode = nullptr; } #if ENABLE(YARR_JIT_DEBUG) @@ -561,16 +571,32 @@ void RegExp::matchCompareWithInterpreter(const String& s, int startOffset, int* Yarr::YarrCodeBlock& codeBlock = m_regExpJITCode; const size_t jitAddrSize = 20; - char jitAddr[jitAddrSize]; - if (m_state == JITCode) - snprintf(jitAddr, jitAddrSize, "fallback"); - else - snprintf(jitAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.getAddr())); + char jit8BitMatchOnlyAddr[jitAddrSize]; + char jit16BitMatchOnlyAddr[jitAddrSize]; + char jit8BitMatchAddr[jitAddrSize]; + char jit16BitMatchAddr[jitAddrSize]; + if (m_state == ByteCode) { + snprintf(jit8BitMatchOnlyAddr, jitAddrSize, "fallback "); + snprintf(jit16BitMatchOnlyAddr, jitAddrSize, "---- "); + snprintf(jit8BitMatchAddr, jitAddrSize, "fallback "); + snprintf(jit16BitMatchAddr, jitAddrSize, "---- "); + } else { + snprintf(jit8BitMatchOnlyAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get8BitMatchOnlyAddr())); + snprintf(jit16BitMatchOnlyAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get16BitMatchOnlyAddr())); + snprintf(jit8BitMatchAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get8BitMatchAddr())); + snprintf(jit16BitMatchAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get16BitMatchAddr())); + } #else - const char* jitAddr = "JIT Off"; + const char* jit8BitMatchOnlyAddr = "JIT Off"; + const char* jit16BitMatchOnlyAddr = ""; + const char* jit8BitMatchAddr = "JIT Off"; + const char* jit16BitMatchAddr = ""; #endif + unsigned averageMatchOnlyStringLen = (unsigned)(m_rtMatchOnlyTotalSubjectStringLen / m_rtMatchOnlyCallCount); + unsigned averageMatchStringLen = (unsigned)(m_rtMatchTotalSubjectStringLen / m_rtMatchCallCount); - printf("%-40.40s %16.16s %10d %10d\n", formattedPattern, jitAddr, m_rtMatchCallCount, m_rtMatchFoundCount); + printf("%-40.40s %16.16s %16.16s %10d %10d %10u\n", formattedPattern, jit8BitMatchOnlyAddr, jit16BitMatchOnlyAddr, m_rtMatchOnlyCallCount, m_rtMatchOnlyFoundCount, averageMatchOnlyStringLen); + printf(" %16.16s %16.16s %10d %10d %10u\n", jit8BitMatchAddr, jit16BitMatchAddr, m_rtMatchCallCount, m_rtMatchFoundCount, averageMatchStringLen); } #endif |