| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "RuntimeDebugPch.h"
- #if ENABLE_TTD
- namespace TTD
- {
- TTDebuggerAbortException::TTDebuggerAbortException(uint32 abortCode, int64 optEventTime, int64 optMoveMode, const char16* staticAbortMessage)
- : m_abortCode(abortCode), m_optEventTime(optEventTime), m_optMoveMode(optMoveMode), m_staticAbortMessage(staticAbortMessage)
- {
- ;
- }
- TTDebuggerAbortException::~TTDebuggerAbortException()
- {
- ;
- }
- TTDebuggerAbortException TTDebuggerAbortException::CreateAbortEndOfLog(const char16* staticMessage)
- {
- return TTDebuggerAbortException(1, -1, 0, staticMessage);
- }
- TTDebuggerAbortException TTDebuggerAbortException::CreateTopLevelAbortRequest(int64 targetEventTime, int64 moveMode, const char16* staticMessage)
- {
- return TTDebuggerAbortException(2, targetEventTime, moveMode, staticMessage);
- }
- TTDebuggerAbortException TTDebuggerAbortException::CreateUncaughtExceptionAbortRequest(int64 targetEventTime, const char16* staticMessage)
- {
- return TTDebuggerAbortException(3, targetEventTime, 0, staticMessage);
- }
- bool TTDebuggerAbortException::IsEndOfLog() const
- {
- return this->m_abortCode == 1;
- }
- bool TTDebuggerAbortException::IsEventTimeMove() const
- {
- return this->m_abortCode == 2;
- }
- bool TTDebuggerAbortException::IsTopLevelException() const
- {
- return this->m_abortCode == 3;
- }
- int64 TTDebuggerAbortException::GetTargetEventTime() const
- {
- return this->m_optEventTime;
- }
- int64 TTDebuggerAbortException::GetMoveMode() const
- {
- return this->m_optMoveMode;
- }
- const char16* TTDebuggerAbortException::GetStaticAbortMessage() const
- {
- return this->m_staticAbortMessage;
- }
- Js::FunctionBody* TTDebuggerSourceLocation::UpdatePostInflateFunctionBody_Helper(Js::FunctionBody* rootBody) const
- {
- for(uint32 i = 0; i < rootBody->GetNestedCount(); ++i)
- {
- Js::ParseableFunctionInfo* ipfi = rootBody->GetNestedFunctionForExecution(i);
- Js::FunctionBody* ifb = JsSupport::ForceAndGetFunctionBody(ipfi);
- if(this->m_functionLine == ifb->GetLineNumber() && this->m_functionColumn == ifb->GetColumnNumber())
- {
- return ifb;
- }
- else
- {
- Js::FunctionBody* found = this->UpdatePostInflateFunctionBody_Helper(ifb);
- if(found != nullptr)
- {
- return found;
- }
- }
- }
- return nullptr;
- }
- TTDebuggerSourceLocation::TTDebuggerSourceLocation()
- : m_sourceScriptLogId(TTD_INVALID_LOG_PTR_ID), m_bpId(-1),
- m_etime(-1), m_ftime(0), m_ltime(0),
- m_topLevelBodyId(0), m_functionLine(0), m_functionColumn(0), m_line(0), m_column(0)
- {
- ;
- }
- TTDebuggerSourceLocation::TTDebuggerSourceLocation(const TTDebuggerSourceLocation& other)
- : m_sourceScriptLogId(other.m_sourceScriptLogId), m_bpId(other.m_bpId),
- m_etime(other.m_etime), m_ftime(other.m_ftime), m_ltime(other.m_ltime),
- m_topLevelBodyId(other.m_topLevelBodyId), m_functionLine(other.m_functionLine), m_functionColumn(other.m_functionColumn), m_line(other.m_line), m_column(other.m_column)
- {
- ;
- }
- TTDebuggerSourceLocation::~TTDebuggerSourceLocation()
- {
- this->Clear();
- }
- TTDebuggerSourceLocation& TTDebuggerSourceLocation::operator= (const TTDebuggerSourceLocation& other)
- {
- if(this != &other)
- {
- this->SetLocationCopy(other);
- }
- return *this;
- }
- #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
- void TTDebuggerSourceLocation::PrintToConsole() const
- {
- if(!this->HasValue())
- {
- wprintf(_u("undef"));
- }
- else
- {
- wprintf(_u("BP: { bpId: %I64i, ctx: %I64u, topId: %I32u, fline: %I32u, fcolumn: %I32u, line: %I32u, column: %I32u }"), this->m_bpId, this->m_sourceScriptLogId, this->m_topLevelBodyId, this->m_functionLine, this->m_functionColumn, this->m_line, this->m_column);
- if(this->m_etime != -1)
- {
- wprintf(_u(" TTDTime: { etime: %I64i, ftime: %I64i, ltime: %I64i }"), this->m_etime, this->m_ftime, this->m_ltime);
- }
- }
- }
- #endif
- void TTDebuggerSourceLocation::Initialize()
- {
- this->m_sourceScriptLogId = TTD_INVALID_LOG_PTR_ID;
- this->m_bpId = -1;
- this->m_etime = -1;
- this->m_ftime = 0;
- this->m_ltime = 0;
- this->m_topLevelBodyId = 0;
- this->m_functionLine = 0;
- this->m_functionColumn = 0;
- this->m_line = 0;
- this->m_column = 0;
- }
- bool TTDebuggerSourceLocation::HasValue() const
- {
- return this->m_sourceScriptLogId != TTD_INVALID_LOG_PTR_ID;
- }
- bool TTDebuggerSourceLocation::HasTTDTimeValue() const
- {
- return this->m_etime != -1;
- }
- void TTDebuggerSourceLocation::Clear()
- {
- this->m_sourceScriptLogId = TTD_INVALID_LOG_PTR_ID;
- this->m_bpId = -1;
- this->m_etime = -1;
- this->m_ftime = 0;
- this->m_ltime = 0;
- this->m_topLevelBodyId = 0;
- this->m_functionLine = 0;
- this->m_functionColumn = 0;
- this->m_line = 0;
- this->m_column = 0;
- }
- void TTDebuggerSourceLocation::SetLocationCopy(const TTDebuggerSourceLocation& other)
- {
- this->m_sourceScriptLogId = other.m_sourceScriptLogId;
- this->m_bpId = other.m_bpId;
- this->m_etime = other.m_etime;
- this->m_ftime = other.m_ftime;
- this->m_ltime = other.m_ltime;
- this->m_topLevelBodyId = other.m_topLevelBodyId;
- this->m_functionLine = other.m_functionLine;
- this->m_functionColumn = other.m_functionColumn;
- this->m_line = other.m_line;
- this->m_column = other.m_column;
- }
- void TTDebuggerSourceLocation::SetLocationFromFrame(int64 topLevelETime, const SingleCallCounter& callFrame)
- {
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = callFrame.Function->GetStatementStartOffset(callFrame.CurrentStatementIndex);
- callFrame.Function->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- this->SetLocationFull(topLevelETime, callFrame.FunctionTime, callFrame.LoopTime, callFrame.Function, (uint32)srcLine, (uint32)srcColumn);
- }
- void TTDebuggerSourceLocation::SetLocationFromFunctionEntryAnyTime(int64 topLevelETime, Js::FunctionBody* body)
- {
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = body->GetStatementStartOffset(0);
- body->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- this->SetLocationFull(topLevelETime, -1, -1, body, (uint32)srcLine, (uint32)srcColumn);
- }
- void TTDebuggerSourceLocation::SetLocationFull(int64 etime, int64 ftime, int64 ltime, Js::FunctionBody* body, ULONG line, LONG column)
- {
- this->m_sourceScriptLogId = body->GetScriptContext()->ScriptContextLogTag;
- this->m_bpId = -1;
- this->m_etime = etime;
- this->m_ftime = ftime;
- this->m_ltime = ltime;
- this->m_topLevelBodyId = body->GetScriptContext()->TTDContextInfo->FindTopLevelCtrForBody(body);
- this->m_functionLine = body->GetLineNumber();
- this->m_functionColumn = body->GetColumnNumber();
- this->m_line = (uint32)line;
- this->m_column = (uint32)column;
- }
- void TTDebuggerSourceLocation::SetLocationFullRaw(TTD_LOG_PTR_ID sourceScriptLogId, int64 etime, int64 ftime, int64 ltime, uint32 topLevelBodyId, uint32 functionLine, uint32 functionColumn, ULONG line, LONG column)
- {
- this->m_sourceScriptLogId = sourceScriptLogId;
- this->m_bpId = -1;
- this->m_etime = etime;
- this->m_ftime = ftime;
- this->m_ltime = ltime;
- this->m_topLevelBodyId = topLevelBodyId;
- this->m_functionLine = functionLine;
- this->m_functionColumn = functionColumn;
- this->m_line = (uint32)line;
- this->m_column = (uint32)column;
- }
- void TTDebuggerSourceLocation::SetLocationWithBP(int64 bpId, Js::FunctionBody* body, ULONG line, LONG column)
- {
- this->m_sourceScriptLogId = body->GetScriptContext()->ScriptContextLogTag;
- this->m_bpId = bpId;
- this->m_etime = -1;
- this->m_ftime = -1;
- this->m_ltime = -1;
- this->m_topLevelBodyId = body->GetScriptContext()->TTDContextInfo->FindTopLevelCtrForBody(body);
- this->m_functionLine = body->GetLineNumber();
- this->m_functionColumn = body->GetColumnNumber();
- this->m_line = (uint32)line;
- this->m_column = (uint32)column;
- }
- int64 TTDebuggerSourceLocation::GetRootEventTime() const
- {
- return this->m_etime;
- }
- int64 TTDebuggerSourceLocation::GetFunctionTime() const
- {
- return this->m_ftime;
- }
- int64 TTDebuggerSourceLocation::GetLoopTime() const
- {
- return this->m_ltime;
- }
- TTD_LOG_PTR_ID TTDebuggerSourceLocation::GetScriptLogTagId() const
- {
- return this->m_sourceScriptLogId;
- }
- Js::FunctionBody* TTDebuggerSourceLocation::LoadFunctionBodyIfPossible(Js::ScriptContext* inCtx) const
- {
- Js::FunctionBody* rootBody = inCtx->TTDContextInfo->FindRootBodyByTopLevelCtr(this->m_topLevelBodyId);
- if(rootBody == nullptr)
- {
- return nullptr;
- }
- if(this->m_functionLine == rootBody->GetLineNumber() && this->m_functionColumn == rootBody->GetColumnNumber())
- {
- return rootBody;
- }
- else
- {
- return this->UpdatePostInflateFunctionBody_Helper(rootBody);
- }
- }
- int64 TTDebuggerSourceLocation::GetBPId() const
- {
- return this->m_bpId;
- }
- uint32 TTDebuggerSourceLocation::GetTopLevelBodyId() const
- {
- return this->m_topLevelBodyId;
- }
- uint32 TTDebuggerSourceLocation::GetFunctionSourceLine() const
- {
- return this->m_functionLine;
- }
- uint32 TTDebuggerSourceLocation::GetFunctionSourceColumn() const
- {
- return this->m_functionColumn;
- }
- uint32 TTDebuggerSourceLocation::GetSourceLine() const
- {
- return this->m_line;
- }
- uint32 TTDebuggerSourceLocation::GetSourceColumn() const
- {
- return this->m_column;
- }
- bool TTDebuggerSourceLocation::AreSameLocations(const TTDebuggerSourceLocation& sl1, const TTDebuggerSourceLocation& sl2)
- {
- //first check the code locations
- if(sl1.m_topLevelBodyId != sl2.m_topLevelBodyId || sl1.m_line != sl2.m_line || sl1.m_column != sl2.m_column)
- {
- return false;
- }
- //next check the time values
- if(sl1.m_etime != sl2.m_etime || sl1.m_ftime != sl2.m_ftime || sl1.m_ltime != sl2.m_ltime)
- {
- return false;
- }
- return true;
- }
- bool TTDebuggerSourceLocation::AreSameLocations_PlaceOnly(const TTDebuggerSourceLocation& sl1, const TTDebuggerSourceLocation& sl2)
- {
- return (sl1.m_topLevelBodyId == sl2.m_topLevelBodyId && sl1.m_line == sl2.m_line && sl1.m_column == sl2.m_column);
- }
- TTLastReturnLocationInfo::TTLastReturnLocationInfo()
- : m_isExceptionFrame(false)
- {
- this->m_lastFrame = { 0 };
- }
- void TTLastReturnLocationInfo::SetReturnLocation(const SingleCallCounter& cframe)
- {
- this->m_isExceptionFrame = false;
- this->m_lastFrame = cframe;
- }
- void TTLastReturnLocationInfo::SetExceptionLocation(const SingleCallCounter& cframe)
- {
- this->m_isExceptionFrame = true;
- this->m_lastFrame = cframe;
- }
- bool TTLastReturnLocationInfo::IsDefined() const
- {
- return this->m_lastFrame.Function != nullptr;
- }
- bool TTLastReturnLocationInfo::IsReturnLocation() const
- {
- return this->IsDefined() && !this->m_isExceptionFrame;
- }
- bool TTLastReturnLocationInfo::IsExceptionLocation() const
- {
- return this->IsDefined() && this->m_isExceptionFrame;
- }
- const SingleCallCounter& TTLastReturnLocationInfo::GetLocation() const
- {
- TTDAssert(this->IsDefined(), "Should check this!");
- return this->m_lastFrame;
- }
- void TTLastReturnLocationInfo::Clear()
- {
- if(this->IsDefined())
- {
- this->m_isExceptionFrame = false;
- this->m_lastFrame = { 0 };
- }
- }
- void TTLastReturnLocationInfo::ClearReturnOnly()
- {
- if(this->IsDefined() && !this->m_isExceptionFrame)
- {
- this->Clear();
- }
- }
- void TTLastReturnLocationInfo::ClearExceptionOnly()
- {
- if(this->IsDefined() && this->m_isExceptionFrame)
- {
- this->Clear();
- }
- }
- TTInnerLoopLastStatementInfo::TTInnerLoopLastStatementInfo()
- : m_eventTime(-1), m_functionTime(0), m_loopTime(0), m_line(0), m_column(0)
- {
- ;
- }
- TTInnerLoopLastStatementInfo::TTInnerLoopLastStatementInfo(const TTInnerLoopLastStatementInfo& lsi)
- : m_eventTime(lsi.m_eventTime), m_functionTime(lsi.m_functionTime), m_loopTime(lsi.m_loopTime), m_line(lsi.m_line), m_column(lsi.m_column)
- {
- ;
- }
- bool TTInnerLoopLastStatementInfo::IsEnabled() const
- {
- return this->m_eventTime != -1;
- }
- void TTInnerLoopLastStatementInfo::SetLastLine(int64 etime, int64 ftime, int64 ltime, uint32 line, uint32 column)
- {
- this->m_eventTime = etime;
- this->m_functionTime = ftime;
- this->m_loopTime = ltime;
- this->m_line = line;
- this->m_column = column;
- }
- bool TTInnerLoopLastStatementInfo::CheckLastTimeMatch(int64 etime, int64 ftime, int64 ltime) const
- {
- return (this->m_eventTime == etime) & (this->m_functionTime == ftime) & (this->m_loopTime == ltime);
- }
- bool TTInnerLoopLastStatementInfo::CheckLineColumnMatch(uint32 line, uint32 column) const
- {
- return (this->m_line == line) & (this->m_column == column);
- }
- //////////////////
- bool ExecutionInfoManager::ShouldSuppressBreakpointsForTimeTravelMove(TTDMode mode)
- {
- return (mode & TTD::TTDMode::DebuggerSuppressBreakpoints) == TTD::TTDMode::DebuggerSuppressBreakpoints;
- }
- bool ExecutionInfoManager::ShouldRecordBreakpointsDuringTimeTravelScan(TTDMode mode)
- {
- return (mode & TTD::TTDMode::DebuggerLogBreakpoints) == TTD::TTDMode::DebuggerLogBreakpoints;
- }
- ExecutionInfoManager::ExecutionInfoManager(const TTInnerLoopLastStatementInfo& lsi)
- : m_topLevelCallbackEventTime(-1), m_runningFunctionTimeCtr(0), m_callStack(&HeapAllocator::Instance),
- m_debuggerNotifiedTopLevelBodies(&HeapAllocator::Instance),
- m_lastReturnLocation(), m_lastExceptionPropagating(false), m_lastExceptionLocation(),
- m_breakOnFirstUserCode(false),
- m_pendingTTDBP(), m_pendingTTDMoveMode(-1), m_activeBPId(-1), m_shouldRemoveWhenDone(false), m_activeTTDBP(),
- m_hitContinueSearchBP(false), m_continueBreakPoint(),
- m_unRestoredBreakpoints(&HeapAllocator::Instance),
- m_innerloopLastLocation(lsi)
- {
- ;
- }
- ExecutionInfoManager::~ExecutionInfoManager()
- {
- if(this->m_unRestoredBreakpoints.Count() != 0)
- {
- for(int32 i = 0; i < this->m_unRestoredBreakpoints.Count(); ++i)
- {
- HeapDelete(this->m_unRestoredBreakpoints.Item(i));
- }
- }
- }
- #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
- TraceLogger* ExecutionInfoManager::GetTraceLogger()
- {
- return &(this->m_diagnosticLogger);
- }
- #endif
- const SingleCallCounter& ExecutionInfoManager::GetTopCallCounter() const
- {
- TTDAssert(this->m_callStack.Count() != 0, "Empty stack!");
- return this->m_callStack.Item(this->m_callStack.Count() - 1);
- }
- SingleCallCounter& ExecutionInfoManager::GetTopCallCounter()
- {
- TTDAssert(this->m_callStack.Count() != 0, "Empty stack!");
- return this->m_callStack.Item(this->m_callStack.Count() - 1);
- }
- bool ExecutionInfoManager::TryGetTopCallCallerCounter(SingleCallCounter& caller) const
- {
- if(this->m_callStack.Count() < 2)
- {
- return false;
- }
- else
- {
- caller = this->m_callStack.Item(this->m_callStack.Count() - 2);
- return true;
- }
- }
- void ExecutionInfoManager::PushCallEvent(Js::JavascriptFunction* function, uint32 argc, Js::Var* argv, bool isInFinally)
- {
- //Clear any previous last return frame info
- this->m_lastReturnLocation.ClearReturnOnly();
- this->m_runningFunctionTimeCtr++;
- SingleCallCounter cfinfo;
- cfinfo.Function = function->GetFunctionBody();
- #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
- cfinfo.Name = cfinfo.Function->GetExternalDisplayName();
- #endif
- cfinfo.FunctionTime = this->m_runningFunctionTimeCtr;
- cfinfo.LoopTime = 0;
- cfinfo.CurrentStatementIndex = -1;
- cfinfo.CurrentStatementLoopTime = 0;
- cfinfo.LastStatementIndex = -1;
- cfinfo.LastStatementLoopTime = 0;
- cfinfo.CurrentStatementBytecodeMin = UINT32_MAX;
- cfinfo.CurrentStatementBytecodeMax = UINT32_MAX;
- this->m_callStack.Add(cfinfo);
- ////
- //If we are running for debugger then check if we need to set a breakpoint at entry to the first function we execute
- if(this->m_breakOnFirstUserCode)
- {
- this->m_breakOnFirstUserCode = false;
- this->m_activeTTDBP.SetLocationFromFunctionEntryAnyTime(this->m_topLevelCallbackEventTime, cfinfo.Function);
- this->SetActiveBP_Helper(function->GetFunctionBody()->GetScriptContext()->GetThreadContext()->TTDContext);
- }
- ////
- #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
- this->m_diagnosticLogger.WriteCall(function, false, argc, argv, function->GetFunctionBody()->GetScriptContext()->GetThreadContext()->TTDLog->GetLastEventTime());
- #endif
- }
- void ExecutionInfoManager::PopCallEvent(Js::JavascriptFunction* function, Js::Var result)
- {
- this->m_lastReturnLocation.SetReturnLocation(this->m_callStack.Last());
- this->m_runningFunctionTimeCtr++;
- this->m_callStack.RemoveAtEnd();
- #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
- this->m_diagnosticLogger.WriteReturn(function, result, function->GetFunctionBody()->GetScriptContext()->GetThreadContext()->TTDLog->GetLastEventTime());
- #endif
- }
- void ExecutionInfoManager::PopCallEventException(Js::JavascriptFunction* function)
- {
- //If we already have the last return as an exception then just leave it.
- //That is where the exception was first rasied, this return is just propagating it in this return.
- if(!this->m_lastReturnLocation.IsExceptionLocation())
- {
- this->m_lastReturnLocation.SetExceptionLocation(this->m_callStack.Last());
- }
- if(!this->m_lastExceptionPropagating)
- {
- this->m_lastExceptionLocation.SetLocationFromFrame(this->m_topLevelCallbackEventTime, this->m_callStack.Last());
- this->m_lastExceptionPropagating = true;
- }
- this->m_runningFunctionTimeCtr++;
- this->m_callStack.RemoveAtEnd();
- #if ENABLE_BASIC_TRACE || ENABLE_FULL_BC_TRACE
- this->m_diagnosticLogger.WriteReturnException(function, function->GetFunctionBody()->GetScriptContext()->GetThreadContext()->TTDLog->GetLastEventTime());
- #endif
- }
- void ExecutionInfoManager::ProcessCatchInfoForLastExecutedStatements()
- {
- this->m_lastReturnLocation.Clear();
- this->m_lastExceptionPropagating = false;
- }
- void ExecutionInfoManager::SetBreakOnFirstUserCode()
- {
- this->m_breakOnFirstUserCode = true;
- }
- void ExecutionInfoManager::SetPendingTTDResetToCurrentPosition()
- {
- this->GetTimeAndPositionForDebugger(this->m_pendingTTDBP);
- this->m_pendingTTDMoveMode = 0;
- }
- void ExecutionInfoManager::SetPendingTTDToTarget(const TTDebuggerSourceLocation& dsl)
- {
- this->m_pendingTTDBP.SetLocationCopy(dsl);
- this->m_pendingTTDMoveMode = 0;
- }
- void ExecutionInfoManager::SetPendingTTDStepBackMove()
- {
- this->GetPreviousTimeAndPositionForDebugger(this->m_pendingTTDBP);
- this->m_pendingTTDMoveMode = 0;
- }
- void ExecutionInfoManager::SetPendingTTDStepBackIntoMove()
- {
- this->GetLastExecutedTimeAndPositionForDebugger(this->m_pendingTTDBP);
- this->m_pendingTTDMoveMode = 0;
- }
- void ExecutionInfoManager::SetPendingTTDReverseContinueMove(uint64 moveflag)
- {
- this->m_continueBreakPoint.Clear();
- this->GetTimeAndPositionForDebugger(this->m_pendingTTDBP);
- this->m_pendingTTDMoveMode = moveflag;
- }
- void ExecutionInfoManager::SetPendingTTDUnhandledException()
- {
- this->GetLastExceptionTimeAndPositionForDebugger(this->m_pendingTTDBP);
- this->m_lastExceptionPropagating = false;
- this->m_pendingTTDMoveMode = 0;
- }
- bool ExecutionInfoManager::ProcessBPInfoPreBreak(Js::FunctionBody* fb, const EventLog* elog)
- {
- //if we aren't in debug mode then we always trigger BP's
- if(!fb->GetScriptContext()->ShouldPerformReplayDebuggerAction())
- {
- return true;
- }
- //If we are in debugger mode but are suppressing BP's for movement then suppress them
- if(ExecutionInfoManager::ShouldSuppressBreakpointsForTimeTravelMove(elog->GetCurrentTTDMode()))
- {
- //Check if we need to record the visit to this bp
- if(ExecutionInfoManager::ShouldRecordBreakpointsDuringTimeTravelScan(elog->GetCurrentTTDMode()))
- {
- this->AddCurrentLocationDuringScan(elog->GetCurrentTopLevelEventTime());
- }
- return false;
- }
- //If we are in debug mode and don't have an active BP target then we treat BP's as usual
- if(!this->m_activeTTDBP.HasValue())
- {
- return true;
- }
- //Finally we are in debug mode and we have an active BP target so only break if the BP is satisfied
- const SingleCallCounter& cfinfo = this->GetTopCallCounter();
- //Make sure we are in the right source code (via top level body ids)
- if(this->m_activeTTDBP.GetTopLevelBodyId() != cfinfo.Function->GetScriptContext()->TTDContextInfo->FindTopLevelCtrForBody(cfinfo.Function))
- {
- return false;
- }
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = cfinfo.Function->GetStatementStartOffset(cfinfo.CurrentStatementIndex);
- cfinfo.Function->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- bool locationOk = ((uint32)srcLine == this->m_activeTTDBP.GetSourceLine()) & ((uint32)srcColumn == this->m_activeTTDBP.GetSourceColumn());
- bool ftimeOk = (this->m_activeTTDBP.GetFunctionTime() == -1) | ((uint64)this->m_activeTTDBP.GetFunctionTime() == cfinfo.FunctionTime);
- bool ltimeOk = (this->m_activeTTDBP.GetLoopTime() == -1) | ((uint64)this->m_activeTTDBP.GetLoopTime() == cfinfo.CurrentStatementLoopTime);
- return locationOk & ftimeOk & ltimeOk;
- }
- void ExecutionInfoManager::ProcessBPInfoPostBreak(Js::FunctionBody* fb)
- {
- if(!fb->GetScriptContext()->ShouldPerformReplayDebuggerAction())
- {
- return;
- }
- if(this->m_activeTTDBP.HasValue())
- {
- this->ClearActiveBPInfo(fb->GetScriptContext()->GetThreadContext()->TTDContext);
- }
- if(this->m_pendingTTDBP.HasValue())
- {
- //Reset any step controller logic
- fb->GetScriptContext()->GetThreadContext()->GetDebugManager()->stepController.Deactivate();
- throw TTD::TTDebuggerAbortException::CreateTopLevelAbortRequest(this->m_pendingTTDBP.GetRootEventTime(), this->m_pendingTTDMoveMode, _u("Reverse operation requested."));
- }
- }
- bool ExecutionInfoManager::IsLocationActiveBPAndNotExplicitBP(const TTDebuggerSourceLocation& current) const
- {
- //If we shound't remove the active BP when done then it is a user visible one so we just return false
- if(!this->m_shouldRemoveWhenDone)
- {
- return false;
- }
- //Check to see if the locations are the same
- return TTDebuggerSourceLocation::AreSameLocations_PlaceOnly(this->m_activeTTDBP, current);
- }
- void ExecutionInfoManager::AddCurrentLocationDuringScan(int64 topLevelEventTime)
- {
- TTDebuggerSourceLocation current;
- current.SetLocationFromFrame(topLevelEventTime, this->m_callStack.Last());
- if(this->m_activeTTDBP.HasValue() && TTDebuggerSourceLocation::AreSameLocations(this->m_activeTTDBP, current))
- {
- this->m_hitContinueSearchBP = true;
- }
- if(!this->m_hitContinueSearchBP && !this->IsLocationActiveBPAndNotExplicitBP(current))
- {
- this->m_continueBreakPoint.SetLocationCopy(current);
- }
- }
- bool ExecutionInfoManager::TryFindAndSetPreviousBP()
- {
- if(!this->m_continueBreakPoint.HasValue())
- {
- return false;
- }
- else
- {
- this->m_pendingTTDBP.SetLocationCopy(this->m_continueBreakPoint);
- this->m_continueBreakPoint.Clear();
- return true;
- }
- }
- //Get the target event time for the pending TTD breakpoint
- int64 ExecutionInfoManager::GetPendingTTDBPTargetEventTime() const
- {
- TTDAssert(this->m_pendingTTDBP.HasValue(), "We did not set the pending TTD breakpoint value?");
- return this->m_pendingTTDBP.GetRootEventTime();
- }
- void ExecutionInfoManager::LoadPreservedBPInfo(ThreadContext* threadContext)
- {
- while(this->m_unRestoredBreakpoints.Contains(nullptr))
- {
- this->m_unRestoredBreakpoints.Remove(nullptr);
- }
- const JsUtil::List<Js::ScriptContext*, HeapAllocator>& ctxs = threadContext->TTDContext->GetTTDContexts();
- for(int32 i = 0; i < ctxs.Count(); ++i)
- {
- Js::ScriptContext* ctx = ctxs.Item(i);
- JsUtil::List<uint32, HeapAllocator> bpIdsToDelete(&HeapAllocator::Instance);
- Js::ProbeContainer* probeContainer = ctx->GetDebugContext()->GetProbeContainer();
- probeContainer->MapProbes([&](int j, Js::Probe* pProbe)
- {
- Js::BreakpointProbe* bp = (Js::BreakpointProbe*)pProbe;
- if((int64)bp->GetId() != this->m_activeBPId)
- {
- Js::FunctionBody* body = bp->GetFunctionBody();
- int32 bpIndex = body->GetEnclosingStatementIndexFromByteCode(bp->GetBytecodeOffset());
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = body->GetStatementStartOffset(bpIndex);
- body->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- TTDebuggerSourceLocation* bpLocation = TT_HEAP_NEW(TTDebuggerSourceLocation);
- bpLocation->SetLocationWithBP(bp->GetId(), body, srcLine, srcColumn);
- this->m_unRestoredBreakpoints.Add(bpLocation);
- bpIdsToDelete.Add(bp->GetId());
- }
- });
- for(int32 j = 0; j < bpIdsToDelete.Count(); ++j)
- {
- ctx->TTDHostCallbackFunctor.pfOnBPDeleteCallback(ctx->TTDHostCallbackFunctor.HostRuntime, bpIdsToDelete.Item(j));
- }
- //done with last context so release the debug document dictionary info
- if(i == ctxs.Count() - 1)
- {
- ctx->TTDHostCallbackFunctor.pfOnBPClearDocumentCallback(ctx->TTDHostCallbackFunctor.HostRuntime);
- }
- }
- }
- void ExecutionInfoManager::AddPreservedBPsForTopLevelLoad(uint32 topLevelBodyId, Js::FunctionBody* body)
- {
- Js::ScriptContext* ctx = body->GetScriptContext();
- Js::Utf8SourceInfo* utf8SourceInfo = body->GetUtf8SourceInfo();
- for(int32 i = 0; i < this->m_unRestoredBreakpoints.Count(); ++i)
- {
- if(this->m_unRestoredBreakpoints.Item(i) == nullptr)
- {
- continue;
- }
- const TTDebuggerSourceLocation* bpLocation = this->m_unRestoredBreakpoints.Item(i);
- if(bpLocation->GetTopLevelBodyId() == topLevelBodyId)
- {
- BOOL isNewBP = FALSE;
- ctx->TTDHostCallbackFunctor.pfOnBPRegisterCallback(ctx->TTDHostCallbackFunctor.HostRuntime, bpLocation->GetBPId(), ctx, utf8SourceInfo, bpLocation->GetSourceLine(), bpLocation->GetSourceColumn(), &isNewBP);
- TTDAssert(isNewBP, "We should be restoring a breapoint we removed previously!");
- //Now that it is set we can clear it from our list
- this->m_unRestoredBreakpoints.SetItem(i, nullptr);
- }
- }
- if(this->m_activeTTDBP.HasValue() && (this->m_activeBPId == -1) && (this->m_activeTTDBP.GetTopLevelBodyId() == topLevelBodyId))
- {
- this->SetActiveBP_Helper(body->GetScriptContext()->GetThreadContext()->TTDContext);
- }
- }
- void ExecutionInfoManager::UpdateLoopCountInfo()
- {
- SingleCallCounter& cfinfo = this->m_callStack.Last();
- cfinfo.LoopTime++;
- }
- void ExecutionInfoManager::UpdateCurrentStatementInfo(uint bytecodeOffset)
- {
- SingleCallCounter& cfinfo = this->GetTopCallCounter();
- if((cfinfo.CurrentStatementBytecodeMin <= bytecodeOffset) & (bytecodeOffset <= cfinfo.CurrentStatementBytecodeMax))
- {
- return;
- }
- else
- {
- Js::FunctionBody* fb = cfinfo.Function;
- TTDAssert(fb->GetUtf8SourceInfo() != nullptr, "Should always have a source info.");
- if (!fb->GetUtf8SourceInfo()->GetIsLibraryCode())
- {
- int32 cIndex = fb->GetEnclosingStatementIndexFromByteCode(bytecodeOffset, true);
- //We moved to a new statement
- Js::FunctionBody::StatementMap* pstmt = fb->GetStatementMaps()->Item(cIndex);
- bool newstmt = (cIndex != cfinfo.CurrentStatementIndex && pstmt->byteCodeSpan.begin <= (int)bytecodeOffset && (int)bytecodeOffset <= pstmt->byteCodeSpan.end);
- //Make sure async step back is ok -- We always step back to the first location in a statement and in most cases a function body must start at the first location in a statement.
- //However an await can be in the middle of a statment/expression and is implicitly the start of a function body. So, we must check for that case.
- bool functionBodyStartUnalignedWithStatementCase = (cfinfo.CurrentStatementIndex == -1) && (pstmt->byteCodeSpan.begin != (int)bytecodeOffset);
- if (newstmt && !functionBodyStartUnalignedWithStatementCase)
- {
- cfinfo.LastStatementIndex = cfinfo.CurrentStatementIndex;
- cfinfo.LastStatementLoopTime = cfinfo.CurrentStatementLoopTime;
- cfinfo.CurrentStatementIndex = cIndex;
- cfinfo.CurrentStatementLoopTime = cfinfo.LoopTime;
- cfinfo.CurrentStatementBytecodeMin = (uint32)pstmt->byteCodeSpan.begin;
- cfinfo.CurrentStatementBytecodeMax = (uint32)pstmt->byteCodeSpan.end;
- #if ENABLE_FULL_BC_TRACE
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = cfinfo.Function->GetFunctionBody()->GetStatementStartOffset(cfinfo.CurrentStatementIndex);
- cfinfo.Function->GetFunctionBody()->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- this->m_diagnosticLogger.WriteStmtIndex((uint32)srcLine, (uint32)srcColumn);
- #endif
- }
- }
- }
- }
- void ExecutionInfoManager::ManageLastSourceInfoChecks(Js::FunctionBody* fb, bool bpDisable)
- {
- if(this->IsLastSourceLineEnabled() && this->IsFinalSourceLine())
- {
- this->SetPendingTTDResetToCurrentPosition();
- if(bpDisable)
- {
- //Reset any step controller logic
- fb->GetScriptContext()->GetThreadContext()->GetDebugManager()->stepController.Deactivate();
- }
- throw TTD::TTDebuggerAbortException::CreateTopLevelAbortRequest(this->m_pendingTTDBP.GetRootEventTime(), this->m_pendingTTDMoveMode, _u("Last source info hit -- reset to requested."));
- }
- }
- bool ExecutionInfoManager::IsLastSourceLineEnabled() const
- {
- return this->m_innerloopLastLocation.IsEnabled();
- }
- bool ExecutionInfoManager::IsFinalSourceLine() const
- {
- const SingleCallCounter& cfinfo = this->GetTopCallCounter();
- if(!this->m_innerloopLastLocation.CheckLastTimeMatch(this->m_topLevelCallbackEventTime, cfinfo.FunctionTime, cfinfo.LoopTime))
- {
- return false;
- }
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = cfinfo.Function->GetStatementStartOffset(cfinfo.CurrentStatementIndex);
- cfinfo.Function->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- return this->m_innerloopLastLocation.CheckLineColumnMatch((uint32) srcLine, (uint32)srcColumn);
- }
- void ExecutionInfoManager::GetTimeAndPositionForDebugger(TTDebuggerSourceLocation& sourceLocation) const
- {
- const SingleCallCounter& cfinfo = this->GetTopCallCounter();
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = cfinfo.Function->GetStatementStartOffset(cfinfo.CurrentStatementIndex);
- cfinfo.Function->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- sourceLocation.SetLocationFull(this->m_topLevelCallbackEventTime, cfinfo.FunctionTime, cfinfo.LoopTime, cfinfo.Function, srcLine, srcColumn);
- }
- #if ENABLE_OBJECT_SOURCE_TRACKING
- void ExecutionInfoManager::GetTimeAndPositionForDiagnosticObjectTracking(DiagnosticOrigin& originInfo) const
- {
- const SingleCallCounter& cfinfo = this->GetTopCallCounter();
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = cfinfo.Function->GetStatementStartOffset(cfinfo.CurrentStatementIndex);
- cfinfo.Function->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- SetDiagnosticOriginInformation(originInfo, srcLine, cfinfo.Function->GetFunctionBody()->GetScriptContext()->GetThreadContext()->TTDLog->GetLastEventTime(), cfinfo.FunctionTime, cfinfo.LoopTime);
- }
- #endif
- bool ExecutionInfoManager::GetPreviousTimeAndPositionForDebugger(TTDebuggerSourceLocation& sourceLocation) const
- {
- bool noPrevious = false;
- const SingleCallCounter& cfinfo = this->GetTopCallCounter();
- //if we are at the first statement in the function then we want the parents current
- Js::FunctionBody* fbody = nullptr;
- int32 statementIndex = -1;
- uint64 ftime = 0;
- uint64 ltime = 0;
- if(cfinfo.LastStatementIndex == -1)
- {
- SingleCallCounter cfinfoCaller = { 0 };
- bool hasCaller = this->TryGetTopCallCallerCounter(cfinfoCaller);
- if (hasCaller)
- {
- ftime = cfinfoCaller.FunctionTime;
- ltime = cfinfoCaller.CurrentStatementLoopTime;
- fbody = cfinfoCaller.Function;
- statementIndex = cfinfoCaller.CurrentStatementIndex;
- }
- else
- {
- //Set the position info to the current statement and return true
- noPrevious = true;
- ftime = cfinfo.FunctionTime;
- ltime = cfinfo.CurrentStatementLoopTime;
- fbody = cfinfo.Function;
- statementIndex = cfinfo.CurrentStatementIndex;
- }
- }
- else
- {
- ftime = cfinfo.FunctionTime;
- ltime = cfinfo.LastStatementLoopTime;
- fbody = cfinfo.Function;
- statementIndex = cfinfo.LastStatementIndex;
- }
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = fbody->GetStatementStartOffset(statementIndex);
- fbody->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- sourceLocation.SetLocationFull(this->m_topLevelCallbackEventTime, ftime, ltime, fbody, srcLine, srcColumn);
- return noPrevious;
- }
- void ExecutionInfoManager::GetLastExecutedTimeAndPositionForDebugger(TTDebuggerSourceLocation& sourceLocation) const
- {
- const TTLastReturnLocationInfo& cframe = this->m_lastReturnLocation;
- if(!cframe.IsDefined())
- {
- sourceLocation.Clear();
- return;
- }
- else
- {
- ULONG srcLine = 0;
- LONG srcColumn = -1;
- uint32 startOffset = cframe.GetLocation().Function->GetStatementStartOffset(cframe.GetLocation().CurrentStatementIndex);
- cframe.GetLocation().Function->GetSourceLineFromStartOffset_TTD(startOffset, &srcLine, &srcColumn);
- sourceLocation.SetLocationFull(this->m_topLevelCallbackEventTime, cframe.GetLocation().FunctionTime, cframe.GetLocation().CurrentStatementLoopTime, cframe.GetLocation().Function, srcLine, srcColumn);
- }
- }
- void ExecutionInfoManager::GetLastExceptionTimeAndPositionForDebugger(TTDebuggerSourceLocation& sourceLocation) const
- {
- //If no exception then this will also clear sourceLocation
- sourceLocation.SetLocationCopy(this->m_lastExceptionLocation);
- }
- void ExecutionInfoManager::ResetCallStackForTopLevelCall(int64 topLevelCallbackEventTime)
- {
- TTDAssert(this->m_callStack.Count() == 0, "We should be at the top-level entry!!!");
- this->m_topLevelCallbackEventTime = topLevelCallbackEventTime;
- this->m_runningFunctionTimeCtr = 0;
- this->m_lastReturnLocation.Clear();
- this->m_lastExceptionLocation.Clear();
- }
- void ExecutionInfoManager::SetBPInfoForActiveSegmentContinueScan(ThreadContextTTD* ttdThreadContext)
- {
- TTDAssert(this->m_pendingTTDBP.HasValue(), "We should always set this when launching a reverse continue!");
- this->m_activeTTDBP.SetLocationCopy(this->m_pendingTTDBP);
- this->SetActiveBPInfoAsNeeded(ttdThreadContext);
- }
- void ExecutionInfoManager::ClearBPInfoForActiveSegmentContinueScan(ThreadContextTTD* ttdThreadContext)
- {
- TTDAssert(this->m_activeTTDBP.HasValue(), "We should always have this set when we complete the active segment scan.");
- this->m_hitContinueSearchBP = false;
- this->ClearActiveBPInfo(ttdThreadContext);
- }
- void ExecutionInfoManager::SetActiveBP_Helper(ThreadContextTTD* ttdThreadContext)
- {
- Js::ScriptContext* ctx = ttdThreadContext->LookupContextForScriptId(this->m_activeTTDBP.GetScriptLogTagId());
- Js::FunctionBody* body = this->m_activeTTDBP.LoadFunctionBodyIfPossible(ctx);
- if(body == nullptr)
- {
- return;
- }
- Js::Utf8SourceInfo* utf8SourceInfo = body->GetUtf8SourceInfo();
- Js::DebugDocument* debugDocument = utf8SourceInfo->GetDebugDocument();
- TTDAssert(debugDocument != nullptr, "Something went wrong with our TTD debug breakpoints.");
- utf8SourceInfo->EnsureLineOffsetCacheNoThrow();
- charcount_t charPosition = 0;
- charcount_t byteOffset = 0;
- utf8SourceInfo->GetCharPositionForLineInfo(this->m_activeTTDBP.GetSourceLine(), &charPosition, &byteOffset);
- long ibos = charPosition + this->m_activeTTDBP.GetSourceColumn() + 1;
- Js::StatementLocation statement;
- debugDocument->GetStatementLocation(ibos, &statement);
- // Don't see a use case for supporting multiple breakpoints at same location.
- // If a breakpoint already exists, just return that
- Js::BreakpointProbe* probe = debugDocument->FindBreakpoint(statement);
- if(probe == nullptr)
- {
- this->m_shouldRemoveWhenDone = true;
- probe = debugDocument->SetBreakPoint(statement, BREAKPOINT_ENABLED);
- }
- this->m_activeBPId = probe->GetId();
- }
- void ExecutionInfoManager::SetActiveBPInfoAsNeeded(ThreadContextTTD* ttdThreadContext)
- {
- if(this->m_pendingTTDBP.HasValue())
- {
- this->m_activeTTDBP.SetLocationCopy(this->m_pendingTTDBP);
- this->SetActiveBP_Helper(ttdThreadContext);
- //Finally clear the pending BP info so we don't get confused later
- this->m_pendingTTDMoveMode = 0;
- this->m_pendingTTDBP.Clear();
- }
- }
- void ExecutionInfoManager::ClearActiveBPInfo(ThreadContextTTD* ttdThreadContext)
- {
- TTDAssert(this->m_activeTTDBP.HasValue(), "Need to check that we actually have info to clear first.");
- Js::ScriptContext* ctx = ttdThreadContext->LookupContextForScriptId(this->m_activeTTDBP.GetScriptLogTagId());
- Js::FunctionBody* body = this->m_activeTTDBP.LoadFunctionBodyIfPossible(ctx);
- Js::DebugDocument* debugDocument = body->GetUtf8SourceInfo()->GetDebugDocument();
- Js::StatementLocation statement;
- if(this->m_shouldRemoveWhenDone && debugDocument->FindBPStatementLocation((UINT)this->m_activeBPId, &statement))
- {
- debugDocument->SetBreakPoint(statement, BREAKPOINT_DELETED);
- }
- this->m_activeBPId = -1;
- this->m_shouldRemoveWhenDone = false;
- this->m_activeTTDBP.Clear();
- }
- void ExecutionInfoManager::ProcessScriptLoad(Js::ScriptContext* ctx, uint32 topLevelBodyId, Js::FunctionBody* body, Js::Utf8SourceInfo* utf8SourceInfo, CompileScriptException* se)
- {
- bool newScript = !this->m_debuggerNotifiedTopLevelBodies.Contains(topLevelBodyId);
- //Only notify of loaded script -- eval and new script is only notified later if we need to hit a bp in it?
- if(se != nullptr)
- {
- ctx->TTDHostCallbackFunctor.pfOnScriptLoadCallback(ctx->TTDHostCallbackFunctor.HostContext, body, utf8SourceInfo, se, newScript);
- }
- if(newScript)
- {
- this->m_debuggerNotifiedTopLevelBodies.AddNew(topLevelBodyId);
- }
- this->AddPreservedBPsForTopLevelLoad(topLevelBodyId, body);
- }
- void ExecutionInfoManager::ProcessScriptLoad_InflateReuseBody(uint32 topLevelBodyId, Js::FunctionBody* body)
- {
- this->AddPreservedBPsForTopLevelLoad(topLevelBodyId, body);
- }
- }
- #endif
|