Skip to content

Commit 2389070

Browse files
author
Atul Katti
committed
[MERGE #5441 @atulkatti] Revert "MSFT:18139538 Remove the use of Guest Arena from parser code to avoid ScriptContext leak."
Merge pull request #5441 from atulkatti:Revert.ParserGuestArenaRemoval.1 This reverts commit 3fb7fdd. This introduced a leak in the modules that will need non-trivial work to get rid of.
2 parents 2353319 + 1393e18 commit 2389070

File tree

5 files changed

+38
-11
lines changed

5 files changed

+38
-11
lines changed

lib/Common/Memory/RecyclerRootPtr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class AutoRecyclerRootPtr : public RecyclerRootPtr<T>
5151
}
5252
void Unroot()
5353
{
54-
if (this->ptr != nullptr)
54+
if (ptr != nullptr)
5555
{
5656
__super::Unroot(recycler);
5757
}

lib/Parser/Parse.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,8 @@ Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator
8282
m_doingFastScan(false),
8383
#endif
8484
m_nextBlockId(0),
85-
m_tempGuestArena(scriptContext->GetTemporaryGuestAllocator(_u("ParserRegex")), scriptContext->GetRecycler()),
8685
// use the GuestArena directly for keeping the RegexPattern* alive during byte code generation
87-
m_registeredRegexPatterns(m_tempGuestArena->GetAllocator()),
86+
m_registeredRegexPatterns(scriptContext->GetGuestArena()),
8887

8988
m_scriptContext(scriptContext),
9089
m_token(), // should initialize to 0/nullptrs
@@ -155,10 +154,11 @@ Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator
155154

156155
Parser::~Parser(void)
157156
{
158-
m_registeredRegexPatterns.Reset();
159-
if (m_scriptContext != nullptr)
157+
if (m_scriptContext == nullptr || m_scriptContext->GetGuestArena() == nullptr)
160158
{
161-
m_scriptContext->ReleaseTemporaryGuestAllocator(m_tempGuestArena);
159+
// If the scriptContext or guestArena have gone away, there is no point clearing each item of this list.
160+
// Just reset it so that destructor of the SList will be no-op
161+
m_registeredRegexPatterns.Reset();
162162
}
163163

164164
#if ENABLE_BACKGROUND_PARSING
@@ -1925,7 +1925,7 @@ void Parser::RegisterRegexPattern(UnifiedRegex::RegexPattern *const regexPattern
19251925
Assert(regexPattern);
19261926

19271927
// ensure a no-throw add behavior here, to catch out of memory exceptions, using the guest arena allocator
1928-
if (!m_registeredRegexPatterns.PrependNoThrow(m_tempGuestArena->GetAllocator(), regexPattern))
1928+
if (!m_registeredRegexPatterns.PrependNoThrow(m_scriptContext->GetGuestArena(), regexPattern))
19291929
{
19301930
Parser::Error(ERRnoMemory);
19311931
}

lib/Parser/Parse.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,6 @@ namespace Js
177177
{
178178
class ParseableFunctionInfo;
179179
class FunctionBody;
180-
template <bool isGuestArena>
181-
class TempArenaAllocatorWrapper;
182180
};
183181

184182
class Parser
@@ -275,9 +273,8 @@ class Parser
275273
#endif
276274
int m_nextBlockId;
277275

278-
AutoRecyclerRootPtr<Js::TempArenaAllocatorWrapper<true>> m_tempGuestArena;
279276
// RegexPattern objects created for literal regexes are recycler-allocated and need to be kept alive until the function body
280-
// is created during byte code generation. The RegexPattern pointer is stored in a temporary guest
277+
// is created during byte code generation. The RegexPattern pointer is stored in the script context's guest
281278
// arena for that purpose. This list is then unregistered from the guest arena at the end of parsing/scanning.
282279
SList<UnifiedRegex::RegexPattern *, ArenaAllocator> m_registeredRegexPatterns;
283280

lib/Runtime/Base/ScriptContext.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ namespace Js
8888
integerStringMapCacheMissCount(0),
8989
integerStringMapCacheUseCount(0),
9090
#endif
91+
guestArena(nullptr),
9192
#ifdef ENABLE_SCRIPT_DEBUGGING
9293
diagnosticArena(nullptr),
9394
raiseMessageToDebuggerFunctionType(nullptr),
@@ -797,6 +798,12 @@ namespace Js
797798
interpreterArena = nullptr;
798799
}
799800

801+
if (this->guestArena)
802+
{
803+
ReleaseGuestArena();
804+
guestArena = nullptr;
805+
}
806+
800807
builtInLibraryFunctions = nullptr;
801808

802809
pActiveScriptDirect = nullptr;
@@ -1297,6 +1304,8 @@ namespace Js
12971304

12981305
void ScriptContext::InitializePreGlobal()
12991306
{
1307+
this->guestArena = this->GetRecycler()->CreateGuestArena(_u("Guest"), Throw::OutOfMemory);
1308+
13001309
#if ENABLE_BACKGROUND_PARSING
13011310
if (PHASE_ON1(Js::ParallelParsePhase))
13021311
{
@@ -2671,6 +2680,17 @@ namespace Js
26712680
}
26722681
}
26732682

2683+
2684+
void ScriptContext::ReleaseGuestArena()
2685+
{
2686+
AssertMsg(this->guestArena, "No guest arena to release");
2687+
if (this->guestArena)
2688+
{
2689+
this->GetRecycler()->DeleteGuestArena(this->guestArena);
2690+
this->guestArena = nullptr;
2691+
}
2692+
}
2693+
26742694
void ScriptContext::SetScriptStartEventHandler(ScriptContext::EventHandler eventHandler)
26752695
{
26762696
AssertMsg(this->scriptStartEventHandler == nullptr, "Do not support multi-cast yet");
@@ -4875,6 +4895,7 @@ namespace Js
48754895
void ScriptContext::BindReference(void * addr)
48764896
{
48774897
Assert(!this->isClosed);
4898+
Assert(this->guestArena);
48784899
Assert(recycler->IsValidObject(addr));
48794900
#if DBG
48804901
Assert(!bindRef.ContainsKey(addr)); // Make sure we don't bind the same pointer twice
@@ -5041,6 +5062,7 @@ namespace Js
50415062
{
50425063
return;
50435064
}
5065+
Assert(this->guestArena);
50445066

50455067
if (EnableEvalMapCleanup())
50465068
{

lib/Runtime/Base/ScriptContext.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ namespace Js
578578
CacheAllocator enumeratorCacheAllocator;
579579

580580
ArenaAllocator* interpreterArena;
581+
ArenaAllocator* guestArena;
581582

582583
#ifdef ENABLE_SCRIPT_DEBUGGING
583584
ArenaAllocator* diagnosticArena;
@@ -1377,6 +1378,13 @@ namespace Js
13771378
bool EnsureInterpreterArena(ArenaAllocator **);
13781379
void ReleaseInterpreterArena();
13791380

1381+
ArenaAllocator* GetGuestArena() const
1382+
{
1383+
return guestArena;
1384+
}
1385+
1386+
void ReleaseGuestArena();
1387+
13801388
Recycler* GetRecycler() const { return recycler; }
13811389
RecyclerJavascriptNumberAllocator * GetNumberAllocator() { return &numberAllocator; }
13821390
#if ENABLE_NATIVE_CODEGEN

0 commit comments

Comments
 (0)