Line data Source code
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 : #include "jit/FixedList.h"
11 : #if defined(JS_CODEGEN_X86)
12 : # include "jit/x86/BaselineCompiler-x86.h"
13 : #elif defined(JS_CODEGEN_X64)
14 : # include "jit/x64/BaselineCompiler-x64.h"
15 : #elif defined(JS_CODEGEN_ARM)
16 : # include "jit/arm/BaselineCompiler-arm.h"
17 : #elif defined(JS_CODEGEN_ARM64)
18 : # include "jit/arm64/BaselineCompiler-arm64.h"
19 : #elif defined(JS_CODEGEN_MIPS32)
20 : # include "jit/mips32/BaselineCompiler-mips32.h"
21 : #elif defined(JS_CODEGEN_MIPS64)
22 : # include "jit/mips64/BaselineCompiler-mips64.h"
23 : #elif defined(JS_CODEGEN_NONE)
24 : # include "jit/none/BaselineCompiler-none.h"
25 : #else
26 : # error "Unknown architecture!"
27 : #endif
28 :
29 : namespace js {
30 : namespace jit {
31 :
32 : #define OPCODE_LIST(_) \
33 : _(JSOP_NOP) \
34 : _(JSOP_NOP_DESTRUCTURING) \
35 : _(JSOP_LABEL) \
36 : _(JSOP_POP) \
37 : _(JSOP_POPN) \
38 : _(JSOP_DUPAT) \
39 : _(JSOP_ENTERWITH) \
40 : _(JSOP_LEAVEWITH) \
41 : _(JSOP_DUP) \
42 : _(JSOP_DUP2) \
43 : _(JSOP_SWAP) \
44 : _(JSOP_PICK) \
45 : _(JSOP_UNPICK) \
46 : _(JSOP_GOTO) \
47 : _(JSOP_IFEQ) \
48 : _(JSOP_IFNE) \
49 : _(JSOP_AND) \
50 : _(JSOP_OR) \
51 : _(JSOP_NOT) \
52 : _(JSOP_POS) \
53 : _(JSOP_LOOPHEAD) \
54 : _(JSOP_LOOPENTRY) \
55 : _(JSOP_VOID) \
56 : _(JSOP_UNDEFINED) \
57 : _(JSOP_HOLE) \
58 : _(JSOP_NULL) \
59 : _(JSOP_TRUE) \
60 : _(JSOP_FALSE) \
61 : _(JSOP_ZERO) \
62 : _(JSOP_ONE) \
63 : _(JSOP_INT8) \
64 : _(JSOP_INT32) \
65 : _(JSOP_UINT16) \
66 : _(JSOP_UINT24) \
67 : _(JSOP_DOUBLE) \
68 : _(JSOP_STRING) \
69 : _(JSOP_SYMBOL) \
70 : _(JSOP_OBJECT) \
71 : _(JSOP_CALLSITEOBJ) \
72 : _(JSOP_REGEXP) \
73 : _(JSOP_LAMBDA) \
74 : _(JSOP_LAMBDA_ARROW) \
75 : _(JSOP_SETFUNNAME) \
76 : _(JSOP_BITOR) \
77 : _(JSOP_BITXOR) \
78 : _(JSOP_BITAND) \
79 : _(JSOP_LSH) \
80 : _(JSOP_RSH) \
81 : _(JSOP_URSH) \
82 : _(JSOP_ADD) \
83 : _(JSOP_SUB) \
84 : _(JSOP_MUL) \
85 : _(JSOP_DIV) \
86 : _(JSOP_MOD) \
87 : _(JSOP_POW) \
88 : _(JSOP_LT) \
89 : _(JSOP_LE) \
90 : _(JSOP_GT) \
91 : _(JSOP_GE) \
92 : _(JSOP_EQ) \
93 : _(JSOP_NE) \
94 : _(JSOP_STRICTEQ) \
95 : _(JSOP_STRICTNE) \
96 : _(JSOP_CONDSWITCH) \
97 : _(JSOP_CASE) \
98 : _(JSOP_DEFAULT) \
99 : _(JSOP_LINENO) \
100 : _(JSOP_BITNOT) \
101 : _(JSOP_NEG) \
102 : _(JSOP_NEWARRAY) \
103 : _(JSOP_SPREADCALLARRAY) \
104 : _(JSOP_NEWARRAY_COPYONWRITE) \
105 : _(JSOP_INITELEM_ARRAY) \
106 : _(JSOP_NEWOBJECT) \
107 : _(JSOP_NEWINIT) \
108 : _(JSOP_INITELEM) \
109 : _(JSOP_INITELEM_GETTER) \
110 : _(JSOP_INITELEM_SETTER) \
111 : _(JSOP_INITELEM_INC) \
112 : _(JSOP_MUTATEPROTO) \
113 : _(JSOP_INITPROP) \
114 : _(JSOP_INITLOCKEDPROP) \
115 : _(JSOP_INITHIDDENPROP) \
116 : _(JSOP_INITPROP_GETTER) \
117 : _(JSOP_INITPROP_SETTER) \
118 : _(JSOP_ARRAYPUSH) \
119 : _(JSOP_GETELEM) \
120 : _(JSOP_SETELEM) \
121 : _(JSOP_STRICTSETELEM) \
122 : _(JSOP_CALLELEM) \
123 : _(JSOP_DELELEM) \
124 : _(JSOP_STRICTDELELEM) \
125 : _(JSOP_GETELEM_SUPER) \
126 : _(JSOP_SETELEM_SUPER) \
127 : _(JSOP_STRICTSETELEM_SUPER) \
128 : _(JSOP_IN) \
129 : _(JSOP_HASOWN) \
130 : _(JSOP_GETGNAME) \
131 : _(JSOP_BINDGNAME) \
132 : _(JSOP_SETGNAME) \
133 : _(JSOP_STRICTSETGNAME) \
134 : _(JSOP_SETNAME) \
135 : _(JSOP_STRICTSETNAME) \
136 : _(JSOP_GETPROP) \
137 : _(JSOP_SETPROP) \
138 : _(JSOP_STRICTSETPROP) \
139 : _(JSOP_CALLPROP) \
140 : _(JSOP_DELPROP) \
141 : _(JSOP_STRICTDELPROP) \
142 : _(JSOP_GETPROP_SUPER) \
143 : _(JSOP_SETPROP_SUPER) \
144 : _(JSOP_STRICTSETPROP_SUPER) \
145 : _(JSOP_LENGTH) \
146 : _(JSOP_GETBOUNDNAME) \
147 : _(JSOP_GETALIASEDVAR) \
148 : _(JSOP_SETALIASEDVAR) \
149 : _(JSOP_GETNAME) \
150 : _(JSOP_BINDNAME) \
151 : _(JSOP_DELNAME) \
152 : _(JSOP_GETIMPORT) \
153 : _(JSOP_GETINTRINSIC) \
154 : _(JSOP_BINDVAR) \
155 : _(JSOP_DEFVAR) \
156 : _(JSOP_DEFCONST) \
157 : _(JSOP_DEFLET) \
158 : _(JSOP_DEFFUN) \
159 : _(JSOP_GETLOCAL) \
160 : _(JSOP_SETLOCAL) \
161 : _(JSOP_GETARG) \
162 : _(JSOP_SETARG) \
163 : _(JSOP_CHECKLEXICAL) \
164 : _(JSOP_INITLEXICAL) \
165 : _(JSOP_INITGLEXICAL) \
166 : _(JSOP_CHECKALIASEDLEXICAL) \
167 : _(JSOP_INITALIASEDLEXICAL) \
168 : _(JSOP_UNINITIALIZED) \
169 : _(JSOP_CALL) \
170 : _(JSOP_CALL_IGNORES_RV) \
171 : _(JSOP_CALLITER) \
172 : _(JSOP_FUNCALL) \
173 : _(JSOP_FUNAPPLY) \
174 : _(JSOP_NEW) \
175 : _(JSOP_EVAL) \
176 : _(JSOP_STRICTEVAL) \
177 : _(JSOP_SPREADCALL) \
178 : _(JSOP_SPREADNEW) \
179 : _(JSOP_SPREADEVAL) \
180 : _(JSOP_STRICTSPREADEVAL) \
181 : _(JSOP_OPTIMIZE_SPREADCALL)\
182 : _(JSOP_IMPLICITTHIS) \
183 : _(JSOP_GIMPLICITTHIS) \
184 : _(JSOP_INSTANCEOF) \
185 : _(JSOP_TYPEOF) \
186 : _(JSOP_TYPEOFEXPR) \
187 : _(JSOP_THROWMSG) \
188 : _(JSOP_THROW) \
189 : _(JSOP_THROWING) \
190 : _(JSOP_TRY) \
191 : _(JSOP_FINALLY) \
192 : _(JSOP_GOSUB) \
193 : _(JSOP_RETSUB) \
194 : _(JSOP_PUSHLEXICALENV) \
195 : _(JSOP_POPLEXICALENV) \
196 : _(JSOP_FRESHENLEXICALENV) \
197 : _(JSOP_RECREATELEXICALENV) \
198 : _(JSOP_DEBUGLEAVELEXICALENV) \
199 : _(JSOP_PUSHVARENV) \
200 : _(JSOP_POPVARENV) \
201 : _(JSOP_EXCEPTION) \
202 : _(JSOP_DEBUGGER) \
203 : _(JSOP_ARGUMENTS) \
204 : _(JSOP_RUNONCE) \
205 : _(JSOP_REST) \
206 : _(JSOP_TOASYNC) \
207 : _(JSOP_TOASYNCGEN) \
208 : _(JSOP_TOASYNCITER) \
209 : _(JSOP_TOID) \
210 : _(JSOP_TOSTRING) \
211 : _(JSOP_TABLESWITCH) \
212 : _(JSOP_ITER) \
213 : _(JSOP_MOREITER) \
214 : _(JSOP_ISNOITER) \
215 : _(JSOP_ENDITER) \
216 : _(JSOP_ISGENCLOSING) \
217 : _(JSOP_GENERATOR) \
218 : _(JSOP_INITIALYIELD) \
219 : _(JSOP_YIELD) \
220 : _(JSOP_AWAIT) \
221 : _(JSOP_DEBUGAFTERYIELD) \
222 : _(JSOP_FINALYIELDRVAL) \
223 : _(JSOP_RESUME) \
224 : _(JSOP_CALLEE) \
225 : _(JSOP_SUPERBASE) \
226 : _(JSOP_SUPERFUN) \
227 : _(JSOP_GETRVAL) \
228 : _(JSOP_SETRVAL) \
229 : _(JSOP_RETRVAL) \
230 : _(JSOP_RETURN) \
231 : _(JSOP_FUNCTIONTHIS) \
232 : _(JSOP_GLOBALTHIS) \
233 : _(JSOP_CHECKISOBJ) \
234 : _(JSOP_CHECKISCALLABLE) \
235 : _(JSOP_CHECKTHIS) \
236 : _(JSOP_CHECKTHISREINIT) \
237 : _(JSOP_CHECKRETURN) \
238 : _(JSOP_NEWTARGET) \
239 : _(JSOP_SUPERCALL) \
240 : _(JSOP_SPREADSUPERCALL) \
241 : _(JSOP_THROWSETCONST) \
242 : _(JSOP_THROWSETALIASEDCONST) \
243 : _(JSOP_THROWSETCALLEE) \
244 : _(JSOP_INITHIDDENPROP_GETTER) \
245 : _(JSOP_INITHIDDENPROP_SETTER) \
246 : _(JSOP_INITHIDDENELEM) \
247 : _(JSOP_INITHIDDENELEM_GETTER) \
248 : _(JSOP_INITHIDDENELEM_SETTER) \
249 : _(JSOP_CHECKOBJCOERCIBLE) \
250 : _(JSOP_DEBUGCHECKSELFHOSTED) \
251 : _(JSOP_JUMPTARGET) \
252 : _(JSOP_IS_CONSTRUCTING) \
253 : _(JSOP_TRY_DESTRUCTURING_ITERCLOSE) \
254 : _(JSOP_CHECKCLASSHERITAGE) \
255 : _(JSOP_INITHOMEOBJECT) \
256 : _(JSOP_BUILTINPROTO) \
257 : _(JSOP_OBJWITHPROTO) \
258 : _(JSOP_FUNWITHPROTO) \
259 : _(JSOP_CLASSCONSTRUCTOR) \
260 : _(JSOP_DERIVEDCONSTRUCTOR)
261 :
262 628 : class BaselineCompiler : public BaselineCompilerSpecific
263 : {
264 : FixedList<Label> labels_;
265 : NonAssertingLabel return_;
266 : NonAssertingLabel postBarrierSlot_;
267 :
268 : // Native code offset right before the scope chain is initialized.
269 : CodeOffset prologueOffset_;
270 :
271 : // Native code offset right before the frame is popped and the method
272 : // returned from.
273 : CodeOffset epilogueOffset_;
274 :
275 : // Native code offset right after debug prologue and epilogue, or
276 : // equivalent positions when debug mode is off.
277 : CodeOffset postDebugPrologueOffset_;
278 :
279 : // For each INITIALYIELD or YIELD or AWAIT op, this Vector maps the yield
280 : // index to the bytecode offset of the next op.
281 : Vector<uint32_t> yieldAndAwaitOffsets_;
282 :
283 : // Whether any on stack arguments are modified.
284 : bool modifiesArguments_;
285 :
286 65142 : Label* labelOf(jsbytecode* pc) {
287 65142 : return &labels_[script->pcToOffset(pc)];
288 : }
289 :
290 : // If a script has more |nslots| than this, then emit code to do an
291 : // early stack check.
292 : static const unsigned EARLY_STACK_CHECK_SLOT_COUNT = 128;
293 3768 : bool needsEarlyStackCheck() const {
294 3768 : return script->nslots() > EARLY_STACK_CHECK_SLOT_COUNT;
295 : }
296 :
297 : public:
298 : BaselineCompiler(JSContext* cx, TempAllocator& alloc, JSScript* script);
299 : MOZ_MUST_USE bool init();
300 :
301 : MethodStatus compile();
302 :
303 : private:
304 : MethodStatus emitBody();
305 :
306 : MOZ_MUST_USE bool emitCheckThis(ValueOperand val, bool reinit=false);
307 : void emitLoadReturnValue(ValueOperand val);
308 :
309 : void emitInitializeLocals();
310 : MOZ_MUST_USE bool emitPrologue();
311 : MOZ_MUST_USE bool emitEpilogue();
312 : MOZ_MUST_USE bool emitOutOfLinePostBarrierSlot();
313 : MOZ_MUST_USE bool emitIC(ICStub* stub, ICEntry::Kind kind);
314 17611 : MOZ_MUST_USE bool emitOpIC(ICStub* stub) {
315 17611 : return emitIC(stub, ICEntry::Kind_Op);
316 : }
317 1734 : MOZ_MUST_USE bool emitNonOpIC(ICStub* stub) {
318 1734 : return emitIC(stub, ICEntry::Kind_NonOp);
319 : }
320 :
321 : MOZ_MUST_USE bool emitStackCheck(bool earlyCheck=false);
322 : MOZ_MUST_USE bool emitInterruptCheck();
323 : MOZ_MUST_USE bool emitWarmUpCounterIncrement(bool allowOsr=true);
324 : MOZ_MUST_USE bool emitArgumentTypeChecks();
325 : void emitIsDebuggeeCheck();
326 : MOZ_MUST_USE bool emitDebugPrologue();
327 : MOZ_MUST_USE bool emitDebugTrap();
328 : MOZ_MUST_USE bool emitTraceLoggerEnter();
329 : MOZ_MUST_USE bool emitTraceLoggerExit();
330 : MOZ_MUST_USE bool emitTraceLoggerResume(Register script, AllocatableGeneralRegisterSet& regs);
331 :
332 : void emitProfilerEnterFrame();
333 : void emitProfilerExitFrame();
334 :
335 : MOZ_MUST_USE bool initEnvironmentChain();
336 :
337 : void storeValue(const StackValue* source, const Address& dest,
338 : const ValueOperand& scratch);
339 :
340 : #define EMIT_OP(op) bool emit_##op();
341 : OPCODE_LIST(EMIT_OP)
342 : #undef EMIT_OP
343 :
344 : // JSOP_NEG, JSOP_BITNOT
345 : MOZ_MUST_USE bool emitUnaryArith();
346 :
347 : // JSOP_BITXOR, JSOP_LSH, JSOP_ADD etc.
348 : MOZ_MUST_USE bool emitBinaryArith();
349 :
350 : // Handles JSOP_LT, JSOP_GT, and friends
351 : MOZ_MUST_USE bool emitCompare();
352 :
353 : MOZ_MUST_USE bool emitReturn();
354 :
355 : MOZ_MUST_USE bool emitToBoolean();
356 : MOZ_MUST_USE bool emitTest(bool branchIfTrue);
357 : MOZ_MUST_USE bool emitAndOr(bool branchIfTrue);
358 : MOZ_MUST_USE bool emitCall();
359 : MOZ_MUST_USE bool emitSpreadCall();
360 :
361 : MOZ_MUST_USE bool emitInitPropGetterSetter();
362 : MOZ_MUST_USE bool emitInitElemGetterSetter();
363 :
364 : MOZ_MUST_USE bool emitFormalArgAccess(uint32_t arg, bool get);
365 :
366 : MOZ_MUST_USE bool emitThrowConstAssignment();
367 : MOZ_MUST_USE bool emitUninitializedLexicalCheck(const ValueOperand& val);
368 :
369 : MOZ_MUST_USE bool emitIsMagicValue();
370 :
371 : MOZ_MUST_USE bool addPCMappingEntry(bool addIndexEntry);
372 :
373 : MOZ_MUST_USE bool addYieldAndAwaitOffset();
374 :
375 : void getEnvironmentCoordinateObject(Register reg);
376 : Address getEnvironmentCoordinateAddressFromObject(Register objReg, Register reg);
377 : Address getEnvironmentCoordinateAddress(Register reg);
378 :
379 : void getThisEnvironmentCallee(Register reg);
380 : };
381 :
382 : extern const VMFunction NewArrayCopyOnWriteInfo;
383 :
384 : } // namespace jit
385 : } // namespace js
386 :
387 : #endif /* jit_BaselineCompiler_h */
|