Skip to content

Publish record_slot_offset in otel_thread_ctx_nodejs_v1 - #421

Merged
szegedi merged 2 commits into
mainfrom
szegedi/record-slot-offset
Oct 2, 2026
Merged

szegedi merged 2 commits into
mainfrom
szegedi/record-slot-offset

Conversation

@szegedi

@szegedi szegedi commented Oct 1, 2026

Copy link
Copy Markdown

Bringing back an offset into the schema

Shortly after merging #417, @nsavoire found out that the offset for the record pointer in JSObject is variable: it is 24 bytes on Node.js 22, and 32 on Node.js 23+. (For those curious, this is the relevant V8 commit, released in V8 12.5.43. Node.js 22 ships with V8 12.4.x and Node.js 23 ships with V8 12.9.x.)

This means that we can't hardcode the value in a single schema that targets both Node.js 22 and 23+. We also can't "just" drop support for Node.js 22, since its EOL is not until April 2027, and regardless many libraries support Node.js versions for some time after their EOL.

This leaves us with just one option forward: have the writer publish at least this one offset somewhere the reader can find it. Instead of bringing back process context attributes, though, we decided to store the value in each thread's otel_thread_ctx_nodejs_v1 struct even though the value is the same for all threads. Since the struct's als_identity_hash field is four bytes long due to 8-alignment of the next field, there's conveniently another four bytes of padding after it. We're now repurposing one of these four bytes as uint8 record_slot_offset.

The value is to be interpreted as number of bytes in the offset (so expected values today are 24 and 32). This is somewhat redundant encoding, as the value is always at least 24, and always a multiple of 8, so we could've also used something a bit more compact such as "number of words above 3" which'd be 0 for 24, and 1 for 32. Or we could've also just treated it as a boolean flag! This form is more straightforward and it's at least possible to easier recognize garbage values. I also don't expect we'll ever need to use the maximum effective value of 248…

undefined_addr fix

While discussing this it was pointed out that normally, undefined_addr also has the same value on every thread despite it being a per-isolate value. This is true 'cause isolates share a read-only heap for intrinsic values (if we're being pedantic, there's one build flag to turn it off on Node.js 22) but looking into this also highlighted that we weren't publishing the correct value. We were publishing reinterpret_cast<Address>(*v8::Undefined(isolate)) which gives the address of the isolate's roots-table slot that holds undefined, not undefined's tagged value. This is fixed as a separate small commit in this PR.

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

Overall package size

Self size: 2.61 MB
Deduped: 3.32 MB
No deduping: 3.32 MB

Dependency sizes | name | version | self size | total size | |------|---------|-----------|------------| | pprof-format | 2.3.1 | 504.33 kB | 504.33 kB | | source-map | 0.8.0 | 185.66 kB | 185.66 kB | | node-gyp-build | 4.8.4 | 13.86 kB | 13.86 kB |

🤖 This report was automatically generated by heaviest-objects-in-the-universe

@szegedi szegedi added the semver-minor Usually minor non-breaking improvements label Oct 1, 2026
@szegedi
szegedi merged commit b103f38 into main Oct 2, 2026
70 checks passed
@szegedi
szegedi deleted the szegedi/record-slot-offset branch October 2, 2026 13:41
gh-worker-dd-mergequeue-cf854d Bot pushed a commit to DataDog/datadog-agent that referenced this pull request Oct 2, 2026
…ct (#57373)

### What does this PR do?

Reads the JSObject record slot offset from the per-thread `otel_thread_ctx_nodejs_v1` discovery struct, instead of hardcoding it, and drops the unused offset attributes from the test writer.

### Motivation

The offset is 24 bytes on Node.js 22 and 32 on Node.js 23+, so the writer now publishes it per thread (DataDog/pprof-nodejs#421).

Co-authored-by: daniel.mercier <daniel.mercier@datadoghq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver-minor Usually minor non-breaking improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants