]>
git.saurik.com Git - apple/javascriptcore.git/blob - bytecode/Opcode.cpp
0bb714bca2d14ed884574fb73c9cac8947faca4f
   2  * Copyright (C) 2008 Apple Inc. All rights reserved. 
   3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> 
   5  * Redistribution and use in source and binary forms, with or without 
   6  * modification, are permitted provided that the following conditions 
   9  * 1.  Redistributions of source code must retain the above copyright 
  10  *     notice, this list of conditions and the following disclaimer. 
  11  * 2.  Redistributions in binary form must reproduce the above copyright 
  12  *     notice, this list of conditions and the following disclaimer in the 
  13  *     documentation and/or other materials provided with the distribution. 
  14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of 
  15  *     its contributors may be used to endorse or promote products derived 
  16  *     from this software without specific prior written permission. 
  18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 
  19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
  20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
  21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 
  22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
  23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
  24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
  25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
  27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  33 #if ENABLE(OPCODE_STATS) 
  35 #include <wtf/FixedArray.h> 
  42 #if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS) 
  44 const char* const opcodeNames
[] = { 
  45 #define OPCODE_NAME_ENTRY(opcode, size) #opcode, 
  46     FOR_EACH_OPCODE_ID(OPCODE_NAME_ENTRY
) 
  47 #undef OPCODE_NAME_ENTRY 
  52 #if ENABLE(OPCODE_STATS) 
  54 long long OpcodeStats::opcodeCounts
[numOpcodeIDs
]; 
  55 long long OpcodeStats::opcodePairCounts
[numOpcodeIDs
][numOpcodeIDs
]; 
  56 int OpcodeStats::lastOpcode 
= -1; 
  58 static OpcodeStats logger
; 
  60 OpcodeStats::OpcodeStats() 
  62     for (int i 
= 0; i 
< numOpcodeIDs
; ++i
) 
  65     for (int i 
= 0; i 
< numOpcodeIDs
; ++i
) 
  66         for (int j 
= 0; j 
< numOpcodeIDs
; ++j
) 
  67             opcodePairCounts
[i
][j
] = 0; 
  70 static int compareOpcodeIndices(const void* left
, const void* right
) 
  72     long long leftValue 
= OpcodeStats::opcodeCounts
[*(int*) left
]; 
  73     long long rightValue 
= OpcodeStats::opcodeCounts
[*(int*) right
]; 
  75     if (leftValue 
< rightValue
) 
  77     else if (leftValue 
> rightValue
) 
  83 static int compareOpcodePairIndices(const void* left
, const void* right
) 
  85     pair
<int, int> leftPair 
= *(pair
<int, int>*) left
; 
  86     long long leftValue 
= OpcodeStats::opcodePairCounts
[leftPair
.first
][leftPair
.second
]; 
  87     pair
<int, int> rightPair 
= *(pair
<int, int>*) right
; 
  88     long long rightValue 
= OpcodeStats::opcodePairCounts
[rightPair
.first
][rightPair
.second
]; 
  90     if (leftValue 
< rightValue
) 
  92     else if (leftValue 
> rightValue
) 
  98 OpcodeStats::~OpcodeStats() 
 100     long long totalInstructions 
= 0; 
 101     for (int i 
= 0; i 
< numOpcodeIDs
; ++i
) 
 102         totalInstructions 
+= opcodeCounts
[i
]; 
 104     long long totalInstructionPairs 
= 0; 
 105     for (int i 
= 0; i 
< numOpcodeIDs
; ++i
) 
 106         for (int j 
= 0; j 
< numOpcodeIDs
; ++j
) 
 107             totalInstructionPairs 
+= opcodePairCounts
[i
][j
]; 
 109     FixedArray
<int, numOpcodeIDs
> sortedIndices
; 
 110     for (int i 
= 0; i 
< numOpcodeIDs
; ++i
) 
 111         sortedIndices
[i
] = i
; 
 112     qsort(sortedIndices
.data(), numOpcodeIDs
, sizeof(int), compareOpcodeIndices
); 
 114     pair
<int, int> sortedPairIndices
[numOpcodeIDs 
* numOpcodeIDs
]; 
 115     pair
<int, int>* currentPairIndex 
= sortedPairIndices
; 
 116     for (int i 
= 0; i 
< numOpcodeIDs
; ++i
) 
 117         for (int j 
= 0; j 
< numOpcodeIDs
; ++j
) 
 118             *(currentPairIndex
++) = make_pair(i
, j
); 
 119     qsort(sortedPairIndices
, numOpcodeIDs 
* numOpcodeIDs
, sizeof(pair
<int, int>), compareOpcodePairIndices
); 
 121     printf("\nExecuted opcode statistics\n");  
 123     printf("Total instructions executed: %lld\n\n", totalInstructions
); 
 125     printf("All opcodes by frequency:\n\n"); 
 127     for (int i 
= 0; i 
< numOpcodeIDs
; ++i
) { 
 128         int index 
= sortedIndices
[i
]; 
 129         printf("%s:%s %lld - %.2f%%\n", opcodeNames
[index
], padOpcodeName((OpcodeID
)index
, 28), opcodeCounts
[index
], ((double) opcodeCounts
[index
]) / ((double) totalInstructions
) * 100.0);     
 133     printf("2-opcode sequences by frequency: %lld\n\n", totalInstructions
); 
 135     for (int i 
= 0; i 
< numOpcodeIDs 
* numOpcodeIDs
; ++i
) { 
 136         pair
<int, int> indexPair 
= sortedPairIndices
[i
]; 
 137         long long count 
= opcodePairCounts
[indexPair
.first
][indexPair
.second
]; 
 142         printf("%s%s %s:%s %lld %.2f%%\n", opcodeNames
[indexPair
.first
], padOpcodeName((OpcodeID
)indexPair
.first
, 28), opcodeNames
[indexPair
.second
], padOpcodeName((OpcodeID
)indexPair
.second
, 28), count
, ((double) count
) / ((double) totalInstructionPairs
) * 100.0); 
 146     printf("Most common opcodes and sequences:\n"); 
 148     for (int i 
= 0; i 
< numOpcodeIDs
; ++i
) { 
 149         int index 
= sortedIndices
[i
]; 
 150         long long opcodeCount 
= opcodeCounts
[index
]; 
 151         double opcodeProportion 
= ((double) opcodeCount
) / ((double) totalInstructions
); 
 152         if (opcodeProportion 
< 0.0001) 
 154         printf("\n%s:%s %lld - %.2f%%\n", opcodeNames
[index
], padOpcodeName((OpcodeID
)index
, 28), opcodeCount
, opcodeProportion 
* 100.0); 
 156         for (int j 
= 0; j 
< numOpcodeIDs 
* numOpcodeIDs
; ++j
) { 
 157             pair
<int, int> indexPair 
= sortedPairIndices
[j
]; 
 158             long long pairCount 
= opcodePairCounts
[indexPair
.first
][indexPair
.second
]; 
 159             double pairProportion 
= ((double) pairCount
) / ((double) totalInstructionPairs
); 
 161             if (!pairCount 
|| pairProportion 
< 0.0001 || pairProportion 
< opcodeProportion 
/ 100) 
 164             if (indexPair
.first 
!= index 
&& indexPair
.second 
!= index
) 
 167             printf("    %s%s %s:%s %lld - %.2f%%\n", opcodeNames
[indexPair
.first
], padOpcodeName((OpcodeID
)indexPair
.first
, 28), opcodeNames
[indexPair
.second
], padOpcodeName((OpcodeID
)indexPair
.second
, 28), pairCount
, pairProportion 
* 100.0); 
 174 void OpcodeStats::recordInstruction(int opcode
) 
 176     opcodeCounts
[opcode
]++; 
 178     if (lastOpcode 
!= -1) 
 179         opcodePairCounts
[lastOpcode
][opcode
]++; 
 184 void OpcodeStats::resetLastInstruction()