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
17 * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
20 * The Initial Developer of the Original Code is
21 * Brendan Eich <brendan@mozilla.org>
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
44 #include "assembler/assembler/MacroAssemblerCodeRef.h"
46 #if !defined JS_CPU_X64 && \
47 !defined JS_CPU_X86 && \
49 # error "Oh no, you should define a platform so this compiles."
52 #if !defined(JS_NUNBOX32) && !defined(JS_PUNBOX64)
53 # error "No boxing format selected."
73 JSStackFrame
*entryFp
;
75 #if defined(JS_CPU_X86)
82 # ifdef JS_NO_FASTCALL
83 inline void** returnAddressLocation() {
84 return reinterpret_cast<void**>(this) - 3;
87 inline void** returnAddressLocation() {
88 return reinterpret_cast<void**>(this) - 1;
91 #elif defined(JS_CPU_X64)
105 inline void** returnAddressLocation() {
106 return reinterpret_cast<void**>(this) - 5;
109 inline void** returnAddressLocation() {
110 return reinterpret_cast<void**>(this) - 1;
114 #elif defined(JS_CPU_ARM)
125 inline void** returnAddressLocation() {
126 return reinterpret_cast<void**>(this) - 1;
129 # error "The VMFrame layout isn't defined for your processor architecture!"
132 JSRuntime
*runtime() { return cx
->runtime
; }
134 JSStackFrame
*&fp() { return regs
.fp
; }
138 // WARNING: Do not call this function directly from C(++) code because it is not ABI-compliant.
139 extern "C" void JaegerStubVeneer(void);
144 # if defined JS_POLYIC
148 # if defined JS_MONOIC
150 struct EqualityICInfo
;
157 typedef void (JS_FASTCALL
*VoidStub
)(VMFrame
&);
158 typedef void (JS_FASTCALL
*VoidVpStub
)(VMFrame
&, Value
*);
159 typedef void (JS_FASTCALL
*VoidStubUInt32
)(VMFrame
&, uint32
);
160 typedef void (JS_FASTCALL
*VoidStubInt32
)(VMFrame
&, int32
);
161 typedef JSBool (JS_FASTCALL
*BoolStub
)(VMFrame
&);
162 typedef void * (JS_FASTCALL
*VoidPtrStub
)(VMFrame
&);
163 typedef void * (JS_FASTCALL
*VoidPtrStubPC
)(VMFrame
&, jsbytecode
*);
164 typedef void * (JS_FASTCALL
*VoidPtrStubUInt32
)(VMFrame
&, uint32
);
165 typedef JSObject
* (JS_FASTCALL
*JSObjStub
)(VMFrame
&);
166 typedef JSObject
* (JS_FASTCALL
*JSObjStubUInt32
)(VMFrame
&, uint32
);
167 typedef JSObject
* (JS_FASTCALL
*JSObjStubFun
)(VMFrame
&, JSFunction
*);
168 typedef void (JS_FASTCALL
*VoidStubFun
)(VMFrame
&, JSFunction
*);
169 typedef JSObject
* (JS_FASTCALL
*JSObjStubJSObj
)(VMFrame
&, JSObject
*);
170 typedef void (JS_FASTCALL
*VoidStubAtom
)(VMFrame
&, JSAtom
*);
171 typedef JSString
* (JS_FASTCALL
*JSStrStub
)(VMFrame
&);
172 typedef JSString
* (JS_FASTCALL
*JSStrStubUInt32
)(VMFrame
&, uint32
);
173 typedef void (JS_FASTCALL
*VoidStubJSObj
)(VMFrame
&, JSObject
*);
174 typedef void (JS_FASTCALL
*VoidStubPC
)(VMFrame
&, jsbytecode
*);
175 typedef JSBool (JS_FASTCALL
*BoolStubUInt32
)(VMFrame
&f
, uint32
);
177 typedef void (JS_FASTCALL
*VoidStubCallIC
)(VMFrame
&, js::mjit::ic::CallICInfo
*);
178 typedef void * (JS_FASTCALL
*VoidPtrStubCallIC
)(VMFrame
&, js::mjit::ic::CallICInfo
*);
179 typedef void (JS_FASTCALL
*VoidStubMIC
)(VMFrame
&, js::mjit::ic::MICInfo
*);
180 typedef void * (JS_FASTCALL
*VoidPtrStubMIC
)(VMFrame
&, js::mjit::ic::MICInfo
*);
181 typedef JSBool (JS_FASTCALL
*BoolStubEqualityIC
)(VMFrame
&, js::mjit::ic::EqualityICInfo
*);
182 typedef void * (JS_FASTCALL
*VoidPtrStubTraceIC
)(VMFrame
&, js::mjit::ic::TraceICInfo
*);
185 typedef void (JS_FASTCALL
*VoidStubPIC
)(VMFrame
&, js::mjit::ic::PICInfo
*);
186 typedef void (JS_FASTCALL
*VoidStubGetElemIC
)(VMFrame
&, js::mjit::ic::GetElementIC
*);
194 typedef JSC::MacroAssemblerCodeRef CodeRef
;
195 CodeRef code
; /* pool & code addresses */
196 void **nmap
; /* pc -> JIT code map, sparse */
198 js::mjit::CallSite
*callSites
;
201 ic::MICInfo
*mics
; /* MICs in this script. */
202 uint32 nMICs
; /* number of MonoICs */
203 ic::CallICInfo
*callICs
; /* CallICs in this script. */
204 uint32 nCallICs
; /* number of call ICs */
205 ic::EqualityICInfo
*equalityICs
;
207 ic::TraceICInfo
*traceICs
;
210 // Additional ExecutablePools that IC stubs were generated into.
211 typedef Vector
<JSC::ExecutablePool
*, 0, SystemAllocPolicy
> ExecPoolVector
;
212 ExecPoolVector execPools
;
215 ic::PICInfo
*pics
; /* PICs in this script */
216 uint32 nPICs
; /* number of PolyICs */
217 ic::GetElementIC
*getElems
;
220 void *invokeEntry
; /* invoke address */
221 void *fastEntry
; /* cached entry, fastest */
222 void *arityCheckEntry
; /* arity check address */
224 bool isValidCode(void *ptr
) {
225 char *jitcode
= (char *)code
.m_code
.executableAddress();
226 char *jcheck
= (char *)ptr
;
227 return jcheck
>= jitcode
&& jcheck
< jitcode
+ code
.m_size
;
237 * Execute the given mjit code. This is a low-level call and callers must
238 * provide the same guarantees as JaegerShot/CheckStackAndEnterMethodJIT.
240 JSBool
EnterMethodJIT(JSContext
*cx
, JSStackFrame
*fp
, void *code
, Value
*stackLimit
);
242 /* Execute a method that has been JIT compiled. */
243 JSBool
JaegerShot(JSContext
*cx
);
245 /* Drop into the middle of a method at an arbitrary point, and execute. */
246 JSBool
JaegerShotAtSafePoint(JSContext
*cx
, void *safePoint
);
256 ProfileStubCall(VMFrame
&f
);
258 CompileStatus JS_NEVER_INLINE
259 TryCompile(JSContext
*cx
, JSStackFrame
*fp
);
262 ReleaseScriptCode(JSContext
*cx
, JSScript
*script
);
264 static inline CompileStatus
265 CanMethodJIT(JSContext
*cx
, JSScript
*script
, JSStackFrame
*fp
)
267 if (!cx
->methodJitEnabled
)
268 return Compile_Abort
;
269 JITScriptStatus status
= script
->getJITStatus(fp
->isConstructing());
270 if (status
== JITScript_Invalid
)
271 return Compile_Abort
;
272 if (status
== JITScript_None
)
273 return TryCompile(cx
, fp
);
284 /* Re-enables a tracepoint in the method JIT. */
286 EnableTraceHint(JSScript
*script
, jsbytecode
*pc
, uint16_t index
);
289 GetCallTargetCount(JSScript
*script
, jsbytecode
*pc
);
291 } /* namespace mjit */
296 JSScript::maybeNativeCodeForPC(bool constructing
, jsbytecode
*pc
)
298 js::mjit::JITScript
*jit
= getJIT(constructing
);
301 JS_ASSERT(pc
>= code
&& pc
< code
+ length
);
302 return jit
->nmap
[pc
- code
];
306 JSScript::nativeMap(bool constructing
)
308 return getJIT(constructing
)->nmap
;
312 JSScript::nativeCodeForPC(bool constructing
, jsbytecode
*pc
)
314 void **nmap
= nativeMap(constructing
);
315 JS_ASSERT(pc
>= code
&& pc
< code
+ length
);
316 JS_ASSERT(nmap
[pc
- code
]);
317 return nmap
[pc
- code
];
321 extern "C" void *JaegerThrowpoline(js::VMFrame
*vmFrame
);
323 extern "C" void JaegerThrowpoline();
325 extern "C" void InjectJaegerReturn();
327 #endif /* jsjaeger_h__ */