NativeEntryPointData.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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> BailOutRecordMap;
  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. BailOutRecordMap * GetBailOutRecordMap();
  123. void RecordBailOutMap(JsUtil::List<LazyBailOutRecord, ArenaAllocator>* bailoutMap);
  124. #if !FLOATVAR
  125. void SetNumberChunks(CodeGenNumberChunk* chunks)
  126. {
  127. numberChunks = chunks;
  128. }
  129. #endif
  130. void OnCleanup();
  131. private:
  132. FieldNoBarrier(NativeCodeData *) nativeCodeData;
  133. FieldNoBarrier(InlineeFrameMap*) inlineeFrameMap;
  134. FieldNoBarrier(BailOutRecordMap*) bailoutRecordMap;
  135. #if !FLOATVAR
  136. Field(CodeGenNumberChunk*) numberChunks;
  137. #endif
  138. };
  139. class OOPNativeEntryPointData : public NativeEntryPointData
  140. {
  141. public:
  142. OOPNativeEntryPointData();
  143. static uint32 GetOffsetOfNativeDataBuffer();
  144. static void DeleteNativeDataBuffer(char * naitveDataBuffer);
  145. char* GetNativeDataBuffer();
  146. char** GetNativeDataBufferRef();
  147. void SetNativeDataBuffer(char *);
  148. uint GetInlineeFrameOffsetArrayOffset();
  149. uint GetInlineeFrameOffsetArrayCount();
  150. void RecordInlineeFrameOffsetsInfo(unsigned int offsetsArrayOffset, unsigned int offsetsArrayCount);
  151. #if !FLOATVAR
  152. void ProcessNumberPageSegments(Js::ScriptContext * scriptContext);
  153. void SetNumberPageSegment(XProcNumberPageSegment * segments)
  154. {
  155. Assert(numberPageSegments == nullptr);
  156. numberPageSegments = segments;
  157. }
  158. #endif
  159. void OnCleanup();
  160. private:
  161. Field(uint) inlineeFrameOffsetArrayOffset;
  162. Field(uint) inlineeFrameOffsetArrayCount;
  163. FieldNoBarrier(char *) nativeDataBuffer;
  164. #if !FLOATVAR
  165. Field(Field(Js::JavascriptNumber*)*) numberArray;
  166. Field(XProcNumberPageSegment*) numberPageSegments;
  167. #endif
  168. };
  169. #endif