summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/RegExp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/RegExp.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.cpp100
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