NativeCodeData.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. #define NativeCodeDataNew(alloc, T, ...) AllocatorNew(NativeCodeData::AllocatorT<T>, alloc, T, __VA_ARGS__)
  7. #define NativeCodeDataNewZ(alloc, T, ...) AllocatorNewZ(NativeCodeData::AllocatorT<T>, alloc, T, __VA_ARGS__)
  8. #define NativeCodeDataNewArray(alloc, T, count) AllocatorNewArray(NativeCodeData::AllocatorT<NativeCodeData::Array<T>>, alloc, T, count)
  9. #define NativeCodeDataNewArrayZ(alloc, T, count) AllocatorNewArrayZ(NativeCodeData::AllocatorT<NativeCodeData::Array<T>>, alloc, T, count)
  10. #define NativeCodeDataNewPlusZ(size, alloc, T, ...) AllocatorNewPlusZ(NativeCodeData::AllocatorT<T>, alloc, size, T, __VA_ARGS__)
  11. #define NativeCodeDataNewNoFixup(alloc, T, ...) AllocatorNew(NativeCodeData::AllocatorNoFixup<T>, alloc, T, __VA_ARGS__)
  12. #define NativeCodeDataNewZNoFixup(alloc, T, ...) AllocatorNewZ(NativeCodeData::AllocatorNoFixup<T>, alloc, T, __VA_ARGS__)
  13. #define NativeCodeDataNewArrayNoFixup(alloc, T, count) AllocatorNewArray(NativeCodeData::AllocatorNoFixup<NativeCodeData::Array<T>>, alloc, T, count)
  14. #define NativeCodeDataNewArrayZNoFixup(alloc, T, count) AllocatorNewArrayZ(NativeCodeData::AllocatorNoFixup<NativeCodeData::Array<T>>, alloc, T, count)
  15. #define NativeCodeDataNewPlusZNoFixup(size, alloc, T, ...) AllocatorNewPlusZ(NativeCodeData::AllocatorNoFixup<T>, alloc, size, T, __VA_ARGS__)
  16. #define FixupNativeDataPointer(field, chunkList) NativeCodeData::AddFixupEntry(this->field, &this->field, this, chunkList)
  17. class NativeCodeData
  18. {
  19. public:
  20. struct DataChunk
  21. {
  22. unsigned int len;
  23. unsigned int allocIndex;
  24. unsigned int offset; // offset to the aggregated buffer
  25. #if DBG
  26. const char* dataType;
  27. #endif
  28. // todo: use union?
  29. void(*fixupFunc)(void* _this, NativeCodeData::DataChunk*);
  30. NativeDataFixupEntry *fixupList;
  31. DataChunk * next;
  32. char data[0];
  33. };
  34. struct DataChunkNoFixup
  35. {
  36. DataChunkNoFixup * next;
  37. char data[0];
  38. };
  39. static DataChunk* GetDataChunk(void* data)
  40. {
  41. Assert(JITManager::GetJITManager()->IsJITServer());
  42. return (NativeCodeData::DataChunk*)((char*)data - offsetof(NativeCodeData::DataChunk, data));
  43. }
  44. static char16* GetDataDescription(void* data, JitArenaAllocator * alloc);
  45. static unsigned int GetDataTotalOffset(void* data)
  46. {
  47. Assert(JITManager::GetJITManager()->IsJITServer());
  48. return GetDataChunk(data)->offset;
  49. }
  50. NativeCodeData(DataChunk * chunkList);
  51. union
  52. {
  53. DataChunk * chunkList;
  54. DataChunkNoFixup * noFixupChunkList;
  55. };
  56. #ifdef PERF_COUNTERS
  57. size_t size;
  58. #endif
  59. public:
  60. static void VerifyExistFixupEntry(void* targetAddr, void* addrToFixup, void* startAddress);
  61. static void AddFixupEntry(void* targetAddr, void* addrToFixup, void* startAddress, DataChunk * chunkList);
  62. static void AddFixupEntry(void* targetAddr, void* targetStartAddr, void* addrToFixup, void* startAddress, DataChunk * chunkList);
  63. static void AddFixupEntryForPointerArray(void* startAddress, DataChunk * chunkList);
  64. template<class DataChunkT>
  65. static void DeleteChunkList(DataChunkT * chunkList);
  66. public:
  67. class Allocator
  68. {
  69. public:
  70. static const bool FakeZeroLengthArray = false;
  71. Allocator();
  72. ~Allocator();
  73. char * Alloc(DECLSPEC_GUARD_OVERFLOW size_t requestedBytes);
  74. char * AllocZero(DECLSPEC_GUARD_OVERFLOW size_t requestedBytes);
  75. char * AllocLeaf(DECLSPEC_GUARD_OVERFLOW size_t requestedBytes);
  76. NativeCodeData * Finalize();
  77. void Free(void * buffer, size_t byteSize);
  78. union
  79. {
  80. DataChunk * chunkList;
  81. DataChunkNoFixup* noFixupChunkList;
  82. };
  83. DataChunk * lastChunkList; // used to maintain the allocation order in the list
  84. unsigned int totalSize;
  85. unsigned int allocCount;
  86. #ifdef TRACK_ALLOC
  87. // Doesn't support tracking information, dummy implementation
  88. Allocator * TrackAllocInfo(TrackAllocData const& data) { return this; }
  89. void ClearTrackAllocInfo(TrackAllocData* data = NULL) {}
  90. #endif
  91. protected:
  92. bool isOOPJIT;
  93. private:
  94. #if DBG
  95. bool finalized;
  96. #endif
  97. #ifdef PERF_COUNTERS
  98. size_t size;
  99. #endif
  100. };
  101. template<typename T>
  102. class Array
  103. {
  104. public:
  105. void Fixup(NativeCodeData::DataChunk* chunkList)
  106. {
  107. int count = NativeCodeData::GetDataChunk(this)->len / sizeof(T);
  108. while (count-- > 0)
  109. {
  110. (((T*)this) + count)->Fixup(chunkList);
  111. }
  112. }
  113. };
  114. template<typename T>
  115. class AllocatorNoFixup : public Allocator
  116. {
  117. public:
  118. char * Alloc(size_t requestedBytes)
  119. {
  120. char* dataBlock = __super::Alloc(requestedBytes);
  121. #if DBG
  122. if (JITManager::GetJITManager()->IsJITServer())
  123. {
  124. DataChunk* chunk = NativeCodeData::GetDataChunk(dataBlock);
  125. chunk->dataType = typeid(T).name();
  126. if (PHASE_TRACE1(Js::NativeCodeDataPhase))
  127. {
  128. Output::Print(_u("NativeCodeData AllocNoFix: chunk: %p, data: %p, index: %d, len: %x, totalOffset: %x, type: %S\n"),
  129. chunk, (void*)dataBlock, chunk->allocIndex, chunk->len, chunk->offset, chunk->dataType);
  130. }
  131. }
  132. #endif
  133. return dataBlock;
  134. }
  135. char * AllocZero(size_t requestedBytes)
  136. {
  137. char* dataBlock = __super::AllocZero(requestedBytes);
  138. #if DBG
  139. if (JITManager::GetJITManager()->IsJITServer())
  140. {
  141. DataChunk* chunk = NativeCodeData::GetDataChunk(dataBlock);
  142. chunk->dataType = typeid(T).name();
  143. if (PHASE_TRACE1(Js::NativeCodeDataPhase))
  144. {
  145. Output::Print(_u("NativeCodeData AllocNoFix: chunk: %p, data: %p, index: %d, len: %x, totalOffset: %x, type: %S\n"),
  146. chunk, (void*)dataBlock, chunk->allocIndex, chunk->len, chunk->offset, chunk->dataType);
  147. }
  148. }
  149. #endif
  150. return dataBlock;
  151. }
  152. char * AllocLeaf(size_t requestedBytes)
  153. {
  154. return Alloc(requestedBytes);
  155. }
  156. };
  157. template<typename T>
  158. class AllocatorT : public Allocator
  159. {
  160. char* AddFixup(char* dataBlock)
  161. {
  162. if (isOOPJIT)
  163. {
  164. DataChunk* chunk = NativeCodeData::GetDataChunk(dataBlock);
  165. chunk->fixupFunc = &Fixup;
  166. #if DBG
  167. chunk->dataType = typeid(T).name();
  168. if (PHASE_TRACE1(Js::NativeCodeDataPhase))
  169. {
  170. Output::Print(_u("NativeCodeData Alloc: chunk: %p, data: %p, index: %d, len: %x, totalOffset: %x, type: %S\n"),
  171. chunk, (void*)dataBlock, chunk->allocIndex, chunk->len, chunk->offset, chunk->dataType);
  172. }
  173. #endif
  174. }
  175. return dataBlock;
  176. }
  177. public:
  178. char * Alloc(size_t requestedBytes)
  179. {
  180. return AddFixup(__super::Alloc(requestedBytes));
  181. }
  182. char * AllocZero(size_t requestedBytes)
  183. {
  184. return AddFixup(__super::AllocZero(requestedBytes));
  185. }
  186. static void Fixup(void* pThis, NativeCodeData::DataChunk* chunkList)
  187. {
  188. ((T*)pThis)->Fixup(chunkList);
  189. }
  190. };
  191. ~NativeCodeData();
  192. };
  193. enum DataDesc
  194. {
  195. DataDesc_None,
  196. DataDesc_InlineeFrameRecord_ArgOffsets,
  197. DataDesc_InlineeFrameRecord_Constants,
  198. DataDesc_BailoutInfo_CotalOutParamCount,
  199. DataDesc_ArgOutOffsetInfo_StartCallOutParamCounts,
  200. DataDesc_ArgOutOffsetInfo_StartCallArgRestoreAdjustCounts,
  201. DataDesc_LowererMD_LoadFloatValue_Float,
  202. DataDesc_LowererMD_LoadFloatValue_Double,
  203. DataDesc_LowererMD_EmitLoadFloatCommon_Double,
  204. DataDesc_LowererMD_Simd128LoadConst,
  205. };
  206. template<DataDesc desc = DataDesc_None>
  207. struct IntType
  208. {
  209. int data;
  210. };
  211. template<DataDesc desc = DataDesc_None>
  212. struct UIntType
  213. {
  214. uint data;
  215. };
  216. template<DataDesc desc = DataDesc_None>
  217. struct FloatType
  218. {
  219. FloatType(float val) :data(val) {}
  220. float data;
  221. };
  222. template<DataDesc desc = DataDesc_None>
  223. struct DoubleType
  224. {
  225. DoubleType() {}
  226. DoubleType(double val) :data(val) {}
  227. double data;
  228. };
  229. template<DataDesc desc = DataDesc_None>
  230. struct SIMDType
  231. {
  232. SIMDType() {}
  233. SIMDType(AsmJsSIMDValue val) :data(val) {}
  234. AsmJsSIMDValue data;
  235. };
  236. template<DataDesc desc = DataDesc_None>
  237. struct VarType
  238. {
  239. Js::Var data;
  240. void Fixup(NativeCodeData::DataChunk* chunkList)
  241. {
  242. AssertMsg(false, "Please specialize Fixup method for this Var type or use no-fixup allocator");
  243. }
  244. };
  245. template<>
  246. inline void VarType<DataDesc_InlineeFrameRecord_Constants>::Fixup(NativeCodeData::DataChunk* chunkList)
  247. {
  248. AssertMsg(false, "InlineeFrameRecord::constants contains Var from main process, should not fixup");
  249. }
  250. struct GlobalBailOutRecordDataTable;
  251. template<>
  252. inline void NativeCodeData::Array<GlobalBailOutRecordDataTable *>::Fixup(NativeCodeData::DataChunk* chunkList)
  253. {
  254. NativeCodeData::AddFixupEntryForPointerArray(this, chunkList);
  255. }