| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653 |
- //-------------------------------------------------------------------------------------------------------
- // 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
- #define TTD_EVENTLOG_LIST_BLOCK_SIZE 65536
- namespace TTD
- {
- //A class to ensure that even when exceptions are thrown we increment/decrement the root nesting depth
- class TTDNestingDepthAutoAdjuster
- {
- private:
- ThreadContext* m_threadContext;
- public:
- TTDNestingDepthAutoAdjuster(ThreadContext* threadContext)
- : m_threadContext(threadContext)
- {
- this->m_threadContext->TTDRootNestingCount++;
- }
- ~TTDNestingDepthAutoAdjuster()
- {
- this->m_threadContext->TTDRootNestingCount--;
- }
- };
- //A class to manage the recording of JsRT action call state
- class TTDJsRTActionResultAutoRecorder
- {
- private:
- NSLogEvents::EventLogEntry* m_actionEvent;
- TTDVar* m_resultPtr;
- public:
- TTDJsRTActionResultAutoRecorder()
- : m_actionEvent(nullptr), m_resultPtr(nullptr)
- {
- ;
- }
- void InitializeWithEventAndEnter(NSLogEvents::EventLogEntry* actionEvent)
- {
- TTDAssert(this->m_actionEvent == nullptr, "Don't double initialize");
- this->m_actionEvent = actionEvent;
- }
- void InitializeWithEventAndEnterWResult(NSLogEvents::EventLogEntry* actionEvent, TTDVar* resultPtr)
- {
- TTDAssert(this->m_actionEvent == nullptr, "Don't double initialize");
- this->m_actionEvent = actionEvent;
- this->m_resultPtr = resultPtr;
- *(this->m_resultPtr) = (TTDVar)nullptr; //set the result field to a default value in case we fail during execution
- }
- void SetResult(Js::Var* result)
- {
- TTDAssert(this->m_resultPtr != nullptr, "Why are we calling this then???");
- if(result != nullptr)
- {
- *(this->m_resultPtr) = TTD_CONVERT_JSVAR_TO_TTDVAR(*(result));
- }
- }
- void CompleteWithStatusCode(int32 exitStatus)
- {
- if(this->m_actionEvent != nullptr)
- {
- TTDAssert(this->m_actionEvent->ResultStatus == -1, "Hmm this got changed somewhere???");
- this->m_actionEvent->ResultStatus = exitStatus;
- }
- }
- };
- //A class to ensure that even when exceptions are thrown we record the time difference info
- class TTDJsRTFunctionCallActionPopperRecorder
- {
- private:
- Js::ScriptContext* m_ctx;
- double m_beginTime;
- NSLogEvents::EventLogEntry* m_callAction;
- public:
- TTDJsRTFunctionCallActionPopperRecorder();
- ~TTDJsRTFunctionCallActionPopperRecorder();
- void InitializeForRecording(Js::ScriptContext* ctx, double beginWallTime, NSLogEvents::EventLogEntry* callAction);
- };
- //A list class for the events that we accumulate in the event log
- class TTEventList
- {
- public:
- struct TTEventListLink
- {
- //The current end of the allocated data in the block
- size_t CurrPos;
- //The First index that holds data
- size_t StartPos;
- //The actual block for the data
- byte* BlockData;
- //The next block in the list
- TTEventListLink* Next;
- TTEventListLink* Previous;
- };
- private:
- //The the data in this
- TTEventListLink* m_headBlock;
- //the allocators we use for this work
- UnlinkableSlabAllocator* m_alloc;
- //The vtable with callbacks for the event log entries in the list
- const NSLogEvents::EventLogEntryVTableEntry* m_vtable;
- //Map from event entries to previous event entries -- only valid in replay mode otherwise empty
- JsUtil::BaseDictionary<const NSLogEvents::EventLogEntry*, size_t, HeapAllocator> m_previousEventMap;
- void AddArrayLink();
- void RemoveArrayLink(TTEventListLink* block);
- public:
- TTEventList(UnlinkableSlabAllocator* alloc);
- void SetVTable(const NSLogEvents::EventLogEntryVTableEntry* vtable);
- void InitializePreviousEventMap();
- void UnloadEventList();
- //Add the entry to the list
- template <typename T>
- NSLogEvents::EventLogEntry* GetNextAvailableEntry()
- {
- const size_t esize = TTD_EVENT_PLUS_DATA_SIZE(T);
- if((this->m_headBlock == nullptr) || (this->m_headBlock->CurrPos + esize >= TTD_EVENTLOG_LIST_BLOCK_SIZE))
- {
- this->AddArrayLink();
- }
- NSLogEvents::EventLogEntry* entry = reinterpret_cast<NSLogEvents::EventLogEntry*>(this->m_headBlock->BlockData + this->m_headBlock->CurrPos);
- this->m_headBlock->CurrPos += esize;
- return entry;
- }
- //Add the entry to the list
- NSLogEvents::EventLogEntry* GetNextAvailableEntry(size_t requiredSize);
- //Delete the entry from the list (must always be the first link/entry in the list)
- //This also calls unload on the entry
- void DeleteFirstEntry(TTEventListLink* block, NSLogEvents::EventLogEntry* data);
- //Return true if this is empty
- bool IsEmpty() const;
- //NOT constant time
- uint32 Count() const;
- class Iterator
- {
- private:
- TTEventListLink* m_currLink;
- size_t m_currIdx;
- const NSLogEvents::EventLogEntryVTableEntry* m_vtable;
- const JsUtil::BaseDictionary<const NSLogEvents::EventLogEntry*, size_t, HeapAllocator>* m_previousEventMap;
- public:
- Iterator();
- Iterator(TTEventListLink* head, size_t pos, const NSLogEvents::EventLogEntryVTableEntry* vtable, const JsUtil::BaseDictionary<const NSLogEvents::EventLogEntry*, size_t, HeapAllocator>* previousEventMap);
- const NSLogEvents::EventLogEntry* Current() const;
- NSLogEvents::EventLogEntry* Current();
- //Get the underlying block for deletion support
- TTEventListLink* GetBlock();
- bool IsValid() const;
- void MoveNext();
- void MovePrevious_ReplayOnly();
- };
- Iterator GetIteratorAtFirst() const;
- Iterator GetIteratorAtLast_ReplayOnly() const;
- };
- //A class that represents the event log for the program execution
- class EventLog
- {
- private:
- ThreadContext* m_threadContext;
- //Allocator we use for all the events we see
- UnlinkableSlabAllocator m_eventSlabAllocator;
- //Allocator we use for all the property records
- SlabAllocator m_miscSlabAllocator;
- //The global event time variable and a high res timer we can use to extract some diagnostic timing info as we go
- int64 m_eventTimeCtr;
- //A high res timer we can use to extract some diagnostic timing info as we go
- TTDTimer m_timer;
- //Top-Level callback event time (or -1 if we are not in a callback)
- int64 m_topLevelCallbackEventTime;
- //The list of all the events and the iterator we use during replay
- NSLogEvents::EventLogEntryVTableEntry* m_eventListVTable;
- TTEventList m_eventList;
- TTEventList::Iterator m_currentReplayEventIterator;
- //The current mode the system is running in (and a stack of mode push/pops that we use to generate it)
- TTModeStack m_modeStack;
- TTDMode m_currentMode;
- bool m_autoTracesEnabled;
- //The snapshot extractor that this log uses
- SnapshotExtractor m_snapExtractor;
- //The execution time that has elapsed since the last snapshot
- double m_elapsedExecutionTimeSinceSnapshot;
- //If we are inflating a snapshot multiple times we want to re-use the inflated objects when possible so keep this recent info
- int64 m_lastInflateSnapshotTime;
- InflateMap* m_lastInflateMap;
- //Pin set of all property records created during this logging session
- RecyclerRootPtr<PropertyRecordPinSet> m_propertyRecordPinSet;
- UnorderedArrayList<NSSnapType::SnapPropertyRecord, TTD_ARRAY_LIST_SIZE_DEFAULT> m_propertyRecordList;
- //The value of the threadContext sourceInfoCounter in record -- in replay initialize to this value to avoid collisions
- uint32 m_sourceInfoCount;
- //A list of all *root* scripts that have been loaded during this session
- UnorderedArrayList<NSSnapValues::TopLevelScriptLoadFunctionBodyResolveInfo, TTD_ARRAY_LIST_SIZE_MID> m_loadedTopLevelScripts;
- UnorderedArrayList<NSSnapValues::TopLevelNewFunctionBodyResolveInfo, TTD_ARRAY_LIST_SIZE_SMALL> m_newFunctionTopLevelScripts;
- UnorderedArrayList<NSSnapValues::TopLevelEvalFunctionBodyResolveInfo, TTD_ARRAY_LIST_SIZE_SMALL> m_evalTopLevelScripts;
- ////
- //Helper methods
- //Get the current XTTDEventTime and advance the event time counter
- int64 GetCurrentEventTimeAndAdvance()
- {
- return this->m_eventTimeCtr++;
- }
- //Advance the time and event position for replay
- void AdvanceTimeAndPositionForReplay();
- //Look at the stack to get the new computed mode
- void UpdateComputedMode();
- //A helper for extracting snapshots
- SnapShot* DoSnapshotExtract_Helper(double gcTime, JsUtil::BaseHashSet<Js::FunctionBody*, HeapAllocator>& liveTopLevelBodies);
- //Replay a snapshot event -- either just advance the event position or, if running diagnostics, take new snapshot and compare
- void ReplaySnapshotEvent();
- //Replay an event loop yield point event
- void ReplayEventLoopYieldPointEvent();
- template <typename T, NSLogEvents::EventKind tag>
- NSLogEvents::EventLogEntry* RecordGetInitializedEvent(T** extraData)
- {
- AssertMsg(TTD_EVENT_PLUS_DATA_SIZE_DIRECT(sizeof(T)) == this->m_eventListVTable[(uint32)tag].DataSize, "Computed and extracted data sizes don't match!!!");
- NSLogEvents::EventLogEntry* res = this->m_eventList.GetNextAvailableEntry<T>();
- NSLogEvents::EventLogEntry_Initialize<tag>(res, this->GetCurrentEventTimeAndAdvance());
- *extraData = NSLogEvents::GetInlineEventDataAs<T, tag>(res);
- return res;
- }
- template <typename T, NSLogEvents::EventKind tag>
- T* RecordGetInitializedEvent_DataOnly()
- {
- AssertMsg(TTD_EVENT_PLUS_DATA_SIZE_DIRECT(sizeof(T)) == this->m_eventListVTable[(uint32)tag].DataSize, "Computed and extracted data sizes don't match!!!");
- NSLogEvents::EventLogEntry* res = this->m_eventList.GetNextAvailableEntry<T>();
- NSLogEvents::EventLogEntry_Initialize<tag>(res, this->GetCurrentEventTimeAndAdvance());
- //For these operations are not allowed to fail so success is always 0
- res->ResultStatus = 0;
- return NSLogEvents::GetInlineEventDataAs<T, tag>(res);
- }
- //Sometimes we need to abort replay and immediately return to the top-level host (debugger) so it can decide what to do next
- // (1) If we are trying to replay something and we are at the end of the log then we need to terminate
- // (2) If we are at a breakpoint and we want to step back (in some form) then we need to terminate
- void AbortReplayReturnToHost();
- //A helper for getting and doing some iterator manipulation during replay
- template <typename T, NSLogEvents::EventKind tag>
- const T* ReplayGetReplayEvent_Helper()
- {
- if(!this->m_currentReplayEventIterator.IsValid())
- {
- this->AbortReplayReturnToHost();
- }
- #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
- TTDAssert(this->m_currentReplayEventIterator.Current()->EventTimeStamp == this->m_eventTimeCtr, "Out of Sync!!!");
- #endif
- const NSLogEvents::EventLogEntry* evt = this->m_currentReplayEventIterator.Current();
- this->AdvanceTimeAndPositionForReplay();
- return NSLogEvents::GetInlineEventDataAs<T, tag>(evt);
- }
- //Initialize the vtable for the event list data
- void InitializeEventListVTable();
- public:
- EventLog(ThreadContext* threadContext);
- ~EventLog();
- //When we stop recording we want to unload all of the data in the log (otherwise we get strange transitions if we start again later)
- void UnloadAllLogData();
- //Initialize the log so that it is ready to perform TTD (record or replay) and set into the correct global mode
- void InitForTTDRecord(bool debug);
- void InitForTTDReplay(TTDataIOInfo& iofp, const char* parseUri, size_t parseUriLength, bool debug);
- //If the last statement of this log is an inner loop emit event put the data in lsi otherwise leave it as the default value
- void LoadLastSourceLineInfo(TTInnerLoopLastStatementInfo& lsi, TTD::TTDebuggerSourceLocation& dsl) const;
- //reset the bottom (global) mode with the specific value
- void SetGlobalMode(TTDMode m);
- //Mark that a snapshot is in (or or is now complete)
- void SetSnapshotOrInflateInProgress(bool flag);
- //push a new debugger mode
- void PushMode(TTDMode m);
- //pop the top debugger mode
- void PopMode(TTDMode m);
- //Get the current mode for TTD execution
- TTDMode GetCurrentTTDMode() const;
- //Set the mode flags on the script context based on the TTDMode in the Log
- void SetModeFlagsOnContext(Js::ScriptContext* ctx);
- //Get the global mode flags for creating a script context
- void GetModesForExplicitContextCreate(bool& inRecord, bool& activelyRecording, bool& inReplay);
- //Just check if the debug mode flag has been set (don't check any active or suppressed properties)
- bool IsDebugModeFlagSet() const;
- //Add a property record to our pin set
- void AddPropertyRecord(const Js::PropertyRecord* record);
- //Add top level function load info to our sets
- const NSSnapValues::TopLevelScriptLoadFunctionBodyResolveInfo* AddScriptLoad(Js::FunctionBody* fb, Js::ModuleID moduleId, uint64 sourceContextId, const byte* source, uint32 sourceLen, LoadScriptFlag loadFlag);
- const NSSnapValues::TopLevelNewFunctionBodyResolveInfo* AddNewFunction(Js::FunctionBody* fb, Js::ModuleID moduleId, const char16* source, uint32 sourceLen);
- const NSSnapValues::TopLevelEvalFunctionBodyResolveInfo* AddEvalFunction(Js::FunctionBody* fb, Js::ModuleID moduleId, const char16* source, uint32 sourceLen, uint32 grfscr, bool registerDocument, BOOL isIndirect, BOOL strictMode);
- uint32 GetSourceInfoCount() const;
- void RecordTopLevelCodeAction(uint32 bodyCtrId);
- uint32 ReplayTopLevelCodeAction();
- ////////////////////////////////
- //Logging support
- //Log an event generated by user telemetry
- void RecordTelemetryLogEvent(Js::JavascriptString* infoStringJs, bool doPrint);
- //Replay a user telemetry event
- void ReplayTelemetryLogEvent(Js::JavascriptString* infoStringJs);
- //Log an event generated to write the log to a given uri
- void RecordEmitLogEvent(Js::JavascriptString* uriString);
- //Replay a event that writes the log to a given uri
- void ReplayEmitLogEvent();
- //Record that we are accessing the TTDFetchAutoTraceStatus and what the value is
- void RecordTTDFetchAutoTraceStatusEvent(bool status);
- //Replay that we are accessing the TTDFetchAutoTraceStatus
- bool ReplayTTDFetchAutoTraceStatusLogEvent();
- //Log a time that is fetched during date operations
- void RecordDateTimeEvent(double time);
- //Log a time (as a string) that is fetched during date operations
- void RecordDateStringEvent(Js::JavascriptString* stringValue);
- //replay date event (which should be the current event)
- void ReplayDateTimeEvent(double* result);
- //replay date event with a string result (which should be the current event)
- void ReplayDateStringEvent(Js::ScriptContext* ctx, Js::JavascriptString** result);
- //Log a random seed value that is being generated using external entropy
- void RecordExternalEntropyRandomEvent(uint64 seed0, uint64 seed1);
- //Replay a random seed value that is being generated using external entropy
- void ReplayExternalEntropyRandomEvent(uint64* seed0, uint64* seed1);
- //Log property enumeration step
- void RecordPropertyEnumEvent(BOOL returnCode, Js::PropertyId pid, Js::PropertyAttributes attributes, Js::JavascriptString* propertyName);
- //Replay a property enumeration step
- void ReplayPropertyEnumEvent(Js::ScriptContext* requestContext, BOOL* returnCode, Js::BigPropertyIndex* newIndex, const Js::DynamicObject* obj, Js::PropertyId* pid, Js::PropertyAttributes* attributes, Js::JavascriptString** propertyName);
- //Log symbol creation
- void RecordSymbolCreationEvent(Js::PropertyId pid);
- //Replay symbol creation
- void ReplaySymbolCreationEvent(Js::PropertyId* pid);
- //Log if a weak collection contained a value when an operation occours
- void RecordWeakCollectionContainsEvent(bool contains);
- //Replay a weak collection contained a value when an operation occours (return the truth value)
- bool ReplayWeakCollectionContainsEvent();
- //Log a value event for return from an external call
- NSLogEvents::EventLogEntry* RecordExternalCallEvent(Js::JavascriptFunction* func, int32 rootDepth, const Js::Arguments& args, bool checkExceptions);
- void RecordExternalCallEvent_Complete(Js::JavascriptFunction* efunction, NSLogEvents::EventLogEntry* evt, Js::Var result);
- //replay an external return event (which should be the current event)
- void ReplayExternalCallEvent(Js::JavascriptFunction* function, const Js::Arguments& args, Js::Var* result);
- NSLogEvents::EventLogEntry* RecordEnqueueTaskEvent(Js::Var taskVar);
- void RecordEnqueueTaskEvent_Complete(NSLogEvents::EventLogEntry* evt);
- void ReplayEnqueueTaskEvent(Js::ScriptContext* ctx, Js::Var taskVar);
- //Get the current top-level event time
- int64 GetCurrentTopLevelEventTime() const;
- //Get the event time corresponding to the first/last/k-th top-level event in the log
- int64 GetFirstEventTimeInLog() const;
- int64 GetLastEventTimeInLog() const;
- int64 GetKthEventTimeInLog(uint32 k) const;
- //Ensure the call stack is clear and counters are zeroed appropriately
- void ResetCallStackForTopLevelCall(int64 topLevelCallbackEventTime);
- //Check if we want to take a snapshot
- bool IsTimeForSnapshot() const;
- //After a snapshot we may want to discard old events so do that in here as needed
- void PruneLogLength();
- //Get/Increment the elapsed time since the last snapshot
- void IncrementElapsedSnapshotTime(double addtlTime);
- ////////////////////////////////
- //Snapshot and replay support
- //Do the snapshot extraction
- void DoSnapshotExtract();
- //Take a ready-to-run snapshot for the event if needed
- void DoRtrSnapIfNeeded();
- //Find the event time that has the snapshot we want to inflate from in order to replay to the requested target time
- //Return -1 if no such snapshot is available
- int64 FindSnapTimeForEventTime(int64 targetTime, int64* optEndSnapTime);
- //Find the enclosing snapshot interval for the specified event time
- void GetSnapShotBoundInterval(int64 targetTime, int64* snapIntervalStart, int64* snapIntervalEnd) const;
- //Find the snapshot start time for the previous interval return -1 if no such time exists
- int64 GetPreviousSnapshotInterval(int64 currentSnapTime) const;
- //Do the inflation of the snapshot that is at the given event time
- void DoSnapshotInflate(int64 etime);
- //Run execute top level event calls until the given time is reached
- void ReplayRootEventsToTime(int64 eventTime);
- //For a single root level event -- snapshot, yield point, or ActionEvent
- void ReplaySingleRootEntry();
- //When we have an externalFunction (or promise register) we exit script context and need to play until the event time counts up to (and including) the given eventTime
- void ReplayActionEventSequenceThroughTime(int64 eventTime);
- //Replay the enter/exit and any iteration need to discharge all the effects of a single ActionEvent
- void ReplaySingleActionEventEntry();
- ////////////////////////////////
- //Host API record & replay support
- //Return true if this is a propertyRecord reference
- bool IsPropertyRecordRef(void* ref) const;
- //Get the current time from the hi res timer
- double GetCurrentWallTime();
- //Get the most recently assigned event time value
- int64 GetLastEventTime() const;
- NSLogEvents::EventLogEntry* RecordJsRTCreateScriptContext(TTDJsRTActionResultAutoRecorder& actionPopper);
- void RecordJsRTCreateScriptContextResult(NSLogEvents::EventLogEntry* evt, Js::ScriptContext* newCtx);
- void RecordJsRTSetCurrentContext(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var globalObject);
- #if !INT32VAR
- void RecordJsRTCreateInteger(TTDJsRTActionResultAutoRecorder& actionPopper, int value);
- #endif
- //Record creation operations
- void RecordJsRTCreateNumber(TTDJsRTActionResultAutoRecorder& actionPopper, double value);
- void RecordJsRTCreateBoolean(TTDJsRTActionResultAutoRecorder& actionPopper, bool value);
- void RecordJsRTCreateString(TTDJsRTActionResultAutoRecorder& actionPopper, const char16* stringValue, size_t stringLength);
- void RecordJsRTCreateSymbol(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- //Record error creation
- void RecordJsRTCreateError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg);
- void RecordJsRTCreateRangeError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var vmsg);
- void RecordJsRTCreateReferenceError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg);
- void RecordJsRTCreateSyntaxError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg);
- void RecordJsRTCreateTypeError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg);
- void RecordJsRTCreateURIError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg);
- //Record conversions
- void RecordJsRTVarToNumberConversion(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- void RecordJsRTVarToBooleanConversion(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- void RecordJsRTVarToStringConversion(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- void RecordJsRTVarToObjectConversion(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- //Record lifetime management events
- void RecordJsRTAddRootRef(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- void RecordJsRTAddWeakRootRef(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- void RecordJsRTEventLoopYieldPoint();
- //Record object allocate operations
- void RecordJsRTAllocateBasicObject(TTDJsRTActionResultAutoRecorder& actionPopper);
- void RecordJsRTAllocateExternalObject(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var prototype);
- void RecordJsRTAllocateBasicArray(TTDJsRTActionResultAutoRecorder& actionPopper, uint32 length);
- void RecordJsRTAllocateArrayBuffer(TTDJsRTActionResultAutoRecorder& actionPopper, uint32 size);
- void RecordJsRTAllocateExternalArrayBuffer(TTDJsRTActionResultAutoRecorder& actionPopper, byte* buff, uint32 size);
- void RecordJsRTAllocateFunction(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var optMetadata);
- //Record GetAndClearException
- void RecordJsRTHostExitProcess(TTDJsRTActionResultAutoRecorder& actionPopper, int32 exitCode);
- void RecordJsRTGetAndClearExceptionWithMetadata(TTDJsRTActionResultAutoRecorder& actionPopper);
- void RecordJsRTGetAndClearException(TTDJsRTActionResultAutoRecorder& actionPopper);
- void RecordJsRTSetException(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, bool propagateToDebugger);
- //Record query operations
- void RecordJsRTHasProperty(TTDJsRTActionResultAutoRecorder& actionPopper, const Js::PropertyRecord* pRecord, Js::Var var);
- void RecordJsRTHasOwnProperty(TTDJsRTActionResultAutoRecorder& actionPopper, const Js::PropertyRecord* pRecord, Js::Var var);
- void RecordJsRTInstanceOf(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var object, Js::Var constructor);
- void RecordJsRTEquals(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var1, Js::Var var2, bool doStrict);
- void RecordJsRTLessThan(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var1, Js::Var var2, bool allowsEqual);
- //Record getters with native results
- void RecordJsRTGetPropertyIdFromSymbol(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var sym);
- //Record Object Getters
- void RecordJsRTGetPrototype(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- void RecordJsRTGetProperty(TTDJsRTActionResultAutoRecorder& actionPopper, const Js::PropertyRecord* pRecord, Js::Var var);
- void RecordJsRTGetIndex(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var index, Js::Var var);
- void RecordJsRTGetOwnPropertyInfo(TTDJsRTActionResultAutoRecorder& actionPopper, const Js::PropertyRecord* pRecord, Js::Var var);
- void RecordJsRTGetOwnPropertyNamesInfo(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- void RecordJsRTGetOwnPropertySymbolsInfo(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var);
- //Record Object Setters
- void RecordJsRTDefineProperty(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, const Js::PropertyRecord* pRecord, Js::Var propertyDescriptor);
- void RecordJsRTDeleteProperty(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, const Js::PropertyRecord* pRecord, bool useStrictRules);
- void RecordJsRTSetPrototype(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, Js::Var proto);
- void RecordJsRTSetProperty(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, const Js::PropertyRecord* pRecord, Js::Var val, bool useStrictRules);
- void RecordJsRTSetIndex(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, Js::Var index, Js::Var val);
- //Record a get info from a typed array
- void RecordJsRTGetTypedArrayInfo(Js::Var var, Js::Var result);
- void RecordJsRTGetDataViewInfo(Js::Var var, Js::Var result);
- //Record various raw byte* from ArrayBuffer manipulations
- void RecordJsRTRawBufferCopySync(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var dst, uint32 dstIndex, Js::Var src, uint32 srcIndex, uint32 length);
- void RecordJsRTRawBufferModifySync(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var dst, uint32 index, uint32 count);
- void RecordJsRTRawBufferAsyncModificationRegister(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var dst, uint32 index);
- void RecordJsRTRawBufferAsyncModifyComplete(TTDJsRTActionResultAutoRecorder& actionPopper, TTDPendingAsyncBufferModification& pendingAsyncInfo, byte* finalModPos);
- //Record a constructor call from JsRT
- void RecordJsRTConstructCall(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var funcVar, uint32 argCount, Js::Var* args);
- //Record code parse
- NSLogEvents::EventLogEntry* RecordJsRTCodeParse(TTDJsRTActionResultAutoRecorder& actionPopper, LoadScriptFlag loadFlag, bool isUft8, const byte* script, uint32 scriptByteLength, uint64 sourceContextId, const char16* sourceUri);
- //Record callback of an existing function
- NSLogEvents::EventLogEntry* RecordJsRTCallFunction(TTDJsRTActionResultAutoRecorder& actionPopper, int32 rootDepth, Js::Var funcVar, uint32 argCount, Js::Var* args);
- ////////////////////////////////
- //Emit code and support
- void InnerLoopEmitLog(const TTDebuggerSourceLocation& writeLocation, const char* emitUri, size_t emitUriLength);
- bool CanWriteInnerLoopTrace() const;
- void SetAutoTraceEnabled(bool enabled);
- bool GetAutoTraceEnabled() const;
- void EmitLog(const char* emitUri, size_t emitUriLength, NSLogEvents::EventLogEntry* optInnerLoopEvent = nullptr);
- void ParseLogInto(TTDataIOInfo& iofp, const char* parseUri, size_t parseUriLength);
- };
- //In cases where we may have many exits where we need to pop something we pushed earlier (i.e. exceptions)
- class TTModeStackAutoPopper
- {
- private:
- EventLog* m_log;
- TTDMode m_popMode; //the mode to pop or invalid if we don't need to pop anything
- public:
- TTModeStackAutoPopper(EventLog* log)
- : m_log(log), m_popMode(TTDMode::Invalid)
- {
- ;
- }
- void PushModeAndSetToAutoPop(TTDMode mode)
- {
- this->m_log->PushMode(mode);
- this->m_popMode = mode;
- }
- ~TTModeStackAutoPopper()
- {
- if(this->m_popMode != TTDMode::Invalid)
- {
- this->m_log->PopMode(this->m_popMode);
- }
- }
- };
- }
- #endif
|