Skip to content

Commit a5fd26c

Browse files
author
Thomas Moore (CHAKRA)
committed
Indicate how bytecode serializer allocates return buffer
This change allows for callers to ByteCodeSerializer to specify if the buffer containing the serialized bytecode (and parser cache state) should be allocated with ANew or CoTaskMemAlloc. The caller is then responsible for freeing the memory appropriately after use.
1 parent 5e5e7b1 commit a5fd26c

File tree

6 files changed

+32
-16
lines changed

6 files changed

+32
-16
lines changed

lib/Jsrt/Jsrt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3819,7 +3819,7 @@ JsErrorCode JsSerializeScriptCore(const byte *script, size_t cb,
38193819
// However, the PAL defines DWORD for us on linux as unsigned int so the cast is safe here.
38203820
HRESULT hr = Js::ByteCodeSerializer::SerializeToBuffer(scriptContext,
38213821
tempAllocator, static_cast<DWORD>(cSourceCodeLength), utf8Code,
3822-
functionBody, functionBody->GetHostSrcInfo(), false, &buffer,
3822+
functionBody, functionBody->GetHostSrcInfo(), &buffer,
38233823
(DWORD*) bufferSize, dwFlags);
38243824
END_TEMP_ALLOCATOR(tempAllocator, scriptContext);
38253825

lib/Parser/BGParseManager.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,10 +541,9 @@ void BGParseWorkItem::ParseUTF8Core(Js::ScriptContext* scriptContext)
541541
this->script,
542542
functionBody,
543543
functionBody->GetHostSrcInfo(),
544-
true, // allocateBuffer
545544
&this->bufferReturn,
546545
&this->bufferReturnBytes,
547-
GENERATE_BYTE_CODE_PARSER_STATE
546+
GENERATE_BYTE_CODE_PARSER_STATE | GENERATE_BYTE_CODE_COTASKMEMALLOC
548547
);
549548
END_TEMP_ALLOCATOR(tempAllocator, scriptContext);
550549
Assert(this->parseHR == S_OK);

lib/Runtime/Base/ScriptContext.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,7 +2229,7 @@ namespace Js
22292229
#ifdef ENABLE_WININET_PROFILE_DATA_CACHE
22302230
byte* serializeParserStateCacheBuffer = parserStateCacheBuffer;
22312231
DWORD serializeParserStateCacheSize = parserStateCacheByteCount;
2232-
DWORD dwFlags = GENERATE_BYTE_CODE_PARSER_STATE;
2232+
DWORD dwFlags = GENERATE_BYTE_CODE_PARSER_STATE | GENERATE_BYTE_CODE_ALLOC_ANEW;
22332233
DebugOnly(auto url = !srcInfo->sourceContextInfo->isHostDynamicDocument ? srcInfo->sourceContextInfo->url : this->GetUrl());
22342234

22352235
// If we already have a parser state cache serialized into a buffer, we should skip creating it again
@@ -2242,7 +2242,7 @@ namespace Js
22422242
BEGIN_TEMP_ALLOCATOR(tempAllocator, this, _u("ByteCodeSerializer"));
22432243
hr = Js::ByteCodeSerializer::SerializeToBuffer(this,
22442244
tempAllocator, (DWORD)cbLength, pszSrc, func->GetFunctionBody(),
2245-
func->GetHostSrcInfo(), true, &serializeParserStateCacheBuffer,
2245+
func->GetHostSrcInfo(), &serializeParserStateCacheBuffer,
22462246
&serializeParserStateCacheSize, dwFlags);
22472247
END_TEMP_ALLOCATOR(tempAllocator, this);
22482248

@@ -2410,7 +2410,7 @@ namespace Js
24102410

24112411
return Js::ByteCodeSerializer::SerializeToBuffer(this,
24122412
alloc, static_cast<DWORD>(cSourceCodeLength), utf8Code,
2413-
functionBody, functionBody->GetHostSrcInfo(), false, buffer,
2413+
functionBody, functionBody->GetHostSrcInfo(), buffer,
24142414
bufferSize, dwFlags);
24152415
}
24162416
else

lib/Runtime/ByteCode/ByteCodeSerializeFlags.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
//-------------------------------------------------------------------------------------------------------
55
#pragma once
66

7-
#define GENERATE_BYTE_CODE_BUFFER_LIBRARY 0x00000001
8-
#define GENERATE_BYTE_CODE_FOR_NATIVE 0x00000002
9-
#define GENERATE_BYTE_CODE_PARSER_STATE 0x00000004
7+
#define GENERATE_BYTE_CODE_BUFFER_LIBRARY 0x00000001
8+
#define GENERATE_BYTE_CODE_FOR_NATIVE 0x00000002
9+
#define GENERATE_BYTE_CODE_PARSER_STATE 0x00000004
10+
// When the return buffer needs to be allocated while generating bytecode, use one
11+
// of these flags to indicate how to allocate the memory. The absence of both flags
12+
// indicates that no allocation is needed.
13+
#define GENERATE_BYTE_CODE_COTASKMEMALLOC 0x00000008
14+
#define GENERATE_BYTE_CODE_ALLOC_ANEW 0x00000010

lib/Runtime/ByteCode/ByteCodeSerializer.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,16 @@ class ByteCodeBufferBuilder
420420
return (dwFlags & GENERATE_BYTE_CODE_PARSER_STATE) != 0;
421421
}
422422

423+
bool ShouldAllocWithCoTaskMem() const
424+
{
425+
return (dwFlags & GENERATE_BYTE_CODE_COTASKMEMALLOC);
426+
}
427+
428+
bool ShouldAllocWithANew() const
429+
{
430+
return (dwFlags & GENERATE_BYTE_CODE_ALLOC_ANEW);
431+
}
432+
423433
public:
424434

425435
ByteCodeBufferBuilder(uint32 sourceSize, uint32 sourceCharLength, LPCUTF8 utf8Source, Utf8SourceInfo* sourceInfo, ScriptContext * scriptContext, ArenaAllocator * alloc, DWORD dwFlags, int builtInPropertyCount)
@@ -528,7 +538,7 @@ class ByteCodeBufferBuilder
528538
string16ToId = Anew(alloc, TString16ToId, alloc);
529539
}
530540

531-
HRESULT Create(bool allocateBuffer, byte ** buffer, DWORD * bufferBytes)
541+
HRESULT Create(byte ** buffer, DWORD * bufferBytes)
532542
{
533543
BufferBuilderList all(_u("Final"));
534544

@@ -574,15 +584,16 @@ class ByteCodeBufferBuilder
574584
totalSize.value = size;
575585

576586
// Allocate the bytes
577-
if (allocateBuffer)
587+
if (ShouldAllocWithANew() || ShouldAllocWithCoTaskMem())
578588
{
579589
*bufferBytes = size;
580-
if (GenerateParserStateCache())
590+
if (ShouldAllocWithANew())
581591
{
582592
*buffer = AnewArray(scriptContext->SourceCodeAllocator(), byte, *bufferBytes);
583593
}
584594
else
585595
{
596+
Assert(ShouldAllocWithCoTaskMem());
586597
*buffer = (byte*)CoTaskMemAlloc(*bufferBytes);
587598
}
588599

@@ -4701,7 +4712,7 @@ FunctionInfo* ByteCodeCache::LookupFunctionInfo(ScriptContext * scriptContext, L
47014712
}
47024713

47034714
// Serialize function body
4704-
HRESULT ByteCodeSerializer::SerializeToBuffer(ScriptContext * scriptContext, ArenaAllocator * alloc, DWORD sourceByteLength, LPCUTF8 utf8Source, FunctionBody * function, SRCINFO const* srcInfo, bool allocateBuffer, byte ** buffer, DWORD * bufferBytes, DWORD dwFlags)
4715+
HRESULT ByteCodeSerializer::SerializeToBuffer(ScriptContext * scriptContext, ArenaAllocator * alloc, DWORD sourceByteLength, LPCUTF8 utf8Source, FunctionBody * function, SRCINFO const* srcInfo, byte ** buffer, DWORD * bufferBytes, DWORD dwFlags)
47054716
{
47064717
int builtInPropertyCount = (dwFlags & GENERATE_BYTE_CODE_BUFFER_LIBRARY) != 0 ? PropertyIds::_countJSOnlyProperty : TotalNumberOfBuiltInProperties;
47074718

@@ -4715,7 +4726,8 @@ HRESULT ByteCodeSerializer::SerializeToBuffer(ScriptContext * scriptContext, Are
47154726

47164727
ArenaAllocator* codeAllocator = nullptr;
47174728
ByteCodeCache* cache = nullptr;
4718-
if (((dwFlags & GENERATE_BYTE_CODE_PARSER_STATE) != 0) && allocateBuffer)
4729+
DWORD shouldUseCodeAllocator = GENERATE_BYTE_CODE_PARSER_STATE | GENERATE_BYTE_CODE_ALLOC_ANEW;
4730+
if ((dwFlags & shouldUseCodeAllocator) == shouldUseCodeAllocator) // does this apply for cotaskmemalloc as well?
47194731
{
47204732
codeAllocator = scriptContext->SourceCodeAllocator();
47214733
cache = Anew(codeAllocator, ByteCodeCache, scriptContext, builtInPropertyCount);
@@ -4728,7 +4740,7 @@ HRESULT ByteCodeSerializer::SerializeToBuffer(ScriptContext * scriptContext, Are
47284740

47294741
if (SUCCEEDED(hr))
47304742
{
4731-
hr = builder.Create(allocateBuffer, buffer, bufferBytes);
4743+
hr = builder.Create(buffer, bufferBytes);
47324744
}
47334745

47344746
if (SUCCEEDED(hr) && cache != nullptr)

lib/Runtime/ByteCode/ByteCodeSerializer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ namespace Js
167167
struct ByteCodeSerializer
168168
{
169169
// Serialize a function body.
170-
static HRESULT SerializeToBuffer(ScriptContext * scriptContext, ArenaAllocator * alloc, DWORD sourceByteLength, LPCUTF8 utf8Source, FunctionBody * function, SRCINFO const* srcInfo, bool allocateBuffer, byte ** buffer, DWORD * bufferBytes, DWORD dwFlags = 0);
170+
static HRESULT SerializeToBuffer(ScriptContext * scriptContext, ArenaAllocator * alloc, DWORD sourceByteLength, LPCUTF8 utf8Source, FunctionBody * function, SRCINFO const* srcInfo, byte ** buffer, DWORD * bufferBytes, DWORD dwFlags = 0);
171171

172172
// Deserialize a function body. The content of utf8Source must be the same as was originally passed to SerializeToBuffer
173173
static HRESULT DeserializeFromBuffer(ScriptContext * scriptContext, uint32 scriptFlags, LPCUTF8 utf8Source, SRCINFO const * srcInfo, byte * buffer, NativeModule *nativeModule, Field(FunctionBody*)* function, uint sourceIndex = Js::Constants::InvalidSourceIndex);

0 commit comments

Comments
 (0)