• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef JITStubs_h
30 #define JITStubs_h
31 
32 #include <wtf/Platform.h>
33 
34 #include "MacroAssemblerCodeRef.h"
35 #include "Register.h"
36 
37 #if ENABLE(JIT)
38 
39 namespace JSC {
40 
41     struct StructureStubInfo;
42 
43     class CodeBlock;
44     class ExecutablePool;
45     class Identifier;
46     class JSGlobalData;
47     class JSGlobalData;
48     class JSObject;
49     class JSPropertyNameIterator;
50     class JSValue;
51     class JSValueEncodedAsPointer;
52     class Profiler;
53     class PropertySlot;
54     class PutPropertySlot;
55     class RegisterFile;
56     class FuncDeclNode;
57     class FuncExprNode;
58     class JSGlobalObject;
59     class RegExp;
60 
61     union JITStubArg {
62         void* asPointer;
63         EncodedJSValue asEncodedJSValue;
64         int32_t asInt32;
65 
jsValue()66         JSValue jsValue() { return JSValue::decode(asEncodedJSValue); }
identifier()67         Identifier& identifier() { return *static_cast<Identifier*>(asPointer); }
int32()68         int32_t int32() { return asInt32; }
codeBlock()69         CodeBlock* codeBlock() { return static_cast<CodeBlock*>(asPointer); }
funcDeclNode()70         FuncDeclNode* funcDeclNode() { return static_cast<FuncDeclNode*>(asPointer); }
funcExprNode()71         FuncExprNode* funcExprNode() { return static_cast<FuncExprNode*>(asPointer); }
regExp()72         RegExp* regExp() { return static_cast<RegExp*>(asPointer); }
propertyNameIterator()73         JSPropertyNameIterator* propertyNameIterator() { return static_cast<JSPropertyNameIterator*>(asPointer); }
globalObject()74         JSGlobalObject* globalObject() { return static_cast<JSGlobalObject*>(asPointer); }
jsString()75         JSString* jsString() { return static_cast<JSString*>(asPointer); }
returnAddress()76         ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); }
77     };
78 
79 #if PLATFORM(X86_64)
80     struct JITStackFrame {
81         void* reserved; // Unused
82         JITStubArg args[6];
83         void* padding[2]; // Maintain 32-byte stack alignment (possibly overkill).
84 
85         void* code;
86         RegisterFile* registerFile;
87         CallFrame* callFrame;
88         JSValue* exception;
89         Profiler** enabledProfilerReference;
90         JSGlobalData* globalData;
91 
92         void* savedRBX;
93         void* savedR15;
94         void* savedR14;
95         void* savedR13;
96         void* savedR12;
97         void* savedRBP;
98         void* savedRIP;
99 
100         // When JIT code makes a call, it pushes its return address just below the rest of the stack.
returnAddressSlotJITStackFrame101         ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
102     };
103 #elif PLATFORM(X86)
104 #if COMPILER(MSVC)
105 #pragma pack(push)
106 #pragma pack(4)
107 #endif // COMPILER(MSVC)
108     struct JITStackFrame {
109         void* reserved; // Unused
110         JITStubArg args[6];
111 #if USE(JSVALUE32_64)
112         void* padding[2]; // Maintain 16-byte stack alignment.
113 #endif
114 
115         void* savedEBX;
116         void* savedEDI;
117         void* savedESI;
118         void* savedEBP;
119         void* savedEIP;
120 
121         void* code;
122         RegisterFile* registerFile;
123         CallFrame* callFrame;
124         JSValue* exception;
125         Profiler** enabledProfilerReference;
126         JSGlobalData* globalData;
127 
128         // When JIT code makes a call, it pushes its return address just below the rest of the stack.
returnAddressSlotJITStackFrame129         ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
130     };
131 #if COMPILER(MSVC)
132 #pragma pack(pop)
133 #endif // COMPILER(MSVC)
134 #elif PLATFORM_ARM_ARCH(7)
135     struct JITStackFrame {
136         void* reserved; // Unused
137         JITStubArg args[6];
138 #if USE(JSVALUE32_64)
139         void* padding[2]; // Maintain 16-byte stack alignment.
140 #endif
141 
142         ReturnAddressPtr thunkReturnAddress;
143 
144         void* preservedReturnAddress;
145         void* preservedR4;
146         void* preservedR5;
147         void* preservedR6;
148 
149         // These arguments passed in r1..r3 (r0 contained the entry code pointed, which is not preserved)
150         RegisterFile* registerFile;
151         CallFrame* callFrame;
152         JSValue* exception;
153 
154         // These arguments passed on the stack.
155         Profiler** enabledProfilerReference;
156         JSGlobalData* globalData;
157 
returnAddressSlotJITStackFrame158         ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
159     };
160 #elif PLATFORM(ARM)
161     struct JITStackFrame {
162         JITStubArg padding; // Unused
163         JITStubArg args[7];
164 
165         void* preservedR4;
166         void* preservedR5;
167         void* preservedR6;
168         void* preservedR7;
169         void* preservedR8;
170         void* preservedLink;
171 
172         RegisterFile* registerFile;
173         CallFrame* callFrame;
174         JSValue* exception;
175         Profiler** enabledProfilerReference;
176         JSGlobalData* globalData;
177 
178         // When JIT code makes a call, it pushes its return address just below the rest of the stack.
returnAddressSlotJITStackFrame179         ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
180     };
181 #else
182 #error "JITStackFrame not defined for this platform."
183 #endif
184 
185 #if USE(JIT_STUB_ARGUMENT_VA_LIST)
186     #define STUB_ARGS_DECLARATION void* args, ...
187     #define STUB_ARGS (reinterpret_cast<void**>(vl_args) - 1)
188 
189     #if COMPILER(MSVC)
190     #define JIT_STUB __cdecl
191     #else
192     #define JIT_STUB
193     #endif
194 #else
195     #define STUB_ARGS_DECLARATION void** args
196     #define STUB_ARGS (args)
197 
198     #if PLATFORM(X86) && COMPILER(MSVC)
199     #define JIT_STUB __fastcall
200     #elif PLATFORM(X86) && COMPILER(GCC)
201     #define JIT_STUB  __attribute__ ((fastcall))
202     #else
203     #define JIT_STUB
204     #endif
205 #endif
206 
207 #if PLATFORM(X86_64)
208     struct VoidPtrPair {
209         void* first;
210         void* second;
211     };
212     #define RETURN_POINTER_PAIR(a,b) VoidPtrPair pair = { a, b }; return pair
213 #else
214     // MSVC doesn't support returning a two-value struct in two registers, so
215     // we cast the struct to int64_t instead.
216     typedef uint64_t VoidPtrPair;
217     union VoidPtrPairUnion {
218         struct { void* first; void* second; } s;
219         VoidPtrPair i;
220     };
221     #define RETURN_POINTER_PAIR(a,b) VoidPtrPairUnion pair = {{ a, b }}; return pair.i
222 #endif
223 
224     extern "C" void ctiVMThrowTrampoline();
225     extern "C" void ctiOpThrowNotCaught();
226     extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*);
227 
228     class JITThunks {
229     public:
230         JITThunks(JSGlobalData*);
231 
232         static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&, StructureStubInfo* stubInfo);
233         static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo);
234 
ctiStringLengthTrampoline()235         MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_ctiStringLengthTrampoline; }
ctiVirtualCallLink()236         MacroAssemblerCodePtr ctiVirtualCallLink() { return m_ctiVirtualCallLink; }
ctiVirtualCall()237         MacroAssemblerCodePtr ctiVirtualCall() { return m_ctiVirtualCall; }
ctiNativeCallThunk()238         MacroAssemblerCodePtr ctiNativeCallThunk() { return m_ctiNativeCallThunk; }
239 
240     private:
241         RefPtr<ExecutablePool> m_executablePool;
242 
243         MacroAssemblerCodePtr m_ctiStringLengthTrampoline;
244         MacroAssemblerCodePtr m_ctiVirtualCallLink;
245         MacroAssemblerCodePtr m_ctiVirtualCall;
246         MacroAssemblerCodePtr m_ctiNativeCallThunk;
247     };
248 
249 extern "C" {
250     EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION);
251     EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION);
252     EncodedJSValue JIT_STUB cti_op_bitnot(STUB_ARGS_DECLARATION);
253     EncodedJSValue JIT_STUB cti_op_bitor(STUB_ARGS_DECLARATION);
254     EncodedJSValue JIT_STUB cti_op_bitxor(STUB_ARGS_DECLARATION);
255     EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION);
256     EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION);
257     EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION);
258     EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION);
259     EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION);
260     EncodedJSValue JIT_STUB cti_op_del_by_val(STUB_ARGS_DECLARATION);
261     EncodedJSValue JIT_STUB cti_op_div(STUB_ARGS_DECLARATION);
262     EncodedJSValue JIT_STUB cti_op_get_by_id(STUB_ARGS_DECLARATION);
263     EncodedJSValue JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS_DECLARATION);
264     EncodedJSValue JIT_STUB cti_op_get_by_id_generic(STUB_ARGS_DECLARATION);
265     EncodedJSValue JIT_STUB cti_op_get_by_id_method_check(STUB_ARGS_DECLARATION);
266     EncodedJSValue JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION);
267     EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS_DECLARATION);
268     EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION);
269     EncodedJSValue JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION);
270     EncodedJSValue JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION);
271     EncodedJSValue JIT_STUB cti_op_get_by_val(STUB_ARGS_DECLARATION);
272     EncodedJSValue JIT_STUB cti_op_get_by_val_byte_array(STUB_ARGS_DECLARATION);
273     EncodedJSValue JIT_STUB cti_op_get_by_val_string(STUB_ARGS_DECLARATION);
274     EncodedJSValue JIT_STUB cti_op_in(STUB_ARGS_DECLARATION);
275     EncodedJSValue JIT_STUB cti_op_instanceof(STUB_ARGS_DECLARATION);
276     EncodedJSValue JIT_STUB cti_op_is_boolean(STUB_ARGS_DECLARATION);
277     EncodedJSValue JIT_STUB cti_op_is_function(STUB_ARGS_DECLARATION);
278     EncodedJSValue JIT_STUB cti_op_is_number(STUB_ARGS_DECLARATION);
279     EncodedJSValue JIT_STUB cti_op_is_object(STUB_ARGS_DECLARATION);
280     EncodedJSValue JIT_STUB cti_op_is_string(STUB_ARGS_DECLARATION);
281     EncodedJSValue JIT_STUB cti_op_is_undefined(STUB_ARGS_DECLARATION);
282     EncodedJSValue JIT_STUB cti_op_less(STUB_ARGS_DECLARATION);
283     EncodedJSValue JIT_STUB cti_op_lesseq(STUB_ARGS_DECLARATION);
284     EncodedJSValue JIT_STUB cti_op_lshift(STUB_ARGS_DECLARATION);
285     EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION);
286     EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION);
287     EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION);
288     EncodedJSValue JIT_STUB cti_op_next_pname(STUB_ARGS_DECLARATION);
289     EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION);
290     EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION);
291     EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION);
292     EncodedJSValue JIT_STUB cti_op_post_inc(STUB_ARGS_DECLARATION);
293     EncodedJSValue JIT_STUB cti_op_pre_dec(STUB_ARGS_DECLARATION);
294     EncodedJSValue JIT_STUB cti_op_pre_inc(STUB_ARGS_DECLARATION);
295     EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION);
296     EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION);
297     EncodedJSValue JIT_STUB cti_op_resolve_global(STUB_ARGS_DECLARATION);
298     EncodedJSValue JIT_STUB cti_op_resolve_skip(STUB_ARGS_DECLARATION);
299     EncodedJSValue JIT_STUB cti_op_resolve_with_base(STUB_ARGS_DECLARATION);
300     EncodedJSValue JIT_STUB cti_op_rshift(STUB_ARGS_DECLARATION);
301     EncodedJSValue JIT_STUB cti_op_strcat(STUB_ARGS_DECLARATION);
302     EncodedJSValue JIT_STUB cti_op_stricteq(STUB_ARGS_DECLARATION);
303     EncodedJSValue JIT_STUB cti_op_sub(STUB_ARGS_DECLARATION);
304     EncodedJSValue JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION);
305     EncodedJSValue JIT_STUB cti_op_to_jsnumber(STUB_ARGS_DECLARATION);
306     EncodedJSValue JIT_STUB cti_op_to_primitive(STUB_ARGS_DECLARATION);
307     EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION);
308     EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION);
309     EncodedJSValue JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION);
310     JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS_DECLARATION);
311     JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION);
312     JSObject* JIT_STUB cti_op_new_error(STUB_ARGS_DECLARATION);
313     JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION);
314     JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION);
315     JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION);
316     JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION);
317     JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION);
318     JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION);
319     JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS_DECLARATION);
320     JSObject* JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION);
321     JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION);
322     VoidPtrPair JIT_STUB cti_op_call_arityCheck(STUB_ARGS_DECLARATION);
323     int JIT_STUB cti_op_eq(STUB_ARGS_DECLARATION);
324 #if USE(JSVALUE32_64)
325     int JIT_STUB cti_op_eq_strings(STUB_ARGS_DECLARATION);
326 #endif
327     int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION);
328     int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION);
329     int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION);
330     int JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION);
331     int JIT_STUB cti_op_loop_if_less(STUB_ARGS_DECLARATION);
332     int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS_DECLARATION);
333     int JIT_STUB cti_op_loop_if_true(STUB_ARGS_DECLARATION);
334     int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION);
335     void JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION);
336     void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION);
337     void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION);
338     void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION);
339     void JIT_STUB cti_op_jmp_scopes(STUB_ARGS_DECLARATION);
340     void JIT_STUB cti_op_pop_scope(STUB_ARGS_DECLARATION);
341     void JIT_STUB cti_op_profile_did_call(STUB_ARGS_DECLARATION);
342     void JIT_STUB cti_op_profile_will_call(STUB_ARGS_DECLARATION);
343     void JIT_STUB cti_op_put_by_id(STUB_ARGS_DECLARATION);
344     void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION);
345     void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION);
346     void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION);
347     void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION);
348     void JIT_STUB cti_op_put_by_val_array(STUB_ARGS_DECLARATION);
349     void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS_DECLARATION);
350     void JIT_STUB cti_op_put_getter(STUB_ARGS_DECLARATION);
351     void JIT_STUB cti_op_put_setter(STUB_ARGS_DECLARATION);
352     void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS_DECLARATION);
353     void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION);
354     void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION);
355     void JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION);
356     void* JIT_STUB cti_op_call_JSFunction(STUB_ARGS_DECLARATION);
357     void* JIT_STUB cti_op_switch_char(STUB_ARGS_DECLARATION);
358     void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION);
359     void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION);
360     void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION);
361 } // extern "C"
362 
363 } // namespace JSC
364 
365 #endif // ENABLE(JIT)
366 
367 #endif // JITStubs_h
368