diff --git a/bin/ChakraCore/ChakraCore.def b/bin/ChakraCore/ChakraCore.def
index 8883c53695e..903eca2a38b 100644
--- a/bin/ChakraCore/ChakraCore.def
+++ b/bin/ChakraCore/ChakraCore.def
@@ -46,6 +46,7 @@ JsTTDMoveToTopLevelEvent
JsTTDReplayExecution
JsTTDDiagWriteLog
+JsTTDDiagSetAutoTraceStatus
JsInitializeModuleRecord
JsParseModuleSource
diff --git a/lib/Jsrt/ChakraDebug.h b/lib/Jsrt/ChakraDebug.h
index 3ee2c2bbbd9..e7239766d5c 100644
--- a/lib/Jsrt/ChakraDebug.h
+++ b/lib/Jsrt/ChakraDebug.h
@@ -1014,6 +1014,17 @@ typedef unsigned __int32 uint32_t;
_Inout_ JsTTDMoveMode* moveMode,
_Out_ int64_t* rootEventTime);
+ ///
+ /// TTD API -- may change in future versions:
+ /// Enable or disable autotrace ability from JsRT.
+ ///
+ /// True to enable autotracing false to disable it.
+ /// The code JsNoError if the operation succeeded, a failure code otherwise.
+ CHAKRA_API
+ JsTTDDiagSetAutoTraceStatus(
+ _In_ bool status
+ );
+
///
/// TTD API -- may change in future versions:
/// A way for the debugger to programatically write a trace when it is at a breakpoint.
diff --git a/lib/Jsrt/Jsrt.cpp b/lib/Jsrt/Jsrt.cpp
index 22c01b59221..2530dd8e335 100644
--- a/lib/Jsrt/Jsrt.cpp
+++ b/lib/Jsrt/Jsrt.cpp
@@ -4695,6 +4695,27 @@ CHAKRA_API JsTTDReplayExecution(_Inout_ JsTTDMoveMode* moveMode, _Out_ int64_t*
#endif
}
+CHAKRA_API JsTTDDiagSetAutoTraceStatus(_In_ bool status)
+{
+#if !ENABLE_TTD
+ return JsErrorCategoryUsage;
+#else
+ JsrtContext *currentContext = JsrtContext::GetCurrent();
+ JsErrorCode cCheck = CheckContext(currentContext, JSRT_MAYBE_TRUE);
+ TTDAssert(cCheck == JsNoError, "Must have valid context when setting auto trace status.");
+
+ Js::ScriptContext* scriptContext = currentContext->GetScriptContext();
+ ThreadContext* threadContext = scriptContext->GetThreadContext();
+
+ if (threadContext->IsRuntimeInTTDMode())
+ {
+ threadContext->TTDLog->SetAutoTraceEnabled(status);
+ }
+
+ return JsNoError;
+#endif
+}
+
#ifdef _CHAKRACOREBUILD
template
diff --git a/lib/Runtime/Debug/TTEventLog.cpp b/lib/Runtime/Debug/TTEventLog.cpp
index b9bdc1232da..369be47decc 100644
--- a/lib/Runtime/Debug/TTEventLog.cpp
+++ b/lib/Runtime/Debug/TTEventLog.cpp
@@ -508,6 +508,7 @@ namespace TTD
TTD_CREATE_EVENTLIST_VTABLE_ENTRY(ExternalCallTag, None, ExternalCallEventLogEntry, nullptr, NSLogEvents::ExternalCallEventLogEntry_UnloadEventMemory, NSLogEvents::ExternalCallEventLogEntry_Emit, NSLogEvents::ExternalCallEventLogEntry_Parse);
TTD_CREATE_EVENTLIST_VTABLE_ENTRY(ExplicitLogWriteTag, None, ExplicitLogWriteEventLogEntry, nullptr, nullptr, NSLogEvents::ExplicitLogWriteEntry_Emit, NSLogEvents::ExplicitLogWriteEntry_Parse);
TTD_CREATE_EVENTLIST_VTABLE_ENTRY(TTDInnerLoopLogWriteTag, None, TTDInnerLoopLogWriteEventLogEntry, nullptr, nullptr, NSLogEvents::TTDInnerLoopLogWriteEventLogEntry_Emit, NSLogEvents::TTDInnerLoopLogWriteEventLogEntry_Parse);
+ TTD_CREATE_EVENTLIST_VTABLE_ENTRY(TTDFetchAutoTraceStatusTag, None, TTDFetchAutoTraceStatusEventLogEntry, nullptr, nullptr, NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry_Emit, NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry_Parse);
TTD_CREATE_EVENTLIST_VTABLE_ENTRY(CreateScriptContextActionTag, GlobalAPIWrapper, JsRTCreateScriptContextAction, NSLogEvents::CreateScriptContext_Execute, NSLogEvents::CreateScriptContext_UnloadEventMemory, NSLogEvents::CreateScriptContext_Emit, NSLogEvents::CreateScriptContext_Parse);
TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(SetActiveScriptContextActionTag, GlobalAPIWrapper, JsRTSingleVarArgumentAction, SetActiveScriptContext_Execute);
@@ -586,7 +587,7 @@ namespace TTD
: m_threadContext(threadContext), m_eventSlabAllocator(TTD_SLAB_BLOCK_ALLOCATION_SIZE_MID), m_miscSlabAllocator(TTD_SLAB_BLOCK_ALLOCATION_SIZE_SMALL),
m_eventTimeCtr(0), m_timer(), m_topLevelCallbackEventTime(-1),
m_eventListVTable(nullptr), m_eventList(&this->m_eventSlabAllocator), m_currentReplayEventIterator(),
- m_modeStack(), m_currentMode(TTDMode::Invalid),
+ m_modeStack(), m_currentMode(TTDMode::Invalid), m_autoTracesEnabled(true),
m_snapExtractor(), m_elapsedExecutionTimeSinceSnapshot(0.0),
m_lastInflateSnapshotTime(-1), m_lastInflateMap(nullptr), m_propertyRecordList(&this->m_miscSlabAllocator),
m_sourceInfoCount(0), m_loadedTopLevelScripts(&this->m_miscSlabAllocator), m_newFunctionTopLevelScripts(&this->m_miscSlabAllocator), m_evalTopLevelScripts(&this->m_miscSlabAllocator)
@@ -879,6 +880,18 @@ namespace TTD
}
}
+ void EventLog::RecordTTDFetchAutoTraceStatusEvent(bool status)
+ {
+ NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry* atfEvent = this->RecordGetInitializedEvent_DataOnly();
+ atfEvent->IsEnabled = status;
+ }
+
+ bool EventLog::ReplayTTDFetchAutoTraceStatusLogEvent()
+ {
+ const NSLogEvents::TTDFetchAutoTraceStatusEventLogEntry* atfEvent = this->ReplayGetReplayEvent_Helper();
+ return atfEvent->IsEnabled;
+ }
+
void EventLog::RecordDateTimeEvent(double time)
{
NSLogEvents::DoubleEventLogEntry* dEvent = this->RecordGetInitializedEvent_DataOnly();
@@ -2558,9 +2571,14 @@ namespace TTD
return isInnerLoop & isEnabled;
}
- bool EventLog::SuppressDiagnosticTracesDuringInnerLoop() const
+ void EventLog::SetAutoTraceEnabled(bool enabled)
+ {
+ this->m_autoTracesEnabled = enabled;
+ }
+
+ bool EventLog::GetAutoTraceEnabled() const
{
- return (this->m_currentMode & (TTDMode::DebuggerAttachedMode)) == TTDMode::DebuggerAttachedMode;
+ return this->m_autoTracesEnabled;
}
void EventLog::EmitLog(const char* emitUri, size_t emitUriLength, NSLogEvents::EventLogEntry* optInnerLoopEvent)
diff --git a/lib/Runtime/Debug/TTEventLog.h b/lib/Runtime/Debug/TTEventLog.h
index 90dd493f11c..9a320724349 100644
--- a/lib/Runtime/Debug/TTEventLog.h
+++ b/lib/Runtime/Debug/TTEventLog.h
@@ -226,6 +226,7 @@ namespace TTD
//The current mode the system is running in (and a stack of mode push/pops that we use to generate it)
TTModeStack m_modeStack;
TTDMode m_currentMode;
+ bool m_autoTracesEnabled;
//The snapshot extractor that this log uses
SnapshotExtractor m_snapExtractor;
@@ -393,6 +394,12 @@ namespace TTD
//Replay a event that writes the log to a given uri
void ReplayEmitLogEvent();
+ //Record that we are accessing the TTDFetchAutoTraceStatus and what the value is
+ void RecordTTDFetchAutoTraceStatusEvent(bool status);
+
+ //Replay that we are accessing the TTDFetchAutoTraceStatus
+ bool ReplayTTDFetchAutoTraceStatusLogEvent();
+
//Log a time that is fetched during date operations
void RecordDateTimeEvent(double time);
@@ -605,7 +612,8 @@ namespace TTD
void InnerLoopEmitLog(const TTDebuggerSourceLocation& writeLocation, const char* emitUri, size_t emitUriLength);
bool CanWriteInnerLoopTrace() const;
- bool SuppressDiagnosticTracesDuringInnerLoop() const;
+ void SetAutoTraceEnabled(bool enabled);
+ bool GetAutoTraceEnabled() const;
void EmitLog(const char* emitUri, size_t emitUriLength, NSLogEvents::EventLogEntry* optInnerLoopEvent = nullptr);
void ParseLogInto(TTDataIOInfo& iofp, const char* parseUri, size_t parseUriLength);
diff --git a/lib/Runtime/Debug/TTEvents.cpp b/lib/Runtime/Debug/TTEvents.cpp
index a43af831d24..068ebe28755 100644
--- a/lib/Runtime/Debug/TTEvents.cpp
+++ b/lib/Runtime/Debug/TTEvents.cpp
@@ -597,6 +597,20 @@ namespace TTD
ilevt->Line = reader->ReadUInt32(NSTokens::Key::line, true);
ilevt->Column = reader->ReadUInt32(NSTokens::Key::column, true);
}
+
+ void TTDFetchAutoTraceStatusEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext)
+ {
+ const TTDFetchAutoTraceStatusEventLogEntry* atfevt = GetInlineEventDataAs(evt);
+
+ writer->WriteLogTag(NSTokens::Key::boolVal, atfevt->IsEnabled, NSTokens::Separator::CommaSeparator);
+ }
+
+ void TTDFetchAutoTraceStatusEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc)
+ {
+ TTDFetchAutoTraceStatusEventLogEntry* atfevt = GetInlineEventDataAs(evt);
+
+ atfevt->IsEnabled = reader->ReadLogTag(NSTokens::Key::boolVal, true);
+ }
}
}
diff --git a/lib/Runtime/Debug/TTEvents.h b/lib/Runtime/Debug/TTEvents.h
index dfed9e8c34b..8621221c27d 100644
--- a/lib/Runtime/Debug/TTEvents.h
+++ b/lib/Runtime/Debug/TTEvents.h
@@ -98,6 +98,7 @@ namespace TTD
ExternalCallTag,
ExplicitLogWriteTag,
TTDInnerLoopLogWriteTag,
+ TTDFetchAutoTraceStatusTag,
//JsRTActionTag is a marker for where the JsRT actions begin
JsRTActionTag,
@@ -498,6 +499,15 @@ namespace TTD
void TTDInnerLoopLogWriteEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext);
void TTDInnerLoopLogWriteEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc);
+
+ //A struct for recording the result of a read of the AutoTraceStatus
+ struct TTDFetchAutoTraceStatusEventLogEntry
+ {
+ bool IsEnabled;
+ };
+
+ void TTDFetchAutoTraceStatusEventLogEntry_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext);
+ void TTDFetchAutoTraceStatusEventLogEntry_Parse(EventLogEntry* evt, ThreadContext* threadContext, FileReader* reader, UnlinkableSlabAllocator& alloc);
}
}
diff --git a/lib/Runtime/Library/GlobalObject.cpp b/lib/Runtime/Library/GlobalObject.cpp
index 8e8a4947104..310067adf4c 100644
--- a/lib/Runtime/Library/GlobalObject.cpp
+++ b/lib/Runtime/Library/GlobalObject.cpp
@@ -1675,9 +1675,20 @@ namespace Js
PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
ARGUMENTS(args, callInfo);
- if(function->GetScriptContext()->ShouldPerformRecordOrReplayAction() && !function->GetScriptContext()->GetThreadContext()->TTDLog->SuppressDiagnosticTracesDuringInnerLoop())
+ if (function->GetScriptContext()->ShouldPerformReplayAction())
{
- return function->GetScriptContext()->GetLibrary()->GetTrue();
+ TTD::EventLog* ttlog = function->GetScriptContext()->GetThreadContext()->TTDLog;
+ bool isEnabled = ttlog->ReplayTTDFetchAutoTraceStatusLogEvent();
+
+ return function->GetScriptContext()->GetLibrary()->CreateBoolean(isEnabled);
+ }
+ else if (function->GetScriptContext()->ShouldPerformRecordAction())
+ {
+ TTD::EventLog* ttlog = function->GetScriptContext()->GetThreadContext()->TTDLog;
+ bool isEnabled = ttlog->GetAutoTraceEnabled();
+ ttlog->RecordTTDFetchAutoTraceStatusEvent(isEnabled);
+
+ return function->GetScriptContext()->GetLibrary()->CreateBoolean(isEnabled);
}
else
{