Skip to content

Commit d7fba37

Browse files
committed
[1.6>1.7] [MERGE #3479 @tcare] Port AutoDisableInterrupt updates from internal branch
Merge pull request #3479 from tcare:autodisable I made use of Akrosh's auto interrupt disable class, and moved it to ThreadContext to replace the existing one which has less functionality.
2 parents 1cadbb3 + 9929d4b commit d7fba37

File tree

4 files changed

+44
-56
lines changed

4 files changed

+44
-56
lines changed

lib/Runtime/Base/ScriptContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,7 +3011,7 @@ namespace Js
30113011
DEBUGGER_ATTACHDETACH_FATAL_ERROR_IF_FAILED(hr);
30123012

30133013
// Disable QC while functions are re-parsed as this can be time consuming
3014-
AutoDisableInterrupt autoDisableInterrupt(this->threadContext->GetInterruptPoller(), true);
3014+
AutoDisableInterrupt autoDisableInterrupt(this->threadContext, false /* explicitCompletion */);
30153015

30163016
hr = this->GetDebugContext()->RundownSourcesAndReparse(shouldPerformSourceRundown, /*shouldReparseFunctions*/ true);
30173017

@@ -3107,7 +3107,7 @@ namespace Js
31073107
this->GetDebugContext()->SetDebuggerMode(Js::DebuggerMode::SourceRundown);
31083108

31093109
// Disable QC while functions are re-parsed as this can be time consuming
3110-
AutoDisableInterrupt autoDisableInterrupt(this->threadContext->GetInterruptPoller(), true);
3110+
AutoDisableInterrupt autoDisableInterrupt(this->threadContext, false /* explicitCompletion */);
31113111

31123112
// Force a reparse so that indirect function caches are updated.
31133113
hr = this->GetDebugContext()->RundownSourcesAndReparse(/*shouldPerformSourceRundown*/ false, /*shouldReparseFunctions*/ true);

lib/Runtime/Base/ThreadContext.h

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -82,30 +82,6 @@ class InterruptPoller _ABSTRACT
8282
bool isDisabled;
8383
};
8484

85-
class AutoDisableInterrupt
86-
{
87-
private:
88-
InterruptPoller* interruptPoller;
89-
bool previousState;
90-
public:
91-
AutoDisableInterrupt(InterruptPoller* interruptPoller, bool disable)
92-
: interruptPoller(interruptPoller)
93-
{
94-
if (interruptPoller != nullptr)
95-
{
96-
previousState = interruptPoller->IsDisabled();
97-
interruptPoller->SetDisabled(disable);
98-
}
99-
}
100-
~AutoDisableInterrupt()
101-
{
102-
if (interruptPoller != nullptr)
103-
{
104-
interruptPoller->SetDisabled(previousState);
105-
}
106-
}
107-
};
108-
10985
// This function is called before we step out of script (currently only for WinRT callout).
11086
// Debugger would put a breakpoint on this function if they want to detect the point at which we step
11187
// over the boundary.
@@ -1800,6 +1776,42 @@ class ThreadContext sealed :
18001776

18011777
extern void(*InitializeAdditionalProperties)(ThreadContext *threadContext);
18021778

1779+
// This is for protecting a region of code, where we can't recover and be consistent upon failures (mainly due to OOM and SO).
1780+
// FailFast on that.
1781+
class AutoDisableInterrupt
1782+
{
1783+
public:
1784+
AutoDisableInterrupt::AutoDisableInterrupt(ThreadContext *threadContext, bool explicitCompletion = true)
1785+
: m_operationCompleted(false), m_interruptDisableState(false), m_threadContext(threadContext), m_explicitCompletion(explicitCompletion)
1786+
{
1787+
if (m_threadContext->HasInterruptPoller())
1788+
{
1789+
m_interruptDisableState = m_threadContext->GetInterruptPoller()->IsDisabled();
1790+
m_threadContext->GetInterruptPoller()->SetDisabled(true);
1791+
}
1792+
}
1793+
AutoDisableInterrupt::~AutoDisableInterrupt()
1794+
{
1795+
if (m_threadContext->HasInterruptPoller())
1796+
{
1797+
m_threadContext->GetInterruptPoller()->SetDisabled(m_interruptDisableState);
1798+
}
1799+
1800+
if (m_explicitCompletion && !m_operationCompleted)
1801+
{
1802+
AssertOrFailFast(false);
1803+
}
1804+
}
1805+
1806+
void Completed() { m_operationCompleted = true; }
1807+
1808+
private:
1809+
ThreadContext * m_threadContext;
1810+
bool m_operationCompleted;
1811+
bool m_interruptDisableState;
1812+
bool m_explicitCompletion;
1813+
};
1814+
18031815
#if ENABLE_JS_REENTRANCY_CHECK
18041816
class JsReentLock
18051817
{

lib/Runtime/Library/JavascriptArray.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,12 +1601,11 @@ namespace Js
16011601
}
16021602
#endif
16031603

1604-
// Grow the segments
1605-
16061604
// Code below has potential to throw due to OOM or SO. Just FailFast on those cases
1607-
AutoFailFastOnError failFastError;
1608-
16091605
ScriptContext *scriptContext = intArray->GetScriptContext();
1606+
AutoDisableInterrupt failFastError(scriptContext->GetThreadContext());
1607+
1608+
// Grow the segments
16101609
Recycler *recycler = scriptContext->GetRecycler();
16111610
SparseArraySegmentBase *seg, *nextSeg, *prevSeg = nullptr;
16121611
for (seg = intArray->head; seg; seg = nextSeg)
@@ -1884,7 +1883,7 @@ namespace Js
18841883
SparseArraySegmentBase *seg, *nextSeg, *prevSeg = nullptr;
18851884

18861885
// Code below has potential to throw due to OOM or SO. Just FailFast on those cases
1887-
AutoFailFastOnError failFastError;
1886+
AutoDisableInterrupt failFastError(scriptContext->GetThreadContext());
18881887

18891888
for (seg = intArray->head; seg; seg = nextSeg)
18901889
{
@@ -2074,7 +2073,7 @@ namespace Js
20742073
SparseArraySegmentBase *seg, *nextSeg, *prevSeg = nullptr;
20752074

20762075
// Code below has potential to throw due to OOM or SO. Just FailFast on those cases
2077-
AutoFailFastOnError failFastError;
2076+
AutoDisableInterrupt failFastError(scriptContext->GetThreadContext());
20782077

20792078
for (seg = fArray->head; seg; seg = nextSeg)
20802079
{
@@ -7377,7 +7376,7 @@ namespace Js
73777376
if (newArr && isBuiltinArrayCtor && len == pArr->length)
73787377
{
73797378
// Code below has potential to throw due to OOM or SO. Just FailFast on those cases
7380-
AutoFailFastOnError failFastOnError;
7379+
AutoDisableInterrupt failFastOnError(scriptContext->GetThreadContext());
73817380

73827381
// Array has a single segment (need not start at 0) and splice start lies in the range
73837382
// of that segment we optimize splice - Fast path.
@@ -12708,14 +12707,6 @@ namespace Js
1270812707
return static_cast<JavascriptNativeFloatArray *>(RecyclableObject::FromVar(aValue));
1270912708
}
1271012709

12711-
AutoFailFastOnError::~AutoFailFastOnError()
12712-
{
12713-
if (!m_operationCompleted)
12714-
{
12715-
AssertOrFailFast(false);
12716-
}
12717-
}
12718-
1271912710
template int Js::JavascriptArray::GetParamForIndexOf<unsigned int>(unsigned int, Js::Arguments const&, void*&, unsigned int&, Js::ScriptContext*);
1272012711
template bool Js::JavascriptArray::ArrayElementEnumerator::MoveNext<void*>();
1272112712
template void Js::JavascriptArray::SetArrayLiteralItem<void*>(unsigned int, void*);

lib/Runtime/Library/JavascriptArray.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,19 +1267,4 @@ namespace Js
12671267
template <>
12681268
inline uint32 JavascriptArray::ConvertToIndex<uint32, uint32>(uint32 idxDest, ScriptContext* scriptContext) { return idxDest; }
12691269

1270-
// This is for protecting a region of code, where we can't recover and be consistent upon failures (mainly due to OOM and SO).
1271-
// FailFast on that.
1272-
class AutoFailFastOnError
1273-
{
1274-
public:
1275-
AutoFailFastOnError() : m_operationCompleted(false) { }
1276-
~AutoFailFastOnError();
1277-
1278-
void Completed() { m_operationCompleted = true; }
1279-
1280-
private:
1281-
bool m_operationCompleted;
1282-
};
1283-
1284-
12851270
} // namespace Js

0 commit comments

Comments
 (0)