[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:
parent
30ccfb294f
commit
bfe3d6bce7
2
BUILD.gn
2
BUILD.gn
@ -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",
|
||||
|
29
include/v8.h
29
include/v8.h
@ -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();
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
41
src/d8/d8.cc
41
src/d8/d8.cc
@ -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();
|
||||
}
|
||||
|
@ -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
|
@ -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_
|
@ -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")
|
||||
|
@ -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 ||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user