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

[wasm] Grow table entries exponentially

In order to implement {dlsym} like functionality, toolchains might
generate code that grows the table by one element at a time (e.g.
Emscripten currently does that). To improve performance in such a case,
we over-allocate the backing store of the {WasmTableObject}. Whenever
the backing store grows, it grows at least by the old size of the table.
This ensures exponentially growth, avoiding too many re-allocations.

R=mstarzinger@chromium.org
CC=​ecmziegler@chromium.org

Bug: v8:10018
Change-Id: I502d590a89f7804363938a157b7ed2189283227a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1939051Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65210}
parent fad8039f
...@@ -485,9 +485,20 @@ int WasmTableObject::Grow(Isolate* isolate, Handle<WasmTableObject> table, ...@@ -485,9 +485,20 @@ int WasmTableObject::Grow(Isolate* isolate, Handle<WasmTableObject> table,
if (max_size - old_size < count) return -1; if (max_size - old_size < count) return -1;
uint32_t new_size = old_size + count; uint32_t new_size = old_size + count;
auto new_store = isolate->factory()->CopyFixedArrayAndGrow( // Even with 2x over-allocation, there should not be an integer overflow.
handle(table->entries(), isolate), count); STATIC_ASSERT(wasm::kV8MaxWasmTableSize <= kMaxInt / 2);
table->set_entries(*new_store, WriteBarrierMode::UPDATE_WRITE_BARRIER); DCHECK_GE(kMaxInt, new_size);
int old_capacity = table->entries().length();
if (new_size > static_cast<uint32_t>(old_capacity)) {
int grow = static_cast<int>(new_size) - old_capacity;
// Grow at least by the old capacity, to implement exponential growing.
grow = std::max(grow, old_capacity);
// Never grow larger than the max size.
grow = std::min(grow, static_cast<int>(max_size - old_capacity));
auto new_store = isolate->factory()->CopyFixedArrayAndGrow(
handle(table->entries(), isolate), grow);
table->set_entries(*new_store, WriteBarrierMode::UPDATE_WRITE_BARRIER);
}
table->set_current_length(new_size); table->set_current_length(new_size);
Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate); Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate);
......
...@@ -203,6 +203,8 @@ class V8_EXPORT_PRIVATE WasmTableObject : public JSObject { ...@@ -203,6 +203,8 @@ class V8_EXPORT_PRIVATE WasmTableObject : public JSObject {
public: public:
DECL_CAST(WasmTableObject) DECL_CAST(WasmTableObject)
// The entries array is at least as big as {current_length()}, but might be
// bigger to make future growth more efficient.
DECL_ACCESSORS(entries, FixedArray) DECL_ACCESSORS(entries, FixedArray)
DECL_INT_ACCESSORS(current_length) DECL_INT_ACCESSORS(current_length)
// TODO(titzer): introduce DECL_I64_ACCESSORS macro // TODO(titzer): introduce DECL_I64_ACCESSORS macro
......
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