Skip to content

Inline cbor_incref and cbor_decref fast paths#434

Open
PJK wants to merge 3 commits into
masterfrom
inline-refcount-hot-path
Open

Inline cbor_incref and cbor_decref fast paths#434
PJK wants to merge 3 commits into
masterfrom
inline-refcount-hot-path

Conversation

@PJK

@PJK PJK commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

Move the reference-counting hot path (increment; decrement + zero check) into static inline definitions in cbor/common.h. The deallocation branch of cbor_decref stays 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_allocs arena), 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_EXPORT extern declarations to static inline in the public header removes cbor_incref and cbor_decref from the shared library's exported symbol table. That is technically an ABI change:

  • Existing binaries linked against an older libcbor.so continue to work (they carry their own extern resolution).
  • Binaries compiled against the new header cannot be re-linked against an older libcbor.so.
  • Consumers using dlsym(\"cbor_incref\") / dlsym(\"cbor_decref\") would break.

If ABI compatibility matters, an alternative is C99 inline + extern inline in common.c, which keeps the exported symbols alive. Happy to reshape into that form.

Test plan

  • All 28 existing ctest suites pass
  • CI green

🤖 Generated with Claude Code

PJK and others added 3 commits July 19, 2026 00:45
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>
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>
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.

1 participant