FunctionCodeGenJitTimeData.h 7.6 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. #pragma once
  6. #if ENABLE_NATIVE_CODEGEN
  7. // forward ref
  8. struct FunctionBodyDataIDL;
  9. namespace Js
  10. {
  11. // - Data generated for jitting purposes
  12. // - Recycler-allocated, lifetime is from when a code gen work item is added to the jit queue, to when jitting is complete
  13. // - Also keeps the function body and inlinee function bodies alive while jitting.
  14. class FunctionCodeGenJitTimeData
  15. {
  16. private:
  17. FunctionInfo *const functionInfo;
  18. // Point's to an entry point if the work item needs the entry point alive- null for cases where the entry point isn't used
  19. EntryPointInfo *const entryPointInfo;
  20. // These cloned inline caches are guaranteed to have stable data while jitting, but will be collectible after jitting
  21. ObjTypeSpecFldInfoArray objTypeSpecFldInfoArray;
  22. // Globally ordered list of all object type specialized property access information (monomorphic and polymorphic caches combined).
  23. uint globalObjTypeSpecFldInfoCount;
  24. ObjTypeSpecFldInfo** globalObjTypeSpecFldInfoArray;
  25. // There will be a non-null entry for each profiled call site where a function is to be inlined
  26. FunctionCodeGenJitTimeData **inlinees;
  27. FunctionCodeGenJitTimeData **ldFldInlinees;
  28. RecyclerWeakReference<FunctionBody> *weakFuncRef;
  29. PolymorphicInlineCacheInfoIDL* inlineeInfo;
  30. PolymorphicInlineCacheInfoIDL* selfInfo;
  31. PolymorphicInlineCacheIDL* polymorphicInlineCaches;
  32. // current value of global this object, may be changed in case of script engine invalidation
  33. Var globalThisObject;
  34. // Number of functions that are to be inlined (this is not the length of the 'inlinees' array above, includes getter setter inlinee count)
  35. uint inlineeCount;
  36. // Number of counts of getter setter to be inlined. This is not an exact count as inline caches are shared and we have no way of knowing
  37. // accurate count.
  38. uint ldFldInlineeCount;
  39. // For polymorphic call site we will have linked list of FunctionCodeGenJitTimeData
  40. // Each is differentiated by id starting from 0, 1
  41. FunctionCodeGenJitTimeData *next;
  42. bool isInlined;
  43. // This indicates the function is aggressively Inlined(see NativeCodeGenerator::TryAggressiveInlining) .
  44. bool isAggressiveInliningEnabled;
  45. // The profiled iterations need to be determined at the time of gathering code gen data on the main thread
  46. const uint16 profiledIterations;
  47. #ifdef FIELD_ACCESS_STATS
  48. public:
  49. FieldAccessStatsPtr inlineCacheStats;
  50. void EnsureInlineCacheStats(Recycler* recycler);
  51. void AddInlineeInlineCacheStats(FunctionCodeGenJitTimeData* inlineeJitTimeData);
  52. #endif
  53. public:
  54. FunctionCodeGenJitTimeData(FunctionInfo *const functionInfo, EntryPointInfo *const entryPoint, bool isInlined = true);
  55. public:
  56. BVFixed *inlineesBv;
  57. FunctionInfo *GetFunctionInfo() const;
  58. FunctionBody *GetFunctionBody() const;
  59. Var GetGlobalThisObject() const;
  60. FunctionBodyDataIDL *GetJITBody() const;
  61. FunctionCodeGenJitTimeData *GetNext() const { return next; }
  62. const ObjTypeSpecFldInfoArray* GetObjTypeSpecFldInfoArray() const { return &this->objTypeSpecFldInfoArray; }
  63. ObjTypeSpecFldInfoArray* GetObjTypeSpecFldInfoArray() { return &this->objTypeSpecFldInfoArray; }
  64. EntryPointInfo* GetEntryPointInfo() const { return this->entryPointInfo; }
  65. public:
  66. const FunctionCodeGenJitTimeData *GetInlinee(const ProfileId profiledCallSiteId) const;
  67. FunctionCodeGenJitTimeData ** GetInlinees();
  68. const FunctionCodeGenJitTimeData *GetLdFldInlinee(const InlineCacheIndex inlineCacheIndex) const;
  69. FunctionCodeGenJitTimeData ** GetLdFldInlinees();
  70. FunctionCodeGenJitTimeData *AddInlinee(
  71. Recycler *const recycler,
  72. const ProfileId profiledCallSiteId,
  73. FunctionInfo *const inlinee,
  74. bool isInlined = true);
  75. uint InlineeCount() const;
  76. uint LdFldInlineeCount() const;
  77. bool IsLdFldInlineePresent() const { return ldFldInlineeCount != 0; }
  78. RecyclerWeakReference<FunctionBody> *GetWeakFuncRef() const { return this->weakFuncRef; }
  79. void SetWeakFuncRef(RecyclerWeakReference<FunctionBody> *weakFuncRef)
  80. {
  81. Assert(this->weakFuncRef == nullptr || weakFuncRef == nullptr || this->weakFuncRef == weakFuncRef);
  82. this->weakFuncRef = weakFuncRef;
  83. }
  84. void SetPolymorphicInlineInfo(PolymorphicInlineCacheInfoIDL* inlineeInfo, PolymorphicInlineCacheInfoIDL* selfInfo, PolymorphicInlineCacheIDL* polymorphicInlineCaches)
  85. {
  86. this->inlineeInfo = inlineeInfo;
  87. this->selfInfo = selfInfo;
  88. this->polymorphicInlineCaches = polymorphicInlineCaches;
  89. }
  90. FunctionCodeGenJitTimeData *AddLdFldInlinee(
  91. Recycler *const recycler,
  92. const InlineCacheIndex inlineCacheIndex,
  93. FunctionInfo *const inlinee);
  94. bool IsPolymorphicCallSite(const ProfileId profiledCallSiteId) const;
  95. // This function walks all the chained jittimedata and returns the one which match the functionInfo.
  96. // This can return null, if the functionInfo doesn't match.
  97. const FunctionCodeGenJitTimeData *GetJitTimeDataFromFunctionInfo(FunctionInfo *polyFunctionInfo) const;
  98. uint GetGlobalObjTypeSpecFldInfoCount() const { return this->globalObjTypeSpecFldInfoCount; }
  99. ObjTypeSpecFldInfo** GetGlobalObjTypeSpecFldInfoArray() const {return this->globalObjTypeSpecFldInfoArray; }
  100. ObjTypeSpecFldInfo* GetGlobalObjTypeSpecFldInfo(uint propertyInfoId) const
  101. {
  102. Assert(this->globalObjTypeSpecFldInfoArray != nullptr && propertyInfoId < this->globalObjTypeSpecFldInfoCount);
  103. return this->globalObjTypeSpecFldInfoArray[propertyInfoId];
  104. }
  105. void SetGlobalObjTypeSpecFldInfo(uint propertyInfoId, ObjTypeSpecFldInfo* info) const
  106. {
  107. Assert(this->globalObjTypeSpecFldInfoArray != nullptr && propertyInfoId < this->globalObjTypeSpecFldInfoCount);
  108. this->globalObjTypeSpecFldInfoArray[propertyInfoId] = info;
  109. }
  110. void SetGlobalObjTypeSpecFldInfoArray(ObjTypeSpecFldInfo** array, uint count)
  111. {
  112. Assert(array != nullptr);
  113. this->globalObjTypeSpecFldInfoArray = array;
  114. this->globalObjTypeSpecFldInfoCount = count;
  115. }
  116. bool GetIsInlined() const
  117. {
  118. return isInlined;
  119. }
  120. bool GetIsAggressiveInliningEnabled() const
  121. {
  122. return isAggressiveInliningEnabled;
  123. }
  124. void SetIsAggressiveInliningEnabled()
  125. {
  126. isAggressiveInliningEnabled = true;
  127. }
  128. void SetupRecursiveInlineeChain(
  129. Recycler *const recycler,
  130. const ProfileId profiledCallSiteId)
  131. {
  132. if (!inlinees)
  133. {
  134. inlinees = RecyclerNewArrayZ(recycler, FunctionCodeGenJitTimeData *, GetFunctionBody()->GetProfiledCallSiteCount());
  135. }
  136. inlinees[profiledCallSiteId] = this;
  137. inlineeCount++;
  138. }
  139. uint16 GetProfiledIterations() const;
  140. PREVENT_COPY(FunctionCodeGenJitTimeData)
  141. };
  142. }
  143. #endif