| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #pragma once
- #if ENABLE_TTD
- namespace TTD
- {
- //A class that represents a heap snapshot the page context
- class SnapShot
- {
- private:
- ////
- //The slab allocator we use for storing the data extracted
- SlabAllocator m_slabAllocator;
- ////
- //List containing the "context" information for the objects in this snapshot
- UnorderedArrayList<NSSnapValues::SnapContext, TTD_ARRAY_LIST_SIZE_XSMALL> m_ctxList;
- //List containing all the propertyids for the symbols that are in the thread context symbolRegistrationMap
- UnorderedArrayList<Js::PropertyId, TTD_ARRAY_LIST_SIZE_XSMALL> m_tcSymbolRegistrationMapContents;
- //The active script context
- TTD_LOG_PTR_ID m_activeScriptContext;
- //A list of all the global root objects and local root objects
- UnorderedArrayList<NSSnapValues::SnapRootInfoEntry, TTD_ARRAY_LIST_SIZE_MID> m_rootList;
- ////
- //Lists containing the "type" information for the objects in this snapshot
- //The list of all the dynamichandler definitions that the snapshot uses
- UnorderedArrayList<NSSnapType::SnapHandler, TTD_ARRAY_LIST_SIZE_DEFAULT> m_handlerList;
- //The list of all the type definitions that the snapshot uses
- UnorderedArrayList<NSSnapType::SnapType, TTD_ARRAY_LIST_SIZE_DEFAULT> m_typeList;
- ////
- //Lists containing the objects in this snapshot
- //The list of all the type definitions that the snapshot uses
- UnorderedArrayList<NSSnapValues::FunctionBodyResolveInfo, TTD_ARRAY_LIST_SIZE_DEFAULT> m_functionBodyList;
- //The list of all the primitive objects (empty until we convert all the primitive pinned objects during extractor unlink)
- UnorderedArrayList<NSSnapValues::SnapPrimitiveValue, TTD_ARRAY_LIST_SIZE_LARGE> m_primitiveObjectList;
- //The list of all the non-primitive javascript objects in the snapshot
- UnorderedArrayList<NSSnapObjects::SnapObject, TTD_ARRAY_LIST_SIZE_LARGE> m_compoundObjectList;
- //pseudo vtable for working with snap objects
- NSSnapObjects::SnapObjectVTable* m_snapObjectVTableArray;
- ////
- //Function scope info
- //All the scopes in the snapshot
- UnorderedArrayList<NSSnapValues::ScriptFunctionScopeInfo, TTD_ARRAY_LIST_SIZE_DEFAULT> m_scopeEntries;
- //All the slot arrays in the snapshot
- UnorderedArrayList<NSSnapValues::SlotArrayInfo, TTD_ARRAY_LIST_SIZE_DEFAULT> m_slotArrayEntries;
- //Emit the json file for the snapshot into the given directory
- void EmitSnapshotToFile(FileWriter* writer, ThreadContext* threadContext) const;
- static SnapShot* ParseSnapshotFromFile(FileReader* reader);
- template<typename Fn, typename T, size_t allocSize>
- static void EmitListHelper(Fn emitFunc, const UnorderedArrayList<T, allocSize>& list, FileWriter* snapwriter)
- {
- snapwriter->WriteLengthValue(list.Count(), NSTokens::Separator::CommaAndBigSpaceSeparator);
- snapwriter->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaAndBigSpaceSeparator);
- snapwriter->AdjustIndent(1);
- bool firstElement = true;
- for(auto iter = list.GetIterator(); iter.IsValid(); iter.MoveNext())
- {
- (*emitFunc)(iter.Current(), snapwriter, firstElement ? NSTokens::Separator::BigSpaceSeparator : NSTokens::Separator::CommaAndBigSpaceSeparator);
- firstElement = false;
- }
- snapwriter->AdjustIndent(-1);
- snapwriter->WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
- }
- template<typename Fn, typename T, size_t allocSize>
- static void ParseListHelper(Fn parseFunc, UnorderedArrayList<T, allocSize>& list, FileReader* snapreader, SlabAllocator& alloc)
- {
- uint32 count = snapreader->ReadLengthValue(true);
- snapreader->ReadSequenceStart_WDefaultKey(true);
- for(uint32 i = 0; i < count; ++i)
- {
- T* into = list.NextOpenEntry();
- (*parseFunc)(into, i != 0, snapreader, alloc);
- }
- snapreader->ReadSequenceEnd();
- }
- template<typename Fn, typename T, typename U, size_t allocSize>
- static void ParseListHelper_WMap(Fn parseFunc, UnorderedArrayList<T, allocSize>& list, FileReader* snapreader, SlabAllocator& alloc, const TTDIdentifierDictionary<TTD_PTR_ID, U>& infoMap)
- {
- uint32 count = snapreader->ReadLengthValue(true);
- snapreader->ReadSequenceStart_WDefaultKey(true);
- for(uint32 i = 0; i < count; ++i)
- {
- T* into = list.NextOpenEntry();
- (*parseFunc)(into, i != 0, snapreader, alloc, infoMap);
- }
- snapreader->ReadSequenceEnd();
- }
- //Inflate a single JS object
- void InflateSingleObject(const NSSnapObjects::SnapObject* snpObject, InflateMap* inflator, const TTDIdentifierDictionary<TTD_PTR_ID, NSSnapObjects::SnapObject*>& idToSnpObjectMap) const;
- void ReLinkThreadContextInfo(InflateMap* inflator, ThreadContextTTD* intoCtx) const;
- static void SnapRootPinEntryEmit(const NSSnapValues::SnapRootInfoEntry* spe, FileWriter* snapwriter, NSTokens::Separator separator);
- static void SnapRootPinEntryParse(NSSnapValues::SnapRootInfoEntry* spe, bool readSeperator, FileReader* reader, SlabAllocator& alloc);
- public:
- //Performance counter values
- double GCTime;
- double MarkTime;
- double ExtractTime;
- //Compute the memory used by this snapshot
- void ComputeSnapshotMemory(uint64* usedSpace, uint64* reservedSpace) const;
- SnapShot(double gcTime);
- ~SnapShot();
- //Get the counts for the various list sizes (not constant time -- so use carefully!!!!)
- uint32 ContextCount() const;
- uint32 HandlerCount() const;
- uint32 TypeCount() const;
- uint32 BodyCount() const;
- uint32 PrimitiveCount() const;
- uint32 ObjectCount() const;
- uint32 EnvCount() const;
- uint32 SlotArrayCount() const;
- uint32 GetDbgScopeCountNonTopLevel() const;
- //Get the context list for this snapshot
- UnorderedArrayList<NSSnapValues::SnapContext, TTD_ARRAY_LIST_SIZE_XSMALL>& GetContextList();
- const UnorderedArrayList<NSSnapValues::SnapContext, TTD_ARRAY_LIST_SIZE_XSMALL>& GetContextList() const;
- //Get the thread context symbol map info list for this snapshot
- UnorderedArrayList<Js::PropertyId, TTD_ARRAY_LIST_SIZE_XSMALL>& GetTCSymbolMapInfoList();
- TTD_LOG_PTR_ID GetActiveScriptContext() const;
- void SetActiveScriptContext(TTD_LOG_PTR_ID activeCtx);
- //Get the root lists
- UnorderedArrayList<NSSnapValues::SnapRootInfoEntry, TTD_ARRAY_LIST_SIZE_MID>& GetRootList();
- //Get a pointer to the next open handler slot that we can fill
- NSSnapType::SnapHandler* GetNextAvailableHandlerEntry();
- //Get a pointer to the next open handler slot that we can fill
- NSSnapType::SnapType* GetNextAvailableTypeEntry();
- //Get a pointer to the next open FunctionBodyResolveInfo slot that we can fill
- NSSnapValues::FunctionBodyResolveInfo* GetNextAvailableFunctionBodyResolveInfoEntry();
- //Get a pointer to the next open primitive object slot that we can fill
- NSSnapValues::SnapPrimitiveValue* GetNextAvailablePrimitiveObjectEntry();
- //Get a pointer to the next open compound object slot that we can fill
- NSSnapObjects::SnapObject* GetNextAvailableCompoundObjectEntry();
- //Get a pointer to the next open scope entry slot that we can fill
- NSSnapValues::ScriptFunctionScopeInfo* GetNextAvailableFunctionScopeEntry();
- //Get a pointer to the next open slot array entry that we can fill
- NSSnapValues::SlotArrayInfo* GetNextAvailableSlotArrayEntry();
- //Get the slab allocator for this snapshot context
- SlabAllocator& GetSnapshotSlabAllocator();
- //Make sure that all well known objects can be re-used -- if not we will need to recreate all script contexts from scratch
- bool AllWellKnownObjectsReusable(InflateMap* inflator) const;
- //Inflate the snapshot
- void Inflate(InflateMap* inflator, ThreadContextTTD* tCtx) const;
- //serialize the snapshot data
- void EmitSnapshot(int64 snapId, ThreadContext* threadContext) const;
- //de-serialize the snapshot data
- static SnapShot* Parse(int64 snapId, ThreadContext* threadContext);
- #if ENABLE_SNAPSHOT_COMPARE
- static void InitializeForSnapshotCompare(const SnapShot* snap1, const SnapShot* snap2, TTDCompareMap& compareMap);
- static void DoSnapshotCompare(const SnapShot* snap1, const SnapShot* snap2, TTDCompareMap& compareMap);
- #endif
- };
- }
- #endif
|