Update ArrayBuffer to use new BackingStore API (fixes issue #3074)

This commit is contained in:
Marshall Greenblatt 2021-03-12 12:26:52 -05:00
parent c4baba880e
commit 1587d6da03
2 changed files with 26 additions and 5 deletions

View File

@ -329,9 +329,7 @@ class V8TrackArrayBuffer : public CefTrackNode {
} }
~V8TrackArrayBuffer() { ~V8TrackArrayBuffer() {
if (buffer_ != nullptr) { ReleaseBuffer();
release_callback_->ReleaseBuffer(buffer_);
}
isolate_->AdjustAmountOfExternalAllocatedMemory( isolate_->AdjustAmountOfExternalAllocatedMemory(
-static_cast<int>(sizeof(V8TrackArrayBuffer))); -static_cast<int>(sizeof(V8TrackArrayBuffer)));
} }
@ -340,6 +338,13 @@ class V8TrackArrayBuffer : public CefTrackNode {
return release_callback_; return release_callback_;
} }
void ReleaseBuffer() {
if (buffer_ && release_callback_) {
release_callback_->ReleaseBuffer(buffer_);
}
Detach();
}
void Detach() { buffer_ = nullptr; } void Detach() { buffer_ = nullptr; }
// Attach this track object to the specified V8 object. // Attach this track object to the specified V8 object.
@ -1410,7 +1415,18 @@ CefRefPtr<CefV8Value> CefV8Value::CreateArrayBuffer(
// released when the V8 object is destroyed. // released when the V8 object is destroyed.
V8TrackArrayBuffer* tracker = V8TrackArrayBuffer* tracker =
new V8TrackArrayBuffer(isolate, buffer, release_callback); new V8TrackArrayBuffer(isolate, buffer, release_callback);
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, buffer, length);
auto deleter = [](void* data, size_t length, void* deleter_data) {
auto* tracker = reinterpret_cast<V8TrackArrayBuffer*>(deleter_data);
if (tracker) {
tracker->ReleaseBuffer();
}
};
std::unique_ptr<v8::BackingStore> backing =
v8::ArrayBuffer::NewBackingStore(buffer, length, deleter, tracker);
v8::Local<v8::ArrayBuffer> ab =
v8::ArrayBuffer::New(isolate, std::move(backing));
// Attach the tracker object. // Attach the tracker object.
tracker->AttachTo(context, ab); tracker->AttachTo(context, ab);

View File

@ -577,13 +577,18 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
->GetArrayBufferReleaseCallback() ->GetArrayBufferReleaseCallback()
.get()) == release_callback); .get()) == release_callback);
// |neuteredValue| buffer is explicitly freed by NeuterArrayBuffer().
EXPECT_FALSE(neuteredReleaseBufferCalled);
EXPECT_TRUE(neuteredValue->NeuterArrayBuffer()); EXPECT_TRUE(neuteredValue->NeuterArrayBuffer());
EXPECT_TRUE(neuteredReleaseBufferCalled);
// |value| buffer is implicitly freed when the value goes out of scope.
EXPECT_FALSE(releaseBufferCalled);
} }
// Exit the V8 context. // Exit the V8 context.
EXPECT_TRUE(destructorCalled); EXPECT_TRUE(destructorCalled);
EXPECT_TRUE(releaseBufferCalled); EXPECT_TRUE(releaseBufferCalled);
EXPECT_TRUE(neuteredDestructorCalled); EXPECT_TRUE(neuteredDestructorCalled);
EXPECT_FALSE(neuteredReleaseBufferCalled);
EXPECT_TRUE(context->Exit()); EXPECT_TRUE(context->Exit());
DestroyTest(); DestroyTest();
} }