summaryrefslogtreecommitdiff
path: root/src/passes/Monomorphize.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-07-18 13:40:20 -0700
committerGitHub <noreply@github.com>2024-07-18 13:40:20 -0700
commit7b1ef0c9023368fffd1b6eb6771cab3690295fef (patch)
treeabfafcc13a2c0ff18be3f9611466c9beb6983980 /src/passes/Monomorphize.cpp
parenta744bec7bc744182822c6b86aa3159d08dea0b3c (diff)
downloadbinaryen-7b1ef0c9023368fffd1b6eb6771cab3690295fef.tar.gz
binaryen-7b1ef0c9023368fffd1b6eb6771cab3690295fef.tar.bz2
binaryen-7b1ef0c9023368fffd1b6eb6771cab3690295fef.zip
Monomorphization: Add a limit on the number of parameters (#6774)
Diffstat (limited to 'src/passes/Monomorphize.cpp')
-rw-r--r--src/passes/Monomorphize.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/passes/Monomorphize.cpp b/src/passes/Monomorphize.cpp
index 1fd81b9d1..f46e27d83 100644
--- a/src/passes/Monomorphize.cpp
+++ b/src/passes/Monomorphize.cpp
@@ -102,6 +102,7 @@
#include "ir/utils.h"
#include "pass.h"
#include "support/hash.h"
+#include "wasm-limits.h"
#include "wasm-type.h"
#include "wasm.h"
@@ -109,6 +110,15 @@ namespace wasm {
namespace {
+// A limit on the number of parameters we are willing to have on monomorphized
+// functions. Large numbers can lead to large stack frames, which can be slow
+// and lead to stack overflows.
+// TODO: Tune this and perhaps make it a flag.
+const Index MaxParams = 20;
+// This must be less than the corresponding Web limitation, so we do not emit
+// invalid binaries.
+static_assert(MaxParams < WebLimitations::MaxFunctionParams);
+
// Core information about a call: the call itself, and if it is dropped, the
// drop.
struct CallInfo {
@@ -628,6 +638,16 @@ struct Monomorphize : public Pass {
std::unique_ptr<Function> monoFunc =
makeMonoFunctionWithContext(func, context, wasm);
+ // If we ended up with too many params, give up. In theory we could try to
+ // monomorphize in ways that use less params, but this is a rare situation
+ // that is not easy to handle (when we move something into the context, it
+ // *removes* a param, which is good, but if it has many children and end up
+ // not moved, that is where the problem happens, so we'd need to backtrack).
+ // TODO: Consider doing more here.
+ if (monoFunc->getNumParams() >= MaxParams) {
+ return;
+ }
+
// Decide whether it is worth using the monomorphized function.
auto worthwhile = true;
if (onlyWhenHelpful) {