]>
git.saurik.com Git - apple/javascriptcore.git/blob - bytecode/Opcode.cpp
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.
37 #if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS)
39 const char* const opcodeNames
[] = {
40 #define OPCODE_NAME_ENTRY(opcode, size) #opcode,
41 FOR_EACH_OPCODE_ID(OPCODE_NAME_ENTRY
)
42 #undef OPCODE_NAME_ENTRY
47 #if ENABLE(OPCODE_STATS)
49 long long OpcodeStats::opcodeCounts
[numOpcodeIDs
];
50 long long OpcodeStats::opcodePairCounts
[numOpcodeIDs
][numOpcodeIDs
];
51 int OpcodeStats::lastOpcode
= -1;
53 static OpcodeStats logger
;
55 OpcodeStats::OpcodeStats()
57 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
60 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
61 for (int j
= 0; j
< numOpcodeIDs
; ++j
)
62 opcodePairCounts
[i
][j
] = 0;
65 static int compareOpcodeIndices(const void* left
, const void* right
)
67 long long leftValue
= OpcodeStats::opcodeCounts
[*(int*) left
];
68 long long rightValue
= OpcodeStats::opcodeCounts
[*(int*) right
];
70 if (leftValue
< rightValue
)
72 else if (leftValue
> rightValue
)
78 static int compareOpcodePairIndices(const void* left
, const void* right
)
80 pair
<int, int> leftPair
= *(pair
<int, int>*) left
;
81 long long leftValue
= OpcodeStats::opcodePairCounts
[leftPair
.first
][leftPair
.second
];
82 pair
<int, int> rightPair
= *(pair
<int, int>*) right
;
83 long long rightValue
= OpcodeStats::opcodePairCounts
[rightPair
.first
][rightPair
.second
];
85 if (leftValue
< rightValue
)
87 else if (leftValue
> rightValue
)
93 OpcodeStats::~OpcodeStats()
95 long long totalInstructions
= 0;
96 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
97 totalInstructions
+= opcodeCounts
[i
];
99 long long totalInstructionPairs
= 0;
100 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
101 for (int j
= 0; j
< numOpcodeIDs
; ++j
)
102 totalInstructionPairs
+= opcodePairCounts
[i
][j
];
104 int sortedIndices
[numOpcodeIDs
];
105 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
106 sortedIndices
[i
] = i
;
107 qsort(sortedIndices
, numOpcodeIDs
, sizeof(int), compareOpcodeIndices
);
109 pair
<int, int> sortedPairIndices
[numOpcodeIDs
* numOpcodeIDs
];
110 pair
<int, int>* currentPairIndex
= sortedPairIndices
;
111 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
112 for (int j
= 0; j
< numOpcodeIDs
; ++j
)
113 *(currentPairIndex
++) = make_pair(i
, j
);
114 qsort(sortedPairIndices
, numOpcodeIDs
* numOpcodeIDs
, sizeof(pair
<int, int>), compareOpcodePairIndices
);
116 printf("\nExecuted opcode statistics\n");
118 printf("Total instructions executed: %lld\n\n", totalInstructions
);
120 printf("All opcodes by frequency:\n\n");
122 for (int i
= 0; i
< numOpcodeIDs
; ++i
) {
123 int index
= sortedIndices
[i
];
124 printf("%s:%s %lld - %.2f%%\n", opcodeNames
[index
], padOpcodeName((OpcodeID
)index
, 28), opcodeCounts
[index
], ((double) opcodeCounts
[index
]) / ((double) totalInstructions
) * 100.0);
128 printf("2-opcode sequences by frequency: %lld\n\n", totalInstructions
);
130 for (int i
= 0; i
< numOpcodeIDs
* numOpcodeIDs
; ++i
) {
131 pair
<int, int> indexPair
= sortedPairIndices
[i
];
132 long long count
= opcodePairCounts
[indexPair
.first
][indexPair
.second
];
137 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);
141 printf("Most common opcodes and sequences:\n");
143 for (int i
= 0; i
< numOpcodeIDs
; ++i
) {
144 int index
= sortedIndices
[i
];
145 long long opcodeCount
= opcodeCounts
[index
];
146 double opcodeProportion
= ((double) opcodeCount
) / ((double) totalInstructions
);
147 if (opcodeProportion
< 0.0001)
149 printf("\n%s:%s %lld - %.2f%%\n", opcodeNames
[index
], padOpcodeName((OpcodeID
)index
, 28), opcodeCount
, opcodeProportion
* 100.0);
151 for (int j
= 0; j
< numOpcodeIDs
* numOpcodeIDs
; ++j
) {
152 pair
<int, int> indexPair
= sortedPairIndices
[j
];
153 long long pairCount
= opcodePairCounts
[indexPair
.first
][indexPair
.second
];
154 double pairProportion
= ((double) pairCount
) / ((double) totalInstructionPairs
);
156 if (!pairCount
|| pairProportion
< 0.0001 || pairProportion
< opcodeProportion
/ 100)
159 if (indexPair
.first
!= index
&& indexPair
.second
!= index
)
162 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);
169 void OpcodeStats::recordInstruction(int opcode
)
171 opcodeCounts
[opcode
]++;
173 if (lastOpcode
!= -1)
174 opcodePairCounts
[lastOpcode
][opcode
]++;
179 void OpcodeStats::resetLastInstruction()