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