TTActionEvents.h 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  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. namespace NSLogEvents
  10. {
  11. //true if this is a root call function
  12. bool IsJsRTActionRootCall(const EventLogEntry* evt);
  13. //We have a number of loops where we look for a snapshot or root with a given time value -- this encapsulates the access logic
  14. int64 AccessTimeInRootCallOrSnapshot(const EventLogEntry* evt, bool& isSnap, bool& isRoot, bool& hasRtrSnap);
  15. bool TryGetTimeFromRootCallOrSnapshot(const EventLogEntry* evt, int64& res);
  16. int64 GetTimeFromRootCallOrSnapshot(const EventLogEntry* evt);
  17. //Handle the replay of the result of an action for the the given action type and tag
  18. template <typename T, EventKind tag>
  19. void JsRTActionHandleResultForReplay(ThreadContextTTD* executeContext, const EventLogEntry* evt, Js::Var result)
  20. {
  21. TTDVar origResult = GetInlineEventDataAs<T, tag>(evt)->Result;
  22. PassVarToHostInReplay(executeContext, origResult, result);
  23. }
  24. //////////////////
  25. //A generic struct for actions that only need a result value
  26. struct JsRTResultOnlyAction
  27. {
  28. TTDVar Result;
  29. };
  30. template <EventKind tag>
  31. void JsRTResultOnlyAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  32. {
  33. const JsRTResultOnlyAction* vAction = GetInlineEventDataAs<JsRTResultOnlyAction, tag>(evt);
  34. writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
  35. NSSnapValues::EmitTTDVar(vAction->Result, writer, NSTokens::Separator::NoSeparator);
  36. }
  37. template <EventKind tag>
  38. void JsRTResultOnlyAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  39. {
  40. JsRTResultOnlyAction* vAction = GetInlineEventDataAs<JsRTResultOnlyAction, tag>(evt);
  41. reader->ReadKey(NSTokens::Key::argRetVal, true);
  42. vAction->Result = NSSnapValues::ParseTTDVar(false, reader);
  43. }
  44. //A generic struct for actions that only need a single integral value
  45. struct JsRTIntegralArgumentAction
  46. {
  47. TTDVar Result;
  48. int64 Scalar;
  49. };
  50. template <EventKind tag>
  51. void JsRTIntegralArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  52. {
  53. const JsRTIntegralArgumentAction* vAction = GetInlineEventDataAs<JsRTIntegralArgumentAction, tag>(evt);
  54. writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
  55. NSSnapValues::EmitTTDVar(vAction->Result, writer, NSTokens::Separator::NoSeparator);
  56. writer->WriteInt64(NSTokens::Key::i64Val, vAction->Scalar, NSTokens::Separator::CommaSeparator);
  57. }
  58. template <EventKind tag>
  59. void JsRTIntegralArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  60. {
  61. JsRTIntegralArgumentAction* vAction = GetInlineEventDataAs<JsRTIntegralArgumentAction, tag>(evt);
  62. reader->ReadKey(NSTokens::Key::argRetVal, true);
  63. vAction->Result = NSSnapValues::ParseTTDVar(false, reader);
  64. vAction->Scalar = reader->ReadInt64(NSTokens::Key::i64Val, true);
  65. }
  66. //A generic struct for actions that only need variables
  67. template <size_t count>
  68. struct JsRTVarsArgumentAction_InternalUse
  69. {
  70. TTDVar Result;
  71. TTDVar VarArray[count];
  72. };
  73. template <EventKind tag, size_t count>
  74. void JsRTVarsArgumentAction_InternalUse_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  75. {
  76. const JsRTVarsArgumentAction_InternalUse<count>* vAction = GetInlineEventDataAs<JsRTVarsArgumentAction_InternalUse<count>, tag>(evt);
  77. writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
  78. NSSnapValues::EmitTTDVar(vAction->Result, writer, NSTokens::Separator::NoSeparator);
  79. if(count == 1)
  80. {
  81. NSSnapValues::EmitTTDVar(vAction->VarArray[0], writer, NSTokens::Separator::CommaSeparator);
  82. }
  83. else
  84. {
  85. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  86. for(size_t i = 0; i < count; ++i)
  87. {
  88. NSSnapValues::EmitTTDVar(vAction->VarArray[i], writer, i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  89. }
  90. writer->WriteSequenceEnd();
  91. }
  92. }
  93. template <EventKind tag, size_t count>
  94. void JsRTVarsArgumentAction_InternalUse_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  95. {
  96. JsRTVarsArgumentAction_InternalUse<count>* vAction = GetInlineEventDataAs<JsRTVarsArgumentAction_InternalUse<count>, tag>(evt);
  97. reader->ReadKey(NSTokens::Key::argRetVal, true);
  98. vAction->Result = NSSnapValues::ParseTTDVar(false, reader);
  99. if(count == 1)
  100. {
  101. vAction->VarArray[0] = NSSnapValues::ParseTTDVar(true, reader);
  102. }
  103. else
  104. {
  105. reader->ReadSequenceStart_WDefaultKey(true);
  106. for(size_t i = 0; i < count; ++i)
  107. {
  108. vAction->VarArray[i] = NSSnapValues::ParseTTDVar(i != 0, reader);
  109. }
  110. reader->ReadSequenceEnd();
  111. }
  112. }
  113. template <size_t count, size_t index>
  114. TTDVar GetVarItem_InternalUse(const JsRTVarsArgumentAction_InternalUse<count>* argAction)
  115. {
  116. static_assert(index < count, "Index out of bounds in JsRTVarAndIntegralArgumentsAction.");
  117. return argAction->VarArray[index];
  118. }
  119. template <size_t count> TTDVar GetVarItem_0(const JsRTVarsArgumentAction_InternalUse<count>* argAction) { return GetVarItem_InternalUse<count, 0>(argAction); }
  120. template <size_t count> TTDVar GetVarItem_1(const JsRTVarsArgumentAction_InternalUse<count>* argAction) { return GetVarItem_InternalUse<count, 1>(argAction); }
  121. template <size_t count> TTDVar GetVarItem_2(const JsRTVarsArgumentAction_InternalUse<count>* argAction) { return GetVarItem_InternalUse<count, 2>(argAction); }
  122. template <size_t count, size_t index>
  123. void SetVarItem_InternalUse(JsRTVarsArgumentAction_InternalUse<count>* argAction, TTDVar value)
  124. {
  125. static_assert(index < count, "Index out of bounds in JsRTVarAndIntegralArgumentsAction.");
  126. argAction->VarArray[index] = value;
  127. }
  128. template <size_t count> void SetVarItem_0(JsRTVarsArgumentAction_InternalUse<count>* argAction, TTDVar value) { return SetVarItem_InternalUse<count, 0>(argAction, value); }
  129. template <size_t count> void SetVarItem_1(JsRTVarsArgumentAction_InternalUse<count>* argAction, TTDVar value) { return SetVarItem_InternalUse<count, 1>(argAction, value); }
  130. template <size_t count> void SetVarItem_2(JsRTVarsArgumentAction_InternalUse<count>* argAction, TTDVar value) { return SetVarItem_InternalUse<count, 2>(argAction, value); }
  131. typedef JsRTVarsArgumentAction_InternalUse<1> JsRTSingleVarArgumentAction;
  132. template <EventKind tag> void JsRTSingleVarArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext) { JsRTVarsArgumentAction_InternalUse_Emit<tag, 1>(evt, writer, threadContext); }
  133. template <EventKind tag> void JsRTSingleVarArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc) { JsRTVarsArgumentAction_InternalUse_Parse<tag, 1>(evt, threadContext, reader, alloc); }
  134. typedef JsRTVarsArgumentAction_InternalUse<2> JsRTDoubleVarArgumentAction;
  135. template <EventKind tag> void JsRTDoubleVarArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext) { JsRTVarsArgumentAction_InternalUse_Emit<tag, 2>(evt, writer, threadContext); }
  136. template <EventKind tag> void JsRTDoubleVarArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc) { JsRTVarsArgumentAction_InternalUse_Parse<tag, 2>(evt, threadContext, reader, alloc); }
  137. typedef JsRTVarsArgumentAction_InternalUse<3> JsRTTrippleVarArgumentAction;
  138. template <EventKind tag> void JsRTTrippleVarArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext) { JsRTVarsArgumentAction_InternalUse_Emit<tag, 3>(evt, writer, threadContext); }
  139. template <EventKind tag> void JsRTTrippleVarArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc) { JsRTVarsArgumentAction_InternalUse_Parse<tag, 3>(evt, threadContext, reader, alloc); }
  140. //A generic struct for actions that need variables and scalar data
  141. template <size_t vcount, size_t icount>
  142. struct JsRTVarAndIntegralArgumentsAction_InternalUse
  143. {
  144. TTDVar Result;
  145. TTDVar VarArray[vcount];
  146. int64 ScalarArray[icount];
  147. };
  148. template <EventKind tag, size_t vcount, size_t icount>
  149. void JsRTVarAndIntegralArgumentsAction_InternalUse_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  150. {
  151. const JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* vAction = GetInlineEventDataAs<JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>, tag>(evt);
  152. writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
  153. NSSnapValues::EmitTTDVar(vAction->Result, writer, NSTokens::Separator::NoSeparator);
  154. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  155. for(size_t i = 0; i < vcount; ++i)
  156. {
  157. NSSnapValues::EmitTTDVar(vAction->VarArray[i], writer, i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  158. }
  159. for(size_t i = 0; i < icount; ++i)
  160. {
  161. writer->WriteNakedInt64(vAction->ScalarArray[i], vcount + i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  162. }
  163. writer->WriteSequenceEnd();
  164. }
  165. template <EventKind tag, size_t vcount, size_t icount>
  166. void JsRTVarAndIntegralArgumentsAction_InternalUse_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  167. {
  168. JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* vAction = GetInlineEventDataAs<JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>, tag>(evt);
  169. reader->ReadKey(NSTokens::Key::argRetVal, true);
  170. vAction->Result = NSSnapValues::ParseTTDVar(false, reader);
  171. reader->ReadSequenceStart_WDefaultKey(true);
  172. for(size_t i = 0; i < vcount; ++i)
  173. {
  174. vAction->VarArray[i] = NSSnapValues::ParseTTDVar(i != 0, reader);
  175. }
  176. for(size_t i = 0; i < icount; ++i)
  177. {
  178. vAction->ScalarArray[i] = reader->ReadNakedInt64(vcount + i != 0);
  179. }
  180. reader->ReadSequenceEnd();
  181. }
  182. template <size_t vcount, size_t icount, size_t index>
  183. TTDVar GetVarItem_InternalUse(const JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction)
  184. {
  185. static_assert(index < vcount, "Index out of bounds in JsRTVarAndIntegralArgumentsAction.");
  186. return argAction->VarArray[index];
  187. }
  188. template <size_t vcount, size_t icount> TTDVar GetVarItem_0(const JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction) { return GetVarItem_InternalUse<vcount, icount, 0>(argAction); }
  189. template <size_t vcount, size_t icount> TTDVar GetVarItem_1(const JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction) { return GetVarItem_InternalUse<vcount, icount, 1>(argAction); }
  190. template <size_t vcount, size_t icount, size_t index>
  191. void SetVarItem_InternalUse(JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction, TTDVar value)
  192. {
  193. static_assert(index < vcount, "Index out of bounds in JsRTVarAndIntegralArgumentsAction.");
  194. argAction->VarArray[index] = value;
  195. }
  196. template <size_t vcount, size_t icount> void SetVarItem_0(JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction, TTDVar value) { return SetVarItem_InternalUse<vcount, icount, 0>(argAction, value); }
  197. template <size_t vcount, size_t icount> void SetVarItem_1(JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction, TTDVar value) { return SetVarItem_InternalUse<vcount, icount, 1>(argAction, value); }
  198. template <size_t vcount, size_t icount, size_t index>
  199. int64 GetScalarItem_InternalUse(const JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction)
  200. {
  201. static_assert(index < icount, "Index out of bounds in JsRTVarAndIntegralArgumentsAction.");
  202. return argAction->ScalarArray[index];
  203. }
  204. template <size_t vcount, size_t icount> int64 GetScalarItem_0(const JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction) { return GetScalarItem_InternalUse<vcount, icount, 0>(argAction); }
  205. template <size_t vcount, size_t icount> int64 GetScalarItem_1(const JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction) { return GetScalarItem_InternalUse<vcount, icount, 1>(argAction); }
  206. template <size_t vcount, size_t icount, size_t index>
  207. void SetScalarItem_InternalUse(JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction, int64 value)
  208. {
  209. static_assert(index < icount, "Index out of bounds in JsRTVarAndIntegralArgumentsAction.");
  210. argAction->ScalarArray[index] = value;
  211. }
  212. template <size_t vcount, size_t icount> void SetScalarItem_0(JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction, int64 value) { return SetScalarItem_InternalUse<vcount, icount, 0>(argAction, value); }
  213. template <size_t vcount, size_t icount> void SetScalarItem_1(JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction, int64 value) { return SetScalarItem_InternalUse<vcount, icount, 1>(argAction, value); }
  214. template <size_t vcount, size_t icount>
  215. Js::PropertyId GetPropertyIdItem(const JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction)
  216. {
  217. static_assert(0 < icount, "Index out of bounds in JsRTVarAndIntegralArgumentsAction.");
  218. return (Js::PropertyId)argAction->ScalarArray[0];
  219. }
  220. template <size_t vcount, size_t icount>
  221. void SetPropertyIdItem(JsRTVarAndIntegralArgumentsAction_InternalUse<vcount, icount>* argAction, Js::PropertyId value)
  222. {
  223. AssertMsg(0 < icount, "Index out of bounds in JsRTVarAndIntegralArgumentsAction.");
  224. argAction->ScalarArray[0] = (int64)value;
  225. }
  226. typedef JsRTVarAndIntegralArgumentsAction_InternalUse<1, 1> JsRTSingleVarScalarArgumentAction;
  227. template <EventKind tag> void JsRTSingleVarScalarArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext) { JsRTVarAndIntegralArgumentsAction_InternalUse_Emit<tag, 1, 1>(evt, writer, threadContext); }
  228. template <EventKind tag> void JsRTSingleVarScalarArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc) { JsRTVarAndIntegralArgumentsAction_InternalUse_Parse<tag, 1, 1>(evt, threadContext, reader, alloc); }
  229. typedef JsRTVarAndIntegralArgumentsAction_InternalUse<2, 1> JsRTDoubleVarSingleScalarArgumentAction;
  230. template <EventKind tag> void JsRTDoubleVarSingleScalarArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext) { JsRTVarAndIntegralArgumentsAction_InternalUse_Emit<tag, 2, 1>(evt, writer, threadContext); }
  231. template <EventKind tag> void JsRTDoubleVarSingleScalarArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc) { JsRTVarAndIntegralArgumentsAction_InternalUse_Parse<tag, 2, 1>(evt, threadContext, reader, alloc); }
  232. typedef JsRTVarAndIntegralArgumentsAction_InternalUse<1, 2> JsRTSingleVarDoubleScalarArgumentAction;
  233. template <EventKind tag> void JsRTSingleVarDoubleScalarArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext) { JsRTVarAndIntegralArgumentsAction_InternalUse_Emit<tag, 1, 2>(evt, writer, threadContext); }
  234. template <EventKind tag> void JsRTSingleVarDoubleScalarArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc) { JsRTVarAndIntegralArgumentsAction_InternalUse_Parse<tag, 1, 2>(evt, threadContext, reader, alloc); }
  235. typedef JsRTVarAndIntegralArgumentsAction_InternalUse<2, 2> JsRTDoubleVarDoubleScalarArgumentAction;
  236. template <EventKind tag> void JsRTDoubleVarDoubleScalarArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext) { JsRTVarAndIntegralArgumentsAction_InternalUse_Emit<tag, 2, 2>(evt, writer, threadContext); }
  237. template <EventKind tag> void JsRTDoubleVarDoubleScalarArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc) { JsRTVarAndIntegralArgumentsAction_InternalUse_Parse<tag, 2, 2>(evt, threadContext, reader, alloc); }
  238. //A struct for actions that are definied by their tag and a double
  239. struct JsRTDoubleArgumentAction
  240. {
  241. TTDVar Result;
  242. double DoubleValue;
  243. };
  244. template <EventKind tag>
  245. void JsRTDoubleArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  246. {
  247. const JsRTDoubleArgumentAction* dblAction = GetInlineEventDataAs<JsRTDoubleArgumentAction, tag>(evt);
  248. writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
  249. NSSnapValues::EmitTTDVar(dblAction->Result, writer, NSTokens::Separator::NoSeparator);
  250. writer->WriteDouble(NSTokens::Key::doubleVal, dblAction->DoubleValue, NSTokens::Separator::CommaSeparator);
  251. }
  252. template <EventKind tag>
  253. void JsRTDoubleArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  254. {
  255. JsRTDoubleArgumentAction* dblAction = GetInlineEventDataAs<JsRTDoubleArgumentAction, tag>(evt);
  256. reader->ReadKey(NSTokens::Key::argRetVal, true);
  257. dblAction->Result = NSSnapValues::ParseTTDVar(false, reader);
  258. dblAction->DoubleValue = reader->ReadDouble(NSTokens::Key::doubleVal, true);
  259. }
  260. //A struct for actions that are definied by their tag and a single string
  261. struct JsRTStringArgumentAction
  262. {
  263. TTDVar Result;
  264. TTString StringValue;
  265. };
  266. template <EventKind tag>
  267. void JsRTStringArgumentAction_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
  268. {
  269. JsRTStringArgumentAction* strAction = GetInlineEventDataAs<JsRTStringArgumentAction, tag>(evt);
  270. alloc.UnlinkString(strAction->StringValue);
  271. }
  272. template <EventKind tag>
  273. void JsRTStringArgumentAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  274. {
  275. const JsRTStringArgumentAction* strAction = GetInlineEventDataAs<JsRTStringArgumentAction, tag>(evt);
  276. writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
  277. NSSnapValues::EmitTTDVar(strAction->Result, writer, NSTokens::Separator::NoSeparator);
  278. writer->WriteString(NSTokens::Key::stringVal, strAction->StringValue, NSTokens::Separator::CommaSeparator);
  279. }
  280. template <EventKind tag>
  281. void JsRTStringArgumentAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  282. {
  283. JsRTStringArgumentAction* strAction = GetInlineEventDataAs<JsRTStringArgumentAction, tag>(evt);
  284. reader->ReadKey(NSTokens::Key::argRetVal, true);
  285. strAction->Result = NSSnapValues::ParseTTDVar(false, reader);
  286. reader->ReadString(NSTokens::Key::stringVal, alloc, strAction->StringValue, true);
  287. }
  288. //A struct for actions that are definied by a raw byte* + length
  289. struct JsRTByteBufferAction
  290. {
  291. TTDVar Result;
  292. byte* Buffer;
  293. uint32 Length;
  294. };
  295. template <EventKind tag>
  296. void JsRTByteBufferAction_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
  297. {
  298. JsRTByteBufferAction* bufferAction = GetInlineEventDataAs<JsRTByteBufferAction, tag>(evt);
  299. if(bufferAction->Buffer != nullptr)
  300. {
  301. alloc.UnlinkAllocation(bufferAction->Buffer);
  302. }
  303. }
  304. template <EventKind tag>
  305. void JsRTByteBufferAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  306. {
  307. const JsRTByteBufferAction* bufferAction = GetInlineEventDataAs<JsRTByteBufferAction, tag>(evt);
  308. writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
  309. NSSnapValues::EmitTTDVar(bufferAction->Result, writer, NSTokens::Separator::NoSeparator);
  310. bool badValue = (bufferAction->Buffer == nullptr && bufferAction->Length > 0);
  311. writer->WriteBool(NSTokens::Key::boolVal, badValue, NSTokens::Separator::CommaSeparator);
  312. writer->WriteLengthValue(bufferAction->Length, NSTokens::Separator::CommaSeparator);
  313. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  314. if(!badValue)
  315. {
  316. for(uint32 i = 0; i < bufferAction->Length; ++i)
  317. {
  318. writer->WriteNakedByte(bufferAction->Buffer[i], i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  319. }
  320. }
  321. writer->WriteSequenceEnd();
  322. }
  323. template <EventKind tag>
  324. void JsRTByteBufferAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  325. {
  326. JsRTByteBufferAction* bufferAction = GetInlineEventDataAs<JsRTByteBufferAction, tag>(evt);
  327. reader->ReadKey(NSTokens::Key::argRetVal, true);
  328. bufferAction->Result = NSSnapValues::ParseTTDVar(false, reader);
  329. bool badValue = reader->ReadBool(NSTokens::Key::boolVal, true);
  330. bufferAction->Length = reader->ReadLengthValue(true);
  331. bufferAction->Buffer = nullptr;
  332. reader->ReadSequenceStart_WDefaultKey(true);
  333. if(!badValue)
  334. {
  335. bufferAction->Buffer = (bufferAction->Length != 0) ? alloc.SlabAllocateArray<byte>(bufferAction->Length) : nullptr;
  336. for(uint32 i = 0; i < bufferAction->Length; ++i)
  337. {
  338. bufferAction->Buffer[i] = reader->ReadNakedByte(i != 0);
  339. }
  340. reader->ReadSequenceEnd();
  341. }
  342. }
  343. //////////////////
  344. //A class for constructor calls
  345. struct JsRTCreateScriptContextAction_KnownObjects
  346. {
  347. TTD_LOG_PTR_ID UndefinedObject;
  348. TTD_LOG_PTR_ID NullObject;
  349. TTD_LOG_PTR_ID TrueObject;
  350. TTD_LOG_PTR_ID FalseObject;
  351. };
  352. struct JsRTCreateScriptContextAction
  353. {
  354. TTD_LOG_PTR_ID GlobalObject;
  355. JsRTCreateScriptContextAction_KnownObjects* KnownObjects;
  356. };
  357. void CreateScriptContext_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  358. void CreateScriptContext_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc);
  359. void CreateScriptContext_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext);
  360. void CreateScriptContext_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc);
  361. void SetActiveScriptContext_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  362. #if !INT32VAR
  363. void CreateInt_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  364. #endif
  365. void CreateNumber_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  366. void CreateBoolean_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  367. void CreateString_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  368. void CreateSymbol_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  369. void Execute_CreateErrorHelper(const JsRTSingleVarArgumentAction* errorData, ThreadContextTTD* executeContext, Js::ScriptContext* ctx, EventKind eventKind, Js::Var* res);
  370. template<EventKind errorKind>
  371. void CreateError_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext)
  372. {
  373. const JsRTSingleVarArgumentAction* action = GetInlineEventDataAs<JsRTSingleVarArgumentAction, errorKind>(evt);
  374. Js::Var res = nullptr;
  375. Execute_CreateErrorHelper(action, executeContext, executeContext->GetActiveScriptContext(), errorKind, &res);
  376. if(res != nullptr)
  377. {
  378. JsRTActionHandleResultForReplay<JsRTSingleVarArgumentAction, errorKind>(executeContext, evt, res);
  379. }
  380. }
  381. void VarConvertToNumber_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  382. void VarConvertToBoolean_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  383. void VarConvertToString_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  384. void VarConvertToObject_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  385. void AddRootRef_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  386. void AddWeakRootRef_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  387. void AllocateObject_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  388. void AllocateExternalObject_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  389. void AllocateArrayAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  390. void AllocateArrayBufferAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  391. void AllocateExternalArrayBufferAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  392. void AllocateFunctionAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  393. void HostProcessExitAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  394. void GetAndClearExceptionWithMetadataAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  395. void GetAndClearExceptionAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  396. void SetExceptionAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  397. void HasPropertyAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  398. void HasOwnPropertyAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  399. void InstanceOfAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  400. void EqualsAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  401. void LessThanAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  402. void GetPropertyIdFromSymbolAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  403. void GetPrototypeAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  404. void GetPropertyAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  405. void GetIndexAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  406. void GetOwnPropertyInfoAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  407. void GetOwnPropertyNamesInfoAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  408. void GetOwnPropertySymbolsInfoAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  409. void DefinePropertyAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  410. void DeletePropertyAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  411. void SetPrototypeAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  412. void SetPropertyAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  413. void SetIndexAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  414. void GetTypedArrayInfoAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  415. void GetDataViewInfoAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  416. //////////////////
  417. //A generic struct for the naked buffer copy action
  418. struct JsRTRawBufferCopyAction
  419. {
  420. TTDVar Dst;
  421. TTDVar Src;
  422. uint32 DstIndx;
  423. uint32 SrcIndx;
  424. uint32 Count;
  425. };
  426. void JsRTRawBufferCopyAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext);
  427. void JsRTRawBufferCopyAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc);
  428. //A generic struct for the naked buffer modify action (with buffer data)
  429. struct JsRTRawBufferModifyAction
  430. {
  431. TTDVar Trgt;
  432. byte* Data;
  433. uint32 Index;
  434. uint32 Length;
  435. };
  436. template <EventKind tag>
  437. void JsRTRawBufferModifyAction_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc)
  438. {
  439. JsRTRawBufferModifyAction* bufferAction = GetInlineEventDataAs<JsRTRawBufferModifyAction, tag>(evt);
  440. if(bufferAction->Data != nullptr)
  441. {
  442. alloc.UnlinkAllocation(bufferAction->Data);
  443. }
  444. }
  445. template <EventKind tag>
  446. void JsRTRawBufferModifyAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
  447. {
  448. const JsRTRawBufferModifyAction* bufferAction = GetInlineEventDataAs<JsRTRawBufferModifyAction, tag>(evt);
  449. writer->WriteKey(NSTokens::Key::argRetVal, NSTokens::Separator::CommaSeparator);
  450. NSSnapValues::EmitTTDVar(bufferAction->Trgt, writer, NSTokens::Separator::NoSeparator);
  451. writer->WriteUInt32(NSTokens::Key::index, bufferAction->Index, NSTokens::Separator::CommaSeparator);
  452. writer->WriteLengthValue(bufferAction->Length, NSTokens::Separator::CommaSeparator);
  453. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  454. for(uint32 i = 0; i < bufferAction->Length; ++i)
  455. {
  456. writer->WriteNakedByte(bufferAction->Data[i], i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  457. }
  458. writer->WriteSequenceEnd();
  459. }
  460. template <EventKind tag>
  461. void JsRTRawBufferModifyAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
  462. {
  463. JsRTRawBufferModifyAction* bufferAction = GetInlineEventDataAs<JsRTRawBufferModifyAction, tag>(evt);
  464. reader->ReadKey(NSTokens::Key::argRetVal, true);
  465. bufferAction->Trgt = NSSnapValues::ParseTTDVar(false, reader);
  466. bufferAction->Index = reader->ReadUInt32(NSTokens::Key::index, true);
  467. bufferAction->Length = reader->ReadUInt32(NSTokens::Key::count, true);
  468. bufferAction->Data = (bufferAction->Length != 0) ? alloc.SlabAllocateArray<byte>(bufferAction->Length) : nullptr;
  469. reader->ReadSequenceStart_WDefaultKey(true);
  470. for(uint32 i = 0; i < bufferAction->Length; ++i)
  471. {
  472. bufferAction->Data[i] = reader->ReadNakedByte(i != 0);
  473. }
  474. reader->ReadSequenceEnd();
  475. }
  476. void RawBufferCopySync_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  477. void RawBufferModifySync_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  478. void RawBufferAsyncModificationRegister_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  479. void RawBufferAsyncModifyComplete_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  480. //////////////////
  481. //A class for constructor calls
  482. struct JsRTConstructCallAction
  483. {
  484. TTDVar Result;
  485. //The arguments info (constructor function is always args[0])
  486. uint32 ArgCount;
  487. TTDVar* ArgArray;
  488. //A buffer we can use for the actual invocation
  489. Js::Var* ExecArgs;
  490. };
  491. void JsRTConstructCallAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  492. void JsRTConstructCallAction_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc);
  493. void JsRTConstructCallAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext);
  494. void JsRTConstructCallAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc);
  495. //A struct for calls to script parse
  496. struct JsRTCodeParseAction
  497. {
  498. TTDVar Result;
  499. //The body counter id associated with this load
  500. uint32 BodyCtrId;
  501. //Is the code utf8
  502. bool IsUtf8;
  503. //The actual source code and the length in bytes
  504. byte* SourceCode;
  505. uint32 SourceByteLength;
  506. //The URI the souce code was loaded from and the source context id
  507. TTString SourceUri;
  508. uint64 SourceContextId;
  509. //The flags for loading this script
  510. LoadScriptFlag LoadFlag;
  511. };
  512. void JsRTCodeParseAction_SetBodyCtrId(EventLogEntry* parseEvent, uint32 bodyCtrId);
  513. void JsRTCodeParseAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  514. void JsRTCodeParseAction_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc);
  515. void JsRTCodeParseAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext);
  516. void JsRTCodeParseAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc);
  517. //A struct for the replay-debugger info associated with a JsRTCallFunctionAction
  518. struct JsRTCallFunctionAction_ReplayAdditionalInfo
  519. {
  520. //ready-to-run snapshot information -- null if not set and if we want to unload it we just throw it away
  521. SnapShot* RtRSnap;
  522. //A buffer we can use for the actual invocation
  523. Js::Var* ExecArgs;
  524. //Info on the last executed statement in this call
  525. TTDebuggerSourceLocation LastExecutedLocation;
  526. };
  527. //A struct for calls to that execute existing functions
  528. struct JsRTCallFunctionAction
  529. {
  530. TTDVar Result;
  531. //The re-entry depth we are at when this happens
  532. int32 CallbackDepth;
  533. //the number of arguments and the argument array -- function is always argument[0]
  534. uint32 ArgCount;
  535. TTDVar* ArgArray;
  536. //The actual event time associated with this call (is >= the TopLevelCallbackEventTime)
  537. int64 CallEventTime;
  538. //The event time that corresponds to the top-level event time around this call
  539. int64 TopLevelCallbackEventTime;
  540. //The additional info assocated with this action that we use in replay/debug but doesn't matter for record
  541. JsRTCallFunctionAction_ReplayAdditionalInfo* AdditionalReplayInfo;
  542. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  543. //The last event time that is nested in this call
  544. int64 LastNestedEvent;
  545. //The name of the function
  546. TTString FunctionName;
  547. #endif
  548. };
  549. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  550. int64 JsRTCallFunctionAction_GetLastNestedEventTime(const EventLogEntry* evt);
  551. void JsRTCallFunctionAction_ProcessDiagInfoPre(EventLogEntry* evt, Js::Var funcVar, UnlinkableSlabAllocator& alloc);
  552. void JsRTCallFunctionAction_ProcessDiagInfoPost(EventLogEntry* evt, int64 lastNestedEvent);
  553. #endif
  554. void JsRTCallFunctionAction_ProcessArgs(EventLogEntry* evt, int32 rootDepth, int64 callEventTime, Js::Var funcVar, uint32 argc, Js::Var* argv, int64 topLevelCallbackEventTime, UnlinkableSlabAllocator& alloc);
  555. void JsRTCallFunctionAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext);
  556. void JsRTCallFunctionAction_UnloadEventMemory(EventLogEntry* evt, UnlinkableSlabAllocator& alloc);
  557. void JsRTCallFunctionAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext);
  558. void JsRTCallFunctionAction_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc);
  559. //Unload the snapshot
  560. void JsRTCallFunctionAction_UnloadSnapshot(EventLogEntry* evt);
  561. //Set the last executed statement and frame (in debugging mode -- nops for replay mode)
  562. void JsRTCallFunctionAction_SetLastExecutedStatementAndFrameInfo(EventLogEntry* evt, const TTDebuggerSourceLocation& lastSourceLocation);
  563. bool JsRTCallFunctionAction_GetLastExecutedStatementAndFrameInfoForDebugger(const EventLogEntry* evt, TTDebuggerSourceLocation& lastSourceInfo);
  564. }
  565. }
  566. #endif