IRBuilder.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. ///---------------------------------------------------------------------------
  7. ///
  8. /// class IRBuilder
  9. ///
  10. /// To generate IR from the Jn bytecodes.
  11. ///
  12. ///---------------------------------------------------------------------------
  13. class BranchReloc
  14. {
  15. public:
  16. BranchReloc(IR::BranchInstr * instr, uint32 branchOffset, uint32 offs)
  17. : branchInstr(instr), branchOffset(branchOffset), offset(offs), isNotBackEdge(false)
  18. { }
  19. private:
  20. IR::BranchInstr * branchInstr;
  21. uint32 offset;
  22. bool isNotBackEdge;
  23. uint32 branchOffset;
  24. public:
  25. IR::BranchInstr * GetBranchInstr()
  26. {
  27. return this->branchInstr;
  28. }
  29. uint32 GetOffset() const
  30. {
  31. return this->offset;
  32. }
  33. uint32 GetBranchOffset() const
  34. {
  35. return this->branchOffset;
  36. }
  37. bool IsNotBackEdge() const
  38. {
  39. return this->isNotBackEdge;
  40. }
  41. void SetNotBackEdge()
  42. {
  43. this->isNotBackEdge = true;
  44. }
  45. };
  46. class IRBuilder
  47. {
  48. friend struct IRBuilderSwitchAdapter;
  49. public:
  50. IRBuilder(Func * func)
  51. : m_func(func)
  52. , m_argsOnStack(0)
  53. , m_loopBodyRetIPSym(nullptr)
  54. , m_ldSlots(nullptr)
  55. , m_loopCounterSym(nullptr)
  56. , callTreeHasSomeProfileInfo(false)
  57. , finallyBlockLevel(0)
  58. , m_saveLoopImplicitCallFlags(nullptr)
  59. , handlerOffsetStack(nullptr)
  60. , m_switchAdapter(this)
  61. , m_switchBuilder(&m_switchAdapter)
  62. , m_stackFuncPtrSym(nullptr)
  63. , m_loopBodyForInEnumeratorArrayOpnd(nullptr)
  64. , m_paramScopeDone(false)
  65. #if DBG
  66. , m_callsOnStack(0)
  67. , m_usedAsTemp(nullptr)
  68. #endif
  69. #ifdef BAILOUT_INJECTION
  70. , seenLdStackArgPtr(false)
  71. , expectApplyArg(false)
  72. , seenProfiledBeginSwitch(false)
  73. #endif
  74. #ifdef BYTECODE_BRANCH_ISLAND
  75. , longBranchMap(nullptr)
  76. #endif
  77. {
  78. auto loopCount = func->GetJITFunctionBody()->GetLoopCount();
  79. if (loopCount > 0) {
  80. #if DBG
  81. m_saveLoopImplicitCallFlags = AnewArrayZ(func->m_alloc, IR::Opnd*, loopCount);
  82. #else
  83. m_saveLoopImplicitCallFlags = AnewArray(func->m_alloc, IR::Opnd*, loopCount);
  84. #endif
  85. }
  86. // Note: use original byte code without debugging probes, so that we don't jit BPs inserted by the user.
  87. func->m_workItem->InitializeReader(&m_jnReader, &m_statementReader, func->m_alloc);
  88. };
  89. ~IRBuilder()
  90. {
  91. Assert(m_func->GetJITFunctionBody()->GetLoopCount() == 0 || m_saveLoopImplicitCallFlags);
  92. if (m_saveLoopImplicitCallFlags)
  93. {
  94. AdeleteArray(m_func->m_alloc, m_func->GetJITFunctionBody()->GetLoopCount(), m_saveLoopImplicitCallFlags);
  95. }
  96. }
  97. void Build();
  98. void InsertLabels();
  99. IR::LabelInstr * CreateLabel(IR::BranchInstr * branchInstr, uint& offset);
  100. private:
  101. void InsertInstr(IR::Instr *instr, IR::Instr* insertBeforeInstr);
  102. void AddInstr(IR::Instr *instr, uint32 offset);
  103. BranchReloc * AddBranchInstr(IR::BranchInstr *instr, uint32 offset, uint32 targetOffset);
  104. #ifdef BYTECODE_BRANCH_ISLAND
  105. void ConsumeBranchIsland();
  106. void EnsureConsumeBranchIsland();
  107. uint ResolveVirtualLongBranch(IR::BranchInstr * branchInstr, uint offset);
  108. #endif
  109. BranchReloc * CreateRelocRecord(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset);
  110. void BuildGeneratorPreamble();
  111. void LoadNativeCodeData();
  112. void BuildConstantLoads();
  113. void BuildImplicitArgIns();
  114. #define LAYOUT_TYPE(layout) \
  115. void Build##layout(Js::OpCode newOpcode, uint32 offset);
  116. #define LAYOUT_TYPE_WMS(layout) \
  117. template <typename SizePolicy> void Build##layout(Js::OpCode newOpcode, uint32 offset);
  118. #include "ByteCode/LayoutTypes.h"
  119. void BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0);
  120. void BuildReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0, Js::RegSlot R1, uint32 nextOffset);
  121. void BuildProfiledReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot, Js::ProfileId profileId);
  122. void BuildReg3(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot,
  123. Js::RegSlot src2RegSlot, Js::ProfileId profileId);
  124. void BuildIsIn(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot, Js::ProfileId profileId);
  125. void BuildReg3C(Js::OpCode newOpCode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot,
  126. Js::RegSlot src2RegSlot, Js::CacheId inlineCacheIndex);
  127. void BuildReg4(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot,
  128. Js::RegSlot src2RegSlot, Js::RegSlot src3RegSlot);
  129. void BuildReg2B1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot, byte index);
  130. void BuildReg3B1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot,
  131. Js::RegSlot src2RegSlot, uint8 index);
  132. void BuildReg5(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot,
  133. Js::RegSlot src2RegSlot, Js::RegSlot src3RegSlot, Js::RegSlot src4RegSlot);
  134. void BuildUnsigned1(Js::OpCode newOpcode, uint32 offset, uint32 C1);
  135. void BuildReg1Unsigned1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0, int32 C1);
  136. void BuildProfiledReg1Unsigned1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0, int32 C1, Js::ProfileId profileId);
  137. void BuildReg2Int1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot, int32 value);
  138. void BuildElementC(Js::OpCode newOpcode, uint32 offset, Js::RegSlot fieldRegSlot, Js::RegSlot regSlot,
  139. Js::PropertyIdIndexType propertyIdIndex);
  140. void BuildElementScopedC(Js::OpCode newOpcode, uint32 offset, Js::RegSlot regSlot,
  141. Js::PropertyIdIndexType propertyIdIndex);
  142. void BuildElementSlot(Js::OpCode newOpcode, uint32 offset, Js::RegSlot fieldRegSlot, Js::RegSlot regSlot,
  143. int32 slotId, Js::ProfileId profileId);
  144. void BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot regSlot,
  145. int32 slotId, Js::ProfileId profileId);
  146. void BuildElementSlotI2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot regSlot,
  147. int32 slotId1, int32 slotId2, Js::ProfileId profileId);
  148. void BuildElementSlotI3(Js::OpCode newOpcode, uint32 offset, Js::RegSlot fieldRegSlot, Js::RegSlot regSlot,
  149. int32 slotId, Js::RegSlot homeObjLocation, Js::ProfileId profileId);
  150. void BuildArgIn0(uint32 offset, Js::RegSlot R0);
  151. void BuildArg(Js::OpCode newOpcode, uint32 offset, Js::ArgSlot argument, Js::RegSlot srcRegSlot);
  152. void BuildArgIn(uint32 offset, Js::RegSlot dstRegSlot, uint16 argument);
  153. void BuildArgInRest();
  154. void BuildElementP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot regSlot, Js::CacheId inlineCacheIndex);
  155. void BuildElementCP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot instance, Js::RegSlot regSlot, Js::CacheId inlineCacheIndex);
  156. void BuildProfiledElementCP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot instance, Js::RegSlot regSlot, Js::CacheId inlineCacheIndex, Js::ProfileId profileId);
  157. void BuildElementC2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot instanceSlot, Js::RegSlot instance2Slot,
  158. Js::RegSlot regSlot, Js::PropertyIdIndexType propertyIdIndex);
  159. void BuildElementScopedC2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot instance2Slot,
  160. Js::RegSlot regSlot, Js::PropertyIdIndexType propertyIdIndex);
  161. void BuildElementU(Js::OpCode newOpcode, uint32 offset, Js::RegSlot instance, Js::PropertyIdIndexType propertyIdIndex);
  162. void BuildElementI(Js::OpCode newOpcode, uint32 offset, Js::RegSlot baseRegSlot, Js::RegSlot indexRegSlot,
  163. Js::RegSlot regSlot, Js::ProfileId profileId);
  164. void BuildElementUnsigned1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot baseRegSlot, uint32 index, Js::RegSlot regSlot);
  165. IR::Instr * BuildCallI_Helper(Js::OpCode newOpcode, uint32 offset, Js::RegSlot Return, Js::RegSlot Function, Js::ArgSlot ArgCount,
  166. Js::ProfileId profileId, Js::CallFlags flags = Js::CallFlags_None, Js::InlineCacheIndex inlineCacheIndex = Js::Constants::NoInlineCacheIndex);
  167. IR::Instr * BuildProfiledCallI(Js::OpCode opcode, uint32 offset, Js::RegSlot returnValue, Js::RegSlot function,
  168. Js::ArgSlot argCount, Js::ProfileId profileId, Js::CallFlags flags = Js::CallFlags_None, Js::InlineCacheIndex inlineCacheIndex = Js::Constants::NoInlineCacheIndex);
  169. IR::Instr * BuildProfiledCallIExtended(Js::OpCode opcode, uint32 offset, Js::RegSlot returnValue, Js::RegSlot function,
  170. Js::ArgSlot argCount, Js::ProfileId profileId, Js::CallIExtendedOptions options, uint32 spreadAuxOffset, Js::CallFlags flags = Js::CallFlags_None);
  171. IR::Instr * BuildProfiledCallIWithICIndex(Js::OpCode opcode, uint32 offset, Js::RegSlot returnValue, Js::RegSlot function,
  172. Js::ArgSlot argCount, Js::ProfileId profileId, Js::InlineCacheIndex inlineCacheIndex);
  173. void BuildProfiledCallIExtendedFlags(Js::OpCode opcode, uint32 offset, Js::RegSlot returnValue, Js::RegSlot function,
  174. Js::ArgSlot argCount, Js::ProfileId profileId, Js::CallIExtendedOptions options, uint32 spreadAuxOffset);
  175. void BuildProfiledCallIExtendedWithICIndex(Js::OpCode opcode, uint32 offset, Js::RegSlot returnValue, Js::RegSlot function,
  176. Js::ArgSlot argCount, Js::ProfileId profileId, Js::CallIExtendedOptions options, uint32 spreadAuxOffset);
  177. void BuildProfiledCallIExtendedFlagsWithICIndex(Js::OpCode opcode, uint32 offset, Js::RegSlot returnValue, Js::RegSlot function,
  178. Js::ArgSlot argCount, Js::ProfileId profileId, Js::CallIExtendedOptions options, uint32 spreadAuxOffset);
  179. void BuildProfiled2CallI(Js::OpCode opcode, uint32 offset, Js::RegSlot returnValue, Js::RegSlot function,
  180. Js::ArgSlot argCount, Js::ProfileId profileId, Js::ProfileId profileId2);
  181. void BuildProfiled2CallIExtended(Js::OpCode opcode, uint32 offset, Js::RegSlot returnValue, Js::RegSlot function,
  182. Js::ArgSlot argCount, Js::ProfileId profileId, Js::ProfileId profileId2, Js::CallIExtendedOptions options, uint32 spreadAuxOffset);
  183. void BuildLdSpreadIndices(uint32 offset, uint32 spreadAuxOffset);
  184. IR::Instr * BuildCallIExtended(Js::OpCode newOpcode, uint32 offset, Js::RegSlot returnValue, Js::RegSlot function,
  185. Js::ArgSlot argCount, Js::CallIExtendedOptions options, uint32 spreadAuxOffset, Js::CallFlags flags = Js::CallFlags_None);
  186. void BuildCallCommon(IR::Instr *instr, StackSym *symDst, Js::ArgSlot argCount, Js::CallFlags flags = Js::CallFlags_None);
  187. void BuildRegexFromPattern(Js::RegSlot dstRegSlot, uint32 patternIndex, uint32 offset);
  188. void BuildClass(Js::OpCode newOpcode, uint32 offset, Js::RegSlot constructor, Js::RegSlot extends);
  189. void BuildBrReg1(Js::OpCode newOpcode, uint32 offset, uint targetOffset, Js::RegSlot srcRegSlot);
  190. void BuildBrReg2(Js::OpCode newOpcode, uint32 offset, uint targetOffset, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot);
  191. void BuildBrBReturn(Js::OpCode newOpcode, uint32 offset, Js::RegSlot DestRegSlot, uint32 forInLoopLevel, uint32 targetOffset);
  192. IR::IndirOpnd * BuildIndirOpnd(IR::RegOpnd *baseReg, IR::RegOpnd *indexReg);
  193. IR::IndirOpnd * BuildIndirOpnd(IR::RegOpnd *baseReg, uint32 offset);
  194. #if DBG_DUMP || defined(ENABLE_IR_VIEWER)
  195. IR::IndirOpnd * BuildIndirOpnd(IR::RegOpnd *baseReg, uint32 offset, const char16 *desc);
  196. #endif
  197. IR::SymOpnd * BuildFieldOpnd(Js::OpCode newOpCode, Js::RegSlot reg, Js::PropertyId propertyId, Js::PropertyIdIndexType propertyIdIndex, PropertyKind propertyKind, uint inlineCacheIndex = -1);
  198. PropertySym * BuildFieldSym(Js::RegSlot reg, Js::PropertyId propertyId, Js::PropertyIdIndexType propertyIdIndex, uint inlineCacheIndex, PropertyKind propertyKind);
  199. SymID BuildSrcStackSymID(Js::RegSlot regSlot);
  200. IR::RegOpnd * BuildDstOpnd(Js::RegSlot dstRegSlot, IRType type = TyVar, bool isCatchObjectSym = false);
  201. IR::RegOpnd * BuildSrcOpnd(Js::RegSlot srcRegSlot, IRType type = TyVar);
  202. IR::AddrOpnd * BuildAuxArrayOpnd(AuxArrayValue auxArrayType, uint32 auxArrayOffset);
  203. IR::Opnd * BuildAuxObjectLiteralTypeRefOpnd(int objectId);
  204. IR::Opnd * BuildForInEnumeratorOpnd(uint forInLoopLevel);
  205. IR::RegOpnd * EnsureLoopBodyForInEnumeratorArrayOpnd();
  206. private:
  207. uint AddStatementBoundary(uint statementIndex, uint offset);
  208. void CheckBuiltIn(PropertySym * propertySym, Js::BuiltinFunction *puBuiltInIndex);
  209. bool IsFloatFunctionCallsite(Js::BuiltinFunction index, size_t argc);
  210. IR::Instr * BuildProfiledFieldLoad(Js::OpCode loadOp, IR::RegOpnd *dstOpnd, IR::SymOpnd *srcOpnd, Js::CacheId inlineCacheIndex, bool *pUnprofiled);
  211. IR::Instr * BuildProfiledSlotLoad(Js::OpCode loadOp, IR::RegOpnd *dstOpnd, IR::SymOpnd *srcOpnd, Js::ProfileId profileId, bool *pUnprofiled);
  212. SymID GetMappedTemp(Js::RegSlot reg)
  213. {
  214. AssertMsg(this->RegIsTemp(reg), "Processing non-temp reg as a temp?");
  215. AssertMsg(this->tempMap, "Processing non-temp reg without a temp map?");
  216. Js::RegSlot tempIndex = reg - this->firstTemp;
  217. AssertOrFailFast(tempIndex < m_func->GetJITFunctionBody()->GetTempCount());
  218. return this->tempMap[tempIndex];
  219. }
  220. void SetMappedTemp(Js::RegSlot reg, SymID tempId)
  221. {
  222. AssertMsg(this->RegIsTemp(reg), "Processing non-temp reg as a temp?");
  223. AssertMsg(this->tempMap, "Processing non-temp reg without a temp map?");
  224. Js::RegSlot tempIndex = reg - this->firstTemp;
  225. AssertOrFailFast(tempIndex < m_func->GetJITFunctionBody()->GetTempCount());
  226. this->tempMap[tempIndex] = tempId;
  227. }
  228. BOOL GetTempUsed(Js::RegSlot reg)
  229. {
  230. AssertMsg(this->RegIsTemp(reg), "Processing non-temp reg as a temp?");
  231. AssertMsg(this->fbvTempUsed, "Processing non-temp reg without a used BV?");
  232. Js::RegSlot tempIndex = reg - this->firstTemp;
  233. AssertOrFailFast(tempIndex < m_func->GetJITFunctionBody()->GetTempCount());
  234. return this->fbvTempUsed->Test(tempIndex);
  235. }
  236. void SetTempUsed(Js::RegSlot reg, BOOL used)
  237. {
  238. AssertMsg(this->RegIsTemp(reg), "Processing non-temp reg as a temp?");
  239. AssertMsg(this->fbvTempUsed, "Processing non-temp reg without a used BV?");
  240. Js::RegSlot tempIndex = reg - this->firstTemp;
  241. AssertOrFailFast(tempIndex < m_func->GetJITFunctionBody()->GetTempCount());
  242. if (used)
  243. {
  244. this->fbvTempUsed->Set(tempIndex);
  245. }
  246. else
  247. {
  248. this->fbvTempUsed->Clear(tempIndex);
  249. }
  250. }
  251. BOOL RegIsTemp(Js::RegSlot reg)
  252. {
  253. return reg >= this->firstTemp;
  254. }
  255. BOOL RegIsConstant(Js::RegSlot reg)
  256. {
  257. return reg > 0 && reg < m_func->GetJITFunctionBody()->GetConstCount();
  258. }
  259. bool IsParamScopeDone() const { return m_paramScopeDone; }
  260. void SetParamScopeDone(bool done = true) { m_paramScopeDone = done; }
  261. Js::RegSlot InnerScopeIndexToRegSlot(uint32) const;
  262. Js::RegSlot GetEnvReg() const;
  263. Js::RegSlot GetEnvRegForEvalCode() const;
  264. Js::RegSlot GetEnvRegForInnerFrameDisplay() const;
  265. void AddEnvOpndForInnerFrameDisplay(IR::Instr *instr, uint offset);
  266. bool DoSlotArrayCheck(IR::SymOpnd *fieldOpnd, bool doDynamicCheck);
  267. void EmitClosureRangeChecks();
  268. void DoClosureRegCheck(Js::RegSlot reg);
  269. void BuildInitCachedScope(int auxOffset, int offset);
  270. void GenerateLoopBodySlotAccesses(uint offset);
  271. void GenerateLoopBodyStSlots(SymID loopParamSymId, uint offset);
  272. IR::Instr * GenerateLoopBodyStSlot(Js::RegSlot regSlot, uint offset = Js::Constants::NoByteCodeOffset);
  273. bool IsLoopBody() const;
  274. bool IsLoopBodyInTry() const;
  275. uint GetLoopBodyExitInstrOffset() const;
  276. IR::SymOpnd * BuildLoopBodySlotOpnd(SymID symId);
  277. void EnsureLoopBodyLoadSlot(SymID symId, bool isCatchObjectSym = false);
  278. void SetLoopBodyStSlot(SymID symID, bool isCatchObjectSym);
  279. bool IsLoopBodyOuterOffset(uint offset) const;
  280. bool IsLoopBodyReturnIPInstr(IR::Instr * instr) const;
  281. IR::Opnd * InsertLoopBodyReturnIPInstr(uint targetOffset, uint offset);
  282. IR::Instr * CreateLoopBodyReturnIPInstr(uint targetOffset, uint offset);
  283. StackSym * EnsureStackFuncPtrSym();
  284. void InsertBailOutForDebugger(uint offset, IR::BailOutKind kind, IR::Instr* insertBeforeInstr = nullptr);
  285. void InsertBailOnNoProfile(uint offset);
  286. void InsertBailOnNoProfile(IR::Instr *const insertBeforeInstr);
  287. bool DoBailOnNoProfile();
  288. void InsertIncrLoopBodyLoopCounter(IR::LabelInstr *loopTopLabelInstr);
  289. void InsertInitLoopBodyLoopCounter(uint loopNum);
  290. void InsertDoneLoopBodyLoopCounter(uint32 lastOffset);
  291. IR::RegOpnd * InsertConvPrimStr(IR::RegOpnd * srcOpnd, uint offset, bool forcePreOpBailOutIfNeeded);
  292. IR::Opnd * IRBuilder::GetEnvironmentOperand(uint32 offset);
  293. bool DoLoadInstructionArrayProfileInfo();
  294. bool AllowNativeArrayProfileInfo();
  295. #ifdef BAILOUT_INJECTION
  296. void InjectBailOut(uint offset);
  297. void CheckBailOutInjection(Js::OpCode opcode);
  298. bool seenLdStackArgPtr;
  299. bool expectApplyArg;
  300. bool seenProfiledBeginSwitch;
  301. #endif
  302. JitArenaAllocator * m_tempAlloc;
  303. JitArenaAllocator * m_funcAlloc;
  304. Func * m_func;
  305. IR::Instr * m_lastInstr;
  306. IR::Instr ** m_offsetToInstruction;
  307. uint32 m_offsetToInstructionCount;
  308. uint32 m_functionStartOffset;
  309. Js::ByteCodeReader m_jnReader;
  310. Js::StatementReader<Js::FunctionBody::ArenaStatementMapList> m_statementReader;
  311. SList<IR::Instr *> *m_argStack;
  312. SList<BranchReloc*> *branchRelocList;
  313. typedef Pair<uint, bool> handlerStackElementType;
  314. SList<handlerStackElementType> *handlerOffsetStack;
  315. SymID * tempMap;
  316. BVFixed * fbvTempUsed;
  317. Js::RegSlot firstTemp;
  318. IRBuilderSwitchAdapter m_switchAdapter;
  319. SwitchIRBuilder m_switchBuilder;
  320. BVFixed * m_ldSlots;
  321. BVFixed * m_stSlots;
  322. #if DBG
  323. BVFixed * m_usedAsTemp;
  324. #endif
  325. StackSym * m_loopBodyRetIPSym;
  326. StackSym* m_loopCounterSym;
  327. StackSym * m_stackFuncPtrSym;
  328. bool m_paramScopeDone;
  329. bool callTreeHasSomeProfileInfo;
  330. uint finallyBlockLevel;
  331. // Keep track of how many args we have on the stack whenever
  332. // we make a call so that the max stack used over all calls can be
  333. // used to estimate how much stack we should probe for at the
  334. // beginning of a JITted function.
  335. #if DBG
  336. uint32 m_callsOnStack;
  337. #endif
  338. uint32 m_argsOnStack;
  339. Js::PropertyId m_loopBodyLocalsStartSlot;
  340. IR::Opnd** m_saveLoopImplicitCallFlags;
  341. IR::RegOpnd * m_loopBodyForInEnumeratorArrayOpnd;
  342. #ifdef BYTECODE_BRANCH_ISLAND
  343. typedef JsUtil::BaseDictionary<uint32, uint32, JitArenaAllocator> LongBranchMap;
  344. LongBranchMap * longBranchMap;
  345. static IR::Instr * const VirtualLongBranchInstr;
  346. #endif
  347. };