Commit 7fc06d62 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[arraybuffer] Merge ArrayBuffer into DOMArrayBufferBase

With this CL the ArrayBuffer class gets finally removed and completely
merged into DOMArrayBufferBase. This required the following changes:

* Move the internal fields of ArrayBuffer to DOMArrayBufferBase:
  array_buffer_contents_ and is_detached_.
* Change DOMArrayBufferBase to be based on ArrayBufferContents instead of
  ArrayBuffer now.
* Change the constructors of DOMArrayBuffer and SharedDOMArrayBuffer.
* Move the implementation of ArrayBuffer::Transfer to DOMArrayBuffer.
* Make ArrayBufferContents copyable. As ArrayBufferContents is just a
  wrapper around an std::shared_ptr, this is fine.
* Add a Detach function to DOMArrayBufferBase which allows to set the
  is_detached_ flag.

R=haraken@chromium.org, ulan@chromium.org

Bug: chromium:1008840
Change-Id: I2355ce0a38cf0453af2960b03e7a984dc002d1c8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2106058Reviewed-by: default avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#750945}
parent 7ea3734d
include_rules = [
"+base/allocator/partition_allocator/partition_alloc.h",
"+base/allocator/partition_allocator/oom.h",
"+base/auto_reset.h",
"+base/bind.h",
"+base/bind_helpers.h",
......
......@@ -147,7 +147,7 @@ DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() {
SafeCast<size_t>(bytes_loaded_));
}
array_buffer_result_ = DOMArrayBuffer::Create(raw_data_);
array_buffer_result_ = DOMArrayBuffer::Create(std::move(raw_data_));
DCHECK_EQ(raw_data_.DataLength(), 0u);
raw_data_.Reset();
return array_buffer_result_;
......
......@@ -38,7 +38,6 @@
#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
......
......@@ -6,8 +6,6 @@ import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("typed_arrays") {
sources = [
"array_buffer/array_buffer.cc",
"array_buffer/array_buffer.h",
"array_buffer/array_buffer_contents.cc",
"array_buffer/array_buffer_contents.h",
"array_buffer_view_helpers.h",
......
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
#include "base/memory/scoped_refptr.h"
namespace blink {
bool ArrayBuffer::Transfer(ArrayBufferContents& result) {
DCHECK(!IsShared());
scoped_refptr<ArrayBuffer> keep_alive(this);
if (is_detached_) {
result.Detach();
return false;
}
if (!contents_.Data()) {
// We transfer an empty ArrayBuffer, we can just allocate an empty content.
result = ArrayBufferContents(contents_.BackingStore());
return true;
}
contents_.Transfer(result);
is_detached_ = true;
return true;
}
bool ArrayBuffer::ShareContentsWith(ArrayBufferContents& result) {
DCHECK(IsShared());
scoped_refptr<ArrayBuffer> keep_alive(this);
if (!contents_.BackingStore()) {
result.Detach();
return false;
}
contents_.ShareWith(result);
return true;
}
bool ArrayBuffer::ShareNonSharedForInternalUse(ArrayBufferContents& result) {
DCHECK(!IsShared());
scoped_refptr<ArrayBuffer> keep_alive(this);
if (!contents_.BackingStore()) {
result.Detach();
return false;
}
contents_.ShareNonSharedForInternalUse(result);
return true;
}
} // namespace blink
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_H_
#include "base/allocator/partition_allocator/oom.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
namespace blink {
class ArrayBuffer;
class ArrayBufferView;
class CORE_EXPORT ArrayBuffer : public RefCounted<ArrayBuffer> {
USING_FAST_MALLOC(ArrayBuffer);
public:
static inline scoped_refptr<ArrayBuffer> Create(size_t num_elements,
size_t element_byte_size);
static inline scoped_refptr<ArrayBuffer> Create(ArrayBuffer*);
static inline scoped_refptr<ArrayBuffer> Create(const void* source,
size_t byte_length);
static inline scoped_refptr<ArrayBuffer> Create(ArrayBufferContents&);
static inline scoped_refptr<ArrayBuffer> CreateOrNull(
size_t num_elements,
size_t element_byte_size);
// Only for use by DOMArrayBuffer::CreateUninitializedOrNull().
static inline scoped_refptr<ArrayBuffer> CreateUninitializedOrNull(
size_t num_elements,
size_t element_byte_size);
static inline scoped_refptr<ArrayBuffer> CreateShared(
size_t num_elements,
size_t element_byte_size);
static inline scoped_refptr<ArrayBuffer> CreateShared(const void* source,
size_t byte_length);
inline void* Data();
inline const void* Data() const;
inline void* DataShared();
inline const void* DataShared() const;
inline void* DataMaybeShared();
inline const void* DataMaybeShared() const;
inline size_t ByteLengthAsSizeT() const;
void AddView(ArrayBufferView*);
void RemoveView(ArrayBufferView*);
bool Transfer(ArrayBufferContents&);
bool ShareContentsWith(ArrayBufferContents&);
// Documentation see DOMArrayBuffer.
bool ShareNonSharedForInternalUse(ArrayBufferContents&);
bool IsDetached() const { return is_detached_; }
bool IsShared() const { return contents_.IsShared(); }
ArrayBufferContents* Content() { return &contents_; }
~ArrayBuffer() = default;
protected:
inline explicit ArrayBuffer(ArrayBufferContents&);
private:
static inline scoped_refptr<ArrayBuffer> Create(
size_t num_elements,
size_t element_byte_size,
ArrayBufferContents::InitializationPolicy);
static inline scoped_refptr<ArrayBuffer> CreateOrNull(
size_t num_elements,
size_t element_byte_size,
ArrayBufferContents::InitializationPolicy);
static inline scoped_refptr<ArrayBuffer> CreateShared(
size_t num_elements,
size_t element_byte_size,
ArrayBufferContents::InitializationPolicy);
ArrayBufferContents contents_;
bool is_detached_;
};
scoped_refptr<ArrayBuffer> ArrayBuffer::Create(size_t num_elements,
size_t element_byte_size) {
return Create(num_elements, element_byte_size,
ArrayBufferContents::kZeroInitialize);
}
scoped_refptr<ArrayBuffer> ArrayBuffer::Create(ArrayBuffer* other) {
// TODO(binji): support creating a SharedArrayBuffer by copying another
// ArrayBuffer?
DCHECK(!other->IsShared());
return ArrayBuffer::Create(other->Data(), other->ByteLengthAsSizeT());
}
scoped_refptr<ArrayBuffer> ArrayBuffer::Create(const void* source,
size_t byte_length) {
ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kNotShared,
ArrayBufferContents::kDontInitialize);
if (UNLIKELY(!contents.Data()))
OOM_CRASH(byte_length);
scoped_refptr<ArrayBuffer> buffer = base::AdoptRef(new ArrayBuffer(contents));
memcpy(buffer->Data(), source, byte_length);
return buffer;
}
scoped_refptr<ArrayBuffer> ArrayBuffer::Create(ArrayBufferContents& contents) {
CHECK(contents.DataLength() == 0 || contents.DataMaybeShared());
return base::AdoptRef(new ArrayBuffer(contents));
}
scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull(size_t num_elements,
size_t element_byte_size) {
return CreateOrNull(num_elements, element_byte_size,
ArrayBufferContents::kZeroInitialize);
}
scoped_refptr<ArrayBuffer> ArrayBuffer::CreateUninitializedOrNull(
size_t num_elements,
size_t element_byte_size) {
return CreateOrNull(num_elements, element_byte_size,
ArrayBufferContents::kDontInitialize);
}
scoped_refptr<ArrayBuffer> ArrayBuffer::Create(
size_t num_elements,
size_t element_byte_size,
ArrayBufferContents::InitializationPolicy policy) {
ArrayBufferContents contents(num_elements, element_byte_size,
ArrayBufferContents::kNotShared, policy);
if (UNLIKELY(!contents.Data()))
OOM_CRASH(num_elements * element_byte_size);
return base::AdoptRef(new ArrayBuffer(contents));
}
scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull(
size_t num_elements,
size_t element_byte_size,
ArrayBufferContents::InitializationPolicy policy) {
ArrayBufferContents contents(num_elements, element_byte_size,
ArrayBufferContents::kNotShared, policy);
if (!contents.Data())
return nullptr;
return base::AdoptRef(new ArrayBuffer(contents));
}
scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(size_t num_elements,
size_t element_byte_size) {
return CreateShared(num_elements, element_byte_size,
ArrayBufferContents::kZeroInitialize);
}
scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(const void* source,
size_t byte_length) {
ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kShared,
ArrayBufferContents::kDontInitialize);
CHECK(contents.DataShared());
scoped_refptr<ArrayBuffer> buffer = base::AdoptRef(new ArrayBuffer(contents));
memcpy(buffer->DataShared(), source, byte_length);
return buffer;
}
scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(
size_t num_elements,
size_t element_byte_size,
ArrayBufferContents::InitializationPolicy policy) {
ArrayBufferContents contents(num_elements, element_byte_size,
ArrayBufferContents::kShared, policy);
CHECK(contents.DataShared());
return base::AdoptRef(new ArrayBuffer(contents));
}
ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents) : is_detached_(false) {
if (contents.IsShared())
contents.ShareWith(contents_);
else
contents.Transfer(contents_);
}
void* ArrayBuffer::Data() {
return contents_.Data();
}
const void* ArrayBuffer::Data() const {
return contents_.Data();
}
void* ArrayBuffer::DataShared() {
return contents_.DataShared();
}
const void* ArrayBuffer::DataShared() const {
return contents_.DataShared();
}
void* ArrayBuffer::DataMaybeShared() {
return contents_.DataMaybeShared();
}
const void* ArrayBuffer::DataMaybeShared() const {
return contents_.DataMaybeShared();
}
size_t ArrayBuffer::ByteLengthAsSizeT() const {
return contents_.DataLength();
}
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_H_
......@@ -65,11 +65,13 @@ class CORE_EXPORT ArrayBufferContents {
InitializationPolicy);
ArrayBufferContents(void* data, size_t length, DataDeleter deleter);
ArrayBufferContents(ArrayBufferContents&&) = default;
ArrayBufferContents(const ArrayBufferContents&) = default;
explicit ArrayBufferContents(std::shared_ptr<v8::BackingStore> backing_store)
: backing_store_(std::move(backing_store)) {}
~ArrayBufferContents();
ArrayBufferContents& operator=(const ArrayBufferContents&) = default;
ArrayBufferContents& operator=(ArrayBufferContents&&) = default;
void Detach();
......@@ -112,8 +114,6 @@ class CORE_EXPORT ArrayBufferContents {
static void* AllocateMemoryWithFlags(size_t, InitializationPolicy, int);
std::shared_ptr<v8::BackingStore> backing_store_;
DISALLOW_COPY_AND_ASSIGN(ArrayBufferContents);
};
} // namespace blink
......
......@@ -44,11 +44,21 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate,
DOMArrayBuffer* to_transfer = this;
if (!IsDetachable(isolate)) {
to_transfer =
DOMArrayBuffer::Create(Buffer()->Data(), Buffer()->ByteLengthAsSizeT());
DOMArrayBuffer::Create(Content()->Data(), ByteLengthAsSizeT());
}
if (!to_transfer->Buffer()->Transfer(result))
if (IsDetached()) {
result.Detach();
return false;
}
if (!Content()->Data()) {
// We transfer an empty ArrayBuffer, we can just allocate an empty content.
result = ArrayBufferContents(Content()->BackingStore());
} else {
Content()->Transfer(result);
Detach();
}
Vector<v8::Local<v8::ArrayBuffer>, 4> buffer_handles;
v8::HandleScope handle_scope(isolate);
......@@ -62,21 +72,25 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate,
DOMArrayBuffer* DOMArrayBuffer::CreateOrNull(size_t num_elements,
size_t element_byte_size) {
scoped_refptr<ArrayBuffer> buffer =
ArrayBuffer::CreateOrNull(num_elements, element_byte_size);
if (!buffer)
ArrayBufferContents contents(num_elements, element_byte_size,
ArrayBufferContents::kNotShared,
ArrayBufferContents::kZeroInitialize);
if (!contents.Data()) {
return nullptr;
return Create(std::move(buffer));
}
return Create(std::move(contents));
}
DOMArrayBuffer* DOMArrayBuffer::CreateUninitializedOrNull(
size_t num_elements,
size_t element_byte_size) {
scoped_refptr<ArrayBuffer> buffer =
ArrayBuffer::CreateUninitializedOrNull(num_elements, element_byte_size);
if (!buffer)
ArrayBufferContents contents(num_elements, element_byte_size,
ArrayBufferContents::kNotShared,
ArrayBufferContents::kDontInitialize);
if (!contents.Data()) {
return nullptr;
return Create(std::move(buffer));
}
return Create(std::move(contents));
}
v8::Local<v8::Value> DOMArrayBuffer::Wrap(
......@@ -89,10 +103,9 @@ v8::Local<v8::Value> DOMArrayBuffer::Wrap(
v8::Local<v8::ArrayBuffer> wrapper;
{
v8::Context::Scope context_scope(creation_context->CreationContext());
wrapper =
v8::ArrayBuffer::New(isolate, Buffer()->Content()->BackingStore());
wrapper = v8::ArrayBuffer::New(isolate, Content()->BackingStore());
wrapper->Externalize(Buffer()->Content()->BackingStore());
wrapper->Externalize(Content()->BackingStore());
}
return AssociateWithWrapper(isolate, wrapper_type_info, wrapper);
......@@ -112,7 +125,7 @@ DOMArrayBuffer* DOMArrayBuffer::Create(
data += span.size();
}
return Create(ArrayBuffer::Create(contents));
return Create(std::move(contents));
}
DOMArrayBuffer* DOMArrayBuffer::Create(
......@@ -132,7 +145,7 @@ DOMArrayBuffer* DOMArrayBuffer::Create(
ptr += span.size();
}
return Create(ArrayBuffer::Create(contents));
return Create(std::move(contents));
}
DOMArrayBuffer* DOMArrayBuffer::Slice(size_t begin, size_t end) const {
......
......@@ -5,9 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_H_
#include "base/allocator/partition_allocator/oom.h"
#include "base/containers/span.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
......@@ -17,18 +18,29 @@ class CORE_EXPORT DOMArrayBuffer final : public DOMArrayBufferBase {
DEFINE_WRAPPERTYPEINFO();
public:
static DOMArrayBuffer* Create(scoped_refptr<ArrayBuffer> buffer) {
return MakeGarbageCollected<DOMArrayBuffer>(std::move(buffer));
static DOMArrayBuffer* Create(ArrayBufferContents contents) {
return MakeGarbageCollected<DOMArrayBuffer>(std::move(contents));
}
static DOMArrayBuffer* Create(size_t num_elements, size_t element_byte_size) {
return Create(ArrayBuffer::Create(num_elements, element_byte_size));
ArrayBufferContents contents(num_elements, element_byte_size,
ArrayBufferContents::kNotShared,
ArrayBufferContents::kZeroInitialize);
if (UNLIKELY(!contents.Data())) {
OOM_CRASH(num_elements * element_byte_size);
}
return Create(std::move(contents));
}
static DOMArrayBuffer* Create(const void* source, size_t byte_length) {
return Create(ArrayBuffer::Create(source, byte_length));
ArrayBufferContents contents(byte_length, 1,
ArrayBufferContents::kNotShared,
ArrayBufferContents::kDontInitialize);
if (UNLIKELY(!contents.Data())) {
OOM_CRASH(byte_length);
}
static DOMArrayBuffer* Create(ArrayBufferContents& contents) {
return Create(ArrayBuffer::Create(contents));
memcpy(contents.Data(), source, byte_length);
return Create(std::move(contents));
}
static DOMArrayBuffer* Create(scoped_refptr<SharedBuffer>);
static DOMArrayBuffer* Create(const Vector<base::span<const char>>&);
......@@ -41,8 +53,8 @@ class CORE_EXPORT DOMArrayBuffer final : public DOMArrayBufferBase {
static DOMArrayBuffer* CreateUninitializedOrNull(size_t num_elements,
size_t element_byte_size);
explicit DOMArrayBuffer(scoped_refptr<ArrayBuffer> buffer)
: DOMArrayBufferBase(std::move(buffer)) {}
explicit DOMArrayBuffer(ArrayBufferContents contents)
: DOMArrayBufferBase(std::move(contents)) {}
DOMArrayBuffer* Slice(size_t begin, size_t end) const;
......@@ -56,7 +68,12 @@ class CORE_EXPORT DOMArrayBuffer final : public DOMArrayBufferBase {
// for e.g. WebAudio which uses a separate thread for processing the
// ArrayBuffer while at the same time exposing a NonShared Float32Array.
bool ShareNonSharedForInternalUse(ArrayBufferContents& result) {
return Buffer()->ShareNonSharedForInternalUse(result);
if (!Content()->BackingStore()) {
result.Detach();
return false;
}
Content()->ShareNonSharedForInternalUse(result);
return true;
}
v8::Local<v8::Value> Wrap(v8::Isolate*,
......
......@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_BASE_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
......@@ -16,27 +16,28 @@ class CORE_EXPORT DOMArrayBufferBase : public ScriptWrappable {
public:
~DOMArrayBufferBase() override = default;
const ArrayBuffer* Buffer() const { return buffer_.get(); }
ArrayBuffer* Buffer() { return buffer_.get(); }
const ArrayBufferContents* Content() const { return &contents_; }
ArrayBufferContents* Content() { return &contents_; }
const void* Data() const { return Buffer()->Data(); }
void* Data() { return Buffer()->Data(); }
const void* Data() const { return contents_.Data(); }
void* Data() { return contents_.Data(); }
const void* DataMaybeShared() const { return Buffer()->DataMaybeShared(); }
void* DataMaybeShared() { return Buffer()->DataMaybeShared(); }
const void* DataMaybeShared() const { return contents_.DataMaybeShared(); }
void* DataMaybeShared() { return contents_.DataMaybeShared(); }
size_t ByteLengthAsSizeT() const { return Buffer()->ByteLengthAsSizeT(); }
size_t ByteLengthAsSizeT() const { return contents_.DataLength(); }
// This function is deprecated and should not be used. Use {ByteLengthAsSizeT}
// instead.
unsigned DeprecatedByteLengthAsUnsigned() const {
size_t size = ByteLengthAsSizeT();
CHECK_LE(size, static_cast<size_t>(std::numeric_limits<unsigned>::max()));
return static_cast<unsigned>(size);
return base::checked_cast<unsigned>(contents_.DataLength());
}
bool IsDetached() const { return Buffer()->IsDetached(); }
bool IsShared() const { return Buffer()->IsShared(); }
bool IsDetached() const { return is_detached_; }
void Detach() { is_detached_ = true; }
bool IsShared() const { return contents_.IsShared(); }
v8::Local<v8::Value> Wrap(v8::Isolate*,
v8::Local<v8::Object> creation_context) override {
......@@ -45,12 +46,11 @@ class CORE_EXPORT DOMArrayBufferBase : public ScriptWrappable {
}
protected:
explicit DOMArrayBufferBase(scoped_refptr<ArrayBuffer> buffer)
: buffer_(std::move(buffer)) {
DCHECK(buffer_);
}
explicit DOMArrayBufferBase(ArrayBufferContents contents)
: contents_(std::move(contents)) {}
scoped_refptr<ArrayBuffer> buffer_;
ArrayBufferContents contents_;
bool is_detached_ = false;
};
} // namespace blink
......
......@@ -15,8 +15,8 @@ v8::Local<v8::Value> DOMSharedArrayBuffer::Wrap(
const WrapperTypeInfo* wrapper_type_info = this->GetWrapperTypeInfo();
v8::Local<v8::SharedArrayBuffer> wrapper =
v8::SharedArrayBuffer::New(isolate, Buffer()->Content()->BackingStore());
wrapper->Externalize(Buffer()->Content()->BackingStore());
v8::SharedArrayBuffer::New(isolate, Content()->BackingStore());
wrapper->Externalize(Content()->BackingStore());
return AssociateWithWrapper(isolate, wrapper_type_info, wrapper);
}
......
......@@ -5,8 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_SHARED_ARRAY_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_SHARED_ARRAY_BUFFER_H_
#include "base/allocator/partition_allocator/oom.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h"
namespace blink {
......@@ -15,28 +16,43 @@ class CORE_EXPORT DOMSharedArrayBuffer final : public DOMArrayBufferBase {
DEFINE_WRAPPERTYPEINFO();
public:
static DOMSharedArrayBuffer* Create(scoped_refptr<ArrayBuffer> buffer) {
DCHECK(buffer->IsShared());
return MakeGarbageCollected<DOMSharedArrayBuffer>(std::move(buffer));
static DOMSharedArrayBuffer* Create(ArrayBufferContents contents) {
DCHECK(contents.IsShared());
return MakeGarbageCollected<DOMSharedArrayBuffer>(std::move(contents));
}
static DOMSharedArrayBuffer* Create(unsigned num_elements,
unsigned element_byte_size) {
return Create(ArrayBuffer::CreateShared(num_elements, element_byte_size));
ArrayBufferContents contents(num_elements, element_byte_size,
ArrayBufferContents::kShared,
ArrayBufferContents::kZeroInitialize);
if (UNLIKELY(!contents.DataShared())) {
OOM_CRASH(num_elements * element_byte_size);
}
return Create(std::move(contents));
}
static DOMSharedArrayBuffer* Create(const void* source,
unsigned byte_length) {
return Create(ArrayBuffer::CreateShared(source, byte_length));
ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kShared,
ArrayBufferContents::kDontInitialize);
if (UNLIKELY(!contents.DataShared())) {
OOM_CRASH(byte_length);
}
static DOMSharedArrayBuffer* Create(ArrayBufferContents& contents) {
DCHECK(contents.IsShared());
return Create(ArrayBuffer::Create(contents));
memcpy(contents.DataShared(), source, byte_length);
return Create(std::move(contents));
}
explicit DOMSharedArrayBuffer(scoped_refptr<ArrayBuffer> buffer)
: DOMArrayBufferBase(std::move(buffer)) {}
explicit DOMSharedArrayBuffer(ArrayBufferContents contents)
: DOMArrayBufferBase(std::move(contents)) {}
bool ShareContentsWith(ArrayBufferContents& result) {
return Buffer()->ShareContentsWith(result);
if (!Content()->BackingStore()) {
result.Detach();
return false;
}
Content()->ShareWith(result);
return true;
}
v8::Local<v8::Value> Wrap(v8::Isolate*,
......
......@@ -1665,7 +1665,7 @@ ImageData* BaseRenderingContext2D::getImageData(
"Buffer size exceeds maximum heap object size.");
return nullptr;
}
DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents);
DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(std::move(contents));
ImageData* imageData = ImageData::Create(
image_data_rect.Size(),
......
......@@ -450,7 +450,6 @@ void PresentationConnection::send(const String& message,
void PresentationConnection::send(DOMArrayBuffer* array_buffer,
ExceptionState& exception_state) {
DCHECK(array_buffer);
DCHECK(array_buffer->Buffer());
if (!CanSendMessage(exception_state))
return;
if (!base::CheckedNumeric<wtf_size_t>(array_buffer->ByteLengthAsSizeT())
......@@ -643,7 +642,6 @@ void PresentationConnection::DidFinishLoadingBlob(DOMArrayBuffer* buffer) {
DCHECK(!messages_.IsEmpty());
DCHECK_EQ(messages_.front()->type, kMessageTypeBlob);
DCHECK(buffer);
DCHECK(buffer->Buffer());
if (!base::CheckedNumeric<wtf_size_t>(buffer->ByteLengthAsSizeT())
.IsValid()) {
// TODO(crbug.com/1036565): generate error message? The problem is that the
......
......@@ -348,7 +348,6 @@ void DOMWebSocket::send(DOMArrayBuffer* binary_data,
NETWORK_DVLOG(1) << "WebSocket " << this << " send() Sending ArrayBuffer "
<< binary_data;
DCHECK(binary_data);
DCHECK(binary_data->Buffer());
if (common_.GetState() == kConnecting) {
SetInvalidStateErrorForSendMethod(exception_state);
return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment