TTEventLog.cpp 139 KB

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