[api] Deprecate [Shared]ArrayBuffer::Externalize/GetContents and constructors

The new API with v8::BackingStore should be used instead as explained in
https://docs.google.com/document/d/1sTc_jRL87Fu175Holm5SV0kajkseGl2r8ifGY76G35k

This also relaxes the pre-condition for [Shared]ArrayBuffer::Detach to
not require externalization first.

Bug: v8:9380, v8:9908
Change-Id: Idd119fcd28be84a2fae74ae86f7381fd997766f5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1859628
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64625}
This commit is contained in:
Andreas Haas 2019-10-29 20:00:28 +01:00 committed by Commit Bot
parent 30ccfb294f
commit bfe3d6bce7
16 changed files with 120 additions and 142 deletions

View File

@ -2185,8 +2185,6 @@ v8_source_set("v8_base_without_compiler") {
"src/extensions/cputracemark-extension.h",
"src/extensions/externalize-string-extension.cc",
"src/extensions/externalize-string-extension.h",
"src/extensions/free-buffer-extension.cc",
"src/extensions/free-buffer-extension.h",
"src/extensions/gc-extension.cc",
"src/extensions/gc-extension.h",
"src/extensions/ignition-statistics-extension.cc",

View File

@ -4846,6 +4846,7 @@ enum class ArrayBufferCreationMode { kInternalized, kExternalized };
/**
* A wrapper around the backing store (i.e. the raw memory) of an array buffer.
* See a document linked in http://crbug.com/v8/9908 for more information.
*
* The allocation and destruction of backing stores is generally managed by
* V8. Clients should always use standard C++ memory ownership types (i.e.
@ -4879,6 +4880,10 @@ class V8_EXPORT BackingStore : public v8::internal::BackingStoreBase {
bool IsShared() const;
private:
/**
* See [Shared]ArrayBuffer::GetBackingStore and
* [Shared]ArrayBuffer::NewBackingStore.
*/
BackingStore();
};
@ -5021,6 +5026,9 @@ class V8_EXPORT ArrayBuffer : public Object {
* |Allocator::Free| once all ArrayBuffers referencing it are collected by
* the garbage collector.
*/
V8_DEPRECATE_SOON(
"Use the version that takes a BackingStore. "
"See http://crbug.com/v8/9908.")
static Local<ArrayBuffer> New(
Isolate* isolate, void* data, size_t byte_length,
ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
@ -5067,6 +5075,9 @@ class V8_EXPORT ArrayBuffer : public Object {
* Returns true if ArrayBuffer is externalized, that is, does not
* own its memory block.
*/
V8_DEPRECATE_SOON(
"With v8::BackingStore externalized ArrayBuffers are "
"the same as ordinary ArrayBuffers. See http://crbug.com/v8/9908.")
bool IsExternal() const;
/**
@ -5092,6 +5103,8 @@ class V8_EXPORT ArrayBuffer : public Object {
* deleter, which will call ArrayBuffer::Allocator::Free if the buffer
* was allocated with ArrayBuffer::Allocator::Allocate.
*/
V8_DEPRECATE_SOON(
"Use GetBackingStore or Detach. See http://crbug.com/v8/9908.")
Contents Externalize();
/**
@ -5101,6 +5114,7 @@ class V8_EXPORT ArrayBuffer : public Object {
* With the new lifetime management of backing stores there is no need for
* externalizing, so this function exists only to make the transition easier.
*/
V8_DEPRECATE_SOON("This will be removed together with IsExternal.")
void Externalize(const std::shared_ptr<BackingStore>& backing_store);
/**
@ -5111,6 +5125,7 @@ class V8_EXPORT ArrayBuffer : public Object {
* The embedder should make sure to hold a strong reference to the
* ArrayBuffer while accessing this pointer.
*/
V8_DEPRECATE_SOON("Use GetBackingStore. See http://crbug.com/v8/9908.")
Contents GetContents();
/**
@ -5494,6 +5509,9 @@ class V8_EXPORT SharedArrayBuffer : public Object {
* specified. The memory block will not be reclaimed when a created
* SharedArrayBuffer is garbage-collected.
*/
V8_DEPRECATE_SOON(
"Use the version that takes a BackingStore. "
"See http://crbug.com/v8/9908.")
static Local<SharedArrayBuffer> New(
Isolate* isolate, void* data, size_t byte_length,
ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
@ -5540,7 +5558,9 @@ class V8_EXPORT SharedArrayBuffer : public Object {
* Create a new SharedArrayBuffer over an existing memory block. Propagate
* flags to indicate whether the underlying buffer can be grown.
*/
V8_DEPRECATED("Use New method with data, and byte_length instead.")
V8_DEPRECATED(
"Use the version that takes a BackingStore. "
"See http://crbug.com/v8/9908.")
static Local<SharedArrayBuffer> New(
Isolate* isolate, const SharedArrayBuffer::Contents&,
ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
@ -5549,6 +5569,9 @@ class V8_EXPORT SharedArrayBuffer : public Object {
* Returns true if SharedArrayBuffer is externalized, that is, does not
* own its memory block.
*/
V8_DEPRECATE_SOON(
"With v8::BackingStore externalized SharedArrayBuffers are the same "
"as ordinary SharedArrayBuffers. See http://crbug.com/v8/9908.")
bool IsExternal() const;
/**
@ -5563,6 +5586,8 @@ class V8_EXPORT SharedArrayBuffer : public Object {
* v8::Isolate::CreateParams::array_buffer_allocator.
*
*/
V8_DEPRECATE_SOON(
"Use GetBackingStore or Detach. See http://crbug.com/v8/9908.")
Contents Externalize();
/**
@ -5572,6 +5597,7 @@ class V8_EXPORT SharedArrayBuffer : public Object {
* With the new lifetime management of backing stores there is no need for
* externalizing, so this function exists only to make the transition easier.
*/
V8_DEPRECATE_SOON("This will be removed together with IsExternal.")
void Externalize(const std::shared_ptr<BackingStore>& backing_store);
/**
@ -5586,6 +5612,7 @@ class V8_EXPORT SharedArrayBuffer : public Object {
* by the allocator specified in
* v8::Isolate::CreateParams::array_buffer_allocator.
*/
V8_DEPRECATE_SOON("Use GetBackingStore. See http://crbug.com/v8/9908.")
Contents GetContents();
/**

View File

@ -7433,8 +7433,6 @@ v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents(bool externalize) {
void v8::ArrayBuffer::Detach() {
i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
Utils::ApiCheck(obj->is_external(), "v8::ArrayBuffer::Detach",
"Only externalized ArrayBuffers can be detached");
Utils::ApiCheck(obj->is_detachable(), "v8::ArrayBuffer::Detach",
"Only detachable ArrayBuffers can be detached");
LOG_API(isolate, ArrayBuffer, Detach);

View File

@ -2317,23 +2317,6 @@ static char* ReadChars(const char* name, int* size_out) {
return chars;
}
struct DataAndPersistent {
uint8_t* data;
int byte_length;
Global<ArrayBuffer> handle;
};
static void ReadBufferWeakCallback(
const v8::WeakCallbackInfo<DataAndPersistent>& data) {
int byte_length = data.GetParameter()->byte_length;
data.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(
-static_cast<intptr_t>(byte_length));
delete[] data.GetParameter()->data;
data.GetParameter()->handle.Reset();
delete data.GetParameter();
}
void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) {
static_assert(sizeof(char) == sizeof(uint8_t),
"char and uint8_t should both have 1 byte");
@ -2345,19 +2328,20 @@ void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
DataAndPersistent* data = new DataAndPersistent;
data->data = reinterpret_cast<uint8_t*>(ReadChars(*filename, &length));
if (data->data == nullptr) {
delete data;
uint8_t* data = reinterpret_cast<uint8_t*>(ReadChars(*filename, &length));
if (data == nullptr) {
Throw(isolate, "Error reading file");
return;
}
data->byte_length = length;
Local<v8::ArrayBuffer> buffer = ArrayBuffer::New(isolate, data->data, length);
data->handle.Reset(isolate, buffer);
data->handle.SetWeak(data, ReadBufferWeakCallback,
v8::WeakCallbackType::kParameter);
isolate->AdjustAmountOfExternalAllocatedMemory(length);
std::unique_ptr<v8::BackingStore> backing_store =
ArrayBuffer::NewBackingStore(
data, length,
[](void* data, size_t length, void*) {
delete[] reinterpret_cast<uint8_t*>(data);
},
nullptr);
Local<v8::ArrayBuffer> buffer =
ArrayBuffer::New(isolate, std::move(backing_store));
args.GetReturnValue().Set(buffer);
}
@ -3394,9 +3378,6 @@ class Serializer : public ValueSerializer::Delegate {
}
auto backing_store = array_buffer->GetBackingStore();
if (!array_buffer->IsExternal()) {
array_buffer->Externalize(backing_store);
}
data_->backing_stores_.push_back(std::move(backing_store));
array_buffer->Detach();
}

View File

@ -1,29 +0,0 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/extensions/free-buffer-extension.h"
#include "src/base/platform/platform.h"
#include "src/execution/isolate.h"
namespace v8 {
namespace internal {
v8::Local<v8::FunctionTemplate> FreeBufferExtension::GetNativeFunctionTemplate(
v8::Isolate* isolate, v8::Local<v8::String> str) {
return v8::FunctionTemplate::New(isolate, FreeBufferExtension::FreeBuffer);
}
void FreeBufferExtension::FreeBuffer(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Local<v8::ArrayBuffer> arrayBuffer = args[0].As<v8::ArrayBuffer>();
v8::ArrayBuffer::Contents contents = arrayBuffer->Externalize();
contents.Deleter()(contents.Data(), contents.ByteLength(),
contents.DeleterData());
}
} // namespace internal
} // namespace v8

View File

@ -1,25 +0,0 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_EXTENSIONS_FREE_BUFFER_EXTENSION_H_
#define V8_EXTENSIONS_FREE_BUFFER_EXTENSION_H_
#include "include/v8.h"
namespace v8 {
namespace internal {
class FreeBufferExtension : public v8::Extension {
public:
FreeBufferExtension()
: v8::Extension("v8/free-buffer", "native function freeBuffer();") {}
v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
v8::Isolate* isolate, v8::Local<v8::String> name) override;
static void FreeBuffer(const v8::FunctionCallbackInfo<v8::Value>& args);
};
} // namespace internal
} // namespace v8
#endif // V8_EXTENSIONS_FREE_BUFFER_EXTENSION_H_

View File

@ -1038,7 +1038,6 @@ DEFINE_BOOL(disable_old_api_accessors, false,
"prototype chain")
// bootstrapper.cc
DEFINE_BOOL(expose_free_buffer, false, "expose freeBuffer extension")
DEFINE_BOOL(expose_gc, false, "expose gc extension")
DEFINE_STRING(expose_gc_as, nullptr,
"expose gc extension under the specified name")

View File

@ -15,7 +15,6 @@
#include "src/execution/protectors.h"
#include "src/extensions/cputracemark-extension.h"
#include "src/extensions/externalize-string-extension.h"
#include "src/extensions/free-buffer-extension.h"
#include "src/extensions/gc-extension.h"
#include "src/extensions/ignition-statistics-extension.h"
#include "src/extensions/statistics-extension.h"
@ -121,7 +120,6 @@ static bool isValidCpuTraceMarkFunctionName() {
}
void Bootstrapper::InitializeOncePerProcess() {
v8::RegisterExtension(std::make_unique<FreeBufferExtension>());
v8::RegisterExtension(std::make_unique<GCExtension>(GCFunctionName()));
v8::RegisterExtension(std::make_unique<ExternalizeStringExtension>());
v8::RegisterExtension(std::make_unique<StatisticsExtension>());
@ -4958,8 +4956,6 @@ bool Genesis::InstallExtensions(Isolate* isolate,
v8::ExtensionConfiguration* extensions) {
ExtensionStates extension_states; // All extensions have state UNVISITED.
return InstallAutoExtensions(isolate, &extension_states) &&
(!FLAG_expose_free_buffer ||
InstallExtension(isolate, "v8/free-buffer", &extension_states)) &&
(!FLAG_expose_gc ||
InstallExtension(isolate, "v8/gc", &extension_states)) &&
(!FLAG_expose_externalize_string ||

View File

@ -151,7 +151,7 @@ TEST(ArrayBuffer_Compaction) {
TEST(ArrayBuffer_UnregisterDuringSweep) {
// Regular pages in old space (without compaction) are processed concurrently
// in the sweeper. If we happen to unregister a buffer (either explicitly, or
// implicitly through e.g. |Externalize|) we need to sync with the sweeper
// implicitly through e.g. |Detach|) we need to sync with the sweeper
// task.
//
// Note: This test will will only fail on TSAN configurations.
@ -189,12 +189,10 @@ TEST(ArrayBuffer_UnregisterDuringSweep) {
}
CcTest::CollectGarbage(OLD_SPACE);
// |Externalize| will cause the buffer to be |Unregister|ed. Without
// |Detach| will cause the buffer to be |Unregister|ed. Without
// barriers and proper synchronization this will trigger a data race on
// TSAN.
v8::ArrayBuffer::Contents contents = ab->Externalize();
contents.Deleter()(contents.Data(), contents.ByteLength(),
contents.DeleterData());
ab->Detach();
}
}

View File

@ -15,16 +15,16 @@ namespace testing {
// externalized in a test.
struct ManuallyExternalizedBuffer {
Handle<JSArrayBuffer> buffer_;
v8::ArrayBuffer::Contents contents_;
std::shared_ptr<v8::BackingStore> backing_store_;
explicit ManuallyExternalizedBuffer(Handle<JSArrayBuffer> buffer)
: buffer_(buffer),
contents_(v8::Utils::ToLocal(buffer_)->Externalize()) {}
backing_store_(v8::Utils::ToLocal(buffer_)->GetBackingStore()) {}
~ManuallyExternalizedBuffer() {
contents_.Deleter()(contents_.Data(), contents_.ByteLength(),
contents_.DeleterData());
// Nothing to be done. The reference to the backing store will be
// dropped automatically.
}
void* backing_store() { return contents_.Data(); }
void* backing_store() { return backing_store_->Data(); }
};
} // namespace testing

View File

@ -48,15 +48,31 @@ Local<TypedArray> CreateAndCheck(Local<v8::ArrayBuffer> ab, int byteOffset,
std::shared_ptr<v8::BackingStore> Externalize(Local<v8::ArrayBuffer> ab) {
std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore();
// Keep the tests until the deprecated functions are removed.
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
ab->Externalize(backing_store);
CHECK(ab->IsExternal());
#if __clang__
#pragma clang diagnostic pop
#endif
return backing_store;
}
std::shared_ptr<v8::BackingStore> Externalize(Local<v8::SharedArrayBuffer> ab) {
std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore();
// Keep the tests until the deprecated functions are removed.
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
ab->Externalize(backing_store);
CHECK(ab->IsExternal());
#if __clang__
#pragma clang diagnostic pop
#endif
return backing_store;
}
@ -70,7 +86,6 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) {
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024);
CheckInternalFieldsAreZero(ab);
CHECK_EQ(1024, ab->ByteLength());
CHECK(!ab->IsExternal());
CcTest::CollectAllGarbage();
std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab);
@ -110,7 +125,6 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) {
Local<v8::ArrayBuffer> ab1 = Local<v8::ArrayBuffer>::Cast(result);
CheckInternalFieldsAreZero(ab1);
CHECK_EQ(2, ab1->ByteLength());
CHECK(!ab1->IsExternal());
std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab1);
result = CompileRun("ab1.byteLength");
@ -144,11 +158,19 @@ THREADED_TEST(ArrayBuffer_External) {
i::ScopedVector<uint8_t> my_data(100);
memset(my_data.begin(), 0, 100);
// Keep the tests until the deprecated functions are removed.
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
Local<v8::ArrayBuffer> ab3 =
v8::ArrayBuffer::New(isolate, my_data.begin(), 100);
CheckInternalFieldsAreZero(ab3);
CHECK_EQ(100, ab3->ByteLength());
CHECK(ab3->IsExternal());
#if __clang__
#pragma clang diagnostic pop
#endif
CHECK(env->Global()->Set(env.local(), v8_str("ab3"), ab3).FromJust());
@ -174,10 +196,7 @@ THREADED_TEST(ArrayBuffer_DisableDetach) {
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
i::ScopedVector<uint8_t> my_data(100);
memset(my_data.begin(), 0, 100);
Local<v8::ArrayBuffer> ab =
v8::ArrayBuffer::New(isolate, my_data.begin(), 100);
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 100);
CHECK(ab->IsDetachable());
i::Handle<i::JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab);
@ -285,7 +304,15 @@ THREADED_TEST(ArrayBuffer_AllocationInformation) {
const size_t ab_size = 1024;
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, ab_size);
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
v8::ArrayBuffer::Contents contents(ab->GetContents());
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
// Array buffers should have normal allocation mode.
CHECK_EQ(contents.AllocationMode(),
@ -308,7 +335,6 @@ THREADED_TEST(ArrayBuffer_ExternalizeEmpty) {
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 2);
CheckInternalFieldsAreZero(ab);
CHECK_EQ(2, ab->ByteLength());
CHECK(!ab->IsExternal());
// Externalize the buffer (taking ownership of the backing store memory).
std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab);
@ -332,7 +358,6 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) {
Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, 1024);
CheckInternalFieldsAreZero(ab);
CHECK_EQ(1024, ab->ByteLength());
CHECK(!ab->IsExternal());
CcTest::CollectAllGarbage();
std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab);
@ -550,6 +575,7 @@ THREADED_TEST(ArrayBuffer_NewBackingStore) {
v8::HandleScope handle_scope(isolate);
std::shared_ptr<v8::BackingStore> backing_store =
v8::ArrayBuffer::NewBackingStore(isolate, 100);
CHECK(!backing_store->IsShared());
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, backing_store);
CHECK_EQ(backing_store.get(), ab->GetBackingStore().get());
}
@ -560,6 +586,7 @@ THREADED_TEST(SharedArrayBuffer_NewBackingStore) {
v8::HandleScope handle_scope(isolate);
std::shared_ptr<v8::BackingStore> backing_store =
v8::SharedArrayBuffer::NewBackingStore(isolate, 100);
CHECK(backing_store->IsShared());
Local<v8::SharedArrayBuffer> ab =
v8::SharedArrayBuffer::New(isolate, backing_store);
CHECK_EQ(backing_store.get(), ab->GetBackingStore().get());

View File

@ -359,15 +359,12 @@ void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low,
int64_t high) {
const int kElementCount = 50;
i::ScopedVector<ElementType> backing_store(kElementCount + 2);
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
Local<ArrayBufferType> ab =
ArrayBufferType::New(isolate, backing_store.begin(),
(kElementCount + 2) * sizeof(ElementType));
ArrayBufferType::New(isolate, (kElementCount + 2) * sizeof(ElementType));
Local<TypedArray> ta =
TypedArray::New(ab, 2 * sizeof(ElementType), kElementCount);
CheckInternalFieldsAreZero<v8::ArrayBufferView>(ta);
@ -376,7 +373,8 @@ void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low,
CHECK_EQ(kElementCount * sizeof(ElementType), ta->ByteLength());
CHECK(ab->Equals(env.local(), ta->Buffer()).FromJust());
ElementType* data = backing_store.begin() + 2;
ElementType* data =
reinterpret_cast<ElementType*>(ab->GetBackingStore()->Data()) + 2;
for (int i = 0; i < kElementCount; i++) {
data[i] = static_cast<ElementType>(i);
}
@ -435,14 +433,11 @@ THREADED_TEST(Uint8ClampedArray) {
THREADED_TEST(DataView) {
const int kSize = 50;
i::ScopedVector<uint8_t> backing_store(kSize + 2);
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
Local<v8::ArrayBuffer> ab =
v8::ArrayBuffer::New(isolate, backing_store.begin(), 2 + kSize);
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 2 + kSize);
Local<v8::DataView> dv = v8::DataView::New(ab, 2, kSize);
CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv);
CHECK_EQ(2u, dv->ByteOffset());
@ -508,14 +503,12 @@ THREADED_TEST(SharedDataView) {
i::FLAG_harmony_sharedarraybuffer = true;
const int kSize = 50;
i::ScopedVector<uint8_t> backing_store(kSize + 2);
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
Local<v8::SharedArrayBuffer> ab =
v8::SharedArrayBuffer::New(isolate, backing_store.begin(), 2 + kSize);
v8::SharedArrayBuffer::New(isolate, 2 + kSize);
Local<v8::DataView> dv = v8::DataView::New(ab, 2, kSize);
CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv);
CHECK_EQ(2u, dv->ByteOffset());

View File

@ -1757,11 +1757,11 @@ TEST(TryLookupElement) {
CHECK_ABSENT(object, 13);
CHECK_ABSENT(object, 42);
v8::ArrayBuffer::Contents contents = buffer->Externalize();
buffer->Detach();
contents.Deleter()(contents.Data(), contents.ByteLength(),
contents.DeleterData());
{
std::shared_ptr<v8::BackingStore> backing_store =
buffer->GetBackingStore();
buffer->Detach();
}
CHECK_ABSENT(object, 0);
CHECK_ABSENT(object, 1);
CHECK_ABSENT(object, -10);

View File

@ -3027,16 +3027,12 @@ TEST(ArrayBufferSharedBackingStore) {
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024);
CHECK_EQ(1024, static_cast<int>(ab->ByteLength()));
CHECK(!ab->IsExternal());
v8::ArrayBuffer::Contents ab_contents = ab->Externalize();
CHECK(ab->IsExternal());
std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore();
CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength()));
void* data = ab_contents.Data();
CHECK_EQ(1024, static_cast<int>(backing_store->ByteLength()));
void* data = backing_store->Data();
CHECK_NOT_NULL(data);
v8::Local<v8::ArrayBuffer> ab2 =
v8::ArrayBuffer::New(isolate, data, ab_contents.ByteLength());
CHECK(ab2->IsExternal());
v8::Local<v8::ArrayBuffer> ab2 = v8::ArrayBuffer::New(isolate, backing_store);
env->Global()->Set(env.local(), v8_str("ab1"), ab).FromJust();
env->Global()->Set(env.local(), v8_str("ab2"), ab2).FromJust();
@ -3062,8 +3058,6 @@ TEST(ArrayBufferSharedBackingStore) {
CHECK(ab2_data);
CHECK_EQ(ab1_data, ab2_data);
CHECK_EQ(2, GetRetainersCount(snapshot, ab1_data));
ab_contents.Deleter()(ab_contents.Data(), ab_contents.ByteLength(),
ab_contents.DeleterData());
}

View File

@ -78,10 +78,20 @@ TEST(AllocateNotExternal) {
void* memory = reinterpret_cast<Isolate*>(env->GetIsolate())
->array_buffer_allocator()
->Allocate(1024);
// Keep the test until the functions are removed.
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
v8::Local<v8::ArrayBuffer> buffer =
v8::ArrayBuffer::New(env->GetIsolate(), memory, 1024,
v8::ArrayBufferCreationMode::kInternalized);
CHECK(!buffer->IsExternal());
#if __clang__
#pragma clang diagnostic pop
#endif
CHECK_EQ(memory, buffer->GetBackingStore()->Data());
}

View File

@ -259,8 +259,11 @@ class ValueSerializerTest : public TestWithIsolate {
Local<Object> NewDummyUint8Array() {
static uint8_t data[] = {4, 5, 6};
std::unique_ptr<v8::BackingStore> backing_store =
ArrayBuffer::NewBackingStore(
data, sizeof(data), [](void*, size_t, void*) {}, nullptr);
Local<ArrayBuffer> ab =
ArrayBuffer::New(isolate(), static_cast<void*>(data), sizeof(data));
ArrayBuffer::New(isolate(), std::move(backing_store));
return Uint8Array::New(ab, 0, sizeof(data));
}
@ -1724,7 +1727,7 @@ class ValueSerializerTestWithArrayBufferTransfer : public ValueSerializerTest {
ValueSerializerTestWithArrayBufferTransfer() {
{
Context::Scope scope(serialization_context());
input_buffer_ = ArrayBuffer::New(isolate(), nullptr, 0);
input_buffer_ = ArrayBuffer::New(isolate(), 0);
}
{
Context::Scope scope(deserialization_context());
@ -2022,7 +2025,15 @@ class ValueSerializerTestWithSharedArrayBufferClone
std::move(backing_store));
return Utils::ToLocalShared(buffer);
} else {
return SharedArrayBuffer::New(isolate(), data, byte_length);
std::unique_ptr<v8::BackingStore> backing_store =
SharedArrayBuffer::NewBackingStore(
data, byte_length,
[](void*, size_t, void*) {
// Leak the buffer as it has the
// lifetime of the test.
},
nullptr);
return SharedArrayBuffer::New(isolate(), std::move(backing_store));
}
}