blob: 77a8edbf46dfa14fb044c50115baf6f2f524ba92 [file]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "RuntimeDebugPch.h"
#if ENABLE_TTD
namespace TTD
{
namespace NSLogEvents
{
void PassVarToHostInReplay(ThreadContextTTD* executeContext, TTDVar origVar, Js::Var replayVar)
{
static_assert(sizeof(TTDVar) == sizeof(Js::Var), "We assume the bit patterns on these types are the same!!!");
#if ENABLE_TTD_INTERNAL_DIAGNOSTICS
if(replayVar == nullptr || TTD::JsSupport::IsVarTaggedInline(replayVar))
{
TTDAssert(TTD::JsSupport::AreInlineVarsEquiv(origVar, replayVar), "Should be same bit pattern.");
}
#endif
if(replayVar != nullptr && TTD::JsSupport::IsVarPtrValued(replayVar))
{
Js::RecyclableObject* obj = Js::RecyclableObject::FromVar(replayVar);
executeContext->AddLocalRoot(TTD_CONVERT_OBJ_TO_LOG_PTR_ID(origVar), obj);
}
}
Js::Var InflateVarInReplay(ThreadContextTTD* executeContext, TTDVar origVar)
{
static_assert(sizeof(TTDVar) == sizeof(Js::Var), "We assume the bit patterns on these types are the same!!!");
if(origVar == nullptr || TTD::JsSupport::IsVarTaggedInline(origVar))
{
return TTD_CONVERT_TTDVAR_TO_JSVAR(origVar);
}
else
{
return executeContext->LookupObjectForLogID(TTD_CONVERT_OBJ_TO_LOG_PTR_ID(origVar));
}
}
void EventLogEntry_Emit(const EventLogEntry* evt, EventLogEntryVTableEntry* evtFPVTable, FileWriter* writer, ThreadContext* threadContext, NSTokens::Separator separator)
{
writer->WriteRecordStart(separator);
writer->WriteTag<EventKind>(NSTokens::Key::eventKind, evt->EventKind);
writer->WriteInt32(NSTokens::Key::eventResultStatus, evt->ResultStatus, NSTokens::Separator::CommaSeparator);
#if ENABLE_TTD_INTERNAL_DIAGNOSTICS
writer->WriteInt64(NSTokens::Key::eventTime, evt->EventTimeStamp, NSTokens::Separator::CommaSeparator);
#endif
auto emitFP = evtFPVTable[(uint32)evt->EventKind].EmitFP;
if(emitFP != nullptr)
{
emitFP(evt, writer, threadContext);
}
writer->WriteRecordEnd();
}
EventKind EventLogEntry_ParseHeader(bool readSeperator, FileReader* reader)
{
reader->ReadRecordStart(readSeperator);
return reader->ReadTag<EventKind>(NSTokens::Key::eventKind);
}
void EventLogEntry_ParseRest(EventLogEntry* evt, EventLogEntryVTableEntry* evtFPVTable, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
evt->ResultStatus = reader->ReadInt32(NSTokens::Key::eventResultStatus, true);
#if ENABLE_TTD_INTERNAL_DIAGNOSTICS
evt->EventTimeStamp = reader->ReadInt64(NSTokens::Key::eventTime, true);
#endif
auto parseFP = evtFPVTable[(uint32)evt->EventKind].ParseFP;
if(parseFP != nullptr)
{
parseFP(evt, threadContext, reader, alloc);
}
reader->ReadRecordEnd();
}
bool EventFailsWithRuntimeError(const EventLogEntry* evt)
{
return !(EventDoesNotReturn(evt) || EventCompletesNormally(evt) || EventCompletesWithException(evt));
}
bool EventDoesNotReturn(const EventLogEntry* evt)
{
return evt->ResultStatus == -1;
}
bool EventCompletesNormally(const EventLogEntry* evt)
{
return (evt->ResultStatus == 0) || (evt->ResultStatus == TTD_REPLAY_JsErrorInvalidArgument) || (evt->ResultStatus == TTD_REPLAY_JsErrorArgumentNotObject);
}
bool EventCompletesWithException(const EventLogEntry* evt)
{
return (evt->ResultStatus == TTD_REPLAY_JsErrorCategoryScript) || (evt->ResultStatus == TTD_REPLAY_JsErrorScriptTerminated);
}
//////////////////
void SnapshotEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
{
SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
if(snapEvt->LiveContextCount != 0)
{
alloc.UnlinkAllocation(snapEvt->LiveContextIdArray);
}
if(snapEvt->LongLivedRefRootsCount != 0)
{
alloc.UnlinkAllocation(snapEvt->LongLivedRefRootsIdArray);
}
SnapshotEventLogEntry_UnloadSnapshot(evt);
}
void SnapshotEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
writer->WriteInt64(NSTokens::Key::restoreTime, snapEvt->RestoreTimestamp, NSTokens::Separator::CommaSeparator);
writer->WriteLengthValue(snapEvt->LiveContextCount, NSTokens::Separator::CommaSeparator);
writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
for(uint32 i = 0; i < snapEvt->LiveContextCount; ++i)
{
writer->WriteNakedLogTag(snapEvt->LiveContextIdArray[i], i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
}
writer->WriteSequenceEnd();
writer->WriteLengthValue(snapEvt->LongLivedRefRootsCount, NSTokens::Separator::CommaSeparator);
writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
for(uint32 i = 0; i < snapEvt->LongLivedRefRootsCount; ++i)
{
writer->WriteNakedLogTag(snapEvt->LongLivedRefRootsIdArray[i], i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
}
writer->WriteSequenceEnd();
if(snapEvt->Snap != nullptr)
{
snapEvt->Snap->EmitSnapshot(snapEvt->RestoreTimestamp, threadContext);
}
}
void SnapshotEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
snapEvt->RestoreTimestamp = reader->ReadInt64(NSTokens::Key::restoreTime, true);
snapEvt->LiveContextCount = reader->ReadLengthValue(true);
snapEvt->LiveContextIdArray = (snapEvt->LiveContextCount != 0) ? alloc.SlabAllocateArray<TTD_LOG_PTR_ID>(snapEvt->LiveContextCount) : nullptr;
reader->ReadSequenceStart_WDefaultKey(true);
for(uint32 i = 0; i < snapEvt->LiveContextCount; ++i)
{
snapEvt->LiveContextIdArray[i] = reader->ReadNakedLogTag(i != 0);
}
reader->ReadSequenceEnd();
snapEvt->LongLivedRefRootsCount = reader->ReadLengthValue(true);
snapEvt->LongLivedRefRootsIdArray = (snapEvt->LongLivedRefRootsCount != 0) ? alloc.SlabAllocateArray<TTD_LOG_PTR_ID>(snapEvt->LongLivedRefRootsCount) : nullptr;
reader->ReadSequenceStart_WDefaultKey(true);
for(uint32 i = 0; i < snapEvt->LongLivedRefRootsCount; ++i)
{
snapEvt->LongLivedRefRootsIdArray[i] = reader->ReadNakedLogTag(i != 0);
}
reader->ReadSequenceEnd();
snapEvt->Snap = nullptr;
}
void SnapshotEventLogEntry_EnsureSnapshotDeserialized(EventLogEntry* evt, ThreadContext* threadContext)
{
SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
if(snapEvt->Snap == nullptr)
{
snapEvt->Snap = SnapShot::Parse(snapEvt->RestoreTimestamp, threadContext);
}
}
void SnapshotEventLogEntry_UnloadSnapshot(EventLogEntry* evt)
{
SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
if(snapEvt->Snap != nullptr)
{
TT_HEAP_DELETE(SnapShot, snapEvt->Snap);
snapEvt->Snap = nullptr;
}
}
void EventLoopYieldPointEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const EventLoopYieldPointEntry* ypEvt = GetInlineEventDataAs<EventLoopYieldPointEntry, EventKind::EventLoopYieldPointTag>(evt);
writer->WriteUInt64(NSTokens::Key::eventTime, ypEvt->EventTimeStamp, NSTokens::Separator::CommaSeparator);
writer->WriteDouble(NSTokens::Key::loopTime, ypEvt->EventWallTime, NSTokens::Separator::CommaSeparator);
}
void EventLoopYieldPointEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
EventLoopYieldPointEntry* ypEvt = GetInlineEventDataAs<EventLoopYieldPointEntry, EventKind::EventLoopYieldPointTag>(evt);
ypEvt->EventTimeStamp = reader->ReadUInt64(NSTokens::Key::eventTime, true);
ypEvt->EventWallTime = reader->ReadDouble(NSTokens::Key::loopTime, true);
}
//////////////////
void CodeLoadEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const CodeLoadEventLogEntry* codeEvt = GetInlineEventDataAs<CodeLoadEventLogEntry, EventKind::TopLevelCodeTag>(evt);
writer->WriteUInt32(NSTokens::Key::u32Val, codeEvt->BodyCounterId, NSTokens::Separator::CommaSeparator);
}
void CodeLoadEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
CodeLoadEventLogEntry* codeEvt = GetInlineEventDataAs<CodeLoadEventLogEntry, EventKind::TopLevelCodeTag>(evt);
codeEvt->BodyCounterId = reader->ReadUInt32(NSTokens::Key::u32Val, true);
}
void TelemetryEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
{
TelemetryEventLogEntry* telemetryEvt = GetInlineEventDataAs<TelemetryEventLogEntry, EventKind::TelemetryLogTag>(evt);
alloc.UnlinkString(telemetryEvt->InfoString);
}
void TelemetryEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const TelemetryEventLogEntry* telemetryEvt = GetInlineEventDataAs<TelemetryEventLogEntry, EventKind::TelemetryLogTag>(evt);
writer->WriteString(NSTokens::Key::stringVal, telemetryEvt->InfoString, NSTokens::Separator::CommaSeparator);
writer->WriteBool(NSTokens::Key::boolVal, telemetryEvt->DoPrint, NSTokens::Separator::CommaSeparator);
}
void TelemetryEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
TelemetryEventLogEntry* telemetryEvt = GetInlineEventDataAs<TelemetryEventLogEntry, EventKind::TelemetryLogTag>(evt);
reader->ReadString(NSTokens::Key::stringVal, alloc, telemetryEvt->InfoString, true);
telemetryEvt->DoPrint = reader->ReadBool(NSTokens::Key::boolVal, true);
}
//////////////////
void RandomSeedEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const RandomSeedEventLogEntry* rndEvt = GetInlineEventDataAs<RandomSeedEventLogEntry, EventKind::RandomSeedTag>(evt);
writer->WriteUInt64(NSTokens::Key::u64Val, rndEvt->Seed0, NSTokens::Separator::CommaSeparator);
writer->WriteUInt64(NSTokens::Key::u64Val, rndEvt->Seed1, NSTokens::Separator::CommaSeparator);
}
void RandomSeedEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
RandomSeedEventLogEntry* rndEvt = GetInlineEventDataAs<RandomSeedEventLogEntry, EventKind::RandomSeedTag>(evt);
rndEvt->Seed0 = reader->ReadUInt64(NSTokens::Key::u64Val, true);
rndEvt->Seed1 = reader->ReadUInt64(NSTokens::Key::u64Val, true);
}
void DoubleEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const DoubleEventLogEntry* dblEvt = GetInlineEventDataAs<DoubleEventLogEntry, EventKind::DoubleTag>(evt);
writer->WriteDouble(NSTokens::Key::doubleVal, dblEvt->DoubleValue, NSTokens::Separator::CommaSeparator);
}
void DoubleEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
DoubleEventLogEntry* dblEvt = GetInlineEventDataAs<DoubleEventLogEntry, EventKind::DoubleTag>(evt);
dblEvt->DoubleValue = reader->ReadDouble(NSTokens::Key::doubleVal, true);
}
void StringValueEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
{
StringValueEventLogEntry* strEvt = GetInlineEventDataAs<StringValueEventLogEntry, EventKind::StringTag>(evt);
alloc.UnlinkString(strEvt->StringValue);
}
void StringValueEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const StringValueEventLogEntry* strEvt = GetInlineEventDataAs<StringValueEventLogEntry, EventKind::StringTag>(evt);
writer->WriteString(NSTokens::Key::stringVal, strEvt->StringValue, NSTokens::Separator::CommaSeparator);
}
void StringValueEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
StringValueEventLogEntry* strEvt = GetInlineEventDataAs<StringValueEventLogEntry, EventKind::StringTag>(evt);
reader->ReadString(NSTokens::Key::stringVal, alloc, strEvt->StringValue, true);
}
//////////////////
void PropertyEnumStepEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
{
PropertyEnumStepEventLogEntry* propertyEvt = GetInlineEventDataAs<PropertyEnumStepEventLogEntry, EventKind::PropertyEnumTag>(evt);
if(!IsNullPtrTTString(propertyEvt->PropertyString))
{
alloc.UnlinkString(propertyEvt->PropertyString);
}
}
void PropertyEnumStepEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const PropertyEnumStepEventLogEntry* propertyEvt = GetInlineEventDataAs<PropertyEnumStepEventLogEntry, EventKind::PropertyEnumTag>(evt);
writer->WriteBool(NSTokens::Key::boolVal, !!propertyEvt->ReturnCode, NSTokens::Separator::CommaSeparator);
writer->WriteUInt32(NSTokens::Key::propertyId, propertyEvt->Pid, NSTokens::Separator::CommaSeparator);
writer->WriteUInt32(NSTokens::Key::attributeFlags, propertyEvt->Attributes, NSTokens::Separator::CommaSeparator);
if(propertyEvt->ReturnCode)
{
#if ENABLE_TTD_INTERNAL_DIAGNOSTICS
writer->WriteString(NSTokens::Key::stringVal, propertyEvt->PropertyString, NSTokens::Separator::CommaSeparator);
#else
if(propertyEvt->Pid == Js::Constants::NoProperty)
{
writer->WriteString(NSTokens::Key::stringVal, propertyEvt->PropertyString, NSTokens::Separator::CommaSeparator);
}
#endif
}
}
void PropertyEnumStepEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
PropertyEnumStepEventLogEntry* propertyEvt = GetInlineEventDataAs<PropertyEnumStepEventLogEntry, EventKind::PropertyEnumTag>(evt);
propertyEvt->ReturnCode = reader->ReadBool(NSTokens::Key::boolVal, true);
propertyEvt->Pid = (Js::PropertyId)reader->ReadUInt32(NSTokens::Key::propertyId, true);
propertyEvt->Attributes = (Js::PropertyAttributes)reader->ReadUInt32(NSTokens::Key::attributeFlags, true);
InitializeAsNullPtrTTString(propertyEvt->PropertyString);
if(propertyEvt->ReturnCode)
{
#if ENABLE_TTD_INTERNAL_DIAGNOSTICS
reader->ReadString(NSTokens::Key::stringVal, alloc, propertyEvt->PropertyString, true);
#else
if(propertyEvt->Pid == Js::Constants::NoProperty)
{
reader->ReadString(NSTokens::Key::stringVal, alloc, propertyEvt->PropertyString, true);
}
#endif
}
}
//////////////////
void SymbolCreationEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const SymbolCreationEventLogEntry* symEvt = GetInlineEventDataAs<SymbolCreationEventLogEntry, EventKind::SymbolCreationTag>(evt);
writer->WriteUInt32(NSTokens::Key::propertyId, symEvt->Pid, NSTokens::Separator::CommaSeparator);
}
void SymbolCreationEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
SymbolCreationEventLogEntry* symEvt = GetInlineEventDataAs<SymbolCreationEventLogEntry, EventKind::SymbolCreationTag>(evt);
symEvt->Pid = (Js::PropertyId)reader->ReadUInt32(NSTokens::Key::propertyId, true);
}
//////////////////
void WeakCollectionContainsEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const WeakCollectionContainsEventLogEntry* wcEvt = GetInlineEventDataAs<WeakCollectionContainsEventLogEntry, EventKind::WeakCollectionContainsTag>(evt);
writer->WriteBool(NSTokens::Key::boolVal, wcEvt->ContainsValue, NSTokens::Separator::CommaSeparator);
}
void WeakCollectionContainsEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
WeakCollectionContainsEventLogEntry* wcEvt = GetInlineEventDataAs<WeakCollectionContainsEventLogEntry, EventKind::WeakCollectionContainsTag>(evt);
wcEvt->ContainsValue = reader->ReadBool(NSTokens::Key::boolVal, true);
}
//////////////////
int64 ExternalCbRegisterCallEventLogEntry_GetLastNestedEventTime(const EventLogEntry* evt)
{
const ExternalCbRegisterCallEventLogEntry* cbrEvt = GetInlineEventDataAs<ExternalCbRegisterCallEventLogEntry, EventKind::ExternalCbRegisterCall>(evt);
return cbrEvt->LastNestedEventTime;
}
void ExternalCbRegisterCallEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const ExternalCbRegisterCallEventLogEntry* cbrEvt = GetInlineEventDataAs<ExternalCbRegisterCallEventLogEntry, EventKind::ExternalCbRegisterCall>(evt);
NSSnapValues::EmitTTDVar(cbrEvt->CallbackFunction, writer, NSTokens::Separator::CommaSeparator);
writer->WriteInt64(NSTokens::Key::i64Val, cbrEvt->LastNestedEventTime, NSTokens::Separator::CommaSeparator);
}
void ExternalCbRegisterCallEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
ExternalCbRegisterCallEventLogEntry* cbrEvt = GetInlineEventDataAs<ExternalCbRegisterCallEventLogEntry, EventKind::ExternalCbRegisterCall>(evt);
cbrEvt->CallbackFunction = NSSnapValues::ParseTTDVar(true, reader);
cbrEvt->LastNestedEventTime = reader->ReadInt64(NSTokens::Key::i64Val, true);
}
//////////////////
#if ENABLE_TTD_INTERNAL_DIAGNOSTICS
void ExternalCallEventLogEntry_ProcessDiagInfoPre(EventLogEntry* evt, Js::JavascriptFunction* function, UnlinkableSlabAllocator& alloc)
{
ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
Js::JavascriptString* displayName = function->GetDisplayName();
alloc.CopyStringIntoWLength(displayName->GetSz(), displayName->GetLength(), callEvt->FunctionName);
}
#endif
int64 ExternalCallEventLogEntry_GetLastNestedEventTime(const EventLogEntry* evt)
{
const ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
return callEvt->LastNestedEventTime;
}
void ExternalCallEventLogEntry_ProcessArgs(EventLogEntry* evt, int32 rootDepth, Js::JavascriptFunction* function, uint32 argc, Js::Var* argv, bool checkExceptions, UnlinkableSlabAllocator& alloc)
{
ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
callEvt->RootNestingDepth = rootDepth;
callEvt->ArgCount = argc + 1;
static_assert(sizeof(TTDVar) == sizeof(Js::Var), "These need to be the same size (and have same bit layout) for this to work!");
callEvt->ArgArray = alloc.SlabAllocateArray<TTDVar>(callEvt->ArgCount);
callEvt->ArgArray[0] = static_cast<TTDVar>(function);
js_memcpy_s(callEvt->ArgArray + 1, (callEvt->ArgCount - 1) * sizeof(TTDVar), argv, argc * sizeof(Js::Var));
callEvt->ReturnValue = nullptr;
callEvt->LastNestedEventTime = TTD_EVENT_MAXTIME;
callEvt->CheckExceptionStatus = checkExceptions;
}
void ExternalCallEventLogEntry_ProcessReturn(EventLogEntry* evt, Js::Var res, int64 lastNestedEvent)
{
ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
callEvt->ReturnValue = TTD_CONVERT_JSVAR_TO_TTDVAR(res);
callEvt->LastNestedEventTime = lastNestedEvent;
}
void ExternalCallEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
{
ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
alloc.UnlinkAllocation(callEvt->ArgArray);
#if ENABLE_TTD_INTERNAL_DIAGNOSTICS
alloc.UnlinkString(callEvt->FunctionName);
#endif
}
void ExternalCallEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
const ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
#if ENABLE_TTD_INTERNAL_DIAGNOSTICS
writer->WriteString(NSTokens::Key::name, callEvt->FunctionName, NSTokens::Separator::CommaSeparator);
#endif
writer->WriteInt32(NSTokens::Key::rootNestingDepth, callEvt->RootNestingDepth, NSTokens::Separator::CommaSeparator);
writer->WriteLengthValue(callEvt->ArgCount, NSTokens::Separator::CommaSeparator);
writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
for(uint32 i = 0; i < callEvt->ArgCount; ++i)
{
NSTokens::Separator sep = (i != 0) ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator;
NSSnapValues::EmitTTDVar(callEvt->ArgArray[i], writer, sep);
}
writer->WriteSequenceEnd();
writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
NSSnapValues::EmitTTDVar(callEvt->ReturnValue, writer, NSTokens::Separator::NoSeparator);
writer->WriteBool(NSTokens::Key::boolVal, callEvt->CheckExceptionStatus, NSTokens::Separator::CommaSeparator);
writer->WriteInt64(NSTokens::Key::i64Val, callEvt->LastNestedEventTime, NSTokens::Separator::CommaSeparator);
}
void ExternalCallEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
#if ENABLE_TTD_INTERNAL_DIAGNOSTICS
reader->ReadString(NSTokens::Key::name, alloc, callEvt->FunctionName, true);
#endif
callEvt->RootNestingDepth = reader->ReadInt32(NSTokens::Key::rootNestingDepth, true);
callEvt->ArgCount = reader->ReadLengthValue(true);
callEvt->ArgArray = alloc.SlabAllocateArray<TTDVar>(callEvt->ArgCount);
reader->ReadSequenceStart_WDefaultKey(true);
for(uint32 i = 0; i < callEvt->ArgCount; ++i)
{
callEvt->ArgArray[i] = NSSnapValues::ParseTTDVar(i != 0, reader);
}
reader->ReadSequenceEnd();
reader->ReadKey(NSTokens::Key::argRetVal, true);
callEvt->ReturnValue = NSSnapValues::ParseTTDVar(false, reader);
callEvt->CheckExceptionStatus = reader->ReadBool(NSTokens::Key::boolVal, true);
callEvt->LastNestedEventTime = reader->ReadInt64(NSTokens::Key::i64Val, true);
}
//////////////////
void ExplicitLogWriteEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
{
; //We don't track any extra data with this
}
void ExplicitLogWriteEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
{
; //We don't track any extra data with this
}
}
}
#endif