Roll out r164732 since it broke Production Mac builds.
[WebKit-https.git] / Source / JavaScriptCore / bytecode / Opcode.h
1 /*
2  * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
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 Opcode_h
31 #define Opcode_h
32
33 #include "LLIntOpcode.h"
34
35 #include <algorithm>
36 #include <string.h>
37
38 #include <wtf/Assertions.h>
39
40 namespace JSC {
41
42 #define FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION(macro, extension__) \
43     macro(op_enter, 1) \
44     macro(op_create_activation, 2) \
45     macro(op_touch_entry, 1) \
46     macro(op_init_lazy_reg, 2) \
47     macro(op_create_arguments, 2) \
48     macro(op_create_this, 4) \
49     macro(op_get_callee, 3) \
50     macro(op_to_this, 3) \
51     \
52     macro(op_new_object, 4) \
53     macro(op_new_array, 5) \
54     macro(op_new_array_with_size, 4) \
55     macro(op_new_array_buffer, 5) \
56     macro(op_new_regexp, 3) \
57     macro(op_mov, 3) \
58     macro(op_captured_mov, 4) \
59     \
60     macro(op_not, 3) \
61     macro(op_eq, 4) \
62     macro(op_eq_null, 3) \
63     macro(op_neq, 4) \
64     macro(op_neq_null, 3) \
65     macro(op_stricteq, 4) \
66     macro(op_nstricteq, 4) \
67     macro(op_less, 4) \
68     macro(op_lesseq, 4) \
69     macro(op_greater, 4) \
70     macro(op_greatereq, 4) \
71     \
72     macro(op_inc, 2) \
73     macro(op_dec, 2) \
74     macro(op_to_number, 3) \
75     macro(op_negate, 3) \
76     macro(op_add, 5) \
77     macro(op_mul, 5) \
78     macro(op_div, 5) \
79     macro(op_mod, 4) \
80     macro(op_sub, 5) \
81     \
82     macro(op_lshift, 4) \
83     macro(op_rshift, 4) \
84     macro(op_urshift, 4) \
85     macro(op_unsigned, 3) \
86     macro(op_bitand, 5) \
87     macro(op_bitxor, 5) \
88     macro(op_bitor, 5) \
89     \
90     macro(op_check_has_instance, 5) \
91     macro(op_instanceof, 4) \
92     macro(op_typeof, 3) \
93     macro(op_is_undefined, 3) \
94     macro(op_is_boolean, 3) \
95     macro(op_is_number, 3) \
96     macro(op_is_string, 3) \
97     macro(op_is_object, 3) \
98     macro(op_is_function, 3) \
99     macro(op_in, 4) \
100     \
101     macro(op_init_global_const_nop, 5) \
102     macro(op_init_global_const, 5) \
103     macro(op_get_by_id, 9) /* has value profiling */ \
104     macro(op_get_by_id_out_of_line, 9) /* has value profiling */ \
105     macro(op_get_array_length, 9) /* has value profiling */ \
106     macro(op_get_arguments_length, 4) \
107     macro(op_put_by_id, 9) \
108     macro(op_put_by_id_out_of_line, 9) \
109     macro(op_put_by_id_transition_direct, 9) \
110     macro(op_put_by_id_transition_direct_out_of_line, 9) \
111     macro(op_put_by_id_transition_normal, 9) \
112     macro(op_put_by_id_transition_normal_out_of_line, 9) \
113     macro(op_del_by_id, 4) \
114     macro(op_get_by_val, 6) /* has value profiling */ \
115     macro(op_get_argument_by_val, 6) /* must be the same size as op_get_by_val */ \
116     macro(op_get_by_pname, 7) \
117     macro(op_put_by_val, 5) \
118     macro(op_put_by_val_direct, 5) \
119     macro(op_del_by_val, 4) \
120     macro(op_put_by_index, 4) \
121     macro(op_put_getter_setter, 5) \
122     \
123     macro(op_jmp, 2) \
124     macro(op_jtrue, 3) \
125     macro(op_jfalse, 3) \
126     macro(op_jeq_null, 3) \
127     macro(op_jneq_null, 3) \
128     macro(op_jneq_ptr, 4) \
129     macro(op_jless, 4) \
130     macro(op_jlesseq, 4) \
131     macro(op_jgreater, 4) \
132     macro(op_jgreatereq, 4) \
133     macro(op_jnless, 4) \
134     macro(op_jnlesseq, 4) \
135     macro(op_jngreater, 4) \
136     macro(op_jngreatereq, 4) \
137     \
138     macro(op_loop_hint, 1) \
139     \
140     macro(op_switch_imm, 4) \
141     macro(op_switch_char, 4) \
142     macro(op_switch_string, 4) \
143     \
144     macro(op_new_func, 4) \
145     macro(op_new_captured_func, 4) \
146     macro(op_new_func_exp, 3) \
147     macro(op_call, 9) /* has value profiling */ \
148     macro(op_call_eval, 9) /* has value profiling */ \
149     macro(op_call_varargs, 9) /* has value profiling */ \
150     macro(op_tear_off_activation, 2) \
151     macro(op_tear_off_arguments, 3) \
152     macro(op_ret, 2) \
153     macro(op_ret_object_or_this, 3) \
154     \
155     macro(op_construct, 9) \
156     macro(op_strcat, 4) \
157     macro(op_to_primitive, 3) \
158     \
159     macro(op_get_pnames, 6) \
160     macro(op_next_pname, 7) \
161     \
162     macro(op_resolve_scope, 6) \
163     macro(op_get_from_scope, 8) /* has value profiling */ \
164     macro(op_put_to_scope, 7) \
165     \
166     macro(op_push_with_scope, 2) \
167     macro(op_pop_scope, 1) \
168     macro(op_push_name_scope, 4) \
169     \
170     macro(op_catch, 2) \
171     macro(op_throw, 2) \
172     macro(op_throw_static_error, 3) \
173     \
174     macro(op_debug, 3) \
175     macro(op_profile_will_call, 2) \
176     macro(op_profile_did_call, 2) \
177     \
178     extension__ \
179     \
180     macro(op_end, 2) // end must be the last opcode in the list
181
182 #define FOR_EACH_CORE_OPCODE_ID(macro) \
183     FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION(macro, /* No extension */ )
184
185 #define FOR_EACH_OPCODE_ID(macro) \
186     FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION( \
187         macro, \
188         FOR_EACH_LLINT_OPCODE_EXTENSION(macro) \
189     )
190
191
192 #define OPCODE_ID_ENUM(opcode, length) opcode,
193     typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
194 #undef OPCODE_ID_ENUM
195
196 const int maxOpcodeLength = 9;
197 const int numOpcodeIDs = op_end + 1;
198
199 #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
200     FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTHS);
201 #undef OPCODE_ID_LENGTHS
202
203 #define OPCODE_LENGTH(opcode) opcode##_length
204
205 #define OPCODE_ID_LENGTH_MAP(opcode, length) length,
206     const int opcodeLengths[numOpcodeIDs] = { FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTH_MAP) };
207 #undef OPCODE_ID_LENGTH_MAP
208
209 #define VERIFY_OPCODE_ID(id, size) COMPILE_ASSERT(id <= op_end, ASSERT_THAT_JS_OPCODE_IDS_ARE_VALID);
210     FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
211 #undef VERIFY_OPCODE_ID
212
213 #if ENABLE(COMPUTED_GOTO_OPCODES)
214 typedef void* Opcode;
215 #else
216 typedef OpcodeID Opcode;
217 #endif
218
219 #define PADDING_STRING "                                "
220 #define PADDING_STRING_LENGTH static_cast<unsigned>(strlen(PADDING_STRING))
221
222 extern const char* const opcodeNames[];
223
224 inline const char* padOpcodeName(OpcodeID op, unsigned width)
225 {
226     unsigned pad = width - strlen(opcodeNames[op]);
227     pad = std::min(pad, PADDING_STRING_LENGTH);
228     return PADDING_STRING + PADDING_STRING_LENGTH - pad;
229 }
230
231 #undef PADDING_STRING_LENGTH
232 #undef PADDING_STRING
233
234 #if ENABLE(OPCODE_STATS)
235
236 struct OpcodeStats {
237     OpcodeStats();
238     ~OpcodeStats();
239     static long long opcodeCounts[numOpcodeIDs];
240     static long long opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
241     static int lastOpcode;
242     
243     static void recordInstruction(int opcode);
244     static void resetLastInstruction();
245 };
246
247 #endif
248
249 inline size_t opcodeLength(OpcodeID opcode)
250 {
251     switch (opcode) {
252 #define OPCODE_ID_LENGTHS(id, length) case id: return OPCODE_LENGTH(id);
253          FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTHS)
254 #undef OPCODE_ID_LENGTHS
255     }
256     RELEASE_ASSERT_NOT_REACHED();
257     return 0;
258 }
259
260 } // namespace JSC
261
262 #endif // Opcode_h