2
0

JITTimeFunctionBody.cpp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151
  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. #include "Backend.h"
  6. JITTimeFunctionBody::JITTimeFunctionBody(FunctionBodyDataIDL * bodyData) :
  7. m_bodyData(*bodyData)
  8. {
  9. CompileAssert(sizeof(JITTimeFunctionBody) == sizeof(FunctionBodyDataIDL));
  10. }
  11. /* static */
  12. void
  13. JITTimeFunctionBody::InitializeJITFunctionData(
  14. __in ArenaAllocator * arena,
  15. __in Js::FunctionBody *functionBody,
  16. __out FunctionBodyDataIDL * jitBody)
  17. {
  18. Assert(functionBody != nullptr);
  19. // const table
  20. jitBody->constCount = functionBody->GetConstantCount();
  21. if (functionBody->GetConstantCount() > 0)
  22. {
  23. jitBody->constTable = (intptr_t *)PointerValue(functionBody->GetConstTable());
  24. if (!functionBody->GetIsAsmJsFunction())
  25. {
  26. jitBody->constTableContent = AnewStructZ(arena, ConstTableContentIDL);
  27. jitBody->constTableContent->count = functionBody->GetConstantCount();
  28. jitBody->constTableContent->content = AnewArrayZ(arena, RecyclableObjectIDL*, functionBody->GetConstantCount());
  29. for (Js::RegSlot reg = Js::FunctionBody::FirstRegSlot; reg < functionBody->GetConstantCount(); ++reg)
  30. {
  31. Js::Var varConst = functionBody->GetConstantVar(reg);
  32. Assert(varConst != nullptr);
  33. if (Js::TaggedInt::Is(varConst) ||
  34. varConst == (Js::Var)&Js::NullFrameDisplay ||
  35. varConst == (Js::Var)&Js::StrictNullFrameDisplay)
  36. {
  37. // don't need TypeId for these
  38. }
  39. else
  40. {
  41. if (Js::TaggedNumber::Is(varConst))
  42. {
  43. // the typeid should be TypeIds_Number, determine this directly from const table
  44. }
  45. else
  46. {
  47. jitBody->constTableContent->content[reg - Js::FunctionBody::FirstRegSlot] = (RecyclableObjectIDL*)varConst;
  48. }
  49. }
  50. }
  51. }
  52. else if (functionBody->IsWasmFunction())
  53. {
  54. // no consts in wasm
  55. Assert(jitBody->constTable == nullptr);
  56. jitBody->constCount = 0;
  57. }
  58. }
  59. Js::SmallSpanSequence * statementMap = functionBody->GetStatementMapSpanSequence();
  60. // REVIEW: OOP JIT, is it possible for this to not match with isJitInDebugMode?
  61. if (functionBody->IsInDebugMode())
  62. {
  63. Assert(!statementMap);
  64. jitBody->byteCodeLength = functionBody->GetOriginalByteCode()->GetLength();
  65. jitBody->byteCodeBuffer = functionBody->GetOriginalByteCode()->GetBuffer();
  66. auto fullStatementMaps = functionBody->GetStatementMaps();
  67. jitBody->fullStatementMapCount = fullStatementMaps->Count();
  68. jitBody->fullStatementMaps = AnewArrayZ(arena, StatementMapIDL, jitBody->fullStatementMapCount);
  69. fullStatementMaps->Map([jitBody](int index, Js::FunctionBody::StatementMap * map) {
  70. jitBody->fullStatementMaps[index] = *(StatementMapIDL*)map;
  71. Assert(jitBody->fullStatementMaps[index].byteCodeSpanBegin == map->byteCodeSpan.Begin());
  72. Assert(jitBody->fullStatementMaps[index].byteCodeSpanEnd == map->byteCodeSpan.End());
  73. Assert(jitBody->fullStatementMaps[index].sourceSpanBegin == map->sourceSpan.Begin());
  74. Assert(jitBody->fullStatementMaps[index].sourceSpanEnd == map->sourceSpan.End());
  75. Assert((jitBody->fullStatementMaps[index].isSubExpression != FALSE) == map->isSubexpression);
  76. });
  77. Js::PropertyIdOnRegSlotsContainer * propOnRegSlots = functionBody->GetPropertyIdOnRegSlotsContainerWithLock();
  78. if (propOnRegSlots)
  79. {
  80. jitBody->propertyIdsForRegSlotsCount = propOnRegSlots->length;
  81. jitBody->propertyIdsForRegSlots = propOnRegSlots->propertyIdsForRegSlots;
  82. }
  83. }
  84. else
  85. {
  86. jitBody->byteCodeLength = functionBody->GetByteCode()->GetLength();
  87. jitBody->byteCodeBuffer = functionBody->GetByteCode()->GetBuffer();
  88. if (!functionBody->IsWasmFunction()) {
  89. Assert(statementMap);
  90. jitBody->statementMap = AnewStructZ(arena, SmallSpanSequenceIDL);
  91. jitBody->statementMap->baseValue = statementMap->baseValue;
  92. if (statementMap->pActualOffsetList)
  93. {
  94. jitBody->statementMap->actualOffsetLength = statementMap->pActualOffsetList->Count();
  95. jitBody->statementMap->actualOffsetList = statementMap->pActualOffsetList->GetBuffer();
  96. }
  97. if (statementMap->pStatementBuffer)
  98. {
  99. jitBody->statementMap->statementLength = statementMap->pStatementBuffer->Count();
  100. jitBody->statementMap->statementBuffer = statementMap->pStatementBuffer->GetBuffer();
  101. }
  102. }
  103. }
  104. jitBody->inlineCacheCount = functionBody->GetInlineCacheCount();
  105. if (functionBody->GetInlineCacheCount() > 0)
  106. {
  107. jitBody->cacheIdToPropertyIdMap = functionBody->GetCacheIdToPropertyIdMap();
  108. }
  109. jitBody->inlineCaches = reinterpret_cast<intptr_t*>(functionBody->GetInlineCaches());
  110. // body data
  111. jitBody->functionBodyAddr = (intptr_t)functionBody;
  112. jitBody->funcNumber = functionBody->GetFunctionNumber();
  113. jitBody->sourceContextId = functionBody->GetSourceContextId();
  114. jitBody->nestedCount = functionBody->GetNestedCount();
  115. if (functionBody->GetNestedCount() > 0)
  116. {
  117. jitBody->nestedFuncArrayAddr = (intptr_t)functionBody->GetNestedFuncArray();
  118. }
  119. jitBody->scopeSlotArraySize = functionBody->scopeSlotArraySize;
  120. jitBody->paramScopeSlotArraySize = functionBody->paramScopeSlotArraySize;
  121. jitBody->attributes = functionBody->GetAttributes();
  122. jitBody->isInstInlineCacheCount = functionBody->GetIsInstInlineCacheCount();
  123. jitBody->byteCodeCount = functionBody->GetByteCodeCount();
  124. jitBody->byteCodeInLoopCount = functionBody->GetByteCodeInLoopCount();
  125. jitBody->nonLoadByteCodeCount = functionBody->GetByteCodeWithoutLDACount();
  126. jitBody->loopCount = functionBody->GetLoopCount();
  127. Js::LoopHeader * loopHeaders = functionBody->GetLoopHeaderArrayWithLock();
  128. if (loopHeaders != nullptr)
  129. {
  130. jitBody->loopHeaderArrayAddr = (intptr_t)loopHeaders;
  131. jitBody->loopHeaderArrayLength = functionBody->GetLoopCount();
  132. jitBody->loopHeaders = AnewArray(arena, JITLoopHeaderIDL, functionBody->GetLoopCount());
  133. for (uint i = 0; i < functionBody->GetLoopCount(); ++i)
  134. {
  135. jitBody->loopHeaders[i].startOffset = loopHeaders[i].startOffset;
  136. jitBody->loopHeaders[i].endOffset = loopHeaders[i].endOffset;
  137. jitBody->loopHeaders[i].isNested = loopHeaders[i].isNested;
  138. jitBody->loopHeaders[i].isInTry = loopHeaders[i].isInTry;
  139. jitBody->loopHeaders[i].interpretCount = functionBody->GetLoopInterpretCount(&loopHeaders[i]);
  140. }
  141. }
  142. jitBody->localFrameDisplayReg = functionBody->GetLocalFrameDisplayRegister();
  143. jitBody->localClosureReg = functionBody->GetLocalClosureRegister();
  144. jitBody->envReg = functionBody->GetEnvRegister();
  145. jitBody->firstTmpReg = functionBody->GetFirstTmpReg();
  146. jitBody->varCount = functionBody->GetVarCount();
  147. jitBody->innerScopeCount = functionBody->GetInnerScopeCount();
  148. if (functionBody->GetInnerScopeCount() > 0)
  149. {
  150. jitBody->firstInnerScopeReg = functionBody->GetFirstInnerScopeRegister();
  151. }
  152. jitBody->envDepth = functionBody->GetEnvDepth();
  153. jitBody->profiledCallSiteCount = functionBody->GetProfiledCallSiteCount();
  154. jitBody->inParamCount = functionBody->GetInParamsCount();
  155. jitBody->thisRegisterForEventHandler = functionBody->GetThisRegisterForEventHandler();
  156. jitBody->funcExprScopeRegister = functionBody->GetFuncExprScopeRegister();
  157. jitBody->recursiveCallSiteCount = functionBody->GetNumberOfRecursiveCallSites();
  158. jitBody->forInLoopDepth = functionBody->GetForInLoopDepth();
  159. jitBody->argUsedForBranch = functionBody->m_argUsedForBranch;
  160. jitBody->flags = functionBody->GetFlags();
  161. jitBody->doBackendArgumentsOptimization = functionBody->GetDoBackendArgumentsOptimization();
  162. jitBody->isLibraryCode = functionBody->GetUtf8SourceInfo()->GetIsLibraryCode();
  163. jitBody->isAsmJsMode = functionBody->GetIsAsmjsMode();
  164. jitBody->isWasmFunction = functionBody->IsWasmFunction();
  165. jitBody->isStrictMode = functionBody->GetIsStrictMode();
  166. jitBody->isEval = functionBody->IsEval();
  167. jitBody->isGlobalFunc = functionBody->GetIsGlobalFunc();
  168. jitBody->isInlineApplyDisabled = functionBody->IsInlineApplyDisabled();
  169. jitBody->doJITLoopBody = functionBody->DoJITLoopBody();
  170. jitBody->hasScopeObject = functionBody->HasScopeObject();
  171. jitBody->hasImplicitArgIns = functionBody->GetHasImplicitArgIns();
  172. jitBody->hasCachedScopePropIds = functionBody->HasCachedScopePropIds();
  173. jitBody->inlineCachesOnFunctionObject = functionBody->GetInlineCachesOnFunctionObject();
  174. jitBody->doInterruptProbe = functionBody->GetScriptContext()->GetThreadContext()->DoInterruptProbe(functionBody);
  175. jitBody->disableInlineSpread = functionBody->IsInlineSpreadDisabled();
  176. jitBody->hasNestedLoop = functionBody->GetHasNestedLoop();
  177. jitBody->isParamAndBodyScopeMerged = functionBody->IsParamAndBodyScopeMerged();
  178. jitBody->paramClosureReg = functionBody->GetParamClosureRegister();
  179. jitBody->usesArgumentsObject = functionBody->GetUsesArgumentsObject();
  180. jitBody->doScopeObjectCreation = functionBody->GetDoScopeObjectCreation();
  181. //CompileAssert(sizeof(PropertyIdArrayIDL) == sizeof(Js::PropertyIdArray));
  182. jitBody->formalsPropIdArray = (PropertyIdArrayIDL*)functionBody->GetFormalsPropIdArray(false);
  183. jitBody->formalsPropIdArrayAddr = (intptr_t)functionBody->GetFormalsPropIdArray(false);
  184. jitBody->forInCacheArrayAddr = (intptr_t)functionBody->GetForInCacheArray();
  185. if (functionBody->HasDynamicProfileInfo() && Js::DynamicProfileInfo::HasCallSiteInfo(functionBody))
  186. {
  187. jitBody->hasNonBuiltInCallee = functionBody->HasNonBuiltInCallee();
  188. }
  189. Js::ByteBlock * auxData = functionBody->GetAuxiliaryDataWithLock();
  190. if (auxData != nullptr)
  191. {
  192. jitBody->auxDataCount = auxData->GetLength();
  193. jitBody->auxData = auxData->GetBuffer();
  194. jitBody->auxDataBufferAddr = (intptr_t)auxData->GetBuffer();
  195. }
  196. Js::ByteBlock * auxContextData = functionBody->GetAuxiliaryContextDataWithLock();
  197. if (auxContextData != nullptr)
  198. {
  199. jitBody->auxContextDataCount = auxContextData->GetLength();
  200. jitBody->auxContextData = auxContextData->GetBuffer();
  201. }
  202. jitBody->scriptIdAddr = (intptr_t)functionBody->GetAddressOfScriptId();
  203. jitBody->flagsAddr = (intptr_t)functionBody->GetAddressOfFlags();
  204. jitBody->probeCountAddr = (intptr_t)&functionBody->GetSourceInfo()->m_probeCount;
  205. jitBody->regAllocLoadCountAddr = (intptr_t)&functionBody->regAllocLoadCount;
  206. jitBody->regAllocStoreCountAddr = (intptr_t)&functionBody->regAllocStoreCount;
  207. jitBody->callCountStatsAddr = (intptr_t)&functionBody->callCountStats;
  208. jitBody->referencedPropertyIdCount = functionBody->GetReferencedPropertyIdCount();
  209. jitBody->referencedPropertyIdMap = functionBody->GetReferencedPropertyIdMapWithLock();
  210. jitBody->hasFinally = functionBody->GetHasFinally();
  211. jitBody->nameLength = functionBody->GetDisplayNameLength() + 1; // +1 for null terminator
  212. jitBody->displayName = (char16 *)functionBody->GetDisplayName();
  213. jitBody->objectLiteralTypesAddr = (intptr_t)functionBody->GetObjectLiteralTypesWithLock();
  214. jitBody->literalRegexCount = functionBody->GetLiteralRegexCount();
  215. jitBody->literalRegexes = (intptr_t*)functionBody->GetLiteralRegexesWithLock();
  216. Js::AuxArray<uint32> * slotIdInCachedScopeToNestedIndexArray = functionBody->GetSlotIdInCachedScopeToNestedIndexArrayWithLock();
  217. if (slotIdInCachedScopeToNestedIndexArray)
  218. {
  219. jitBody->functionSlotsInCachedScopeCount = slotIdInCachedScopeToNestedIndexArray->count;
  220. jitBody->slotIdInCachedScopeToNestedIndexArray = slotIdInCachedScopeToNestedIndexArray->elements;
  221. }
  222. #ifdef ASMJS_PLAT
  223. if (functionBody->GetIsAsmJsFunction())
  224. {
  225. jitBody->asmJsData = Anew(arena, AsmJsDataIDL);
  226. Js::AsmJsFunctionInfo * asmFuncInfo = functionBody->GetAsmJsFunctionInfoWithLock();
  227. // 5 is hard coded in JITTypes.h
  228. CompileAssert(WAsmJs::LIMIT == 5);
  229. for (int i = 0; i < WAsmJs::LIMIT; ++i)
  230. {
  231. WAsmJs::Types type = (WAsmJs::Types)i;
  232. const auto typedInfo = asmFuncInfo->GetTypedSlotInfo(type);
  233. jitBody->asmJsData->typedSlotInfos[i].byteOffset = typedInfo->byteOffset;
  234. jitBody->asmJsData->typedSlotInfos[i].constCount = typedInfo->constCount;
  235. jitBody->asmJsData->typedSlotInfos[i].constSrcByteOffset = typedInfo->constSrcByteOffset;
  236. jitBody->asmJsData->typedSlotInfos[i].tmpCount = typedInfo->tmpCount;
  237. jitBody->asmJsData->typedSlotInfos[i].varCount = typedInfo->varCount;
  238. }
  239. jitBody->asmJsData->argCount = asmFuncInfo->GetArgCount();
  240. jitBody->asmJsData->argTypeArray = (byte*)asmFuncInfo->GetArgTypeArray();
  241. jitBody->asmJsData->argByteSize = asmFuncInfo->GetArgByteSize();
  242. jitBody->asmJsData->retType = asmFuncInfo->GetReturnType().which();
  243. jitBody->asmJsData->usesHeapBuffer = asmFuncInfo->UsesHeapBuffer();
  244. jitBody->asmJsData->totalSizeInBytes = asmFuncInfo->GetTotalSizeinBytes();
  245. #ifdef ENABLE_WASM
  246. if (functionBody->IsWasmFunction())
  247. {
  248. jitBody->asmJsData->wasmSignatureCount = asmFuncInfo->GetWebAssemblyModule()->GetSignatureCount();
  249. jitBody->asmJsData->wasmSignaturesBaseAddr = (intptr_t)asmFuncInfo->GetWebAssemblyModule()->GetSignatures();
  250. jitBody->asmJsData->wasmSignatures = (WasmSignatureIDL*)asmFuncInfo->GetWebAssemblyModule()->GetSignatures();
  251. }
  252. #endif
  253. }
  254. #endif
  255. }
  256. intptr_t
  257. JITTimeFunctionBody::GetAddr() const
  258. {
  259. return m_bodyData.functionBodyAddr;
  260. }
  261. uint
  262. JITTimeFunctionBody::GetFunctionNumber() const
  263. {
  264. return m_bodyData.funcNumber;
  265. }
  266. uint
  267. JITTimeFunctionBody::GetSourceContextId() const
  268. {
  269. return m_bodyData.sourceContextId;
  270. }
  271. uint
  272. JITTimeFunctionBody::GetNestedCount() const
  273. {
  274. return m_bodyData.nestedCount;
  275. }
  276. uint
  277. JITTimeFunctionBody::GetScopeSlotArraySize() const
  278. {
  279. return m_bodyData.scopeSlotArraySize;
  280. }
  281. uint
  282. JITTimeFunctionBody::GetParamScopeSlotArraySize() const
  283. {
  284. return m_bodyData.paramScopeSlotArraySize;
  285. }
  286. uint
  287. JITTimeFunctionBody::GetByteCodeCount() const
  288. {
  289. return m_bodyData.byteCodeCount;
  290. }
  291. uint
  292. JITTimeFunctionBody::GetByteCodeInLoopCount() const
  293. {
  294. return m_bodyData.byteCodeInLoopCount;
  295. }
  296. uint
  297. JITTimeFunctionBody::GetNonLoadByteCodeCount() const
  298. {
  299. return m_bodyData.nonLoadByteCodeCount;
  300. }
  301. uint
  302. JITTimeFunctionBody::GetLoopCount() const
  303. {
  304. return m_bodyData.loopCount;
  305. }
  306. bool
  307. JITTimeFunctionBody::HasLoops() const
  308. {
  309. return GetLoopCount() != 0;
  310. }
  311. uint
  312. JITTimeFunctionBody::GetByteCodeLength() const
  313. {
  314. return m_bodyData.byteCodeLength;
  315. }
  316. uint
  317. JITTimeFunctionBody::GetInnerScopeCount() const
  318. {
  319. return m_bodyData.innerScopeCount;
  320. }
  321. uint
  322. JITTimeFunctionBody::GetInlineCacheCount() const
  323. {
  324. return m_bodyData.inlineCacheCount;
  325. }
  326. uint
  327. JITTimeFunctionBody::GetRecursiveCallSiteCount() const
  328. {
  329. return m_bodyData.recursiveCallSiteCount;
  330. }
  331. uint
  332. JITTimeFunctionBody::GetForInLoopDepth() const
  333. {
  334. return m_bodyData.forInLoopDepth;
  335. }
  336. Js::RegSlot
  337. JITTimeFunctionBody::GetLocalFrameDisplayReg() const
  338. {
  339. return static_cast<Js::RegSlot>(m_bodyData.localFrameDisplayReg);
  340. }
  341. Js::RegSlot
  342. JITTimeFunctionBody::GetLocalClosureReg() const
  343. {
  344. return static_cast<Js::RegSlot>(m_bodyData.localClosureReg);
  345. }
  346. Js::RegSlot
  347. JITTimeFunctionBody::GetEnvReg() const
  348. {
  349. return static_cast<Js::RegSlot>(m_bodyData.envReg);
  350. }
  351. Js::RegSlot
  352. JITTimeFunctionBody::GetFirstTmpReg() const
  353. {
  354. return static_cast<Js::RegSlot>(m_bodyData.firstTmpReg);
  355. }
  356. Js::RegSlot
  357. JITTimeFunctionBody::GetFirstInnerScopeReg() const
  358. {
  359. return static_cast<Js::RegSlot>(m_bodyData.firstInnerScopeReg);
  360. }
  361. Js::RegSlot
  362. JITTimeFunctionBody::GetVarCount() const
  363. {
  364. return static_cast<Js::RegSlot>(m_bodyData.varCount);
  365. }
  366. Js::RegSlot
  367. JITTimeFunctionBody::GetConstCount() const
  368. {
  369. return static_cast<Js::RegSlot>(m_bodyData.constCount);
  370. }
  371. Js::RegSlot
  372. JITTimeFunctionBody::GetLocalsCount() const
  373. {
  374. return GetConstCount() + GetVarCount();
  375. }
  376. Js::RegSlot
  377. JITTimeFunctionBody::GetTempCount() const
  378. {
  379. return GetLocalsCount() - GetFirstTmpReg();
  380. }
  381. Js::RegSlot
  382. JITTimeFunctionBody::GetFuncExprScopeReg() const
  383. {
  384. return static_cast<Js::RegSlot>(m_bodyData.funcExprScopeRegister);
  385. }
  386. Js::RegSlot
  387. JITTimeFunctionBody::GetThisRegForEventHandler() const
  388. {
  389. return static_cast<Js::RegSlot>(m_bodyData.thisRegisterForEventHandler);
  390. }
  391. Js::RegSlot
  392. JITTimeFunctionBody::GetParamClosureReg() const
  393. {
  394. return static_cast<Js::RegSlot>(m_bodyData.paramClosureReg);
  395. }
  396. Js::RegSlot
  397. JITTimeFunctionBody::GetFirstNonTempLocalIndex() const
  398. {
  399. // First local var starts when the const vars end.
  400. return GetConstCount();
  401. }
  402. Js::RegSlot
  403. JITTimeFunctionBody::GetEndNonTempLocalIndex() const
  404. {
  405. // It will give the index on which current non temp locals ends, which is a first temp reg.
  406. return GetFirstTmpReg() != Js::Constants::NoRegister ? GetFirstTmpReg() : GetLocalsCount();
  407. }
  408. Js::RegSlot
  409. JITTimeFunctionBody::GetNonTempLocalVarCount() const
  410. {
  411. Assert(GetEndNonTempLocalIndex() >= GetFirstNonTempLocalIndex());
  412. return GetEndNonTempLocalIndex() - GetFirstNonTempLocalIndex();
  413. }
  414. Js::RegSlot
  415. JITTimeFunctionBody::GetRestParamRegSlot() const
  416. {
  417. Js::RegSlot dstRegSlot = GetConstCount();
  418. if (HasImplicitArgIns())
  419. {
  420. dstRegSlot += GetInParamsCount() - 1;
  421. }
  422. return dstRegSlot;
  423. }
  424. Js::PropertyId
  425. JITTimeFunctionBody::GetPropertyIdFromCacheId(uint cacheId) const
  426. {
  427. Assert(m_bodyData.cacheIdToPropertyIdMap);
  428. Assert(cacheId < GetInlineCacheCount());
  429. return static_cast<Js::PropertyId>(m_bodyData.cacheIdToPropertyIdMap[cacheId]);
  430. }
  431. Js::PropertyId
  432. JITTimeFunctionBody::GetReferencedPropertyId(uint index) const
  433. {
  434. if (index < (uint)TotalNumberOfBuiltInProperties)
  435. {
  436. return index;
  437. }
  438. uint mapIndex = index - TotalNumberOfBuiltInProperties;
  439. Assert(m_bodyData.referencedPropertyIdMap != nullptr);
  440. Assert(mapIndex < m_bodyData.referencedPropertyIdCount);
  441. return m_bodyData.referencedPropertyIdMap[mapIndex];
  442. }
  443. uint16
  444. JITTimeFunctionBody::GetArgUsedForBranch() const
  445. {
  446. return m_bodyData.argUsedForBranch;
  447. }
  448. uint16
  449. JITTimeFunctionBody::GetEnvDepth() const
  450. {
  451. return m_bodyData.envDepth;
  452. }
  453. Js::ProfileId
  454. JITTimeFunctionBody::GetProfiledCallSiteCount() const
  455. {
  456. return static_cast<Js::ProfileId>(m_bodyData.profiledCallSiteCount);
  457. }
  458. Js::ArgSlot
  459. JITTimeFunctionBody::GetInParamsCount() const
  460. {
  461. return static_cast<Js::ArgSlot>(m_bodyData.inParamCount);
  462. }
  463. bool
  464. JITTimeFunctionBody::DoStackNestedFunc() const
  465. {
  466. return Js::FunctionBody::DoStackNestedFunc(GetFlags());
  467. }
  468. bool
  469. JITTimeFunctionBody::DoStackClosure() const
  470. {
  471. return Js::FunctionBody::DoStackClosure(this);
  472. }
  473. bool
  474. JITTimeFunctionBody::HasTry() const
  475. {
  476. return Js::FunctionBody::GetHasTry(GetFlags());
  477. }
  478. bool
  479. JITTimeFunctionBody::HasThis() const
  480. {
  481. return Js::FunctionBody::GetHasThis(GetFlags());
  482. }
  483. bool
  484. JITTimeFunctionBody::HasFinally() const
  485. {
  486. return m_bodyData.hasFinally != FALSE;
  487. }
  488. bool
  489. JITTimeFunctionBody::HasOrParentHasArguments() const
  490. {
  491. return Js::FunctionBody::GetHasOrParentHasArguments(GetFlags());
  492. }
  493. bool
  494. JITTimeFunctionBody::DoBackendArgumentsOptimization() const
  495. {
  496. return m_bodyData.doBackendArgumentsOptimization != FALSE;
  497. }
  498. bool
  499. JITTimeFunctionBody::IsLibraryCode() const
  500. {
  501. return m_bodyData.isLibraryCode != FALSE;
  502. }
  503. bool
  504. JITTimeFunctionBody::IsAsmJsMode() const
  505. {
  506. return m_bodyData.isAsmJsMode != FALSE;
  507. }
  508. bool
  509. JITTimeFunctionBody::IsWasmFunction() const
  510. {
  511. return m_bodyData.isWasmFunction != FALSE;
  512. }
  513. bool
  514. JITTimeFunctionBody::IsStrictMode() const
  515. {
  516. return m_bodyData.isStrictMode != FALSE;
  517. }
  518. bool
  519. JITTimeFunctionBody::IsEval() const
  520. {
  521. return m_bodyData.isEval != FALSE;
  522. }
  523. bool
  524. JITTimeFunctionBody::HasScopeObject() const
  525. {
  526. return m_bodyData.hasScopeObject != FALSE;
  527. }
  528. bool
  529. JITTimeFunctionBody::HasNestedLoop() const
  530. {
  531. return m_bodyData.hasNestedLoop != FALSE;
  532. }
  533. bool
  534. JITTimeFunctionBody::UsesArgumentsObject() const
  535. {
  536. return m_bodyData.usesArgumentsObject != FALSE;
  537. }
  538. bool
  539. JITTimeFunctionBody::IsParamAndBodyScopeMerged() const
  540. {
  541. return m_bodyData.isParamAndBodyScopeMerged != FALSE;
  542. }
  543. bool
  544. JITTimeFunctionBody::IsCoroutine() const
  545. {
  546. return Js::FunctionInfo::IsCoroutine(GetAttributes());
  547. }
  548. bool
  549. JITTimeFunctionBody::IsGenerator() const
  550. {
  551. return Js::FunctionInfo::IsGenerator(GetAttributes());
  552. }
  553. bool
  554. JITTimeFunctionBody::IsLambda() const
  555. {
  556. return Js::FunctionInfo::IsLambda(GetAttributes());
  557. }
  558. bool
  559. JITTimeFunctionBody::HasImplicitArgIns() const
  560. {
  561. return m_bodyData.hasImplicitArgIns != FALSE;
  562. }
  563. bool
  564. JITTimeFunctionBody::HasCachedScopePropIds() const
  565. {
  566. return m_bodyData.hasCachedScopePropIds != FALSE;
  567. }
  568. bool
  569. JITTimeFunctionBody::HasInlineCachesOnFunctionObject() const
  570. {
  571. return m_bodyData.inlineCachesOnFunctionObject != FALSE;
  572. }
  573. bool
  574. JITTimeFunctionBody::DoInterruptProbe() const
  575. {
  576. // TODO michhol: this is technically a threadcontext flag,
  577. // may want to pass all these when initializing thread context
  578. return m_bodyData.doInterruptProbe != FALSE;
  579. }
  580. bool
  581. JITTimeFunctionBody::HasRestParameter() const
  582. {
  583. return Js::FunctionBody::GetHasRestParameter(GetFlags());
  584. }
  585. bool
  586. JITTimeFunctionBody::IsGlobalFunc() const
  587. {
  588. return m_bodyData.isGlobalFunc != FALSE;
  589. }
  590. void
  591. JITTimeFunctionBody::DisableInlineApply()
  592. {
  593. m_bodyData.isInlineApplyDisabled = TRUE;
  594. }
  595. bool
  596. JITTimeFunctionBody::IsInlineApplyDisabled() const
  597. {
  598. return m_bodyData.isInlineApplyDisabled != FALSE;
  599. }
  600. bool
  601. JITTimeFunctionBody::IsNonTempLocalVar(uint32 varIndex) const
  602. {
  603. return GetFirstNonTempLocalIndex() <= varIndex && varIndex < GetEndNonTempLocalIndex();
  604. }
  605. bool
  606. JITTimeFunctionBody::DoJITLoopBody() const
  607. {
  608. return m_bodyData.doJITLoopBody != FALSE;
  609. }
  610. void
  611. JITTimeFunctionBody::DisableInlineSpread()
  612. {
  613. m_bodyData.disableInlineSpread = TRUE;
  614. }
  615. bool
  616. JITTimeFunctionBody::IsInlineSpreadDisabled() const
  617. {
  618. return m_bodyData.disableInlineSpread != FALSE;
  619. }
  620. bool
  621. JITTimeFunctionBody::HasNonBuiltInCallee() const
  622. {
  623. return m_bodyData.hasNonBuiltInCallee != FALSE;
  624. }
  625. bool
  626. JITTimeFunctionBody::CanInlineRecursively(uint depth, bool tryAggressive) const
  627. {
  628. uint recursiveInlineSpan = GetRecursiveCallSiteCount();
  629. uint minRecursiveInlineDepth = (uint)CONFIG_FLAG(RecursiveInlineDepthMin);
  630. if (recursiveInlineSpan != GetProfiledCallSiteCount() || tryAggressive == false)
  631. {
  632. return depth < minRecursiveInlineDepth;
  633. }
  634. uint maxRecursiveInlineDepth = (uint)CONFIG_FLAG(RecursiveInlineDepthMax);
  635. uint maxRecursiveBytecodeBudget = (uint)CONFIG_FLAG(RecursiveInlineThreshold);
  636. uint numberOfAllowedFuncs = maxRecursiveBytecodeBudget / GetNonLoadByteCodeCount();
  637. uint maxDepth;
  638. if (recursiveInlineSpan == 1)
  639. {
  640. maxDepth = numberOfAllowedFuncs;
  641. }
  642. else
  643. {
  644. maxDepth = (uint)ceil(log((double)((double)numberOfAllowedFuncs) / log((double)recursiveInlineSpan)));
  645. }
  646. maxDepth = maxDepth < minRecursiveInlineDepth ? minRecursiveInlineDepth : maxDepth;
  647. maxDepth = maxDepth < maxRecursiveInlineDepth ? maxDepth : maxRecursiveInlineDepth;
  648. return depth < maxDepth;
  649. }
  650. bool
  651. JITTimeFunctionBody::NeedScopeObjectForArguments(bool hasNonSimpleParams) const
  652. {
  653. // TODO: OOP JIT, enable assert
  654. //Assert(HasReferenceableBuiltInArguments());
  655. // We can avoid creating a scope object with arguments present if:
  656. bool dontNeedScopeObject =
  657. // Either we are in strict mode, or have strict mode formal semantics from a non-simple parameter list, and
  658. (IsStrictMode() || hasNonSimpleParams)
  659. // Neither of the scopes are objects
  660. && !HasScopeObject();
  661. return
  662. // Regardless of the conditions above, we won't need a scope object if there aren't any formals.
  663. (GetInParamsCount() > 1 || HasRestParameter())
  664. && !dontNeedScopeObject;
  665. }
  666. bool
  667. JITTimeFunctionBody::GetDoScopeObjectCreation() const
  668. {
  669. return !!m_bodyData.doScopeObjectCreation;
  670. }
  671. const byte *
  672. JITTimeFunctionBody::GetByteCodeBuffer() const
  673. {
  674. return m_bodyData.byteCodeBuffer;
  675. }
  676. StatementMapIDL *
  677. JITTimeFunctionBody::GetFullStatementMap() const
  678. {
  679. return m_bodyData.fullStatementMaps;
  680. }
  681. uint
  682. JITTimeFunctionBody::GetFullStatementMapCount() const
  683. {
  684. return m_bodyData.fullStatementMapCount;
  685. }
  686. intptr_t
  687. JITTimeFunctionBody::GetScriptIdAddr() const
  688. {
  689. return m_bodyData.scriptIdAddr;
  690. }
  691. intptr_t
  692. JITTimeFunctionBody::GetProbeCountAddr() const
  693. {
  694. return m_bodyData.probeCountAddr;
  695. }
  696. intptr_t
  697. JITTimeFunctionBody::GetFlagsAddr() const
  698. {
  699. return m_bodyData.flagsAddr;
  700. }
  701. intptr_t
  702. JITTimeFunctionBody::GetRegAllocLoadCountAddr() const
  703. {
  704. return m_bodyData.regAllocLoadCountAddr;
  705. }
  706. intptr_t
  707. JITTimeFunctionBody::GetFormalsPropIdArrayAddr() const
  708. {
  709. return m_bodyData.formalsPropIdArrayAddr;
  710. }
  711. intptr_t
  712. JITTimeFunctionBody::GetRegAllocStoreCountAddr() const
  713. {
  714. return m_bodyData.regAllocStoreCountAddr;
  715. }
  716. intptr_t
  717. JITTimeFunctionBody::GetCallCountStatsAddr() const
  718. {
  719. return m_bodyData.callCountStatsAddr;
  720. }
  721. intptr_t
  722. JITTimeFunctionBody::GetObjectLiteralTypeRef(uint index) const
  723. {
  724. Assert(m_bodyData.objectLiteralTypesAddr != 0);
  725. return m_bodyData.objectLiteralTypesAddr + index * MachPtr;
  726. }
  727. intptr_t
  728. JITTimeFunctionBody::GetConstantVar(Js::RegSlot location) const
  729. {
  730. Assert(m_bodyData.constTable != nullptr);
  731. Assert(location < GetConstCount());
  732. Assert(location != 0);
  733. return static_cast<intptr_t>(m_bodyData.constTable[location - Js::FunctionBody::FirstRegSlot]);
  734. }
  735. JITRecyclableObject *
  736. JITTimeFunctionBody::GetConstantContent(Js::RegSlot location) const
  737. {
  738. Assert(m_bodyData.constTableContent != nullptr);
  739. Assert(m_bodyData.constTableContent->content != nullptr);
  740. Assert(location < GetConstCount());
  741. Assert(location != 0);
  742. JITRecyclableObject * obj = (JITRecyclableObject *)m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot];
  743. Assert(obj);
  744. return obj;
  745. }
  746. void
  747. JITTimeFunctionBody::EnsureConsistentConstCount() const
  748. {
  749. if (GetConstCount() == 0 || IsAsmJsMode())
  750. {
  751. AssertOrFailFast(m_bodyData.constTableContent == nullptr);
  752. }
  753. else
  754. {
  755. AssertOrFailFast(m_bodyData.constTableContent != nullptr && GetConstCount() == m_bodyData.constTableContent->count);
  756. }
  757. }
  758. intptr_t
  759. JITTimeFunctionBody::GetInlineCache(uint index) const
  760. {
  761. Assert(m_bodyData.inlineCaches != nullptr);
  762. Assert(index < GetInlineCacheCount());
  763. #if 0 // TODO: michhol OOP JIT, add these asserts
  764. Assert(this->m_inlineCacheTypes[index] == InlineCacheTypeNone ||
  765. this->m_inlineCacheTypes[index] == InlineCacheTypeInlineCache);
  766. this->m_inlineCacheTypes[index] = InlineCacheTypeInlineCache;
  767. #endif
  768. return static_cast<intptr_t>(m_bodyData.inlineCaches[index]);
  769. }
  770. intptr_t
  771. JITTimeFunctionBody::GetIsInstInlineCache(uint index) const
  772. {
  773. Assert(m_bodyData.inlineCaches != nullptr);
  774. Assert(index < m_bodyData.isInstInlineCacheCount);
  775. index += GetInlineCacheCount();
  776. #if 0 // TODO: michhol OOP JIT, add these asserts
  777. Assert(this->m_inlineCacheTypes[index] == InlineCacheTypeNone ||
  778. this->m_inlineCacheTypes[index] == InlineCacheTypeIsInst);
  779. this->m_inlineCacheTypes[index] = InlineCacheTypeIsInst;
  780. #endif
  781. return static_cast<intptr_t>(m_bodyData.inlineCaches[index]);
  782. }
  783. Js::TypeId
  784. JITTimeFunctionBody::GetConstantType(Js::RegSlot location) const
  785. {
  786. Assert(m_bodyData.constTable != nullptr);
  787. Assert(m_bodyData.constTableContent != nullptr);
  788. Assert(location < GetConstCount());
  789. Assert(location != 0);
  790. auto obj = m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot];
  791. if (obj == nullptr)
  792. {
  793. if (Js::TaggedNumber::Is((Js::Var)GetConstantVar(location)))
  794. {
  795. // tagged float
  796. return Js::TypeId::TypeIds_Number;
  797. }
  798. else
  799. {
  800. return Js::TypeId::TypeIds_Limit;
  801. }
  802. }
  803. return static_cast<Js::TypeId>(*(obj->typeId));
  804. }
  805. intptr_t
  806. JITTimeFunctionBody::GetLiteralRegexAddr(uint index) const
  807. {
  808. Assert(index < m_bodyData.literalRegexCount);
  809. return m_bodyData.literalRegexes[index];
  810. }
  811. uint
  812. JITTimeFunctionBody::GetNestedFuncIndexForSlotIdInCachedScope(uint index) const
  813. {
  814. AssertOrFailFast(m_bodyData.slotIdInCachedScopeToNestedIndexArray != nullptr);
  815. AssertOrFailFast(index < m_bodyData.functionSlotsInCachedScopeCount);
  816. return m_bodyData.slotIdInCachedScopeToNestedIndexArray[index];
  817. }
  818. void *
  819. JITTimeFunctionBody::GetConstTable() const
  820. {
  821. return m_bodyData.constTable;
  822. }
  823. bool
  824. JITTimeFunctionBody::IsConstRegPropertyString(Js::RegSlot reg, ScriptContextInfo * context) const
  825. {
  826. RecyclableObjectIDL * content = m_bodyData.constTableContent->content[reg - Js::FunctionBody::FirstRegSlot];
  827. if (content != nullptr && content->vtbl == context->GetVTableAddress(VtablePropertyString))
  828. {
  829. return true;
  830. }
  831. return false;
  832. }
  833. intptr_t
  834. JITTimeFunctionBody::GetRootObject() const
  835. {
  836. Assert(m_bodyData.constTable != nullptr);
  837. return m_bodyData.constTable[Js::FunctionBody::RootObjectRegSlot - Js::FunctionBody::FirstRegSlot];
  838. }
  839. Js::FunctionInfoPtrPtr
  840. JITTimeFunctionBody::GetNestedFuncRef(uint index) const
  841. {
  842. Assert(index < GetNestedCount());
  843. Js::FunctionInfoPtrPtr baseAddr = (Js::FunctionInfoPtrPtr)m_bodyData.nestedFuncArrayAddr;
  844. return baseAddr + index;
  845. }
  846. intptr_t
  847. JITTimeFunctionBody::GetLoopHeaderAddr(uint loopNum) const
  848. {
  849. Assert(loopNum < GetLoopCount());
  850. intptr_t baseAddr = m_bodyData.loopHeaderArrayAddr;
  851. return baseAddr + (loopNum * sizeof(Js::LoopHeader));
  852. }
  853. const JITLoopHeaderIDL *
  854. JITTimeFunctionBody::GetLoopHeaderData(uint loopNum) const
  855. {
  856. Assert(loopNum < GetLoopCount());
  857. return &m_bodyData.loopHeaders[loopNum];
  858. }
  859. const AsmJsJITInfo *
  860. JITTimeFunctionBody::GetAsmJsInfo() const
  861. {
  862. return reinterpret_cast<const AsmJsJITInfo *>(m_bodyData.asmJsData);
  863. }
  864. JITTimeProfileInfo *
  865. JITTimeFunctionBody::GetProfileInfo() const
  866. {
  867. return reinterpret_cast<JITTimeProfileInfo *>(m_bodyData.profileData);
  868. }
  869. const JITTimeProfileInfo *
  870. JITTimeFunctionBody::GetReadOnlyProfileInfo() const
  871. {
  872. return reinterpret_cast<const JITTimeProfileInfo *>(m_bodyData.profileData);
  873. }
  874. bool
  875. JITTimeFunctionBody::HasProfileInfo() const
  876. {
  877. return m_bodyData.profileData != nullptr;
  878. }
  879. bool
  880. JITTimeFunctionBody::HasPropIdToFormalsMap() const
  881. {
  882. return m_bodyData.propertyIdsForRegSlotsCount > 0 && GetFormalsPropIdArray() != nullptr;
  883. }
  884. bool
  885. JITTimeFunctionBody::IsRegSlotFormal(Js::RegSlot reg) const
  886. {
  887. Assert(reg < m_bodyData.propertyIdsForRegSlotsCount);
  888. Js::PropertyId propId = (Js::PropertyId)m_bodyData.propertyIdsForRegSlots[reg];
  889. Js::PropertyIdArray * formalProps = GetFormalsPropIdArray();
  890. for (uint32 i = 0; i < formalProps->count; i++)
  891. {
  892. if (formalProps->elements[i] == propId)
  893. {
  894. return true;
  895. }
  896. }
  897. return false;
  898. }
  899. /* static */
  900. bool
  901. JITTimeFunctionBody::LoopContains(const JITLoopHeaderIDL * loop1, const JITLoopHeaderIDL * loop2)
  902. {
  903. return (loop1->startOffset <= loop2->startOffset && loop2->endOffset <= loop1->endOffset);
  904. }
  905. Js::FunctionBody::FunctionBodyFlags
  906. JITTimeFunctionBody::GetFlags() const
  907. {
  908. return static_cast<Js::FunctionBody::FunctionBodyFlags>(m_bodyData.flags);
  909. }
  910. Js::FunctionInfo::Attributes
  911. JITTimeFunctionBody::GetAttributes() const
  912. {
  913. return static_cast<Js::FunctionInfo::Attributes>(m_bodyData.attributes);
  914. }
  915. intptr_t
  916. JITTimeFunctionBody::GetAuxDataAddr(uint offset) const
  917. {
  918. return m_bodyData.auxDataBufferAddr + offset;
  919. }
  920. void *
  921. JITTimeFunctionBody::ReadFromAuxData(uint offset) const
  922. {
  923. AssertOrFailFast(offset < m_bodyData.auxDataCount);
  924. return (void *)(m_bodyData.auxData + offset);
  925. }
  926. void *
  927. JITTimeFunctionBody::ReadFromAuxContextData(uint offset) const
  928. {
  929. AssertOrFailFast(offset < m_bodyData.auxContextDataCount);
  930. return (void *)(m_bodyData.auxContextData + offset);
  931. }
  932. const Js::PropertyIdArray *
  933. JITTimeFunctionBody::ReadPropertyIdArrayFromAuxData(uint offset) const
  934. {
  935. Js::PropertyIdArray * auxArray = (Js::PropertyIdArray *)(m_bodyData.auxData + offset);
  936. AssertOrFailFast(AllocSizeMath::Add(offset, auxArray->GetDataSize()) <= m_bodyData.auxDataCount);
  937. return auxArray;
  938. }
  939. Js::PropertyIdArray *
  940. JITTimeFunctionBody::GetFormalsPropIdArray() const
  941. {
  942. return (Js::PropertyIdArray *)m_bodyData.formalsPropIdArray;
  943. }
  944. Js::ForInCache *
  945. JITTimeFunctionBody::GetForInCache(uint profileId) const
  946. {
  947. return &((Js::ForInCache *)m_bodyData.forInCacheArrayAddr)[profileId];
  948. }
  949. bool
  950. JITTimeFunctionBody::InitializeStatementMap(Js::SmallSpanSequence * statementMap, ArenaAllocator* alloc) const
  951. {
  952. if (!m_bodyData.statementMap)
  953. {
  954. return false;
  955. }
  956. const uint statementsLength = m_bodyData.statementMap->statementLength;
  957. const uint offsetsLength = m_bodyData.statementMap->actualOffsetLength;
  958. statementMap->baseValue = m_bodyData.statementMap->baseValue;
  959. // TODO: (leish OOP JIT) using arena to prevent memory leak, fix to really implement GrowingUint32ArenaArray::Create()
  960. // or find other way to reuse like michhol's comments
  961. typedef JsUtil::GrowingArray<uint32, ArenaAllocator> GrowingUint32ArenaArray;
  962. if (statementsLength > 0)
  963. {
  964. // TODO: (michhol OOP JIT) should be able to directly use statementMap.statementBuffer
  965. statementMap->pStatementBuffer = (JsUtil::GrowingUint32HeapArray*)Anew(alloc, GrowingUint32ArenaArray, alloc, statementsLength);
  966. statementMap->pStatementBuffer->SetCount(statementsLength);
  967. js_memcpy_s(
  968. statementMap->pStatementBuffer->GetBuffer(),
  969. statementMap->pStatementBuffer->Count() * sizeof(uint32),
  970. m_bodyData.statementMap->statementBuffer,
  971. statementsLength * sizeof(uint32));
  972. }
  973. if (offsetsLength > 0)
  974. {
  975. statementMap->pActualOffsetList = (JsUtil::GrowingUint32HeapArray*)Anew(alloc, GrowingUint32ArenaArray, alloc, offsetsLength);
  976. statementMap->pActualOffsetList->SetCount(offsetsLength);
  977. js_memcpy_s(
  978. statementMap->pActualOffsetList->GetBuffer(),
  979. statementMap->pActualOffsetList->Count() * sizeof(uint32),
  980. m_bodyData.statementMap->actualOffsetList,
  981. offsetsLength * sizeof(uint32));
  982. }
  983. return true;
  984. }
  985. char16*
  986. JITTimeFunctionBody::GetDisplayName() const
  987. {
  988. return m_bodyData.displayName;
  989. }