summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/wasm-split/instrumenter.cpp44
-rw-r--r--test/lit/wasm-split/instrument-memory64.wast49
2 files changed, 72 insertions, 21 deletions
diff --git a/src/tools/wasm-split/instrumenter.cpp b/src/tools/wasm-split/instrumenter.cpp
index 38ebd271a..1c825f29f 100644
--- a/src/tools/wasm-split/instrumenter.cpp
+++ b/src/tools/wasm-split/instrumenter.cpp
@@ -177,32 +177,12 @@ void Instrumenter::instrumentFuncs() {
// the instrumented run than funtions with larger timestamps.
void Instrumenter::addProfileExport(size_t numFuncs) {
- // 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
- // writes the profile if the given space is sufficient to hold it.
- auto name = Names::getValidFunctionName(*wasm, config.profileExport);
- auto writeProfile = Builder::makeFunction(
- name, Signature({Type::i32, Type::i32}, Type::i32), {});
- writeProfile->hasExplicitName = true;
- writeProfile->setLocalName(0, "addr");
- writeProfile->setLocalName(1, "size");
-
// 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);
- auto getAddr = [&]() { return builder.makeLocalGet(0, Type::i32); };
- auto getSize = [&]() { return builder.makeLocalGet(1, Type::i32); };
- auto hashConst = [&]() { return builder.makeConst(int64_t(moduleHash)); };
- auto profileSizeConst = [&]() {
- return builder.makeConst(int32_t(profileSize));
- };
-
- // Also make sure there is a memory with enough pages to write into
+ // 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"));
@@ -215,6 +195,28 @@ void Instrumenter::addProfileExport(size_t numFuncs) {
}
}
+ auto ptrType = wasm->memories[0]->indexType;
+
+ // 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
+ // writes the profile if the given space is sufficient to hold it.
+ auto name = Names::getValidFunctionName(*wasm, config.profileExport);
+ auto writeProfile =
+ Builder::makeFunction(name, Signature({ptrType, Type::i32}, Type::i32), {});
+ writeProfile->hasExplicitName = true;
+ writeProfile->setLocalName(0, "addr");
+ writeProfile->setLocalName(1, "size");
+
+ // Create the function body
+ Builder builder(*wasm);
+ auto getAddr = [&]() { return builder.makeLocalGet(0, ptrType); };
+ auto getSize = [&]() { return builder.makeLocalGet(1, Type::i32); };
+ auto hashConst = [&]() { return builder.makeConst(int64_t(moduleHash)); };
+ auto profileSizeConst = [&]() {
+ return builder.makeConst(int32_t(profileSize));
+ };
+
// Write the hash followed by all the time stamps
Expression* writeData = builder.makeStore(
8, 0, 1, getAddr(), hashConst(), Type::i64, wasm->memories[0]->name);
diff --git a/test/lit/wasm-split/instrument-memory64.wast b/test/lit/wasm-split/instrument-memory64.wast
new file mode 100644
index 000000000..ec737b95f
--- /dev/null
+++ b/test/lit/wasm-split/instrument-memory64.wast
@@ -0,0 +1,49 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+
+;; Check that the instrumentation is correct when the output memory is 64-bit.
+
+;; RUN: wasm-split %s -all --instrument -S -o - | filecheck %s
+
+;; Check that the output round trips and validates as well
+;; RUN: wasm-split %s -all --instrument -g -o %t
+;; RUN: wasm-opt %t -all --print | filecheck %s
+
+(module
+ (import "env" "foo" (func $foo))
+ (export "bar" (func $bar))
+
+ (memory $mem i64 1 1)
+
+ (func $bar
+ (call $foo)
+ )
+ (func $baz (param i32) (result i32)
+ (local.get 0)
+ )
+)
+
+;; Check that the $addr parameter is an i64.
+
+;; CHECK: (func $__write_profile (type $2) (param $addr i64) (param $size i32) (result i32)
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.ge_u
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: (i32.const 16)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (i64.store align=1
+;; CHECK-NEXT: (local.get $addr)
+;; CHECK-NEXT: (i64.const {{.*}})
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store offset=8 align=1
+;; CHECK-NEXT: (local.get $addr)
+;; CHECK-NEXT: (global.get $bar_timestamp)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store offset=12 align=1
+;; CHECK-NEXT: (local.get $addr)
+;; CHECK-NEXT: (global.get $baz_timestamp)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 16)
+;; CHECK-NEXT: )