Skip to content

Commit f060d7d

Browse files
committed
Detach input buffer in JsrtSourceHolder to keep it alive longer than the ArrayBuffer container object
1 parent bc4a399 commit f060d7d

File tree

4 files changed

+21
-11
lines changed

4 files changed

+21
-11
lines changed

lib/Jsrt/ChakraCore.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,8 @@ CHAKRA_API
540540
/// Requires an active script context.
541541
/// </para>
542542
/// <para>
543-
/// The runtime will hold on to the buffer until all instances of any functions created from
544-
/// the buffer are garbage collected.
543+
/// The runtime will detach the data from the buffer and hold on to it until all
544+
/// instances of any functions created from the buffer are garbage collected.
545545
/// </para>
546546
/// </remarks>
547547
/// <param name="buffer">The serialized script as an ArrayBuffer (preferably ExternalArrayBuffer).</param>

lib/Jsrt/Jsrt.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3706,7 +3706,7 @@ template <typename TLoadCallback, typename TUnloadCallback>
37063706
JsErrorCode RunSerializedScriptCore(
37073707
TLoadCallback scriptLoadCallback, TUnloadCallback scriptUnloadCallback,
37083708
JsSourceContext scriptLoadSourceContext, // only used by scriptLoadCallback
3709-
unsigned char *buffer, JsValueRef bufferVal,
3709+
unsigned char *buffer, Js::ArrayBuffer* bufferVal,
37103710
JsSourceContext sourceContext, const WCHAR *sourceUrl,
37113711
bool parseOnly, JsValueRef *result)
37123712
{
@@ -4939,12 +4939,13 @@ CHAKRA_API JsParseSerialized(
49394939
return JsErrorInvalidArgument;
49404940
}
49414941

4942-
byte* buffer = Js::ArrayBuffer::FromVar(bufferVal)->GetBuffer();
4942+
Js::ArrayBuffer* arrayBuffer = Js::ArrayBuffer::FromVar(bufferVal);
4943+
byte* buffer = arrayBuffer->GetBuffer();
49434944

49444945
return RunSerializedScriptCore(
49454946
scriptLoadCallback, DummyScriptUnloadCallback,
49464947
sourceContext,// use the same user provided sourceContext as scriptLoadSourceContext
4947-
buffer, bufferVal, sourceContext, url, true, result);
4948+
buffer, arrayBuffer, sourceContext, url, true, result);
49484949
}
49494950

49504951
CHAKRA_API JsRunSerialized(
@@ -4972,12 +4973,13 @@ CHAKRA_API JsRunSerialized(
49724973
return JsErrorInvalidArgument;
49734974
}
49744975

4975-
byte* buffer = Js::ArrayBuffer::FromVar(bufferVal)->GetBuffer();
4976+
Js::ArrayBuffer* arrayBuffer = Js::ArrayBuffer::FromVar(bufferVal);
4977+
byte* buffer = arrayBuffer->GetBuffer();
49764978

49774979
return RunSerializedScriptCore(
49784980
scriptLoadCallback, DummyScriptUnloadCallback,
49794981
sourceContext, // use the same user provided sourceContext as scriptLoadSourceContext
4980-
buffer, bufferVal, sourceContext, url, false, result);
4982+
buffer, arrayBuffer, sourceContext, url, false, result);
49814983
}
49824984

49834985
CHAKRA_API JsCreatePromise(_Out_ JsValueRef *promise, _Out_ JsValueRef *resolve, _Out_ JsValueRef *reject)

lib/Jsrt/JsrtSourceHolder.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,6 @@ namespace Js
299299
this->mappedSource = nullptr;
300300
}
301301
this->mappedScriptValue = nullptr;
302-
this->mappedSerializedScriptValue = nullptr;
303302

304303
// Don't allow load or unload again after told to unload.
305304
scriptLoadCallback = nullptr;

lib/Jsrt/JsrtSourceHolder.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace Js
1919

2020
#ifndef NTBUILD
2121
Field(JsValueRef) mappedScriptValue;
22-
Field(JsValueRef) mappedSerializedScriptValue;
22+
Field(DetachedStateBase*) mappedSerializedScriptValue;
2323
#endif
2424
Field(utf8char_t const *) mappedSource;
2525
Field(size_t) mappedSourceByteLength;
@@ -46,13 +46,13 @@ namespace Js
4646
JsrtSourceHolder(_In_ TLoadCallback scriptLoadCallback,
4747
_In_ TUnloadCallback scriptUnloadCallback,
4848
_In_ JsSourceContext sourceContext,
49-
JsValueRef serializedScriptValue = nullptr) :
49+
Js::ArrayBuffer* serializedScriptValue = nullptr) :
5050
scriptLoadCallback(scriptLoadCallback),
5151
scriptUnloadCallback(scriptUnloadCallback),
5252
sourceContext(sourceContext),
5353
#ifndef NTBUILD
5454
mappedScriptValue(nullptr),
55-
mappedSerializedScriptValue(serializedScriptValue),
55+
mappedSerializedScriptValue(serializedScriptValue == nullptr ? nullptr : serializedScriptValue->DetachAndGetState()),
5656
#endif
5757
mappedSourceByteLength(0),
5858
mappedSource(nullptr)
@@ -89,6 +89,15 @@ namespace Js
8989

9090
virtual void Dispose(bool isShutdown) override
9191
{
92+
#ifndef NTBUILD
93+
if (this->mappedSerializedScriptValue != nullptr)
94+
{
95+
// We have to extend the buffer data's lifetime until Dispose because
96+
// it might be used during finalization of other objects, such as
97+
// FunctionEntryPointInfo which wants to log its name.
98+
this->mappedSerializedScriptValue->CleanUp();
99+
}
100+
#endif
92101
}
93102

94103
virtual void Mark(Recycler * recycler) override

0 commit comments

Comments
 (0)