From e0971b12e44525f21d6dfb84821a167ceac6d6ed Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Mon, 22 Jun 2026 12:14:28 +0000 Subject: [PATCH 1/6] use dmt, disable direct stable page charging --- rs/config/src/subnet_config.rs | 2 +- .../src/wasm_utils/system_api_replacements.rs | 30 ------------------- rs/embedders/src/wasmtime_embedder.rs | 11 ++++--- rs/embedders/tests/wasmtime_embedder.rs | 4 ++- 4 files changed, 11 insertions(+), 36 deletions(-) diff --git a/rs/config/src/subnet_config.rs b/rs/config/src/subnet_config.rs index 9e5021d0d01c..ac1a2cd50897 100644 --- a/rs/config/src/subnet_config.rs +++ b/rs/config/src/subnet_config.rs @@ -165,7 +165,7 @@ pub const DEFAULT_REFERENCE_SUBNET_SIZE: usize = 13; pub const SEV_REFERENCE_SUBNET_SIZE: usize = 7; /// Costs for each newly created dirty page in stable memory. -const DEFAULT_DIRTY_PAGE_OVERHEAD: NumInstructions = NumInstructions::new(1_000); +const DEFAULT_DIRTY_PAGE_OVERHEAD: NumInstructions = NumInstructions::new(5_000); /// Accumulated priority reset interval, rounds. /// diff --git a/rs/embedders/src/wasm_utils/system_api_replacements.rs b/rs/embedders/src/wasm_utils/system_api_replacements.rs index 1fb1242c10b5..285c541e1bf0 100644 --- a/rs/embedders/src/wasm_utils/system_api_replacements.rs +++ b/rs/embedders/src/wasm_utils/system_api_replacements.rs @@ -912,21 +912,6 @@ pub(super) fn replacement_functions( function_index: injected_functions.internal_trap, }, End, - // Decrement instruction counter to charge for dirty pages - LocalGet { - local_index: DIRTY_PAGE_COUNT, - }, - I64ExtendI32U, - I64Const { - value: dirty_page_overhead.get().try_into().unwrap(), - }, - I64Mul, - // Bounds check above should guarantee that we don't - // overflow as the over head is a small constant. - Call { - function_index: decr_instruction_counter_fn, - }, - Drop, // perform memory fill LocalGet { local_index: BYTEMAP_START, @@ -1155,21 +1140,6 @@ pub(super) fn replacement_functions( function_index: injected_functions.internal_trap, }, End, - // Decrement instruction counter to charge for dirty pages - LocalGet { - local_index: DIRTY_PAGE_COUNT, - }, - I64ExtendI32U, - I64Const { - value: dirty_page_overhead.get().try_into().unwrap(), - }, - I64Mul, - // Bounds check above should guarantee that we don't - // overflow as the over head is a small constant. - Call { - function_index: decr_instruction_counter_fn, - }, - Drop, // perform memory fill LocalGet { local_index: BYTEMAP_START, diff --git a/rs/embedders/src/wasmtime_embedder.rs b/rs/embedders/src/wasmtime_embedder.rs index f74097c71a1e..369741e51634 100644 --- a/rs/embedders/src/wasmtime_embedder.rs +++ b/rs/embedders/src/wasmtime_embedder.rs @@ -415,9 +415,12 @@ impl WasmtimeEmbedder { bytemap_name: Some(STABLE_BYTEMAP_MEMORY_NAME), memory: stable_memory.clone(), memory_type: CanisterMemoryType::Stable, - // Wasm native stable memory will always be tracked by a - // bytemap within the wasm module. - dirty_page_tracking: DirtyPageTracking::Ignore, + // Wasm native stable memory is tracked by a + // bytemap within the wasm module, but that's used + // only for limiting the memory. The deterministic + // memory tracker accounts for page fault charging, + // same as for the heap pages. + dirty_page_tracking, }); result @@ -652,7 +655,7 @@ impl WasmtimeEmbedder { &mut *store, self.log.clone(), self.config.feature_flags.deterministic_memory_tracker, - /*dirty_page_overhead*/ NumInstructions::new(1), + self.config.dirty_page_overhead, subtract_instruction_counter, ); diff --git a/rs/embedders/tests/wasmtime_embedder.rs b/rs/embedders/tests/wasmtime_embedder.rs index 53ff0a8ecd68..ff06d47bad78 100644 --- a/rs/embedders/tests/wasmtime_embedder.rs +++ b/rs/embedders/tests/wasmtime_embedder.rs @@ -3798,7 +3798,10 @@ fn run_wasm_and_get_instructions_used( wat: &str, use_deterministic_tracker: bool, ) -> NumInstructions { + let mut config = Config::default(); + config.dirty_page_overhead = NumInstructions::new(1); let mut instance = WasmtimeInstanceBuilder::new() + .with_config(config) .with_deterministic_memory_tracker_enabled(use_deterministic_tracker) .with_wat(wat) .with_api_type(ApiType::update( @@ -3830,7 +3833,6 @@ fn assert_deterministic_charges_extra( ) { let prefetching_instructions = run_wasm_and_get_instructions_used(wat, false); let deterministic_instructions = run_wasm_and_get_instructions_used(wat, true); - assert_eq!( deterministic_instructions.get() - prefetching_instructions.get(), expected_extra_instructions, From 855f8fb44d6413531f9beb533e968e1f28b38545 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Mon, 22 Jun 2026 14:01:43 +0000 Subject: [PATCH 2/6] fix memory write tests --- rs/config/src/subnet_config.rs | 2 +- rs/embedders/BUILD.bazel | 1 + rs/embedders/Cargo.toml | 1 + .../tests/wasmtime_random_memory_writes.rs | 43 +++++++++---------- rs/memory_tracker/src/deterministic.rs | 12 ++++++ 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/rs/config/src/subnet_config.rs b/rs/config/src/subnet_config.rs index ac1a2cd50897..28d7a523b084 100644 --- a/rs/config/src/subnet_config.rs +++ b/rs/config/src/subnet_config.rs @@ -165,7 +165,7 @@ pub const DEFAULT_REFERENCE_SUBNET_SIZE: usize = 13; pub const SEV_REFERENCE_SUBNET_SIZE: usize = 7; /// Costs for each newly created dirty page in stable memory. -const DEFAULT_DIRTY_PAGE_OVERHEAD: NumInstructions = NumInstructions::new(5_000); +pub const DEFAULT_DIRTY_PAGE_OVERHEAD: NumInstructions = NumInstructions::new(5_000); /// Accumulated priority reset interval, rounds. /// diff --git a/rs/embedders/BUILD.bazel b/rs/embedders/BUILD.bazel index bdb446fa26e1..0482ff920195 100644 --- a/rs/embedders/BUILD.bazel +++ b/rs/embedders/BUILD.bazel @@ -92,6 +92,7 @@ rust_test( crate = ":embedders", deps = [ # Keep sorted. + "//rs/config", "//rs/interfaces", "//rs/test_utilities", "//rs/test_utilities/types", diff --git a/rs/embedders/Cargo.toml b/rs/embedders/Cargo.toml index 39b6fbb1e9a5..77acc7815465 100644 --- a/rs/embedders/Cargo.toml +++ b/rs/embedders/Cargo.toml @@ -68,6 +68,7 @@ assert_matches = { workspace = true } canister-test = { path = "../rust_canisters/canister_test" } criterion = { workspace = true } embedders_bench = { path = "benches/embedders_bench" } +ic-config = {path = "../config"} ic-registry-routing-table = { path = "../registry/routing_table" } ic-test-utilities = { path = "../test_utilities" } ic-test-utilities-embedders = { path = "../test_utilities/embedders" } diff --git a/rs/embedders/tests/wasmtime_random_memory_writes.rs b/rs/embedders/tests/wasmtime_random_memory_writes.rs index a87065bccf21..89af9b9cfe86 100644 --- a/rs/embedders/tests/wasmtime_random_memory_writes.rs +++ b/rs/embedders/tests/wasmtime_random_memory_writes.rs @@ -1,6 +1,7 @@ use ic_config::{ - embedders::Config as EmbeddersConfig, execution_environment::Config as HypervisorConfig, - subnet_config::SchedulerConfig, + embedders::Config as EmbeddersConfig, + execution_environment::Config as HypervisorConfig, + subnet_config::{DEFAULT_DIRTY_PAGE_OVERHEAD, SchedulerConfig}, }; use ic_cycles_account_manager::{CyclesAccountManagerSubnetConfig, ResourceSaturation}; use ic_embedders::{ @@ -58,7 +59,7 @@ fn dsm_charge_per_wasm_page() -> u64 { .deterministic_memory_tracker == FlagStatus::Enabled { - OS_PAGES_PER_WASM_PAGE as u64 + OS_PAGES_PER_WASM_PAGE as u64 * DEFAULT_DIRTY_PAGE_OVERHEAD.get() } else { 0 } @@ -763,7 +764,7 @@ mod tests { // Set maximum number of instructions to some low value to trap // Note: system API calls get charged per call, see system_api::charges - let max_num_instructions = NumInstructions::new(10_000); + let max_num_instructions = NumInstructions::new(200_000); // Consumes less than max_num_instructions. let instructions_consumed_without_data = get_num_instructions_consumed( @@ -924,9 +925,7 @@ mod tests { + ic_embedders::wasmtime_embedder::system_api_complexity::overhead::STABLE_WRITE .get() + STABLE_OP_BYTES - + SchedulerConfig::application_subnet() - .dirty_page_overhead - .get() + + dsm_charge_per_wasm_page() + dsm_charge_per_wasm_page() + dsm_charge_per_wasm_page() ); } @@ -949,7 +948,7 @@ mod tests { + ic_embedders::wasmtime_embedder::system_api_complexity::overhead::STABLE_WRITE .get() + STABLE_OP_BYTES - + SchedulerConfig::system_subnet().dirty_page_overhead.get() + + dsm_charge_per_wasm_page() + dsm_charge_per_wasm_page() + dsm_charge_per_wasm_page() ); } @@ -973,9 +972,7 @@ mod tests { + ic_embedders::wasmtime_embedder::system_api_complexity::overhead::STABLE_WRITE .get() + STABLE_OP_BYTES - + SchedulerConfig::application_subnet() - .dirty_page_overhead - .get() + + dsm_charge_per_wasm_page() + dsm_charge_per_wasm_page() + dsm_charge_per_wasm_page() ); } @@ -998,7 +995,7 @@ mod tests { + ic_embedders::wasmtime_embedder::system_api_complexity::overhead::STABLE_WRITE .get() + STABLE_OP_BYTES - + SchedulerConfig::system_subnet().dirty_page_overhead.get() + + dsm_charge_per_wasm_page() + dsm_charge_per_wasm_page() + dsm_charge_per_wasm_page() ); } @@ -1075,12 +1072,13 @@ mod tests { let dirty_heap = run_stats.wasm_dirty_pages.len() as u64; let consumed_instructions = consumed_instructions - instructions_consumed_without_data; + let incremental_tracker = + tracker_charge(&instance_stats).saturating_sub(dry_run_tracker); + let incremental_dirty = + dirty_heap.saturating_sub(dry_run_dirty_heap) * dirty_heap_cost; assert_eq!( - (consumed_instructions.get() - - dirty_heap * dirty_heap_cost - - tracker_charge(&instance_stats)) as usize, - (payload_size / BYTES_PER_INSTRUCTION) - - (dry_run_dirty_heap * dirty_heap_cost + dry_run_tracker) as usize, + consumed_instructions.get() - incremental_dirty - incremental_tracker, + payload_size as u64 / BYTES_PER_INSTRUCTION as u64, ); } @@ -1097,13 +1095,14 @@ mod tests { let dirty_heap = run_stats.wasm_dirty_pages.len() as u64; let consumed_instructions = consumed_instructions - instructions_consumed_without_data; + let incremental_tracker = + tracker_charge(&instance_stats).saturating_sub(dry_run_tracker); + let incremental_dirty = + dirty_heap.saturating_sub(dry_run_dirty_heap) * dirty_heap_cost; assert_eq!( - (consumed_instructions.get() - - dirty_heap * dirty_heap_cost - - tracker_charge(&instance_stats)) as usize, - (2 * payload_size / BYTES_PER_INSTRUCTION) - - (dry_run_dirty_heap * dirty_heap_cost + dry_run_tracker) as usize + consumed_instructions.get() - incremental_dirty - incremental_tracker, + 2 * payload_size as u64 / BYTES_PER_INSTRUCTION as u64, ); } }) diff --git a/rs/memory_tracker/src/deterministic.rs b/rs/memory_tracker/src/deterministic.rs index 3d58ca1a7a64..5442f2ae5a1c 100644 --- a/rs/memory_tracker/src/deterministic.rs +++ b/rs/memory_tracker/src/deterministic.rs @@ -353,6 +353,12 @@ impl DeterministicMemoryTracker { } // Charge instructions per OS page accessed. + println!( + "DMT charging for {} pages accessed @ {} = {}", + num_os_pages, + self.page_overhead, + num_os_pages * self.page_overhead + ); (self.subtract_instruction_counter.lock())(num_os_pages * self.page_overhead); } @@ -363,6 +369,12 @@ impl DeterministicMemoryTracker { let os_page_range = Range::from_wasm_page_idx(wasm_page_idx); let num_os_pages = os_page_range.end.get() - os_page_range.start.get(); + println!( + "DMT charging for {} pages dirtied @ {} = {}", + num_os_pages, + self.page_overhead, + num_os_pages * self.page_overhead + ); (self.subtract_instruction_counter.lock())(num_os_pages * self.page_overhead); } From b5944479edd7ffcc9959d0d241a71a04a6940268 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Mon, 22 Jun 2026 15:34:48 +0000 Subject: [PATCH 3/6] wip --- rs/embedders/tests/instrumentation.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/rs/embedders/tests/instrumentation.rs b/rs/embedders/tests/instrumentation.rs index e3857b8c1e1a..0259d59e93d1 100644 --- a/rs/embedders/tests/instrumentation.rs +++ b/rs/embedders/tests/instrumentation.rs @@ -1,6 +1,6 @@ use ic_config::embedders::{Config as EmbeddersConfig, MeteringType}; use ic_config::flag_status::FlagStatus; -use ic_config::subnet_config::SchedulerConfig; +use ic_config::subnet_config::{DEFAULT_DIRTY_PAGE_OVERHEAD, SchedulerConfig}; use ic_embedders::wasm_utils; use ic_embedders::{ WasmtimeEmbedder, @@ -287,9 +287,7 @@ fn instr_used(instance: &mut WasmtimeInstance) -> u64 { /// - `n_heap_wasm_pages`: pages first *written* on the heap. /// Each triggers `mark_wasm_page_accessed` + `mark_wasm_page_dirty`: /// 2 × (WASM_PAGE_SIZE / OS_PAGE_SIZE) = 2 × 16 = 32 instructions. -/// - `n_stable_wasm_pages`: pages first *accessed* in stable memory. -/// Stable memory uses `DirtyPageTracking::Ignore`, so only -/// `mark_wasm_page_accessed` fires: 16 instructions per page. +/// - `n_stable_wasm_pages`: same as for heap: 32 instructions per page. /// /// Returns 0 when the deterministic memory tracker is disabled. fn deterministic_tracker_overhead(n_heap_wasm_pages: u64, n_stable_wasm_pages: u64) -> u64 { @@ -300,7 +298,7 @@ fn deterministic_tracker_overhead(n_heap_wasm_pages: u64, n_stable_wasm_pages: u { let os_pages_per_wasm_page = (WASM_PAGE_SIZE_IN_BYTES / PAGE_SIZE) as u64; n_heap_wasm_pages * 2 * os_pages_per_wasm_page - + n_stable_wasm_pages * os_pages_per_wasm_page + + n_stable_wasm_pages * 2 * os_pages_per_wasm_page } else { 0 } @@ -813,23 +811,20 @@ fn run_charge_for_dirty_heap(wasm_memory_type: WasmMemoryType) { }, wasm_memory_type, ); - let mut cd = SchedulerConfig::application_subnet() + let cd = SchedulerConfig::application_subnet() .dirty_page_overhead .get(); - if let WasmMemoryType::Wasm64 = wasm_memory_type { - cd *= EmbeddersConfig::default().wasm64_dirty_page_overhead_multiplier; - } - // Both stores target Wasm page 0 (bytes 0 and 4096 are within the 64KB page), // so only one heap page-first-write event occurs. let overhead = deterministic_tracker_overhead(1, 0); + let dirty_page_overhead = DEFAULT_DIRTY_PAGE_OVERHEAD.get(); let instructions_used = instr_used(&mut instance); // Function is 1 instruction. assert_eq!( instructions_used, - 1 + 5 * cc + cg + 2 * cs + cl + 2 * cd + overhead + 1 + 5 * cc + cg + 2 * cs + cl + 2 * cd + overhead * dirty_page_overhead ); // Now run the same with insufficient instructions @@ -1170,7 +1165,8 @@ fn metering_wasm64_load_store_canister() { (memory i64 1000) )"#; - let embedder_config = EmbeddersConfig::default(); + let mut embedder_config = EmbeddersConfig::default(); + // embedder_config.dirty_page_overhead = NumInstructions::new(1); let mut instance = WasmtimeInstanceBuilder::new() .with_config(embedder_config) @@ -1224,6 +1220,7 @@ fn metering_wasm64_load_store_canister() { // Both stores hit Wasm page 0 (bytes 0 and 4096 are within the 64KB page), // so only one heap page-first-write event occurs. let overhead = deterministic_tracker_overhead(1, 0); + println!("overhead {}", overhead); let total_cost = 1 + 2 * const_0 + const_17 + const_117 + const_4096 + 2 * store + load + drop + overhead; assert_eq!(instr_used_wasm64, total_cost); From afa958bb3343bbbe110b38ed43180977d07225de Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 23 Jun 2026 13:42:56 +0000 Subject: [PATCH 4/6] remove multiplier --- rs/config/src/embedders.rs | 7 ------- rs/embedders/src/wasmtime_embedder.rs | 8 +------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/rs/config/src/embedders.rs b/rs/config/src/embedders.rs index 167c0bfabbdb..2d65862bddcc 100644 --- a/rs/config/src/embedders.rs +++ b/rs/config/src/embedders.rs @@ -86,9 +86,6 @@ pub(crate) const DEFAULT_MAX_DIRTY_PAGES_WITHOUT_OPTIMIZATION: usize = (GIB as u /// Scheduling overhead for copying dirty pages, in instructions. pub(crate) const DIRTY_PAGE_COPY_OVERHEAD: NumInstructions = NumInstructions::new(3_000); -/// The overhead for dirty pages in Wasm64. -pub const WASM64_DIRTY_PAGE_OVERHEAD_MULTIPLIER: u64 = 4; - const KIB: u64 = 1024; const GIB: u64 = KIB * KIB * KIB; @@ -245,9 +242,6 @@ pub struct Config { /// The dirty page copying overhead, in instructions. pub dirty_page_copy_overhead: NumInstructions, - /// The dirty page overhead factor for Wasm64. - pub wasm64_dirty_page_overhead_multiplier: u64, - /// The maximum allowed size for an uncompressed canister Wasm module. pub wasm_max_size: NumBytes, @@ -298,7 +292,6 @@ impl Config { max_wasm_memory_size: NumBytes::new(MAX_WASM_MEMORY_IN_BYTES), max_wasm64_memory_size: NumBytes::new(MAX_WASM64_MEMORY_IN_BYTES), max_stable_memory_size: NumBytes::new(MAX_STABLE_MEMORY_IN_BYTES), - wasm64_dirty_page_overhead_multiplier: WASM64_DIRTY_PAGE_OVERHEAD_MULTIPLIER, } } } diff --git a/rs/embedders/src/wasmtime_embedder.rs b/rs/embedders/src/wasmtime_embedder.rs index 369741e51634..7b656673ab27 100644 --- a/rs/embedders/src/wasmtime_embedder.rs +++ b/rs/embedders/src/wasmtime_embedder.rs @@ -642,13 +642,7 @@ impl WasmtimeEmbedder { main_memory_type = WasmMemoryType::Wasm64; } - let dirty_page_overhead = match main_memory_type { - WasmMemoryType::Wasm32 => self.config.dirty_page_overhead, - WasmMemoryType::Wasm64 => NumInstructions::from( - self.config.dirty_page_overhead.get() - * self.config.wasm64_dirty_page_overhead_multiplier, - ), - }; + let dirty_page_overhead = self.config.dirty_page_overhead; let memory_trackers = sigsegv_memory_tracker( memories, From 5def612cb608d2647c367c6e6dd29d1ff29a4d49 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 23 Jun 2026 15:12:48 +0000 Subject: [PATCH 5/6] adjust costs --- .../benches/system_api/execute_update.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rs/execution_environment/benches/system_api/execute_update.rs b/rs/execution_environment/benches/system_api/execute_update.rs index 33df015ffd46..48e92a9ec317 100644 --- a/rs/execution_environment/benches/system_api/execute_update.rs +++ b/rs/execution_environment/benches/system_api/execute_update.rs @@ -372,7 +372,7 @@ pub fn execute_update_bench(c: &mut Criterion) { Result::No, Wasm64::Enabled, ), // 10B max - 529004006 + common::deterministic_tracker_write_overhead(1), + 529001006 + common::deterministic_tracker_write_overhead(1), ), common::Benchmark( "wasm32/ic0_debug_print()/1B".into(), @@ -786,7 +786,7 @@ pub fn execute_update_bench(c: &mut Criterion) { Result::No, Wasm64::Enabled, ), - 517004006 + common::deterministic_tracker_write_overhead(1), + 517001006 + common::deterministic_tracker_write_overhead(1), ), common::Benchmark( "wasm32/ic0_msg_cycles_available()".into(), @@ -936,7 +936,7 @@ pub fn execute_update_bench(c: &mut Criterion) { Result::No, Wasm64::Enabled, ), - 19004006 + common::deterministic_tracker_write_overhead(1), + 19001006 + common::deterministic_tracker_write_overhead(1), ), common::Benchmark( "wasm32/ic0_is_controller()".into(), @@ -1026,7 +1026,7 @@ pub fn execute_update_bench(c: &mut Criterion) { Result::No, Wasm64::Enabled, ), - 519004006 + common::deterministic_tracker_write_overhead(1), + 519001006 + common::deterministic_tracker_write_overhead(1), ), common::Benchmark( "wasm32/ic0_cost_create_canister()".into(), @@ -1046,7 +1046,7 @@ pub fn execute_update_bench(c: &mut Criterion) { Result::No, Wasm64::Enabled, ), - 517004006 + common::deterministic_tracker_write_overhead(1), + 517001006 + common::deterministic_tracker_write_overhead(1), ), common::Benchmark( "wasm32/ic0_cost_http_request()".into(), @@ -1066,7 +1066,7 @@ pub fn execute_update_bench(c: &mut Criterion) { Result::No, Wasm64::Enabled, ), - 519004006 + common::deterministic_tracker_write_overhead(1), + 519001006 + common::deterministic_tracker_write_overhead(1), ), { let serialized_params = candid::encode_one(COST_HTTP_REQUEST_V2_PARAMS).unwrap(); @@ -1110,7 +1110,7 @@ pub fn execute_update_bench(c: &mut Criterion) { }, Wasm64::Enabled, ), - 10019004006 + common::deterministic_tracker_write_overhead(1), + 10019001006 + common::deterministic_tracker_write_overhead(1), ) }, common::Benchmark( From d1899fd8d9c31ad0f28203109fcd1b527bde2f1d Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Wed, 24 Jun 2026 11:52:46 +0000 Subject: [PATCH 6/6] wip tests --- rs/embedders/tests/instrumentation.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rs/embedders/tests/instrumentation.rs b/rs/embedders/tests/instrumentation.rs index 0259d59e93d1..5908e9d27383 100644 --- a/rs/embedders/tests/instrumentation.rs +++ b/rs/embedders/tests/instrumentation.rs @@ -867,7 +867,7 @@ fn run_charge_for_dirty_stable64_test() { (memory (export "memory") 10) )"#; - let mut instance = new_instance_for_stable_write(wat, 10000); + let mut instance = new_instance_for_stable_write(wat, 1_000_000); let res = instance.run(func_ref("test")).unwrap(); let g = &res.exported_globals; @@ -940,12 +940,12 @@ fn run_charge_for_dirty_stable64_test() { + csg + cc * 15 + cs * 2 - + cd * 3 + + cd + csw * 2 + csr + cl + cg - + overhead + + overhead * cd ); // Now run the same with insufficient instructions