]>
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.
33 #if ENABLE(OPCODE_STATS)
35 #include <wtf/FixedArray.h>
42 const char* const opcodeNames
[] = {
43 #define OPCODE_NAME_ENTRY(opcode, size) #opcode,
44 FOR_EACH_OPCODE_ID(OPCODE_NAME_ENTRY
)
45 #undef OPCODE_NAME_ENTRY
48 #if ENABLE(OPCODE_STATS)
50 long long OpcodeStats::opcodeCounts
[numOpcodeIDs
];
51 long long OpcodeStats::opcodePairCounts
[numOpcodeIDs
][numOpcodeIDs
];
52 int OpcodeStats::lastOpcode
= -1;
54 static OpcodeStats logger
;
56 OpcodeStats::OpcodeStats()
58 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
61 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
62 for (int j
= 0; j
< numOpcodeIDs
; ++j
)
63 opcodePairCounts
[i
][j
] = 0;
66 static int compareOpcodeIndices(const void* left
, const void* right
)
68 long long leftValue
= OpcodeStats::opcodeCounts
[*(int*) left
];
69 long long rightValue
= OpcodeStats::opcodeCounts
[*(int*) right
];
71 if (leftValue
< rightValue
)
73 else if (leftValue
> rightValue
)
79 static int compareOpcodePairIndices(const void* left
, const void* right
)
81 pair
<int, int> leftPair
= *(pair
<int, int>*) left
;
82 long long leftValue
= OpcodeStats::opcodePairCounts
[leftPair
.first
][leftPair
.second
];
83 pair
<int, int> rightPair
= *(pair
<int, int>*) right
;
84 long long rightValue
= OpcodeStats::opcodePairCounts
[rightPair
.first
][rightPair
.second
];
86 if (leftValue
< rightValue
)
88 else if (leftValue
> rightValue
)
94 OpcodeStats::~OpcodeStats()
96 long long totalInstructions
= 0;
97 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
98 totalInstructions
+= opcodeCounts
[i
];
100 long long totalInstructionPairs
= 0;
101 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
102 for (int j
= 0; j
< numOpcodeIDs
; ++j
)
103 totalInstructionPairs
+= opcodePairCounts
[i
][j
];
105 FixedArray
<int, numOpcodeIDs
> sortedIndices
;
106 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
107 sortedIndices
[i
] = i
;
108 qsort(sortedIndices
.data(), numOpcodeIDs
, sizeof(int), compareOpcodeIndices
);
110 pair
<int, int> sortedPairIndices
[numOpcodeIDs
* numOpcodeIDs
];
111 pair
<int, int>* currentPairIndex
= sortedPairIndices
;
112 for (int i
= 0; i
< numOpcodeIDs
; ++i
)
113 for (int j
= 0; j
< numOpcodeIDs
; ++j
)
114 *(currentPairIndex
++) = make_pair(i
, j
);
115 qsort(sortedPairIndices
, numOpcodeIDs
* numOpcodeIDs
, sizeof(pair
<int, int>), compareOpcodePairIndices
);
117 dataLog("\nExecuted opcode statistics\n");
119 dataLog("Total instructions executed: %lld\n\n", totalInstructions
);
121 dataLog("All opcodes by frequency:\n\n");
123 for (int i
= 0; i
< numOpcodeIDs
; ++i
) {
124 int index
= sortedIndices
[i
];
125 dataLog("%s:%s %lld - %.2f%%\n", opcodeNames
[index
], padOpcodeName((OpcodeID
)index
, 28), opcodeCounts
[index
], ((double) opcodeCounts
[index
]) / ((double) totalInstructions
) * 100.0);
129 dataLog("2-opcode sequences by frequency: %lld\n\n", totalInstructions
);
131 for (int i
= 0; i
< numOpcodeIDs
* numOpcodeIDs
; ++i
) {
132 pair
<int, int> indexPair
= sortedPairIndices
[i
];
133 long long count
= opcodePairCounts
[indexPair
.first
][indexPair
.second
];
138 dataLog("%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);
142 dataLog("Most common opcodes and sequences:\n");
144 for (int i
= 0; i
< numOpcodeIDs
; ++i
) {
145 int index
= sortedIndices
[i
];
146 long long opcodeCount
= opcodeCounts
[index
];
147 double opcodeProportion
= ((double) opcodeCount
) / ((double) totalInstructions
);
148 if (opcodeProportion
< 0.0001)
150 dataLog("\n%s:%s %lld - %.2f%%\n", opcodeNames
[index
], padOpcodeName((OpcodeID
)index
, 28), opcodeCount
, opcodeProportion
* 100.0);
152 for (int j
= 0; j
< numOpcodeIDs
* numOpcodeIDs
; ++j
) {
153 pair
<int, int> indexPair
= sortedPairIndices
[j
];
154 long long pairCount
= opcodePairCounts
[indexPair
.first
][indexPair
.second
];
155 double pairProportion
= ((double) pairCount
) / ((double) totalInstructionPairs
);
157 if (!pairCount
|| pairProportion
< 0.0001 || pairProportion
< opcodeProportion
/ 100)
160 if (indexPair
.first
!= index
&& indexPair
.second
!= index
)
163 dataLog(" %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);
170 void OpcodeStats::recordInstruction(int opcode
)
172 opcodeCounts
[opcode
]++;
174 if (lastOpcode
!= -1)
175 opcodePairCounts
[lastOpcode
][opcode
]++;
180 void OpcodeStats::resetLastInstruction()