@@ -218,11 +218,10 @@ namespace Js
218
218
{
219
219
Assert (!this ->isDetached );
220
220
221
- if (this ->IsProjectionArrayBuffer ())
222
- {
223
- Recycler* recycler = GetType ()->GetLibrary ()->GetRecycler ();
224
- recycler->ReportExternalMemoryFree (bufferLength);
225
- }
221
+ // we are about to lose track of the buffer to another owner
222
+ // report that we no longer own the memory
223
+ Recycler* recycler = GetType ()->GetLibrary ()->GetRecycler ();
224
+ recycler->ReportExternalMemoryFree (bufferLength);
226
225
227
226
this ->buffer = nullptr ;
228
227
this ->bufferLength = 0 ;
@@ -702,6 +701,13 @@ namespace Js
702
701
Recycler* recycler = type->GetScriptContext ()->GetRecycler ();
703
702
JavascriptArrayBuffer* result = RecyclerNewFinalized (recycler, JavascriptArrayBuffer, buffer, length, type);
704
703
Assert (result);
704
+
705
+ // we take the ownership of the buffer and will have to free it so charge it to our quota.
706
+ if (!recycler->RequestExternalMemoryAllocation (length))
707
+ {
708
+ JavascriptError::ThrowOutOfMemoryError (result->GetScriptContext ());
709
+ }
710
+
705
711
recycler->AddExternalMemoryUsage (length);
706
712
return result;
707
713
}
@@ -713,12 +719,6 @@ namespace Js
713
719
{
714
720
freeFunction (this ->buffer );
715
721
this ->buffer = nullptr ;
716
-
717
- // for projection array buffers we have already reported freeing on detach
718
- if (this ->allocationType != ArrayBufferAllocationType::CoTask)
719
- {
720
- this ->recycler ->ReportExternalMemoryFree (this ->bufferLength );
721
- }
722
722
}
723
723
this ->bufferLength = 0 ;
724
724
}
@@ -890,6 +890,12 @@ namespace Js
890
890
if (buffer)
891
891
{
892
892
result = RecyclerNewFinalized (recycler, WebAssemblyArrayBuffer, buffer, length, type);
893
+
894
+ // we take the ownership of the buffer and will have to free it so charge it to our quota.
895
+ if (!recycler->RequestExternalMemoryAllocation (length))
896
+ {
897
+ JavascriptError::ThrowOutOfMemoryError (result->GetScriptContext ());
898
+ }
893
899
}
894
900
else
895
901
{
@@ -903,9 +909,9 @@ namespace Js
903
909
{
904
910
result = RecyclerNewFinalized (recycler, WebAssemblyArrayBuffer, length, type);
905
911
}
906
- // Only add external memory when we create a new internal buffer
907
- recycler->AddExternalMemoryUsage (length);
908
912
}
913
+
914
+ recycler->AddExternalMemoryUsage (length);
909
915
Assert (result);
910
916
return result;
911
917
}
@@ -960,6 +966,11 @@ namespace Js
960
966
{
961
967
return nullptr ;
962
968
}
969
+
970
+ // We are transferring the buffer to the new owner.
971
+ // To avoid double-charge to the allocation quota we will free the "diff" amount here.
972
+ this ->GetRecycler ()->ReportExternalMemoryFree (growSize);
973
+
963
974
return finalizeGrowMemory (this ->GetLibrary ()->CreateWebAssemblyArrayBuffer (this ->buffer , newBufferLength));
964
975
}
965
976
#endif
@@ -995,6 +1006,10 @@ namespace Js
995
1006
return nullptr ;
996
1007
}
997
1008
1009
+ // We are transferring the buffer to the new owner.
1010
+ // To avoid double-charge to the allocation quota we will free the "diff" amount here.
1011
+ this ->GetRecycler ()->ReportExternalMemoryFree (growSize);
1012
+
998
1013
WebAssemblyArrayBuffer* newArrayBuffer = finalizeGrowMemory (this ->GetLibrary ()->CreateWebAssemblyArrayBuffer (newBuffer, newBufferLength));
999
1014
// We've successfully Detached this buffer and created a new WebAssemblyArrayBuffer
1000
1015
autoDisableInterrupt.Completed ();
0 commit comments