[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/+/1939051
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65210}
This commit is contained in:
Clemens Backes 2019-11-27 13:59:26 +01:00 committed by Commit Bot
parent fad8039ff1
commit a15afd7786
2 changed files with 16 additions and 3 deletions

View File

@ -485,9 +485,20 @@ int WasmTableObject::Grow(Isolate* isolate, Handle<WasmTableObject> table,
if (max_size - old_size < count) return -1;
uint32_t new_size = old_size + count;
auto new_store = isolate->factory()->CopyFixedArrayAndGrow(
handle(table->entries(), isolate), count);
table->set_entries(*new_store, WriteBarrierMode::UPDATE_WRITE_BARRIER);
// Even with 2x over-allocation, there should not be an integer overflow.
STATIC_ASSERT(wasm::kV8MaxWasmTableSize <= kMaxInt / 2);
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);
Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate);

View File

@ -203,6 +203,8 @@ class V8_EXPORT_PRIVATE WasmTableObject : public JSObject {
public:
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_INT_ACCESSORS(current_length)
// TODO(titzer): introduce DECL_I64_ACCESSORS macro