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>
24 * David Anderson <danderson@mozilla.com>
25 * David Mandelin <dmandelin@mozilla.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
40 #if !defined jsjaeger_compiler_h__ && defined JS_METHODJIT
41 #define jsjaeger_compiler_h__
45 #include "BytecodeAnalyzer.h"
46 #include "MethodJIT.h"
47 #include "CodeGenIncludes.h"
48 #include "StubCompiler.h"
57 typedef JSC::MacroAssembler::Label Label
;
58 typedef JSC::MacroAssembler::Imm32 Imm32
;
59 typedef JSC::MacroAssembler::ImmPtr ImmPtr
;
60 typedef JSC::MacroAssembler::RegisterID RegisterID
;
61 typedef JSC::MacroAssembler::FPRegisterID FPRegisterID
;
62 typedef JSC::MacroAssembler::Address Address
;
63 typedef JSC::MacroAssembler::BaseIndex BaseIndex
;
64 typedef JSC::MacroAssembler::Jump Jump
;
65 typedef JSC::MacroAssembler::Call Call
;
66 typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr
;
69 BranchPatch(const Jump
&j
, jsbytecode
*pc
)
79 MICGenInfo(ic::MICInfo::Kind kind
) : kind(kind
)
83 DataLabelPtr shapeVal
;
86 ic::MICInfo::Kind kind
;
87 jsbytecode
*jumpTarget
;
102 #if defined JS_POLYIC
104 PICGenInfo(ic::PICInfo::Kind kind
) : kind(kind
)
106 ic::PICInfo::Kind kind
;
123 void copySimpleMembersTo(ic::PICInfo
&pi
) const {
125 pi
.shapeReg
= shapeReg
;
128 if (kind
== ic::PICInfo::SET
) {
130 } else if (kind
!= ic::PICInfo::NAME
) {
131 pi
.u
.get
.idReg
= idReg
;
132 pi
.u
.get
.typeReg
= typeReg
;
133 pi
.u
.get
.hasTypeCheck
= hasTypeCheck
;
134 pi
.u
.get
.objRemat
= objRemat
.offset
;
154 inline Jump
getJump() const { JS_ASSERT(set
); return jump
; }
155 inline Jump
get() const { JS_ASSERT(set
); return jump
; }
156 inline void setJump(const Jump
&j
) { jump
= j
; set
= true; }
157 inline bool isSet() const { return set
; }
159 inline MaybeJump
&operator=(Jump j
) { setJump(j
); return *this; }
166 struct InternalCallSite
{
181 JSObject
*scopeChain
;
184 BytecodeAnalyzer analysis
;
189 js::Vector
<BranchPatch
, 64> branchPatches
;
190 #if defined JS_MONOIC
191 js::Vector
<MICGenInfo
, 64> mics
;
193 #if defined JS_POLYIC
194 js::Vector
<PICGenInfo
, 64> pics
;
196 js::Vector
<InternalCallSite
, 64> callSites
;
197 js::Vector
<DoublePatch
, 16> doubleList
;
203 // Special atom index used to indicate that the atom is 'length'. This
204 // follows interpreter usage in JSOP_LENGTH.
205 enum { LengthAtomIndex
= uint32(-2) };
207 Compiler(JSContext
*cx
, JSScript
*script
, JSFunction
*fun
, JSObject
*scopeChain
);
210 CompileStatus
Compile();
212 jsbytecode
*getPC() { return PC
; }
213 Label
getLabel() { return masm
.label(); }
214 bool knownJump(jsbytecode
*pc
);
215 Label
labelOf(jsbytecode
*target
);
216 void *findCallSite(const CallSite
&callSite
);
219 CompileStatus
generatePrologue();
220 CompileStatus
generateMethod();
221 CompileStatus
generateEpilogue();
222 CompileStatus
finishThisUp();
224 /* Non-emitting helpers. */
225 uint32
fullAtomIndex(jsbytecode
*pc
);
226 void jumpInScript(Jump j
, jsbytecode
*pc
);
227 JSC::ExecutablePool
*getExecPool(size_t size
);
228 bool compareTwoValues(JSContext
*cx
, JSOp op
, const Value
&lhs
, const Value
&rhs
);
229 void addCallSite(uint32 id
, bool stub
);
231 /* Emitting helpers. */
232 void restoreFrameRegs(Assembler
&masm
);
233 void emitStubCmpOp(BoolStub stub
, jsbytecode
*target
, JSOp fused
);
236 MaybeJump
loadDouble(FrameEntry
*fe
, FPRegisterID fpReg
);
238 /* Opcode handlers. */
239 void jumpAndTrace(Jump j
, jsbytecode
*target
);
240 void jsop_bindname(uint32 index
);
241 void jsop_setglobal(uint32 index
);
242 void jsop_getglobal(uint32 index
);
243 void jsop_getprop_slow();
244 void jsop_getarg(uint32 index
);
247 void dispatchCall(VoidPtrStubUInt32 stub
, uint32 argc
);
248 void interruptCheckHelper();
249 void inlineCallHelper(uint32 argc
, bool callingNew
);
250 void jsop_gnameinc(JSOp op
, VoidStubAtom stub
, uint32 index
);
251 void jsop_nameinc(JSOp op
, VoidStubAtom stub
, uint32 index
);
252 void jsop_propinc(JSOp op
, VoidStubAtom stub
, uint32 index
);
253 void jsop_eleminc(JSOp op
, VoidStub
);
254 void jsop_getgname(uint32 index
);
255 void jsop_getgname_slow(uint32 index
);
256 void jsop_setgname(uint32 index
);
257 void jsop_setgname_slow(uint32 index
);
258 void jsop_bindgname();
259 void jsop_setelem_slow();
260 void jsop_getelem_slow();
262 void jsop_getprop(JSAtom
*atom
, bool typeCheck
= true);
264 void jsop_setprop(JSAtom
*atom
);
265 void jsop_setprop_slow(JSAtom
*atom
);
266 bool jsop_callprop_slow(JSAtom
*atom
);
267 bool jsop_callprop(JSAtom
*atom
);
268 bool jsop_callprop_obj(JSAtom
*atom
);
269 bool jsop_callprop_str(JSAtom
*atom
);
270 bool jsop_callprop_generic(JSAtom
*atom
);
271 void jsop_instanceof();
272 void jsop_name(JSAtom
*atom
);
274 /* Fast arithmetic. */
275 void jsop_binary(JSOp op
, VoidStub stub
);
276 void jsop_binary_full(FrameEntry
*lhs
, FrameEntry
*rhs
, JSOp op
, VoidStub stub
);
277 void jsop_binary_full_simple(FrameEntry
*fe
, JSOp op
, VoidStub stub
);
278 void jsop_binary_double(FrameEntry
*lhs
, FrameEntry
*rhs
, JSOp op
, VoidStub stub
);
279 void slowLoadConstantDouble(Assembler
&masm
, FrameEntry
*fe
,
281 void maybeJumpIfNotInt32(Assembler
&masm
, MaybeJump
&mj
, FrameEntry
*fe
,
282 MaybeRegisterID
&mreg
);
283 void maybeJumpIfNotDouble(Assembler
&masm
, MaybeJump
&mj
, FrameEntry
*fe
,
284 MaybeRegisterID
&mreg
);
285 void jsop_relational(JSOp op
, BoolStub stub
, jsbytecode
*target
, JSOp fused
);
286 void jsop_relational_int(JSOp op
, BoolStub stub
, jsbytecode
*target
, JSOp fused
);
287 void jsop_relational_self(JSOp op
, BoolStub stub
, jsbytecode
*target
, JSOp fused
);
288 void jsop_relational_full(JSOp op
, BoolStub stub
, jsbytecode
*target
, JSOp fused
);
289 void jsop_relational_double(JSOp op
, BoolStub stub
, jsbytecode
*target
, JSOp fused
);
291 void emitLeftDoublePath(FrameEntry
*lhs
, FrameEntry
*rhs
, FrameState::BinaryAlloc
®s
,
292 MaybeJump
&lhsNotDouble
, MaybeJump
&rhsNotNumber
,
293 MaybeJump
&lhsUnknownDone
);
294 void emitRightDoublePath(FrameEntry
*lhs
, FrameEntry
*rhs
, FrameState::BinaryAlloc
®s
,
295 MaybeJump
&rhsNotNumber2
);
298 void jsop_bitop(JSOp op
);
300 RegisterID
rightRegForShift(FrameEntry
*rhs
);
301 void jsop_rsh_int_int(FrameEntry
*lhs
, FrameEntry
*rhs
);
302 void jsop_rsh_const_int(FrameEntry
*lhs
, FrameEntry
*rhs
);
303 void jsop_rsh_int_const(FrameEntry
*lhs
, FrameEntry
*rhs
);
304 void jsop_rsh_int_unknown(FrameEntry
*lhs
, FrameEntry
*rhs
);
305 void jsop_rsh_const_const(FrameEntry
*lhs
, FrameEntry
*rhs
);
306 void jsop_rsh_const_unknown(FrameEntry
*lhs
, FrameEntry
*rhs
);
307 void jsop_rsh_unknown_const(FrameEntry
*lhs
, FrameEntry
*rhs
);
308 void jsop_rsh_unknown_any(FrameEntry
*lhs
, FrameEntry
*rhs
);
309 void jsop_globalinc(JSOp op
, uint32 index
);
313 void jsop_objtostr();
316 void booleanJumpScript(JSOp op
, jsbytecode
*target
);
317 void jsop_ifneq(JSOp op
, jsbytecode
*target
);
318 void jsop_andor(JSOp op
, jsbytecode
*target
);
319 void jsop_arginc(JSOp op
, uint32 slot
, bool popped
);
320 void jsop_localinc(JSOp op
, uint32 slot
, bool popped
);
323 void jsop_getelem_known_type(FrameEntry
*obj
, FrameEntry
*id
, RegisterID tmpReg
);
324 void jsop_getelem_with_pic(FrameEntry
*obj
, FrameEntry
*id
, RegisterID tmpReg
);
325 void jsop_getelem_nopic(FrameEntry
*obj
, FrameEntry
*id
, RegisterID tmpReg
);
326 void jsop_getelem_pic(FrameEntry
*obj
, FrameEntry
*id
, RegisterID objReg
, RegisterID idReg
,
327 RegisterID shapeReg
);
328 void jsop_getelem_dense(FrameEntry
*obj
, FrameEntry
*id
, RegisterID objReg
,
329 MaybeRegisterID
&idReg
, RegisterID shapeReg
);
330 void jsop_stricteq(JSOp op
);
331 void jsop_equality(JSOp op
, BoolStub stub
, jsbytecode
*target
, JSOp fused
);
334 #define STUB_CALL_TYPE(type) \
335 Call stubCall(type stub) { \
336 return stubCall(JS_FUNC_TO_DATA_PTR(void *, stub)); \
339 STUB_CALL_TYPE(JSObjStub
);
340 STUB_CALL_TYPE(VoidStubUInt32
);
341 STUB_CALL_TYPE(VoidStub
);
342 STUB_CALL_TYPE(VoidPtrStubUInt32
);
343 STUB_CALL_TYPE(VoidPtrStub
);
344 STUB_CALL_TYPE(BoolStub
);
345 STUB_CALL_TYPE(JSObjStubUInt32
);
346 STUB_CALL_TYPE(JSObjStubFun
);
347 STUB_CALL_TYPE(JSObjStubJSObj
);
348 STUB_CALL_TYPE(VoidStubAtom
);
349 STUB_CALL_TYPE(JSStrStub
);
350 STUB_CALL_TYPE(JSStrStubUInt32
);
351 STUB_CALL_TYPE(VoidStubJSObj
);
352 STUB_CALL_TYPE(VoidPtrStubPC
);
353 STUB_CALL_TYPE(VoidVpStub
);
354 STUB_CALL_TYPE(VoidStubPC
);
356 #undef STUB_CALL_TYPE
357 void prepareStubCall(Uses uses
);
358 Call
stubCall(void *ptr
);
362 } /* namespace mjit */