impl multi-memories wasm-split
diff --git a/src/ir/names.h b/src/ir/names.h
index af6ca15..db45ef4 100644
--- a/src/ir/names.h
+++ b/src/ir/names.h
@@ -83,6 +83,10 @@
   return getValidName(
     root, [&](Name test) { return !module.getElementSegmentOrNull(test); });
 }
+inline Name getValidMemoryName(Module& module, Name root) {
+  return getValidName(root,
+                      [&](Name test) { return !module.getMemoryOrNull(test); });
+}
 
 class MinifiedNameGenerator {
   size_t state = 0;
diff --git a/src/tools/wasm-split/instrumenter.cpp b/src/tools/wasm-split/instrumenter.cpp
index 50da9d0..538cd43 100644
--- a/src/tools/wasm-split/instrumenter.cpp
+++ b/src/tools/wasm-split/instrumenter.cpp
@@ -28,19 +28,27 @@
 void Instrumenter::run(PassRunner* runner, Module* wasm) {
   this->runner = runner;
   this->wasm = wasm;
-  addGlobals();
+  size_t numFuncs = 0;
+  ModuleUtils::iterDefinedFunctions(*wasm, [&](Function*) { ++numFuncs; });
+
+  // Calculate the size of the profile:
+  //   8 bytes module hash +
+  //   4 bytes for the timestamp for each function
+  const size_t profileSize = 8 + 4 * numFuncs;
+  addGlobals(numFuncs);
+  addMemory(profileSize);
   instrumentFuncs();
-  addProfileExport();
+  addProfileExport(numFuncs, profileSize);
 }
 
-void Instrumenter::addGlobals() {
+void Instrumenter::addGlobals(size_t numFuncs) {
   if (options.storageKind != WasmSplitOptions::StorageKind::InGlobals) {
     // Don't need globals
     return;
   }
   // Create fresh global names (over-reserves, but that's ok)
   counterGlobal = Names::getValidGlobalName(*wasm, "monotonic_counter");
-  functionGlobals.reserve(wasm->functions.size());
+  functionGlobals.reserve(numFuncs);
   ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
     functionGlobals.push_back(Names::getValidGlobalName(
       *wasm, std::string(func->name.c_str()) + "_timestamp"));
@@ -62,6 +70,13 @@
   }
 }
 
+void Instrumenter::addMemory(size_t profileSize) {
+  instrumentMemory = Names::getValidMemoryName(*wasm, "split_instrumenter");
+  // Create a memory with enough pages to write into
+  size_t pages = (profileSize + Memory::kPageSize - 1) / Memory::kPageSize;
+  wasm->addMemory(Builder::makeMemory(instrumentMemory, pages, pages));
+}
+
 void Instrumenter::instrumentFuncs() {
   // Inject code at the beginning of each function to advance the monotonic
   // counter and set the function's timestamp if it hasn't already been set.
@@ -108,7 +123,6 @@
       }
       // (i32.atomic.store8 offset=funcidx (i32.const 0) (i32.const 1))
       Index funcIdx = 0;
-      assert(!wasm->memories.empty());
       ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
         func->body = builder.makeSequence(
           builder.makeAtomicStore(1,
@@ -116,7 +130,7 @@
                                   builder.makeConstPtr(0, Type::i32),
                                   builder.makeConst(uint32_t(1)),
                                   Type::i32,
-                                  wasm->memories[0]->name),
+                                  instrumentMemory),
           func->body,
           func->body->type);
         ++funcIdx;
@@ -141,7 +155,7 @@
 // otherwise. Functions with smaller non-zero timestamps were called earlier in
 // the instrumented run than funtions with larger timestamps.
 
-void Instrumenter::addProfileExport() {
+void Instrumenter::addProfileExport(size_t numFuncs, size_t profileSize) {
   // Create and export a function to dump the profile into a given memory
   // buffer. The function takes the available address and buffer size as
   // arguments and returns the total size of the profile. It only actually
@@ -153,13 +167,6 @@
   writeProfile->setLocalName(0, "addr");
   writeProfile->setLocalName(1, "size");
 
-  size_t numFuncs = 0;
-  ModuleUtils::iterDefinedFunctions(*wasm, [&](Function*) { ++numFuncs; });
-
-  // Calculate the size of the profile:
-  //   8 bytes module hash +
-  //   4 bytes for the timestamp for each function
-  const size_t profileSize = 8 + 4 * numFuncs;
 
   // Create the function body
   Builder builder(*wasm);
@@ -170,22 +177,10 @@
     return builder.makeConst(int32_t(profileSize));
   };
 
-  // Also make sure there is a memory with enough pages to write into
-  size_t pages = (profileSize + Memory::kPageSize - 1) / Memory::kPageSize;
-  if (wasm->memories.empty()) {
-    wasm->addMemory(Builder::makeMemory("0"));
-    wasm->memories[0]->initial = pages;
-    wasm->memories[0]->max = pages;
-  } else if (wasm->memories[0]->initial < pages) {
-    wasm->memories[0]->initial = pages;
-    if (wasm->memories[0]->max < pages) {
-      wasm->memories[0]->max = pages;
-    }
-  }
 
   // Write the hash followed by all the time stamps
   Expression* writeData = builder.makeStore(
-    8, 0, 1, getAddr(), hashConst(), Type::i64, wasm->memories[0]->name);
+    8, 0, 1, getAddr(), hashConst(), Type::i64, instrumentMemory);
   uint32_t offset = 8;
 
   switch (options.storageKind) {
@@ -199,7 +194,7 @@
                             getAddr(),
                             builder.makeGlobalGet(global, Type::i32),
                             Type::i32,
-                            wasm->memories[0]->name));
+                            instrumentMemory));
         offset += 4;
       }
       break;
@@ -249,9 +244,9 @@
                   builder.makeBinary(
                     MulInt32, getFuncIdx(), builder.makeConst(uint32_t(4)))),
                 builder.makeAtomicLoad(
-                  1, 0, getFuncIdx(), Type::i32, wasm->memories[0]->name),
+                  1, 0, getFuncIdx(), Type::i32, instrumentMemory),
                 Type::i32,
-                wasm->memories[0]->name),
+                instrumentMemory),
               builder.makeLocalSet(
                 funcIdxVar,
                 builder.makeBinary(
@@ -271,11 +266,13 @@
   wasm->addExport(
     Builder::makeExport(options.profileExport, name, ExternalKind::Function));
 
-  // Export the memory if it is not already exported or imported.
+  // Export the main memory, assumed to be at idx 0, if it is not already exported or imported.
   if (!wasm->memories[0]->imported()) {
     bool memoryExported = false;
+    const char* memoryName = wasm->memories[0]->name.c_str();
     for (auto& ex : wasm->exports) {
-      if (ex->kind == ExternalKind::Memory) {
+      const char* exportValue = ex->value.c_str();
+      if (ex->kind == ExternalKind::Memory && strncmp(exportValue, memoryName, strlen(memoryName) == 0)) {
         memoryExported = true;
         break;
       }
diff --git a/src/tools/wasm-split/instrumenter.h b/src/tools/wasm-split/instrumenter.h
index 7de5a91..1913d12 100644
--- a/src/tools/wasm-split/instrumenter.h
+++ b/src/tools/wasm-split/instrumenter.h
@@ -36,14 +36,16 @@
   Name counterGlobal;
   std::vector<Name> functionGlobals;
 
-  Instrumenter(const WasmSplitOptions& options, uint64_t moduleHash);
+  Name instrumentMemory;
 
+  Instrumenter(const WasmSplitOptions& options, uint64_t moduleHash);
   void run(PassRunner* runner, Module* wasm) override;
 
 private:
-  void addGlobals();
+  void addGlobals(size_t numFuncs);
+  void addMemory(size_t profileSize);
   void instrumentFuncs();
-  void addProfileExport();
+  void addProfileExport(size_t numFuncs, size_t profileSize);
 };
 
 } // namespace wasm