NativeEntryPointData.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. class NativeCodeData;
  8. namespace Js
  9. {
  10. class FunctionBody;
  11. };
  12. typedef JsUtil::List<NativeOffsetInlineeFramePair, HeapAllocator> InlineeFrameMap;
  13. typedef JsUtil::List<LazyBailOutRecord, HeapAllocator> NativeLazyBailOutRecordList;
  14. class JitTransferData;
  15. class NativeEntryPointData
  16. {
  17. public:
  18. NativeEntryPointData();
  19. JitTransferData* EnsureJitTransferData(Recycler* recycler);
  20. JitTransferData* GetJitTransferData() { return this->jitTransferData; }
  21. void FreeJitTransferData();
  22. void RecordNativeCode(Js::JavascriptMethod thunkAddress, Js::JavascriptMethod nativeAddress, ptrdiff_t codeSize, void * validationCookie);
  23. Js::JavascriptMethod GetNativeAddress() { return this->nativeAddress; }
  24. Js::JavascriptMethod GetThunkAddress() { return this->thunkAddress; }
  25. ptrdiff_t GetCodeSize() { return this->codeSize; }
  26. void SetTJNativeAddress(Js::JavascriptMethod nativeAddress, void * validationCookie);
  27. void SetTJCodeSize(ptrdiff_t codeSize);
  28. void AddWeakFuncRef(RecyclerWeakReference<Js::FunctionBody> *weakFuncRef, Recycler *recycler);
  29. Js::EntryPointPolymorphicInlineCacheInfo * EnsurePolymorphicInlineCacheInfo(Recycler * recycler, Js::FunctionBody * functionBody);
  30. Js::EntryPointPolymorphicInlineCacheInfo * GetPolymorphicInlineCacheInfo() { return polymorphicInlineCacheInfo; }
  31. void RegisterConstructorCache(Js::ConstructorCache* constructorCache, Recycler* recycler);
  32. #if DBG
  33. uint GetConstructorCacheCount() const { return this->constructorCaches != nullptr ? this->constructorCaches->Count() : 0; }
  34. #endif
  35. void PinTypeRefs(Recycler * recycler, size_t count, void ** typeRefs);
  36. Js::PropertyGuard* RegisterSharedPropertyGuard(Js::PropertyId propertyId, Js::ScriptContext* scriptContext);
  37. Js::PropertyId* GetSharedPropertyGuards(Recycler * recycler, _Out_ unsigned int& count);
  38. bool TryGetSharedPropertyGuard(Js::PropertyId propertyId, Js::PropertyGuard*& guard);
  39. Js::EquivalentTypeCache * EnsureEquivalentTypeCache(int guardCount, Js::ScriptContext * scriptContext, Js::EntryPointInfo * entryPointInfo);
  40. bool ClearEquivalentTypeCaches(Recycler * recycler);
  41. Field(Js::FakePropertyGuardWeakReference*) * EnsurePropertyGuardWeakRefs(int guardCount, Recycler * recycler);
  42. Js::SmallSpanSequence * GetNativeThrowSpanSequence() { return this->nativeThrowSpanSequence; }
  43. void SetNativeThrowSpanSequence(Js::SmallSpanSequence * seq) { this->nativeThrowSpanSequence = seq; }
  44. uint GetFrameHeight() { return frameHeight; }
  45. void SetFrameHeight(uint frameHeight) { this->frameHeight = frameHeight; }
  46. uint32 GetPendingPolymorphicCacheState() const { return this->pendingPolymorphicCacheState; }
  47. void SetPendingPolymorphicCacheState(uint32 state) { this->pendingPolymorphicCacheState = state; }
  48. BYTE GetPendingInlinerVersion() const { return this->pendingInlinerVersion; }
  49. void SetPendingInlinerVersion(BYTE version) { this->pendingInlinerVersion = version; }
  50. Js::ImplicitCallFlags GetPendingImplicitCallFlags() const { return this->pendingImplicitCallFlags; }
  51. void SetPendingImplicitCallFlags(Js::ImplicitCallFlags flags) { this->pendingImplicitCallFlags = flags; }
  52. void Cleanup(Js::ScriptContext * scriptContext, bool isShutdown, bool reset);
  53. void ClearTypeRefsAndGuards(Js::ScriptContext * scriptContext);
  54. #if PDATA_ENABLED
  55. XDataAllocation* GetXDataInfo() { return this->xdataInfo; }
  56. void CleanupXDataInfo();
  57. void SetXDataInfo(XDataAllocation* xdataInfo) { this->xdataInfo = xdataInfo; }
  58. #endif
  59. private:
  60. void RegisterEquivalentTypeCaches(Js::ScriptContext * scriptContext, Js::EntryPointInfo * entryPointInfo);
  61. void UnregisterEquivalentTypeCaches(Js::ScriptContext * scriptContext);
  62. void FreePropertyGuards();
  63. void FreeNativeCode(Js::ScriptContext * scriptContext, bool isShutdown);
  64. FieldNoBarrier(Js::JavascriptMethod) nativeAddress;
  65. FieldNoBarrier(Js::JavascriptMethod) thunkAddress;
  66. Field(ptrdiff_t) codeSize;
  67. Field(void*) validationCookie;
  68. // This field holds any recycler allocated references that must be kept alive until
  69. // we install the entry point. It is freed at that point, so anything that must survive
  70. // until the EntryPointInfo itself goes away, must be copied somewhere else.
  71. Field(JitTransferData*) jitTransferData;
  72. typedef JsUtil::BaseHashSet<RecyclerWeakReference<Js::FunctionBody>*, Recycler, PowerOf2SizePolicy> WeakFuncRefSet;
  73. Field(WeakFuncRefSet *) weakFuncRefSet;
  74. // Need to keep strong references to the guards here so they don't get collected while the entry point is alive.
  75. typedef JsUtil::BaseDictionary<Js::PropertyId, Js::PropertyGuard*, Recycler, PowerOf2SizePolicy> SharedPropertyGuardDictionary;
  76. Field(SharedPropertyGuardDictionary*) sharedPropertyGuards;
  77. typedef SListCounted<Js::ConstructorCache*, Recycler> ConstructorCacheList;
  78. Field(ConstructorCacheList*) constructorCaches;
  79. Field(Js::EntryPointPolymorphicInlineCacheInfo *) polymorphicInlineCacheInfo;
  80. // If we pin types this array contains strong references to types, otherwise it holds weak references.
  81. Field(Field(void*)*) runtimeTypeRefs;
  82. // This array holds fake weak references to type property guards. We need it to zero out the weak references when the
  83. // entry point is finalized and the guards are about to be freed. Otherwise, if one of the guards was to be invalidated
  84. // from the thread context, we would AV trying to access freed memory. Note that the guards themselves are allocated by
  85. // NativeCodeData::Allocator and are kept alive by the data field. The weak references are recycler allocated, and so
  86. // the array must be recycler allocated also, so that the recycler doesn't collect the weak references.
  87. Field(Field(Js::FakePropertyGuardWeakReference*)*) propertyGuardWeakRefs;
  88. Field(Js::EquivalentTypeCache*) equivalentTypeCaches;
  89. Field(Js::EntryPointInfo **) registeredEquivalentTypeCacheRef;
  90. FieldNoBarrier(Js::SmallSpanSequence *) nativeThrowSpanSequence;
  91. #if PDATA_ENABLED
  92. Field(XDataAllocation *) xdataInfo;
  93. #endif
  94. Field(int) propertyGuardCount;
  95. Field(int) equivalentTypeCacheCount;
  96. Field(uint) frameHeight;
  97. // TODO: these only applies to FunctionEntryPointInfo
  98. Field(BYTE) pendingInlinerVersion;
  99. Field(Js::ImplicitCallFlags) pendingImplicitCallFlags;
  100. Field(uint32) pendingPolymorphicCacheState;
  101. #if DBG_DUMP || defined(VTUNE_PROFILING)
  102. public:
  103. // NativeOffsetMap is public for DBG_DUMP, private for VTUNE_PROFILING
  104. struct NativeOffsetMap
  105. {
  106. uint32 statementIndex;
  107. regex::Interval nativeOffsetSpan;
  108. };
  109. typedef JsUtil::List<NativeOffsetMap, HeapAllocator> NativeOffsetMapListType;
  110. NativeOffsetMapListType& GetNativeOffsetMaps() { return nativeOffsetMaps; }
  111. private:
  112. Field(NativeOffsetMapListType) nativeOffsetMaps;
  113. #endif
  114. };
  115. class InProcNativeEntryPointData : public NativeEntryPointData
  116. {
  117. public:
  118. InProcNativeEntryPointData();
  119. void SetNativeCodeData(NativeCodeData * nativeCodeData);
  120. InlineeFrameMap * GetInlineeFrameMap();
  121. void RecordInlineeFrameMap(JsUtil::List<NativeOffsetInlineeFramePair, ArenaAllocator>* tempInlineeFrameMap);
  122. NativeLazyBailOutRecordList * GetSortedLazyBailOutRecordList() const;
  123. void SetSortedLazyBailOutRecordList(JsUtil::List<LazyBailOutRecord, ArenaAllocator>* sortedLazyBailOutRecordList);
  124. void SetLazyBailOutRecordSlotOffset(int32 argSlotOffset);
  125. int32 GetLazyBailOutRecordSlotOffset() const;
  126. void SetLazyBailOutThunkOffset(uint32 thunkOffset);
  127. uint32 GetLazyBailOutThunkOffset() const;
  128. #if !FLOATVAR
  129. void SetNumberChunks(CodeGenNumberChunk* chunks)
  130. {
  131. numberChunks = chunks;
  132. }
  133. #endif
  134. void OnCleanup();
  135. private:
  136. FieldNoBarrier(NativeCodeData *) nativeCodeData;
  137. FieldNoBarrier(InlineeFrameMap *) inlineeFrameMap;
  138. FieldNoBarrier(NativeLazyBailOutRecordList *) sortedLazyBailoutRecordList;
  139. FieldNoBarrier(int32) lazyBailOutRecordSlotOffset;
  140. FieldNoBarrier(uint32) lazyBailOutThunkOffset;
  141. #if !FLOATVAR
  142. Field(CodeGenNumberChunk*) numberChunks;
  143. #endif
  144. };
  145. class OOPNativeEntryPointData : public NativeEntryPointData
  146. {
  147. public:
  148. OOPNativeEntryPointData();
  149. static uint32 GetOffsetOfNativeDataBuffer();
  150. static void DeleteNativeDataBuffer(char * naitveDataBuffer);
  151. char* GetNativeDataBuffer();
  152. char** GetNativeDataBufferRef();
  153. void SetNativeDataBuffer(char *);
  154. uint GetInlineeFrameOffsetArrayOffset();
  155. uint GetInlineeFrameOffsetArrayCount();
  156. void RecordInlineeFrameOffsetsInfo(unsigned int offsetsArrayOffset, unsigned int offsetsArrayCount);
  157. #if !FLOATVAR
  158. void ProcessNumberPageSegments(Js::ScriptContext * scriptContext);
  159. void SetNumberPageSegment(XProcNumberPageSegment * segments)
  160. {
  161. Assert(numberPageSegments == nullptr);
  162. numberPageSegments = segments;
  163. }
  164. #endif
  165. void OnCleanup();
  166. private:
  167. Field(uint) inlineeFrameOffsetArrayOffset;
  168. Field(uint) inlineeFrameOffsetArrayCount;
  169. FieldNoBarrier(char *) nativeDataBuffer;
  170. #if !FLOATVAR
  171. Field(Field(Js::JavascriptNumber*)*) numberArray;
  172. Field(XProcNumberPageSegment*) numberPageSegments;
  173. #endif
  174. };
  175. #endif