Commit ff2e485f authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[utils] Add OwnedVector::NewForOverwrite

The existing {OwnedVector::New} value-initializes all elements, which
means zeroing them in case on integral types. In many cases though we
know that we will overwrite the content anyway, so the initialization is
redundant.
In the case of assembly buffers for wasm compilation, this zeroing
showed up with several percent of execution times for some benchmarks.

Hence this CL introduces a new {OwnedVector::NewForOverwrite} (along the
lines of {std::make_unique_for_overwrite}), which only
default-initializes the values (meaning no initialization for integral
values).

R=thibaudm@chromium.org

Bug: v8:10576
Change-Id: I8d2806088acebe8a264dea2c7ed74b0423671d4f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2237140
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68268}
parent ea0a1561
......@@ -81,7 +81,7 @@ namespace {
class DefaultAssemblerBuffer : public AssemblerBuffer {
public:
explicit DefaultAssemblerBuffer(int size)
: buffer_(OwnedVector<uint8_t>::New(size)) {
: buffer_(OwnedVector<uint8_t>::NewForOverwrite(size)) {
#ifdef DEBUG
ZapCode(reinterpret_cast<Address>(buffer_.start()), size);
#endif
......
......@@ -163,6 +163,7 @@ class OwnedVector {
: data_(std::move(data)), length_(length) {
DCHECK_IMPLIES(length_ > 0, data_ != nullptr);
}
// Implicit conversion from {OwnedVector<U>} to {OwnedVector<T>}, instantiable
// if {std::unique_ptr<U>} can be converted to {std::unique_ptr<T>}.
// Can be used to convert {OwnedVector<T>} to {OwnedVector<const T>}.
......@@ -207,11 +208,20 @@ class OwnedVector {
}
// Allocates a new vector of the specified size via the default allocator.
// Elements in the new vector are value-initialized.
static OwnedVector<T> New(size_t size) {
if (size == 0) return {};
return OwnedVector<T>(std::make_unique<T[]>(size), size);
}
// Allocates a new vector of the specified size via the default allocator.
// Elements in the new vector are default-initialized.
static OwnedVector<T> NewForOverwrite(size_t size) {
if (size == 0) return {};
// TODO(v8): Use {std::make_unique_for_overwrite} once we allow C++20.
return OwnedVector<T>(std::unique_ptr<T[]>(new T[size]), size);
}
// Allocates a new vector containing the specified collection of values.
// {Iterator} is the common type of {std::begin} and {std::end} called on a
// {const U&}. This function is only instantiable if that type exists.
......@@ -222,7 +232,8 @@ class OwnedVector {
Iterator begin = std::begin(collection);
Iterator end = std::end(collection);
using non_const_t = typename std::remove_const<T>::type;
auto vec = OwnedVector<non_const_t>::New(std::distance(begin, end));
auto vec =
OwnedVector<non_const_t>::NewForOverwrite(std::distance(begin, end));
std::copy(begin, end, vec.start());
return vec;
}
......
......@@ -48,7 +48,7 @@ class WasmInstructionBufferImpl {
DCHECK_LT(size(), new_size);
holder_->old_buffer_ = std::move(holder_->buffer_);
holder_->buffer_ = OwnedVector<uint8_t>::New(new_size);
holder_->buffer_ = OwnedVector<uint8_t>::NewForOverwrite(new_size);
return std::make_unique<View>(holder_->buffer_.as_vector(), holder_);
}
......@@ -58,7 +58,7 @@ class WasmInstructionBufferImpl {
};
explicit WasmInstructionBufferImpl(size_t size)
: buffer_(OwnedVector<uint8_t>::New(size)) {}
: buffer_(OwnedVector<uint8_t>::NewForOverwrite(size)) {}
std::unique_ptr<AssemblerBuffer> CreateView() {
DCHECK_NOT_NULL(buffer_);
......
......@@ -56,8 +56,8 @@ class V8_EXPORT_PRIVATE AsyncStreamingDecoder : public StreamingDecoder {
Vector<const uint8_t> length_bytes)
: // ID + length + payload
module_offset_(module_offset),
bytes_(OwnedVector<uint8_t>::New(1 + length_bytes.length() +
payload_length)),
bytes_(OwnedVector<uint8_t>::NewForOverwrite(
1 + length_bytes.length() + payload_length)),
payload_offset_(1 + length_bytes.length()) {
bytes_.start()[0] = id;
memcpy(bytes_.start() + 1, &length_bytes.first(), length_bytes.length());
......@@ -278,7 +278,8 @@ void AsyncStreamingDecoder::Finish() {
return;
}
OwnedVector<uint8_t> bytes = OwnedVector<uint8_t>::New(total_size_);
OwnedVector<uint8_t> bytes =
OwnedVector<uint8_t>::NewForOverwrite(total_size_);
uint8_t* cursor = bytes.start();
{
#define BYTES(x) (x & 0xFF), (x >> 8) & 0xFF, (x >> 16) & 0xFF, (x >> 24) & 0xFF
......
......@@ -855,13 +855,13 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) {
code->is_off_heap_trampoline() ? 0 : code->relocation_size();
OwnedVector<byte> reloc_info;
if (relocation_size > 0) {
reloc_info = OwnedVector<byte>::New(relocation_size);
memcpy(reloc_info.start(), code->relocation_start(), relocation_size);
reloc_info = OwnedVector<byte>::Of(
Vector<byte>{code->relocation_start(), relocation_size});
}
Handle<ByteArray> source_pos_table(code->SourcePositionTable(),
code->GetIsolate());
OwnedVector<byte> source_pos =
OwnedVector<byte>::New(source_pos_table->length());
OwnedVector<byte>::NewForOverwrite(source_pos_table->length());
if (source_pos_table->length() > 0) {
source_pos_table->copy_out(0, source_pos.start(),
source_pos_table->length());
......
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