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

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

Bug 18626: SQUIRRELFISH: support the "slow script" dialog <https://bugs.webkit.org/show_bug.cgi?id=18626>
<rdar://problem/5973931> Slow script dialog needs to be reimplemented for squirrelfish

Reviewed by Sam

Adds support for the slow script dialog in squirrelfish. This requires the addition
of three new op codes, op_loop, op_loop_if_true, and op_loop_if_less which have the
same behaviour as their simple jump equivalents but have an additional time out check.

Additional assertions were added to other jump instructions to prevent accidentally
creating loops with jump types that do not support time out checks.

Sunspider does not report a regression, however this appears very sensitive to code
layout and hardware, so i would expect up to a 1% regression on other systems.

Part of this required moving the old timeout logic from JSGlobalObject and into Machine
which is the cause of a number of the larger diff blocks.

File size: 7.8 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 "jless ",
107 "jmp_scopes ",
108 "loop ",
109 "loop_if_true",
110 "loop_if_less",
111
112 "new_func ",
113 "new_func_exp",
114 "call ",
115 "call_eval ",
116 "ret ",
117
118 "construct ",
119
120 "get_pnames ",
121 "next_pname ",
122
123 "push_scope ",
124 "pop_scope ",
125
126 "catch ",
127 "throw ",
128 "new_error ",
129
130 "jsr ",
131 "sret ",
132
133 "debug ",
134
135 "end "
136};
137
138OpcodeStats::OpcodeStats()
139{
140 for (int i = 0; i < numOpcodeIDs; ++i)
141 opcodeCounts[i] = 0;
142
143 for (int i = 0; i < numOpcodeIDs; ++i)
144 for (int j = 0; j < numOpcodeIDs; ++j)
145 opcodePairCounts[i][j] = 0;
146}
147
148static int compareOpcodeIndices(const void* left, const void* right)
149{
150 long long leftValue = OpcodeStats::opcodeCounts[*(int*) left];
151 long long rightValue = OpcodeStats::opcodeCounts[*(int*) right];
152
153 if (leftValue < rightValue)
154 return 1;
155 else if (leftValue > rightValue)
156 return -1;
157 else
158 return 0;
159}
160
161static int compareOpcodePairIndices(const void* left, const void* right)
162{
163 pair<int, int> leftPair = *(pair<int, int>*) left;
164 long long leftValue = OpcodeStats::opcodePairCounts[leftPair.first][leftPair.second];
165 pair<int, int> rightPair = *(pair<int, int>*) right;
166 long long rightValue = OpcodeStats::opcodePairCounts[rightPair.first][rightPair.second];
167
168 if (leftValue < rightValue)
169 return 1;
170 else if (leftValue > rightValue)
171 return -1;
172 else
173 return 0;
174}
175
176OpcodeStats::~OpcodeStats()
177{
178 long long totalInstructions = 0;
179 for (int i = 0; i < numOpcodeIDs; ++i)
180 totalInstructions += opcodeCounts[i];
181
182 long long totalInstructionPairs = 0;
183 for (int i = 0; i < numOpcodeIDs; ++i)
184 for (int j = 0; j < numOpcodeIDs; ++j)
185 totalInstructionPairs += opcodePairCounts[i][j];
186
187 int sortedIndices[numOpcodeIDs];
188 for (int i = 0; i < numOpcodeIDs; ++i)
189 sortedIndices[i] = i;
190 mergesort(sortedIndices, numOpcodeIDs, sizeof(int), compareOpcodeIndices);
191
192 pair<int, int> sortedPairIndices[numOpcodeIDs * numOpcodeIDs];
193 pair<int, int>* currentPairIndex = sortedPairIndices;
194 for (int i = 0; i < numOpcodeIDs; ++i)
195 for (int j = 0; j < numOpcodeIDs; ++j)
196 *(currentPairIndex++) = make_pair(i, j);
197 mergesort(sortedPairIndices, numOpcodeIDs * numOpcodeIDs, sizeof(pair<int, int>), compareOpcodePairIndices);
198
199 printf("\nExecuted opcode statistics\n");
200
201 printf("Total instructions executed: %lld\n\n", totalInstructions);
202
203 printf("All opcodes by frequency:\n\n");
204
205 for (int i = 0; i < numOpcodeIDs; ++i) {
206 int index = sortedIndices[i];
207 printf("%s: %lld - %.2f%%\n", opcodeNames[index], opcodeCounts[index], ((double) opcodeCounts[index]) / ((double) totalInstructions) * 100.0);
208 }
209
210 printf("\n");
211 printf("2-opcode sequences by frequency: %lld\n\n", totalInstructions);
212
213 for (int i = 0; i < numOpcodeIDs * numOpcodeIDs; ++i) {
214 pair<int, int> indexPair = sortedPairIndices[i];
215 long long count = opcodePairCounts[indexPair.first][indexPair.second];
216
217 if (!count)
218 break;
219
220 printf("%s %s: %lld %.2f%%\n", opcodeNames[indexPair.first], opcodeNames[indexPair.second], count, ((double) count) / ((double) totalInstructionPairs) * 100.0);
221 }
222
223 printf("\n");
224 printf("Most common opcodes and sequences:\n");
225
226 for (int i = 0; i < numOpcodeIDs; ++i) {
227 int index = sortedIndices[i];
228 long long opcodeCount = opcodeCounts[index];
229 double opcodeProportion = ((double) opcodeCount) / ((double) totalInstructions);
230 if (opcodeProportion < 0.0001)
231 break;
232 printf("\n%s: %lld - %.2f%%\n", opcodeNames[index], opcodeCount, opcodeProportion * 100.0);
233
234 for (int j = 0; j < numOpcodeIDs * numOpcodeIDs; ++j) {
235 pair<int, int> indexPair = sortedPairIndices[j];
236 long long pairCount = opcodePairCounts[indexPair.first][indexPair.second];
237 double pairProportion = ((double) pairCount) / ((double) totalInstructionPairs);
238
239 if (!pairCount || pairProportion < 0.0001 || pairProportion < opcodeProportion / 100)
240 break;
241
242 if (indexPair.first != index && indexPair.second != index)
243 continue;
244
245 printf(" %s %s: %lld - %.2f%%\n", opcodeNames[indexPair.first], opcodeNames[indexPair.second], pairCount, pairProportion * 100.0);
246 }
247
248 }
249 printf("\n");
250}
251
252void OpcodeStats::recordInstruction(int opcode)
253{
254 opcodeCounts[opcode]++;
255
256 if (lastOpcode != -1)
257 opcodePairCounts[lastOpcode][opcode]++;
258
259 lastOpcode = opcode;
260}
261
262void OpcodeStats::resetLastInstruction()
263{
264 lastOpcode = -1;
265}
266
267#endif
268
269} // namespace WTF
Note: See TracBrowser for help on using the repository browser.