FunctionCodeGenJitTimeData.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. Field(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. Field(EntryPointInfo *) const entryPointInfo;
  20. // These cloned inline caches are guaranteed to have stable data while jitting, but will be collectible after jitting
  21. Field(ObjTypeSpecFldInfoArray) objTypeSpecFldInfoArray;
  22. // Globally ordered list of all object type specialized property access information (monomorphic and polymorphic caches combined).
  23. Field(uint) globalObjTypeSpecFldInfoCount;
  24. Field(Field(ObjTypeSpecFldInfo*)*) globalObjTypeSpecFldInfoArray;
  25. // There will be a non-null entry for each profiled call site where a function is to be inlined
  26. Field(Field(FunctionCodeGenJitTimeData*)*) inlinees;
  27. Field(Field(FunctionCodeGenJitTimeData*)*) ldFldInlinees;
  28. Field(RecyclerWeakReference<FunctionBody>*) weakFuncRef;
  29. Field(PolymorphicInlineCacheInfoIDL*) inlineeInfo;
  30. Field(PolymorphicInlineCacheInfoIDL*) selfInfo;
  31. Field(PolymorphicInlineCacheIDL*) polymorphicInlineCaches;
  32. // current value of global this object, may be changed in case of script engine invalidation
  33. Field(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. Field(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. Field(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. Field(FunctionCodeGenJitTimeData *) next;
  42. Field(bool) isInlined;
  43. // This indicates the function is aggressively Inlined(see NativeCodeGenerator::TryAggressiveInlining) .
  44. Field(bool) isAggressiveInliningEnabled;
  45. // The profiled iterations need to be determined at the time of gathering code gen data on the main thread
  46. Field(const uint16) profiledIterations;
  47. FunctionCodeGenJitTimeData(FunctionInfo *const functionInfo, EntryPointInfo *const entryPoint, Var globalThis, uint16 profiledIterations, bool isInlined = true);
  48. #ifdef FIELD_ACCESS_STATS
  49. public:
  50. Field(FieldAccessStatsPtr) inlineCacheStats;
  51. void EnsureInlineCacheStats(Recycler* recycler);
  52. void AddInlineeInlineCacheStats(FunctionCodeGenJitTimeData* inlineeJitTimeData);
  53. #endif
  54. public:
  55. static FunctionCodeGenJitTimeData* New(Recycler* recycler, FunctionInfo *const functionInfo, EntryPointInfo *const entryPoint, bool isInlined = true);
  56. public:
  57. Field(BVFixed *) inlineesBv;
  58. Field(Js::PropertyId*) sharedPropertyGuards;
  59. Field(uint) sharedPropertyGuardCount;
  60. FunctionInfo *GetFunctionInfo() const;
  61. FunctionBody *GetFunctionBody() const;
  62. Var GetGlobalThisObject() const;
  63. FunctionBodyDataIDL *GetJITBody() const;
  64. FunctionCodeGenJitTimeData *GetNext() const { return next; }
  65. const ObjTypeSpecFldInfoArray* GetObjTypeSpecFldInfoArray() const { return &this->objTypeSpecFldInfoArray; }
  66. ObjTypeSpecFldInfoArray* GetObjTypeSpecFldInfoArray() { return &this->objTypeSpecFldInfoArray; }
  67. EntryPointInfo* GetEntryPointInfo() const { return this->entryPointInfo; }
  68. public:
  69. const FunctionCodeGenJitTimeData *GetInlinee(const ProfileId profiledCallSiteId) const;
  70. const FunctionCodeGenJitTimeData *GetLdFldInlinee(const InlineCacheIndex inlineCacheIndex) const;
  71. FunctionCodeGenJitTimeData *AddInlinee(
  72. Recycler *const recycler,
  73. const ProfileId profiledCallSiteId,
  74. FunctionInfo *const inlinee,
  75. bool isInlined = true);
  76. uint InlineeCount() const;
  77. uint LdFldInlineeCount() const;
  78. bool IsLdFldInlineePresent() const { return ldFldInlineeCount != 0; }
  79. RecyclerWeakReference<FunctionBody> *GetWeakFuncRef() const { return this->weakFuncRef; }
  80. void SetWeakFuncRef(RecyclerWeakReference<FunctionBody> *weakFuncRef)
  81. {
  82. Assert(this->weakFuncRef == nullptr || weakFuncRef == nullptr || this->weakFuncRef == weakFuncRef);
  83. this->weakFuncRef = weakFuncRef;
  84. }
  85. void SetPolymorphicInlineInfo(PolymorphicInlineCacheInfoIDL* inlineeInfo, PolymorphicInlineCacheInfoIDL* selfInfo, PolymorphicInlineCacheIDL* polymorphicInlineCaches)
  86. {
  87. this->inlineeInfo = inlineeInfo;
  88. this->selfInfo = selfInfo;
  89. this->polymorphicInlineCaches = polymorphicInlineCaches;
  90. }
  91. FunctionCodeGenJitTimeData *AddLdFldInlinee(
  92. Recycler *const recycler,
  93. const InlineCacheIndex inlineCacheIndex,
  94. FunctionInfo *const inlinee);
  95. bool IsPolymorphicCallSite(const ProfileId profiledCallSiteId) const;
  96. // This function walks all the chained jittimedata and returns the one which match the functionInfo.
  97. // This can return null, if the functionInfo doesn't match.
  98. const FunctionCodeGenJitTimeData *GetJitTimeDataFromFunctionInfo(FunctionInfo *polyFunctioInfoy) const;
  99. uint GetGlobalObjTypeSpecFldInfoCount() const { return this->globalObjTypeSpecFldInfoCount; }
  100. Field(ObjTypeSpecFldInfo*)* GetGlobalObjTypeSpecFldInfoArray() const {return this->globalObjTypeSpecFldInfoArray; }
  101. ObjTypeSpecFldInfo* GetGlobalObjTypeSpecFldInfo(uint propertyInfoId) const
  102. {
  103. Assert(this->globalObjTypeSpecFldInfoArray != nullptr && propertyInfoId < this->globalObjTypeSpecFldInfoCount);
  104. return this->globalObjTypeSpecFldInfoArray[propertyInfoId];
  105. }
  106. void SetGlobalObjTypeSpecFldInfo(uint propertyInfoId, ObjTypeSpecFldInfo* info) const
  107. {
  108. Assert(this->globalObjTypeSpecFldInfoArray != nullptr && propertyInfoId < this->globalObjTypeSpecFldInfoCount);
  109. this->globalObjTypeSpecFldInfoArray[propertyInfoId] = info;
  110. }
  111. void SetGlobalObjTypeSpecFldInfoArray(Field(ObjTypeSpecFldInfo*)* array, uint count)
  112. {
  113. Assert(array != nullptr);
  114. this->globalObjTypeSpecFldInfoArray = array;
  115. this->globalObjTypeSpecFldInfoCount = count;
  116. }
  117. bool GetIsInlined() const
  118. {
  119. return isInlined;
  120. }
  121. bool GetIsAggressiveInliningEnabled() const
  122. {
  123. return isAggressiveInliningEnabled;
  124. }
  125. void SetIsAggressiveInliningEnabled()
  126. {
  127. isAggressiveInliningEnabled = true;
  128. }
  129. void SetupRecursiveInlineeChain(
  130. Recycler *const recycler,
  131. const ProfileId profiledCallSiteId)
  132. {
  133. if (!inlinees)
  134. {
  135. inlinees = RecyclerNewArrayZ(recycler, Field(FunctionCodeGenJitTimeData *), GetFunctionBody()->GetProfiledCallSiteCount());
  136. }
  137. inlinees[profiledCallSiteId] = this;
  138. inlineeCount++;
  139. }
  140. uint16 GetProfiledIterations() const;
  141. PREVENT_COPY(FunctionCodeGenJitTimeData)
  142. };
  143. }
  144. #endif