JITTimeProfileInfo.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  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. JITTimeProfileInfo::JITTimeProfileInfo(ProfileDataIDL * profileData) :
  7. m_profileData(*profileData)
  8. {
  9. CompileAssert(sizeof(JITTimeProfileInfo) == sizeof(ProfileDataIDL));
  10. }
  11. /* static */
  12. void
  13. JITTimeProfileInfo::InitializeJITProfileData(
  14. __in ArenaAllocator * alloc,
  15. __in Js::DynamicProfileInfo * profileInfo,
  16. __in Js::FunctionBody *functionBody,
  17. __out ProfileDataIDL * data,
  18. bool isForegroundJIT)
  19. {
  20. if (profileInfo == nullptr)
  21. {
  22. return;
  23. }
  24. CompileAssert(sizeof(LdLenIDL) == sizeof(Js::LdLenInfo));
  25. CompileAssert(sizeof(LdElemIDL) == sizeof(Js::LdElemInfo));
  26. CompileAssert(sizeof(StElemIDL) == sizeof(Js::StElemInfo));
  27. data->profiledLdLenCount = functionBody->GetProfiledLdLenCount();
  28. data->profiledLdElemCount = functionBody->GetProfiledLdElemCount();
  29. data->profiledStElemCount = functionBody->GetProfiledStElemCount();
  30. if (JITManager::GetJITManager()->IsOOPJITEnabled() || isForegroundJIT)
  31. {
  32. data->ldLenData = (LdLenIDL*)profileInfo->GetLdLenInfo();
  33. data->ldElemData = (LdElemIDL*)profileInfo->GetLdElemInfo();
  34. data->stElemData = (StElemIDL*)profileInfo->GetStElemInfo();
  35. }
  36. else
  37. {
  38. // for in-proc background JIT we need to explicitly copy LdLen, LdElem, and StElem info
  39. data->ldLenData = AnewArray(alloc, LdLenIDL, data->profiledLdLenCount);
  40. memcpy_s(
  41. data->ldLenData,
  42. data->profiledLdLenCount * sizeof(LdLenIDL),
  43. profileInfo->GetLdLenInfo(),
  44. functionBody->GetProfiledLdLenCount() * sizeof(Js::LdLenInfo)
  45. );
  46. data->ldElemData = AnewArray(alloc, LdElemIDL, data->profiledLdElemCount);
  47. memcpy_s(
  48. data->ldElemData,
  49. data->profiledLdElemCount * sizeof(LdElemIDL),
  50. profileInfo->GetLdElemInfo(),
  51. functionBody->GetProfiledLdElemCount() * sizeof(Js::LdElemInfo)
  52. );
  53. data->stElemData = AnewArray(alloc, StElemIDL, data->profiledStElemCount);
  54. memcpy_s(
  55. data->stElemData,
  56. data->profiledStElemCount * sizeof(StElemIDL),
  57. profileInfo->GetStElemInfo(),
  58. functionBody->GetProfiledStElemCount() * sizeof(Js::StElemInfo)
  59. );
  60. }
  61. CompileAssert(sizeof(ArrayCallSiteIDL) == sizeof(Js::ArrayCallSiteInfo));
  62. data->profiledArrayCallSiteCount = functionBody->GetProfiledArrayCallSiteCount();
  63. data->arrayCallSiteData = (ArrayCallSiteIDL*)profileInfo->GetArrayCallSiteInfo();
  64. data->arrayCallSiteDataAddr = (intptr_t)profileInfo->GetArrayCallSiteInfo();
  65. CompileAssert(sizeof(FldIDL) == sizeof(Js::FldInfo));
  66. data->inlineCacheCount = functionBody->GetProfiledFldCount();
  67. data->fldData = (FldIDL*)profileInfo->GetFldInfo();
  68. data->fldDataAddr = (intptr_t)profileInfo->GetFldInfo();
  69. CompileAssert(sizeof(ThisIDL) == sizeof(Js::ThisInfo));
  70. data->thisData = *reinterpret_cast<ThisIDL*>(&profileInfo->GetThisInfo());
  71. CompileAssert(sizeof(CallSiteIDL) == sizeof(Js::CallSiteInfo));
  72. data->profiledCallSiteCount = functionBody->GetProfiledCallSiteCount();
  73. data->callSiteData = reinterpret_cast<CallSiteIDL*>(profileInfo->GetCallSiteInfo());
  74. CompileAssert(sizeof(CallbackInfoIDL) == sizeof(Js::CallbackInfo));
  75. Js::CallbackInfoList * callbackInfoList = functionBody->GetCallbackInfoListWithLock();
  76. if (callbackInfoList == nullptr)
  77. {
  78. data->profiledCallbackCount = 0;
  79. }
  80. else
  81. {
  82. data->profiledCallbackCount = static_cast<Js::ProfileId>(callbackInfoList->Count());
  83. if (data->profiledCallbackCount > 0)
  84. {
  85. data->callbackData = AnewArrayZ(alloc, CallbackInfoIDL, data->profiledCallbackCount);
  86. Js::CallbackInfoList::Iterator iter = callbackInfoList->GetIterator();
  87. for (Js::ProfileId callbackInfoIndex = 0; callbackInfoIndex < data->profiledCallbackCount; ++callbackInfoIndex)
  88. {
  89. iter.Next();
  90. Js::CallbackInfo * info = iter.Data();
  91. memcpy_s(
  92. &data->callbackData[callbackInfoIndex],
  93. sizeof(CallbackInfoIDL),
  94. info,
  95. sizeof(Js::CallbackInfo)
  96. );
  97. }
  98. }
  99. }
  100. CompileAssert(sizeof(BVUnitIDL) == sizeof(BVUnit));
  101. data->loopFlags = (BVFixedIDL*)profileInfo->GetLoopFlags();
  102. CompileAssert(sizeof(ValueType) == sizeof(uint16));
  103. data->profiledSlotCount = functionBody->GetProfiledSlotCount();
  104. data->slotData = reinterpret_cast<uint16*>(profileInfo->GetSlotInfo());
  105. data->profiledReturnTypeCount = functionBody->GetProfiledReturnTypeCount();
  106. data->returnTypeData = reinterpret_cast<uint16*>(profileInfo->GetReturnTypeInfo());
  107. data->profiledDivOrRemCount = functionBody->GetProfiledDivOrRemCount();
  108. data->divideTypeInfo = reinterpret_cast<uint16*>(profileInfo->GetDivideTypeInfo());
  109. data->profiledSwitchCount = functionBody->GetProfiledSwitchCount();
  110. data->switchTypeInfo = reinterpret_cast<uint16*>(profileInfo->GetSwitchTypeInfo());
  111. data->profiledInParamsCount = functionBody->GetProfiledInParamsCount();
  112. data->parameterInfo = reinterpret_cast<uint16*>(profileInfo->GetParameterInfo());
  113. data->loopCount = functionBody->GetLoopCount();
  114. data->loopImplicitCallFlags = reinterpret_cast<byte*>(profileInfo->GetLoopImplicitCallFlags());
  115. data->implicitCallFlags = static_cast<byte>(profileInfo->GetImplicitCallFlags());
  116. data->flags = 0;
  117. data->flags |= profileInfo->IsAggressiveIntTypeSpecDisabled(false) ? Flags_disableAggressiveIntTypeSpec : 0;
  118. data->flags |= profileInfo->IsAggressiveIntTypeSpecDisabled(true) ? Flags_disableAggressiveIntTypeSpec_jitLoopBody : 0;
  119. data->flags |= profileInfo->IsAggressiveMulIntTypeSpecDisabled(false) ? Flags_disableAggressiveMulIntTypeSpec : 0;
  120. data->flags |= profileInfo->IsAggressiveMulIntTypeSpecDisabled(true) ? Flags_disableAggressiveMulIntTypeSpec_jitLoopBody : 0;
  121. data->flags |= profileInfo->IsDivIntTypeSpecDisabled(false) ? Flags_disableDivIntTypeSpec : 0;
  122. data->flags |= profileInfo->IsDivIntTypeSpecDisabled(true) ? Flags_disableDivIntTypeSpec_jitLoopBody : 0;
  123. data->flags |= profileInfo->IsLossyIntTypeSpecDisabled() ? Flags_disableLossyIntTypeSpec : 0;
  124. data->flags |= profileInfo->IsTrackCompoundedIntOverflowDisabled() ? Flags_disableTrackCompoundedIntOverflow : 0;
  125. data->flags |= profileInfo->IsFloatTypeSpecDisabled() ? Flags_disableFloatTypeSpec : 0;
  126. data->flags |= profileInfo->IsArrayCheckHoistDisabled(false) ? Flags_disableArrayCheckHoist : 0;
  127. data->flags |= profileInfo->IsArrayCheckHoistDisabled(true) ? Flags_disableArrayCheckHoist_jitLoopBody : 0;
  128. data->flags |= profileInfo->IsArrayMissingValueCheckHoistDisabled(false) ? Flags_disableArrayMissingValueCheckHoist : 0;
  129. data->flags |= profileInfo->IsArrayMissingValueCheckHoistDisabled(true) ? Flags_disableArrayMissingValueCheckHoist_jitLoopBody : 0;
  130. data->flags |= profileInfo->IsJsArraySegmentHoistDisabled(false) ? Flags_disableJsArraySegmentHoist : 0;
  131. data->flags |= profileInfo->IsJsArraySegmentHoistDisabled(true) ? Flags_disableJsArraySegmentHoist_jitLoopBody : 0;
  132. data->flags |= profileInfo->IsArrayLengthHoistDisabled(false) ? Flags_disableArrayLengthHoist : 0;
  133. data->flags |= profileInfo->IsArrayLengthHoistDisabled(true) ? Flags_disableArrayLengthHoist_jitLoopBody : 0;
  134. data->flags |= profileInfo->IsTypedArrayTypeSpecDisabled(false) ? Flags_disableTypedArrayTypeSpec : 0;
  135. data->flags |= profileInfo->IsTypedArrayTypeSpecDisabled(true) ? Flags_disableTypedArrayTypeSpec_jitLoopBody : 0;
  136. data->flags |= profileInfo->IsLdLenIntSpecDisabled() ? Flags_disableLdLenIntSpec : 0;
  137. data->flags |= profileInfo->IsBoundCheckHoistDisabled(false) ? Flags_disableBoundCheckHoist : 0;
  138. data->flags |= profileInfo->IsBoundCheckHoistDisabled(true) ? Flags_disableBoundCheckHoist_jitLoopBody : 0;
  139. data->flags |= profileInfo->IsLoopCountBasedBoundCheckHoistDisabled(false) ? Flags_disableLoopCountBasedBoundCheckHoist : 0;
  140. data->flags |= profileInfo->IsLoopCountBasedBoundCheckHoistDisabled(true) ? Flags_disableLoopCountBasedBoundCheckHoist_jitLoopBody : 0;
  141. data->flags |= profileInfo->IsFloorInliningDisabled() ? Flags_disableFloorInlining : 0;
  142. data->flags |= profileInfo->IsNoProfileBailoutsDisabled() ? Flags_disableNoProfileBailouts : 0;
  143. data->flags |= profileInfo->IsSwitchOptDisabled() ? Flags_disableSwitchOpt : 0;
  144. data->flags |= profileInfo->IsEquivalentObjTypeSpecDisabled() ? Flags_disableEquivalentObjTypeSpec : 0;
  145. data->flags |= profileInfo->IsObjTypeSpecDisabledInJitLoopBody() ? Flags_disableObjTypeSpec_jitLoopBody : 0;
  146. data->flags |= profileInfo->IsMemOpDisabled() ? Flags_disableMemOp : 0;
  147. data->flags |= profileInfo->IsCheckThisDisabled() ? Flags_disableCheckThis : 0;
  148. data->flags |= profileInfo->HasLdFldCallSiteInfo() ? Flags_hasLdFldCallSiteInfo : 0;
  149. data->flags |= profileInfo->IsStackArgOptDisabled() ? Flags_disableStackArgOpt : 0;
  150. data->flags |= profileInfo->IsLoopImplicitCallInfoDisabled() ? Flags_disableLoopImplicitCallInfo : 0;
  151. data->flags |= profileInfo->IsPowIntIntTypeSpecDisabled() ? Flags_disablePowIntIntTypeSpec : 0;
  152. data->flags |= profileInfo->IsTagCheckDisabled() ? Flags_disableTagCheck : 0;
  153. data->flags |= profileInfo->IsOptimizeTryFinallyDisabled() ? Flags_disableOptimizeTryFinally : 0;
  154. data->flags |= profileInfo->IsFieldPREDisabled() ? Flags_disableFieldPRE : 0;
  155. }
  156. const Js::LdLenInfo *
  157. JITTimeProfileInfo::GetLdLenInfo(Js::ProfileId ldLenId) const
  158. {
  159. AssertOrFailFast(ldLenId < m_profileData.profiledLdLenCount);
  160. return &(reinterpret_cast<Js::LdLenInfo*>(m_profileData.ldLenData)[ldLenId]);
  161. }
  162. const Js::LdElemInfo *
  163. JITTimeProfileInfo::GetLdElemInfo(Js::ProfileId ldElemId) const
  164. {
  165. AssertOrFailFast(ldElemId < m_profileData.profiledLdElemCount);
  166. return &(reinterpret_cast<Js::LdElemInfo*>(m_profileData.ldElemData)[ldElemId]);
  167. }
  168. const Js::StElemInfo *
  169. JITTimeProfileInfo::GetStElemInfo(Js::ProfileId stElemId) const
  170. {
  171. AssertOrFailFast(stElemId < m_profileData.profiledStElemCount);
  172. return &(reinterpret_cast<Js::StElemInfo*>(m_profileData.stElemData)[stElemId]);
  173. }
  174. Js::ArrayCallSiteInfo *
  175. JITTimeProfileInfo::GetArrayCallSiteInfo(Js::ProfileId index) const
  176. {
  177. AssertOrFailFast(index < GetProfiledArrayCallSiteCount());
  178. return &(reinterpret_cast<Js::ArrayCallSiteInfo*>(m_profileData.arrayCallSiteData)[index]);
  179. }
  180. intptr_t
  181. JITTimeProfileInfo::GetArrayCallSiteInfoAddr(Js::ProfileId index) const
  182. {
  183. AssertOrFailFast(index < GetProfiledArrayCallSiteCount());
  184. return m_profileData.arrayCallSiteDataAddr + index * sizeof(ArrayCallSiteIDL);
  185. }
  186. Js::FldInfo *
  187. JITTimeProfileInfo::GetFldInfo(uint fieldAccessId) const
  188. {
  189. AssertOrFailFast(fieldAccessId < GetProfiledFldCount());
  190. return &(reinterpret_cast<Js::FldInfo*>(m_profileData.fldData)[fieldAccessId]);
  191. }
  192. intptr_t
  193. JITTimeProfileInfo::GetFldInfoAddr(uint fieldAccessId) const
  194. {
  195. Assert(fieldAccessId < GetProfiledFldCount());
  196. return m_profileData.fldDataAddr + fieldAccessId * sizeof(Js::FldInfo);
  197. }
  198. ValueType
  199. JITTimeProfileInfo::GetSlotLoad(Js::ProfileId slotLoadId) const
  200. {
  201. AssertOrFailFast(slotLoadId < GetProfiledSlotCount());
  202. return reinterpret_cast<ValueType*>(m_profileData.slotData)[slotLoadId];
  203. }
  204. Js::ThisInfo
  205. JITTimeProfileInfo::GetThisInfo() const
  206. {
  207. return *reinterpret_cast<const Js::ThisInfo*>(&m_profileData.thisData);
  208. }
  209. ValueType
  210. JITTimeProfileInfo::GetReturnType(Js::OpCode opcode, Js::ProfileId callSiteId) const
  211. {
  212. if (opcode < Js::OpCode::ProfiledReturnTypeCallI || (opcode > Js::OpCode::ProfiledReturnTypeCallIFlags && opcode < Js::OpCode::ProfiledReturnTypeCallIExtended) || opcode > Js::OpCode::ProfiledReturnTypeCallIExtendedFlags)
  213. {
  214. Assert(Js::DynamicProfileInfo::IsProfiledCallOp(opcode));
  215. AssertOrFailFast(callSiteId < GetProfiledCallSiteCount());
  216. return GetCallSiteInfo()[callSiteId].returnType;
  217. }
  218. Assert(Js::DynamicProfileInfo::IsProfiledReturnTypeOp(opcode));
  219. AssertOrFailFast(callSiteId < GetProfiledReturnTypeCount());
  220. return reinterpret_cast<ValueType*>(m_profileData.returnTypeData)[callSiteId];
  221. }
  222. ValueType
  223. JITTimeProfileInfo::GetDivProfileInfo(Js::ProfileId divideId) const
  224. {
  225. AssertOrFailFast(divideId < GetProfiledDivOrRemCount());
  226. return reinterpret_cast<ValueType*>(m_profileData.divideTypeInfo)[divideId];
  227. }
  228. ValueType
  229. JITTimeProfileInfo::GetSwitchProfileInfo(Js::ProfileId switchId) const
  230. {
  231. AssertOrFailFast(switchId < GetProfiledSwitchCount());
  232. return reinterpret_cast<ValueType*>(m_profileData.switchTypeInfo)[switchId];
  233. }
  234. ValueType
  235. JITTimeProfileInfo::GetParameterInfo(Js::ArgSlot index) const
  236. {
  237. AssertOrFailFast(index < GetProfiledInParamsCount());
  238. return reinterpret_cast<ValueType*>(m_profileData.parameterInfo)[index];
  239. }
  240. Js::ImplicitCallFlags
  241. JITTimeProfileInfo::GetLoopImplicitCallFlags(uint loopNum) const
  242. {
  243. // TODO: michhol OOP JIT, investigate vaibility of reenabling this assert
  244. // Assert(Js::DynamicProfileInfo::EnableImplicitCallFlags(functionBody));
  245. AssertOrFailFast(loopNum < GetLoopCount());
  246. // Mask out the dispose implicit call. We would bailout on reentrant dispose,
  247. // but it shouldn't affect optimization.
  248. return (Js::ImplicitCallFlags)(m_profileData.loopImplicitCallFlags[loopNum] & Js::ImplicitCall_All);
  249. }
  250. Js::ImplicitCallFlags
  251. JITTimeProfileInfo::GetImplicitCallFlags() const
  252. {
  253. return static_cast<Js::ImplicitCallFlags>(m_profileData.implicitCallFlags);
  254. }
  255. Js::LoopFlags
  256. JITTimeProfileInfo::GetLoopFlags(uint loopNum) const
  257. {
  258. Assert(GetLoopFlags() != nullptr);
  259. return GetLoopFlags()->GetRange<Js::LoopFlags>(loopNum * Js::LoopFlags::COUNT, Js::LoopFlags::COUNT);
  260. }
  261. bool
  262. JITTimeProfileInfo::CanInlineCallback(Js::ArgSlot argIndex, Js::ProfileId callSiteId) const
  263. {
  264. Js::CallbackInfo * callbackInfo = FindCallbackInfo(callSiteId);
  265. return callbackInfo != nullptr && callbackInfo->CanInlineCallback(argIndex);
  266. }
  267. uint16
  268. JITTimeProfileInfo::GetConstantArgInfo(Js::ProfileId callSiteId) const
  269. {
  270. return GetCallSiteInfo()[callSiteId].isArgConstant;
  271. }
  272. bool
  273. JITTimeProfileInfo::IsModulusOpByPowerOf2(Js::ProfileId profileId) const
  274. {
  275. return GetDivProfileInfo(profileId).IsLikelyTaggedInt();
  276. }
  277. bool
  278. JITTimeProfileInfo::IsAggressiveIntTypeSpecDisabled(const bool isJitLoopBody) const
  279. {
  280. if (isJitLoopBody)
  281. {
  282. return TestFlag(Flags_disableAggressiveIntTypeSpec_jitLoopBody);
  283. }
  284. else
  285. {
  286. return TestFlag(Flags_disableAggressiveIntTypeSpec);
  287. }
  288. }
  289. bool
  290. JITTimeProfileInfo::IsSwitchOptDisabled() const
  291. {
  292. return TestFlag(Flags_disableSwitchOpt);
  293. }
  294. bool
  295. JITTimeProfileInfo::IsEquivalentObjTypeSpecDisabled() const
  296. {
  297. return TestFlag(Flags_disableEquivalentObjTypeSpec);
  298. }
  299. bool
  300. JITTimeProfileInfo::IsObjTypeSpecDisabledInJitLoopBody() const
  301. {
  302. return TestFlag(Flags_disableObjTypeSpec_jitLoopBody);
  303. }
  304. bool
  305. JITTimeProfileInfo::IsAggressiveMulIntTypeSpecDisabled(const bool isJitLoopBody) const
  306. {
  307. if (isJitLoopBody)
  308. {
  309. return TestFlag(Flags_disableAggressiveMulIntTypeSpec_jitLoopBody);
  310. }
  311. else
  312. {
  313. return TestFlag(Flags_disableAggressiveMulIntTypeSpec);
  314. }
  315. }
  316. bool
  317. JITTimeProfileInfo::IsDivIntTypeSpecDisabled(const bool isJitLoopBody) const
  318. {
  319. if (isJitLoopBody)
  320. {
  321. return TestFlag(Flags_disableDivIntTypeSpec_jitLoopBody);
  322. }
  323. else
  324. {
  325. return TestFlag(Flags_disableDivIntTypeSpec);
  326. }
  327. }
  328. bool
  329. JITTimeProfileInfo::IsLossyIntTypeSpecDisabled() const
  330. {
  331. return TestFlag(Flags_disableLossyIntTypeSpec);
  332. }
  333. bool
  334. JITTimeProfileInfo::IsMemOpDisabled() const
  335. {
  336. return TestFlag(Flags_disableMemOp);
  337. }
  338. bool
  339. JITTimeProfileInfo::IsTrackCompoundedIntOverflowDisabled() const
  340. {
  341. return TestFlag(Flags_disableTrackCompoundedIntOverflow);
  342. }
  343. bool
  344. JITTimeProfileInfo::IsFloatTypeSpecDisabled() const
  345. {
  346. return TestFlag(Flags_disableFloatTypeSpec);
  347. }
  348. bool
  349. JITTimeProfileInfo::IsCheckThisDisabled() const
  350. {
  351. return TestFlag(Flags_disableCheckThis);
  352. }
  353. bool
  354. JITTimeProfileInfo::IsArrayCheckHoistDisabled(const bool isJitLoopBody) const
  355. {
  356. if (isJitLoopBody)
  357. {
  358. return TestFlag(Flags_disableArrayCheckHoist_jitLoopBody);
  359. }
  360. else
  361. {
  362. return TestFlag(Flags_disableArrayCheckHoist);
  363. }
  364. }
  365. bool
  366. JITTimeProfileInfo::IsArrayMissingValueCheckHoistDisabled(const bool isJitLoopBody) const
  367. {
  368. if (isJitLoopBody)
  369. {
  370. return TestFlag(Flags_disableArrayMissingValueCheckHoist_jitLoopBody);
  371. }
  372. else
  373. {
  374. return TestFlag(Flags_disableArrayMissingValueCheckHoist);
  375. }
  376. }
  377. bool
  378. JITTimeProfileInfo::IsJsArraySegmentHoistDisabled(const bool isJitLoopBody) const
  379. {
  380. if (isJitLoopBody)
  381. {
  382. return TestFlag(Flags_disableJsArraySegmentHoist_jitLoopBody);
  383. }
  384. else
  385. {
  386. return TestFlag(Flags_disableJsArraySegmentHoist);
  387. }
  388. }
  389. bool
  390. JITTimeProfileInfo::IsArrayLengthHoistDisabled(const bool isJitLoopBody) const
  391. {
  392. if (isJitLoopBody)
  393. {
  394. return TestFlag(Flags_disableArrayLengthHoist_jitLoopBody);
  395. }
  396. else
  397. {
  398. return TestFlag(Flags_disableArrayLengthHoist);
  399. }
  400. }
  401. bool
  402. JITTimeProfileInfo::IsTypedArrayTypeSpecDisabled(const bool isJitLoopBody) const
  403. {
  404. if (isJitLoopBody)
  405. {
  406. return TestFlag(Flags_disableTypedArrayTypeSpec_jitLoopBody);
  407. }
  408. else
  409. {
  410. return TestFlag(Flags_disableTypedArrayTypeSpec);
  411. }
  412. }
  413. bool
  414. JITTimeProfileInfo::IsLdLenIntSpecDisabled() const
  415. {
  416. return TestFlag(Flags_disableLdLenIntSpec);
  417. }
  418. bool
  419. JITTimeProfileInfo::IsBoundCheckHoistDisabled(const bool isJitLoopBody) const
  420. {
  421. if (isJitLoopBody)
  422. {
  423. return TestFlag(Flags_disableBoundCheckHoist_jitLoopBody);
  424. }
  425. else
  426. {
  427. return TestFlag(Flags_disableBoundCheckHoist);
  428. }
  429. }
  430. bool
  431. JITTimeProfileInfo::IsLoopCountBasedBoundCheckHoistDisabled(const bool isJitLoopBody) const
  432. {
  433. if (isJitLoopBody)
  434. {
  435. return TestFlag(Flags_disableLoopCountBasedBoundCheckHoist_jitLoopBody);
  436. }
  437. else
  438. {
  439. return TestFlag(Flags_disableLoopCountBasedBoundCheckHoist);
  440. }
  441. }
  442. bool
  443. JITTimeProfileInfo::IsStackArgOptDisabled() const
  444. {
  445. return TestFlag(Flags_disableStackArgOpt);
  446. }
  447. bool
  448. JITTimeProfileInfo::IsLoopImplicitCallInfoDisabled() const
  449. {
  450. return TestFlag(Flags_disableLoopImplicitCallInfo);
  451. }
  452. bool
  453. JITTimeProfileInfo::IsPowIntIntTypeSpecDisabled() const
  454. {
  455. return TestFlag(Flags_disablePowIntIntTypeSpec);
  456. }
  457. bool
  458. JITTimeProfileInfo::IsFloorInliningDisabled() const
  459. {
  460. return TestFlag(Flags_disableFloorInlining);
  461. }
  462. bool
  463. JITTimeProfileInfo::IsNoProfileBailoutsDisabled() const
  464. {
  465. return TestFlag(Flags_disableNoProfileBailouts);
  466. }
  467. bool
  468. JITTimeProfileInfo::IsTagCheckDisabled() const
  469. {
  470. return TestFlag(Flags_disableTagCheck);
  471. }
  472. bool
  473. JITTimeProfileInfo::IsOptimizeTryFinallyDisabled() const
  474. {
  475. return TestFlag(Flags_disableOptimizeTryFinally);
  476. }
  477. bool
  478. JITTimeProfileInfo::IsFieldPREDisabled() const
  479. {
  480. return TestFlag(Flags_disableFieldPRE);
  481. }
  482. bool
  483. JITTimeProfileInfo::HasLdFldCallSiteInfo() const
  484. {
  485. return TestFlag(Flags_hasLdFldCallSiteInfo);
  486. }
  487. Js::ProfileId
  488. JITTimeProfileInfo::GetProfiledArrayCallSiteCount() const
  489. {
  490. return static_cast<Js::ProfileId>(m_profileData.profiledArrayCallSiteCount);
  491. }
  492. Js::ProfileId
  493. JITTimeProfileInfo::GetProfiledCallSiteCount() const
  494. {
  495. return static_cast<Js::ProfileId>(m_profileData.profiledCallSiteCount);
  496. }
  497. Js::ProfileId
  498. JITTimeProfileInfo::GetProfiledReturnTypeCount() const
  499. {
  500. return static_cast<Js::ProfileId>(m_profileData.profiledReturnTypeCount);
  501. }
  502. Js::ProfileId
  503. JITTimeProfileInfo::GetProfiledDivOrRemCount() const
  504. {
  505. return static_cast<Js::ProfileId>(m_profileData.profiledDivOrRemCount);
  506. }
  507. Js::ProfileId
  508. JITTimeProfileInfo::GetProfiledSwitchCount() const
  509. {
  510. return static_cast<Js::ProfileId>(m_profileData.profiledSwitchCount);
  511. }
  512. Js::ProfileId
  513. JITTimeProfileInfo::GetProfiledSlotCount() const
  514. {
  515. return static_cast<Js::ProfileId>(m_profileData.profiledSlotCount);
  516. }
  517. Js::ArgSlot
  518. JITTimeProfileInfo::GetProfiledInParamsCount() const
  519. {
  520. return static_cast<Js::ArgSlot>(m_profileData.profiledInParamsCount);
  521. }
  522. uint
  523. JITTimeProfileInfo::GetProfiledFldCount() const
  524. {
  525. return m_profileData.inlineCacheCount;
  526. }
  527. uint
  528. JITTimeProfileInfo::GetLoopCount() const
  529. {
  530. return m_profileData.loopCount;
  531. }
  532. Js::CallSiteInfo *
  533. JITTimeProfileInfo::GetCallSiteInfo() const
  534. {
  535. return reinterpret_cast<Js::CallSiteInfo*>(m_profileData.callSiteData);
  536. }
  537. Js::CallbackInfo *
  538. JITTimeProfileInfo::GetCallbackInfo() const
  539. {
  540. return reinterpret_cast<Js::CallbackInfo*>(m_profileData.callbackData);
  541. }
  542. Js::CallbackInfo *
  543. JITTimeProfileInfo::FindCallbackInfo(Js::ProfileId callSiteId) const
  544. {
  545. Js::CallbackInfo * callbackInfo = GetCallbackInfo();
  546. for (size_t i = 0; i < m_profileData.profiledCallbackCount; ++i)
  547. {
  548. if (callbackInfo[i].callSiteId == callSiteId)
  549. {
  550. return &callbackInfo[i];
  551. }
  552. }
  553. return nullptr;
  554. }
  555. bool
  556. JITTimeProfileInfo::TestFlag(ProfileDataFlags flag) const
  557. {
  558. return (m_profileData.flags & flag) != 0;
  559. }
  560. BVFixed *
  561. JITTimeProfileInfo::GetLoopFlags() const
  562. {
  563. return (BVFixed*)m_profileData.loopFlags;
  564. }