Skip to content

perf(ops): replace per-op generated slow metrics wrappers with shared dispatch#32889

Merged
bartlomieju merged 5 commits intomainfrom
opt/shared-slow-metrics-dispatch
Mar 25, 2026
Merged

perf(ops): replace per-op generated slow metrics wrappers with shared dispatch#32889
bartlomieju merged 5 commits intomainfrom
opt/shared-slow-metrics-dispatch

Conversation

@bartlomieju
Copy link
Copy Markdown
Member

Summary

  • Replace N per-op generated v8_fn_ptr_metrics functions with a single shared slow_metrics_dispatch wrapper in deno_core
  • Add slow_fn_impl: SlowFnImplRef field to OpDecl storing a function pointer to the op's implementation (returns status code for success/error detection)
  • OpDecl::new_internal_op2 now accepts slow_fn_impl instead of slow_fn_with_metrics, and automatically sets slow_fn_with_metrics to the shared wrapper
  • The non-metrics hot path (v8_fn_ptr) is completely unchanged — zero performance impact on normal op dispatch
  • ~460KB binary size reduction, -3075/+424 lines (most deletions are test snapshot updates)

Test plan

  • cargo check passes
  • cargo test -p deno_ops snapshot tests updated and passing
  • cargo test -p deno_core runtime::tests::ops::test_op_metrics passes
  • Benchmarked against clean main release build — no regression across performance.now(), atob(), btoa(), URL parse, TextEncoder.encode(), TextDecoder.decode()

🤖 Generated with Claude Code

bartlomieju and others added 4 commits March 21, 2026 11:27
…atch

Instead of generating a unique `v8_fn_ptr_metrics` function for every op,
use a single shared `slow_metrics_dispatch` function in deno_core that
calls the op's `slow_function_impl` via a function pointer stored in OpDecl.

The non-metrics hot path (`v8_fn_ptr`) is completely unchanged - zero
performance impact on normal op dispatch.

Changes:
- Add `slow_fn_impl: SlowFnImplRef` field to OpDecl storing a pointer to
  the op's implementation function
- Add `slow_metrics_dispatch` shared wrapper in ops_metrics.rs that
  extracts OpCtx, dispatches metrics events, and calls slow_fn_impl
- OpDecl::new_internal_op2 now accepts slow_fn_impl instead of
  slow_fn_with_metrics, and sets slow_fn_with_metrics to the shared wrapper
- Remove per-op `v8_fn_ptr_metrics` generation from dispatch_slow.rs
  and dispatch_async.rs
- Remove `slow_function_metrics` from GeneratorState

Result: ~460KB binary size reduction, no performance regression.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…h_slow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

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 optimizes op metrics codegen in deno_core by replacing per-op generated slow metrics wrappers with a single shared dispatch wrapper, reducing binary size and compile time while keeping the non-metrics dispatch hot path unchanged.

Changes:

  • Add slow_fn_impl to OpDecl and route slow-metrics dispatch through a shared slow_metrics_dispatch wrapper.
  • Update the op2 code generator to emit a slow_function_impl function pointer (status-code returning) instead of generating per-op v8_fn_ptr_metrics wrappers.
  • Update deno_ops snapshot test outputs to reflect the new generated code shape.

Reviewed changes

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

Show a summary per file
File Description
libs/core/extensions.rs Adds SlowFnImplRef and OpDecl::slow_fn_impl; wires slow_fn_with_metrics to shared wrapper.
libs/core/ops_metrics.rs Introduces shared slow_metrics_dispatch wrapper for slow op metrics dispatch.
libs/ops/op2/mod.rs Updates op2 codegen to pass slow_fn_impl instead of per-op metrics wrapper.
libs/ops/op2/generator_state.rs Removes generator state tracking for per-op slow metrics wrapper symbol.
libs/ops/op2/dispatch_slow.rs Stops generating per-op slow metrics wrapper; emits slow_function_impl with pointer signature.
libs/ops/op2/dispatch_async.rs Stops generating per-op async slow metrics wrapper; emits slow_function_impl with pointer signature.
libs/ops/op2/test_cases/sync/add.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/add_options.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/bigint.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/bool.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/bool_result.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/buffers.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/buffers_copy.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/buffers_out.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/cfg.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/clippy_allow.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/cppgc_resource.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/doc_comment.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/fast_alternative.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/from_v8.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/generics.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/nofast.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/object_wrap.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/op_state_rc.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/op_state_ref.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/result_external.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/result_primitive.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/result_scope.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/result_void.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/serde_v8.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/smi.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/stack_trace.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/stack_trace_scope.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/string_cow.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/string_onebyte.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/string_option_return.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/string_owned.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/string_ref.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/string_return.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/to_v8.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/v8_handlescope.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/v8_lifetime.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/v8_ref_option.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/v8_string.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/sync/webidl.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_arg_return.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_arg_return_result.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_cppgc.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_deferred.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_jsbuffer.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_lazy.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_op_metadata.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_opstate.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_precise_capture.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_result.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_result_impl.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_result_smi.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_stack_trace.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.
libs/ops/op2/test_cases/async/async_void.out Snapshot update for new slow_fn_impl + shared metrics wrapper model.

Comment thread libs/core/extensions.rs Outdated
Clarify that status code 2 means "deferred" for async ops (not error),
matching the actual behavior in slow_metrics_dispatch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bartlomieju bartlomieju merged commit fd3da5a into main Mar 25, 2026
112 checks passed
@bartlomieju bartlomieju deleted the opt/shared-slow-metrics-dispatch branch March 25, 2026 16:30
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.

2 participants