source: webkit/trunk/JavaScriptCore/VM/Opcode.cpp@ 34411

Last change on this file since 34411 was 34411, checked in by [email protected], 17 years ago

2008-06-06 Cameron Zwarich <[email protected]>

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:
File size: 6.1 KB
Line 
1/*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich <[email protected]>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
17 *
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.
28 */
29
30#include "config.h"
31#include "Opcode.h"
32
33#include <stdlib.h>
34
35using namespace std;
36
37namespace KJS {
38
39#if DUMP_OPCODE_STATS
40
41long long OpcodeStats::opcodeCounts[numOpcodeIDs];
42long long OpcodeStats::opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
43int OpcodeStats::lastOpcode = -1;
44
45static OpcodeStats logger;
46
47static const char* opcodeNames[] = {
48 "load",
49 "new_object",
50 "new_array",
51 "new_regexp",
52 "mov",
53
54 "not",
55 "eq",
56 "neq",
57 "stricteq",
58 "nstricteq",
59 "less",
60 "lesseq",
61
62 "pre_inc",
63 "pre_dec",
64 "post_inc",
65 "post_dec",
66 "to_jsnumber",
67 "negate",
68 "add",
69 "mul",
70 "div",
71 "mod",
72 "sub",
73
74 "lshift",
75 "rshift",
76 "urshift",
77 "bitand",
78 "bitxor",
79 "bitor",
80 "bitnot",
81
82 "instanceof",
83 "typeof",
84 "in",
85
86 "resolve",
87 "resolve_skip",
88 "get_scoped_var",
89 "put_scoped_var",
90 "resolve_base",
91 "resolve_with_base",
92 "resolve_func",
93 "get_by_id",
94 "put_by_id",
95 "del_by_id",
96 "get_by_val",
97 "put_by_val",
98 "del_by_val",
99 "put_by_index",
100 "put_getter",
101 "put_setter",
102
103 "jmp",
104 "jtrue",
105 "jfalse",
106 "jmp_scopes",
107
108 "new_func",
109 "new_func_exp",
110 "call",
111 "call_eval",
112 "ret",
113
114 "construct",
115
116 "get_pnames",
117 "next_pname",
118
119 "push_scope",
120 "pop_scope",
121
122 "catch",
123 "throw",
124 "new_error",
125
126 "jsr",
127 "sret",
128
129 "debug",
130
131 "end"
132};
133
134OpcodeStats::OpcodeStats()
135{
136 for (int i = 0; i < numOpcodeIDs; ++i)
137 opcodeCounts[i] = 0;
138
139 for (int i = 0; i < numOpcodeIDs; ++i)
140 for (int j = 0; j < numOpcodeIDs; ++j)
141 opcodePairCounts[i][j] = 0;
142}
143
144static int compareOpcodeIndices(const void* left, const void* right)
145{
146 long long leftValue = OpcodeStats::opcodeCounts[*(int*) left];
147 long long rightValue = OpcodeStats::opcodeCounts[*(int*) right];
148
149 if (leftValue < rightValue)
150 return 1;
151 else if (leftValue > rightValue)
152 return -1;
153 else
154 return 0;
155}
156
157static int compareOpcodePairIndices(const void* left, const void* right)
158{
159 pair<int, int> leftPair = *(pair<int, int>*) left;
160 long long leftValue = OpcodeStats::opcodePairCounts[leftPair.first][leftPair.second];
161 pair<int, int> rightPair = *(pair<int, int>*) right;
162 long long rightValue = OpcodeStats::opcodePairCounts[rightPair.first][rightPair.second];
163
164 if (leftValue < rightValue)
165 return 1;
166 else if (leftValue > rightValue)
167 return -1;
168 else
169 return 0;
170}
171
172OpcodeStats::~OpcodeStats()
173{
174 long long totalInstructions = 0;
175 for (int i = 0; i < numOpcodeIDs; ++i)
176 totalInstructions += opcodeCounts[i];
177
178 long long totalInstructionPairs = 0;
179 for (int i = 0; i < numOpcodeIDs; ++i)
180 for (int j = 0; j < numOpcodeIDs; ++j)
181 totalInstructionPairs += opcodePairCounts[i][j];
182
183 int sortedIndices[numOpcodeIDs];
184 for (int i = 0; i < numOpcodeIDs; ++i)
185 sortedIndices[i] = i;
186 mergesort(sortedIndices, numOpcodeIDs, sizeof(int), compareOpcodeIndices);
187
188 pair<int, int> sortedPairIndices[numOpcodeIDs * numOpcodeIDs];
189 pair<int, int>* currentPairIndex = sortedPairIndices;
190 for (int i = 0; i < numOpcodeIDs; ++i)
191 for (int j = 0; j < numOpcodeIDs; ++j)
192 *(currentPairIndex++) = make_pair(i, j);
193 mergesort(sortedPairIndices, numOpcodeIDs * numOpcodeIDs, sizeof(pair<int, int>), compareOpcodePairIndices);
194
195 printf("\nExecuted opcode statistics:\n\n");
196
197 printf("Total instructions executed: %lld\n\n", totalInstructions);
198
199 for (int i = 0; i < numOpcodeIDs; ++i) {
200 int index = sortedIndices[i];
201 printf("%s: %.2f%%\n", opcodeNames[index], ((double) opcodeCounts[index]) / ((double) totalInstructions) * 100.0);
202 }
203
204 printf("\n");
205
206 for (int i = 0; i < numOpcodeIDs * numOpcodeIDs; ++i) {
207 pair<int, int> indexPair = sortedPairIndices[i];
208 long long count = opcodePairCounts[indexPair.first][indexPair.second];
209
210 if (!count)
211 break;
212
213 printf("(%s, %s): %.2f%%\n", opcodeNames[indexPair.first], opcodeNames[indexPair.second], ((double) count) / ((double) totalInstructionPairs) * 100.0);
214 }
215
216 printf("\n");
217}
218
219void OpcodeStats::recordInstruction(int opcode)
220{
221 opcodeCounts[opcode]++;
222
223 if (lastOpcode != -1)
224 opcodePairCounts[lastOpcode][opcode]++;
225
226 lastOpcode = opcode;
227}
228
229void OpcodeStats::resetLastInstruction()
230{
231 lastOpcode = -1;
232}
233
234#endif
235
236} // namespace WTF
Note: See TracBrowser for help on using the repository browser.