TTEventLog.cpp 145 KB

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