ICs for scripted calls (bug 587698, r=dmandelin).
[mozilla-central.git] / js / src / methodjit / MethodJIT.h
blobb61e2d6075f83aed0b42efc430efda6e47ee53e1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=4 sw=4 et tw=99:
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
17 * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
18 * May 28, 2008.
20 * The Initial Developer of the Original Code is
21 * Brendan Eich <brendan@mozilla.org>
23 * Contributor(s):
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #if !defined jsjaeger_h__ && defined JS_METHODJIT
40 #define jsjaeger_h__
42 #include "jscntxt.h"
44 #include "assembler/assembler/MacroAssemblerCodeRef.h"
46 #if !defined JS_CPU_X64 && \
47 !defined JS_CPU_X86 && \
48 !defined JS_CPU_ARM
49 # error "Oh no, you should define a platform so this compiles."
50 #endif
52 #if !defined(JS_NUNBOX32) && !defined(JS_PUNBOX64)
53 # error "No boxing format selected."
54 #endif
56 namespace js {
58 struct VMFrame
60 union Arguments {
61 struct {
62 void *ptr;
63 void *ptr2;
64 void *ptr3;
65 } x;
66 } u;
68 VMFrame *previous;
69 JSFrameRegs *oldRegs;
70 JSFrameRegs regs;
71 JSContext *cx;
72 Value *stackLimit;
73 JSStackFrame *entryFp;
75 #if defined(JS_CPU_X86)
76 void *savedEBX;
77 void *savedEDI;
78 void *savedESI;
79 void *savedEBP;
80 void *savedEIP;
82 # ifdef JS_NO_FASTCALL
83 inline void** returnAddressLocation() {
84 return reinterpret_cast<void**>(this) - 3;
86 # else
87 inline void** returnAddressLocation() {
88 return reinterpret_cast<void**>(this) - 1;
90 # endif
91 #elif defined(JS_CPU_X64)
92 void *savedRBX;
93 # ifdef _WIN64
94 void *savedRSI;
95 void *savedRDI;
96 # endif
97 void *savedR15;
98 void *savedR14;
99 void *savedR13;
100 void *savedR12;
101 void *savedRBP;
102 void *savedRIP;
104 # ifdef _WIN64
105 inline void** returnAddressLocation() {
106 return reinterpret_cast<void**>(this) - 5;
108 # else
109 inline void** returnAddressLocation() {
110 return reinterpret_cast<void**>(this) - 1;
112 # endif
114 #elif defined(JS_CPU_ARM)
115 void *savedR4;
116 void *savedR5;
117 void *savedR6;
118 void *savedR7;
119 void *savedR8;
120 void *savedR9;
121 void *savedR10;
122 void *savedR11;
123 void *savedLR;
125 inline void** returnAddressLocation() {
126 return reinterpret_cast<void**>(this) - 1;
128 #else
129 # error "The VMFrame layout isn't defined for your processor architecture!"
130 #endif
132 JSRuntime *runtime() { return cx->runtime; }
134 JSStackFrame *&fp() { return regs.fp; }
136 bool slowEnsureSpace(uint32 nslots);
138 bool ensureSpace(uint32 nmissing, uint32 nslots) {
139 /* Fast check - if it's below the limit, it's safe to just get a frame. */
140 if (JS_LIKELY(regs.sp + VALUES_PER_STACK_FRAME + nmissing + nslots < stackLimit))
141 return true;
143 /* Slower check that might have to commit memory or throw an error. */
144 return slowEnsureSpace(nmissing + nslots);
148 #ifdef JS_CPU_ARM
149 // WARNING: Do not call this function directly from C(++) code because it is not ABI-compliant.
150 extern "C" void JaegerStubVeneer(void);
151 #endif
153 typedef void (JS_FASTCALL *VoidStub)(VMFrame &);
154 typedef void (JS_FASTCALL *VoidVpStub)(VMFrame &, Value *);
155 typedef void (JS_FASTCALL *VoidStubUInt32)(VMFrame &, uint32);
156 typedef void (JS_FASTCALL *VoidStubInt32)(VMFrame &, int32);
157 typedef JSBool (JS_FASTCALL *BoolStub)(VMFrame &);
158 typedef void * (JS_FASTCALL *VoidPtrStub)(VMFrame &);
159 typedef void * (JS_FASTCALL *VoidPtrStubPC)(VMFrame &, jsbytecode *);
160 typedef void * (JS_FASTCALL *VoidPtrStubUInt32)(VMFrame &, uint32);
161 typedef JSObject * (JS_FASTCALL *JSObjStub)(VMFrame &);
162 typedef JSObject * (JS_FASTCALL *JSObjStubUInt32)(VMFrame &, uint32);
163 typedef JSObject * (JS_FASTCALL *JSObjStubFun)(VMFrame &, JSFunction *);
164 typedef JSObject * (JS_FASTCALL *JSObjStubJSObj)(VMFrame &, JSObject *);
165 typedef void (JS_FASTCALL *VoidStubAtom)(VMFrame &, JSAtom *);
166 typedef JSString * (JS_FASTCALL *JSStrStub)(VMFrame &);
167 typedef JSString * (JS_FASTCALL *JSStrStubUInt32)(VMFrame &, uint32);
168 typedef void (JS_FASTCALL *VoidStubJSObj)(VMFrame &, JSObject *);
169 typedef void (JS_FASTCALL *VoidStubPC)(VMFrame &, jsbytecode *);
170 typedef JSBool (JS_FASTCALL *BoolStubUInt32)(VMFrame &f, uint32);
172 #define JS_UNJITTABLE_METHOD (reinterpret_cast<void*>(1))
174 namespace mjit {
176 struct JITScript {
177 JSC::ExecutablePool *execPool; /* pool that contains |ncode|; script owns the pool */
178 uint32 inlineLength; /* length of inline JIT'd code */
179 uint32 outOfLineLength; /* length of out of line JIT'd code */
180 js::mjit::CallSite *callSites;
181 uint32 nCallSites;
182 #ifdef JS_MONOIC
183 uint32 nMICs; /* number of MonoICs */
184 uint32 nCallICs; /* number of call ICs */
185 #endif
186 #ifdef JS_POLYIC
187 uint32 nPICs; /* number of PolyICs */
188 #endif
189 void *invoke; /* invoke address */
190 void *arityCheck; /* arity check address */
191 uint32 *escaping; /* list of escaping slots */
192 uint32 nescaping; /* number of escaping slots */
195 /* Execute a method that has been JIT compiled. */
196 JSBool JaegerShot(JSContext *cx);
198 /* Drop into the middle of a method at an arbitrary point, and execute. */
199 JSBool JaegerShotAtSafePoint(JSContext *cx, void *safePoint);
201 enum CompileStatus
203 Compile_Okay,
204 Compile_Abort,
205 Compile_Error
208 void JS_FASTCALL
209 ProfileStubCall(VMFrame &f);
211 CompileStatus
212 TryCompile(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *scopeChain);
214 void
215 ReleaseScriptCode(JSContext *cx, JSScript *script);
217 void
218 SweepCallICs(JSContext *cx);
220 static inline CompileStatus
221 CanMethodJIT(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *scopeChain)
223 if (!(cx->options & JSOPTION_METHODJIT) || script->ncode == JS_UNJITTABLE_METHOD)
224 return Compile_Abort;
225 if (script->ncode == NULL)
226 return TryCompile(cx, script, fun, scopeChain);
227 return Compile_Okay;
230 struct CallSite
232 uint32 codeOffset;
233 uint32 pcOffset;
234 uint32 id;
237 } /* namespace mjit */
239 } /* namespace js */
241 #ifdef _MSC_VER
242 extern "C" void *JaegerThrowpoline(js::VMFrame *vmFrame);
243 #else
244 extern "C" void JaegerThrowpoline();
245 #endif
246 extern "C" void InjectJaegerReturn();
248 #endif /* jsjaeger_h__ */