Skip to content

Commit fbec449

Browse files
atulkattiAtul Katti
authored andcommitted
MSFT:18139538 Remove the use of Guest Arena from parser code to avoid ScriptContext leak.
1 parent 288d7fe commit fbec449

File tree

5 files changed

+11
-38
lines changed

5 files changed

+11
-38
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 (ptr != nullptr)
54+
if (this->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,8 +82,9 @@ 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()),
8586
// use the GuestArena directly for keeping the RegexPattern* alive during byte code generation
86-
m_registeredRegexPatterns(scriptContext->GetGuestArena()),
87+
m_registeredRegexPatterns(m_tempGuestArena->GetAllocator()),
8788

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

155156
Parser::~Parser(void)
156157
{
157-
if (m_scriptContext == nullptr || m_scriptContext->GetGuestArena() == nullptr)
158+
m_registeredRegexPatterns.Reset();
159+
if (m_scriptContext != nullptr)
158160
{
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();
161+
m_scriptContext->ReleaseTemporaryGuestAllocator(m_tempGuestArena);
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_scriptContext->GetGuestArena(), regexPattern))
1928+
if (!m_registeredRegexPatterns.PrependNoThrow(m_tempGuestArena->GetAllocator(), regexPattern))
19291929
{
19301930
Parser::Error(ERRnoMemory);
19311931
}

lib/Parser/Parse.h

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

182184
class Parser
@@ -273,8 +275,9 @@ class Parser
273275
#endif
274276
int m_nextBlockId;
275277

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

lib/Runtime/Base/ScriptContext.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ namespace Js
8888
integerStringMapCacheMissCount(0),
8989
integerStringMapCacheUseCount(0),
9090
#endif
91-
guestArena(nullptr),
9291
#ifdef ENABLE_SCRIPT_DEBUGGING
9392
diagnosticArena(nullptr),
9493
raiseMessageToDebuggerFunctionType(nullptr),
@@ -798,12 +797,6 @@ namespace Js
798797
interpreterArena = nullptr;
799798
}
800799

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

809802
pActiveScriptDirect = nullptr;
@@ -1304,8 +1297,6 @@ namespace Js
13041297

13051298
void ScriptContext::InitializePreGlobal()
13061299
{
1307-
this->guestArena = this->GetRecycler()->CreateGuestArena(_u("Guest"), Throw::OutOfMemory);
1308-
13091300
#if ENABLE_BACKGROUND_PARSING
13101301
if (PHASE_ON1(Js::ParallelParsePhase))
13111302
{
@@ -2680,17 +2671,6 @@ namespace Js
26802671
}
26812672
}
26822673

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-
26942674
void ScriptContext::SetScriptStartEventHandler(ScriptContext::EventHandler eventHandler)
26952675
{
26962676
AssertMsg(this->scriptStartEventHandler == nullptr, "Do not support multi-cast yet");
@@ -4895,7 +4875,6 @@ namespace Js
48954875
void ScriptContext::BindReference(void * addr)
48964876
{
48974877
Assert(!this->isClosed);
4898-
Assert(this->guestArena);
48994878
Assert(recycler->IsValidObject(addr));
49004879
#if DBG
49014880
Assert(!bindRef.ContainsKey(addr)); // Make sure we don't bind the same pointer twice
@@ -5062,7 +5041,6 @@ namespace Js
50625041
{
50635042
return;
50645043
}
5065-
Assert(this->guestArena);
50665044

50675045
if (EnableEvalMapCleanup())
50685046
{

lib/Runtime/Base/ScriptContext.h

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

580580
ArenaAllocator* interpreterArena;
581-
ArenaAllocator* guestArena;
582581

583582
#ifdef ENABLE_SCRIPT_DEBUGGING
584583
ArenaAllocator* diagnosticArena;
@@ -1378,13 +1377,6 @@ namespace Js
13781377
bool EnsureInterpreterArena(ArenaAllocator **);
13791378
void ReleaseInterpreterArena();
13801379

1381-
ArenaAllocator* GetGuestArena() const
1382-
{
1383-
return guestArena;
1384-
}
1385-
1386-
void ReleaseGuestArena();
1387-
13881380
Recycler* GetRecycler() const { return recycler; }
13891381
RecyclerJavascriptNumberAllocator * GetNumberAllocator() { return &numberAllocator; }
13901382
#if ENABLE_NATIVE_CODEGEN

0 commit comments

Comments
 (0)