TTEventLog.cpp 145 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940
  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. #define TTD_CREATE_EVENTLIST_VTABLE_ENTRY(TAG, WRAPPER, TYPE, EXEC_FP, UNLOAD_FP, EMIT_FP, PARSE_FP) this->m_eventListVTable[(uint32)NSLogEvents::EventKind:: ## TAG] = { NSLogEvents::ContextExecuteKind:: ## WRAPPER, EXEC_FP, UNLOAD_FP, EMIT_FP, PARSE_FP, TTD_EVENT_PLUS_DATA_SIZE_DIRECT(sizeof(NSLogEvents:: TYPE)) }
  8. #define TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(TAG, WRAPPER, TYPE, EXEC_FP) this->m_eventListVTable[(uint32)NSLogEvents::EventKind:: ## TAG] = { NSLogEvents::ContextExecuteKind:: ## WRAPPER, NSLogEvents:: ## EXEC_FP, nullptr, NSLogEvents:: ## TYPE ## _Emit ## <NSLogEvents::EventKind:: ## TAG ## >, NSLogEvents:: ## TYPE ## _Parse ## <NSLogEvents::EventKind:: ## TAG ## >, TTD_EVENT_PLUS_DATA_SIZE_DIRECT(sizeof(NSLogEvents:: ## TYPE)) }
  9. namespace TTD
  10. {
  11. TTDJsRTFunctionCallActionPopperRecorder::TTDJsRTFunctionCallActionPopperRecorder()
  12. : m_ctx(nullptr), m_beginTime(0.0), m_callAction(nullptr)
  13. {
  14. ;
  15. }
  16. TTDJsRTFunctionCallActionPopperRecorder::~TTDJsRTFunctionCallActionPopperRecorder()
  17. {
  18. if(this->m_ctx != nullptr)
  19. {
  20. TTDAssert(this->m_callAction != nullptr, "Should be set in sync with ctx!!!");
  21. TTD::EventLog* elog = this->m_ctx->GetThreadContext()->TTDLog;
  22. NSLogEvents::JsRTCallFunctionAction* cfAction = NSLogEvents::GetInlineEventDataAs<NSLogEvents::JsRTCallFunctionAction, NSLogEvents::EventKind::CallExistingFunctionActionTag>(this->m_callAction);
  23. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  24. NSLogEvents::JsRTCallFunctionAction_ProcessDiagInfoPost(this->m_callAction, this->m_ctx->GetThreadContext()->TTDLog->GetLastEventTime());
  25. #endif
  26. //Update the time elapsed since a snapshot if needed
  27. if(cfAction->CallbackDepth == 0)
  28. {
  29. double elapsedTime = (elog->GetCurrentWallTime() - this->m_beginTime);
  30. elog->IncrementElapsedSnapshotTime(elapsedTime);
  31. }
  32. }
  33. }
  34. void TTDJsRTFunctionCallActionPopperRecorder::InitializeForRecording(Js::ScriptContext* ctx, double beginWallTime, NSLogEvents::EventLogEntry* callAction)
  35. {
  36. TTDAssert(this->m_ctx == nullptr && this->m_callAction == nullptr, "Don't double initialize!!!");
  37. this->m_ctx = ctx;
  38. this->m_beginTime = beginWallTime;
  39. this->m_callAction = callAction;
  40. }
  41. /////////////
  42. void TTEventList::AddArrayLink()
  43. {
  44. TTEventListLink* newHeadBlock = this->m_alloc->SlabAllocateStruct<TTEventListLink>();
  45. newHeadBlock->BlockData = this->m_alloc->SlabAllocateFixedSizeArray<byte, TTD_EVENTLOG_LIST_BLOCK_SIZE>();
  46. memset(newHeadBlock->BlockData, 0, TTD_EVENTLOG_LIST_BLOCK_SIZE);
  47. newHeadBlock->CurrPos = 0;
  48. newHeadBlock->StartPos = 0;
  49. newHeadBlock->Next = nullptr;
  50. newHeadBlock->Previous = this->m_headBlock;
  51. if(this->m_headBlock != nullptr)
  52. {
  53. this->m_headBlock->Next = newHeadBlock;
  54. }
  55. this->m_headBlock = newHeadBlock;
  56. }
  57. void TTEventList::RemoveArrayLink(TTEventListLink* block)
  58. {
  59. TTDAssert(block->Previous == nullptr, "Not first event block in log!!!");
  60. TTDAssert(block->StartPos == block->CurrPos, "Haven't cleared all the events in this link");
  61. if(block->Next == nullptr)
  62. {
  63. this->m_headBlock = nullptr; //was only 1 block to we are now all null
  64. }
  65. else
  66. {
  67. block->Next->Previous = nullptr;
  68. }
  69. this->m_alloc->UnlinkAllocation(block->BlockData);
  70. this->m_alloc->UnlinkAllocation(block);
  71. }
  72. TTEventList::TTEventList(UnlinkableSlabAllocator* alloc)
  73. : m_alloc(alloc), m_headBlock(nullptr), m_vtable(nullptr), m_previousEventMap(&HeapAllocator::Instance)
  74. {
  75. ;
  76. }
  77. void TTEventList::SetVTable(const NSLogEvents::EventLogEntryVTableEntry* vtable)
  78. {
  79. this->m_vtable = vtable;
  80. }
  81. void TTEventList::InitializePreviousEventMap()
  82. {
  83. for(TTEventListLink* curr = this->m_headBlock; curr != nullptr; curr = curr->Previous)
  84. {
  85. size_t cpos = curr->StartPos;
  86. size_t ppos = TTD_EVENTLOG_LIST_BLOCK_SIZE; //an invalid sentinal value
  87. while(cpos != curr->CurrPos)
  88. {
  89. NSLogEvents::EventLogEntry* data = reinterpret_cast<NSLogEvents::EventLogEntry*>(curr->BlockData + cpos);
  90. if(cpos != curr->StartPos)
  91. {
  92. this->m_previousEventMap.AddNew(data, ppos);
  93. }
  94. ppos = cpos;
  95. cpos += this->m_vtable[(uint32)data->EventKind].DataSize;
  96. }
  97. }
  98. }
  99. void TTEventList::UnloadEventList()
  100. {
  101. if(this->m_headBlock == nullptr)
  102. {
  103. return;
  104. }
  105. TTEventListLink* firstBlock = this->m_headBlock;
  106. while(firstBlock->Previous != nullptr)
  107. {
  108. firstBlock = firstBlock->Previous;
  109. }
  110. TTEventListLink* curr = firstBlock;
  111. while(curr != nullptr)
  112. {
  113. size_t cpos = curr->StartPos;
  114. while(cpos < curr->CurrPos)
  115. {
  116. NSLogEvents::EventLogEntry* entry = reinterpret_cast<NSLogEvents::EventLogEntry*>(curr->BlockData + cpos);
  117. auto unloadFP = this->m_vtable[(uint32)entry->EventKind].UnloadFP; //use vtable magic here
  118. if(unloadFP != nullptr)
  119. {
  120. unloadFP(entry, *(this->m_alloc));
  121. }
  122. cpos += this->m_vtable[(uint32)entry->EventKind].DataSize;
  123. }
  124. curr->StartPos = curr->CurrPos;
  125. TTEventListLink* next = curr->Next;
  126. this->RemoveArrayLink(curr);
  127. curr = next;
  128. }
  129. this->m_headBlock = nullptr;
  130. }
  131. NSLogEvents::EventLogEntry* TTEventList::GetNextAvailableEntry(size_t requiredSize)
  132. {
  133. if((this->m_headBlock == nullptr) || (this->m_headBlock->CurrPos + requiredSize >= TTD_EVENTLOG_LIST_BLOCK_SIZE))
  134. {
  135. this->AddArrayLink();
  136. }
  137. NSLogEvents::EventLogEntry* entry = reinterpret_cast<NSLogEvents::EventLogEntry*>(this->m_headBlock->BlockData + this->m_headBlock->CurrPos);
  138. this->m_headBlock->CurrPos += requiredSize;
  139. return entry;
  140. }
  141. void TTEventList::DeleteFirstEntry(TTEventListLink* block, NSLogEvents::EventLogEntry* data)
  142. {
  143. TTDAssert(reinterpret_cast<NSLogEvents::EventLogEntry*>(block->BlockData + block->StartPos) == data, "Not the data at the start of the list!!!");
  144. auto unloadFP = this->m_vtable[(uint32)data->EventKind].UnloadFP; //use vtable magic here
  145. if(unloadFP != nullptr)
  146. {
  147. unloadFP(data, *(this->m_alloc));
  148. }
  149. block->StartPos += this->m_vtable[(uint32)data->EventKind].DataSize;
  150. if(block->StartPos == block->CurrPos)
  151. {
  152. this->RemoveArrayLink(block);
  153. }
  154. }
  155. bool TTEventList::IsEmpty() const
  156. {
  157. return this->m_headBlock == nullptr;
  158. }
  159. uint32 TTEventList::Count() const
  160. {
  161. uint32 count = 0;
  162. for(TTEventListLink* curr = this->m_headBlock; curr != nullptr; curr = curr->Previous)
  163. {
  164. size_t cpos = curr->StartPos;
  165. while(cpos != curr->CurrPos)
  166. {
  167. count++;
  168. NSLogEvents::EventLogEntry* data = reinterpret_cast<NSLogEvents::EventLogEntry*>(curr->BlockData + cpos);
  169. cpos += this->m_vtable[(uint32)data->EventKind].DataSize;
  170. }
  171. }
  172. return count;
  173. }
  174. TTEventList::Iterator::Iterator()
  175. : m_currLink(nullptr), m_currIdx(0), m_previousEventMap(nullptr)
  176. {
  177. ;
  178. }
  179. TTEventList::Iterator::Iterator(TTEventListLink* head, size_t pos, const NSLogEvents::EventLogEntryVTableEntry* vtable, const JsUtil::BaseDictionary<const NSLogEvents::EventLogEntry*, size_t, HeapAllocator>* previousEventMap)
  180. : m_currLink(head), m_currIdx(pos), m_vtable(vtable), m_previousEventMap(previousEventMap)
  181. {
  182. ;
  183. }
  184. const NSLogEvents::EventLogEntry* TTEventList::Iterator::Current() const
  185. {
  186. TTDAssert(this->IsValid(), "Iterator is invalid!!!");
  187. return reinterpret_cast<const NSLogEvents::EventLogEntry*>(this->m_currLink->BlockData + this->m_currIdx);
  188. }
  189. NSLogEvents::EventLogEntry* TTEventList::Iterator::Current()
  190. {
  191. TTDAssert(this->IsValid(), "Iterator is invalid!!!");
  192. return reinterpret_cast<NSLogEvents::EventLogEntry*>(this->m_currLink->BlockData + this->m_currIdx);
  193. }
  194. TTEventList::TTEventListLink* TTEventList::Iterator::GetBlock()
  195. {
  196. return this->m_currLink;
  197. }
  198. bool TTEventList::Iterator::IsValid() const
  199. {
  200. return (this->m_currLink != nullptr && this->m_currLink->StartPos <= this->m_currIdx && this->m_currIdx < this->m_currLink->CurrPos);
  201. }
  202. void TTEventList::Iterator::MoveNext()
  203. {
  204. NSLogEvents::EventLogEntry* data = this->Current();
  205. size_t dataSize = this->m_vtable[(uint32)data->EventKind].DataSize;
  206. if(this->m_currIdx + dataSize < this->m_currLink->CurrPos)
  207. {
  208. this->m_currIdx += dataSize;
  209. }
  210. else
  211. {
  212. this->m_currLink = this->m_currLink->Next;
  213. this->m_currIdx = (this->m_currLink != nullptr) ? this->m_currLink->StartPos : 0;
  214. }
  215. }
  216. void TTEventList::Iterator::MovePrevious_ReplayOnly()
  217. {
  218. if(this->m_currIdx > this->m_currLink->StartPos)
  219. {
  220. this->m_currIdx = this->m_previousEventMap->Item(this->Current());
  221. }
  222. else
  223. {
  224. this->m_currLink = this->m_currLink->Previous;
  225. this->m_currIdx = 0;
  226. //move index to the last element
  227. if(this->m_currLink != nullptr && this->m_currIdx < this->m_currLink->CurrPos)
  228. {
  229. NSLogEvents::EventLogEntry* data = this->Current();
  230. size_t npos = this->m_vtable[(uint32)data->EventKind].DataSize;
  231. while(npos < this->m_currLink->CurrPos)
  232. {
  233. this->m_currIdx = npos;
  234. data = this->Current();
  235. npos += this->m_vtable[(uint32)data->EventKind].DataSize;
  236. }
  237. }
  238. }
  239. }
  240. TTEventList::Iterator TTEventList::GetIteratorAtFirst() const
  241. {
  242. if(this->m_headBlock == nullptr)
  243. {
  244. return Iterator(nullptr, 0, this->m_vtable, &this->m_previousEventMap);
  245. }
  246. else
  247. {
  248. TTEventListLink* firstBlock = this->m_headBlock;
  249. while(firstBlock->Previous != nullptr)
  250. {
  251. firstBlock = firstBlock->Previous;
  252. }
  253. return Iterator(firstBlock, firstBlock->StartPos, this->m_vtable, &this->m_previousEventMap);
  254. }
  255. }
  256. TTEventList::Iterator TTEventList::GetIteratorAtLast_ReplayOnly() const
  257. {
  258. if(this->m_headBlock == nullptr)
  259. {
  260. return Iterator(nullptr, 0, this->m_vtable, &this->m_previousEventMap);
  261. }
  262. else
  263. {
  264. size_t cpos = this->m_headBlock->StartPos;
  265. size_t ipos = 0;
  266. do
  267. {
  268. ipos = cpos;
  269. NSLogEvents::EventLogEntry* data = reinterpret_cast<NSLogEvents::EventLogEntry*>(this->m_headBlock->BlockData + cpos);
  270. cpos += this->m_vtable[(uint32)data->EventKind].DataSize;
  271. } while(cpos != this->m_headBlock->CurrPos);
  272. return Iterator(this->m_headBlock, ipos, this->m_vtable, &this->m_previousEventMap);
  273. }
  274. }
  275. //////
  276. void EventLog::AdvanceTimeAndPositionForReplay()
  277. {
  278. this->m_eventTimeCtr++;
  279. this->m_currentReplayEventIterator.MoveNext();
  280. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  281. TTDAssert(!this->m_currentReplayEventIterator.IsValid() || this->m_eventTimeCtr == this->m_currentReplayEventIterator.Current()->EventTimeStamp, "Something is out of sync.");
  282. #endif
  283. }
  284. void EventLog::UpdateComputedMode()
  285. {
  286. TTDAssert(this->m_modeStack.Count() > 0, "Should never be empty!!!");
  287. TTDMode cm = TTDMode::Invalid;
  288. for(uint32 i = 0; i < this->m_modeStack.Count(); ++i)
  289. {
  290. TTDMode m = this->m_modeStack.GetAt(i);
  291. switch(m)
  292. {
  293. case TTDMode::RecordMode:
  294. case TTDMode::ReplayMode:
  295. TTDAssert(i == 0, "One of these should always be first on the stack.");
  296. cm = m;
  297. break;
  298. case TTDMode::DebuggerAttachedMode:
  299. case TTDMode::CurrentlyEnabled:
  300. case TTDMode::ExcludedExecutionTTAction:
  301. case TTDMode::ExcludedExecutionDebuggerAction:
  302. case TTDMode::DebuggerSuppressGetter:
  303. case TTDMode::DebuggerSuppressBreakpoints:
  304. case TTDMode::DebuggerLogBreakpoints:
  305. TTDAssert(i != 0, "A base mode should always be first on the stack.");
  306. cm |= m;
  307. break;
  308. default:
  309. TTDAssert(false, "This mode is unknown or should never appear.");
  310. break;
  311. }
  312. }
  313. this->m_currentMode = cm;
  314. //Set fast path values on ThreadContext
  315. const JsUtil::List<Js::ScriptContext*, HeapAllocator>& contexts = this->m_threadContext->TTDContext->GetTTDContexts();
  316. for(int32 i = 0; i < contexts.Count(); ++i)
  317. {
  318. this->SetModeFlagsOnContext(contexts.Item(i));
  319. }
  320. }
  321. SnapShot* EventLog::DoSnapshotExtract_Helper(double gcTime, JsUtil::BaseHashSet<Js::FunctionBody*, HeapAllocator>& liveTopLevelBodies)
  322. {
  323. SnapShot* snap = nullptr;
  324. //Begin the actual snapshot operation
  325. this->m_snapExtractor.BeginSnapshot(this->m_threadContext, gcTime);
  326. this->m_snapExtractor.DoMarkWalk(this->m_threadContext);
  327. ///////////////////////////
  328. //Phase 2: Evacuate marked objects
  329. //Allows for parallel execute and evacuate (in conjunction with later refactoring)
  330. this->m_snapExtractor.EvacuateMarkedIntoSnapshot(this->m_threadContext, liveTopLevelBodies);
  331. ///////////////////////////
  332. //Phase 3: Complete and return snapshot
  333. snap = this->m_snapExtractor.CompleteSnapshot();
  334. return snap;
  335. }
  336. void EventLog::ReplaySnapshotEvent()
  337. {
  338. SnapShot* snap = nullptr;
  339. try
  340. {
  341. AUTO_NESTED_HANDLED_EXCEPTION_TYPE((ExceptionType)(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));
  342. //clear the weak collection pin set and force a GC (to get weak containers in a consistent state)
  343. NSLogEvents::EventLogEntry* revt = this->m_currentReplayEventIterator.Current();
  344. NSLogEvents::SnapshotEventLogEntry* snapUpdateEvt = NSLogEvents::GetInlineEventDataAs<NSLogEvents::SnapshotEventLogEntry, NSLogEvents::EventKind::SnapshotTag>(revt);
  345. this->m_threadContext->TTDContext->SyncCtxtsAndRootsWithSnapshot_Replay(snapUpdateEvt->LiveContextCount, snapUpdateEvt->LiveContextIdArray, snapUpdateEvt->LongLivedRefRootsCount, snapUpdateEvt->LongLivedRefRootsIdArray);
  346. this->m_threadContext->GetRecycler()->CollectNow<CollectNowForceInThread>();
  347. //need to do a visit of some sort to reset the weak collection pin set
  348. this->m_snapExtractor.DoResetWeakCollectionPinSet(this->m_threadContext);
  349. //We always need to cleanup references (above but only do compare in extra diagnostics mode)
  350. #if ENABLE_SNAPSHOT_COMPARE
  351. this->SetSnapshotOrInflateInProgress(true);
  352. this->PushMode(TTDMode::ExcludedExecutionTTAction);
  353. JsUtil::BaseHashSet<Js::FunctionBody*, HeapAllocator> liveTopLevelBodies(&HeapAllocator::Instance);
  354. snap = this->DoSnapshotExtract_Helper(0.0, liveTopLevelBodies);
  355. for(int32 i = 0; i < this->m_threadContext->TTDContext->GetTTDContexts().Count(); ++i)
  356. {
  357. this->m_threadContext->TTDContext->GetTTDContexts().Item(i)->TTDContextInfo->CleanUnreachableTopLevelBodies(liveTopLevelBodies);
  358. }
  359. NSLogEvents::EventLogEntry* evt = this->m_currentReplayEventIterator.Current();
  360. NSLogEvents::SnapshotEventLogEntry_EnsureSnapshotDeserialized(evt, this->m_threadContext);
  361. const NSLogEvents::SnapshotEventLogEntry* recordedSnapEntry = NSLogEvents::GetInlineEventDataAs<NSLogEvents::SnapshotEventLogEntry, NSLogEvents::EventKind::SnapshotTag>(evt);
  362. const SnapShot* recordedSnap = recordedSnapEntry->Snap;
  363. TTDCompareMap compareMap(this->m_threadContext);
  364. SnapShot::InitializeForSnapshotCompare(recordedSnap, snap, compareMap);
  365. SnapShot::DoSnapshotCompare(recordedSnap, snap, compareMap);
  366. TT_HEAP_DELETE(SnapShot, snap);
  367. this->PopMode(TTDMode::ExcludedExecutionTTAction);
  368. this->SetSnapshotOrInflateInProgress(false);
  369. #endif
  370. }
  371. catch(...)
  372. {
  373. if(snap != nullptr)
  374. {
  375. TT_HEAP_DELETE(SnapShot, snap);
  376. }
  377. TTDAssert(false, "OOM in snapshot replay...");
  378. }
  379. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  380. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteLiteralMsg("---SNAPSHOT EVENT---\n");
  381. #endif
  382. this->AdvanceTimeAndPositionForReplay(); //move along
  383. }
  384. void EventLog::ReplayEventLoopYieldPointEvent()
  385. {
  386. try
  387. {
  388. AUTO_NESTED_HANDLED_EXCEPTION_TYPE((ExceptionType)(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));
  389. this->m_threadContext->TTDContext->ClearLocalRootsAndRefreshMap_Replay();
  390. }
  391. catch(...)
  392. {
  393. TTDAssert(false, "OOM in yield point replay...");
  394. }
  395. this->AdvanceTimeAndPositionForReplay(); //move along
  396. }
  397. void EventLog::AbortReplayReturnToHost()
  398. {
  399. throw TTDebuggerAbortException::CreateAbortEndOfLog(_u("End of log reached -- returning to top-level."));
  400. }
  401. void EventLog::InitializeEventListVTable()
  402. {
  403. this->m_eventListVTable = this->m_miscSlabAllocator.SlabAllocateArray<NSLogEvents::EventLogEntryVTableEntry>((uint32)NSLogEvents::EventKind::Count);
  404. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(SnapshotTag, GlobalAPIWrapper, SnapshotEventLogEntry, nullptr, NSLogEvents::SnapshotEventLogEntry_UnloadEventMemory, NSLogEvents::SnapshotEventLogEntry_Emit, NSLogEvents::SnapshotEventLogEntry_Parse);
  405. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(EventLoopYieldPointTag, GlobalAPIWrapper, EventLoopYieldPointEntry, nullptr, nullptr, NSLogEvents::EventLoopYieldPointEntry_Emit, NSLogEvents::EventLoopYieldPointEntry_Parse);
  406. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(TopLevelCodeTag, None, CodeLoadEventLogEntry, nullptr, nullptr, NSLogEvents::CodeLoadEventLogEntry_Emit, NSLogEvents::CodeLoadEventLogEntry_Parse);
  407. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(TelemetryLogTag, None, TelemetryEventLogEntry, nullptr, NSLogEvents::TelemetryEventLogEntry_UnloadEventMemory, NSLogEvents::TelemetryEventLogEntry_Emit, NSLogEvents::TelemetryEventLogEntry_Parse);
  408. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(DoubleTag, None, DoubleEventLogEntry, nullptr, nullptr, NSLogEvents::DoubleEventLogEntry_Emit, NSLogEvents::DoubleEventLogEntry_Parse);
  409. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(StringTag, None, StringValueEventLogEntry, nullptr, NSLogEvents::StringValueEventLogEntry_UnloadEventMemory, NSLogEvents::StringValueEventLogEntry_Emit, NSLogEvents::StringValueEventLogEntry_Parse);
  410. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(RandomSeedTag, None, RandomSeedEventLogEntry, nullptr, nullptr, NSLogEvents::RandomSeedEventLogEntry_Emit, NSLogEvents::RandomSeedEventLogEntry_Parse);
  411. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(PropertyEnumTag, None, PropertyEnumStepEventLogEntry, nullptr, NSLogEvents::PropertyEnumStepEventLogEntry_UnloadEventMemory, NSLogEvents::PropertyEnumStepEventLogEntry_Emit, NSLogEvents::PropertyEnumStepEventLogEntry_Parse);
  412. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(SymbolCreationTag, None, SymbolCreationEventLogEntry, nullptr, nullptr, NSLogEvents::SymbolCreationEventLogEntry_Emit, NSLogEvents::SymbolCreationEventLogEntry_Parse);
  413. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(WeakCollectionContainsTag, None, WeakCollectionContainsEventLogEntry, nullptr, nullptr, NSLogEvents::WeakCollectionContainsEventLogEntry_Emit, NSLogEvents::WeakCollectionContainsEventLogEntry_Parse);
  414. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(ExternalCbRegisterCall, None, ExternalCbRegisterCallEventLogEntry, nullptr, nullptr, NSLogEvents::ExternalCbRegisterCallEventLogEntry_Emit, NSLogEvents::ExternalCbRegisterCallEventLogEntry_Parse);
  415. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(ExternalCallTag, None, ExternalCallEventLogEntry, nullptr, NSLogEvents::ExternalCallEventLogEntry_UnloadEventMemory, NSLogEvents::ExternalCallEventLogEntry_Emit, NSLogEvents::ExternalCallEventLogEntry_Parse);
  416. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(ExplicitLogWriteTag, None, ExplicitLogWriteEventLogEntry, nullptr, nullptr, NSLogEvents::ExplicitLogWriteEntry_Emit, NSLogEvents::ExplicitLogWriteEntry_Parse);
  417. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(TTDInnerLoopLogWriteTag, None, TTDInnerLoopLogWriteEventLogEntry, nullptr, nullptr, NSLogEvents::TTDInnerLoopLogWriteEventLogEntry_Emit, NSLogEvents::TTDInnerLoopLogWriteEventLogEntry_Parse);
  418. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(TTDFetchAutoTraceStatusTag, None, TTDFetchAutoTraceStatusEventLogEntry, nullptr, nullptr, NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry_Emit, NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry_Parse);
  419. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(CreateScriptContextActionTag, GlobalAPIWrapper, JsRTCreateScriptContextAction, NSLogEvents::CreateScriptContext_Execute, NSLogEvents::CreateScriptContext_UnloadEventMemory, NSLogEvents::CreateScriptContext_Emit, NSLogEvents::CreateScriptContext_Parse);
  420. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(SetActiveScriptContextActionTag, GlobalAPIWrapper, JsRTSingleVarArgumentAction, SetActiveScriptContext_Execute);
  421. #if !INT32VAR
  422. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(CreateIntegerActionTag, ContextAPINoScriptWrapper, JsRTIntegralArgumentAction, CreateInt_Execute);
  423. #endif
  424. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(CreateNumberActionTag, ContextAPINoScriptWrapper, JsRTDoubleArgumentAction, NSLogEvents::CreateNumber_Execute, nullptr, NSLogEvents::JsRTDoubleArgumentAction_Emit<NSLogEvents::EventKind::CreateNumberActionTag>, NSLogEvents::JsRTDoubleArgumentAction_Parse<NSLogEvents::EventKind::CreateNumberActionTag>);
  425. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(CreateBooleanActionTag, ContextAPINoScriptWrapper, JsRTIntegralArgumentAction, CreateBoolean_Execute);
  426. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(CreateStringActionTag, ContextAPINoScriptWrapper, JsRTStringArgumentAction, NSLogEvents::CreateString_Execute, NSLogEvents::JsRTStringArgumentAction_UnloadEventMemory<NSLogEvents::EventKind::CreateStringActionTag>, NSLogEvents::JsRTStringArgumentAction_Emit<NSLogEvents::EventKind::CreateStringActionTag>, NSLogEvents::JsRTStringArgumentAction_Parse<NSLogEvents::EventKind::CreateStringActionTag>);
  427. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(CreateSymbolActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, CreateSymbol_Execute);
  428. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(CreateErrorActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, CreateError_Execute<NSLogEvents::EventKind::CreateErrorActionTag>);
  429. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(CreateRangeErrorActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, CreateError_Execute<NSLogEvents::EventKind::CreateRangeErrorActionTag>);
  430. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(CreateReferenceErrorActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, CreateError_Execute<NSLogEvents::EventKind::CreateReferenceErrorActionTag>);
  431. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(CreateSyntaxErrorActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, CreateError_Execute<NSLogEvents::EventKind::CreateSyntaxErrorActionTag>);
  432. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(CreateTypeErrorActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, CreateError_Execute<NSLogEvents::EventKind::CreateTypeErrorActionTag>);
  433. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(CreateURIErrorActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, CreateError_Execute<NSLogEvents::EventKind::CreateURIErrorActionTag>);
  434. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(VarConvertToNumberActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, VarConvertToNumber_Execute);
  435. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(VarConvertToBooleanActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, VarConvertToBoolean_Execute);
  436. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(VarConvertToStringActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, VarConvertToString_Execute);
  437. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(VarConvertToObjectActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, VarConvertToObject_Execute);
  438. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(AddRootRefActionTag, GlobalAPIWrapper, JsRTSingleVarArgumentAction, AddRootRef_Execute);
  439. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(AddWeakRootRefActionTag, GlobalAPIWrapper, JsRTSingleVarArgumentAction, AddWeakRootRef_Execute);
  440. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(AllocateObjectActionTag, ContextAPINoScriptWrapper, JsRTResultOnlyAction, AllocateObject_Execute);
  441. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(AllocateExternalObjectActionTag, ContextAPINoScriptWrapper, JsRTSingleVarArgumentAction, AllocateExternalObject_Execute);
  442. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(AllocateArrayActionTag, ContextAPINoScriptWrapper, JsRTIntegralArgumentAction, AllocateArrayAction_Execute);
  443. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(AllocateArrayBufferActionTag, ContextAPIWrapper, JsRTIntegralArgumentAction, AllocateArrayBufferAction_Execute);
  444. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(AllocateExternalArrayBufferActionTag, ContextAPINoScriptWrapper, JsRTByteBufferAction, NSLogEvents::AllocateExternalArrayBufferAction_Execute, NSLogEvents::JsRTByteBufferAction_UnloadEventMemory<NSLogEvents::EventKind::AllocateExternalArrayBufferActionTag>, NSLogEvents::JsRTByteBufferAction_Emit<NSLogEvents::EventKind::AllocateExternalArrayBufferActionTag>, NSLogEvents::JsRTByteBufferAction_Parse<NSLogEvents::EventKind::AllocateExternalArrayBufferActionTag>);
  445. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(AllocateFunctionActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, AllocateFunctionAction_Execute);
  446. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(HostExitProcessTag, ContextAPIWrapper, JsRTIntegralArgumentAction, HostProcessExitAction_Execute);
  447. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetAndClearExceptionWithMetadataActionTag, None, JsRTResultOnlyAction, GetAndClearExceptionWithMetadataAction_Execute);
  448. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetAndClearExceptionActionTag, None, JsRTResultOnlyAction, GetAndClearExceptionAction_Execute);
  449. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(SetExceptionActionTag, ContextAPINoScriptWrapper, JsRTSingleVarScalarArgumentAction, SetExceptionAction_Execute);
  450. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(HasPropertyActionTag, ContextAPIWrapper, JsRTSingleVarScalarArgumentAction, HasPropertyAction_Execute);
  451. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(HasOwnPropertyActionTag, ContextAPIWrapper, JsRTSingleVarScalarArgumentAction, HasOwnPropertyAction_Execute);
  452. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(InstanceOfActionTag, ContextAPIWrapper, JsRTDoubleVarArgumentAction, InstanceOfAction_Execute);
  453. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(EqualsActionTag, ContextAPIWrapper, JsRTDoubleVarSingleScalarArgumentAction, EqualsAction_Execute);
  454. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(LessThanActionTag, ContextAPIWrapper, JsRTDoubleVarSingleScalarArgumentAction, LessThanAction_Execute);
  455. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetPropertyIdFromSymbolTag, ContextAPINoScriptWrapper, JsRTSingleVarArgumentAction, GetPropertyIdFromSymbolAction_Execute);
  456. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetPrototypeActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, GetPrototypeAction_Execute);
  457. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetPropertyActionTag, ContextAPIWrapper, JsRTSingleVarScalarArgumentAction, GetPropertyAction_Execute);
  458. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetIndexActionTag, ContextAPIWrapper, JsRTDoubleVarArgumentAction, GetIndexAction_Execute);
  459. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetOwnPropertyInfoActionTag, ContextAPIWrapper, JsRTSingleVarScalarArgumentAction, GetOwnPropertyInfoAction_Execute);
  460. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetOwnPropertyNamesInfoActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, GetOwnPropertyNamesInfoAction_Execute);
  461. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetOwnPropertySymbolsInfoActionTag, ContextAPIWrapper, JsRTSingleVarArgumentAction, GetOwnPropertySymbolsInfoAction_Execute);
  462. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(DefinePropertyActionTag, ContextAPIWrapper, JsRTDoubleVarSingleScalarArgumentAction, DefinePropertyAction_Execute);
  463. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(DeletePropertyActionTag, ContextAPIWrapper, JsRTSingleVarDoubleScalarArgumentAction, DeletePropertyAction_Execute);
  464. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(SetPrototypeActionTag, ContextAPIWrapper, JsRTDoubleVarArgumentAction, SetPrototypeAction_Execute);
  465. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(SetPropertyActionTag, ContextAPIWrapper, JsRTDoubleVarDoubleScalarArgumentAction, SetPropertyAction_Execute);
  466. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(SetIndexActionTag, ContextAPIWrapper, JsRTTrippleVarArgumentAction, SetIndexAction_Execute);
  467. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetTypedArrayInfoActionTag, None, JsRTSingleVarArgumentAction, GetTypedArrayInfoAction_Execute);
  468. TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetDataViewInfoActionTag, None, JsRTSingleVarArgumentAction, GetDataViewInfoAction_Execute);
  469. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(RawBufferCopySync, ContextAPIWrapper, JsRTRawBufferCopyAction, NSLogEvents::RawBufferCopySync_Execute, nullptr, NSLogEvents::JsRTRawBufferCopyAction_Emit, NSLogEvents::JsRTRawBufferCopyAction_Parse);
  470. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(RawBufferModifySync, ContextAPIWrapper, JsRTRawBufferModifyAction, NSLogEvents::RawBufferModifySync_Execute, NSLogEvents::JsRTRawBufferModifyAction_UnloadEventMemory<NSLogEvents::EventKind::RawBufferModifySync>, NSLogEvents::JsRTRawBufferModifyAction_Emit<NSLogEvents::EventKind::RawBufferModifySync>, NSLogEvents::JsRTRawBufferModifyAction_Parse<NSLogEvents::EventKind::RawBufferModifySync>);
  471. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(RawBufferAsyncModificationRegister, ContextAPIWrapper, JsRTRawBufferModifyAction, NSLogEvents::RawBufferAsyncModificationRegister_Execute, NSLogEvents::JsRTRawBufferModifyAction_UnloadEventMemory<NSLogEvents::EventKind::RawBufferAsyncModificationRegister>, NSLogEvents::JsRTRawBufferModifyAction_Emit<NSLogEvents::EventKind::RawBufferAsyncModificationRegister>, NSLogEvents::JsRTRawBufferModifyAction_Parse<NSLogEvents::EventKind::RawBufferAsyncModificationRegister>);
  472. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(RawBufferAsyncModifyComplete, ContextAPIWrapper, JsRTRawBufferModifyAction, NSLogEvents::RawBufferAsyncModifyComplete_Execute, NSLogEvents::JsRTRawBufferModifyAction_UnloadEventMemory<NSLogEvents::EventKind::RawBufferAsyncModifyComplete>, NSLogEvents::JsRTRawBufferModifyAction_Emit<NSLogEvents::EventKind::RawBufferAsyncModifyComplete>, NSLogEvents::JsRTRawBufferModifyAction_Parse<NSLogEvents::EventKind::RawBufferAsyncModifyComplete>);
  473. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(ConstructCallActionTag, ContextAPIWrapper, JsRTConstructCallAction, NSLogEvents::JsRTConstructCallAction_Execute, NSLogEvents::JsRTConstructCallAction_UnloadEventMemory, NSLogEvents::JsRTConstructCallAction_Emit, NSLogEvents::JsRTConstructCallAction_Parse);
  474. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(CodeParseActionTag, ContextAPINoScriptWrapper, JsRTCodeParseAction, NSLogEvents::JsRTCodeParseAction_Execute, NSLogEvents::JsRTCodeParseAction_UnloadEventMemory, NSLogEvents::JsRTCodeParseAction_Emit, NSLogEvents::JsRTCodeParseAction_Parse);
  475. TTD_CREATE_EVENTLIST_VTABLE_ENTRY(CallExistingFunctionActionTag, ContextAPIWrapper, JsRTCallFunctionAction, NSLogEvents::JsRTCallFunctionAction_Execute, NSLogEvents::JsRTCallFunctionAction_UnloadEventMemory, NSLogEvents::JsRTCallFunctionAction_Emit, NSLogEvents::JsRTCallFunctionAction_Parse);
  476. }
  477. EventLog::EventLog(ThreadContext* threadContext)
  478. : m_threadContext(threadContext), m_eventSlabAllocator(TTD_SLAB_BLOCK_ALLOCATION_SIZE_MID), m_miscSlabAllocator(TTD_SLAB_BLOCK_ALLOCATION_SIZE_SMALL),
  479. m_eventTimeCtr(0), m_timer(), m_topLevelCallbackEventTime(-1),
  480. m_eventListVTable(nullptr), m_eventList(&this->m_eventSlabAllocator), m_currentReplayEventIterator(),
  481. m_modeStack(), m_currentMode(TTDMode::Invalid), m_autoTracesEnabled(true),
  482. m_snapExtractor(), m_elapsedExecutionTimeSinceSnapshot(0.0),
  483. m_lastInflateSnapshotTime(-1), m_lastInflateMap(nullptr), m_propertyRecordList(&this->m_miscSlabAllocator),
  484. m_sourceInfoCount(0), m_loadedTopLevelScripts(&this->m_miscSlabAllocator), m_newFunctionTopLevelScripts(&this->m_miscSlabAllocator), m_evalTopLevelScripts(&this->m_miscSlabAllocator)
  485. {
  486. this->InitializeEventListVTable();
  487. this->m_eventList.SetVTable(this->m_eventListVTable);
  488. this->m_modeStack.Push(TTDMode::Invalid);
  489. Recycler * recycler = threadContext->GetRecycler();
  490. this->m_propertyRecordPinSet.Root(RecyclerNew(recycler, PropertyRecordPinSet, recycler), recycler);
  491. }
  492. EventLog::~EventLog()
  493. {
  494. this->m_eventList.UnloadEventList();
  495. if(this->m_lastInflateMap != nullptr)
  496. {
  497. TT_HEAP_DELETE(InflateMap, this->m_lastInflateMap);
  498. this->m_lastInflateMap = nullptr;
  499. }
  500. if(this->m_propertyRecordPinSet != nullptr)
  501. {
  502. this->m_propertyRecordPinSet.Unroot(this->m_propertyRecordPinSet->GetAllocator());
  503. }
  504. }
  505. void EventLog::UnloadAllLogData()
  506. {
  507. this->m_eventList.UnloadEventList();
  508. }
  509. void EventLog::InitForTTDRecord(bool debug)
  510. {
  511. //pin all the current properties so they don't move/disappear on us
  512. for(Js::PropertyId pid = TotalNumberOfBuiltInProperties; pid < this->m_threadContext->GetMaxPropertyId(); ++pid)
  513. {
  514. const Js::PropertyRecord* pRecord = this->m_threadContext->GetPropertyName(pid);
  515. this->AddPropertyRecord(pRecord);
  516. }
  517. this->SetGlobalMode(TTDMode::RecordMode);
  518. if (debug)
  519. {
  520. this->PushMode(TTDMode::DebuggerAttachedMode);
  521. }
  522. }
  523. void EventLog::InitForTTDReplay(TTDataIOInfo& iofp, const char* parseUri, size_t parseUriLength, bool debug)
  524. {
  525. this->SetGlobalMode(TTDMode::ReplayMode);
  526. if (debug)
  527. {
  528. this->PushMode(TTDMode::DebuggerAttachedMode);
  529. }
  530. this->ParseLogInto(iofp, parseUri, parseUriLength);
  531. Js::PropertyId maxPid = TotalNumberOfBuiltInProperties + 1;
  532. JsUtil::BaseDictionary<Js::PropertyId, NSSnapType::SnapPropertyRecord*, HeapAllocator> pidMap(&HeapAllocator::Instance);
  533. for(auto iter = this->m_propertyRecordList.GetIterator(); iter.IsValid(); iter.MoveNext())
  534. {
  535. maxPid = max(maxPid, iter.Current()->PropertyId);
  536. pidMap.AddNew(iter.Current()->PropertyId, iter.Current());
  537. }
  538. for(Js::PropertyId cpid = TotalNumberOfBuiltInProperties; cpid <= maxPid; ++cpid)
  539. {
  540. NSSnapType::SnapPropertyRecord* spRecord = pidMap.Item(cpid);
  541. const Js::PropertyRecord* newPropertyRecord = NSSnapType::InflatePropertyRecord(spRecord, this->m_threadContext);
  542. if(!this->m_propertyRecordPinSet->ContainsKey(const_cast<Js::PropertyRecord*>(newPropertyRecord)))
  543. {
  544. this->m_propertyRecordPinSet->AddNew(const_cast<Js::PropertyRecord*>(newPropertyRecord));
  545. }
  546. }
  547. }
  548. void EventLog::LoadLastSourceLineInfo(TTInnerLoopLastStatementInfo& lsi, TTD::TTDebuggerSourceLocation& dsl) const
  549. {
  550. auto iter = this->m_eventList.GetIteratorAtLast_ReplayOnly();
  551. if(iter.IsValid() && iter.Current()->EventKind == NSLogEvents::EventKind::TTDInnerLoopLogWriteTag)
  552. {
  553. const NSLogEvents::TTDInnerLoopLogWriteEventLogEntry* ilevt = NSLogEvents::GetInlineEventDataAs<NSLogEvents::TTDInnerLoopLogWriteEventLogEntry, NSLogEvents::EventKind::TTDInnerLoopLogWriteTag>(iter.Current());
  554. lsi.SetLastLine(ilevt->EventTime, ilevt->FunctionTime, ilevt->LoopTime, ilevt->Line, ilevt->Column);
  555. dsl.SetLocationFullRaw(ilevt->SourceScriptLogId, ilevt->EventTime, ilevt->FunctionTime, ilevt->LoopTime, ilevt->TopLevelBodyId, ilevt->FunctionLine, ilevt->FunctionColumn, ilevt->Line, ilevt->Column);
  556. }
  557. }
  558. void EventLog::SetGlobalMode(TTDMode m)
  559. {
  560. TTDAssert(m == TTDMode::RecordMode || m == TTDMode::ReplayMode, "These are the only valid global modes");
  561. this->m_modeStack.SetAt(0, m);
  562. this->UpdateComputedMode();
  563. }
  564. void EventLog::SetSnapshotOrInflateInProgress(bool flag)
  565. {
  566. const JsUtil::List<Js::ScriptContext*, HeapAllocator>& contexts = this->m_threadContext->TTDContext->GetTTDContexts();
  567. for(int32 i = 0; i < contexts.Count(); ++i)
  568. {
  569. TTDAssert(contexts.Item(i)->TTDSnapshotOrInflateInProgress != flag, "This is not re-entrant!!!");
  570. contexts.Item(i)->TTDSnapshotOrInflateInProgress = flag;
  571. }
  572. }
  573. void EventLog::PushMode(TTDMode m)
  574. {
  575. TTDAssert(m == TTDMode::DebuggerAttachedMode || m == TTDMode::CurrentlyEnabled || m == TTDMode::ExcludedExecutionTTAction || m == TTDMode::ExcludedExecutionDebuggerAction ||
  576. m == TTDMode::DebuggerSuppressGetter || m == TTDMode::DebuggerSuppressBreakpoints || m == TTDMode::DebuggerLogBreakpoints, "These are the only valid mode modifiers to push");
  577. this->m_modeStack.Push(m);
  578. this->UpdateComputedMode();
  579. }
  580. void EventLog::PopMode(TTDMode m)
  581. {
  582. TTDAssert(m == TTDMode::DebuggerAttachedMode || m == TTDMode::CurrentlyEnabled || m == TTDMode::ExcludedExecutionTTAction || m == TTDMode::ExcludedExecutionDebuggerAction ||
  583. m == TTDMode::DebuggerSuppressGetter || m == TTDMode::DebuggerSuppressBreakpoints || m == TTDMode::DebuggerLogBreakpoints, "These are the only valid mode modifiers to pop");
  584. TTDAssert(this->m_modeStack.Peek() == m, "Push/Pop is not matched so something went wrong.");
  585. this->m_modeStack.Pop();
  586. this->UpdateComputedMode();
  587. }
  588. TTDMode EventLog::GetCurrentTTDMode() const
  589. {
  590. return this->m_currentMode;
  591. }
  592. void EventLog::SetModeFlagsOnContext(Js::ScriptContext* ctx)
  593. {
  594. TTDMode cm = this->m_currentMode;
  595. ctx->TTDRecordModeEnabled = (cm & (TTDMode::RecordMode | TTDMode::AnyExcludedMode)) == TTDMode::RecordMode;
  596. ctx->TTDReplayModeEnabled = (cm & (TTDMode::ReplayMode | TTDMode::AnyExcludedMode)) == TTDMode::ReplayMode;
  597. ctx->TTDRecordOrReplayModeEnabled = (ctx->TTDRecordModeEnabled | ctx->TTDReplayModeEnabled);
  598. ctx->TTDShouldPerformRecordAction = (cm & (TTDMode::RecordMode | TTDMode::CurrentlyEnabled | TTDMode::AnyExcludedMode)) == (TTDMode::RecordMode | TTDMode::CurrentlyEnabled);
  599. ctx->TTDShouldPerformReplayAction = (cm & (TTDMode::ReplayMode | TTDMode::CurrentlyEnabled | TTDMode::AnyExcludedMode)) == (TTDMode::ReplayMode | TTDMode::CurrentlyEnabled);
  600. ctx->TTDShouldPerformRecordOrReplayAction = (ctx->TTDShouldPerformRecordAction | ctx->TTDShouldPerformReplayAction);
  601. ctx->TTDShouldPerformRecordDebuggerAction = (cm & (TTDMode::RecordDebuggerMode | TTDMode::CurrentlyEnabled | TTDMode::AnyExcludedMode)) == (TTDMode::RecordDebuggerMode | TTDMode::CurrentlyEnabled);
  602. ctx->TTDShouldPerformReplayDebuggerAction = (cm & ( TTDMode::ReplayDebuggerMode | TTDMode::CurrentlyEnabled | TTDMode::AnyExcludedMode)) == (TTDMode::ReplayDebuggerMode | TTDMode::CurrentlyEnabled);
  603. ctx->TTDShouldPerformRecordOrReplayDebuggerAction = (ctx->TTDShouldPerformRecordDebuggerAction | ctx->TTDShouldPerformReplayDebuggerAction);
  604. ctx->TTDShouldSuppressGetterInvocationForDebuggerEvaluation = (cm & TTDMode::DebuggerSuppressGetter) == TTDMode::DebuggerSuppressGetter;
  605. }
  606. void EventLog::GetModesForExplicitContextCreate(bool& inRecord, bool& activelyRecording, bool& inReplay)
  607. {
  608. inRecord = (this->m_currentMode & (TTDMode::RecordMode | TTDMode::AnyExcludedMode)) == TTDMode::RecordMode;
  609. activelyRecording = (this->m_currentMode & (TTDMode::RecordMode | TTDMode::CurrentlyEnabled | TTDMode::AnyExcludedMode)) == (TTDMode::RecordMode | TTDMode::CurrentlyEnabled);
  610. inReplay = (this->m_currentMode & (TTDMode::ReplayMode | TTDMode::AnyExcludedMode)) == TTDMode::ReplayMode;
  611. }
  612. bool EventLog::IsDebugModeFlagSet() const
  613. {
  614. return (this->m_currentMode & TTDMode::DebuggerAttachedMode) == TTDMode::DebuggerAttachedMode;
  615. }
  616. void EventLog::AddPropertyRecord(const Js::PropertyRecord* record)
  617. {
  618. this->m_propertyRecordPinSet->AddNew(const_cast<Js::PropertyRecord*>(record));
  619. }
  620. const NSSnapValues::TopLevelScriptLoadFunctionBodyResolveInfo* EventLog::AddScriptLoad(Js::FunctionBody* fb, Js::ModuleID moduleId, uint64 sourceContextId, const byte* source, uint32 sourceLen, LoadScriptFlag loadFlag)
  621. {
  622. NSSnapValues::TopLevelScriptLoadFunctionBodyResolveInfo* fbInfo = this->m_loadedTopLevelScripts.NextOpenEntry();
  623. uint32 fCount = (this->m_loadedTopLevelScripts.Count() + this->m_newFunctionTopLevelScripts.Count() + this->m_evalTopLevelScripts.Count());
  624. bool isUtf8 = ((loadFlag & LoadScriptFlag_Utf8Source) == LoadScriptFlag_Utf8Source);
  625. NSSnapValues::ExtractTopLevelLoadedFunctionBodyInfo(fbInfo, fb, fCount, moduleId, sourceContextId, isUtf8, source, sourceLen, loadFlag, this->m_miscSlabAllocator);
  626. this->m_sourceInfoCount = max(this->m_sourceInfoCount, fb->GetUtf8SourceInfo()->GetSourceInfoId() + 1);
  627. return fbInfo;
  628. }
  629. const NSSnapValues::TopLevelNewFunctionBodyResolveInfo* EventLog::AddNewFunction(Js::FunctionBody* fb, Js::ModuleID moduleId, const char16* source, uint32 sourceLen)
  630. {
  631. NSSnapValues::TopLevelNewFunctionBodyResolveInfo* fbInfo = this->m_newFunctionTopLevelScripts.NextOpenEntry();
  632. uint32 fCount = (this->m_loadedTopLevelScripts.Count() + this->m_newFunctionTopLevelScripts.Count() + this->m_evalTopLevelScripts.Count());
  633. NSSnapValues::ExtractTopLevelNewFunctionBodyInfo(fbInfo, fb, fCount, moduleId, source, sourceLen, this->m_miscSlabAllocator);
  634. this->m_sourceInfoCount = max(this->m_sourceInfoCount, fb->GetUtf8SourceInfo()->GetSourceInfoId() + 1);
  635. return fbInfo;
  636. }
  637. const NSSnapValues::TopLevelEvalFunctionBodyResolveInfo* EventLog::AddEvalFunction(Js::FunctionBody* fb, Js::ModuleID moduleId, const char16* source, uint32 sourceLen, uint32 grfscr, bool registerDocument, BOOL isIndirect, BOOL strictMode)
  638. {
  639. NSSnapValues::TopLevelEvalFunctionBodyResolveInfo* fbInfo = this->m_evalTopLevelScripts.NextOpenEntry();
  640. uint32 fCount = (this->m_loadedTopLevelScripts.Count() + this->m_newFunctionTopLevelScripts.Count() + this->m_evalTopLevelScripts.Count());
  641. NSSnapValues::ExtractTopLevelEvalFunctionBodyInfo(fbInfo, fb, fCount, moduleId, source, sourceLen, grfscr, registerDocument, isIndirect, strictMode, this->m_miscSlabAllocator);
  642. this->m_sourceInfoCount = max(this->m_sourceInfoCount, fb->GetUtf8SourceInfo()->GetSourceInfoId() + 1);
  643. return fbInfo;
  644. }
  645. uint32 EventLog::GetSourceInfoCount() const
  646. {
  647. return this->m_sourceInfoCount;
  648. }
  649. void EventLog::RecordTopLevelCodeAction(uint32 bodyCtrId)
  650. {
  651. NSLogEvents::CodeLoadEventLogEntry* clEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::CodeLoadEventLogEntry, NSLogEvents::EventKind::TopLevelCodeTag>();
  652. clEvent->BodyCounterId = bodyCtrId;
  653. }
  654. uint32 EventLog::ReplayTopLevelCodeAction()
  655. {
  656. const NSLogEvents::CodeLoadEventLogEntry* clEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::CodeLoadEventLogEntry, NSLogEvents::EventKind::TopLevelCodeTag>();
  657. return clEvent->BodyCounterId;
  658. }
  659. void EventLog::RecordTelemetryLogEvent(Js::JavascriptString* infoStringJs, bool doPrint)
  660. {
  661. NSLogEvents::TelemetryEventLogEntry* tEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::TelemetryEventLogEntry, NSLogEvents::EventKind::TelemetryLogTag>();
  662. this->m_eventSlabAllocator.CopyStringIntoWLength(infoStringJs->GetString(), infoStringJs->GetLength(), tEvent->InfoString);
  663. tEvent->DoPrint = doPrint;
  664. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  665. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->ForceFlush();
  666. #endif
  667. }
  668. void EventLog::ReplayTelemetryLogEvent(Js::JavascriptString* infoStringJs)
  669. {
  670. #if !ENABLE_TTD_INTERNAL_DIAGNOSTICS
  671. this->AdvanceTimeAndPositionForReplay(); //just eat the telemetry event
  672. #else
  673. const NSLogEvents::TelemetryEventLogEntry* tEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::TelemetryEventLogEntry, NSLogEvents::EventKind::TelemetryLogTag>();
  674. uint32 infoStrLength = (uint32)infoStringJs->GetLength();
  675. const char16* infoStr = infoStringJs->GetSz();
  676. if(tEvent->InfoString.Length != infoStrLength)
  677. {
  678. Output::Print(_u("New Telemetry Msg: %ls\n"), infoStr);
  679. Output::Print(_u("Original Telemetry Msg: %ls\n"), tEvent->InfoString.Contents);
  680. TTDAssert(false, "Telemetry messages differ??");
  681. }
  682. else
  683. {
  684. for(uint32 i = 0; i < infoStrLength; ++i)
  685. {
  686. if(tEvent->InfoString.Contents[i] != infoStr[i])
  687. {
  688. Output::Print(_u("New Telemetry Msg: %ls\n"), infoStr);
  689. Output::Print(_u("Original Telemetry Msg: %ls\n"), tEvent->InfoString.Contents);
  690. TTDAssert(false, "Telemetry messages differ??");
  691. break;
  692. }
  693. }
  694. }
  695. #endif
  696. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  697. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->ForceFlush();
  698. #endif
  699. }
  700. void EventLog::RecordEmitLogEvent(Js::JavascriptString* uriString)
  701. {
  702. this->RecordGetInitializedEvent_DataOnly<NSLogEvents::ExplicitLogWriteEventLogEntry, NSLogEvents::EventKind::ExplicitLogWriteTag>();
  703. size_t cbUri = UInt32Math::Mul<3>(uriString->GetLength());
  704. AutoArrayPtr<char> uri(HeapNewArrayZ(char, cbUri), cbUri);
  705. size_t uriLength = utf8::EncodeInto<utf8::Utf8EncodingKind::Cesu8>((LPUTF8)((char*)uri), cbUri, uriString->GetString(), uriString->GetLength());
  706. this->EmitLog(uri, uriLength);
  707. }
  708. void EventLog::ReplayEmitLogEvent()
  709. {
  710. this->ReplayGetReplayEvent_Helper<NSLogEvents::ExplicitLogWriteEventLogEntry, NSLogEvents::EventKind::ExplicitLogWriteTag>();
  711. //check if at end of log -- if so we are done and don't want to execute any more
  712. if(!this->m_currentReplayEventIterator.IsValid())
  713. {
  714. this->AbortReplayReturnToHost();
  715. }
  716. }
  717. void EventLog::RecordTTDFetchAutoTraceStatusEvent(bool status)
  718. {
  719. NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry* atfEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry, NSLogEvents::EventKind::TTDFetchAutoTraceStatusTag>();
  720. atfEvent->IsEnabled = status;
  721. }
  722. bool EventLog::ReplayTTDFetchAutoTraceStatusLogEvent()
  723. {
  724. const NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry* atfEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry, NSLogEvents::EventKind::TTDFetchAutoTraceStatusTag>();
  725. return atfEvent->IsEnabled;
  726. }
  727. void EventLog::RecordDateTimeEvent(double time)
  728. {
  729. NSLogEvents::DoubleEventLogEntry* dEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::DoubleEventLogEntry, NSLogEvents::EventKind::DoubleTag>();
  730. dEvent->DoubleValue = time;
  731. }
  732. void EventLog::RecordDateStringEvent(Js::JavascriptString* stringValue)
  733. {
  734. NSLogEvents::StringValueEventLogEntry* sEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::StringValueEventLogEntry, NSLogEvents::EventKind::StringTag>();
  735. this->m_eventSlabAllocator.CopyStringIntoWLength(stringValue->GetString(), stringValue->GetLength(), sEvent->StringValue);
  736. }
  737. void EventLog::ReplayDateTimeEvent(double* result)
  738. {
  739. const NSLogEvents::DoubleEventLogEntry* dEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::DoubleEventLogEntry, NSLogEvents::EventKind::DoubleTag>();
  740. *result = dEvent->DoubleValue;
  741. }
  742. void EventLog::ReplayDateStringEvent(Js::ScriptContext* ctx, Js::JavascriptString** result)
  743. {
  744. const NSLogEvents::StringValueEventLogEntry* sEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::StringValueEventLogEntry, NSLogEvents::EventKind::StringTag>();
  745. const TTString& str = sEvent->StringValue;
  746. *result = Js::JavascriptString::NewCopyBuffer(str.Contents, str.Length, ctx);
  747. }
  748. void EventLog::RecordExternalEntropyRandomEvent(uint64 seed0, uint64 seed1)
  749. {
  750. NSLogEvents::RandomSeedEventLogEntry* rsEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::RandomSeedEventLogEntry, NSLogEvents::EventKind::RandomSeedTag>();
  751. rsEvent->Seed0 = seed0;
  752. rsEvent->Seed1 = seed1;
  753. }
  754. void EventLog::ReplayExternalEntropyRandomEvent(uint64* seed0, uint64* seed1)
  755. {
  756. const NSLogEvents::RandomSeedEventLogEntry* rsEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::RandomSeedEventLogEntry, NSLogEvents::EventKind::RandomSeedTag>();
  757. *seed0 = rsEvent->Seed0;
  758. *seed1 = rsEvent->Seed1;
  759. }
  760. void EventLog::RecordPropertyEnumEvent(BOOL returnCode, Js::PropertyId pid, Js::PropertyAttributes attributes, Js::JavascriptString* propertyName)
  761. {
  762. //When we replay we can just skip this pid cause it should never matter -- but if return code is false then we need to record the "at end" info
  763. if(returnCode && Js::IsInternalPropertyId(pid))
  764. {
  765. return;
  766. }
  767. NSLogEvents::PropertyEnumStepEventLogEntry* peEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::PropertyEnumStepEventLogEntry, NSLogEvents::EventKind::PropertyEnumTag>();
  768. peEvent->ReturnCode = returnCode;
  769. peEvent->Pid = pid;
  770. peEvent->Attributes = attributes;
  771. InitializeAsNullPtrTTString(peEvent->PropertyString);
  772. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  773. if(returnCode)
  774. {
  775. this->m_eventSlabAllocator.CopyStringIntoWLength(propertyName->GetString(), propertyName->GetLength(), peEvent->PropertyString);
  776. }
  777. #else
  778. if(returnCode && pid == Js::Constants::NoProperty)
  779. {
  780. this->m_eventSlabAllocator.CopyStringIntoWLength(propertyName->GetString(), propertyName->GetLength(), peEvent->PropertyString);
  781. }
  782. #endif
  783. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  784. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteEnumAction(this->m_eventTimeCtr - 1, returnCode, pid, attributes, propertyName);
  785. #endif
  786. }
  787. void EventLog::ReplayPropertyEnumEvent(Js::ScriptContext* requestContext, BOOL* returnCode, Js::BigPropertyIndex* newIndex, const Js::DynamicObject* obj, Js::PropertyId* pid, Js::PropertyAttributes* attributes, Js::JavascriptString** propertyName)
  788. {
  789. const NSLogEvents::PropertyEnumStepEventLogEntry* peEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::PropertyEnumStepEventLogEntry, NSLogEvents::EventKind::PropertyEnumTag>();
  790. *returnCode = peEvent->ReturnCode;
  791. *pid = peEvent->Pid;
  792. *attributes = peEvent->Attributes;
  793. if(*returnCode)
  794. {
  795. TTDAssert(*pid != Js::Constants::NoProperty, "This is so weird we need to figure out what this means.");
  796. TTDAssert(!Js::IsInternalPropertyId(*pid), "We should skip recording this.");
  797. Js::PropertyString* propertyString = requestContext->GetPropertyString(*pid);
  798. *propertyName = propertyString;
  799. const Js::PropertyRecord* pRecord = requestContext->GetPropertyName(*pid);
  800. *newIndex = obj->GetDynamicType()->GetTypeHandler()->GetPropertyIndex_EnumerateTTD(pRecord);
  801. TTDAssert(*newIndex != Js::Constants::NoBigSlot, "If *returnCode is true then we found it during record -- but missing in replay.");
  802. }
  803. else
  804. {
  805. *propertyName = nullptr;
  806. *newIndex = obj->GetDynamicType()->GetTypeHandler()->GetPropertyCount();
  807. }
  808. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  809. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteEnumAction(this->m_eventTimeCtr - 1, *returnCode, *pid, *attributes, *propertyName);
  810. #endif
  811. }
  812. void EventLog::RecordSymbolCreationEvent(Js::PropertyId pid)
  813. {
  814. NSLogEvents::SymbolCreationEventLogEntry* scEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::SymbolCreationEventLogEntry, NSLogEvents::EventKind::SymbolCreationTag>();
  815. scEvent->Pid = pid;
  816. }
  817. void EventLog::ReplaySymbolCreationEvent(Js::PropertyId* pid)
  818. {
  819. const NSLogEvents::SymbolCreationEventLogEntry* scEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::SymbolCreationEventLogEntry, NSLogEvents::EventKind::SymbolCreationTag>();
  820. *pid = scEvent->Pid;
  821. }
  822. void EventLog::RecordWeakCollectionContainsEvent(bool contains)
  823. {
  824. NSLogEvents::WeakCollectionContainsEventLogEntry* wcEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::WeakCollectionContainsEventLogEntry, NSLogEvents::EventKind::WeakCollectionContainsTag>();
  825. wcEvent->ContainsValue = contains;
  826. }
  827. bool EventLog::ReplayWeakCollectionContainsEvent()
  828. {
  829. const NSLogEvents::WeakCollectionContainsEventLogEntry* wcEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::WeakCollectionContainsEventLogEntry, NSLogEvents::EventKind::WeakCollectionContainsTag>();
  830. return wcEvent->ContainsValue;
  831. }
  832. NSLogEvents::EventLogEntry* EventLog::RecordExternalCallEvent(Js::JavascriptFunction* func, int32 rootDepth, const Js::Arguments& args, bool checkExceptions)
  833. {
  834. NSLogEvents::ExternalCallEventLogEntry* ecEvent = nullptr;
  835. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::ExternalCallEventLogEntry, NSLogEvents::EventKind::ExternalCallTag>(&ecEvent);
  836. //We never fail with an exception (instead we set the HasRecordedException in script context)
  837. evt->ResultStatus = 0;
  838. NSLogEvents::ExternalCallEventLogEntry_ProcessArgs(evt, rootDepth, func, args, checkExceptions, this->m_eventSlabAllocator);
  839. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  840. NSLogEvents::ExternalCallEventLogEntry_ProcessDiagInfoPre(evt, func, this->m_eventSlabAllocator);
  841. #endif
  842. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  843. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteCall(func, true, args.Info.Count, args.Values, this->GetLastEventTime());
  844. #endif
  845. return evt;
  846. }
  847. void EventLog::RecordExternalCallEvent_Complete(Js::JavascriptFunction* efunction, NSLogEvents::EventLogEntry* evt, Js::Var result)
  848. {
  849. NSLogEvents::ExternalCallEventLogEntry_ProcessReturn(evt, result, this->GetLastEventTime());
  850. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  851. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteReturn(efunction, result, this->GetLastEventTime());
  852. #endif
  853. }
  854. void EventLog::ReplayExternalCallEvent(Js::JavascriptFunction* function, const Js::Arguments& args, Js::Var* result)
  855. {
  856. TTDAssert(result != nullptr, "Must be non-null!!!");
  857. TTDAssert(*result == nullptr, "And initialized to a default value.");
  858. const NSLogEvents::ExternalCallEventLogEntry* ecEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::ExternalCallEventLogEntry, NSLogEvents::EventKind::ExternalCallTag>();
  859. Js::ScriptContext* ctx = function->GetScriptContext();
  860. TTDAssert(ctx != nullptr, "Not sure how this would be possible but check just in case.");
  861. ThreadContextTTD* executeContext = ctx->GetThreadContext()->TTDContext;
  862. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  863. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteCall(function, true, args.Info.Count, args.Values, this->GetLastEventTime());
  864. #endif
  865. //make sure we log all of the passed arguments in the replay host
  866. TTDAssert(args.Info.Count + 1 == ecEvent->ArgCount, "Mismatch in args!!!");
  867. TTDVar recordedFunction = ecEvent->ArgArray[0];
  868. NSLogEvents::PassVarToHostInReplay(executeContext, recordedFunction, function);
  869. for(uint32 i = 0; i < args.Info.Count; ++i)
  870. {
  871. Js::Var replayVar = args.Values[i];
  872. TTDVar recordedVar = ecEvent->ArgArray[i + 1];
  873. NSLogEvents::PassVarToHostInReplay(executeContext, recordedVar, replayVar);
  874. }
  875. if (args.HasNewTarget())
  876. {
  877. TTDAssert(ecEvent->NewTarget != nullptr, "Mismatch in new.target!!!");
  878. Js::Var replayVar = args.GetNewTarget();
  879. TTDVar recordedVar = ecEvent->NewTarget;
  880. NSLogEvents::PassVarToHostInReplay(executeContext, recordedVar, replayVar);
  881. }
  882. else
  883. {
  884. TTDAssert(ecEvent->NewTarget == nullptr, "Mismatch in new.target!!!");
  885. }
  886. //replay anything that happens in the external call
  887. BEGIN_LEAVE_SCRIPT(ctx)
  888. {
  889. this->ReplayActionEventSequenceThroughTime(ecEvent->LastNestedEventTime);
  890. }
  891. END_LEAVE_SCRIPT(ctx);
  892. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  893. TTDAssert(!this->m_currentReplayEventIterator.IsValid() || this->m_currentReplayEventIterator.Current()->EventTimeStamp == this->m_eventTimeCtr, "Out of Sync!!!");
  894. #endif
  895. *result = NSLogEvents::InflateVarInReplay(executeContext, ecEvent->ReturnValue);
  896. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  897. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteReturn(function, *result, this->GetLastEventTime());
  898. #endif
  899. //if we had exception info then we need to patch it up and do what the external call did
  900. if(ecEvent->CheckExceptionStatus)
  901. {
  902. if(ctx->HasRecordedException())
  903. {
  904. bool considerPassingToDebugger = false;
  905. Js::JavascriptExceptionObject* recordedException = ctx->GetAndClearRecordedException(&considerPassingToDebugger);
  906. if(recordedException != nullptr)
  907. {
  908. // If this is script termination, then throw ScriptAbortExceptio, else throw normal Exception object.
  909. if(recordedException == ctx->GetThreadContext()->GetPendingTerminatedErrorObject())
  910. {
  911. throw Js::ScriptAbortException();
  912. }
  913. else
  914. {
  915. Js::JavascriptExceptionOperators::RethrowExceptionObject(recordedException, ctx, considerPassingToDebugger);
  916. }
  917. }
  918. }
  919. }
  920. if(*result == nullptr)
  921. {
  922. *result = ctx->GetLibrary()->GetUndefined();
  923. }
  924. else
  925. {
  926. *result = Js::CrossSite::MarshalVar(ctx, *result);
  927. }
  928. }
  929. NSLogEvents::EventLogEntry* EventLog::RecordEnqueueTaskEvent(Js::Var taskVar)
  930. {
  931. NSLogEvents::ExternalCbRegisterCallEventLogEntry* ecEvent = nullptr;
  932. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::ExternalCbRegisterCallEventLogEntry, NSLogEvents::EventKind::ExternalCbRegisterCall>(&ecEvent);
  933. ecEvent->CallbackFunction = static_cast<TTDVar>(taskVar);
  934. ecEvent->LastNestedEventTime = TTD_EVENT_MAXTIME;
  935. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  936. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteLiteralMsg("Enqueue Task: ");
  937. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteVar(taskVar);
  938. #endif
  939. return evt;
  940. }
  941. void EventLog::RecordEnqueueTaskEvent_Complete(NSLogEvents::EventLogEntry* evt)
  942. {
  943. NSLogEvents::ExternalCbRegisterCallEventLogEntry* ecEvent = NSLogEvents::GetInlineEventDataAs<NSLogEvents::ExternalCbRegisterCallEventLogEntry, NSLogEvents::EventKind::ExternalCbRegisterCall>(evt);
  944. ecEvent->LastNestedEventTime = this->GetLastEventTime();
  945. }
  946. void EventLog::ReplayEnqueueTaskEvent(Js::ScriptContext* ctx, Js::Var taskVar)
  947. {
  948. const NSLogEvents::ExternalCbRegisterCallEventLogEntry* ecEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::ExternalCbRegisterCallEventLogEntry, NSLogEvents::EventKind::ExternalCbRegisterCall>();
  949. ThreadContextTTD* executeContext = ctx->GetThreadContext()->TTDContext;
  950. NSLogEvents::PassVarToHostInReplay(executeContext, ecEvent->CallbackFunction, taskVar);
  951. //replay anything that happens when we are out of the call
  952. BEGIN_LEAVE_SCRIPT(ctx)
  953. {
  954. this->ReplayActionEventSequenceThroughTime(ecEvent->LastNestedEventTime);
  955. }
  956. END_LEAVE_SCRIPT(ctx);
  957. }
  958. int64 EventLog::GetCurrentTopLevelEventTime() const
  959. {
  960. return this->m_topLevelCallbackEventTime;
  961. }
  962. int64 EventLog::GetFirstEventTimeInLog() const
  963. {
  964. for(auto iter = this->m_eventList.GetIteratorAtFirst(); iter.IsValid(); iter.MoveNext())
  965. {
  966. if(NSLogEvents::IsJsRTActionRootCall(iter.Current()))
  967. {
  968. return NSLogEvents::GetTimeFromRootCallOrSnapshot(iter.Current());
  969. }
  970. }
  971. return -1;
  972. }
  973. int64 EventLog::GetLastEventTimeInLog() const
  974. {
  975. for(auto iter = this->m_eventList.GetIteratorAtLast_ReplayOnly(); iter.IsValid(); iter.MovePrevious_ReplayOnly())
  976. {
  977. if(NSLogEvents::IsJsRTActionRootCall(iter.Current()))
  978. {
  979. return NSLogEvents::GetTimeFromRootCallOrSnapshot(iter.Current());
  980. }
  981. }
  982. return -1;
  983. }
  984. int64 EventLog::GetKthEventTimeInLog(uint32 k) const
  985. {
  986. uint32 topLevelCount = 0;
  987. for(auto iter = this->m_eventList.GetIteratorAtFirst(); iter.IsValid(); iter.MoveNext())
  988. {
  989. if(NSLogEvents::IsJsRTActionRootCall(iter.Current()))
  990. {
  991. topLevelCount++;
  992. if(topLevelCount == k)
  993. {
  994. return NSLogEvents::GetTimeFromRootCallOrSnapshot(iter.Current());
  995. }
  996. }
  997. }
  998. return -1;
  999. }
  1000. void EventLog::ResetCallStackForTopLevelCall(int64 topLevelCallbackEventTime)
  1001. {
  1002. this->m_topLevelCallbackEventTime = topLevelCallbackEventTime;
  1003. }
  1004. bool EventLog::IsTimeForSnapshot() const
  1005. {
  1006. return this->m_threadContext->TTDContext->SnapInterval == 0 // if SnapInterval is 0, we'll always snapshot irrespective of when last one was taken
  1007. || (this->m_elapsedExecutionTimeSinceSnapshot > this->m_threadContext->TTDContext->SnapInterval);
  1008. }
  1009. void EventLog::PruneLogLength()
  1010. {
  1011. uint32 maxSnaps = this->m_threadContext->TTDContext->SnapHistoryLength;
  1012. uint32 snapCount = 0;
  1013. for(auto iter = this->m_eventList.GetIteratorAtFirst(); iter.IsValid(); iter.MoveNext())
  1014. {
  1015. if(iter.Current()->EventKind == NSLogEvents::EventKind::SnapshotTag)
  1016. {
  1017. snapCount++;
  1018. }
  1019. }
  1020. //If we have more than the desired number of snaps we will trim them off
  1021. if(snapCount > maxSnaps)
  1022. {
  1023. uint32 snapDelCount = snapCount - maxSnaps;
  1024. auto delIter = this->m_eventList.GetIteratorAtFirst();
  1025. while(true)
  1026. {
  1027. NSLogEvents::EventLogEntry* evt = delIter.Current();
  1028. if(delIter.Current()->EventKind == NSLogEvents::EventKind::SnapshotTag)
  1029. {
  1030. if(snapDelCount == 0)
  1031. {
  1032. break;
  1033. }
  1034. snapDelCount--;
  1035. }
  1036. TTEventList::TTEventListLink* block = delIter.GetBlock();
  1037. delIter.MoveNext();
  1038. this->m_eventList.DeleteFirstEntry(block, evt);
  1039. }
  1040. }
  1041. }
  1042. void EventLog::IncrementElapsedSnapshotTime(double addtlTime)
  1043. {
  1044. this->m_elapsedExecutionTimeSinceSnapshot += addtlTime;
  1045. }
  1046. void EventLog::DoSnapshotExtract()
  1047. {
  1048. //force a GC to get weak containers in a consistent state
  1049. TTDTimer timer;
  1050. double startTime = timer.Now();
  1051. this->m_threadContext->GetRecycler()->CollectNow<CollectNowForceInThread>();
  1052. this->m_threadContext->TTDContext->SyncRootsBeforeSnapshot_Record();
  1053. double endTime = timer.Now();
  1054. //do the rest of the snapshot
  1055. this->SetSnapshotOrInflateInProgress(true);
  1056. this->PushMode(TTDMode::ExcludedExecutionTTAction);
  1057. ///////////////////////////
  1058. //Create the event object and add it to the log
  1059. NSLogEvents::SnapshotEventLogEntry* snapEvent = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::SnapshotEventLogEntry, NSLogEvents::EventKind::SnapshotTag>();
  1060. snapEvent->RestoreTimestamp = this->GetLastEventTime();
  1061. JsUtil::BaseHashSet<Js::FunctionBody*, HeapAllocator> liveTopLevelBodies(&HeapAllocator::Instance);
  1062. snapEvent->Snap = this->DoSnapshotExtract_Helper((endTime - startTime) / 1000.0, liveTopLevelBodies);
  1063. for(int32 i = 0; i < this->m_threadContext->TTDContext->GetTTDContexts().Count(); ++i)
  1064. {
  1065. this->m_threadContext->TTDContext->GetTTDContexts().Item(i)->TTDContextInfo->CleanUnreachableTopLevelBodies(liveTopLevelBodies);
  1066. }
  1067. //get info about live weak roots etc. we want to use in the replay from the snapshot into the event as well
  1068. snapEvent->LiveContextCount = snapEvent->Snap->GetContextList().Count();
  1069. snapEvent->LiveContextIdArray = nullptr;
  1070. if(snapEvent->LiveContextCount != 0)
  1071. {
  1072. snapEvent->LiveContextIdArray = this->m_eventSlabAllocator.SlabAllocateArray<TTD_LOG_PTR_ID>(snapEvent->LiveContextCount);
  1073. uint32 clpos = 0;
  1074. for(auto iter = snapEvent->Snap->GetContextList().GetIterator(); iter.IsValid(); iter.MoveNext())
  1075. {
  1076. snapEvent->LiveContextIdArray[clpos] = iter.Current()->ScriptContextLogId;
  1077. clpos++;
  1078. }
  1079. }
  1080. //walk the roots and count all of the "interesting weak ref roots"
  1081. snapEvent->LongLivedRefRootsCount = 0;
  1082. for(auto iter = snapEvent->Snap->GetRootList().GetIterator(); iter.IsValid(); iter.MoveNext())
  1083. {
  1084. const NSSnapValues::SnapRootInfoEntry* spe = iter.Current();
  1085. if(spe->MaybeLongLivedRoot)
  1086. {
  1087. snapEvent->LongLivedRefRootsCount++;
  1088. }
  1089. }
  1090. //Now allocate the arrays for them and do the processing
  1091. snapEvent->LongLivedRefRootsIdArray = nullptr;
  1092. if(snapEvent->LongLivedRefRootsCount != 0)
  1093. {
  1094. snapEvent->LongLivedRefRootsIdArray = this->m_eventSlabAllocator.SlabAllocateArray<TTD_LOG_PTR_ID>(snapEvent->LongLivedRefRootsCount);
  1095. uint32 rpos = 0;
  1096. for(auto iter = snapEvent->Snap->GetRootList().GetIterator(); iter.IsValid(); iter.MoveNext())
  1097. {
  1098. const NSSnapValues::SnapRootInfoEntry* spe = iter.Current();
  1099. if(spe->MaybeLongLivedRoot)
  1100. {
  1101. snapEvent->LongLivedRefRootsIdArray[rpos] = spe->LogId;
  1102. rpos++;
  1103. }
  1104. }
  1105. }
  1106. this->m_elapsedExecutionTimeSinceSnapshot = 0.0;
  1107. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  1108. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteLiteralMsg("---SNAPSHOT EVENT---\n");
  1109. #endif
  1110. this->PopMode(TTDMode::ExcludedExecutionTTAction);
  1111. this->SetSnapshotOrInflateInProgress(false);
  1112. }
  1113. void EventLog::DoRtrSnapIfNeeded()
  1114. {
  1115. TTDAssert(this->m_currentReplayEventIterator.IsValid() && NSLogEvents::IsJsRTActionRootCall(this->m_currentReplayEventIterator.Current()), "Something in wrong with the event position.");
  1116. this->SetSnapshotOrInflateInProgress(true);
  1117. this->PushMode(TTDMode::ExcludedExecutionTTAction);
  1118. NSLogEvents::JsRTCallFunctionAction* rootCall = NSLogEvents::GetInlineEventDataAs<NSLogEvents::JsRTCallFunctionAction, NSLogEvents::EventKind::CallExistingFunctionActionTag>(this->m_currentReplayEventIterator.Current());
  1119. if(rootCall->AdditionalReplayInfo->RtRSnap == nullptr)
  1120. {
  1121. //Be careful to ensure that caller is actually doing this
  1122. AUTO_NESTED_HANDLED_EXCEPTION_TYPE((ExceptionType)(ExceptionType_OutOfMemory | ExceptionType_JavascriptException));
  1123. JsUtil::BaseHashSet<Js::FunctionBody*, HeapAllocator> liveTopLevelBodies(&HeapAllocator::Instance); //don't actually care about the result here
  1124. rootCall->AdditionalReplayInfo->RtRSnap = this->DoSnapshotExtract_Helper(0.0, liveTopLevelBodies);
  1125. }
  1126. this->PopMode(TTDMode::ExcludedExecutionTTAction);
  1127. this->SetSnapshotOrInflateInProgress(false);
  1128. }
  1129. int64 EventLog::FindSnapTimeForEventTime(int64 targetTime, int64* optEndSnapTime)
  1130. {
  1131. int64 snapTime = -1;
  1132. if(optEndSnapTime != nullptr)
  1133. {
  1134. *optEndSnapTime = -1;
  1135. }
  1136. for(auto iter = this->m_eventList.GetIteratorAtLast_ReplayOnly(); iter.IsValid(); iter.MovePrevious_ReplayOnly())
  1137. {
  1138. bool isSnap = false;
  1139. bool isRoot = false;
  1140. bool hasRtrSnap = false;
  1141. int64 time = NSLogEvents::AccessTimeInRootCallOrSnapshot(iter.Current(), isSnap, isRoot, hasRtrSnap);
  1142. bool validSnap = isSnap | (isRoot & hasRtrSnap);
  1143. if(validSnap && time <= targetTime)
  1144. {
  1145. snapTime = time;
  1146. break;
  1147. }
  1148. }
  1149. if(optEndSnapTime != nullptr)
  1150. {
  1151. for(auto iter = this->m_eventList.GetIteratorAtFirst(); iter.IsValid(); iter.MoveNext())
  1152. {
  1153. if(iter.Current()->EventKind == NSLogEvents::EventKind::SnapshotTag)
  1154. {
  1155. NSLogEvents::SnapshotEventLogEntry* snapEvent = NSLogEvents::GetInlineEventDataAs<NSLogEvents::SnapshotEventLogEntry, NSLogEvents::EventKind::SnapshotTag>(iter.Current());
  1156. if(snapEvent->RestoreTimestamp > snapTime)
  1157. {
  1158. *optEndSnapTime = snapEvent->RestoreTimestamp;
  1159. break;
  1160. }
  1161. }
  1162. }
  1163. }
  1164. return snapTime;
  1165. }
  1166. void EventLog::GetSnapShotBoundInterval(int64 targetTime, int64* snapIntervalStart, int64* snapIntervalEnd) const
  1167. {
  1168. *snapIntervalStart = -1;
  1169. *snapIntervalEnd = -1;
  1170. //move the iterator to the current snapshot just before the event
  1171. auto iter = this->m_eventList.GetIteratorAtLast_ReplayOnly();
  1172. while(iter.IsValid())
  1173. {
  1174. NSLogEvents::EventLogEntry* evt = iter.Current();
  1175. if(evt->EventKind == NSLogEvents::EventKind::SnapshotTag)
  1176. {
  1177. NSLogEvents::SnapshotEventLogEntry* snapEvent = NSLogEvents::GetInlineEventDataAs<NSLogEvents::SnapshotEventLogEntry, NSLogEvents::EventKind::SnapshotTag>(iter.Current());
  1178. if(snapEvent->RestoreTimestamp <= targetTime)
  1179. {
  1180. *snapIntervalStart = snapEvent->RestoreTimestamp;
  1181. break;
  1182. }
  1183. }
  1184. iter.MovePrevious_ReplayOnly();
  1185. }
  1186. //now move the iter to the next snapshot
  1187. while(iter.IsValid())
  1188. {
  1189. NSLogEvents::EventLogEntry* evt = iter.Current();
  1190. if(evt->EventKind == NSLogEvents::EventKind::SnapshotTag)
  1191. {
  1192. NSLogEvents::SnapshotEventLogEntry* snapEvent = NSLogEvents::GetInlineEventDataAs<NSLogEvents::SnapshotEventLogEntry, NSLogEvents::EventKind::SnapshotTag>(iter.Current());
  1193. if(*snapIntervalStart < snapEvent->RestoreTimestamp)
  1194. {
  1195. *snapIntervalEnd = snapEvent->RestoreTimestamp;
  1196. break;
  1197. }
  1198. }
  1199. iter.MoveNext();
  1200. }
  1201. }
  1202. int64 EventLog::GetPreviousSnapshotInterval(int64 currentSnapTime) const
  1203. {
  1204. //move the iterator to the current snapshot just before the event
  1205. for(auto iter = this->m_eventList.GetIteratorAtLast_ReplayOnly(); iter.IsValid(); iter.MovePrevious_ReplayOnly())
  1206. {
  1207. NSLogEvents::EventLogEntry* evt = iter.Current();
  1208. if(evt->EventKind == NSLogEvents::EventKind::SnapshotTag)
  1209. {
  1210. NSLogEvents::SnapshotEventLogEntry* snapEvent = NSLogEvents::GetInlineEventDataAs<NSLogEvents::SnapshotEventLogEntry, NSLogEvents::EventKind::SnapshotTag>(iter.Current());
  1211. if(snapEvent->RestoreTimestamp < currentSnapTime)
  1212. {
  1213. return snapEvent->RestoreTimestamp;
  1214. }
  1215. }
  1216. }
  1217. return -1;
  1218. }
  1219. void EventLog::DoSnapshotInflate(int64 etime)
  1220. {
  1221. this->PushMode(TTDMode::ExcludedExecutionTTAction);
  1222. const SnapShot* snap = nullptr;
  1223. int64 restoreEventTime = -1;
  1224. for(auto iter = this->m_eventList.GetIteratorAtLast_ReplayOnly(); iter.IsValid(); iter.MovePrevious_ReplayOnly())
  1225. {
  1226. NSLogEvents::EventLogEntry* evt = iter.Current();
  1227. if(evt->EventKind == NSLogEvents::EventKind::SnapshotTag)
  1228. {
  1229. NSLogEvents::SnapshotEventLogEntry* snapEvent = NSLogEvents::GetInlineEventDataAs<NSLogEvents::SnapshotEventLogEntry, NSLogEvents::EventKind::SnapshotTag>(evt);
  1230. if(snapEvent->RestoreTimestamp == etime)
  1231. {
  1232. NSLogEvents::SnapshotEventLogEntry_EnsureSnapshotDeserialized(evt, this->m_threadContext);
  1233. restoreEventTime = snapEvent->RestoreTimestamp;
  1234. snap = snapEvent->Snap;
  1235. break;
  1236. }
  1237. }
  1238. if(NSLogEvents::IsJsRTActionRootCall(evt))
  1239. {
  1240. const NSLogEvents::JsRTCallFunctionAction* rootEntry = NSLogEvents::GetInlineEventDataAs<NSLogEvents::JsRTCallFunctionAction, NSLogEvents::EventKind::CallExistingFunctionActionTag>(evt);
  1241. if(rootEntry->CallEventTime == etime)
  1242. {
  1243. restoreEventTime = rootEntry->CallEventTime;
  1244. snap = rootEntry->AdditionalReplayInfo->RtRSnap;
  1245. break;
  1246. }
  1247. }
  1248. }
  1249. TTDAssert(snap != nullptr, "Log should start with a snapshot!!!");
  1250. uint32 dbgScopeCount = snap->GetDbgScopeCountNonTopLevel();
  1251. TTDIdentifierDictionary<uint64, NSSnapValues::TopLevelScriptLoadFunctionBodyResolveInfo*> topLevelLoadScriptMap;
  1252. topLevelLoadScriptMap.Initialize(this->m_loadedTopLevelScripts.Count());
  1253. for(auto iter = this->m_loadedTopLevelScripts.GetIterator(); iter.IsValid(); iter.MoveNext())
  1254. {
  1255. topLevelLoadScriptMap.AddItem(iter.Current()->TopLevelBase.TopLevelBodyCtr, iter.Current());
  1256. dbgScopeCount += iter.Current()->TopLevelBase.ScopeChainInfo.ScopeCount;
  1257. }
  1258. TTDIdentifierDictionary<uint64, NSSnapValues::TopLevelNewFunctionBodyResolveInfo*> topLevelNewScriptMap;
  1259. topLevelNewScriptMap.Initialize(this->m_newFunctionTopLevelScripts.Count());
  1260. for(auto iter = this->m_newFunctionTopLevelScripts.GetIterator(); iter.IsValid(); iter.MoveNext())
  1261. {
  1262. topLevelNewScriptMap.AddItem(iter.Current()->TopLevelBase.TopLevelBodyCtr, iter.Current());
  1263. dbgScopeCount += iter.Current()->TopLevelBase.ScopeChainInfo.ScopeCount;
  1264. }
  1265. TTDIdentifierDictionary<uint64, NSSnapValues::TopLevelEvalFunctionBodyResolveInfo*> topLevelEvalScriptMap;
  1266. topLevelEvalScriptMap.Initialize(this->m_evalTopLevelScripts.Count());
  1267. for(auto iter = this->m_evalTopLevelScripts.GetIterator(); iter.IsValid(); iter.MoveNext())
  1268. {
  1269. topLevelEvalScriptMap.AddItem(iter.Current()->TopLevelBase.TopLevelBodyCtr, iter.Current());
  1270. dbgScopeCount += iter.Current()->TopLevelBase.ScopeChainInfo.ScopeCount;
  1271. }
  1272. uint32 topFunctionCount = topLevelLoadScriptMap.Count() + topLevelNewScriptMap.Count() + topLevelEvalScriptMap.Count();
  1273. ThreadContextTTD* threadCtx = this->m_threadContext->TTDContext;
  1274. const UnorderedArrayList<NSSnapValues::SnapContext, TTD_ARRAY_LIST_SIZE_XSMALL>& snpCtxs = snap->GetContextList();
  1275. //check if we can reuse script contexts or we need to create new ones
  1276. bool reuseInflateMap = (this->m_lastInflateMap != nullptr && this->m_lastInflateSnapshotTime == etime && !threadCtx->ContextCreatedOrDestoyedInReplay());
  1277. //Fast checks ok but make sure we aren't blocked by a non-restorable well known object
  1278. if(reuseInflateMap)
  1279. {
  1280. reuseInflateMap = snap->AllWellKnownObjectsReusable(this->m_lastInflateMap);
  1281. }
  1282. if(reuseInflateMap)
  1283. {
  1284. this->m_lastInflateMap->PrepForReInflate(snap->ContextCount(), snap->HandlerCount(), snap->TypeCount(), snap->PrimitiveCount() + snap->ObjectCount(), snap->BodyCount() + topFunctionCount, dbgScopeCount, snap->EnvCount(), snap->SlotArrayCount());
  1285. //collect anything that is dead
  1286. threadCtx->ClearRootsForSnapRestore();
  1287. this->m_threadContext->GetRecycler()->CollectNow<CollectNowForceInThread>();
  1288. //inflate into existing contexts
  1289. const JsUtil::List<Js::ScriptContext*, HeapAllocator>& oldCtxts = threadCtx->GetTTDContexts();
  1290. for(auto iter = snpCtxs.GetIterator(); iter.IsValid(); iter.MoveNext())
  1291. {
  1292. const NSSnapValues::SnapContext* sCtx = iter.Current();
  1293. Js::ScriptContext* vCtx = nullptr;
  1294. for(int32 i = 0; i < oldCtxts.Count(); ++i)
  1295. {
  1296. if(oldCtxts.Item(i)->ScriptContextLogTag == sCtx->ScriptContextLogId)
  1297. {
  1298. vCtx = oldCtxts.Item(i);
  1299. break;
  1300. }
  1301. }
  1302. TTDAssert(vCtx != nullptr, "We lost a context somehow!!!");
  1303. NSSnapValues::InflateScriptContext(sCtx, vCtx, this->m_lastInflateMap, topLevelLoadScriptMap, topLevelNewScriptMap, topLevelEvalScriptMap);
  1304. }
  1305. }
  1306. else
  1307. {
  1308. bool shouldReleaseCtxs = false;
  1309. if(this->m_lastInflateMap != nullptr)
  1310. {
  1311. shouldReleaseCtxs = true;
  1312. TT_HEAP_DELETE(InflateMap, this->m_lastInflateMap);
  1313. this->m_lastInflateMap = nullptr;
  1314. }
  1315. this->m_lastInflateMap = TT_HEAP_NEW(InflateMap);
  1316. this->m_lastInflateMap->PrepForInitialInflate(this->m_threadContext, snap->ContextCount(), snap->HandlerCount(), snap->TypeCount(), snap->PrimitiveCount() + snap->ObjectCount(), snap->BodyCount() + topFunctionCount, dbgScopeCount, snap->EnvCount(), snap->SlotArrayCount());
  1317. this->m_lastInflateSnapshotTime = etime;
  1318. //collect anything that is dead
  1319. JsUtil::List<FinalizableObject*, HeapAllocator> deadCtxs(&HeapAllocator::Instance);
  1320. threadCtx->ClearContextsForSnapRestore(deadCtxs);
  1321. threadCtx->ClearRootsForSnapRestore();
  1322. //allocate and inflate into new contexts
  1323. for(auto iter = snpCtxs.GetIterator(); iter.IsValid(); iter.MoveNext())
  1324. {
  1325. const NSSnapValues::SnapContext* sCtx = iter.Current();
  1326. Js::ScriptContext* vCtx = nullptr;
  1327. threadCtx->TTDExternalObjectFunctions.pfCreateJsRTContextCallback(threadCtx->GetRuntimeHandle(), &vCtx);
  1328. NSSnapValues::InflateScriptContext(sCtx, vCtx, this->m_lastInflateMap, topLevelLoadScriptMap, topLevelNewScriptMap, topLevelEvalScriptMap);
  1329. }
  1330. threadCtx->ResetContextCreatedOrDestoyedInReplay();
  1331. if(shouldReleaseCtxs)
  1332. {
  1333. for(int32 i = 0; i < deadCtxs.Count(); ++i)
  1334. {
  1335. threadCtx->TTDExternalObjectFunctions.pfReleaseJsRTContextCallback(deadCtxs.Item(i));
  1336. }
  1337. this->m_threadContext->GetRecycler()->CollectNow<CollectNowForceInThread>();
  1338. }
  1339. //We don't want to have a bunch of snapshots in memory (that will get big fast) so unload all but the current one
  1340. for(auto iter = this->m_eventList.GetIteratorAtLast_ReplayOnly(); iter.IsValid(); iter.MovePrevious_ReplayOnly())
  1341. {
  1342. bool isSnap = false;
  1343. bool isRoot = false;
  1344. bool hasRtrSnap = false;
  1345. int64 time = NSLogEvents::AccessTimeInRootCallOrSnapshot(iter.Current(), isSnap, isRoot, hasRtrSnap);
  1346. bool hasSnap = isSnap | (isRoot & hasRtrSnap);
  1347. if(hasSnap && time != etime)
  1348. {
  1349. if(isSnap)
  1350. {
  1351. NSLogEvents::SnapshotEventLogEntry_UnloadSnapshot(iter.Current());
  1352. }
  1353. else
  1354. {
  1355. NSLogEvents::JsRTCallFunctionAction_UnloadSnapshot(iter.Current());
  1356. }
  1357. }
  1358. }
  1359. }
  1360. this->SetSnapshotOrInflateInProgress(true); //make sure we don't do any un-intended CrossSite conversions
  1361. snap->Inflate(this->m_lastInflateMap, this->m_threadContext->TTDContext);
  1362. this->m_lastInflateMap->CleanupAfterInflate();
  1363. this->SetSnapshotOrInflateInProgress(false); //re-enable CrossSite conversions
  1364. this->m_eventTimeCtr = restoreEventTime;
  1365. if(!this->m_eventList.IsEmpty())
  1366. {
  1367. this->m_currentReplayEventIterator = this->m_eventList.GetIteratorAtLast_ReplayOnly();
  1368. while(true)
  1369. {
  1370. bool isSnap = false;
  1371. bool isRoot = false;
  1372. bool hasRtrSnap = false;
  1373. int64 time = NSLogEvents::AccessTimeInRootCallOrSnapshot(this->m_currentReplayEventIterator.Current(), isSnap, isRoot, hasRtrSnap);
  1374. if((isSnap | isRoot) && time == this->m_eventTimeCtr)
  1375. {
  1376. break;
  1377. }
  1378. this->m_currentReplayEventIterator.MovePrevious_ReplayOnly();
  1379. }
  1380. //we want to advance to the event immediately after the snapshot as well so do that
  1381. if(this->m_currentReplayEventIterator.Current()->EventKind == NSLogEvents::EventKind::SnapshotTag)
  1382. {
  1383. this->m_eventTimeCtr++;
  1384. this->m_currentReplayEventIterator.MoveNext();
  1385. }
  1386. }
  1387. this->PopMode(TTDMode::ExcludedExecutionTTAction);
  1388. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  1389. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->WriteLiteralMsg("---INFLATED SNAPSHOT---\n");
  1390. #endif
  1391. }
  1392. void EventLog::ReplayRootEventsToTime(int64 eventTime)
  1393. {
  1394. while(this->m_eventTimeCtr < eventTime)
  1395. {
  1396. this->ReplaySingleRootEntry();
  1397. }
  1398. }
  1399. void EventLog::ReplaySingleRootEntry()
  1400. {
  1401. if(!this->m_currentReplayEventIterator.IsValid())
  1402. {
  1403. this->AbortReplayReturnToHost();
  1404. }
  1405. NSLogEvents::EventKind eKind = this->m_currentReplayEventIterator.Current()->EventKind;
  1406. if(eKind == NSLogEvents::EventKind::SnapshotTag)
  1407. {
  1408. this->ReplaySnapshotEvent();
  1409. }
  1410. else if(eKind == NSLogEvents::EventKind::EventLoopYieldPointTag)
  1411. {
  1412. this->ReplayEventLoopYieldPointEvent();
  1413. }
  1414. else
  1415. {
  1416. TTDAssert(eKind > NSLogEvents::EventKind::JsRTActionTag, "Either this is an invalid tag to replay directly (should be driven internally) or it is not known!!!");
  1417. this->ReplaySingleActionEventEntry();
  1418. }
  1419. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  1420. TTDAssert(!this->m_currentReplayEventIterator.IsValid() || this->m_currentReplayEventIterator.Current()->EventTimeStamp == this->m_eventTimeCtr, "We are out of sync here");
  1421. #endif
  1422. }
  1423. void EventLog::ReplayActionEventSequenceThroughTime(int64 eventTime)
  1424. {
  1425. while(this->m_eventTimeCtr <= eventTime)
  1426. {
  1427. this->ReplaySingleActionEventEntry();
  1428. }
  1429. }
  1430. void EventLog::ReplaySingleActionEventEntry()
  1431. {
  1432. if(!this->m_currentReplayEventIterator.IsValid())
  1433. {
  1434. this->AbortReplayReturnToHost();
  1435. }
  1436. NSLogEvents::EventLogEntry* evt = this->m_currentReplayEventIterator.Current();
  1437. this->AdvanceTimeAndPositionForReplay();
  1438. NSLogEvents::ContextExecuteKind execKind = this->m_eventListVTable[(uint32)evt->EventKind].ContextKind;
  1439. auto executeFP = this->m_eventListVTable[(uint32)evt->EventKind].ExecuteFP;
  1440. TTDAssert(!NSLogEvents::EventFailsWithRuntimeError(evt), "We have a failing Event in the Log -- we assume host is correct!");
  1441. ThreadContextTTD* executeContext = this->m_threadContext->TTDContext;
  1442. if(execKind == NSLogEvents::ContextExecuteKind::GlobalAPIWrapper)
  1443. {
  1444. //enter/exit global wrapper -- see JsrtInternal.h
  1445. try
  1446. {
  1447. AUTO_NESTED_HANDLED_EXCEPTION_TYPE((ExceptionType)(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));
  1448. executeFP(evt, executeContext);
  1449. TTDAssert(NSLogEvents::EventCompletesNormally(evt), "All my action events should exit or terminate before return so no need to loop yet but may want to later");
  1450. }
  1451. catch(TTD::TTDebuggerAbortException)
  1452. {
  1453. throw;
  1454. }
  1455. catch(...)
  1456. {
  1457. TTDAssert(false, "Encountered other kind of exception in replay??");
  1458. }
  1459. }
  1460. else if(execKind == NSLogEvents::ContextExecuteKind::ContextAPIWrapper)
  1461. {
  1462. //enter/exit context wrapper -- see JsrtInternal.h
  1463. Js::ScriptContext* ctx = executeContext->GetActiveScriptContext();
  1464. TTDAssert(ctx != nullptr, "This should be set!!!");
  1465. TTDAssert(ctx->GetThreadContext()->GetRecordedException() == nullptr, "Shouldn't have outstanding exceptions (assume always CheckContext when recording).");
  1466. TTDAssert(this->m_threadContext->TTDContext->GetActiveScriptContext() == ctx, "Make sure the replay host didn't change contexts on us unexpectedly without resetting back to the correct one.");
  1467. try
  1468. {
  1469. AUTO_NESTED_HANDLED_EXCEPTION_TYPE((ExceptionType)(ExceptionType_OutOfMemory | ExceptionType_JavascriptException));
  1470. // Enter script
  1471. BEGIN_ENTER_SCRIPT(ctx, true, true, true)
  1472. {
  1473. executeFP(evt, executeContext);
  1474. }
  1475. END_ENTER_SCRIPT
  1476. TTDAssert(NSLogEvents::EventCompletesNormally(evt), "All my action events should exit / terminate before return so no need to loop yet but may want to later");
  1477. }
  1478. catch(const Js::JavascriptException& err)
  1479. {
  1480. TTDAssert(NSLogEvents::EventCompletesWithException(evt), "Should see same exception here");
  1481. ctx->GetThreadContext()->SetRecordedException(err.GetAndClear());
  1482. }
  1483. catch(Js::ScriptAbortException)
  1484. {
  1485. TTDAssert(NSLogEvents::EventCompletesWithException(evt), "Should see same exception here");
  1486. Assert(ctx->GetThreadContext()->GetRecordedException() == nullptr);
  1487. ctx->GetThreadContext()->SetRecordedException(ctx->GetThreadContext()->GetPendingTerminatedErrorObject());
  1488. }
  1489. catch(TTD::TTDebuggerAbortException)
  1490. {
  1491. throw;
  1492. }
  1493. catch(...)
  1494. {
  1495. TTDAssert(false, "Encountered other kind of exception in replay??");
  1496. }
  1497. }
  1498. else if(execKind == NSLogEvents::ContextExecuteKind::ContextAPINoScriptWrapper)
  1499. {
  1500. //enter/exit context no script wrapper -- see JsrtInternal.h
  1501. Js::ScriptContext* ctx = executeContext->GetActiveScriptContext();
  1502. TTDAssert(ctx != nullptr, "This should be set!!!");
  1503. TTDAssert(ctx->GetThreadContext()->GetRecordedException() == nullptr, "Shouldn't have outstanding exceptions (assume always CheckContext when recording).");
  1504. TTDAssert(this->m_threadContext->TTDContext->GetActiveScriptContext() == ctx, "Make sure the replay host didn't change contexts on us unexpectedly without resetting back to the correct one.");
  1505. try
  1506. {
  1507. AUTO_NESTED_HANDLED_EXCEPTION_TYPE((ExceptionType)(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));
  1508. executeFP(evt, executeContext);
  1509. TTDAssert(NSLogEvents::EventCompletesNormally(evt), "All my action events should both exit / terminate before return so no need to loop yet but may want to later");
  1510. }
  1511. catch(const Js::JavascriptException& err)
  1512. {
  1513. TTDAssert(NSLogEvents::EventCompletesWithException(evt), "Should see same exception here");
  1514. TTDAssert(false, "Should never get JavascriptExceptionObject for ContextAPINoScriptWrapper.");
  1515. ctx->GetThreadContext()->SetRecordedException(err.GetAndClear());
  1516. }
  1517. catch(Js::ScriptAbortException)
  1518. {
  1519. TTDAssert(NSLogEvents::EventCompletesWithException(evt), "Should see same exception here");
  1520. Assert(ctx->GetThreadContext()->GetRecordedException() == nullptr);
  1521. ctx->GetThreadContext()->SetRecordedException(ctx->GetThreadContext()->GetPendingTerminatedErrorObject());
  1522. }
  1523. catch(TTD::TTDebuggerAbortException)
  1524. {
  1525. throw;
  1526. }
  1527. catch(...)
  1528. {
  1529. TTDAssert(false, "Encountered other kind of exception in replay??");
  1530. }
  1531. }
  1532. else
  1533. {
  1534. TTDAssert(executeContext->GetActiveScriptContext() == nullptr || !executeContext->GetActiveScriptContext()->GetThreadContext()->IsScriptActive(), "These should all be outside of script context!!!");
  1535. //No need to move into script context just execute the action
  1536. executeFP(evt, executeContext);
  1537. }
  1538. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  1539. TTDAssert(!this->m_currentReplayEventIterator.IsValid() || this->m_currentReplayEventIterator.Current()->EventTimeStamp == this->m_eventTimeCtr, "We are out of sync here");
  1540. #endif
  1541. }
  1542. bool EventLog::IsPropertyRecordRef(void* ref) const
  1543. {
  1544. //This is an ugly cast but we just want to know if the pointer is in the set so it is ok here
  1545. return this->m_propertyRecordPinSet->ContainsKey((Js::PropertyRecord*)ref);
  1546. }
  1547. double EventLog::GetCurrentWallTime()
  1548. {
  1549. return this->m_timer.Now();
  1550. }
  1551. int64 EventLog::GetLastEventTime() const
  1552. {
  1553. return this->m_eventTimeCtr - 1;
  1554. }
  1555. NSLogEvents::EventLogEntry* EventLog::RecordJsRTCreateScriptContext(TTDJsRTActionResultAutoRecorder& actionPopper)
  1556. {
  1557. NSLogEvents::JsRTCreateScriptContextAction* cAction = nullptr;
  1558. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTCreateScriptContextAction, NSLogEvents::EventKind::CreateScriptContextActionTag>(&cAction);
  1559. cAction->KnownObjects = this->m_eventSlabAllocator.SlabAllocateStruct<NSLogEvents::JsRTCreateScriptContextAction_KnownObjects>();
  1560. cAction->KnownObjects = { 0 };
  1561. actionPopper.InitializeWithEventAndEnter(evt);
  1562. return evt;
  1563. }
  1564. void EventLog::RecordJsRTCreateScriptContextResult(NSLogEvents::EventLogEntry* evt, Js::ScriptContext* newCtx)
  1565. {
  1566. NSLogEvents::JsRTCreateScriptContextAction* cAction = NSLogEvents::GetInlineEventDataAs<NSLogEvents::JsRTCreateScriptContextAction, NSLogEvents::EventKind::CreateScriptContextActionTag>(evt);
  1567. cAction->KnownObjects = this->m_eventSlabAllocator.SlabAllocateStruct<NSLogEvents::JsRTCreateScriptContextAction_KnownObjects>();
  1568. cAction->GlobalObject = TTD_CONVERT_OBJ_TO_LOG_PTR_ID(newCtx->GetGlobalObject());
  1569. cAction->KnownObjects->UndefinedObject = TTD_CONVERT_OBJ_TO_LOG_PTR_ID(newCtx->GetLibrary()->GetUndefined());
  1570. cAction->KnownObjects->NullObject = TTD_CONVERT_OBJ_TO_LOG_PTR_ID(newCtx->GetLibrary()->GetNull());
  1571. cAction->KnownObjects->TrueObject = TTD_CONVERT_OBJ_TO_LOG_PTR_ID(newCtx->GetLibrary()->GetTrue());
  1572. cAction->KnownObjects->FalseObject = TTD_CONVERT_OBJ_TO_LOG_PTR_ID(newCtx->GetLibrary()->GetFalse());
  1573. }
  1574. void EventLog::RecordJsRTSetCurrentContext(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var globalObject)
  1575. {
  1576. NSLogEvents::JsRTSingleVarArgumentAction* sAction = nullptr;
  1577. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::SetActiveScriptContextActionTag>(&sAction);
  1578. NSLogEvents::SetVarItem_0(sAction, TTD_CONVERT_JSVAR_TO_TTDVAR(globalObject));
  1579. actionPopper.InitializeWithEventAndEnter(evt);
  1580. }
  1581. #if !INT32VAR
  1582. void EventLog::RecordJsRTCreateInteger(TTDJsRTActionResultAutoRecorder& actionPopper, int value)
  1583. {
  1584. NSLogEvents::JsRTIntegralArgumentAction* iAction = nullptr;
  1585. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTIntegralArgumentAction, NSLogEvents::EventKind::CreateIntegerActionTag>(&iAction);
  1586. iAction->Scalar = value;
  1587. actionPopper.InitializeWithEventAndEnterWResult(evt, &(iAction->Result));
  1588. }
  1589. #endif
  1590. void EventLog::RecordJsRTCreateNumber(TTDJsRTActionResultAutoRecorder& actionPopper, double value)
  1591. {
  1592. NSLogEvents::JsRTDoubleArgumentAction* dAction = nullptr;
  1593. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTDoubleArgumentAction, NSLogEvents::EventKind::CreateNumberActionTag>(&dAction);
  1594. dAction->DoubleValue = value;
  1595. actionPopper.InitializeWithEventAndEnterWResult(evt, &(dAction->Result));
  1596. }
  1597. void EventLog::RecordJsRTCreateBoolean(TTDJsRTActionResultAutoRecorder& actionPopper, bool value)
  1598. {
  1599. NSLogEvents::JsRTIntegralArgumentAction* bAction = nullptr;
  1600. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTIntegralArgumentAction, NSLogEvents::EventKind::CreateBooleanActionTag>(&bAction);
  1601. bAction->Scalar = value;
  1602. actionPopper.InitializeWithEventAndEnterWResult(evt, &(bAction->Result));
  1603. }
  1604. void EventLog::RecordJsRTCreateString(TTDJsRTActionResultAutoRecorder& actionPopper, const char16* stringValue, size_t stringLength)
  1605. {
  1606. NSLogEvents::JsRTStringArgumentAction* sAction = nullptr;
  1607. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTStringArgumentAction, NSLogEvents::EventKind::CreateStringActionTag>(&sAction);
  1608. this->m_eventSlabAllocator.CopyStringIntoWLength(stringValue, (uint32)stringLength, sAction->StringValue);
  1609. actionPopper.InitializeWithEventAndEnterWResult(evt, &(sAction->Result));
  1610. }
  1611. void EventLog::RecordJsRTCreateSymbol(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1612. {
  1613. NSLogEvents::JsRTSingleVarArgumentAction* sAction = nullptr;
  1614. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::CreateSymbolActionTag>(&sAction);
  1615. NSLogEvents::SetVarItem_0(sAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1616. actionPopper.InitializeWithEventAndEnterWResult(evt, &(sAction->Result));
  1617. }
  1618. void EventLog::RecordJsRTCreateError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg)
  1619. {
  1620. NSLogEvents::JsRTSingleVarArgumentAction* sAction = nullptr;
  1621. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::CreateErrorActionTag>(&sAction);
  1622. NSLogEvents::SetVarItem_0(sAction, TTD_CONVERT_JSVAR_TO_TTDVAR(msg));
  1623. actionPopper.InitializeWithEventAndEnterWResult(evt, &(sAction->Result));
  1624. }
  1625. void EventLog::RecordJsRTCreateRangeError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg)
  1626. {
  1627. NSLogEvents::JsRTSingleVarArgumentAction* sAction = nullptr;
  1628. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::CreateRangeErrorActionTag>(&sAction);
  1629. NSLogEvents::SetVarItem_0(sAction, TTD_CONVERT_JSVAR_TO_TTDVAR(msg));
  1630. actionPopper.InitializeWithEventAndEnterWResult(evt, &(sAction->Result));
  1631. }
  1632. void EventLog::RecordJsRTCreateReferenceError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg)
  1633. {
  1634. NSLogEvents::JsRTSingleVarArgumentAction* sAction = nullptr;
  1635. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::CreateReferenceErrorActionTag>(&sAction);
  1636. NSLogEvents::SetVarItem_0(sAction, TTD_CONVERT_JSVAR_TO_TTDVAR(msg));
  1637. actionPopper.InitializeWithEventAndEnterWResult(evt, &(sAction->Result));
  1638. }
  1639. void EventLog::RecordJsRTCreateSyntaxError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg)
  1640. {
  1641. NSLogEvents::JsRTSingleVarArgumentAction* sAction = nullptr;
  1642. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::CreateSyntaxErrorActionTag>(&sAction);
  1643. NSLogEvents::SetVarItem_0(sAction, TTD_CONVERT_JSVAR_TO_TTDVAR(msg));
  1644. actionPopper.InitializeWithEventAndEnterWResult(evt, &(sAction->Result));
  1645. }
  1646. void EventLog::RecordJsRTCreateTypeError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg)
  1647. {
  1648. NSLogEvents::JsRTSingleVarArgumentAction* sAction = nullptr;
  1649. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::CreateTypeErrorActionTag>(&sAction);
  1650. NSLogEvents::SetVarItem_0(sAction, TTD_CONVERT_JSVAR_TO_TTDVAR(msg));
  1651. actionPopper.InitializeWithEventAndEnterWResult(evt, &(sAction->Result));
  1652. }
  1653. void EventLog::RecordJsRTCreateURIError(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var msg)
  1654. {
  1655. NSLogEvents::JsRTSingleVarArgumentAction* sAction = nullptr;
  1656. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::CreateURIErrorActionTag>(&sAction);
  1657. NSLogEvents::SetVarItem_0(sAction, TTD_CONVERT_JSVAR_TO_TTDVAR(msg));
  1658. actionPopper.InitializeWithEventAndEnterWResult(evt, &(sAction->Result));
  1659. }
  1660. void EventLog::RecordJsRTVarToNumberConversion(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1661. {
  1662. NSLogEvents::JsRTSingleVarArgumentAction* cAction = nullptr;
  1663. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::VarConvertToNumberActionTag>(&cAction);
  1664. NSLogEvents::SetVarItem_0(cAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1665. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  1666. }
  1667. void EventLog::RecordJsRTVarToBooleanConversion(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1668. {
  1669. NSLogEvents::JsRTSingleVarArgumentAction* cAction = nullptr;
  1670. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::VarConvertToBooleanActionTag>(&cAction);
  1671. NSLogEvents::SetVarItem_0(cAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1672. actionPopper.InitializeWithEventAndEnter(evt);
  1673. }
  1674. void EventLog::RecordJsRTVarToStringConversion(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1675. {
  1676. NSLogEvents::JsRTSingleVarArgumentAction* cAction = nullptr;
  1677. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::VarConvertToStringActionTag>(&cAction);
  1678. NSLogEvents::SetVarItem_0(cAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1679. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  1680. }
  1681. void EventLog::RecordJsRTVarToObjectConversion(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1682. {
  1683. NSLogEvents::JsRTSingleVarArgumentAction* cAction = nullptr;
  1684. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::VarConvertToObjectActionTag>(&cAction);
  1685. NSLogEvents::SetVarItem_0(cAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1686. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  1687. }
  1688. void EventLog::RecordJsRTAddRootRef(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1689. {
  1690. NSLogEvents::JsRTSingleVarArgumentAction* addAction = nullptr;
  1691. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::AddRootRefActionTag>(&addAction);
  1692. NSLogEvents::SetVarItem_0(addAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1693. actionPopper.InitializeWithEventAndEnter(evt);
  1694. }
  1695. void EventLog::RecordJsRTAddWeakRootRef(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1696. {
  1697. NSLogEvents::JsRTSingleVarArgumentAction* addAction = nullptr;
  1698. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::AddWeakRootRefActionTag>(&addAction);
  1699. NSLogEvents::SetVarItem_0(addAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1700. actionPopper.InitializeWithEventAndEnter(evt);
  1701. }
  1702. void EventLog::RecordJsRTEventLoopYieldPoint()
  1703. {
  1704. NSLogEvents::EventLoopYieldPointEntry* ypEvt = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::EventLoopYieldPointEntry, NSLogEvents::EventKind::EventLoopYieldPointTag >();
  1705. ypEvt->EventTimeStamp = this->GetLastEventTime();
  1706. ypEvt->EventWallTime = this->GetCurrentWallTime();
  1707. //Put this here in the hope that after handling an event there is an idle period where we can work without blocking user work
  1708. if(this->IsTimeForSnapshot())
  1709. {
  1710. this->DoSnapshotExtract();
  1711. this->PruneLogLength();
  1712. }
  1713. }
  1714. void EventLog::RecordJsRTAllocateBasicObject(TTDJsRTActionResultAutoRecorder& actionPopper)
  1715. {
  1716. NSLogEvents::JsRTResultOnlyAction* cAction = nullptr;
  1717. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTResultOnlyAction, NSLogEvents::EventKind::AllocateObjectActionTag>(&cAction);
  1718. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  1719. }
  1720. void EventLog::RecordJsRTAllocateExternalObject(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var prototype)
  1721. {
  1722. NSLogEvents::JsRTSingleVarArgumentAction* cAction = nullptr;
  1723. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::AllocateExternalObjectActionTag>(&cAction);
  1724. NSLogEvents::SetVarItem_0(cAction, TTD_CONVERT_JSVAR_TO_TTDVAR(prototype));
  1725. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  1726. }
  1727. void EventLog::RecordJsRTAllocateBasicArray(TTDJsRTActionResultAutoRecorder& actionPopper, uint32 length)
  1728. {
  1729. NSLogEvents::JsRTIntegralArgumentAction* cAction = nullptr;
  1730. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTIntegralArgumentAction, NSLogEvents::EventKind::AllocateArrayActionTag>(&cAction);
  1731. cAction->Scalar = length;
  1732. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  1733. }
  1734. void EventLog::RecordJsRTAllocateArrayBuffer(TTDJsRTActionResultAutoRecorder& actionPopper, uint32 size)
  1735. {
  1736. NSLogEvents::JsRTIntegralArgumentAction* cAction = nullptr;
  1737. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTIntegralArgumentAction, NSLogEvents::EventKind::AllocateArrayBufferActionTag>(&cAction);
  1738. cAction->Scalar = size;
  1739. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  1740. }
  1741. void EventLog::RecordJsRTAllocateExternalArrayBuffer(TTDJsRTActionResultAutoRecorder& actionPopper, byte* buff, uint32 size)
  1742. {
  1743. NSLogEvents::JsRTByteBufferAction* cAction = nullptr;
  1744. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTByteBufferAction, NSLogEvents::EventKind::AllocateExternalArrayBufferActionTag>(&cAction);
  1745. cAction->Length = size;
  1746. cAction->Buffer = nullptr;
  1747. if(cAction->Length != 0)
  1748. {
  1749. cAction->Buffer = this->m_eventSlabAllocator.SlabAllocateArray<byte>(cAction->Length);
  1750. js_memcpy_s(cAction->Buffer, cAction->Length, buff, size);
  1751. }
  1752. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  1753. }
  1754. void EventLog::RecordJsRTAllocateFunction(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var optMetadata)
  1755. {
  1756. NSLogEvents::JsRTSingleVarArgumentAction* cAction = nullptr;
  1757. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::AllocateFunctionActionTag>(&cAction);
  1758. NSLogEvents::SetVarItem_0(cAction, TTD_CONVERT_JSVAR_TO_TTDVAR(optMetadata));
  1759. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  1760. }
  1761. void EventLog::RecordJsRTHostExitProcess(TTDJsRTActionResultAutoRecorder& actionPopper, int32 exitCode)
  1762. {
  1763. NSLogEvents::JsRTIntegralArgumentAction* eAction = nullptr;
  1764. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTIntegralArgumentAction, NSLogEvents::EventKind::HostExitProcessTag>(&eAction);
  1765. eAction->Scalar = exitCode;
  1766. actionPopper.InitializeWithEventAndEnter(evt);
  1767. }
  1768. void EventLog::RecordJsRTGetAndClearExceptionWithMetadata(TTDJsRTActionResultAutoRecorder& actionPopper)
  1769. {
  1770. NSLogEvents::JsRTResultOnlyAction* gcAction = nullptr;
  1771. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTResultOnlyAction, NSLogEvents::EventKind::GetAndClearExceptionWithMetadataActionTag>(&gcAction);
  1772. actionPopper.InitializeWithEventAndEnterWResult(evt, &(gcAction->Result));
  1773. }
  1774. void EventLog::RecordJsRTGetAndClearException(TTDJsRTActionResultAutoRecorder& actionPopper)
  1775. {
  1776. NSLogEvents::JsRTResultOnlyAction* gcAction = nullptr;
  1777. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTResultOnlyAction, NSLogEvents::EventKind::GetAndClearExceptionActionTag>(&gcAction);
  1778. actionPopper.InitializeWithEventAndEnterWResult(evt, &(gcAction->Result));
  1779. }
  1780. void EventLog::RecordJsRTSetException(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, bool propagateToDebugger)
  1781. {
  1782. NSLogEvents::JsRTSingleVarScalarArgumentAction* spAction = nullptr;
  1783. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarScalarArgumentAction, NSLogEvents::EventKind::SetExceptionActionTag>(&spAction);
  1784. NSLogEvents::SetVarItem_0(spAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1785. NSLogEvents::SetScalarItem_0(spAction, propagateToDebugger);
  1786. actionPopper.InitializeWithEventAndEnter(evt);
  1787. }
  1788. void EventLog::RecordJsRTHasProperty(TTDJsRTActionResultAutoRecorder& actionPopper, const Js::PropertyRecord* pRecord, Js::Var var)
  1789. {
  1790. //The host may not have validated this yet (and will exit early if the check fails) so we check it here as well before getting the property id below
  1791. if(pRecord == nullptr || Js::IsInternalPropertyId(pRecord->GetPropertyId()))
  1792. {
  1793. return;
  1794. }
  1795. NSLogEvents::JsRTSingleVarScalarArgumentAction* gpAction = nullptr;
  1796. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarScalarArgumentAction, NSLogEvents::EventKind::HasPropertyActionTag>(&gpAction);
  1797. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1798. NSLogEvents::SetPropertyIdItem(gpAction, pRecord->GetPropertyId());
  1799. actionPopper.InitializeWithEventAndEnter(evt);
  1800. }
  1801. void EventLog::RecordJsRTHasOwnProperty(TTDJsRTActionResultAutoRecorder& actionPopper, const Js::PropertyRecord* pRecord, Js::Var var)
  1802. {
  1803. //The host may not have validated this yet (and will exit early if the check fails) so we check it here as well before getting the property id below
  1804. if(pRecord == nullptr || Js::IsInternalPropertyId(pRecord->GetPropertyId()))
  1805. {
  1806. return;
  1807. }
  1808. NSLogEvents::JsRTSingleVarScalarArgumentAction* gpAction = nullptr;
  1809. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarScalarArgumentAction, NSLogEvents::EventKind::HasOwnPropertyActionTag>(&gpAction);
  1810. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1811. NSLogEvents::SetPropertyIdItem(gpAction, pRecord->GetPropertyId());
  1812. actionPopper.InitializeWithEventAndEnter(evt);
  1813. }
  1814. void EventLog::RecordJsRTInstanceOf(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var object, Js::Var constructor)
  1815. {
  1816. NSLogEvents::JsRTDoubleVarArgumentAction* gpAction = nullptr;
  1817. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTDoubleVarArgumentAction, NSLogEvents::EventKind::InstanceOfActionTag>(&gpAction);
  1818. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(object));
  1819. NSLogEvents::SetVarItem_1(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(constructor));
  1820. actionPopper.InitializeWithEventAndEnter(evt);
  1821. }
  1822. void EventLog::RecordJsRTEquals(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var1, Js::Var var2, bool doStrict)
  1823. {
  1824. NSLogEvents::JsRTDoubleVarSingleScalarArgumentAction* gpAction = nullptr;
  1825. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTDoubleVarSingleScalarArgumentAction, NSLogEvents::EventKind::EqualsActionTag>(&gpAction);
  1826. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var1));
  1827. NSLogEvents::SetVarItem_1(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var2));
  1828. NSLogEvents::SetScalarItem_0(gpAction, doStrict);
  1829. actionPopper.InitializeWithEventAndEnter(evt);
  1830. }
  1831. void EventLog::RecordJsRTLessThan(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var1, Js::Var var2, bool allowsEqual)
  1832. {
  1833. NSLogEvents::JsRTDoubleVarSingleScalarArgumentAction* gpAction = nullptr;
  1834. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTDoubleVarSingleScalarArgumentAction, NSLogEvents::EventKind::LessThanActionTag>(&gpAction);
  1835. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var1));
  1836. NSLogEvents::SetVarItem_1(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var2));
  1837. NSLogEvents::SetScalarItem_0(gpAction, allowsEqual);
  1838. actionPopper.InitializeWithEventAndEnter(evt);
  1839. }
  1840. void EventLog::RecordJsRTGetPropertyIdFromSymbol(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var sym)
  1841. {
  1842. NSLogEvents::JsRTSingleVarArgumentAction* gpAction = nullptr;
  1843. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::GetPropertyIdFromSymbolTag>(&gpAction);
  1844. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(sym));
  1845. actionPopper.InitializeWithEventAndEnter(evt);
  1846. }
  1847. void EventLog::RecordJsRTGetPrototype(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1848. {
  1849. NSLogEvents::JsRTSingleVarArgumentAction* gpAction = nullptr;
  1850. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::GetPrototypeActionTag>(&gpAction);
  1851. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1852. actionPopper.InitializeWithEventAndEnterWResult(evt, &(gpAction->Result));
  1853. }
  1854. void EventLog::RecordJsRTGetProperty(TTDJsRTActionResultAutoRecorder& actionPopper, const Js::PropertyRecord* pRecord, Js::Var var)
  1855. {
  1856. //The host may not have validated this yet (and will exit early if the check fails) so we check it here as well before getting the property id below
  1857. if(pRecord == nullptr || Js::IsInternalPropertyId(pRecord->GetPropertyId()))
  1858. {
  1859. return;
  1860. }
  1861. NSLogEvents::JsRTSingleVarScalarArgumentAction* gpAction = nullptr;
  1862. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarScalarArgumentAction, NSLogEvents::EventKind::GetPropertyActionTag>(&gpAction);
  1863. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1864. NSLogEvents::SetPropertyIdItem(gpAction, pRecord->GetPropertyId());
  1865. actionPopper.InitializeWithEventAndEnterWResult(evt, &(gpAction->Result));
  1866. }
  1867. void EventLog::RecordJsRTGetIndex(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var index, Js::Var var)
  1868. {
  1869. NSLogEvents::JsRTDoubleVarArgumentAction* giAction = nullptr;
  1870. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTDoubleVarArgumentAction, NSLogEvents::EventKind::GetIndexActionTag>(&giAction);
  1871. NSLogEvents::SetVarItem_0(giAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1872. NSLogEvents::SetVarItem_1(giAction, TTD_CONVERT_JSVAR_TO_TTDVAR(index));
  1873. actionPopper.InitializeWithEventAndEnterWResult(evt, &(giAction->Result));
  1874. }
  1875. void EventLog::RecordJsRTGetOwnPropertyInfo(TTDJsRTActionResultAutoRecorder& actionPopper, const Js::PropertyRecord* pRecord, Js::Var var)
  1876. {
  1877. //The host may not have validated this yet (and will exit early if the check fails) so we check it here as well before getting the property id below
  1878. if(pRecord == nullptr || Js::IsInternalPropertyId(pRecord->GetPropertyId()))
  1879. {
  1880. return;
  1881. }
  1882. NSLogEvents::JsRTSingleVarScalarArgumentAction* gpAction = nullptr;
  1883. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarScalarArgumentAction, NSLogEvents::EventKind::GetOwnPropertyInfoActionTag>(&gpAction);
  1884. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1885. NSLogEvents::SetPropertyIdItem(gpAction, pRecord->GetPropertyId());
  1886. actionPopper.InitializeWithEventAndEnterWResult(evt, &(gpAction->Result));
  1887. }
  1888. void EventLog::RecordJsRTGetOwnPropertyNamesInfo(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1889. {
  1890. NSLogEvents::JsRTSingleVarArgumentAction* gpAction = nullptr;
  1891. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::GetOwnPropertyNamesInfoActionTag>(&gpAction);
  1892. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1893. actionPopper.InitializeWithEventAndEnterWResult(evt, &(gpAction->Result));
  1894. }
  1895. void EventLog::RecordJsRTGetOwnPropertySymbolsInfo(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var)
  1896. {
  1897. NSLogEvents::JsRTSingleVarArgumentAction* gpAction = nullptr;
  1898. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::GetOwnPropertySymbolsInfoActionTag>(&gpAction);
  1899. NSLogEvents::SetVarItem_0(gpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1900. actionPopper.InitializeWithEventAndEnterWResult(evt, &(gpAction->Result));
  1901. }
  1902. void EventLog::RecordJsRTDefineProperty(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, const Js::PropertyRecord* pRecord, Js::Var propertyDescriptor)
  1903. {
  1904. //The host may not have validated this yet (and will exit early if the check fails) so we check it here as well before getting the property id below
  1905. if(pRecord == nullptr || Js::IsInternalPropertyId(pRecord->GetPropertyId()))
  1906. {
  1907. return;
  1908. }
  1909. NSLogEvents::JsRTDoubleVarSingleScalarArgumentAction* dpAction = nullptr;
  1910. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTDoubleVarSingleScalarArgumentAction, NSLogEvents::EventKind::DefinePropertyActionTag>(&dpAction);
  1911. NSLogEvents::SetVarItem_0(dpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1912. NSLogEvents::SetVarItem_1(dpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(propertyDescriptor));
  1913. NSLogEvents::SetPropertyIdItem(dpAction, pRecord->GetPropertyId());
  1914. actionPopper.InitializeWithEventAndEnter(evt);
  1915. }
  1916. void EventLog::RecordJsRTDeleteProperty(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, const Js::PropertyRecord* pRecord, bool useStrictRules)
  1917. {
  1918. //The host may not have validated this yet (and will exit early if the check fails) so we check it here as well before getting the property id below
  1919. if(pRecord == nullptr || Js::IsInternalPropertyId(pRecord->GetPropertyId()))
  1920. {
  1921. return;
  1922. }
  1923. NSLogEvents::JsRTSingleVarDoubleScalarArgumentAction* dpAction = nullptr;
  1924. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTSingleVarDoubleScalarArgumentAction, NSLogEvents::EventKind::DeletePropertyActionTag>(&dpAction);
  1925. NSLogEvents::SetVarItem_0(dpAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1926. NSLogEvents::SetPropertyIdItem(dpAction, pRecord->GetPropertyId());
  1927. NSLogEvents::SetScalarItem_1(dpAction, useStrictRules);
  1928. actionPopper.InitializeWithEventAndEnterWResult(evt, &(dpAction->Result));
  1929. }
  1930. void EventLog::RecordJsRTSetPrototype(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, Js::Var proto)
  1931. {
  1932. NSLogEvents::JsRTDoubleVarArgumentAction* spAction = nullptr;
  1933. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTDoubleVarArgumentAction, NSLogEvents::EventKind::SetPrototypeActionTag>(&spAction);
  1934. NSLogEvents::SetVarItem_0(spAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1935. NSLogEvents::SetVarItem_1(spAction, TTD_CONVERT_JSVAR_TO_TTDVAR(proto));
  1936. actionPopper.InitializeWithEventAndEnter(evt);
  1937. }
  1938. void EventLog::RecordJsRTSetProperty(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, const Js::PropertyRecord* pRecord, Js::Var val, bool useStrictRules)
  1939. {
  1940. //The host may not have validated this yet (and will exit early if the check fails) so we check it here as well before getting the property id below
  1941. if(pRecord == nullptr || Js::IsInternalPropertyId(pRecord->GetPropertyId()))
  1942. {
  1943. return;
  1944. }
  1945. NSLogEvents::JsRTDoubleVarDoubleScalarArgumentAction* spAction = nullptr;
  1946. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTDoubleVarDoubleScalarArgumentAction, NSLogEvents::EventKind::SetPropertyActionTag>(&spAction);
  1947. NSLogEvents::SetVarItem_0(spAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1948. NSLogEvents::SetVarItem_1(spAction, TTD_CONVERT_JSVAR_TO_TTDVAR(val));
  1949. NSLogEvents::SetPropertyIdItem(spAction, pRecord->GetPropertyId());
  1950. NSLogEvents::SetScalarItem_1(spAction, useStrictRules);
  1951. actionPopper.InitializeWithEventAndEnter(evt);
  1952. }
  1953. void EventLog::RecordJsRTSetIndex(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var var, Js::Var index, Js::Var val)
  1954. {
  1955. NSLogEvents::JsRTTrippleVarArgumentAction* spAction = nullptr;
  1956. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTTrippleVarArgumentAction, NSLogEvents::EventKind::SetIndexActionTag>(&spAction);
  1957. NSLogEvents::SetVarItem_0(spAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1958. NSLogEvents::SetVarItem_1(spAction, TTD_CONVERT_JSVAR_TO_TTDVAR(index));
  1959. NSLogEvents::SetVarItem_2(spAction, TTD_CONVERT_JSVAR_TO_TTDVAR(val));
  1960. actionPopper.InitializeWithEventAndEnter(evt);
  1961. }
  1962. void EventLog::RecordJsRTGetTypedArrayInfo(Js::Var var, Js::Var result)
  1963. {
  1964. NSLogEvents::JsRTSingleVarArgumentAction* giAction = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::GetTypedArrayInfoActionTag>();
  1965. NSLogEvents::SetVarItem_0(giAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1966. // entry/exit status should be set to clear by initialization so don't need to do anything
  1967. giAction->Result = TTD_CONVERT_JSVAR_TO_TTDVAR(result);
  1968. }
  1969. void EventLog::RecordJsRTGetDataViewInfo(Js::Var var, Js::Var result)
  1970. {
  1971. NSLogEvents::JsRTSingleVarArgumentAction* giAction = this->RecordGetInitializedEvent_DataOnly<NSLogEvents::JsRTSingleVarArgumentAction, NSLogEvents::EventKind::GetDataViewInfoActionTag>();
  1972. NSLogEvents::SetVarItem_0(giAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var));
  1973. // entry/exit status should be set to clear by initialization so don't need to do anything
  1974. giAction->Result = TTD_CONVERT_JSVAR_TO_TTDVAR(result);
  1975. }
  1976. void EventLog::RecordJsRTRawBufferCopySync(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var dst, uint32 dstIndex, Js::Var src, uint32 srcIndex, uint32 length)
  1977. {
  1978. TTDAssert(Js::ArrayBuffer::Is(dst) && Js::ArrayBuffer::Is(src), "Not array buffer objects!!!");
  1979. TTDAssert(dstIndex + length <= Js::ArrayBuffer::FromVar(dst)->GetByteLength(), "Copy off end of buffer!!!");
  1980. TTDAssert(srcIndex + length <= Js::ArrayBuffer::FromVar(src)->GetByteLength(), "Copy off end of buffer!!!");
  1981. NSLogEvents::JsRTRawBufferCopyAction* rbcAction = nullptr;
  1982. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTRawBufferCopyAction, NSLogEvents::EventKind::RawBufferCopySync>(&rbcAction);
  1983. rbcAction->Dst = TTD_CONVERT_JSVAR_TO_TTDVAR(dst);
  1984. rbcAction->Src = TTD_CONVERT_JSVAR_TO_TTDVAR(src);
  1985. rbcAction->DstIndx = dstIndex;
  1986. rbcAction->SrcIndx = srcIndex;
  1987. rbcAction->Count = length;
  1988. actionPopper.InitializeWithEventAndEnter(evt);
  1989. }
  1990. void EventLog::RecordJsRTRawBufferModifySync(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var dst, uint32 index, uint32 count)
  1991. {
  1992. TTDAssert(Js::ArrayBuffer::Is(dst), "Not array buffer object!!!");
  1993. TTDAssert(index + count <= Js::ArrayBuffer::FromVar(dst)->GetByteLength(), "Copy off end of buffer!!!");
  1994. NSLogEvents::JsRTRawBufferModifyAction* rbmAction = nullptr;
  1995. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTRawBufferModifyAction, NSLogEvents::EventKind::RawBufferModifySync>(&rbmAction);
  1996. rbmAction->Trgt = TTD_CONVERT_JSVAR_TO_TTDVAR(dst);
  1997. rbmAction->Index = index;
  1998. rbmAction->Length = count;
  1999. rbmAction->Data = (rbmAction->Length != 0) ? this->m_eventSlabAllocator.SlabAllocateArray<byte>(rbmAction->Length) : nullptr;
  2000. byte* copyBuff = Js::ArrayBuffer::FromVar(dst)->GetBuffer() + index;
  2001. js_memcpy_s(rbmAction->Data, rbmAction->Length, copyBuff, count);
  2002. actionPopper.InitializeWithEventAndEnter(evt);
  2003. }
  2004. void EventLog::RecordJsRTRawBufferAsyncModificationRegister(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var dst, uint32 index)
  2005. {
  2006. NSLogEvents::JsRTRawBufferModifyAction* rbrAction = nullptr;
  2007. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTRawBufferModifyAction, NSLogEvents::EventKind::RawBufferAsyncModificationRegister>(&rbrAction);
  2008. rbrAction->Trgt = TTD_CONVERT_JSVAR_TO_TTDVAR(dst);
  2009. rbrAction->Index = index;
  2010. actionPopper.InitializeWithEventAndEnter(evt);
  2011. }
  2012. void EventLog::RecordJsRTRawBufferAsyncModifyComplete(TTDJsRTActionResultAutoRecorder& actionPopper, TTDPendingAsyncBufferModification& pendingAsyncInfo, byte* finalModPos)
  2013. {
  2014. Js::ArrayBuffer* dstBuff = Js::ArrayBuffer::FromVar(pendingAsyncInfo.ArrayBufferVar);
  2015. byte* copyBuff = dstBuff->GetBuffer() + pendingAsyncInfo.Index;
  2016. NSLogEvents::JsRTRawBufferModifyAction* rbrAction = nullptr;
  2017. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTRawBufferModifyAction, NSLogEvents::EventKind::RawBufferAsyncModifyComplete>(&rbrAction);
  2018. rbrAction->Trgt = TTD_CONVERT_JSVAR_TO_TTDVAR(dstBuff);
  2019. rbrAction->Index = (uint32)pendingAsyncInfo.Index;
  2020. rbrAction->Length = (uint32)(finalModPos - copyBuff);
  2021. rbrAction->Data = (rbrAction->Length != 0) ? this->m_eventSlabAllocator.SlabAllocateArray<byte>(rbrAction->Length) : nullptr;
  2022. js_memcpy_s(rbrAction->Data, rbrAction->Length, copyBuff, rbrAction->Length);
  2023. actionPopper.InitializeWithEventAndEnter(evt);
  2024. }
  2025. void EventLog::RecordJsRTConstructCall(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var funcVar, uint32 argCount, Js::Var* args)
  2026. {
  2027. NSLogEvents::JsRTConstructCallAction* ccAction = nullptr;
  2028. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTConstructCallAction, NSLogEvents::EventKind::ConstructCallActionTag>(&ccAction);
  2029. ccAction->ArgCount = argCount + 1;
  2030. static_assert(sizeof(TTDVar) == sizeof(Js::Var), "These need to be the same size (and have same bit layout) for this to work!");
  2031. ccAction->ArgArray = this->m_eventSlabAllocator.SlabAllocateArray<TTDVar>(ccAction->ArgCount);
  2032. ccAction->ArgArray[0] = TTD_CONVERT_JSVAR_TO_TTDVAR(funcVar);
  2033. js_memcpy_s(ccAction->ArgArray + 1, (ccAction->ArgCount - 1) * sizeof(TTDVar), args, argCount * sizeof(Js::Var));
  2034. actionPopper.InitializeWithEventAndEnterWResult(evt, &(ccAction->Result));
  2035. }
  2036. NSLogEvents::EventLogEntry* EventLog::RecordJsRTCodeParse(TTDJsRTActionResultAutoRecorder& actionPopper, LoadScriptFlag loadFlag, bool isUft8, const byte* script, uint32 scriptByteLength, uint64 sourceContextId, const char16* sourceUri)
  2037. {
  2038. NSLogEvents::JsRTCodeParseAction* cpAction = nullptr;
  2039. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTCodeParseAction, NSLogEvents::EventKind::CodeParseActionTag>(&cpAction);
  2040. cpAction->BodyCtrId = 0; //initialize to known default -- should always update later or something is wrong
  2041. cpAction->IsUtf8 = isUft8;
  2042. cpAction->SourceByteLength = scriptByteLength;
  2043. cpAction->SourceCode = this->m_eventSlabAllocator.SlabAllocateArray<byte>(cpAction->SourceByteLength);
  2044. js_memcpy_s(cpAction->SourceCode, cpAction->SourceByteLength, script, scriptByteLength);
  2045. this->m_eventSlabAllocator.CopyNullTermStringInto(sourceUri, cpAction->SourceUri);
  2046. cpAction->SourceContextId = sourceContextId;
  2047. cpAction->LoadFlag = loadFlag;
  2048. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cpAction->Result));
  2049. return evt;
  2050. }
  2051. NSLogEvents::EventLogEntry* EventLog::RecordJsRTCallFunction(TTDJsRTActionResultAutoRecorder& actionPopper, int32 rootDepth, Js::Var funcVar, uint32 argCount, Js::Var* args)
  2052. {
  2053. NSLogEvents::JsRTCallFunctionAction* cAction = nullptr;
  2054. NSLogEvents::EventLogEntry* evt = this->RecordGetInitializedEvent<NSLogEvents::JsRTCallFunctionAction, NSLogEvents::EventKind::CallExistingFunctionActionTag>(&cAction);
  2055. int64 evtTime = this->GetLastEventTime();
  2056. int64 topLevelCallTime = (rootDepth == 0) ? evtTime : this->m_topLevelCallbackEventTime;
  2057. NSLogEvents::JsRTCallFunctionAction_ProcessArgs(evt, rootDepth, evtTime, funcVar, argCount, args, topLevelCallTime, this->m_eventSlabAllocator);
  2058. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  2059. NSLogEvents::JsRTCallFunctionAction_ProcessDiagInfoPre(evt, funcVar, this->m_eventSlabAllocator);
  2060. #endif
  2061. actionPopper.InitializeWithEventAndEnterWResult(evt, &(cAction->Result));
  2062. return evt;
  2063. }
  2064. void EventLog::InnerLoopEmitLog(const TTDebuggerSourceLocation& writeLocation, const char* emitUri, size_t emitUriLength)
  2065. {
  2066. //Events are slab allocated with header immediately followed by payload -- we need to replicate this layout here so we allocate an array and explicitly layout.
  2067. //See definition of GetNextAvailableEntry and GetInlineEventDataAs for more detail.
  2068. byte buff[TTD_EVENT_PLUS_DATA_SIZE(NSLogEvents::TTDInnerLoopLogWriteEventLogEntry)];
  2069. NSLogEvents::EventLogEntry* entry = reinterpret_cast<NSLogEvents::EventLogEntry*>(buff);
  2070. NSLogEvents::EventLogEntry_Initialize<NSLogEvents::EventKind::TTDInnerLoopLogWriteTag>(entry, this->m_eventTimeCtr);
  2071. NSLogEvents::TTDInnerLoopLogWriteEventLogEntry* evt = NSLogEvents::GetInlineEventDataAs<NSLogEvents::TTDInnerLoopLogWriteEventLogEntry, NSLogEvents::EventKind::TTDInnerLoopLogWriteTag>(entry);
  2072. evt->SourceScriptLogId = writeLocation.GetScriptLogTagId();
  2073. evt->EventTime = writeLocation.GetRootEventTime();
  2074. evt->FunctionTime = writeLocation.GetFunctionTime();
  2075. evt->LoopTime = writeLocation.GetLoopTime();
  2076. evt->TopLevelBodyId = writeLocation.GetTopLevelBodyId();
  2077. evt->FunctionLine = writeLocation.GetFunctionSourceLine();
  2078. evt->FunctionColumn = writeLocation.GetFunctionSourceColumn();
  2079. evt->Line = writeLocation.GetSourceLine();
  2080. evt->Column = writeLocation.GetSourceColumn();
  2081. this->EmitLog(emitUri, emitUriLength, entry);
  2082. }
  2083. bool EventLog::CanWriteInnerLoopTrace() const
  2084. {
  2085. bool isInnerLoop = (this->m_currentMode & (TTDMode::RecordDebuggerMode)) == TTDMode::RecordDebuggerMode;
  2086. bool isEnabled = (this->m_currentMode & (TTDMode::CurrentlyEnabled)) == TTDMode::CurrentlyEnabled;
  2087. return isInnerLoop & isEnabled;
  2088. }
  2089. void EventLog::SetAutoTraceEnabled(bool enabled)
  2090. {
  2091. this->m_autoTracesEnabled = enabled;
  2092. }
  2093. bool EventLog::GetAutoTraceEnabled() const
  2094. {
  2095. return this->m_autoTracesEnabled;
  2096. }
  2097. void EventLog::EmitLog(const char* emitUri, size_t emitUriLength, NSLogEvents::EventLogEntry* optInnerLoopEvent)
  2098. {
  2099. #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
  2100. this->m_threadContext->TTDExecutionInfo->GetTraceLogger()->ForceFlush();
  2101. #endif
  2102. TTDataIOInfo& iofp = this->m_threadContext->TTDContext->TTDataIOInfo;
  2103. iofp.ActiveTTUriLength = emitUriLength;
  2104. iofp.ActiveTTUri = emitUri;
  2105. const char* logfilename = "ttdlog.log";
  2106. JsTTDStreamHandle logHandle = iofp.pfOpenResourceStream(iofp.ActiveTTUriLength, iofp.ActiveTTUri, strlen(logfilename), logfilename, false, true);
  2107. TTDAssert(logHandle != nullptr, "Failed to initialize strem for writing TTD Log.");
  2108. TTD_LOG_WRITER writer(logHandle, iofp.pfWriteBytesToStream, iofp.pfFlushAndCloseStream);
  2109. writer.WriteRecordStart();
  2110. writer.AdjustIndent(1);
  2111. TTString archString;
  2112. #if defined(_M_IX86)
  2113. this->m_miscSlabAllocator.CopyNullTermStringInto(_u("x86"), archString);
  2114. #elif defined(_M_X64)
  2115. this->m_miscSlabAllocator.CopyNullTermStringInto(_u("x64"), archString);
  2116. #elif defined(_M_ARM)
  2117. this->m_miscSlabAllocator.CopyNullTermStringInto(_u("arm"), archString);
  2118. #elif defined(_M_ARM64)
  2119. this->m_miscSlabAllocator.CopyNullTermStringInto(_u("arm64"), archString);
  2120. #else
  2121. this->m_miscSlabAllocator.CopyNullTermStringInto(_u("unknown"), archString);
  2122. #endif
  2123. writer.WriteString(NSTokens::Key::arch, archString);
  2124. TTString platformString;
  2125. #if defined(_WIN32)
  2126. this->m_miscSlabAllocator.CopyNullTermStringInto(_u("Windows"), platformString);
  2127. #elif defined(__APPLE__)
  2128. this->m_miscSlabAllocator.CopyNullTermStringInto(_u("macOS"), platformString);
  2129. #else
  2130. this->m_miscSlabAllocator.CopyNullTermStringInto(_u("Linux"), platformString);
  2131. #endif
  2132. writer.WriteString(NSTokens::Key::platform, platformString, NSTokens::Separator::CommaSeparator);
  2133. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  2134. bool diagEnabled = true;
  2135. #else
  2136. bool diagEnabled = false;
  2137. #endif
  2138. writer.WriteBool(NSTokens::Key::diagEnabled, diagEnabled, NSTokens::Separator::CommaSeparator);
  2139. uint64 usedSpace = 0;
  2140. uint64 reservedSpace = 0;
  2141. this->m_eventSlabAllocator.ComputeMemoryUsed(&usedSpace, &reservedSpace);
  2142. writer.WriteUInt64(NSTokens::Key::usedMemory, usedSpace, NSTokens::Separator::CommaSeparator);
  2143. writer.WriteUInt64(NSTokens::Key::reservedMemory, reservedSpace, NSTokens::Separator::CommaSeparator);
  2144. uint32 ecount = this->m_eventList.Count() + (optInnerLoopEvent != nullptr ? 1 : 0);
  2145. writer.WriteLengthValue(ecount, NSTokens::Separator::CommaAndBigSpaceSeparator);
  2146. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  2147. JsUtil::Stack<int64, HeapAllocator> callNestingStack(&HeapAllocator::Instance);
  2148. #endif
  2149. bool firstElem = true;
  2150. writer.WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  2151. writer.AdjustIndent(1);
  2152. writer.WriteSeparator(NSTokens::Separator::BigSpaceSeparator);
  2153. for(auto iter = this->m_eventList.GetIteratorAtFirst(); iter.IsValid(); iter.MoveNext())
  2154. {
  2155. const NSLogEvents::EventLogEntry* evt = iter.Current();
  2156. NSTokens::Separator sep = firstElem ? NSTokens::Separator::NoSeparator : NSTokens::Separator::BigSpaceSeparator;
  2157. NSLogEvents::EventLogEntry_Emit(evt, this->m_eventListVTable, &writer, this->m_threadContext, sep);
  2158. firstElem = false;
  2159. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  2160. bool isJsRTCall = (evt->EventKind == NSLogEvents::EventKind::CallExistingFunctionActionTag);
  2161. bool isExternalCall = (evt->EventKind == NSLogEvents::EventKind::ExternalCallTag);
  2162. bool isRegisterCall = (evt->EventKind == NSLogEvents::EventKind::ExternalCbRegisterCall);
  2163. if(isJsRTCall | isExternalCall | isRegisterCall)
  2164. {
  2165. writer.WriteSequenceStart(NSTokens::Separator::BigSpaceSeparator);
  2166. int64 lastNestedTime = -1;
  2167. if(isJsRTCall)
  2168. {
  2169. lastNestedTime = NSLogEvents::JsRTCallFunctionAction_GetLastNestedEventTime(evt);
  2170. }
  2171. else if(isExternalCall)
  2172. {
  2173. lastNestedTime = NSLogEvents::ExternalCallEventLogEntry_GetLastNestedEventTime(evt);
  2174. }
  2175. else
  2176. {
  2177. lastNestedTime = NSLogEvents::ExternalCbRegisterCallEventLogEntry_GetLastNestedEventTime(evt);
  2178. }
  2179. callNestingStack.Push(lastNestedTime);
  2180. if(lastNestedTime != evt->EventTimeStamp)
  2181. {
  2182. writer.AdjustIndent(1);
  2183. writer.WriteSeparator(NSTokens::Separator::BigSpaceSeparator);
  2184. firstElem = true;
  2185. }
  2186. }
  2187. if(!callNestingStack.Empty() && evt->EventTimeStamp == callNestingStack.Peek())
  2188. {
  2189. int64 eTime = callNestingStack.Pop();
  2190. if(!isJsRTCall & !isExternalCall & !isRegisterCall)
  2191. {
  2192. writer.AdjustIndent(-1);
  2193. writer.WriteSeparator(NSTokens::Separator::BigSpaceSeparator);
  2194. }
  2195. writer.WriteSequenceEnd();
  2196. while(!callNestingStack.Empty() && eTime == callNestingStack.Peek())
  2197. {
  2198. callNestingStack.Pop();
  2199. writer.AdjustIndent(-1);
  2200. writer.WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
  2201. }
  2202. }
  2203. #endif
  2204. }
  2205. if (optInnerLoopEvent != nullptr)
  2206. {
  2207. //Emit the special event that indicates we want to break at the end of the log (with a known breakpoint time)
  2208. NSLogEvents::EventLogEntry_Emit(optInnerLoopEvent, this->m_eventListVTable, &writer, this->m_threadContext, NSTokens::Separator::BigSpaceSeparator);
  2209. }
  2210. writer.AdjustIndent(-1);
  2211. writer.WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
  2212. //emit the properties
  2213. writer.WriteLengthValue(this->m_propertyRecordPinSet->Count(), NSTokens::Separator::CommaSeparator);
  2214. writer.WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  2215. writer.AdjustIndent(1);
  2216. bool firstProperty = true;
  2217. for(auto iter = this->m_propertyRecordPinSet->GetIterator(); iter.IsValid(); iter.MoveNext())
  2218. {
  2219. NSTokens::Separator sep = (!firstProperty) ? NSTokens::Separator::CommaAndBigSpaceSeparator : NSTokens::Separator::BigSpaceSeparator;
  2220. NSSnapType::EmitPropertyRecordAsSnapPropertyRecord(iter.CurrentValue(), &writer, sep);
  2221. firstProperty = false;
  2222. }
  2223. writer.AdjustIndent(-1);
  2224. writer.WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
  2225. //do top level script processing here
  2226. writer.WriteUInt32(NSTokens::Key::u32Val, this->m_sourceInfoCount, NSTokens::Separator::CommaSeparator);
  2227. writer.WriteLengthValue(this->m_loadedTopLevelScripts.Count(), NSTokens::Separator::CommaSeparator);
  2228. writer.WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  2229. writer.AdjustIndent(1);
  2230. bool firstLoadScript = true;
  2231. for(auto iter = this->m_loadedTopLevelScripts.GetIterator(); iter.IsValid(); iter.MoveNext())
  2232. {
  2233. NSTokens::Separator sep = (!firstLoadScript) ? NSTokens::Separator::CommaAndBigSpaceSeparator : NSTokens::Separator::BigSpaceSeparator;
  2234. NSSnapValues::EmitTopLevelLoadedFunctionBodyInfo(iter.Current(), this->m_threadContext, &writer, sep);
  2235. firstLoadScript = false;
  2236. }
  2237. writer.AdjustIndent(-1);
  2238. writer.WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
  2239. writer.WriteLengthValue(this->m_newFunctionTopLevelScripts.Count(), NSTokens::Separator::CommaSeparator);
  2240. writer.WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  2241. writer.AdjustIndent(1);
  2242. bool firstNewScript = true;
  2243. for(auto iter = this->m_newFunctionTopLevelScripts.GetIterator(); iter.IsValid(); iter.MoveNext())
  2244. {
  2245. NSTokens::Separator sep = (!firstNewScript) ? NSTokens::Separator::CommaAndBigSpaceSeparator : NSTokens::Separator::BigSpaceSeparator;
  2246. NSSnapValues::EmitTopLevelNewFunctionBodyInfo(iter.Current(), this->m_threadContext, &writer, sep);
  2247. firstNewScript = false;
  2248. }
  2249. writer.AdjustIndent(-1);
  2250. writer.WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
  2251. writer.WriteLengthValue(this->m_evalTopLevelScripts.Count(), NSTokens::Separator::CommaSeparator);
  2252. writer.WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  2253. writer.AdjustIndent(1);
  2254. bool firstEvalScript = true;
  2255. for(auto iter = this->m_evalTopLevelScripts.GetIterator(); iter.IsValid(); iter.MoveNext())
  2256. {
  2257. NSTokens::Separator sep = (!firstEvalScript) ? NSTokens::Separator::CommaAndBigSpaceSeparator : NSTokens::Separator::BigSpaceSeparator;
  2258. NSSnapValues::EmitTopLevelEvalFunctionBodyInfo(iter.Current(), this->m_threadContext, &writer, sep);
  2259. firstEvalScript = false;
  2260. }
  2261. writer.AdjustIndent(-1);
  2262. writer.WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
  2263. //
  2264. writer.AdjustIndent(-1);
  2265. writer.WriteRecordEnd(NSTokens::Separator::BigSpaceSeparator);
  2266. writer.FlushAndClose();
  2267. iofp.ActiveTTUriLength = 0;
  2268. iofp.ActiveTTUri = nullptr;
  2269. }
  2270. void EventLog::ParseLogInto(TTDataIOInfo& iofp, const char* parseUri, size_t parseUriLength)
  2271. {
  2272. iofp.ActiveTTUriLength = parseUriLength;
  2273. iofp.ActiveTTUri = parseUri;
  2274. const char* logfilename = "ttdlog.log";
  2275. JsTTDStreamHandle logHandle = iofp.pfOpenResourceStream(iofp.ActiveTTUriLength, iofp.ActiveTTUri, strlen(logfilename), logfilename, true, false);
  2276. TTDAssert(logHandle != nullptr, "Failed to initialize strem for reading TTD Log.");
  2277. TTD_LOG_READER reader(logHandle, iofp.pfReadBytesFromStream, iofp.pfFlushAndCloseStream);
  2278. reader.ReadRecordStart();
  2279. TTString archString;
  2280. reader.ReadString(NSTokens::Key::arch, this->m_miscSlabAllocator, archString);
  2281. #if defined(_M_IX86)
  2282. TTDAssert(wcscmp(_u("x86"), archString.Contents) == 0, "Mismatch in arch between record and replay!!!");
  2283. #elif defined(_M_X64)
  2284. TTDAssert(wcscmp(_u("x64"), archString.Contents) == 0, "Mismatch in arch between record and replay!!!");
  2285. #elif defined(_M_ARM)
  2286. TTDAssert(wcscmp(_u("arm64"), archString.Contents) == 0, "Mismatch in arch between record and replay!!!");
  2287. #else
  2288. TTDAssert(false, "Unknown arch!!!");
  2289. #endif
  2290. //This is informational only so just read off the value and ignore
  2291. TTString platformString;
  2292. reader.ReadString(NSTokens::Key::platform, this->m_miscSlabAllocator, platformString, true);
  2293. bool diagEnabled = reader.ReadBool(NSTokens::Key::diagEnabled, true);
  2294. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  2295. TTDAssert(diagEnabled, "Diag was enabled in record so it should be in replay as well!!!");
  2296. #else
  2297. TTDAssert(!diagEnabled, "Diag was *not* enabled in record so it should *not* be in replay either!!!");
  2298. #endif
  2299. reader.ReadUInt64(NSTokens::Key::usedMemory, true);
  2300. reader.ReadUInt64(NSTokens::Key::reservedMemory, true);
  2301. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  2302. JsUtil::Stack<int64, HeapAllocator> callNestingStack(&HeapAllocator::Instance);
  2303. bool doSep = false;
  2304. #endif
  2305. uint32 ecount = reader.ReadLengthValue(true);
  2306. reader.ReadSequenceStart_WDefaultKey(true);
  2307. for(uint32 i = 0; i < ecount; ++i)
  2308. {
  2309. NSLogEvents::EventKind evtKind = NSLogEvents::EventLogEntry_ParseHeader(false, &reader);
  2310. NSLogEvents::EventLogEntry* evt = this->m_eventList.GetNextAvailableEntry(this->m_eventListVTable[(uint32)evtKind].DataSize);
  2311. evt->EventKind = evtKind;
  2312. NSLogEvents::EventLogEntry_ParseRest(evt, this->m_eventListVTable, this->m_threadContext, &reader, this->m_eventSlabAllocator);
  2313. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  2314. bool isJsRTCall = (evt->EventKind == NSLogEvents::EventKind::CallExistingFunctionActionTag);
  2315. bool isExternalCall = (evt->EventKind == NSLogEvents::EventKind::ExternalCallTag);
  2316. bool isRegisterCall = (evt->EventKind == NSLogEvents::EventKind::ExternalCbRegisterCall);
  2317. if(isJsRTCall | isExternalCall | isRegisterCall)
  2318. {
  2319. reader.ReadSequenceStart(false);
  2320. int64 lastNestedTime = -1;
  2321. if(isJsRTCall)
  2322. {
  2323. lastNestedTime = NSLogEvents::JsRTCallFunctionAction_GetLastNestedEventTime(evt);
  2324. }
  2325. else if(isExternalCall)
  2326. {
  2327. lastNestedTime = NSLogEvents::ExternalCallEventLogEntry_GetLastNestedEventTime(evt);
  2328. }
  2329. else
  2330. {
  2331. lastNestedTime = NSLogEvents::ExternalCbRegisterCallEventLogEntry_GetLastNestedEventTime(evt);
  2332. }
  2333. callNestingStack.Push(lastNestedTime);
  2334. }
  2335. doSep = (!isJsRTCall & !isExternalCall & !isRegisterCall);
  2336. while(callNestingStack.Count() != 0 && evt->EventTimeStamp == callNestingStack.Peek())
  2337. {
  2338. callNestingStack.Pop();
  2339. reader.ReadSequenceEnd();
  2340. }
  2341. #endif
  2342. }
  2343. reader.ReadSequenceEnd();
  2344. //parse the properties
  2345. uint32 propertyCount = reader.ReadLengthValue(true);
  2346. reader.ReadSequenceStart_WDefaultKey(true);
  2347. for(uint32 i = 0; i < propertyCount; ++i)
  2348. {
  2349. NSSnapType::SnapPropertyRecord* sRecord = this->m_propertyRecordList.NextOpenEntry();
  2350. NSSnapType::ParseSnapPropertyRecord(sRecord, i != 0, &reader, this->m_miscSlabAllocator);
  2351. }
  2352. reader.ReadSequenceEnd();
  2353. //do top level script processing here
  2354. this->m_sourceInfoCount = reader.ReadUInt32(NSTokens::Key::u32Val, true);
  2355. uint32 loadedScriptCount = reader.ReadLengthValue(true);
  2356. reader.ReadSequenceStart_WDefaultKey(true);
  2357. for(uint32 i = 0; i < loadedScriptCount; ++i)
  2358. {
  2359. NSSnapValues::TopLevelScriptLoadFunctionBodyResolveInfo* fbInfo = this->m_loadedTopLevelScripts.NextOpenEntry();
  2360. NSSnapValues::ParseTopLevelLoadedFunctionBodyInfo(fbInfo, i != 0, this->m_threadContext, &reader, this->m_miscSlabAllocator);
  2361. }
  2362. reader.ReadSequenceEnd();
  2363. uint32 newScriptCount = reader.ReadLengthValue(true);
  2364. reader.ReadSequenceStart_WDefaultKey(true);
  2365. for(uint32 i = 0; i < newScriptCount; ++i)
  2366. {
  2367. NSSnapValues::TopLevelNewFunctionBodyResolveInfo* fbInfo = this->m_newFunctionTopLevelScripts.NextOpenEntry();
  2368. NSSnapValues::ParseTopLevelNewFunctionBodyInfo(fbInfo, i != 0, this->m_threadContext, &reader, this->m_miscSlabAllocator);
  2369. }
  2370. reader.ReadSequenceEnd();
  2371. uint32 evalScriptCount = reader.ReadLengthValue(true);
  2372. reader.ReadSequenceStart_WDefaultKey(true);
  2373. for(uint32 i = 0; i < evalScriptCount; ++i)
  2374. {
  2375. NSSnapValues::TopLevelEvalFunctionBodyResolveInfo* fbInfo = this->m_evalTopLevelScripts.NextOpenEntry();
  2376. NSSnapValues::ParseTopLevelEvalFunctionBodyInfo(fbInfo, i != 0, this->m_threadContext, &reader, this->m_miscSlabAllocator);
  2377. }
  2378. reader.ReadSequenceEnd();
  2379. //
  2380. reader.ReadRecordEnd();
  2381. //After reading setup the previous event map
  2382. this->m_eventList.InitializePreviousEventMap();
  2383. }
  2384. }
  2385. #endif