From 68f387a40d697570712dc6dec7ba34ddd25759d3 Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Tue, 6 Dec 2022 15:58:00 +0000 Subject: [PATCH] hotfix: suppress GC in heartbeat (#3623) Mainnet doesn't yet support DTS for `canister_heartbeat` yet, so a long GC may fail to complete when it would in an ordinary message supporting DTS. This PR suppresses the GC call, leaving it to the already scheduled async message executing Motoko `system` function `heartbeat`, which will run with DTS enabled, avoiding the issue (and a potential space leak). #3622 tracks the need to revert this hack once IC heartbeats support DTS. --- Changelog.md | 7 +++++-- src/codegen/compile.ml | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index e31f871d150..10870ca6720 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,11 +2,14 @@ * motoko (`moc`) + * Suppress GC during IC `canister_heartbeat`, deferring any GC to the scheduled Motoko `heartbeat` `system` method (#3623). + This is a temporary workaround, to be removed once DTS is supported for `canister_heartbeat` itself (#3622). + * Add a new _generational_ GC, enabled with new moc flag `--generational-gc` (#3495). The generational garbage collector optimizes for fast reclamation of short-lived objects. - New objects are allocated in a young generation that is more frequently collected than the older objects + New objects are allocated in a young generation that is more frequently collected than the older objects that have already survived a GC run. - + For many cases, the generational GC is more efficient than the existing compacting GC and copying GCs: * Lower runtimes: Less number of executed instructions on average. * Shorter interruptions: Young generation collection entails shorter program interruptions. diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 8855cc81a37..41cc5d11a5a 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -3894,7 +3894,11 @@ module IC = struct let fi = E.add_fun env "canister_heartbeat" (Func.of_body env [] [] (fun env -> G.i (Call (nr (E.built_in env "heartbeat_exp"))) ^^ - GC.collect_garbage env)) + (* TODO(3622) + Until DTS is implemented for heartbeats, don't collect garbage here, + just record mutator_instructions and leave GC scheduling to the + already sheduled async message running `system` function `heartbeat` *) + GC.record_mutator_instructions env (* future: GC.collect_garbage env *))) in E.add_export env (nr { name = Wasm.Utf8.decode "canister_heartbeat";