JITTimeFunctionBody.cpp 34 KB

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