Skip to content

Pass unions by value with the C ABI's register classes - #9693

Closed
aminmansuri wants to merge 8 commits into
jruby:jruby-10.0from
aminmansuri:fix-union-by-value-abi
Closed

aminmansuri wants to merge 8 commits into
jruby:jruby-10.0from
aminmansuri:fix-union-by-value-abi

Conversation

@aminmansuri

Copy link
Copy Markdown
Contributor

Fixes #9329.

Makes JRuby pass C unions by value the way a C compiler does.

Before, every 8-byte union went in an integer register, so a union of floats came back as garbage and a callback receiving one crashed the JVM.

Now the union's members decide the register class, on x86_64 and ARM64.

union_spec.rb and UnionTest.c match the ffi gem's March 2026 versions
without its JRuby skips; union_by_value_spec.rb adds mixed-class,
nested, oversize and callback shapes.
Pick the libffi filler from the union's leaves: the float type for a
homogeneous floating aggregate, per-eightbyte SSE/INTEGER cells on
SysV x86_64, an integer of the union's alignment otherwise.
@aminmansuri
aminmansuri marked this pull request as draft September 15, 2026 23:12
@aminmansuri

Copy link
Copy Markdown
Contributor Author

Still a work in progress. I'm going to run a few checks still.

A 4-aligned union whose cells differ in class, nested at offset 4, takes
the enclosing struct's eightbytes: (INTEGER, SSE) on SysV x86_64.
Argument, return and callback forms.
libffi merges the cells into eightbytes at the union's offset inside an
enclosing struct; a per-cell class is exact there and unchanged for a
union passed on its own.
No behaviour change: the one-argument newUnion hands the host platform
to the overload, which tests can call with any CPU and OS.
A union of one floating type is a floating-point aggregate on AArch64,
ARM, PPC64 ELFv2 and x86_64; riscv64, loongarch64 and s390x pass every
union in integer registers, so the integer filler must stay there.
riscv64, loongarch64 and s390x pass unions in integer registers while
libffi would put a struct of doubles into FP registers; keep the integer
filler there and the float one on AArch64, ARM, PPC64 ELFv2 and x86_64.
JRuby's FFI rejects :long_double layout members, so no union has a long
double leaf or an alignment of 16; the integer filler list is now what its name says.
@aminmansuri
aminmansuri marked this pull request as ready for review September 16, 2026 01:24
@aminmansuri

Copy link
Copy Markdown
Contributor Author

Ok.. added some improvements I think this'll do the trick.

@headius headius left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This appears to make sense but I want it to bake in jruby-head for a while. Please rebase to master and we can merge after the 10.1.2.0 release. Once it has been in the wild for a bit we can merge a backport to 10.0.

@headius headius added this to the JRuby 10.1.3.0 milestone Sep 16, 2026
@headius headius linked an issue Sep 16, 2026 that may be closed by this pull request
@aminmansuri

Copy link
Copy Markdown
Contributor Author

ok.. i worked on this because it was on the list for 10.0.7.0 and I wanted that to come out asap. But no problem.

@headius

headius commented Sep 16, 2026

Copy link
Copy Markdown
Member

@aminmansuri I appreciate you looking at the targeted issues! This one just turned out to be a bigger issue than I expected.

In the future I will be marking most issues for the "10.0.x" and "10.1.x" milestones so they're not blockers for release. This is meant to indicate "this should be fixed along the 10.0 or 10.1 release line" and not a hard target until we really want to hard target.

@aminmansuri

Copy link
Copy Markdown
Contributor Author

I created the PR for master now.
I guess I should close this PR for now?

@headius

headius commented Sep 16, 2026

Copy link
Copy Markdown
Member

For future reference, it's possible to rebase within the same PR, by rebasing locally and force pushing and then editing the PR to target the other branch (same edit button as for changing the title of the PR).

Since you already created the other one, we'll go ahead and close this one.

@headius headius closed this Sep 16, 2026
@aminmansuri

Copy link
Copy Markdown
Contributor Author

Yeah.. I don't like to force push in any circumstance. I'm a coward.

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.

Wrong union-by-value argument passing in JRuby

2 participants