FunctionCodeGenJitTimeData.cpp 6.2 KB

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