]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/RegExp.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / RegExp.cpp
index d27bc1eb12db7d5dc65a1ea5775deb9984a9aa63..af1f2fa1da6398bad6af3263d311e39e11c54d16 100644 (file)
 #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
@@ -267,8 +273,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 +287,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 +324,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 +353,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 +392,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 +406,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 +442,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 +456,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 +474,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]);
     }
@@ -490,7 +490,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 +561,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