TTInflateMap.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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_TTD
  7. namespace TTD
  8. {
  9. //A class that manages inflation maps during heap state restoration
  10. class InflateMap
  11. {
  12. private:
  13. TTDIdentifierDictionary<TTD_PTR_ID, Js::DynamicTypeHandler*> m_handlerMap;
  14. TTDIdentifierDictionary<TTD_PTR_ID, Js::Type*> m_typeMap;
  15. //The maps for script contexts and objects
  16. TTDIdentifierDictionary<TTD_LOG_PTR_ID, Js::GlobalObject*> m_tagToGlobalObjectMap; //get the script context from here
  17. TTDIdentifierDictionary<TTD_PTR_ID, Js::RecyclableObject*> m_objectMap;
  18. //The maps for inflated function bodies
  19. TTDIdentifierDictionary<TTD_PTR_ID, Js::FunctionBody*> m_functionBodyMap;
  20. TTDIdentifierDictionary<TTD_PTR_ID, Js::FrameDisplay*> m_environmentMap;
  21. TTDIdentifierDictionary<TTD_PTR_ID, Field(Js::Var)*> m_slotArrayMap;
  22. //The maps for resolving debug scopes
  23. TTDIdentifierDictionary<TTD_PTR_ID, Js::FunctionBody*> m_debuggerScopeHomeBodyMap;
  24. TTDIdentifierDictionary<TTD_PTR_ID, int32> m_debuggerScopeChainIndexMap;
  25. //A dictionary for the Promise related bits (not typesafe and a bit ugly but I prefer it to creating multiple additional collections)
  26. JsUtil::BaseDictionary<TTD_PTR_ID, void*, HeapAllocator> m_promiseDataMap;
  27. //A set we use to pin all the inflated objects live during/after the inflate process (to avoid accidental collection)
  28. RecyclerRootPtr<ObjectPinSet> m_inflatePinSet;
  29. RecyclerRootPtr<EnvironmentPinSet> m_environmentPinSet;
  30. RecyclerRootPtr<SlotArrayPinSet> m_slotArrayPinSet;
  31. //A set we use to keep some old objects alive during inflate in case we want to re-use them
  32. RecyclerRootPtr<ObjectPinSet> m_oldInflatePinSet;
  33. //Temp data structures for holding info during the inflate process
  34. TTDIdentifierDictionary<TTD_PTR_ID, Js::RecyclableObject*> m_oldObjectMap;
  35. TTDIdentifierDictionary<TTD_PTR_ID, Js::FunctionBody*> m_oldFunctionBodyMap;
  36. JsUtil::BaseHashSet<Js::PropertyId, HeapAllocator> m_propertyReset;
  37. public:
  38. InflateMap();
  39. ~InflateMap();
  40. void PrepForInitialInflate(ThreadContext* threadContext, uint32 ctxCount, uint32 handlerCount, uint32 typeCount, uint32 objectCount, uint32 bodyCount, uint32 dbgScopeCount, uint32 envCount, uint32 slotCount);
  41. void PrepForReInflate(uint32 ctxCount, uint32 handlerCount, uint32 typeCount, uint32 objectCount, uint32 bodyCount, uint32 dbgScopeCount, uint32 envCount, uint32 slotCount);
  42. void CleanupAfterInflate();
  43. bool IsObjectAlreadyInflated(TTD_PTR_ID objid) const;
  44. bool IsFunctionBodyAlreadyInflated(TTD_PTR_ID fbodyid) const;
  45. Js::RecyclableObject* FindReusableObjectIfExists(TTD_PTR_ID objid) const;
  46. Js::FunctionBody* FindReusableFunctionBodyIfExists(TTD_PTR_ID fbodyid) const;
  47. //A version of FindReusableObjectIfExists but we haven't moved the last inflate objects to oldObjects yet so we need to look in a differnt location
  48. Js::RecyclableObject* FindReusableObject_WellKnowReuseCheck(TTD_PTR_ID objid) const;
  49. ////
  50. Js::DynamicTypeHandler* LookupHandler(TTD_PTR_ID handlerId) const;
  51. Js::Type* LookupType(TTD_PTR_ID typeId) const;
  52. Js::ScriptContext* LookupScriptContext(TTD_LOG_PTR_ID sctag) const;
  53. Js::RecyclableObject* LookupObject(TTD_PTR_ID objid) const;
  54. Js::FunctionBody* LookupFunctionBody(TTD_PTR_ID functionId) const;
  55. Js::FrameDisplay* LookupEnvironment(TTD_PTR_ID envid) const;
  56. Field(Js::Var)* LookupSlotArray(TTD_PTR_ID slotid) const;
  57. void LookupInfoForDebugScope(TTD_PTR_ID dbgScopeId, Js::FunctionBody** homeBody, int32* chainIndex) const;
  58. ////
  59. void AddDynamicHandler(TTD_PTR_ID handlerId, Js::DynamicTypeHandler* value);
  60. void AddType(TTD_PTR_ID typeId, Js::Type* value);
  61. void AddScriptContext(TTD_LOG_PTR_ID sctag, Js::ScriptContext* value);
  62. void AddObject(TTD_PTR_ID objid, Js::RecyclableObject* value);
  63. void AddInflationFunctionBody(TTD_PTR_ID functionId, Js::FunctionBody* value);
  64. void AddEnvironment(TTD_PTR_ID envId, Js::FrameDisplay* value);
  65. void AddSlotArray(TTD_PTR_ID slotId, Field(Js::Var)* value);
  66. void UpdateFBScopes(const NSSnapValues::SnapFunctionBodyScopeChain& scopeChainInfo, Js::FunctionBody* fb);
  67. ////
  68. //Get the inflate stack and property reset set to use for depends on processing
  69. JsUtil::BaseHashSet<Js::PropertyId, HeapAllocator>& GetPropertyResetSet();
  70. Js::Var InflateTTDVar(TTDVar var) const;
  71. ////
  72. template <typename T>
  73. bool IsPromiseInfoDefined(TTD_PTR_ID ptrId) const
  74. {
  75. return this->m_promiseDataMap.ContainsKey(ptrId);
  76. }
  77. template <typename T>
  78. void AddInflatedPromiseInfo(TTD_PTR_ID ptrId, T* data)
  79. {
  80. this->m_promiseDataMap.AddNew(ptrId, data);
  81. }
  82. template <typename T>
  83. T* LookupInflatedPromiseInfo(TTD_PTR_ID ptrId) const
  84. {
  85. return (T*)this->m_promiseDataMap.Item(ptrId);
  86. }
  87. };
  88. //////////////////
  89. #if ENABLE_SNAPSHOT_COMPARE
  90. enum class TTDCompareTag
  91. {
  92. Done,
  93. //Values should not be matched by ptr -- should be immediately matched by value
  94. SlotArray,
  95. FunctionScopeInfo,
  96. TopLevelLoadFunction,
  97. TopLevelNewFunction,
  98. TopLevelEvalFunction,
  99. FunctionBody,
  100. SnapObject
  101. };
  102. class TTDCompareMap;
  103. typedef void(*fPtr_AssertSnapEquivAddtlInfo)(const NSSnapObjects::SnapObject* v1, const NSSnapObjects::SnapObject* v2, TTDCompareMap& compareMap);
  104. class TTDComparePath
  105. {
  106. public:
  107. enum class StepKind
  108. {
  109. Empty,
  110. Root,
  111. PropertyData,
  112. PropertyGetter,
  113. PropertySetter,
  114. Array,
  115. Scope,
  116. SlotArray,
  117. FunctionBody,
  118. Special,
  119. SpecialArray
  120. };
  121. struct PathEntry
  122. {
  123. int64 IndexOrPID;
  124. const char16* OptName;
  125. };
  126. private:
  127. const StepKind m_stepKind;
  128. const TTDComparePath* m_prefix;
  129. const PathEntry m_step;
  130. public:
  131. TTDComparePath();
  132. TTDComparePath(const TTDComparePath* prefix, StepKind stepKind, const PathEntry& nextStep);
  133. ~TTDComparePath();
  134. void WritePathToConsole(ThreadContext* threadContext, bool printNewline, _Out_writes_z_(namebuffLength) char16* namebuff, charcount_t namebuffLength) const;
  135. };
  136. //A class that we use to manage all the dictionaries we need when comparing 2 snapshots
  137. class TTDCompareMap
  138. {
  139. public:
  140. bool StrictCrossSite;
  141. JsUtil::Queue<TTD_PTR_ID, HeapAllocator> H1PtrIdWorklist;
  142. JsUtil::BaseDictionary<TTD_PTR_ID, TTD_PTR_ID, HeapAllocator> H1PtrToH2PtrMap;
  143. TTDComparePath* CurrentPath;
  144. TTD_PTR_ID CurrentH1Ptr;
  145. TTD_PTR_ID CurrentH2Ptr;
  146. ThreadContext* Context;
  147. char16* PathBuffer;
  148. JsUtil::BaseDictionary<TTD_PTR_ID, TTDComparePath*, HeapAllocator> H1PtrToPathMap;
  149. fPtr_AssertSnapEquivAddtlInfo* SnapObjCmpVTable;
  150. ////
  151. //H1 Maps
  152. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapValues::SnapPrimitiveValue*, HeapAllocator> H1ValueMap;
  153. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapValues::SlotArrayInfo*, HeapAllocator> H1SlotArrayMap;
  154. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapValues::ScriptFunctionScopeInfo*, HeapAllocator> H1FunctionScopeInfoMap;
  155. JsUtil::BaseDictionary<TTD_PTR_ID, uint64, HeapAllocator> H1FunctionTopLevelLoadMap;
  156. JsUtil::BaseDictionary<TTD_PTR_ID, uint64, HeapAllocator> H1FunctionTopLevelNewMap;
  157. JsUtil::BaseDictionary<TTD_PTR_ID, uint64, HeapAllocator> H1FunctionTopLevelEvalMap;
  158. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapValues::FunctionBodyResolveInfo*, HeapAllocator> H1FunctionBodyMap;
  159. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapObjects::SnapObject*, HeapAllocator> H1ObjectMap;
  160. JsUtil::BaseHashSet<TTD_PTR_ID, HeapAllocator> H1PendingAsyncModBufferSet;
  161. ////
  162. //H2 Maps
  163. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapValues::SnapPrimitiveValue*, HeapAllocator> H2ValueMap;
  164. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapValues::SlotArrayInfo*, HeapAllocator> H2SlotArrayMap;
  165. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapValues::ScriptFunctionScopeInfo*, HeapAllocator> H2FunctionScopeInfoMap;
  166. JsUtil::BaseDictionary<TTD_PTR_ID, uint64, HeapAllocator> H2FunctionTopLevelLoadMap;
  167. JsUtil::BaseDictionary<TTD_PTR_ID, uint64, HeapAllocator> H2FunctionTopLevelNewMap;
  168. JsUtil::BaseDictionary<TTD_PTR_ID, uint64, HeapAllocator> H2FunctionTopLevelEvalMap;
  169. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapValues::FunctionBodyResolveInfo*, HeapAllocator> H2FunctionBodyMap;
  170. JsUtil::BaseDictionary<TTD_PTR_ID, const NSSnapObjects::SnapObject*, HeapAllocator> H2ObjectMap;
  171. JsUtil::BaseHashSet<TTD_PTR_ID, HeapAllocator> H2PendingAsyncModBufferSet;
  172. ////
  173. //Code
  174. TTDCompareMap(ThreadContext* threadContext);
  175. ~TTDCompareMap();
  176. //Assert the condition must be true and report if not
  177. void DiagnosticAssert(bool condition);
  178. //Check that the given mapping either (1) does not exist or (2) is consistent -- if needed add the mapping and to worklist as well
  179. void CheckConsistentAndAddPtrIdMapping_Helper(TTD_PTR_ID h1PtrId, TTD_PTR_ID h2PtrId, TTDComparePath::StepKind stepKind, const TTDComparePath::PathEntry& next);
  180. void CheckConsistentAndAddPtrIdMapping_Scope(TTD_PTR_ID h1PtrId, TTD_PTR_ID h2PtrId, uint32 index);
  181. void CheckConsistentAndAddPtrIdMapping_FunctionBody(TTD_PTR_ID h1PtrId, TTD_PTR_ID h2PtrId);
  182. void CheckConsistentAndAddPtrIdMapping_Special(TTD_PTR_ID h1PtrId, TTD_PTR_ID h2PtrId, const char16* specialField);
  183. void CheckConsistentAndAddPtrIdMapping_Root(TTD_PTR_ID h1PtrId, TTD_PTR_ID h2PtrId, TTD_LOG_PTR_ID tag);
  184. //Check if the given mapping is consistent but do not enqueue or try to lookup ptr id in any of the maps (used mainly for heap allocated promise info that may be shared)
  185. void CheckConsistentAndAddPtrIdMapping_NoEnqueue(TTD_PTR_ID h1PtrId, TTD_PTR_ID h2PtrId);
  186. void GetNextCompareInfo(TTDCompareTag* tag, TTD_PTR_ID* h1PtrId, TTD_PTR_ID* h2PtrId);
  187. void GetCompareValues(TTDCompareTag compareTag, TTD_PTR_ID h1PtrId, const NSSnapValues::SlotArrayInfo** val1, TTD_PTR_ID h2PtrId, const NSSnapValues::SlotArrayInfo** val2);
  188. void GetCompareValues(TTDCompareTag compareTag, TTD_PTR_ID h1PtrId, const NSSnapValues::ScriptFunctionScopeInfo** val1, TTD_PTR_ID h2PtrId, const NSSnapValues::ScriptFunctionScopeInfo** val2);
  189. void GetCompareValues(TTDCompareTag compareTag, TTD_PTR_ID h1PtrId, uint64* val1, TTD_PTR_ID h2PtrId, uint64* val2);
  190. void GetCompareValues(TTDCompareTag compareTag, TTD_PTR_ID h1PtrId, const NSSnapValues::FunctionBodyResolveInfo** val1, TTD_PTR_ID h2PtrId, const NSSnapValues::FunctionBodyResolveInfo** val2);
  191. void GetCompareValues(TTDCompareTag compareTag, TTD_PTR_ID h1PtrId, const NSSnapObjects::SnapObject** val1, TTD_PTR_ID h2PtrId, const NSSnapObjects::SnapObject** val2);
  192. };
  193. #endif
  194. }
  195. #endif