summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
authorPhilip Pfaffe <philip.pfaffe@gmail.com>2021-01-27 20:45:46 +0100
committerGitHub <noreply@github.com>2021-01-27 11:45:46 -0800
commit1b950a1c4eb7b1a0a1d71c7e68e223fe57fdff66 (patch)
tree184ec9fbbce636838d95aa332c1454bc551e0c37 /src/wasm/wasm-binary.cpp
parent5331e9d18b9359aa0e9d6e0df455883f62e46ea0 (diff)
downloadbinaryen-1b950a1c4eb7b1a0a1d71c7e68e223fe57fdff66.tar.gz
binaryen-1b950a1c4eb7b1a0a1d71c7e68e223fe57fdff66.tar.bz2
binaryen-1b950a1c4eb7b1a0a1d71c7e68e223fe57fdff66.zip
Memcpy data instead of bytewise copies (#3521)
wasm-finalize currently makes byte-wise copies of section data in the user and data sections. If the section is large, that's extraordinarily expensive. With a memcpy instead I see a speedup of 1.6 for a large wasm binary with DWARF data.
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r--src/wasm/wasm-binary.cpp41
1 files changed, 22 insertions, 19 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 020953c1b..398ef9cb5 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1265,12 +1265,18 @@ void WasmBinaryBuilder::readUserSection(size_t payloadLen) {
wasm.userSections.resize(wasm.userSections.size() + 1);
auto& section = wasm.userSections.back();
section.name = sectionName.str;
- auto sectionSize = payloadLen;
- section.data.resize(sectionSize);
- for (size_t i = 0; i < sectionSize; i++) {
- section.data[i] = getInt8();
- }
+ auto data = getByteView(payloadLen);
+ section.data = {data.first, data.second};
+ }
+}
+
+std::pair<const char*, const char*>
+WasmBinaryBuilder::getByteView(size_t size) {
+ if (size > input.size() || pos > input.size() - size) {
+ throwError("unexpected end of input");
}
+ pos += size;
+ return {&input[pos - size], &input[pos]};
}
uint8_t WasmBinaryBuilder::getInt8() {
@@ -1504,15 +1510,14 @@ Type WasmBinaryBuilder::getConcreteType() {
Name WasmBinaryBuilder::getInlineString() {
BYN_TRACE("<==\n");
auto len = getU32LEB();
- std::string str;
- for (size_t i = 0; i < len; i++) {
- auto curr = char(getInt8());
- if (curr == 0) {
- throwError(
- "inline string contains NULL (0). that is technically valid in wasm, "
- "but you shouldn't do it, and it's not supported in binaryen");
- }
- str = str + curr;
+
+ auto data = getByteView(len);
+
+ std::string str(data.first, data.second);
+ if (str.find('\0') != std::string::npos) {
+ throwError(
+ "inline string contains NULL (0). that is technically valid in wasm, "
+ "but you shouldn't do it, and it's not supported in binaryen");
}
BYN_TRACE("getInlineString: " << str << " ==>\n");
return Name(str);
@@ -2400,11 +2405,9 @@ void WasmBinaryBuilder::readDataSegments() {
curr.offset = readExpression();
}
auto size = getU32LEB();
- curr.data.resize(size);
- for (size_t j = 0; j < size; j++) {
- curr.data[j] = char(getInt8());
- }
- wasm.memory.segments.push_back(curr);
+ auto data = getByteView(size);
+ curr.data = {data.first, data.second};
+ wasm.memory.segments.push_back(std::move(curr));
}
}