source: webkit/trunk/JavaScriptCore/VM/Opcode.h@ 38137

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

2008-10-25 Geoffrey Garen <[email protected]>

Reviewed by Sam Weinig, with Gavin Barraclough's help.


Fixed Sampling Tool:

  • Made CodeBlock sampling work with CTI
  • Improved accuracy by unifying most sampling data into a single 32bit word, which can be written / read atomically.
  • Split out three different #ifdefs for modularity: OPCODE_SAMPLING; CODEBLOCK_SAMPLING; OPCODE_STATS.
  • Improved reporting clarity
  • Refactored for code clarity
  • VM/CTI.cpp: (JSC::CTI::emitCTICall): (JSC::CTI::compileOpCall): (JSC::CTI::emitSlowScriptCheck): (JSC::CTI::compileBinaryArithOpSlowCase): (JSC::CTI::privateCompileMainPass): (JSC::CTI::privateCompileSlowCases): (JSC::CTI::privateCompile):
  • VM/CTI.h: Updated CTI codegen to use the unified SamplingTool interface for encoding samples. (This required passing the current vPC to a lot more functions, since the unified interface samples the current vPC.) Added hooks for writing the current CodeBlock* on function entry and after a function call, for the sake of the CodeBlock sampler. Removed obsolete hook for clearing the current sample inside op_end. Also removed the custom enum used to differentiate flavors of op_call, since the OpcodeID enum works just as well. (This was important in an earlier version of the patch, but now it's just cleanup.)
  • VM/CodeBlock.cpp: (JSC::CodeBlock::lineNumberForVPC):
  • VM/CodeBlock.h: Upated for refactored #ifdefs. Changed lineNumberForVPC to be robust against vPCs not recorded for exception handling, since the Sampler may ask for an arbitrary vPC.
  • VM/Machine.cpp: (JSC::Machine::execute): (JSC::Machine::privateExecute): (JSC::Machine::cti_op_call_NotJSFunction): (JSC::Machine::cti_op_construct_NotJSConstruct):
  • VM/Machine.h: (JSC::Machine::setSampler): (JSC::Machine::sampler): (JSC::Machine::jitCodeBuffer): Upated for refactored #ifdefs. Changed Machine to use SamplingTool helper objects to record movement in and out of host code. This makes samples a bit more precise.


  • VM/Opcode.cpp: (JSC::OpcodeStats::~OpcodeStats):
  • VM/Opcode.h: Upated for refactored #ifdefs. Added a little more padding, to accomodate our more verbose opcode names.
  • VM/SamplingTool.cpp: (JSC::ScopeSampleRecord::sample): Only count a sample toward our total if we actually record it. This solves cases where a CodeBlock will claim to have been sampled many times, with reported samples that don't match.

(JSC::SamplingTool::run): Read the current sample into a Sample helper
object, to ensure that the data doesn't change while we're analyzing it,
and to help decode the data. Only access the CodeBlock sampling hash
table if CodeBlock sampling has been enabled, so non-CodeBlock sampling
runs can operate with even less overhead.

(JSC::SamplingTool::dump): I reorganized this code a lot to print the
most important info at the top, print as a table, annotate and document
the stuff I didn't understand when I started, etc.

  • VM/SamplingTool.h: New helper classes, described above.
  • kjs/Parser.h:
  • kjs/Shell.cpp: (runWithScripts):
  • kjs/nodes.cpp: (JSC::ScopeNode::ScopeNode): Updated for new sampling APIs.
  • wtf/Platform.h: Moved sampling #defines here, since our custom is to put ENABLE #defines into Platform.h. Made explicit the fact that CODEBLOCK_SAMPLING depends on OPCODE_SAMPLING.
File size: 6.6 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#ifndef Opcodes_h
31#define Opcodes_h
32
33#include <algorithm>
34#include <string.h>
35
36#include <wtf/Assertions.h>
37
38namespace JSC {
39
40 #define FOR_EACH_OPCODE_ID(macro) \
41 macro(op_enter) \
42 macro(op_enter_with_activation) \
43 macro(op_create_arguments) \
44 macro(op_convert_this) \
45 \
46 macro(op_unexpected_load) \
47 macro(op_new_object) \
48 macro(op_new_array) \
49 macro(op_new_regexp) \
50 macro(op_mov) \
51 \
52 macro(op_not) \
53 macro(op_eq) \
54 macro(op_eq_null) \
55 macro(op_neq) \
56 macro(op_neq_null) \
57 macro(op_stricteq) \
58 macro(op_nstricteq) \
59 macro(op_less) \
60 macro(op_lesseq) \
61 \
62 macro(op_pre_inc) \
63 macro(op_pre_dec) \
64 macro(op_post_inc) \
65 macro(op_post_dec) \
66 macro(op_to_jsnumber) \
67 macro(op_negate) \
68 macro(op_add) \
69 macro(op_mul) \
70 macro(op_div) \
71 macro(op_mod) \
72 macro(op_sub) \
73 \
74 macro(op_lshift) \
75 macro(op_rshift) \
76 macro(op_urshift) \
77 macro(op_bitand) \
78 macro(op_bitxor) \
79 macro(op_bitor) \
80 macro(op_bitnot) \
81 \
82 macro(op_instanceof) \
83 macro(op_typeof) \
84 macro(op_is_undefined) \
85 macro(op_is_boolean) \
86 macro(op_is_number) \
87 macro(op_is_string) \
88 macro(op_is_object) \
89 macro(op_is_function) \
90 macro(op_in) \
91 \
92 macro(op_resolve) \
93 macro(op_resolve_skip) \
94 macro(op_resolve_global) \
95 macro(op_get_scoped_var) \
96 macro(op_put_scoped_var) \
97 macro(op_get_global_var) \
98 macro(op_put_global_var) \
99 macro(op_resolve_base) \
100 macro(op_resolve_with_base) \
101 macro(op_resolve_func) \
102 macro(op_get_by_id) \
103 macro(op_get_by_id_self) \
104 macro(op_get_by_id_proto) \
105 macro(op_get_by_id_chain) \
106 macro(op_get_by_id_generic) \
107 macro(op_get_array_length) \
108 macro(op_get_string_length) \
109 macro(op_put_by_id) \
110 macro(op_put_by_id_transition) \
111 macro(op_put_by_id_replace) \
112 macro(op_put_by_id_generic) \
113 macro(op_del_by_id) \
114 macro(op_get_by_val) \
115 macro(op_put_by_val) \
116 macro(op_del_by_val) \
117 macro(op_put_by_index) \
118 macro(op_put_getter) \
119 macro(op_put_setter) \
120 \
121 macro(op_jmp) \
122 macro(op_jtrue) \
123 macro(op_jfalse) \
124 macro(op_jeq_null) \
125 macro(op_jneq_null) \
126 macro(op_jnless) \
127 macro(op_jmp_scopes) \
128 macro(op_loop) \
129 macro(op_loop_if_true) \
130 macro(op_loop_if_less) \
131 macro(op_loop_if_lesseq) \
132 macro(op_switch_imm) \
133 macro(op_switch_char) \
134 macro(op_switch_string) \
135 \
136 macro(op_new_func) \
137 macro(op_new_func_exp) \
138 macro(op_call) \
139 macro(op_call_eval) \
140 macro(op_tear_off_activation) \
141 macro(op_tear_off_arguments) \
142 macro(op_ret) \
143 \
144 macro(op_construct) \
145 macro(op_construct_verify) \
146 \
147 macro(op_get_pnames) \
148 macro(op_next_pname) \
149 \
150 macro(op_push_scope) \
151 macro(op_pop_scope) \
152 macro(op_push_new_scope) \
153 \
154 macro(op_catch) \
155 macro(op_throw) \
156 macro(op_new_error) \
157 \
158 macro(op_jsr) \
159 macro(op_sret) \
160 \
161 macro(op_debug) \
162 macro(op_profile_will_call) \
163 macro(op_profile_did_call) \
164 \
165 macro(op_end) // end must be the last opcode in the list
166
167 #define OPCODE_ID_ENUM(opcode) opcode,
168 typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
169 #undef OPCODE_ID_ENUM
170
171 const int numOpcodeIDs = op_end + 1;
172
173 #define VERIFY_OPCODE_ID(id) COMPILE_ASSERT(id <= op_end, ASSERT_THAT_JS_OPCODE_IDS_ARE_VALID);
174 FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
175 #undef VERIFY_OPCODE_ID
176
177#if HAVE(COMPUTED_GOTO)
178 typedef void* Opcode;
179#else
180 typedef OpcodeID Opcode;
181#endif
182
183#if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS)
184
185#define PADDING_STRING " "
186#define PADDING_STRING_LENGTH static_cast<unsigned>(strlen(PADDING_STRING))
187
188 extern const char* const opcodeNames[];
189
190 inline const char* padOpcodeName(OpcodeID op, unsigned width)
191 {
192 unsigned pad = width - strlen(opcodeNames[op]);
193 pad = std::min(pad, PADDING_STRING_LENGTH);
194 return PADDING_STRING + PADDING_STRING_LENGTH - pad;
195 }
196
197#undef PADDING_STRING_LENGTH
198#undef PADDING_STRING
199
200#endif
201
202#if ENABLE(OPCODE_STATS)
203
204 struct OpcodeStats {
205 OpcodeStats();
206 ~OpcodeStats();
207 static long long opcodeCounts[numOpcodeIDs];
208 static long long opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
209 static int lastOpcode;
210
211 static void recordInstruction(int opcode);
212 static void resetLastInstruction();
213 };
214
215#endif
216
217} // namespace JSC
218
219#endif // Opcodes_h
Note: See TracBrowser for help on using the repository browser.