Bug 1536154 - Update JS_updateMallocCounter callers to use the new API r=bzbarsky

This updates existing callers to use the new JS::AddAssociatedMemory API and adds calls to RemoveAssociatedMemory in finalizers.

The associated memory doesn't need to be exact, so some simplifiations are made, e.g. in CanvasRenderingContext2D where we don't wait for memory to be allocated but update the number of bytes when the dimensions change, and for stream blobs where the value returned by SizeOfIncludingThis changes over the lifetime of the object.

Differential Revision: https://phabricator.services.mozilla.com/D28692
This commit is contained in:
Jon Coppeard 2019-04-24 15:58:42 +01:00
parent b00f4011de
commit 2674733d06
5 changed files with 34 additions and 6 deletions

View File

@ -2591,7 +2591,8 @@ class MOZ_STACK_CLASS BindingJSObjectCreator {
}
if (size_t mallocBytes = BindingJSObjectMallocBytes(aNative)) {
JS_updateMallocCounter(aCx, mallocBytes);
JS::AddAssociatedMemory(aReflector, mallocBytes,
JS::MemoryUse::DOMBinding);
}
}
@ -2607,7 +2608,8 @@ class MOZ_STACK_CLASS BindingJSObjectCreator {
}
if (size_t mallocBytes = BindingJSObjectMallocBytes(aNative)) {
JS_updateMallocCounter(aCx, mallocBytes);
JS::AddAssociatedMemory(aReflector, mallocBytes,
JS::MemoryUse::DOMBinding);
}
}

View File

@ -1757,6 +1757,14 @@ def finalizeHook(descriptor, hookName, freeOp, obj):
finalize += "ClearWrapper(self, self, %s);\n" % obj
if descriptor.isGlobal():
finalize += "mozilla::dom::FinalizeGlobal(CastToJSFreeOp(%s), %s);\n" % (freeOp, obj)
finalize += fill(
"""
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(${obj}, mallocBytes,
JS::MemoryUse::DOMBinding);
}
""",
obj=obj)
finalize += ("AddForDeferredFinalization<%s>(self);\n" %
descriptor.nativeType)
return CGIfWrapper(CGGeneric(finalize), "self")

View File

@ -1486,8 +1486,22 @@ void CanvasRenderingContext2D::ClearTarget(int32_t aWidth, int32_t aHeight) {
// Update dimensions only if new (strictly positive) values were passed.
if (aWidth > 0 && aHeight > 0) {
// Update the memory size associated with the wrapper object when we change
// the dimensions. Note that we need to keep updating dying wrappers before
// they are finalized so that the memory accounting balances out.
JSObject* wrapper = GetWrapperMaybeDead();
if (wrapper) {
JS::RemoveAssociatedMemory(wrapper, BindingJSObjectMallocBytes(this),
JS::MemoryUse::DOMBinding);
}
mWidth = aWidth;
mHeight = aHeight;
if (wrapper) {
JS::AddAssociatedMemory(wrapper, BindingJSObjectMallocBytes(this),
JS::MemoryUse::DOMBinding);
}
}
if (!mCanvasElement || !mCanvasElement->IsInComposedDoc()) {

View File

@ -13,6 +13,7 @@
#include "nsPIDOMWindow.h"
#include "StreamBlobImpl.h"
#include "StringBlobImpl.h"
#include "js/GCAPI.h"
namespace mozilla {
namespace dom {
@ -229,6 +230,12 @@ void Blob::CreateInputStream(nsIInputStream** aStream, ErrorResult& aRv) {
size_t BindingJSObjectMallocBytes(Blob* aBlob) {
MOZ_ASSERT(aBlob);
// TODO: The hazard analysis currently can't see that none of the
// implementations of the GetAllocationSize virtual method call can GC (see
// bug 1531951).
JS::AutoSuppressGCAnalysis nogc;
return aBlob->GetAllocationSize();
}

View File

@ -357,6 +357,7 @@ nsresult TypedArrayResult::GetCacheableResult(
const ArrayBufferContents& contents = mContents.get();
MOZ_ASSERT(contents.data);
// This takes ownership of the buffer and notes the memory allocation.
JS::Rooted<JSObject*> arrayBuffer(
cx, JS::NewArrayBufferWithContents(cx, contents.nbytes, contents.data));
if (!arrayBuffer) {
@ -368,10 +369,6 @@ nsresult TypedArrayResult::GetCacheableResult(
if (!result) {
return NS_ERROR_OUT_OF_MEMORY;
}
// The memory of contents has been allocated on a thread that
// doesn't have a JSRuntime, hence without a context. Now that we
// have a context, attach the memory to where it belongs.
JS_updateMallocCounter(cx, contents.nbytes);
mContents.forget();
aResult.setObject(*result);