Skip to content

Improve refcount for unique continuations #863

Open
TimWhiting wants to merge 1 commit intokoka-lang:devfrom
TimWhiting:improve-continuation-refcount
Open

Improve refcount for unique continuations #863
TimWhiting wants to merge 1 commit intokoka-lang:devfrom
TimWhiting:improve-continuation-refcount

Conversation

@TimWhiting
Copy link
Copy Markdown
Collaborator

Fixes #854, and addresses a few todos.
@daanx

Copilot AI review requested due to automatic review settings January 25, 2026 03:01
Comment thread lib/std/core/hnd.kk Outdated
@TimWhiting TimWhiting force-pushed the improve-continuation-refcount branch from aa5b101 to afc2c13 Compare January 25, 2026 03:03
@TimWhiting TimWhiting force-pushed the improve-continuation-refcount branch from afc2c13 to 1cb40e8 Compare January 25, 2026 03:04
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines continuation handling and reference counting for control handlers, specifically optimizing behavior when continuations are unique, and adds a regression test around refcounts. It addresses the leaked or stuck reference counts seen with complex effects (e.g., async) by improving how composed continuations and finalization prompts are managed.

Changes:

  • Optimize kcompose in lib/std/core/inline/hnd.c to detect unique continuation blocks and avoid unnecessary dup/drop operations, with tailored handling when yielding.
  • Rework the protect/protect2 logic in lib/std/core/hnd.kk to track finalization state via a new protect-state type and a new unsafe-st2 helper, improving correctness for resumptions and finalization under effects.
  • Add test/cgen/simple-refcount.kk (and .kk.out) to validate simple refcount behavior around a custom ctl effect and resumption pattern.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
lib/std/core/inline/hnd.c Adds uniqueness-aware path in kcompose to optimize composed continuation invocation and yielding.
lib/std/core/hnd.kk Introduces protect-state and unsafe-st2, and rewrites protect / protect2 / protect-prompt to correctly manage finalization and resumptions with effects.
test/cgen/simple-refcount.kk / .kk.out New cgen test verifying refcount evolution for a boxed value across effectful resumptions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/std/core/hnd.kk
@TimWhiting
Copy link
Copy Markdown
Collaborator Author

TimWhiting commented Feb 24, 2026

I ran the benchmarks from here: https://github.com/effect-handlers/effect-handlers-bench:

There are slight improvements in:

  • nqueens: ~6%
  • generator/tree_explore: ~10.5%
  • resume_nontail: ~24%

Everything else is roughly equal and within variation from multiple runs I did.

Old:

command,mean,stddev,median,user,system,min,max
countdown/main 200000000,1.2216245841200002,0.013097457960270271,1.2170492882200001,1.2134481199999998,0.0047678,1.20872678772,1.25088287172
fibonacci_recursive/main 42,0.92421362602,0.009763783503512343,0.92031885122,0.9161674200000001,0.0042211,0.9134147467200001,0.9404233717200001
product_early/main 100000,1.3867592175199999,0.0304284327448526,1.37119780922,1.3794159199999998,0.0049787,1.35771262172,1.44621662172
iterator/main 40000000,0.165431218095,0.007390034056625232,0.16279237172,0.15923437,0.0022573625000000003,0.15822895472,0.18062316372
nqueens/main 12,1.1569119590199999,0.017909991041971343,1.15707007972,1.1479616199999998,0.004852799999999999,1.13427649672,1.1834659547200002
generator/main 25,5.7108088426200005,0.07435528029232083,5.71386903872,5.68219942,0.014105600000000001,5.55519399672,5.82056137172
tree_explore/main 16,0.19325579672,0.001078928400741546,0.19339541372,0.19085892000000002,0.0014779666666666666,0.19167212172,0.19593866272
triples/main 300 300,0.8743085257200001,0.0068642368323112105,0.8727008712200002,0.8700542199999999,0.0025719000000000002,0.8651514967200001,0.8840237467200001
parsing_dollars/main 20000,1.82072437592,0.004804321725366059,1.8187204552200003,1.81371392,0.004718000000000001,1.8146368297200002,1.83010133072
resume_nontail/main 20000,1.91535725102,0.007202490545974237,1.9139477467200001,1.9084864199999998,0.0044865,1.90591020472,1.92681853872
handler_sieve/main 60000,2.70993834242,0.03705139933226507,2.71244768422,2.6999992199999996,0.006494,2.66178566272,2.7925084547199996

New:

command,mean,stddev,median,user,system,min,max
countdown/main 200000000,1.2312289023800003,0.0061499745787337535,1.22874679838,1.2249821199999997,0.00403104,1.2245549018800002,1.2417574448800002
fibonacci_recursive/main 42,0.95989003598,0.011211520612998738,0.9594421103799999,0.95143202,0.00473814,0.94594815288,0.97980498588
product_early/main 100000,1.4064860191800004,0.017392783664945167,1.40584848638,1.3975502199999998,0.00568144,1.38559302688,1.4490656938800002
iterator/main 40000000,0.15521384551157894,0.0008896818988581859,0.15497898588,0.15272484631578948,0.0013665505263157894,0.15430290288,0.15742473588
nqueens/main 12,1.08314209418,0.006838441225641589,1.08064050638,1.0773020199999999,0.0036328399999999996,1.07480056988,1.09845361088
generator/main 25,5.11096174408,0.0395463510170471,5.10337152738,5.086660519999999,0.01659444,5.06295198588,5.17069323588
tree_explore/main 16,0.1726601770564706,0.0016844145028007576,0.17251623588,0.16973302588235295,0.0016064576470588236,0.17055256888,0.17756581888
triples/main 300 300,0.75250363178,0.00578785742406358,0.75097075688,0.7477755199999999,0.00307514,0.74416244388,0.76534673588
parsing_dollars/main 20000,1.8222293193800003,0.004684792777568356,1.8222978818800002,1.8132483199999996,0.0060284399999999995,1.8152147358800002,1.8296958198800002
resume_nontail/main 20000,1.45199178978,0.006093713514123297,1.4520157978800001,1.44437892,0.00481684,1.4406204858800002,1.4619268608800002
handler_sieve/main 60000,2.72472791088,0.044018776042209384,2.71512896488,2.71188212,0.00880684,2.68808611088,2.83538506988

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reference count never goes to 0 with complex effect (async)?

2 participants