TTSnapshot.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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 represents a heap snapshot the page context
  10. class SnapShot
  11. {
  12. private:
  13. ////
  14. //The slab allocator we use for storing the data extracted
  15. SlabAllocator m_slabAllocator;
  16. ////
  17. //List containing the "context" information for the objects in this snapshot
  18. UnorderedArrayList<NSSnapValues::SnapContext, TTD_ARRAY_LIST_SIZE_XSMALL> m_ctxList;
  19. //List containing all the propertyids for the symbols that are in the thread context symbolRegistrationMap
  20. UnorderedArrayList<Js::PropertyId, TTD_ARRAY_LIST_SIZE_XSMALL> m_tcSymbolRegistrationMapContents;
  21. //The active script context
  22. TTD_LOG_PTR_ID m_activeScriptContext;
  23. //A list of all the global root objects and local root objects
  24. UnorderedArrayList<NSSnapValues::SnapRootInfoEntry, TTD_ARRAY_LIST_SIZE_MID> m_rootList;
  25. ////
  26. //Lists containing the "type" information for the objects in this snapshot
  27. //The list of all the dynamichandler definitions that the snapshot uses
  28. UnorderedArrayList<NSSnapType::SnapHandler, TTD_ARRAY_LIST_SIZE_DEFAULT> m_handlerList;
  29. //The list of all the type definitions that the snapshot uses
  30. UnorderedArrayList<NSSnapType::SnapType, TTD_ARRAY_LIST_SIZE_DEFAULT> m_typeList;
  31. ////
  32. //Lists containing the objects in this snapshot
  33. //The list of all the type definitions that the snapshot uses
  34. UnorderedArrayList<NSSnapValues::FunctionBodyResolveInfo, TTD_ARRAY_LIST_SIZE_DEFAULT> m_functionBodyList;
  35. //The list of all the primitive objects (empty until we convert all the primitive pinned objects during extractor unlink)
  36. UnorderedArrayList<NSSnapValues::SnapPrimitiveValue, TTD_ARRAY_LIST_SIZE_LARGE> m_primitiveObjectList;
  37. //The list of all the non-primitive javascript objects in the snapshot
  38. UnorderedArrayList<NSSnapObjects::SnapObject, TTD_ARRAY_LIST_SIZE_LARGE> m_compoundObjectList;
  39. //pseudo vtable for working with snap objects
  40. NSSnapObjects::SnapObjectVTable* m_snapObjectVTableArray;
  41. ////
  42. //Function scope info
  43. //All the scopes in the snapshot
  44. UnorderedArrayList<NSSnapValues::ScriptFunctionScopeInfo, TTD_ARRAY_LIST_SIZE_DEFAULT> m_scopeEntries;
  45. //All the slot arrays in the snapshot
  46. UnorderedArrayList<NSSnapValues::SlotArrayInfo, TTD_ARRAY_LIST_SIZE_DEFAULT> m_slotArrayEntries;
  47. //Emit the json file for the snapshot into the given directory
  48. void EmitSnapshotToFile(FileWriter* writer, ThreadContext* threadContext) const;
  49. static SnapShot* ParseSnapshotFromFile(FileReader* reader);
  50. template<typename Fn, typename T, size_t allocSize>
  51. static void EmitListHelper(Fn emitFunc, const UnorderedArrayList<T, allocSize>& list, FileWriter* snapwriter)
  52. {
  53. snapwriter->WriteLengthValue(list.Count(), NSTokens::Separator::CommaAndBigSpaceSeparator);
  54. snapwriter->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaAndBigSpaceSeparator);
  55. snapwriter->AdjustIndent(1);
  56. bool firstElement = true;
  57. for(auto iter = list.GetIterator(); iter.IsValid(); iter.MoveNext())
  58. {
  59. (*emitFunc)(iter.Current(), snapwriter, firstElement ? NSTokens::Separator::BigSpaceSeparator : NSTokens::Separator::CommaAndBigSpaceSeparator);
  60. firstElement = false;
  61. }
  62. snapwriter->AdjustIndent(-1);
  63. snapwriter->WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
  64. }
  65. template<typename Fn, typename T, size_t allocSize>
  66. static void ParseListHelper(Fn parseFunc, UnorderedArrayList<T, allocSize>& list, FileReader* snapreader, SlabAllocator& alloc)
  67. {
  68. uint32 count = snapreader->ReadLengthValue(true);
  69. snapreader->ReadSequenceStart_WDefaultKey(true);
  70. for(uint32 i = 0; i < count; ++i)
  71. {
  72. T* into = list.NextOpenEntry();
  73. (*parseFunc)(into, i != 0, snapreader, alloc);
  74. }
  75. snapreader->ReadSequenceEnd();
  76. }
  77. template<typename Fn, typename T, typename U, size_t allocSize>
  78. static void ParseListHelper_WMap(Fn parseFunc, UnorderedArrayList<T, allocSize>& list, FileReader* snapreader, SlabAllocator& alloc, const TTDIdentifierDictionary<TTD_PTR_ID, U>& infoMap)
  79. {
  80. uint32 count = snapreader->ReadLengthValue(true);
  81. snapreader->ReadSequenceStart_WDefaultKey(true);
  82. for(uint32 i = 0; i < count; ++i)
  83. {
  84. T* into = list.NextOpenEntry();
  85. (*parseFunc)(into, i != 0, snapreader, alloc, infoMap);
  86. }
  87. snapreader->ReadSequenceEnd();
  88. }
  89. //Inflate a single JS object
  90. void InflateSingleObject(const NSSnapObjects::SnapObject* snpObject, InflateMap* inflator, const TTDIdentifierDictionary<TTD_PTR_ID, NSSnapObjects::SnapObject*>& idToSnpObjectMap) const;
  91. void ReLinkThreadContextInfo(InflateMap* inflator, ThreadContextTTD* intoCtx) const;
  92. static void SnapRootPinEntryEmit(const NSSnapValues::SnapRootInfoEntry* spe, FileWriter* snapwriter, NSTokens::Separator separator);
  93. static void SnapRootPinEntryParse(NSSnapValues::SnapRootInfoEntry* spe, bool readSeparator, FileReader* reader, SlabAllocator& alloc);
  94. public:
  95. //Performance counter values
  96. double GCTime;
  97. double MarkTime;
  98. double ExtractTime;
  99. //Compute the memory used by this snapshot
  100. void ComputeSnapshotMemory(uint64* usedSpace, uint64* reservedSpace) const;
  101. SnapShot(double gcTime);
  102. ~SnapShot();
  103. //Get the counts for the various list sizes (not constant time -- so use carefully!!!!)
  104. uint32 ContextCount() const;
  105. uint32 HandlerCount() const;
  106. uint32 TypeCount() const;
  107. uint32 BodyCount() const;
  108. uint32 PrimitiveCount() const;
  109. uint32 ObjectCount() const;
  110. uint32 EnvCount() const;
  111. uint32 SlotArrayCount() const;
  112. uint32 GetDbgScopeCountNonTopLevel() const;
  113. //Get the context list for this snapshot
  114. UnorderedArrayList<NSSnapValues::SnapContext, TTD_ARRAY_LIST_SIZE_XSMALL>& GetContextList();
  115. const UnorderedArrayList<NSSnapValues::SnapContext, TTD_ARRAY_LIST_SIZE_XSMALL>& GetContextList() const;
  116. //Get the thread context symbol map info list for this snapshot
  117. UnorderedArrayList<Js::PropertyId, TTD_ARRAY_LIST_SIZE_XSMALL>& GetTCSymbolMapInfoList();
  118. TTD_LOG_PTR_ID GetActiveScriptContext() const;
  119. void SetActiveScriptContext(TTD_LOG_PTR_ID activeCtx);
  120. //Get the root lists
  121. UnorderedArrayList<NSSnapValues::SnapRootInfoEntry, TTD_ARRAY_LIST_SIZE_MID>& GetRootList();
  122. //Get a pointer to the next open handler slot that we can fill
  123. NSSnapType::SnapHandler* GetNextAvailableHandlerEntry();
  124. //Get a pointer to the next open handler slot that we can fill
  125. NSSnapType::SnapType* GetNextAvailableTypeEntry();
  126. //Get a pointer to the next open FunctionBodyResolveInfo slot that we can fill
  127. NSSnapValues::FunctionBodyResolveInfo* GetNextAvailableFunctionBodyResolveInfoEntry();
  128. //Get a pointer to the next open primitive object slot that we can fill
  129. NSSnapValues::SnapPrimitiveValue* GetNextAvailablePrimitiveObjectEntry();
  130. //Get a pointer to the next open compound object slot that we can fill
  131. NSSnapObjects::SnapObject* GetNextAvailableCompoundObjectEntry();
  132. //Get a pointer to the next open scope entry slot that we can fill
  133. NSSnapValues::ScriptFunctionScopeInfo* GetNextAvailableFunctionScopeEntry();
  134. //Get a pointer to the next open slot array entry that we can fill
  135. NSSnapValues::SlotArrayInfo* GetNextAvailableSlotArrayEntry();
  136. //Get the slab allocator for this snapshot context
  137. SlabAllocator& GetSnapshotSlabAllocator();
  138. //Make sure that all well known objects can be re-used -- if not we will need to recreate all script contexts from scratch
  139. bool AllWellKnownObjectsReusable(InflateMap* inflator) const;
  140. //Inflate the snapshot
  141. void Inflate(InflateMap* inflator, ThreadContextTTD* tCtx) const;
  142. //serialize the snapshot data
  143. void EmitSnapshot(int64 snapId, ThreadContext* threadContext) const;
  144. //de-serialize the snapshot data
  145. static SnapShot* Parse(int64 snapId, ThreadContext* threadContext);
  146. #if ENABLE_SNAPSHOT_COMPARE
  147. static void InitializeForSnapshotCompare(const SnapShot* snap1, const SnapShot* snap2, TTDCompareMap& compareMap);
  148. static void DoSnapshotCompare(const SnapShot* snap1, const SnapShot* snap2, TTDCompareMap& compareMap);
  149. #endif
  150. };
  151. }
  152. #endif