Inline cbor_incref and cbor_decref fast paths#434
Open
PJK wants to merge 3 commits into
Open
Conversation
Move the refcount hot path (increment; decrement + zero check) into static inline definitions in the public common.h. The free branch of cbor_decref stays out of line as _cbor_decref_free, called from the inline once refcount hits zero. For typical DOM-building workloads (build tree, serialize, drop), every construction touches an incref/decref that previously crossed a function-call boundary. Inlining removes that overhead at every call site — including libcbor's own internal recursion in the free branch — without changing semantics. Note: switching to static inline in the header changes ABI for consumers that dlsym cbor_incref/cbor_decref out of the shared library. All 28 existing ctest suites pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Expand the Doxygen comments on cbor_incref, cbor_decref, and the new _cbor_decref_free helper to briefly explain the inlining rationale. Add a Next-release changelog entry marking this as ABI BREAKING — same signatures, but cbor_incref and cbor_decref are no longer exported from the shared library. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 task
PJK
added a commit
that referenced
this pull request
Jul 19, 2026
…#435) * Bump codecov orb to v5.0.3 The old 3.2.2 orb ships a Bash-based uploader whose "Validate Codecov Uploader" step fetches a GPG key from a Codecov URL that now returns non-PGP data (32 bytes, no valid OpenPGP), failing the coverage step on every CI run. v5 uses the codecovcli-based uploader and does not perform that validation. Refs: #434 (CI failure surfaced there, unrelated to the PR). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Replace codecov orb with direct codecovcli invocation Both v3 and v5 of the codecov CircleCI orb wrap the CLI download with a GPG signature verification step, and Codecov's PGP key URL now returns 32 bytes of non-PGP data, causing every coverage run to fail. Install the codecov CLI directly via pip and run upload-process. Fall back to true on non-zero exit so a Codecov infra outage does not break CI — coverage is best-effort. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Move the reference-counting hot path (increment; decrement + zero check) into
static inlinedefinitions incbor/common.h. The deallocation branch ofcbor_decrefstays out of line as_cbor_decref_free, called from the inline once refcount hits zero.For DOM-building workloads — every construction touches an incref/decref that previously crossed a function-call boundary. Inlining removes that overhead at every call site, including libcbor's own internal recursion in the free branch.
Perf context
Measured on the GLD serializer benchmark (default matrix, N=100). Combined with two wrapper-side fixes (narrowest-width integer builders +
cbor_set_allocsarena), the DOM path goes from being the slowest CBOR encoder in the published chart to competitive with tinycbor. This library change contributes roughly the first ~1.3–1.5× of that speedup on its own; the rest comes from the wrapper. Sizes are unaffected.Caveats
Switching from
CBOR_EXPORTextern declarations tostatic inlinein the public header removescbor_increfandcbor_decreffrom the shared library's exported symbol table. That is technically an ABI change:libcbor.socontinue to work (they carry their own extern resolution).libcbor.so.dlsym(\"cbor_incref\")/dlsym(\"cbor_decref\")would break.If ABI compatibility matters, an alternative is C99
inline+extern inlineincommon.c, which keeps the exported symbols alive. Happy to reshape into that form.Test plan
🤖 Generated with Claude Code