Skip to content

Commit bc4a399

Browse files
committed
Add detach operation to ExternalArrayBuffer and JsrtExternalArrayBuffer
1 parent 0aeb3a7 commit bc4a399

File tree

7 files changed

+104
-2
lines changed

7 files changed

+104
-2
lines changed

lib/Jsrt/JsrtExternalArrayBuffer.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,41 @@ namespace Js
1919
}
2020

2121
void JsrtExternalArrayBuffer::Finalize(bool isShutdown)
22+
{
23+
if (finalizeCallback != nullptr && !isDetached)
24+
{
25+
finalizeCallback(callbackState);
26+
}
27+
}
28+
29+
ArrayBufferDetachedStateBase* JsrtExternalArrayBuffer::CreateDetachedState(BYTE* buffer, DECLSPEC_GUARD_OVERFLOW uint32 bufferLength)
30+
{
31+
return HeapNew(JsrtExternalArrayBufferDetachedState, buffer, bufferLength, finalizeCallback, callbackState);
32+
};
33+
34+
JsrtExternalArrayBuffer::JsrtExternalArrayBufferDetachedState::JsrtExternalArrayBufferDetachedState(
35+
BYTE* buffer, uint32 bufferLength, JsFinalizeCallback finalizeCallback, void *callbackState)
36+
: ExternalArrayBufferDetachedState(buffer, bufferLength), finalizeCallback(finalizeCallback), callbackState(callbackState)
37+
{}
38+
39+
void JsrtExternalArrayBuffer::JsrtExternalArrayBufferDetachedState::ClearSelfOnly()
40+
{
41+
HeapDelete(this);
42+
}
43+
44+
void JsrtExternalArrayBuffer::JsrtExternalArrayBufferDetachedState::DiscardState()
2245
{
2346
if (finalizeCallback != nullptr)
2447
{
2548
finalizeCallback(callbackState);
2649
}
50+
finalizeCallback = nullptr;
51+
}
52+
53+
ArrayBuffer* JsrtExternalArrayBuffer::JsrtExternalArrayBufferDetachedState::Create(JavascriptLibrary* library)
54+
{
55+
ArrayBuffer* arr = JsrtExternalArrayBuffer::New(buffer, bufferLength, finalizeCallback, callbackState, library->GetArrayBufferType());
56+
JS_ETW(EventWriteJSCRIPT_RECYCLER_ALLOCATE_OBJECT(arr));
57+
return arr;
2758
}
2859
}

lib/Jsrt/JsrtExternalArrayBuffer.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace Js {
1212
DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(JsrtExternalArrayBuffer);
1313

1414
JsrtExternalArrayBuffer(byte *buffer, uint32 length, JsFinalizeCallback finalizeCallback, void *callbackState, DynamicType *type);
15+
virtual ArrayBufferDetachedStateBase* CreateDetachedState(BYTE* buffer, DECLSPEC_GUARD_OVERFLOW uint32 bufferLength) override;
1516

1617
public:
1718
static JsrtExternalArrayBuffer* New(byte *buffer, uint32 length, JsFinalizeCallback finalizeCallback, void *callbackState, DynamicType *type);
@@ -20,6 +21,17 @@ namespace Js {
2021
private:
2122
FieldNoBarrier(JsFinalizeCallback) finalizeCallback;
2223
Field(void *) callbackState;
24+
25+
class JsrtExternalArrayBufferDetachedState : public ExternalArrayBufferDetachedState
26+
{
27+
FieldNoBarrier(JsFinalizeCallback) finalizeCallback;
28+
Field(void *) callbackState;
29+
public:
30+
JsrtExternalArrayBufferDetachedState(BYTE* buffer, uint32 bufferLength, JsFinalizeCallback finalizeCallback, void *callbackState);
31+
virtual void ClearSelfOnly() override;
32+
virtual void DiscardState() override;
33+
virtual ArrayBuffer* Create(JavascriptLibrary* library) override;
34+
};
2335
};
2436
}
2537
AUTO_REGISTER_RECYCLER_OBJECT_DUMPER(Js::JsrtExternalArrayBuffer, &Js::RecyclableObject::DumpObjectFunction);

lib/Runtime/DetachedStateBase.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ namespace Js
4747
{
4848
Heap = 0x0,
4949
CoTask = 0x1,
50-
MemAlloc = 0x02
50+
MemAlloc = 0x02,
51+
External = 0x03,
5152
} ArrayBufferAllocationType;
5253

5354
class ArrayBufferDetachedStateBase : public DetachedStateBase

lib/Runtime/Library/ArrayBuffer.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ namespace Js
3737
case ArrayBufferAllocationType::MemAlloc:
3838
toReturn = library->CreateArrayBuffer(arrayBufferState->buffer, arrayBufferState->bufferLength);
3939
break;
40+
case ArrayBufferAllocationType::External:
41+
toReturn = static_cast<ExternalArrayBufferDetachedState*>(state)->Create(library);
42+
break;
4043
default:
4144
AssertMsg(false, "Unknown allocationType of ArrayBufferDetachedStateBase ");
4245
}
@@ -1028,11 +1031,27 @@ namespace Js
10281031
CoTaskMemFree(buffer);
10291032
}
10301033

1034+
ArrayBuffer* ExternalArrayBufferDetachedState::Create(JavascriptLibrary* library)
1035+
{
1036+
return library->CreateExternalArrayBuffer(buffer, bufferLength);
1037+
}
1038+
10311039
ExternalArrayBuffer::ExternalArrayBuffer(byte *buffer, uint32 length, DynamicType *type)
10321040
: ArrayBuffer(buffer, length, type)
10331041
{
10341042
}
10351043

1044+
ExternalArrayBuffer* ExternalArrayBuffer::Create(byte* buffer, uint32 length, DynamicType * type)
1045+
{
1046+
// This type does not own the external memory, so don't AddExternalMemoryUsage like other ArrayBuffer types do
1047+
return RecyclerNewFinalized(type->GetScriptContext()->GetRecycler(), ExternalArrayBuffer, buffer, length, type);
1048+
}
1049+
1050+
ArrayBufferDetachedStateBase* ExternalArrayBuffer::CreateDetachedState(BYTE* buffer, DECLSPEC_GUARD_OVERFLOW uint32 bufferLength)
1051+
{
1052+
return HeapNew(ExternalArrayBufferDetachedState, buffer, bufferLength);
1053+
};
1054+
10361055
#if ENABLE_TTD
10371056
TTD::NSSnapObjects::SnapObjectType ExternalArrayBuffer::GetSnapTag_TTD() const
10381057
{
@@ -1058,4 +1077,23 @@ namespace Js
10581077
TTD::NSSnapObjects::StdExtractSetKindSpecificInfo<TTD::NSSnapObjects::SnapArrayBufferInfo*, TTD::NSSnapObjects::SnapObjectType::SnapArrayBufferObject>(objData, sabi);
10591078
}
10601079
#endif
1080+
1081+
ExternalArrayBufferDetachedState::ExternalArrayBufferDetachedState(BYTE* buffer, uint32 bufferLength)
1082+
: ArrayBufferDetachedStateBase(TypeIds_ArrayBuffer, buffer, bufferLength, ArrayBufferAllocationType::External)
1083+
{}
1084+
1085+
void ExternalArrayBufferDetachedState::ClearSelfOnly()
1086+
{
1087+
HeapDelete(this);
1088+
}
1089+
1090+
void ExternalArrayBufferDetachedState::DiscardState()
1091+
{
1092+
// Nothing to do as buffer is external
1093+
}
1094+
1095+
void ExternalArrayBufferDetachedState::Discard()
1096+
{
1097+
ClearSelfOnly();
1098+
}
10611099
}

lib/Runtime/Library/ArrayBuffer.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,15 +322,27 @@ namespace Js
322322
protected:
323323
DEFINE_VTABLE_CTOR(ExternalArrayBuffer, ArrayBuffer);
324324
DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(ExternalArrayBuffer);
325+
325326
public:
326327
ExternalArrayBuffer(byte *buffer, DECLSPEC_GUARD_OVERFLOW uint32 length, DynamicType *type);
328+
static ExternalArrayBuffer* Create(byte* buffer, DECLSPEC_GUARD_OVERFLOW uint32 length, DynamicType * type);
327329
protected:
328-
virtual ArrayBufferDetachedStateBase* CreateDetachedState(BYTE* buffer, DECLSPEC_GUARD_OVERFLOW uint32 bufferLength) override { Assert(UNREACHED); Throw::InternalError(); };
330+
virtual ArrayBufferDetachedStateBase* CreateDetachedState(BYTE* buffer, DECLSPEC_GUARD_OVERFLOW uint32 bufferLength) override;
329331

330332
#if ENABLE_TTD
331333
public:
332334
virtual TTD::NSSnapObjects::SnapObjectType GetSnapTag_TTD() const override;
333335
virtual void ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) override;
334336
#endif
335337
};
338+
339+
class ExternalArrayBufferDetachedState : public ArrayBufferDetachedStateBase
340+
{
341+
public:
342+
ExternalArrayBufferDetachedState(BYTE* buffer, uint32 bufferLength);
343+
virtual void ClearSelfOnly() override;
344+
virtual void DiscardState() override;
345+
virtual void Discard() override;
346+
virtual ArrayBuffer* Create(JavascriptLibrary* library);
347+
};
336348
}

lib/Runtime/Library/JavascriptLibrary.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6545,6 +6545,13 @@ namespace Js
65456545
return arr;
65466546
}
65476547

6548+
ArrayBuffer* JavascriptLibrary::CreateExternalArrayBuffer(byte* buffer, uint32 length)
6549+
{
6550+
ArrayBuffer* arr = ExternalArrayBuffer::Create(buffer, length, arrayBufferType);
6551+
JS_ETW(EventWriteJSCRIPT_RECYCLER_ALLOCATE_OBJECT(arr));
6552+
return arr;
6553+
}
6554+
65486555
DataView* JavascriptLibrary::CreateDataView(ArrayBufferBase* arrayBuffer, uint32 offset, uint32 length)
65496556
{
65506557
DataView* dataView = RecyclerNew(this->GetRecycler(), DataView, arrayBuffer, offset, length, dataViewType);

lib/Runtime/Library/JavascriptLibrary.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,7 @@ namespace Js
967967
SharedArrayBuffer* CreateSharedArrayBuffer(SharedContents *contents);
968968
ArrayBuffer* CreateProjectionArraybuffer(uint32 length);
969969
ArrayBuffer* CreateProjectionArraybuffer(byte* buffer, uint32 length);
970+
ArrayBuffer* CreateExternalArrayBuffer(byte* buffer, uint32 length);
970971
DataView* CreateDataView(ArrayBufferBase* arrayBuffer, uint32 offSet, uint32 mappedLength);
971972

972973
template <typename TypeName, bool clamped>

0 commit comments

Comments
 (0)