summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-06-11 21:12:48 -0400
committerGitHub <noreply@github.com>2021-06-12 01:12:48 +0000
commitaec8d12282b5279b80e79f21d54491db5d55278e (patch)
tree4f0325893fda3aa98ab970757e9d3cd2288f6603 /src
parent446634a503116186a025d23375c430cb837e00f0 (diff)
downloadbinaryen-aec8d12282b5279b80e79f21d54491db5d55278e.tar.gz
binaryen-aec8d12282b5279b80e79f21d54491db5d55278e.tar.bz2
binaryen-aec8d12282b5279b80e79f21d54491db5d55278e.zip
[wasm-split] Add an option to emit a placeholder map (#3931)
The new instruction emits a file containing a map between placeholder index and the name of the split out function that placeholder is replacing in the table. This map is intended to be useful for debugging, as discussed in https://github.com/emscripten-core/emscripten/issues/14330.
Diffstat (limited to 'src')
-rw-r--r--src/ir/module-splitting.cpp9
-rw-r--r--src/ir/module-splitting.h7
-rw-r--r--src/tools/wasm-split.cpp26
3 files changed, 37 insertions, 5 deletions
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp
index d6dca8994..9c5c66641 100644
--- a/src/ir/module-splitting.cpp
+++ b/src/ir/module-splitting.cpp
@@ -272,6 +272,9 @@ struct ModuleSplitter {
// names.
std::map<Name, Name> exportedPrimaryFuncs;
+ // Map placeholder indices to the names of the functions they replace.
+ std::map<size_t, Name> placeholderMap;
+
// Initialization helpers
static std::unique_ptr<Module> initSecondary(const Module& primary);
static std::pair<std::set<Name>, std::set<Name>>
@@ -483,6 +486,7 @@ void ModuleSplitter::setupTablePatching() {
// `importNamespace`.`index`.
forEachElement(primary, [&](Name, Name, Index index, Name& elem) {
if (secondaryFuncs.count(elem)) {
+ placeholderMap[index] = elem;
auto* secondaryFunc = secondary.getFunction(elem);
replacedElems[index] = secondaryFunc;
auto placeholder = std::make_unique<Function>();
@@ -655,8 +659,9 @@ void ModuleSplitter::shareImportableItems() {
} // anonymous namespace
-std::unique_ptr<Module> splitFunctions(Module& primary, const Config& config) {
- return std::move(ModuleSplitter(primary, config).secondaryPtr);
+Results splitFunctions(Module& primary, const Config& config) {
+ ModuleSplitter split(primary, config);
+ return {std::move(split.secondaryPtr), std::move(split.placeholderMap)};
}
} // namespace ModuleSplitting
diff --git a/src/ir/module-splitting.h b/src/ir/module-splitting.h
index 479fba148..cfbd45b14 100644
--- a/src/ir/module-splitting.h
+++ b/src/ir/module-splitting.h
@@ -68,8 +68,13 @@ struct Config {
bool minimizeNewExportNames = false;
};
+struct Results {
+ std::unique_ptr<Module> secondary;
+ std::map<size_t, Name> placeholderMap;
+};
+
// Returns the new secondary module and modifies the `primary` module in place.
-std::unique_ptr<Module> splitFunctions(Module& primary, const Config& config);
+Results splitFunctions(Module& primary, const Config& config);
} // namespace ModuleSplitting
diff --git a/src/tools/wasm-split.cpp b/src/tools/wasm-split.cpp
index 4ac295d0e..261c62a68 100644
--- a/src/tools/wasm-split.cpp
+++ b/src/tools/wasm-split.cpp
@@ -61,6 +61,7 @@ struct WasmSplitOptions : ToolOptions {
bool verbose = false;
bool emitBinary = true;
bool symbolMap = false;
+ bool placeholderMap = false;
// TODO: Remove this. See the comment in wasm-binary.h.
bool emitModuleNames = false;
@@ -180,6 +181,13 @@ WasmSplitOptions::WasmSplitOptions()
{Mode::Split},
Options::Arguments::Zero,
[&](Options* o, const std::string& argument) { symbolMap = true; })
+ .add(
+ "--placeholdermap",
+ "",
+ "Write a file mapping placeholder indices to the function names.",
+ {Mode::Split},
+ Options::Arguments::Zero,
+ [&](Options* o, const std::string& argument) { placeholderMap = true; })
.add("--import-namespace",
"",
"The namespace from which to import objects from the primary "
@@ -690,6 +698,15 @@ void writeSymbolMap(Module& wasm, std::string filename) {
runner.run();
}
+void writePlaceholderMap(const std::map<size_t, Name> placeholderMap,
+ std::string filename) {
+ Output output(filename, Flags::Text);
+ auto& o = output.getStream();
+ for (auto pair : placeholderMap) {
+ o << pair.first << ':' << pair.second << '\n';
+ }
+}
+
void splitModule(const WasmSplitOptions& options) {
Module wasm;
parseInput(wasm, options);
@@ -795,8 +812,8 @@ void splitModule(const WasmSplitOptions& options) {
config.newExportPrefix = options.exportPrefix;
}
config.minimizeNewExportNames = !options.passOptions.debugInfo;
- std::unique_ptr<Module> secondary =
- ModuleSplitting::splitFunctions(wasm, config);
+ auto splitResults = ModuleSplitting::splitFunctions(wasm, config);
+ auto& secondary = splitResults.secondary;
adjustTableSize(wasm, options.initialTableSize);
adjustTableSize(*secondary, options.initialTableSize);
@@ -806,6 +823,11 @@ void splitModule(const WasmSplitOptions& options) {
writeSymbolMap(*secondary, options.secondaryOutput + ".symbols");
}
+ if (options.placeholderMap) {
+ writePlaceholderMap(splitResults.placeholderMap,
+ options.primaryOutput + ".placeholders");
+ }
+
// Set the names of the split modules. This can help differentiate them in
// stack traces.
if (options.emitModuleNames) {