TTEvents.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  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. #include "RuntimeDebugPch.h"
  6. #if ENABLE_TTD
  7. namespace TTD
  8. {
  9. namespace NSLogEvents
  10. {
  11. void PassVarToHostInReplay(ThreadContextTTD* executeContext, TTDVar origVar, Js::Var replayVar)
  12. {
  13. static_assert(sizeof(TTDVar) == sizeof(Js::Var), "We assume the bit patterns on these types are the same!!!");
  14. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  15. if(replayVar == nullptr || TTD::JsSupport::IsVarTaggedInline(replayVar))
  16. {
  17. TTDAssert(TTD::JsSupport::AreInlineVarsEquiv(origVar, replayVar), "Should be same bit pattern.");
  18. }
  19. #endif
  20. if(replayVar != nullptr && TTD::JsSupport::IsVarPtrValued(replayVar))
  21. {
  22. Js::RecyclableObject* obj = Js::RecyclableObject::FromVar(replayVar);
  23. executeContext->AddLocalRoot(TTD_CONVERT_OBJ_TO_LOG_PTR_ID(origVar), obj);
  24. }
  25. }
  26. Js::Var InflateVarInReplay(ThreadContextTTD* executeContext, TTDVar origVar)
  27. {
  28. static_assert(sizeof(TTDVar) == sizeof(Js::Var), "We assume the bit patterns on these types are the same!!!");
  29. if(origVar == nullptr || TTD::JsSupport::IsVarTaggedInline(origVar))
  30. {
  31. return TTD_CONVERT_TTDVAR_TO_JSVAR(origVar);
  32. }
  33. else
  34. {
  35. return executeContext->LookupObjectForLogID(TTD_CONVERT_OBJ_TO_LOG_PTR_ID(origVar));
  36. }
  37. }
  38. void EventLogEntry_Emit(const EventLogEntry* evt, EventLogEntryVTableEntry* evtFPVTable, FileWriter* writer, ThreadContext* threadContext, NSTokens::Separator separator)
  39. {
  40. writer->WriteRecordStart(separator);
  41. writer->WriteTag<EventKind>(NSTokens::Key::eventKind, evt->EventKind);
  42. writer->WriteInt32(NSTokens::Key::eventResultStatus, evt->ResultStatus, NSTokens::Separator::CommaSeparator);
  43. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  44. writer->WriteInt64(NSTokens::Key::eventTime, evt->EventTimeStamp, NSTokens::Separator::CommaSeparator);
  45. #endif
  46. auto emitFP = evtFPVTable[(uint32)evt->EventKind].EmitFP;
  47. if(emitFP != nullptr)
  48. {
  49. emitFP(evt, writer, threadContext);
  50. }
  51. writer->WriteRecordEnd();
  52. }
  53. EventKind EventLogEntry_ParseHeader(bool readSeparator, FileReader* reader)
  54. {
  55. reader->ReadRecordStart(readSeparator);
  56. return reader->ReadTag<EventKind>(NSTokens::Key::eventKind);
  57. }
  58. void EventLogEntry_ParseRest(EventLogEntry* evt, EventLogEntryVTableEntry* evtFPVTable, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  59. {
  60. evt->ResultStatus = reader->ReadInt32(NSTokens::Key::eventResultStatus, true);
  61. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  62. evt->EventTimeStamp = reader->ReadInt64(NSTokens::Key::eventTime, true);
  63. #endif
  64. auto parseFP = evtFPVTable[(uint32)evt->EventKind].ParseFP;
  65. if(parseFP != nullptr)
  66. {
  67. parseFP(evt, threadContext, reader, alloc);
  68. }
  69. reader->ReadRecordEnd();
  70. }
  71. bool EventFailsWithRuntimeError(const EventLogEntry* evt)
  72. {
  73. return !(EventDoesNotReturn(evt) || EventCompletesNormally(evt) || EventCompletesWithException(evt));
  74. }
  75. bool EventDoesNotReturn(const EventLogEntry* evt)
  76. {
  77. return evt->ResultStatus == -1;
  78. }
  79. bool EventCompletesNormally(const EventLogEntry* evt)
  80. {
  81. return (evt->ResultStatus == 0) || (evt->ResultStatus == TTD_REPLAY_JsErrorInvalidArgument) || (evt->ResultStatus == TTD_REPLAY_JsErrorArgumentNotObject);
  82. }
  83. bool EventCompletesWithException(const EventLogEntry* evt)
  84. {
  85. return (evt->ResultStatus == TTD_REPLAY_JsErrorCategoryScript) || (evt->ResultStatus == TTD_REPLAY_JsErrorScriptTerminated);
  86. }
  87. //////////////////
  88. void SnapshotEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
  89. {
  90. SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
  91. if(snapEvt->LiveContextCount != 0)
  92. {
  93. alloc.UnlinkAllocation(snapEvt->LiveContextIdArray);
  94. }
  95. if(snapEvt->LongLivedRefRootsCount != 0)
  96. {
  97. alloc.UnlinkAllocation(snapEvt->LongLivedRefRootsIdArray);
  98. }
  99. SnapshotEventLogEntry_UnloadSnapshot(evt);
  100. }
  101. void SnapshotEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  102. {
  103. const SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
  104. writer->WriteInt64(NSTokens::Key::restoreTime, snapEvt->RestoreTimestamp, NSTokens::Separator::CommaSeparator);
  105. writer->WriteLengthValue(snapEvt->LiveContextCount, NSTokens::Separator::CommaSeparator);
  106. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  107. for(uint32 i = 0; i < snapEvt->LiveContextCount; ++i)
  108. {
  109. writer->WriteNakedLogTag(snapEvt->LiveContextIdArray[i], i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  110. }
  111. writer->WriteSequenceEnd();
  112. writer->WriteLengthValue(snapEvt->LongLivedRefRootsCount, NSTokens::Separator::CommaSeparator);
  113. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  114. for(uint32 i = 0; i < snapEvt->LongLivedRefRootsCount; ++i)
  115. {
  116. writer->WriteNakedLogTag(snapEvt->LongLivedRefRootsIdArray[i], i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  117. }
  118. writer->WriteSequenceEnd();
  119. if(snapEvt->Snap != nullptr)
  120. {
  121. snapEvt->Snap->EmitSnapshot(snapEvt->RestoreTimestamp, threadContext);
  122. }
  123. }
  124. void SnapshotEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  125. {
  126. SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
  127. snapEvt->RestoreTimestamp = reader->ReadInt64(NSTokens::Key::restoreTime, true);
  128. snapEvt->LiveContextCount = reader->ReadLengthValue(true);
  129. snapEvt->LiveContextIdArray = (snapEvt->LiveContextCount != 0) ? alloc.SlabAllocateArray<TTD_LOG_PTR_ID>(snapEvt->LiveContextCount) : nullptr;
  130. reader->ReadSequenceStart_WDefaultKey(true);
  131. for(uint32 i = 0; i < snapEvt->LiveContextCount; ++i)
  132. {
  133. snapEvt->LiveContextIdArray[i] = reader->ReadNakedLogTag(i != 0);
  134. }
  135. reader->ReadSequenceEnd();
  136. snapEvt->LongLivedRefRootsCount = reader->ReadLengthValue(true);
  137. snapEvt->LongLivedRefRootsIdArray = (snapEvt->LongLivedRefRootsCount != 0) ? alloc.SlabAllocateArray<TTD_LOG_PTR_ID>(snapEvt->LongLivedRefRootsCount) : nullptr;
  138. reader->ReadSequenceStart_WDefaultKey(true);
  139. for(uint32 i = 0; i < snapEvt->LongLivedRefRootsCount; ++i)
  140. {
  141. snapEvt->LongLivedRefRootsIdArray[i] = reader->ReadNakedLogTag(i != 0);
  142. }
  143. reader->ReadSequenceEnd();
  144. snapEvt->Snap = nullptr;
  145. }
  146. void SnapshotEventLogEntry_EnsureSnapshotDeserialized(EventLogEntry* evt, ThreadContext* threadContext)
  147. {
  148. SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
  149. if(snapEvt->Snap == nullptr)
  150. {
  151. snapEvt->Snap = SnapShot::Parse(snapEvt->RestoreTimestamp, threadContext);
  152. }
  153. }
  154. void SnapshotEventLogEntry_UnloadSnapshot(EventLogEntry* evt)
  155. {
  156. SnapshotEventLogEntry* snapEvt = GetInlineEventDataAs<SnapshotEventLogEntry, EventKind::SnapshotTag>(evt);
  157. if(snapEvt->Snap != nullptr)
  158. {
  159. TT_HEAP_DELETE(SnapShot, snapEvt->Snap);
  160. snapEvt->Snap = nullptr;
  161. }
  162. }
  163. void EventLoopYieldPointEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  164. {
  165. const EventLoopYieldPointEntry* ypEvt = GetInlineEventDataAs<EventLoopYieldPointEntry, EventKind::EventLoopYieldPointTag>(evt);
  166. writer->WriteUInt64(NSTokens::Key::eventTime, ypEvt->EventTimeStamp, NSTokens::Separator::CommaSeparator);
  167. writer->WriteDouble(NSTokens::Key::loopTime, ypEvt->EventWallTime, NSTokens::Separator::CommaSeparator);
  168. }
  169. void EventLoopYieldPointEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  170. {
  171. EventLoopYieldPointEntry* ypEvt = GetInlineEventDataAs<EventLoopYieldPointEntry, EventKind::EventLoopYieldPointTag>(evt);
  172. ypEvt->EventTimeStamp = reader->ReadUInt64(NSTokens::Key::eventTime, true);
  173. ypEvt->EventWallTime = reader->ReadDouble(NSTokens::Key::loopTime, true);
  174. }
  175. //////////////////
  176. void CodeLoadEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  177. {
  178. const CodeLoadEventLogEntry* codeEvt = GetInlineEventDataAs<CodeLoadEventLogEntry, EventKind::TopLevelCodeTag>(evt);
  179. writer->WriteUInt32(NSTokens::Key::u32Val, codeEvt->BodyCounterId, NSTokens::Separator::CommaSeparator);
  180. }
  181. void CodeLoadEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  182. {
  183. CodeLoadEventLogEntry* codeEvt = GetInlineEventDataAs<CodeLoadEventLogEntry, EventKind::TopLevelCodeTag>(evt);
  184. codeEvt->BodyCounterId = reader->ReadUInt32(NSTokens::Key::u32Val, true);
  185. }
  186. void TelemetryEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
  187. {
  188. TelemetryEventLogEntry* telemetryEvt = GetInlineEventDataAs<TelemetryEventLogEntry, EventKind::TelemetryLogTag>(evt);
  189. alloc.UnlinkString(telemetryEvt->InfoString);
  190. }
  191. void TelemetryEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  192. {
  193. const TelemetryEventLogEntry* telemetryEvt = GetInlineEventDataAs<TelemetryEventLogEntry, EventKind::TelemetryLogTag>(evt);
  194. writer->WriteString(NSTokens::Key::stringVal, telemetryEvt->InfoString, NSTokens::Separator::CommaSeparator);
  195. writer->WriteBool(NSTokens::Key::boolVal, telemetryEvt->DoPrint, NSTokens::Separator::CommaSeparator);
  196. }
  197. void TelemetryEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  198. {
  199. TelemetryEventLogEntry* telemetryEvt = GetInlineEventDataAs<TelemetryEventLogEntry, EventKind::TelemetryLogTag>(evt);
  200. reader->ReadString(NSTokens::Key::stringVal, alloc, telemetryEvt->InfoString, true);
  201. telemetryEvt->DoPrint = reader->ReadBool(NSTokens::Key::boolVal, true);
  202. }
  203. //////////////////
  204. void RandomSeedEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  205. {
  206. const RandomSeedEventLogEntry* rndEvt = GetInlineEventDataAs<RandomSeedEventLogEntry, EventKind::RandomSeedTag>(evt);
  207. writer->WriteUInt64(NSTokens::Key::u64Val, rndEvt->Seed0, NSTokens::Separator::CommaSeparator);
  208. writer->WriteUInt64(NSTokens::Key::u64Val, rndEvt->Seed1, NSTokens::Separator::CommaSeparator);
  209. }
  210. void RandomSeedEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  211. {
  212. RandomSeedEventLogEntry* rndEvt = GetInlineEventDataAs<RandomSeedEventLogEntry, EventKind::RandomSeedTag>(evt);
  213. rndEvt->Seed0 = reader->ReadUInt64(NSTokens::Key::u64Val, true);
  214. rndEvt->Seed1 = reader->ReadUInt64(NSTokens::Key::u64Val, true);
  215. }
  216. void DoubleEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  217. {
  218. const DoubleEventLogEntry* dblEvt = GetInlineEventDataAs<DoubleEventLogEntry, EventKind::DoubleTag>(evt);
  219. writer->WriteDouble(NSTokens::Key::doubleVal, dblEvt->DoubleValue, NSTokens::Separator::CommaSeparator);
  220. }
  221. void DoubleEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  222. {
  223. DoubleEventLogEntry* dblEvt = GetInlineEventDataAs<DoubleEventLogEntry, EventKind::DoubleTag>(evt);
  224. dblEvt->DoubleValue = reader->ReadDouble(NSTokens::Key::doubleVal, true);
  225. }
  226. void StringValueEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
  227. {
  228. StringValueEventLogEntry* strEvt = GetInlineEventDataAs<StringValueEventLogEntry, EventKind::StringTag>(evt);
  229. alloc.UnlinkString(strEvt->StringValue);
  230. }
  231. void StringValueEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  232. {
  233. const StringValueEventLogEntry* strEvt = GetInlineEventDataAs<StringValueEventLogEntry, EventKind::StringTag>(evt);
  234. writer->WriteString(NSTokens::Key::stringVal, strEvt->StringValue, NSTokens::Separator::CommaSeparator);
  235. }
  236. void StringValueEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  237. {
  238. StringValueEventLogEntry* strEvt = GetInlineEventDataAs<StringValueEventLogEntry, EventKind::StringTag>(evt);
  239. reader->ReadString(NSTokens::Key::stringVal, alloc, strEvt->StringValue, true);
  240. }
  241. //////////////////
  242. void PropertyEnumStepEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
  243. {
  244. PropertyEnumStepEventLogEntry* propertyEvt = GetInlineEventDataAs<PropertyEnumStepEventLogEntry, EventKind::PropertyEnumTag>(evt);
  245. if(!IsNullPtrTTString(propertyEvt->PropertyString))
  246. {
  247. alloc.UnlinkString(propertyEvt->PropertyString);
  248. }
  249. }
  250. void PropertyEnumStepEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  251. {
  252. const PropertyEnumStepEventLogEntry* propertyEvt = GetInlineEventDataAs<PropertyEnumStepEventLogEntry, EventKind::PropertyEnumTag>(evt);
  253. writer->WriteBool(NSTokens::Key::boolVal, !!propertyEvt->ReturnCode, NSTokens::Separator::CommaSeparator);
  254. writer->WriteUInt32(NSTokens::Key::propertyId, propertyEvt->Pid, NSTokens::Separator::CommaSeparator);
  255. writer->WriteUInt32(NSTokens::Key::attributeFlags, propertyEvt->Attributes, NSTokens::Separator::CommaSeparator);
  256. if(propertyEvt->ReturnCode)
  257. {
  258. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  259. writer->WriteString(NSTokens::Key::stringVal, propertyEvt->PropertyString, NSTokens::Separator::CommaSeparator);
  260. #else
  261. if(propertyEvt->Pid == Js::Constants::NoProperty)
  262. {
  263. writer->WriteString(NSTokens::Key::stringVal, propertyEvt->PropertyString, NSTokens::Separator::CommaSeparator);
  264. }
  265. #endif
  266. }
  267. }
  268. void PropertyEnumStepEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  269. {
  270. PropertyEnumStepEventLogEntry* propertyEvt = GetInlineEventDataAs<PropertyEnumStepEventLogEntry, EventKind::PropertyEnumTag>(evt);
  271. propertyEvt->ReturnCode = reader->ReadBool(NSTokens::Key::boolVal, true);
  272. propertyEvt->Pid = (Js::PropertyId)reader->ReadUInt32(NSTokens::Key::propertyId, true);
  273. propertyEvt->Attributes = (Js::PropertyAttributes)reader->ReadUInt32(NSTokens::Key::attributeFlags, true);
  274. InitializeAsNullPtrTTString(propertyEvt->PropertyString);
  275. if(propertyEvt->ReturnCode)
  276. {
  277. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  278. reader->ReadString(NSTokens::Key::stringVal, alloc, propertyEvt->PropertyString, true);
  279. #else
  280. if(propertyEvt->Pid == Js::Constants::NoProperty)
  281. {
  282. reader->ReadString(NSTokens::Key::stringVal, alloc, propertyEvt->PropertyString, true);
  283. }
  284. #endif
  285. }
  286. }
  287. //////////////////
  288. void SymbolCreationEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  289. {
  290. const SymbolCreationEventLogEntry* symEvt = GetInlineEventDataAs<SymbolCreationEventLogEntry, EventKind::SymbolCreationTag>(evt);
  291. writer->WriteUInt32(NSTokens::Key::propertyId, symEvt->Pid, NSTokens::Separator::CommaSeparator);
  292. }
  293. void SymbolCreationEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  294. {
  295. SymbolCreationEventLogEntry* symEvt = GetInlineEventDataAs<SymbolCreationEventLogEntry, EventKind::SymbolCreationTag>(evt);
  296. symEvt->Pid = (Js::PropertyId)reader->ReadUInt32(NSTokens::Key::propertyId, true);
  297. }
  298. //////////////////
  299. void WeakCollectionContainsEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  300. {
  301. const WeakCollectionContainsEventLogEntry* wcEvt = GetInlineEventDataAs<WeakCollectionContainsEventLogEntry, EventKind::WeakCollectionContainsTag>(evt);
  302. writer->WriteBool(NSTokens::Key::boolVal, wcEvt->ContainsValue, NSTokens::Separator::CommaSeparator);
  303. }
  304. void WeakCollectionContainsEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  305. {
  306. WeakCollectionContainsEventLogEntry* wcEvt = GetInlineEventDataAs<WeakCollectionContainsEventLogEntry, EventKind::WeakCollectionContainsTag>(evt);
  307. wcEvt->ContainsValue = reader->ReadBool(NSTokens::Key::boolVal, true);
  308. }
  309. //////////////////
  310. int64 ExternalCbRegisterCallEventLogEntry_GetLastNestedEventTime(const EventLogEntry* evt)
  311. {
  312. const ExternalCbRegisterCallEventLogEntry* cbrEvt = GetInlineEventDataAs<ExternalCbRegisterCallEventLogEntry, EventKind::ExternalCbRegisterCall>(evt);
  313. return cbrEvt->LastNestedEventTime;
  314. }
  315. void ExternalCbRegisterCallEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  316. {
  317. const ExternalCbRegisterCallEventLogEntry* cbrEvt = GetInlineEventDataAs<ExternalCbRegisterCallEventLogEntry, EventKind::ExternalCbRegisterCall>(evt);
  318. NSSnapValues::EmitTTDVar(cbrEvt->CallbackFunction, writer, NSTokens::Separator::CommaSeparator);
  319. writer->WriteInt64(NSTokens::Key::i64Val, cbrEvt->LastNestedEventTime, NSTokens::Separator::CommaSeparator);
  320. }
  321. void ExternalCbRegisterCallEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  322. {
  323. ExternalCbRegisterCallEventLogEntry* cbrEvt = GetInlineEventDataAs<ExternalCbRegisterCallEventLogEntry, EventKind::ExternalCbRegisterCall>(evt);
  324. cbrEvt->CallbackFunction = NSSnapValues::ParseTTDVar(true, reader);
  325. cbrEvt->LastNestedEventTime = reader->ReadInt64(NSTokens::Key::i64Val, true);
  326. }
  327. //////////////////
  328. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  329. void ExternalCallEventLogEntry_ProcessDiagInfoPre(EventLogEntry* evt, Js::JavascriptFunction* function, UnlinkableSlabAllocator& alloc)
  330. {
  331. ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
  332. Js::JavascriptString* displayName = function->GetDisplayName();
  333. alloc.CopyStringIntoWLength(displayName->GetString(), displayName->GetLength(), callEvt->FunctionName);
  334. }
  335. #endif
  336. int64 ExternalCallEventLogEntry_GetLastNestedEventTime(const EventLogEntry* evt)
  337. {
  338. const ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
  339. return callEvt->LastNestedEventTime;
  340. }
  341. void ExternalCallEventLogEntry_ProcessArgs(EventLogEntry* evt, int32 rootDepth, Js::JavascriptFunction* function, const Js::Arguments& args, bool checkExceptions, UnlinkableSlabAllocator& alloc)
  342. {
  343. ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
  344. callEvt->RootNestingDepth = rootDepth;
  345. callEvt->ArgCount = args.Info.Count + 1;
  346. static_assert(sizeof(TTDVar) == sizeof(Js::Var), "These need to be the same size (and have same bit layout) for this to work!");
  347. callEvt->ArgArray = alloc.SlabAllocateArray<TTDVar>(callEvt->ArgCount);
  348. callEvt->ArgArray[0] = static_cast<TTDVar>(function);
  349. js_memcpy_s(callEvt->ArgArray + 1, args.Info.Count * sizeof(TTDVar), args.Values, args.Info.Count * sizeof(Js::Var));
  350. if (args.HasNewTarget())
  351. {
  352. callEvt->NewTarget = static_cast<TTDVar>(args.GetNewTarget());
  353. }
  354. else
  355. {
  356. callEvt->NewTarget = nullptr;
  357. }
  358. callEvt->ReturnValue = nullptr;
  359. callEvt->LastNestedEventTime = TTD_EVENT_MAXTIME;
  360. callEvt->CheckExceptionStatus = checkExceptions;
  361. }
  362. void ExternalCallEventLogEntry_ProcessReturn(EventLogEntry* evt, Js::Var res, int64 lastNestedEvent)
  363. {
  364. ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
  365. callEvt->ReturnValue = TTD_CONVERT_JSVAR_TO_TTDVAR(res);
  366. callEvt->LastNestedEventTime = lastNestedEvent;
  367. }
  368. void ExternalCallEventLogEntry_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
  369. {
  370. ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
  371. alloc.UnlinkAllocation(callEvt->ArgArray);
  372. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  373. alloc.UnlinkString(callEvt->FunctionName);
  374. #endif
  375. }
  376. void ExternalCallEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  377. {
  378. const ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
  379. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  380. writer->WriteString(NSTokens::Key::name, callEvt->FunctionName, NSTokens::Separator::CommaSeparator);
  381. #endif
  382. writer->WriteInt32(NSTokens::Key::rootNestingDepth, callEvt->RootNestingDepth, NSTokens::Separator::CommaSeparator);
  383. writer->WriteLengthValue(callEvt->ArgCount, NSTokens::Separator::CommaSeparator);
  384. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  385. for(uint32 i = 0; i < callEvt->ArgCount; ++i)
  386. {
  387. NSTokens::Separator sep = (i != 0) ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator;
  388. NSSnapValues::EmitTTDVar(callEvt->ArgArray[i], writer, sep);
  389. }
  390. writer->WriteSequenceEnd();
  391. writer->WriteKey(NSTokens::Key::newTargetVal, NSTokens::Separator::CommaSeparator);
  392. NSSnapValues::EmitTTDVar(callEvt->NewTarget, writer, NSTokens::Separator::NoSeparator);
  393. writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
  394. NSSnapValues::EmitTTDVar(callEvt->ReturnValue, writer, NSTokens::Separator::NoSeparator);
  395. writer->WriteBool(NSTokens::Key::boolVal, callEvt->CheckExceptionStatus, NSTokens::Separator::CommaSeparator);
  396. writer->WriteInt64(NSTokens::Key::i64Val, callEvt->LastNestedEventTime, NSTokens::Separator::CommaSeparator);
  397. }
  398. void ExternalCallEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  399. {
  400. ExternalCallEventLogEntry* callEvt = GetInlineEventDataAs<ExternalCallEventLogEntry, EventKind::ExternalCallTag>(evt);
  401. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  402. reader->ReadString(NSTokens::Key::name, alloc, callEvt->FunctionName, true);
  403. #endif
  404. callEvt->RootNestingDepth = reader->ReadInt32(NSTokens::Key::rootNestingDepth, true);
  405. callEvt->ArgCount = reader->ReadLengthValue(true);
  406. callEvt->ArgArray = alloc.SlabAllocateArray<TTDVar>(callEvt->ArgCount);
  407. reader->ReadSequenceStart_WDefaultKey(true);
  408. for(uint32 i = 0; i < callEvt->ArgCount; ++i)
  409. {
  410. callEvt->ArgArray[i] = NSSnapValues::ParseTTDVar(i != 0, reader);
  411. }
  412. reader->ReadSequenceEnd();
  413. reader->ReadKey(NSTokens::Key::newTargetVal, true);
  414. callEvt->NewTarget = NSSnapValues::ParseTTDVar(false, reader);
  415. reader->ReadKey(NSTokens::Key::argRetVal, true);
  416. callEvt->ReturnValue = NSSnapValues::ParseTTDVar(false, reader);
  417. callEvt->CheckExceptionStatus = reader->ReadBool(NSTokens::Key::boolVal, true);
  418. callEvt->LastNestedEventTime = reader->ReadInt64(NSTokens::Key::i64Val, true);
  419. }
  420. //////////////////
  421. void ExplicitLogWriteEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  422. {
  423. ; //We don't track any extra data with this
  424. }
  425. void ExplicitLogWriteEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  426. {
  427. ; //We don't track any extra data with this
  428. }
  429. void TTDInnerLoopLogWriteEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  430. {
  431. const TTDInnerLoopLogWriteEventLogEntry* ilevt = GetInlineEventDataAs<TTDInnerLoopLogWriteEventLogEntry, EventKind::TTDInnerLoopLogWriteTag>(evt);
  432. writer->WriteLogTag(NSTokens::Key::sourceContextId, ilevt->SourceScriptLogId, NSTokens::Separator::CommaSeparator);
  433. writer->WriteInt64(NSTokens::Key::eventTime, ilevt->EventTime, NSTokens::Separator::CommaSeparator);
  434. writer->WriteInt64(NSTokens::Key::functionTime, ilevt->FunctionTime, NSTokens::Separator::CommaSeparator);
  435. writer->WriteInt64(NSTokens::Key::loopTime, ilevt->LoopTime, NSTokens::Separator::CommaSeparator);
  436. writer->WriteUInt32(NSTokens::Key::functionBodyId, ilevt->TopLevelBodyId, NSTokens::Separator::CommaSeparator);
  437. writer->WriteUInt32(NSTokens::Key::functionColumn, ilevt->FunctionLine, NSTokens::Separator::CommaSeparator);
  438. writer->WriteUInt32(NSTokens::Key::functionLine, ilevt->FunctionColumn, NSTokens::Separator::CommaSeparator);
  439. writer->WriteUInt32(NSTokens::Key::line, ilevt->Line, NSTokens::Separator::CommaSeparator);
  440. writer->WriteUInt32(NSTokens::Key::column, ilevt->Column, NSTokens::Separator::CommaSeparator);
  441. }
  442. void TTDInnerLoopLogWriteEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  443. {
  444. TTDInnerLoopLogWriteEventLogEntry* ilevt = GetInlineEventDataAs<TTDInnerLoopLogWriteEventLogEntry, EventKind::TTDInnerLoopLogWriteTag>(evt);
  445. ilevt->SourceScriptLogId = reader->ReadLogTag(NSTokens::Key::sourceContextId, true);
  446. ilevt->EventTime = reader->ReadInt64(NSTokens::Key::eventTime, true);
  447. ilevt->FunctionTime = reader->ReadInt64(NSTokens::Key::functionTime, true);
  448. ilevt->LoopTime = reader->ReadInt64(NSTokens::Key::loopTime, true);
  449. ilevt->TopLevelBodyId = reader->ReadUInt32(NSTokens::Key::functionBodyId, true);
  450. ilevt->FunctionLine = reader->ReadUInt32(NSTokens::Key::functionColumn, true);
  451. ilevt->FunctionColumn = reader->ReadUInt32(NSTokens::Key::functionLine, true);
  452. ilevt->Line = reader->ReadUInt32(NSTokens::Key::line, true);
  453. ilevt->Column = reader->ReadUInt32(NSTokens::Key::column, true);
  454. }
  455. void TTDFetchAutoTraceStatusEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  456. {
  457. const TTDFetchAutoTraceStatusEventLogEntry* atfevt = GetInlineEventDataAs<TTDFetchAutoTraceStatusEventLogEntry, EventKind::TTDFetchAutoTraceStatusTag>(evt);
  458. writer->WriteLogTag(NSTokens::Key::boolVal, atfevt->IsEnabled, NSTokens::Separator::CommaSeparator);
  459. }
  460. void TTDFetchAutoTraceStatusEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  461. {
  462. TTDFetchAutoTraceStatusEventLogEntry* atfevt = GetInlineEventDataAs<TTDFetchAutoTraceStatusEventLogEntry, EventKind::TTDFetchAutoTraceStatusTag>(evt);
  463. atfevt->IsEnabled = reader->ReadLogTag(NSTokens::Key::boolVal, true);
  464. }
  465. }
  466. }
  467. #endif