blob: 6bcd117e894a7f47d5a627c582d5888e5eb87389 [file] [log] [blame]
// Copyright 2015 The Chromium 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 THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_FLEXIBLE_ARRAY_BUFFER_VIEW_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_FLEXIBLE_ARRAY_BUFFER_VIEW_H_
#include "base/macros.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
// FlexibleArrayBufferView is a performance hack to avoid overhead to
// instantiate DOMArrayBufferView and DOMArrayBuffer when the contents are
// very small. Otherwise, FlexibleArrayBufferView is a thin wrapper to
// DOMArrayBufferView.
class CORE_EXPORT FlexibleArrayBufferView {
STACK_ALLOCATED();
public:
FlexibleArrayBufferView() = default;
FlexibleArrayBufferView(const FlexibleArrayBufferView&) = default;
FlexibleArrayBufferView(FlexibleArrayBufferView&&) = default;
FlexibleArrayBufferView(v8::Local<v8::ArrayBufferView> array_buffer_view) {
SetContents(array_buffer_view);
}
~FlexibleArrayBufferView() = default;
FlexibleArrayBufferView& operator=(const FlexibleArrayBufferView&) = delete;
FlexibleArrayBufferView& operator=(FlexibleArrayBufferView&&) = delete;
void Clear() {
full_ = nullptr;
small_data_ = nullptr;
small_length_ = 0;
}
void SetContents(v8::Local<v8::ArrayBufferView> array_buffer_view) {
DCHECK(IsNull());
size_t size = array_buffer_view->ByteLength();
if (size <= sizeof small_buffer_) {
array_buffer_view->CopyContents(small_buffer_, size);
small_data_ = small_buffer_;
small_length_ = size;
} else {
full_ = V8ArrayBufferView::ToImpl(array_buffer_view);
}
}
// Returns true if this object represents IDL null.
bool IsNull() const { return !full_ && !small_data_; }
bool IsFull() const { return full_; }
DOMArrayBufferView* Full() const {
DCHECK(IsFull());
return full_;
}
// WARNING: The pointer returned by baseAddressMaybeOnStack() may point to
// temporary storage that is only valid during the life-time of the
// FlexibleArrayBufferView object.
void* BaseAddressMaybeOnStack() const {
DCHECK(!IsNull());
return IsFull() ? full_->BaseAddressMaybeShared() : small_data_;
}
size_t ByteLengthAsSizeT() const {
DCHECK(!IsNull());
return IsFull() ? full_->byteLengthAsSizeT() : small_length_;
}
unsigned DeprecatedByteLengthAsUnsigned() const {
DCHECK(!IsNull());
return IsFull() ? base::checked_cast<unsigned>(full_->byteLengthAsSizeT())
: base::checked_cast<unsigned>(small_length_);
}
// TODO(crbug.com/1050474): Remove this cast operator and make the callsites
// explicitly call IsNull().
operator bool() const { return !IsNull(); }
private:
DOMArrayBufferView* full_ = nullptr;
// If the contents of the given v8::ArrayBufferView are small enough to fit
// within |small_buffer_|, the contents are directly copied into
// |small_buffer_| to which accesses are much faster than to a maybe-shared
// buffer in a DOMArrayBufferView.
void* small_data_ = nullptr; // Non null iff |small_buffer_| is used
size_t small_length_ = 0; // The size actually used of |small_buffer_|
uint8_t small_buffer_[64];
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_FLEXIBLE_ARRAY_BUFFER_VIEW_H_