|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set ts=8 sts=4 et sw=4 tw=99: |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef jit_BaselineCompiler_h |
|
8 #define jit_BaselineCompiler_h |
|
9 |
|
10 #ifdef JS_ION |
|
11 |
|
12 #include "jit/FixedList.h" |
|
13 #if defined(JS_CODEGEN_X86) |
|
14 # include "jit/x86/BaselineCompiler-x86.h" |
|
15 #elif defined(JS_CODEGEN_X64) |
|
16 # include "jit/x64/BaselineCompiler-x64.h" |
|
17 #elif defined(JS_CODEGEN_ARM) |
|
18 # include "jit/arm/BaselineCompiler-arm.h" |
|
19 #elif defined(JS_CODEGEN_MIPS) |
|
20 # include "jit/mips/BaselineCompiler-mips.h" |
|
21 #else |
|
22 # error "Unknown architecture!" |
|
23 #endif |
|
24 |
|
25 namespace js { |
|
26 namespace jit { |
|
27 |
|
28 #define OPCODE_LIST(_) \ |
|
29 _(JSOP_NOP) \ |
|
30 _(JSOP_LABEL) \ |
|
31 _(JSOP_POP) \ |
|
32 _(JSOP_POPN) \ |
|
33 _(JSOP_DUPAT) \ |
|
34 _(JSOP_ENTERWITH) \ |
|
35 _(JSOP_LEAVEWITH) \ |
|
36 _(JSOP_DUP) \ |
|
37 _(JSOP_DUP2) \ |
|
38 _(JSOP_SWAP) \ |
|
39 _(JSOP_PICK) \ |
|
40 _(JSOP_GOTO) \ |
|
41 _(JSOP_IFEQ) \ |
|
42 _(JSOP_IFNE) \ |
|
43 _(JSOP_AND) \ |
|
44 _(JSOP_OR) \ |
|
45 _(JSOP_NOT) \ |
|
46 _(JSOP_POS) \ |
|
47 _(JSOP_LOOPHEAD) \ |
|
48 _(JSOP_LOOPENTRY) \ |
|
49 _(JSOP_VOID) \ |
|
50 _(JSOP_UNDEFINED) \ |
|
51 _(JSOP_HOLE) \ |
|
52 _(JSOP_NULL) \ |
|
53 _(JSOP_THIS) \ |
|
54 _(JSOP_TRUE) \ |
|
55 _(JSOP_FALSE) \ |
|
56 _(JSOP_ZERO) \ |
|
57 _(JSOP_ONE) \ |
|
58 _(JSOP_INT8) \ |
|
59 _(JSOP_INT32) \ |
|
60 _(JSOP_UINT16) \ |
|
61 _(JSOP_UINT24) \ |
|
62 _(JSOP_DOUBLE) \ |
|
63 _(JSOP_STRING) \ |
|
64 _(JSOP_OBJECT) \ |
|
65 _(JSOP_REGEXP) \ |
|
66 _(JSOP_LAMBDA) \ |
|
67 _(JSOP_LAMBDA_ARROW) \ |
|
68 _(JSOP_BITOR) \ |
|
69 _(JSOP_BITXOR) \ |
|
70 _(JSOP_BITAND) \ |
|
71 _(JSOP_LSH) \ |
|
72 _(JSOP_RSH) \ |
|
73 _(JSOP_URSH) \ |
|
74 _(JSOP_ADD) \ |
|
75 _(JSOP_SUB) \ |
|
76 _(JSOP_MUL) \ |
|
77 _(JSOP_DIV) \ |
|
78 _(JSOP_MOD) \ |
|
79 _(JSOP_LT) \ |
|
80 _(JSOP_LE) \ |
|
81 _(JSOP_GT) \ |
|
82 _(JSOP_GE) \ |
|
83 _(JSOP_EQ) \ |
|
84 _(JSOP_NE) \ |
|
85 _(JSOP_STRICTEQ) \ |
|
86 _(JSOP_STRICTNE) \ |
|
87 _(JSOP_CONDSWITCH) \ |
|
88 _(JSOP_CASE) \ |
|
89 _(JSOP_DEFAULT) \ |
|
90 _(JSOP_LINENO) \ |
|
91 _(JSOP_BITNOT) \ |
|
92 _(JSOP_NEG) \ |
|
93 _(JSOP_NEWARRAY) \ |
|
94 _(JSOP_INITELEM_ARRAY) \ |
|
95 _(JSOP_NEWOBJECT) \ |
|
96 _(JSOP_NEWINIT) \ |
|
97 _(JSOP_INITELEM) \ |
|
98 _(JSOP_INITELEM_GETTER) \ |
|
99 _(JSOP_INITELEM_SETTER) \ |
|
100 _(JSOP_MUTATEPROTO) \ |
|
101 _(JSOP_INITPROP) \ |
|
102 _(JSOP_INITPROP_GETTER) \ |
|
103 _(JSOP_INITPROP_SETTER) \ |
|
104 _(JSOP_ENDINIT) \ |
|
105 _(JSOP_ARRAYPUSH) \ |
|
106 _(JSOP_GETELEM) \ |
|
107 _(JSOP_SETELEM) \ |
|
108 _(JSOP_CALLELEM) \ |
|
109 _(JSOP_DELELEM) \ |
|
110 _(JSOP_IN) \ |
|
111 _(JSOP_GETGNAME) \ |
|
112 _(JSOP_BINDGNAME) \ |
|
113 _(JSOP_SETGNAME) \ |
|
114 _(JSOP_SETNAME) \ |
|
115 _(JSOP_GETPROP) \ |
|
116 _(JSOP_SETPROP) \ |
|
117 _(JSOP_CALLPROP) \ |
|
118 _(JSOP_DELPROP) \ |
|
119 _(JSOP_LENGTH) \ |
|
120 _(JSOP_GETXPROP) \ |
|
121 _(JSOP_GETALIASEDVAR) \ |
|
122 _(JSOP_SETALIASEDVAR) \ |
|
123 _(JSOP_NAME) \ |
|
124 _(JSOP_BINDNAME) \ |
|
125 _(JSOP_DELNAME) \ |
|
126 _(JSOP_GETINTRINSIC) \ |
|
127 _(JSOP_DEFVAR) \ |
|
128 _(JSOP_DEFCONST) \ |
|
129 _(JSOP_SETCONST) \ |
|
130 _(JSOP_DEFFUN) \ |
|
131 _(JSOP_GETLOCAL) \ |
|
132 _(JSOP_SETLOCAL) \ |
|
133 _(JSOP_GETARG) \ |
|
134 _(JSOP_SETARG) \ |
|
135 _(JSOP_CALL) \ |
|
136 _(JSOP_FUNCALL) \ |
|
137 _(JSOP_FUNAPPLY) \ |
|
138 _(JSOP_NEW) \ |
|
139 _(JSOP_EVAL) \ |
|
140 _(JSOP_IMPLICITTHIS) \ |
|
141 _(JSOP_INSTANCEOF) \ |
|
142 _(JSOP_TYPEOF) \ |
|
143 _(JSOP_TYPEOFEXPR) \ |
|
144 _(JSOP_SETCALL) \ |
|
145 _(JSOP_THROW) \ |
|
146 _(JSOP_TRY) \ |
|
147 _(JSOP_FINALLY) \ |
|
148 _(JSOP_GOSUB) \ |
|
149 _(JSOP_RETSUB) \ |
|
150 _(JSOP_PUSHBLOCKSCOPE) \ |
|
151 _(JSOP_POPBLOCKSCOPE) \ |
|
152 _(JSOP_DEBUGLEAVEBLOCK) \ |
|
153 _(JSOP_EXCEPTION) \ |
|
154 _(JSOP_DEBUGGER) \ |
|
155 _(JSOP_ARGUMENTS) \ |
|
156 _(JSOP_RUNONCE) \ |
|
157 _(JSOP_REST) \ |
|
158 _(JSOP_TOID) \ |
|
159 _(JSOP_TABLESWITCH) \ |
|
160 _(JSOP_ITER) \ |
|
161 _(JSOP_MOREITER) \ |
|
162 _(JSOP_ITERNEXT) \ |
|
163 _(JSOP_ENDITER) \ |
|
164 _(JSOP_CALLEE) \ |
|
165 _(JSOP_SETRVAL) \ |
|
166 _(JSOP_RETRVAL) \ |
|
167 _(JSOP_RETURN) |
|
168 |
|
169 class BaselineCompiler : public BaselineCompilerSpecific |
|
170 { |
|
171 FixedList<Label> labels_; |
|
172 NonAssertingLabel return_; |
|
173 #ifdef JSGC_GENERATIONAL |
|
174 NonAssertingLabel postBarrierSlot_; |
|
175 #endif |
|
176 |
|
177 // Native code offset right before the scope chain is initialized. |
|
178 CodeOffsetLabel prologueOffset_; |
|
179 |
|
180 // Native code offset right before the frame is popped and the method |
|
181 // returned from. |
|
182 CodeOffsetLabel epilogueOffset_; |
|
183 |
|
184 // Native code offset right after debug prologue and epilogue, or |
|
185 // equivalent positions when debug mode is off. |
|
186 CodeOffsetLabel postDebugPrologueOffset_; |
|
187 |
|
188 // Whether any on stack arguments are modified. |
|
189 bool modifiesArguments_; |
|
190 |
|
191 Label *labelOf(jsbytecode *pc) { |
|
192 return &labels_[script->pcToOffset(pc)]; |
|
193 } |
|
194 |
|
195 // If a script has more |nslots| than this, then emit code to do an |
|
196 // early stack check. |
|
197 static const unsigned EARLY_STACK_CHECK_SLOT_COUNT = 128; |
|
198 bool needsEarlyStackCheck() const { |
|
199 return script->nslots() > EARLY_STACK_CHECK_SLOT_COUNT; |
|
200 } |
|
201 |
|
202 public: |
|
203 BaselineCompiler(JSContext *cx, TempAllocator &alloc, JSScript *script); |
|
204 bool init(); |
|
205 |
|
206 MethodStatus compile(); |
|
207 |
|
208 private: |
|
209 MethodStatus emitBody(); |
|
210 |
|
211 bool emitPrologue(); |
|
212 bool emitEpilogue(); |
|
213 #ifdef JSGC_GENERATIONAL |
|
214 bool emitOutOfLinePostBarrierSlot(); |
|
215 #endif |
|
216 bool emitIC(ICStub *stub, ICEntry::Kind kind); |
|
217 bool emitOpIC(ICStub *stub) { |
|
218 return emitIC(stub, ICEntry::Kind_Op); |
|
219 } |
|
220 bool emitNonOpIC(ICStub *stub) { |
|
221 return emitIC(stub, ICEntry::Kind_NonOp); |
|
222 } |
|
223 |
|
224 bool emitStackCheck(bool earlyCheck=false); |
|
225 bool emitInterruptCheck(); |
|
226 bool emitUseCountIncrement(bool allowOsr=true); |
|
227 bool emitArgumentTypeChecks(); |
|
228 bool emitDebugPrologue(); |
|
229 bool emitDebugTrap(); |
|
230 bool emitSPSPush(); |
|
231 void emitSPSPop(); |
|
232 |
|
233 bool initScopeChain(); |
|
234 |
|
235 void storeValue(const StackValue *source, const Address &dest, |
|
236 const ValueOperand &scratch); |
|
237 |
|
238 #define EMIT_OP(op) bool emit_##op(); |
|
239 OPCODE_LIST(EMIT_OP) |
|
240 #undef EMIT_OP |
|
241 |
|
242 // JSOP_NEG, JSOP_BITNOT |
|
243 bool emitUnaryArith(); |
|
244 |
|
245 // JSOP_BITXOR, JSOP_LSH, JSOP_ADD etc. |
|
246 bool emitBinaryArith(); |
|
247 |
|
248 // Handles JSOP_LT, JSOP_GT, and friends |
|
249 bool emitCompare(); |
|
250 |
|
251 bool emitReturn(); |
|
252 |
|
253 bool emitToBoolean(); |
|
254 bool emitTest(bool branchIfTrue); |
|
255 bool emitAndOr(bool branchIfTrue); |
|
256 bool emitCall(); |
|
257 |
|
258 bool emitInitPropGetterSetter(); |
|
259 bool emitInitElemGetterSetter(); |
|
260 |
|
261 bool emitFormalArgAccess(uint32_t arg, bool get); |
|
262 |
|
263 bool addPCMappingEntry(bool addIndexEntry); |
|
264 |
|
265 void getScopeCoordinateObject(Register reg); |
|
266 Address getScopeCoordinateAddressFromObject(Register objReg, Register reg); |
|
267 Address getScopeCoordinateAddress(Register reg); |
|
268 }; |
|
269 |
|
270 } // namespace jit |
|
271 } // namespace js |
|
272 |
|
273 #endif // JS_ION |
|
274 |
|
275 #endif /* jit_BaselineCompiler_h */ |