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