FunctionCodeGenJitTimeData.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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 "RuntimeLanguagePch.h"
  6. #include "JITTimeFunctionBody.h"
  7. #if ENABLE_NATIVE_CODEGEN
  8. namespace Js
  9. {
  10. FunctionCodeGenJitTimeData::FunctionCodeGenJitTimeData(FunctionInfo *const functionInfo, EntryPointInfo *const entryPoint, bool isInlined) :
  11. functionInfo(functionInfo), entryPointInfo(entryPoint), globalObjTypeSpecFldInfoCount(0), globalObjTypeSpecFldInfoArray(nullptr),
  12. weakFuncRef(nullptr), inlinees(nullptr), inlineeCount(0), ldFldInlineeCount(0), isInlined(isInlined), isAggressiveInliningEnabled(false),
  13. #ifdef FIELD_ACCESS_STATS
  14. inlineCacheStats(nullptr),
  15. #endif
  16. next(0),
  17. ldFldInlinees(nullptr),
  18. globalThisObject(GetFunctionBody() && GetFunctionBody()->GetByteCode() ? GetFunctionBody()->GetScriptContext()->GetLibrary()->GetGlobalObject()->ToThis() : 0),
  19. profiledIterations(GetFunctionBody() && GetFunctionBody()->GetByteCode() ? GetFunctionBody()->GetProfiledIterations() : 0)
  20. {
  21. }
  22. uint16 FunctionCodeGenJitTimeData::GetProfiledIterations() const
  23. {
  24. return profiledIterations;
  25. }
  26. FunctionInfo *FunctionCodeGenJitTimeData::GetFunctionInfo() const
  27. {
  28. return this->functionInfo;
  29. }
  30. FunctionBody *FunctionCodeGenJitTimeData::GetFunctionBody() const
  31. {
  32. return this->functionInfo->GetFunctionBody();
  33. }
  34. Var FunctionCodeGenJitTimeData::GetGlobalThisObject() const
  35. {
  36. return this->globalThisObject;
  37. }
  38. bool FunctionCodeGenJitTimeData::IsPolymorphicCallSite(const ProfileId profiledCallSiteId) const
  39. {
  40. Assert(GetFunctionBody());
  41. Assert(profiledCallSiteId < GetFunctionBody()->GetProfiledCallSiteCount());
  42. return inlinees ? inlinees[profiledCallSiteId]->next != nullptr : false;
  43. }
  44. const FunctionCodeGenJitTimeData *FunctionCodeGenJitTimeData::GetInlinee(const ProfileId profiledCallSiteId) const
  45. {
  46. Assert(GetFunctionBody());
  47. Assert(profiledCallSiteId < GetFunctionBody()->GetProfiledCallSiteCount());
  48. return inlinees ? inlinees[profiledCallSiteId] : nullptr;
  49. }
  50. FunctionCodeGenJitTimeData ** FunctionCodeGenJitTimeData::GetInlinees()
  51. {
  52. return inlinees;
  53. }
  54. const FunctionCodeGenJitTimeData *FunctionCodeGenJitTimeData::GetJitTimeDataFromFunctionInfo(FunctionInfo *polyFunctionInfo) const
  55. {
  56. const FunctionCodeGenJitTimeData *next = this;
  57. while (next && next->functionInfo != polyFunctionInfo)
  58. {
  59. next = next->next;
  60. }
  61. return next;
  62. }
  63. const FunctionCodeGenJitTimeData *FunctionCodeGenJitTimeData::GetLdFldInlinee(const InlineCacheIndex inlineCacheIndex) const
  64. {
  65. Assert(GetFunctionBody());
  66. Assert(inlineCacheIndex < GetFunctionBody()->GetInlineCacheCount());
  67. return ldFldInlinees ? ldFldInlinees[inlineCacheIndex] : nullptr;
  68. }
  69. FunctionCodeGenJitTimeData ** FunctionCodeGenJitTimeData::GetLdFldInlinees()
  70. {
  71. return ldFldInlinees;
  72. }
  73. FunctionCodeGenJitTimeData *FunctionCodeGenJitTimeData::AddInlinee(
  74. Recycler *const recycler,
  75. const ProfileId profiledCallSiteId,
  76. FunctionInfo *const inlinee,
  77. bool isInlined)
  78. {
  79. Assert(recycler);
  80. const auto functionBody = GetFunctionBody();
  81. Assert(functionBody);
  82. Assert(profiledCallSiteId < functionBody->GetProfiledCallSiteCount());
  83. Assert(inlinee);
  84. if (!inlinees)
  85. {
  86. inlinees = RecyclerNewArrayZ(recycler, FunctionCodeGenJitTimeData *, functionBody->GetProfiledCallSiteCount());
  87. }
  88. FunctionCodeGenJitTimeData *inlineeData = nullptr;
  89. if (!inlinees[profiledCallSiteId])
  90. {
  91. inlineeData = RecyclerNew(recycler, FunctionCodeGenJitTimeData, inlinee, nullptr /* entryPoint */, isInlined);
  92. inlinees[profiledCallSiteId] = inlineeData;
  93. if (++inlineeCount == 0)
  94. {
  95. Js::Throw::OutOfMemory();
  96. }
  97. }
  98. else
  99. {
  100. inlineeData = RecyclerNew(recycler, FunctionCodeGenJitTimeData, inlinee, nullptr /* entryPoint */, isInlined);
  101. // This is polymorphic, chain the data.
  102. inlineeData->next = inlinees[profiledCallSiteId];
  103. inlinees[profiledCallSiteId] = inlineeData;
  104. }
  105. return inlineeData;
  106. }
  107. FunctionCodeGenJitTimeData *FunctionCodeGenJitTimeData::AddLdFldInlinee(
  108. Recycler *const recycler,
  109. const InlineCacheIndex inlineCacheIndex,
  110. FunctionInfo *const inlinee)
  111. {
  112. Assert(recycler);
  113. const auto functionBody = GetFunctionBody();
  114. Assert(functionBody);
  115. Assert(inlineCacheIndex < GetFunctionBody()->GetInlineCacheCount());
  116. Assert(inlinee);
  117. if (!ldFldInlinees)
  118. {
  119. ldFldInlinees = RecyclerNewArrayZ(recycler, FunctionCodeGenJitTimeData *, GetFunctionBody()->GetInlineCacheCount());
  120. }
  121. const auto inlineeData = RecyclerNew(recycler, FunctionCodeGenJitTimeData, inlinee, nullptr);
  122. Assert(!ldFldInlinees[inlineCacheIndex]);
  123. ldFldInlinees[inlineCacheIndex] = inlineeData;
  124. if (++ldFldInlineeCount == 0)
  125. {
  126. Js::Throw::OutOfMemory();
  127. }
  128. return inlineeData;
  129. }
  130. uint FunctionCodeGenJitTimeData::InlineeCount() const
  131. {
  132. return inlineeCount;
  133. }
  134. uint FunctionCodeGenJitTimeData::LdFldInlineeCount() const
  135. {
  136. return ldFldInlineeCount;
  137. }
  138. #ifdef FIELD_ACCESS_STATS
  139. void FunctionCodeGenJitTimeData::EnsureInlineCacheStats(Recycler* recycler)
  140. {
  141. this->inlineCacheStats = RecyclerNew(recycler, FieldAccessStats);
  142. }
  143. void FunctionCodeGenJitTimeData::AddInlineeInlineCacheStats(FunctionCodeGenJitTimeData* inlineeJitTimeData)
  144. {
  145. Assert(this->inlineCacheStats != nullptr);
  146. Assert(inlineeJitTimeData != nullptr && inlineeJitTimeData->inlineCacheStats != nullptr);
  147. this->inlineCacheStats->Add(inlineeJitTimeData->inlineCacheStats);
  148. }
  149. #endif
  150. }
  151. #endif