diff options
Diffstat (limited to 'deps/v8/test/cctest/test-api-array-buffer.cc')
-rw-r--r-- | deps/v8/test/cctest/test-api-array-buffer.cc | 158 |
1 files changed, 87 insertions, 71 deletions
diff --git a/deps/v8/test/cctest/test-api-array-buffer.cc b/deps/v8/test/cctest/test-api-array-buffer.cc index 5b8433a6a2..508604aa41 100644 --- a/deps/v8/test/cctest/test-api-array-buffer.cc +++ b/deps/v8/test/cctest/test-api-array-buffer.cc @@ -13,43 +13,6 @@ using ::v8::Value; namespace { -class ScopedArrayBufferContents { - public: - explicit ScopedArrayBufferContents(const v8::ArrayBuffer::Contents& contents) - : contents_(contents) {} - ~ScopedArrayBufferContents() { free(contents_.AllocationBase()); } - void* Data() const { return contents_.Data(); } - size_t ByteLength() const { return contents_.ByteLength(); } - - void* AllocationBase() const { return contents_.AllocationBase(); } - size_t AllocationLength() const { return contents_.AllocationLength(); } - v8::ArrayBuffer::Allocator::AllocationMode AllocationMode() const { - return contents_.AllocationMode(); - } - - private: - const v8::ArrayBuffer::Contents contents_; -}; - -class ScopedSharedArrayBufferContents { - public: - explicit ScopedSharedArrayBufferContents( - const v8::SharedArrayBuffer::Contents& contents) - : contents_(contents) {} - ~ScopedSharedArrayBufferContents() { free(contents_.AllocationBase()); } - void* Data() const { return contents_.Data(); } - size_t ByteLength() const { return contents_.ByteLength(); } - - void* AllocationBase() const { return contents_.AllocationBase(); } - size_t AllocationLength() const { return contents_.AllocationLength(); } - v8::ArrayBuffer::Allocator::AllocationMode AllocationMode() const { - return contents_.AllocationMode(); - } - - private: - const v8::SharedArrayBuffer::Contents contents_; -}; - void CheckDataViewIsDetached(v8::Local<v8::DataView> dv) { CHECK_EQ(0, static_cast<int>(dv->ByteLength())); CHECK_EQ(0, static_cast<int>(dv->ByteOffset())); @@ -83,6 +46,20 @@ Local<TypedArray> CreateAndCheck(Local<v8::ArrayBuffer> ab, int byteOffset, return ta; } +std::shared_ptr<v8::BackingStore> Externalize(Local<v8::ArrayBuffer> ab) { + std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore(); + ab->Externalize(backing_store); + CHECK(ab->IsExternal()); + return backing_store; +} + +std::shared_ptr<v8::BackingStore> Externalize(Local<v8::SharedArrayBuffer> ab) { + std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore(); + ab->Externalize(backing_store); + CHECK(ab->IsExternal()); + return backing_store; +} + } // namespace THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { @@ -92,15 +69,14 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024); CheckInternalFieldsAreZero(ab); - CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); + CHECK_EQ(1024, ab->ByteLength()); CHECK(!ab->IsExternal()); CcTest::CollectAllGarbage(); - ScopedArrayBufferContents ab_contents(ab->Externalize()); - CHECK(ab->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab); + CHECK_EQ(1024, backing_store->ByteLength()); - CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); - uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); + uint8_t* data = static_cast<uint8_t*>(backing_store->Data()); CHECK_NOT_NULL(data); CHECK(env->Global()->Set(env.local(), v8_str("ab"), ab).FromJust()); @@ -133,10 +109,9 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { "u8_a[1] = 0xFF; u8_a.buffer"); Local<v8::ArrayBuffer> ab1 = Local<v8::ArrayBuffer>::Cast(result); CheckInternalFieldsAreZero(ab1); - CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); + CHECK_EQ(2, ab1->ByteLength()); CHECK(!ab1->IsExternal()); - ScopedArrayBufferContents ab1_contents(ab1->Externalize()); - CHECK(ab1->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab1); result = CompileRun("ab1.byteLength"); CHECK_EQ(2, result->Int32Value(env.local()).FromJust()); @@ -152,8 +127,8 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { result = CompileRun("u8_b[1]"); CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); - CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); - uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); + CHECK_EQ(2, backing_store->ByteLength()); + uint8_t* ab1_data = static_cast<uint8_t*>(backing_store->Data()); CHECK_EQ(0xBB, ab1_data[0]); CHECK_EQ(0xFF, ab1_data[1]); ab1_data[0] = 0xCC; @@ -172,7 +147,7 @@ THREADED_TEST(ArrayBuffer_External) { Local<v8::ArrayBuffer> ab3 = v8::ArrayBuffer::New(isolate, my_data.begin(), 100); CheckInternalFieldsAreZero(ab3); - CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); + CHECK_EQ(100, ab3->ByteLength()); CHECK(ab3->IsExternal()); CHECK(env->Global()->Set(env.local(), v8_str("ab3"), ab3).FromJust()); @@ -242,12 +217,12 @@ THREADED_TEST(ArrayBuffer_DetachingApi) { v8::Local<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); - CHECK_EQ(1, static_cast<int>(dv->ByteOffset())); - CHECK_EQ(1023, static_cast<int>(dv->ByteLength())); + CHECK_EQ(1, dv->ByteOffset()); + CHECK_EQ(1023, dv->ByteLength()); - ScopedArrayBufferContents contents(buffer->Externalize()); + Externalize(buffer); buffer->Detach(); - CHECK_EQ(0, static_cast<int>(buffer->ByteLength())); + CHECK_EQ(0, buffer->ByteLength()); CheckIsDetached(u8a); CheckIsDetached(u8c); CheckIsDetached(i8a); @@ -283,9 +258,9 @@ THREADED_TEST(ArrayBuffer_DetachingScript) { v8::Local<v8::DataView> dv = v8::Local<v8::DataView>::Cast(CompileRun("dv")); - ScopedArrayBufferContents contents(ab->Externalize()); + Externalize(ab); ab->Detach(); - CHECK_EQ(0, static_cast<int>(ab->ByteLength())); + CHECK_EQ(0, ab->ByteLength()); CHECK_EQ(0, v8_run_int32value(v8_compile("ab.byteLength"))); CheckIsTypedArrayVarDetached("u8a"); @@ -302,6 +277,7 @@ THREADED_TEST(ArrayBuffer_DetachingScript) { CheckDataViewIsDetached(dv); } +// TODO(v8:9380) the Contents data structure should be deprecated. THREADED_TEST(ArrayBuffer_AllocationInformation) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); @@ -309,7 +285,7 @@ THREADED_TEST(ArrayBuffer_AllocationInformation) { const size_t ab_size = 1024; Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, ab_size); - ScopedArrayBufferContents contents(ab->Externalize()); + v8::ArrayBuffer::Contents contents(ab->GetContents()); // Array buffers should have normal allocation mode. CHECK_EQ(contents.AllocationMode(), @@ -329,13 +305,13 @@ THREADED_TEST(ArrayBuffer_ExternalizeEmpty) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope handle_scope(isolate); - Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 0); + Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 2); CheckInternalFieldsAreZero(ab); - CHECK_EQ(0, static_cast<int>(ab->ByteLength())); + CHECK_EQ(2, ab->ByteLength()); CHECK(!ab->IsExternal()); // Externalize the buffer (taking ownership of the backing store memory). - ScopedArrayBufferContents ab_contents(ab->Externalize()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab); Local<v8::Uint8Array> u8a = v8::Uint8Array::New(ab, 0, 0); // Calling Buffer() will materialize the ArrayBuffer (transitioning it from @@ -344,6 +320,7 @@ THREADED_TEST(ArrayBuffer_ExternalizeEmpty) { USE(u8a->Buffer()); CHECK(ab->IsExternal()); + CHECK_EQ(2, backing_store->ByteLength()); } THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { @@ -354,15 +331,14 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, 1024); CheckInternalFieldsAreZero(ab); - CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); + CHECK_EQ(1024, ab->ByteLength()); CHECK(!ab->IsExternal()); CcTest::CollectAllGarbage(); - ScopedSharedArrayBufferContents ab_contents(ab->Externalize()); - CHECK(ab->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab); - CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); - uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); + CHECK_EQ(1024, backing_store->ByteLength()); + uint8_t* data = static_cast<uint8_t*>(backing_store->Data()); CHECK_NOT_NULL(data); CHECK(env->Global()->Set(env.local(), v8_str("ab"), ab).FromJust()); @@ -383,6 +359,35 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } +THREADED_TEST(ArrayBuffer_ExternalReused) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + i::ScopedVector<uint8_t> data(100); + Local<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs1 = ab1->GetBackingStore(); + ab1->Detach(); + Local<v8::ArrayBuffer> ab2 = v8::ArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs2 = ab2->GetBackingStore(); + CHECK_EQ(bs1->Data(), bs2->Data()); +} + +THREADED_TEST(SharedArrayBuffer_ExternalReused) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + i::ScopedVector<uint8_t> data(100); + Local<v8::SharedArrayBuffer> ab1 = + v8::SharedArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs1 = ab1->GetBackingStore(); + Local<v8::SharedArrayBuffer> ab2 = + v8::SharedArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs2 = ab2->GetBackingStore(); + CHECK_EQ(bs1->Data(), bs2->Data()); +} + THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { i::FLAG_harmony_sharedarraybuffer = true; LocalContext env; @@ -396,10 +401,9 @@ THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { "u8_a[1] = 0xFF; u8_a.buffer"); Local<v8::SharedArrayBuffer> ab1 = Local<v8::SharedArrayBuffer>::Cast(result); CheckInternalFieldsAreZero(ab1); - CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); + CHECK_EQ(2, ab1->ByteLength()); CHECK(!ab1->IsExternal()); - ScopedSharedArrayBufferContents ab1_contents(ab1->Externalize()); - CHECK(ab1->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab1); result = CompileRun("ab1.byteLength"); CHECK_EQ(2, result->Int32Value(env.local()).FromJust()); @@ -415,8 +419,8 @@ THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { result = CompileRun("u8_b[1]"); CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); - CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); - uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); + CHECK_EQ(2, backing_store->ByteLength()); + uint8_t* ab1_data = static_cast<uint8_t*>(backing_store->Data()); CHECK_EQ(0xBB, ab1_data[0]); CHECK_EQ(0xFF, ab1_data[1]); ab1_data[0] = 0xCC; @@ -458,6 +462,7 @@ THREADED_TEST(SharedArrayBuffer_External) { CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } +// TODO(v8:9380) the Contents data structure should be deprecated. THREADED_TEST(SharedArrayBuffer_AllocationInformation) { i::FLAG_harmony_sharedarraybuffer = true; LocalContext env; @@ -467,7 +472,7 @@ THREADED_TEST(SharedArrayBuffer_AllocationInformation) { const size_t ab_size = 1024; Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, ab_size); - ScopedSharedArrayBufferContents contents(ab->Externalize()); + v8::SharedArrayBuffer::Contents contents(ab->GetContents()); // Array buffers should have normal allocation mode. CHECK_EQ(contents.AllocationMode(), @@ -500,7 +505,7 @@ THREADED_TEST(SkipArrayBufferBackingStoreDuringGC) { CcTest::CollectAllGarbage(); // Should not move the pointer - CHECK_EQ(ab->GetContents().Data(), store_ptr); + CHECK_EQ(ab->GetBackingStore()->Data(), store_ptr); } THREADED_TEST(SkipArrayBufferDuringScavenge) { @@ -525,5 +530,16 @@ THREADED_TEST(SkipArrayBufferDuringScavenge) { CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now // Use `ab` to silence compiler warning - CHECK_EQ(ab->GetContents().Data(), store_ptr); + CHECK_EQ(ab->GetBackingStore()->Data(), store_ptr); +} + +THREADED_TEST(Regress1006600) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + Local<v8::Value> ab = CompileRunChecked(isolate, "new ArrayBuffer()"); + for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) { + CHECK_NULL(ab.As<v8::Object>()->GetAlignedPointerFromInternalField(i)); + } } |