From ee9d515581998165c0e573d2b5a468c5b361cfcd Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 28 Sep 2017 11:07:29 -0700 Subject: Optimize wasm reading (#1202) * optimize wasm reading: use a set of the breaks we've seen, don't rescan blocks to see if they have breaks to them --- src/wasm-binary.h | 1 + src/wasm/wasm-binary.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wasm-binary.h b/src/wasm-binary.h index b7e614fa5..bf1cb14d6 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -863,6 +863,7 @@ public: BreakTarget(Name name, int arity) : name(name), arity(arity) {} }; std::vector breakStack; + std::unordered_set breakTargetNames; bool breaksToReturn; // whether a break is done to the function scope, which is in effect a return std::vector expressionStack; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 0d142cd8f..f7e10d39b 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1629,6 +1629,7 @@ void WasmBinaryBuilder::readFunctions() { useDebugLocation = false; breaksToReturn = false; // process body + assert(breakTargetNames.size() == 0); assert(breakStack.empty()); breakStack.emplace_back(RETURN_BREAK, func->result != none); // the break target for the function scope assert(expressionStack.empty()); @@ -1637,6 +1638,7 @@ void WasmBinaryBuilder::readFunctions() { assert(depth == 0); assert(breakStack.size() == 1); breakStack.pop_back(); + assert(breakTargetNames.size() == 0); if (!expressionStack.empty()) { throw ParseException("stack not empty on function exit"); } @@ -2222,6 +2224,7 @@ void WasmBinaryBuilder::visitBlock(Block *curr) { pushBlockElements(curr, start, end); curr->finalize(curr->type); breakStack.pop_back(); + breakTargetNames.erase(curr->name); } } @@ -2237,12 +2240,13 @@ Expression* WasmBinaryBuilder::getBlockOrSingleton(WasmType type) { block->name = label; block->finalize(type); // maybe we don't need a block here? - if (!brokenTo(block)) { + if (breakTargetNames.find(block->name) == breakTargetNames.end()) { block->name = Name(); if (block->list.size() == 1) { return block->list[0]; } } + breakTargetNames.erase(block->name); return block; } @@ -2285,6 +2289,7 @@ void WasmBinaryBuilder::visitLoop(Loop *curr) { curr->body = block; } breakStack.pop_back(); + breakTargetNames.erase(curr->name); curr->finalize(curr->type); } @@ -2301,7 +2306,9 @@ WasmBinaryBuilder::BreakTarget WasmBinaryBuilder::getBreakTarget(int32_t offset) breaksToReturn = true; } if (debug) std::cerr << "breaktarget "<< breakStack[index].name << " arity " << breakStack[index].arity << std::endl; - return breakStack[index]; + auto& ret = breakStack[index]; + breakTargetNames.insert(ret.name); + return ret; } void WasmBinaryBuilder::visitBreak(Break *curr, uint8_t code) { -- cgit v1.2.3