Commit 2803a7ec authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[webtransport] Avoid using deprecated ArrayBuffer

This CL removed a use of the deprecated ArrayBuffer class. In the
|OutgoingStream| class, ArrayBuffer was used to own a byte array and
its length. This Cl replaces ArrayBuffer with a small inner class that
does exactly that, it stores a byte array and its length. The
constructor uses the wtf::Vector allocator to allocate the byte array.

R=ricea@chromium.org
CC=​haraken@chromium.org

Bug: chromium:1008840
Change-Id: I21286265eeaabe359ea7709b8d05042c854b7c25
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2102585Reviewed-by: default avatarAdam Rice <ricea@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#750924}
parent 667e005b
......@@ -4,8 +4,10 @@
#include "third_party/blink/renderer/modules/webtransport/outgoing_stream.h"
#include <string.h>
#include <utility>
#include "base/allocator/partition_allocator/partition_alloc.h"
#include "base/numerics/safe_conversions.h"
#include "mojo/public/cpp/system/simple_watcher.h"
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
......@@ -91,6 +93,27 @@ class OutgoingStream::UnderlyingSink final : public UnderlyingSinkBase {
const Member<OutgoingStream> outgoing_stream_;
};
OutgoingStream::CachedDataBuffer::CachedDataBuffer(v8::Isolate* isolate,
const uint8_t* data,
size_t length)
: isolate_(isolate), length_(length) {
// We use the BufferPartition() allocator here to allow big enough
// allocations, and to do proper accounting of the used memory. If
// BufferPartition() will ever not be able to provide big enough allocations,
// e.g. because bigger ArrayBuffers get supported, then we have to switch to
// another allocator, e.g. the ArrayBuffer allocator.
buffer_ = reinterpret_cast<uint8_t*>(
WTF::Partitions::BufferPartition()->Alloc(length, "OutgoingStream"));
memcpy(buffer_, data, length);
isolate_->AdjustAmountOfExternalAllocatedMemory(static_cast<int64_t>(length));
}
OutgoingStream::CachedDataBuffer::~CachedDataBuffer() {
WTF::Partitions::BufferPartition()->Free(buffer_);
isolate_->AdjustAmountOfExternalAllocatedMemory(
-static_cast<int64_t>(length_));
}
OutgoingStream::OutgoingStream(ScriptState* script_state,
WebTransportCloseProxy* close_proxy,
mojo::ScopedDataPipeProducerHandle handle)
......@@ -257,8 +280,8 @@ ScriptPromise OutgoingStream::WriteOrCacheData(ScriptState* script_state,
}
DCHECK(!cached_data_);
cached_data_ =
ArrayBuffer::Create(data.data() + written, data.size() - written);
cached_data_ = std::make_unique<CachedDataBuffer>(
script_state->GetIsolate(), data.data() + written, data.size() - written);
DCHECK_EQ(offset_, 0u);
write_watcher_.ArmOrNotify();
write_promise_resolver_ =
......@@ -272,15 +295,15 @@ ScriptPromise OutgoingStream::WriteOrCacheData(ScriptState* script_state,
void OutgoingStream::WriteCachedData() {
DVLOG(1) << "OutgoingStream::WriteCachedData() this=" << this;
auto data = base::make_span(static_cast<uint8_t*>(cached_data_->Data()),
cached_data_->ByteLengthAsSizeT())
auto data = base::make_span(static_cast<uint8_t*>(cached_data_->data()),
cached_data_->length())
.subspan(offset_);
size_t written = WriteDataSynchronously(data);
if (written == data.size()) {
ScriptState::Scope scope(script_state_);
cached_data_ = nullptr;
cached_data_.reset();
offset_ = 0;
write_promise_resolver_->Resolve();
write_promise_resolver_ = nullptr;
......@@ -288,7 +311,7 @@ void OutgoingStream::WriteCachedData() {
}
if (!data_pipe_) {
cached_data_ = nullptr;
cached_data_.reset();
offset_ = 0;
return;
......@@ -377,7 +400,7 @@ void OutgoingStream::ResetPipe() {
close_watcher_.Cancel();
data_pipe_.reset();
if (cached_data_)
cached_data_ = nullptr;
cached_data_.reset();
}
void OutgoingStream::Dispose() {
......
......@@ -20,9 +20,12 @@
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
namespace v8 {
class Isolate;
}
namespace blink {
class ArrayBuffer;
class ScriptState;
class StreamAbortInfo;
class WebTransportCloseProxy;
......@@ -123,6 +126,24 @@ class MODULES_EXPORT OutgoingStream
// Prepares the object for destruction.
void Dispose();
class CachedDataBuffer {
public:
CachedDataBuffer(v8::Isolate* isolate, const uint8_t* data, size_t length);
~CachedDataBuffer();
size_t length() const { return length_; }
uint8_t* data() { return buffer_; }
private:
// We need the isolate to call |AdjustAmountOfExternalAllocatedMemory| for
// the memory stored in |buffer_|.
v8::Isolate* isolate_;
size_t length_ = 0u;
uint8_t* buffer_ = nullptr;
};
const Member<ScriptState> script_state_;
const Member<WebTransportCloseProxy> close_proxy_;
mojo::ScopedDataPipeProducerHandle data_pipe_;
......@@ -135,10 +156,10 @@ class MODULES_EXPORT OutgoingStream
// Data which has been passed to write() but still needs to be written
// asynchronously.
// Uses an ArrayBuffer rather than a Vector because WTF::Vector is currently
// limited to 2GB.
// Uses a custom CachedDataBuffer rather than a Vector because
// WTF::Vector is currently limited to 2GB.
// TODO(ricea): Change this to a Vector when it becomes 64-bit safe.
scoped_refptr<ArrayBuffer> cached_data_;
std::unique_ptr<CachedDataBuffer> cached_data_;
// The offset into |cached_data_| of the first byte that still needs to be
// written.
......
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