2008-06-06 Cameron Zwarich <cwzwarich@uwaterloo.ca>
authorcwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Jun 2008 04:51:02 +0000 (04:51 +0000)
committercwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Jun 2008 04:51:02 +0000 (04:51 +0000)
        Reviewed by Oliver.

        Bug 19424: Add support for logging opcode pair counts
        <https://bugs.webkit.org/show_bug.cgi?id=19424>

        JavaScriptCore:

        * VM/Machine.cpp:
        (KJS::Machine::privateExecute):
        * VM/Opcode.cpp:
        (KJS::OpcodeStats::OpcodeStats):
        (KJS::compareOpcodeIndices):
        (KJS::compareOpcodePairIndices):
        (KJS::OpcodeStats::~OpcodeStats):
        (KJS::OpcodeStats::recordInstruction):
        (KJS::OpcodeStats::resetLastInstruction):
        * VM/Opcode.h:

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

JavaScriptCore/ChangeLog
JavaScriptCore/VM/Machine.cpp
JavaScriptCore/VM/Opcode.cpp
JavaScriptCore/VM/Opcode.h

index 342b6f9394f2e9d650237195c87303cd0e52883a..b755c7f160f56196a9c2bf6bc58e14784861a2fa 100644 (file)
@@ -1,3 +1,21 @@
+2008-06-06  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
+
+        Reviewed by Oliver.
+
+        Bug 19424: Add support for logging opcode pair counts
+        <https://bugs.webkit.org/show_bug.cgi?id=19424>
+
+        * VM/Machine.cpp:
+        (KJS::Machine::privateExecute):
+        * VM/Opcode.cpp:
+        (KJS::OpcodeStats::OpcodeStats):
+        (KJS::compareOpcodeIndices):
+        (KJS::compareOpcodePairIndices):
+        (KJS::OpcodeStats::~OpcodeStats):
+        (KJS::OpcodeStats::recordInstruction):
+        (KJS::OpcodeStats::resetLastInstruction):
+        * VM/Opcode.h:
+
 2008-06-06  Kevin McCullough  <kmccullough@apple.com>
 
         Reviewed by Adam.
index f0f34ced9bab150f4753a76f31a4c2acf88fd9aa..a1f4454b60d15a0af3ab6998824dd80a6d014011 100644 (file)
@@ -899,6 +899,10 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         } \
     } while (0)
 
+#if DUMP_OPCODE_STATS
+    OpcodeStats::resetLastInstruction();
+#endif
+
 #if HAVE(COMPUTED_GOTO)
     #define NEXT_OPCODE goto *vPC->u.opcode
 #if DUMP_OPCODE_STATS
@@ -1869,6 +1873,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
            Jumps unconditionally to offset target from the current
            instruction.
         */
+#if DUMP_OPCODE_STATS
+        OpcodeStats::resetLastInstruction();
+#endif
         int target = (++vPC)->u.operand;
 
         vPC += target;
@@ -2066,6 +2073,10 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
             k = codeBlock->jsValues.data();
             vPC = codeBlock->instructions.begin();
 
+#if DUMP_OPCODE_STATS
+            OpcodeStats::resetLastInstruction();
+#endif
+            
             NEXT_OPCODE;
         }
 
index c23f78ab28ee5d87a7d641d111a0047e8952d5f6..d878dd8219ab6a438ae4cea4c9e5fc98066c2d78 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "config.h"
 #include "Opcode.h"
 
+#include <stdlib.h>
+
+using namespace std;
+
 namespace KJS {
 
 #if DUMP_OPCODE_STATS
 
-unsigned OpcodeStats::opcodeCounts[numOpcodeIDs];
+long long OpcodeStats::opcodeCounts[numOpcodeIDs];
+long long OpcodeStats::opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
+int OpcodeStats::lastOpcode = -1;
 
 static OpcodeStats logger;
 
@@ -128,46 +135,100 @@ OpcodeStats::OpcodeStats()
 {
     for (int i = 0; i < numOpcodeIDs; ++i)
         opcodeCounts[i] = 0;
+    
+    for (int i = 0; i < numOpcodeIDs; ++i)
+        for (int j = 0; j < numOpcodeIDs; ++j)
+            opcodePairCounts[i][j] = 0;
 }
 
-OpcodeStats::~OpcodeStats()
+static int compareOpcodeIndices(const void* left, const void* right)
 {
-    int totalInstructions = 0;
-    int sortedIndices[numOpcodeIDs];
+    long long leftValue = OpcodeStats::opcodeCounts[*(int*) left];
+    long long rightValue = OpcodeStats::opcodeCounts[*(int*) right];
     
-    for (int i = 0; i < numOpcodeIDs; ++i) {
+    if (leftValue < rightValue)
+        return 1;
+    else if (leftValue > rightValue)
+        return -1;
+    else
+        return 0;
+}
+
+static int compareOpcodePairIndices(const void* left, const void* right)
+{
+    pair<int, int> leftPair = *(pair<int, int>*) left;
+    long long leftValue = OpcodeStats::opcodePairCounts[leftPair.first][leftPair.second];
+    pair<int, int> rightPair = *(pair<int, int>*) right;
+    long long rightValue = OpcodeStats::opcodePairCounts[rightPair.first][rightPair.second];
+    
+    if (leftValue < rightValue)
+        return 1;
+    else if (leftValue > rightValue)
+        return -1;
+    else
+        return 0;
+}
+
+OpcodeStats::~OpcodeStats()
+{
+    long long totalInstructions = 0;
+    for (int i = 0; i < numOpcodeIDs; ++i)
         totalInstructions += opcodeCounts[i];
+    
+    long long totalInstructionPairs = 0;
+    for (int i = 0; i < numOpcodeIDs; ++i)
+        for (int j = 0; j < numOpcodeIDs; ++j)
+            totalInstructionPairs += opcodePairCounts[i][j];
+
+    int sortedIndices[numOpcodeIDs];    
+    for (int i = 0; i < numOpcodeIDs; ++i)
         sortedIndices[i] = i;
-    }
-        
-    for (int i = 0; i < numOpcodeIDs - 1; ++i) {
-        int max = i;
-        
-        for (int j = i + 1; j < numOpcodeIDs; ++j) {
-            if (opcodeCounts[sortedIndices[j]] > opcodeCounts[sortedIndices[max]])
-                max = j;
-        }
-        
-        int temp = sortedIndices[i];
-        sortedIndices[i] = sortedIndices[max];
-        sortedIndices[max] = temp;
-    }
+    mergesort(sortedIndices, numOpcodeIDs, sizeof(int), compareOpcodeIndices);
+    
+    pair<int, int> sortedPairIndices[numOpcodeIDs * numOpcodeIDs];
+    pair<int, int>* currentPairIndex = sortedPairIndices;
+    for (int i = 0; i < numOpcodeIDs; ++i)
+        for (int j = 0; j < numOpcodeIDs; ++j)
+            *(currentPairIndex++) = make_pair(i, j);
+    mergesort(sortedPairIndices, numOpcodeIDs * numOpcodeIDs, sizeof(pair<int, int>), compareOpcodePairIndices);
+    
     printf("\nExecuted opcode statistics:\n\n"); 
     
-    printf("Total instructions executed: %d\n\n", totalInstructions);
-
+    printf("Total instructions executed: %lld\n\n", totalInstructions);
+    
     for (int i = 0; i < numOpcodeIDs; ++i) {
         int index = sortedIndices[i];
         printf("%s: %.2f%%\n", opcodeNames[index], ((double) opcodeCounts[index]) / ((double) totalInstructions) * 100.0);    
     }
     
     printf("\n");
+    
+    for (int i = 0; i < numOpcodeIDs * numOpcodeIDs; ++i) {
+        pair<int, int> indexPair = sortedPairIndices[i];
+        long long count = opcodePairCounts[indexPair.first][indexPair.second];
+        
+        if (!count)
+            break;
+        
+        printf("(%s, %s): %.2f%%\n", opcodeNames[indexPair.first], opcodeNames[indexPair.second], ((double) count) / ((double) totalInstructionPairs) * 100.0);
+    }
+    
+    printf("\n");
 }
 
 void OpcodeStats::recordInstruction(int opcode)
 {
     opcodeCounts[opcode]++;
+    
+    if (lastOpcode != -1)
+        opcodePairCounts[lastOpcode][opcode]++;
+    
+    lastOpcode = opcode;
+}
+
+void OpcodeStats::resetLastInstruction()
+{
+    lastOpcode = -1;
 }
 
 #endif
index bebebf182a5c4e0619647110e4e94827a1fd32fa..1dbbba9e6fd0741bca4614b0a90f275783c368a5 100644 (file)
@@ -143,8 +143,12 @@ namespace KJS {
     struct OpcodeStats {
         OpcodeStats();
         ~OpcodeStats();
-        static unsigned opcodeCounts[numOpcodeIDs];
+        static long long opcodeCounts[numOpcodeIDs];
+        static long long opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
+        static int lastOpcode;
+
         static void recordInstruction(int opcode);
+        static void resetLastInstruction();
     };
 
 #endif