2011-01-06 Michael Saboff <msaboff@apple.com>
authormsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Jan 2011 00:17:23 +0000 (00:17 +0000)
committermsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Jan 2011 00:17:23 +0000 (00:17 +0000)
        Reviewed by Gavin Barraclough.

        Enhancement: Add Regexp Debug Compare between JIT and Interpreter
        https://bugs.webkit.org/show_bug.cgi?id=51834

        * JavaScriptCore: Copied from JavaScriptCore.
2011-01-06  Michael Saboff  <msaboff@apple.com>

        Reviewed by Gavin Barraclough.

        Added debug code to compare the results of JIT regexp with
        interpreted regexp and displays discrepencies.  This debug code is
        controlled by the ENABLE_YARR_JIT_DEBUG macro in wtf/Platform.h and
        is only valid if ENABLE_YARR_JIT is enabled.

        Fixed a discovered problem in RegExp::printTraceData, changing
        m_pattern to the getter pattern().
        Also deleted an extraneous semicolon.

        Enhancement: Add Regexp Debug Compare between JIT and Interpreter
        https://bugs.webkit.org/show_bug.cgi?id=51834

        * runtime/RegExp.cpp:
        (JSC::RegExp::compile):
        (JSC::RegExp::match):
        (JSC::RegExp::printTraceData):
        * wtf/Platform.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@75208 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/RegExp.cpp
Source/JavaScriptCore/runtime/RegExp.h
Source/JavaScriptCore/wtf/Platform.h

index b1929ff..ac03531 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-01-06  Michael Saboff  <msaboff@apple.com>
+
+        Reviewed by Gavin Barraclough.
+
+        Enhancement: Add Regexp Debug Compare between JIT and Interpreter
+        https://bugs.webkit.org/show_bug.cgi?id=51834
+
+        * JavaScriptCore: Copied from JavaScriptCore.
+
 2011-01-06  Martin Robinson  <mrobinson@igalia.com>
 
         Reviewed by Xan Lopez.
index 3a33d09..bc0f35e 100644 (file)
@@ -1,3 +1,25 @@
+2011-01-06  Michael Saboff  <msaboff@apple.com>
+
+        Reviewed by Gavin Barraclough.
+
+        Added debug code to compare the results of JIT regexp with 
+        interpreted regexp and displays discrepencies.  This debug code is
+        controlled by the ENABLE_YARR_JIT_DEBUG macro in wtf/Platform.h and
+        is only valid if ENABLE_YARR_JIT is enabled.
+
+        Fixed a discovered problem in RegExp::printTraceData, changing
+        m_pattern to the getter pattern().
+        Also deleted an extraneous semicolon.
+
+        Enhancement: Add Regexp Debug Compare between JIT and Interpreter
+        https://bugs.webkit.org/show_bug.cgi?id=51834
+
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::compile):
+        (JSC::RegExp::match):
+        (JSC::RegExp::printTraceData):
+        * wtf/Platform.h:
+
 2011-01-06  Patrick Gansterer  <paroga@webkit.org>
 
         Reviewed by Eric Seidel.
index 1cce41e..664a7fb 100644 (file)
@@ -88,23 +88,33 @@ RegExp::RegExpState RegExp::compile(JSGlobalData* globalData)
 
     m_numSubpatterns = pattern.m_numSubpatterns;
 
+    RegExpState res = ByteCode;
+
 #if ENABLE(YARR_JIT)
     if (!pattern.m_containsBackreferences && globalData->canUseJIT()) {
         Yarr::jitCompileRegex(pattern, globalData, m_representation->m_regExpJITCode);
+#if ENABLE(YARR_JIT_DEBUG)
+        if (!m_representation->m_regExpJITCode.isFallBack())
+            res = JITCode;
+        else
+            res = ByteCode;
+#else
         if (!m_representation->m_regExpJITCode.isFallBack())
             return JITCode;
+#endif
     }
 #endif
 
     m_representation->m_regExpBytecode = Yarr::byteCompileRegex(pattern, &globalData->m_regexAllocator);
-    return ByteCode;
+
+    return res;
 }
 
 int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
 {
     if (startOffset < 0)
         startOffset = 0;
-    
+
 #if ENABLE(REGEXP_TRACING)
     m_rtMatchCallCount++;
 #endif
@@ -133,14 +143,16 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
 
         int result;
 #if ENABLE(YARR_JIT)
-        if (m_state == JITCode)
+        if (m_state == JITCode) {
             result = Yarr::executeRegex(m_representation->m_regExpJITCode, s.characters(), startOffset, s.length(), offsetVector);
-        else
+#if ENABLE(YARR_JIT_DEBUG)
+            matchCompareWithInterpreter(s, startOffset, offsetVector, result);
+#endif
+        } else
 #endif
             result = Yarr::interpretRegex(m_representation->m_regExpBytecode.get(), s.characters(), startOffset, s.length(), offsetVector);
+        ASSERT(result >= -1);
 
-        ASSERT(result >= -1);;
-        
 #if ENABLE(REGEXP_TRACING)
         if (result != -1)
             m_rtMatchFoundCount++;
@@ -152,17 +164,69 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
     return -1;
 }
 
+
+#if ENABLE(YARR_JIT_DEBUG)
+void RegExp::matchCompareWithInterpreter(const UString& s, int startOffset, int* offsetVector, int jitResult)
+{
+    int offsetVectorSize = (m_numSubpatterns + 1) * 2;
+    Vector<int, 32> interpreterOvector;
+    interpreterOvector.resize(offsetVectorSize);
+    int* interpreterOffsetVector = interpreterOvector.data();
+    int interpreterResult = 0;
+    int differences = 0;
+
+    // Initialize interpreterOffsetVector with the return value (index 0) and the 
+    // first subpattern start indicies (even index values) set to -1.
+    // No need to init the subpattern end indicies.
+    for (unsigned j = 0, i = 0; i < m_numSubpatterns + 1; j += 2, i++)
+        interpreterOffsetVector[j] = -1;
+
+    interpreterResult = Yarr::interpretRegex(m_representation->m_regExpBytecode.get(), s.characters(), startOffset, s.length(), interpreterOffsetVector);
+
+    if (jitResult != interpreterResult)
+        differences++;
+
+    for (unsigned j = 2, i = 0; i < m_numSubpatterns; j +=2, i++)
+        if ((offsetVector[j] != interpreterOffsetVector[j])
+            || ((offsetVector[j] >= 0) && (offsetVector[j+1] != interpreterOffsetVector[j+1])))
+            differences++;
+
+    if (differences) {
+        fprintf(stderr, "RegExp Discrepency for /%s/\n    string input ", pattern().utf8().data());
+        unsigned segmentLen = s.length() - static_cast<unsigned>(startOffset);
+
+        fprintf(stderr, (segmentLen < 150) ? "\"%s\"\n" : "\"%148s...\"\n", s.utf8().data() + startOffset);
+
+        if (jitResult != interpreterResult) {
+            fprintf(stderr, "    JIT result = %d, blah interpreted result = %d\n", jitResult, interpreterResult);
+            differences--;
+        } else {
+            fprintf(stderr, "    Correct result = %d\n", jitResult);
+        }
+
+        if (differences) {
+            for (unsigned j = 2, i = 0; i < m_numSubpatterns; j +=2, i++) {
+                if (offsetVector[j] != interpreterOffsetVector[j])
+                    fprintf(stderr, "    JIT offset[%d] = %d, interpreted offset[%d] = %d\n", j, offsetVector[j], j, interpreterOffsetVector[j]);
+                if ((offsetVector[j] >= 0) && (offsetVector[j+1] != interpreterOffsetVector[j+1]))
+                    fprintf(stderr, "    JIT offset[%d] = %d, interpreted offset[%d] = %d\n", j+1, offsetVector[j+1], j+1, interpreterOffsetVector[j+1]);
+            }
+        }
+    }
+}
+#endif
+
 #if ENABLE(REGEXP_TRACING)
     void RegExp::printTraceData()
     {
         char formattedPattern[41];
         char rawPattern[41];
-        
-        strncpy(rawPattern, m_pattern.utf8().data(), 40);
+
+        strncpy(rawPattern, pattern().utf8().data(), 40);
         rawPattern[40]= '\0';
-        
+
         int pattLen = strlen(rawPattern);
-        
+
         snprintf(formattedPattern, 41, (pattLen <= 38) ? "/%.38s/" : "/%.36s...", rawPattern);
 
 #if ENABLE(YARR_JIT)
@@ -176,7 +240,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
 #else
         const char* jitAddr = "JIT Off";
 #endif
-        
+
         printf("%-40.40s %16.16s %10d %10d\n", formattedPattern, jitAddr, m_rtMatchCallCount, m_rtMatchFoundCount);
     }
 #endif
index 8f33f57..d99befb 100644 (file)
@@ -64,6 +64,10 @@ namespace JSC {
 
         RegExpState compile(JSGlobalData*);
 
+#if ENABLE(YARR_JIT_DEBUG)
+        void matchCompareWithInterpreter(const UString&, int startOffset, int* offsetVector, int jitResult);
+#endif
+
         enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 };
         UString m_patternString;
         int m_flagBits;
index 6496c60..5cc3a1a 100644 (file)
 /* Yet Another Regex Runtime - turned on by default for JIT enabled ports. */
 #if ENABLE(JIT) && !defined(ENABLE_YARR_JIT)
 #define ENABLE_YARR_JIT 1
+
+/* Setting this flag compares JIT results with interpreter results. */
+#define ENABLE_YARR_JIT_DEBUG 0
 #endif
 
 #if ENABLE(JIT) || ENABLE(YARR_JIT)