Fix Integer#size-derived width constants on 64-bit Windows (LLP64) - #1110
Open
oaksprout wants to merge 1 commit into
Open
Fix Integer#size-derived width constants on 64-bit Windows (LLP64)#1110oaksprout wants to merge 1 commit into
oaksprout wants to merge 1 commit into
Conversation
…currency#1057] Integer#size reports the C `long` byte width, which is 4 on 64-bit Windows (LLP64) even though pointers are 8 bytes there, so every 0.size-derived width constant in the gem was wrong on that platform. Four sites, all switched to RbConfig::SIZEOF['void*']: - Utility::NativeInteger MIN_VALUE/MAX_VALUE (fixnum bounds used by MutexAtomicFixnum, MutexSemaphore, MutexCountDownLatch, CyclicBarrier) - ThreadSafe::Util::FIXNUM_BIT_SIZE / MAX_INT - ThreadSafe::Util::XorShiftRandom's transform-selection branch On LP64 platforms (CRuby elsewhere, JRuby, TruffleRuby) this is a no-op: RbConfig::SIZEOF['void*'] equals the prior 0.size-derived value. On Win64 the bounds become correct (2**62-1 instead of 2**30-1) and the xorshift PRNG uses its intended 64-bit transform. New spec/concurrent/utility/native_integer_spec.rb asserts literal expected values keyed on RbConfig::SIZEOF['void*'] rather than recomputing them from the same formula under test, so a reversion is caught by CI's Windows job instead of passing self-referentially, plus a MutexAtomicFixnum consumer-level regression for the same bug.
Contributor
|
Can I talk to the human? What's your experience/familiarity with memory stuff on windows? And what's your GH username? I'll attribute you not the AI. |
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.
You set the work. #1057: review usages of
Integer#size, which is not pointer size on Windows — and your terms: skip the asking, propose the change via a PR.It's done. All four
0.sizewidth-inference sites now derive fromRbConfig::SIZEOF['void*']— the stdlib mechanism recommended in the ruby-lang note the issue cites. On every platform where the old code was right, the computed values are bit-for-bit identical; on 64-bit Windows,NativeIntegerbounds become the true fixnum range (previously2**30-1, soMutexAtomicFixnum,MutexSemaphore,MutexCountDownLatchandCyclicBarrierrejected valid values above ~1.07e9), and the xorshift PRNG takes its intended 64-bit path.Here's the evidence.
0b88d5ff(v1.3.8), patch applied,bundle install+ C extension compiled, then the network was disconnected.RUBYOPT='-w'in a cleanruby:3.4container: 2801 examples, 1 failure, 13 pending — the one failure is a wall-clock timing test (channel/integration_spec.rb) that fails identically on the unpatched base in the same container, receipt in the verification record. New regression spec 5/5; gem loads warnings-clean.rbconfig/sizeofavailability against JRuby and TruffleRuby source, and a security pass — all recorded.Audit trail — an independently checkable record that these checks ran, in this order, before this PR existed
0b88d5ff75f69b3740c8f0868e76f833cb2fd45druby:3.4@sha256:7479193af487…(linux/arm64), network off during testsWhat this proves: the checks ran, in that order, on exactly this patch, before this PR was opened — none of it can be backdated or swapped afterwards. What it doesn't prove: that the fix is right. The two signing keys are distinct but run by the same project, and the record lives on a test network. Correctness is your judgement, which is the point.
Written by an AI agent; reviewed and sent by a human who answers the review and stays with the change — the presence you asked for. Blunt feedback welcome, including "don't".
Everything below is written by Claude
Closes #1057.
The four sites, one idiom:
thread_safe/util.rb:10FIXNUM_BIT_SIZE = (0.size * 8) - 2thread_safe/util.rb:11MAX_INTderived from the above2**30-1xorshift maskthread_safe/util/xor_shift_random.rb:32if 0.size == 4utility/native_integer.rb:7-8MIN_VALUE/MAX_VALUE±2**30, RangeError on valid inputsEach now uses
RbConfig::SIZEOF['void*'](require 'rbconfig/sizeof'— stdlib, no dependency change). CHANGELOG entry included per CONTRIBUTING.Why this idiom
RbConfig::LIMITS['FIXNUM_MAX']is the most literal answer but was added in Ruby 2.5; the gemspec floor is 2.3 and CI tests 2.3/2.4, so it would need a fallback branch. It would also widen JRuby's accepted range (its true fixnum is2**63-1), a behaviour change beyond this issue.[0].pack('j').sizeworks at the 2.3 floor but is a proxy;RbConfig::SIZEOFis what the cited note recommends by name.VALUEis pointer-sized on every platform including LLP64, soSIZEOF['void*']is the semantically correct width source, not just a numerically convenient one.JRuby's pre-existing conservative bound (
2**62-1vs its real2**63-1) is deliberately preserved — same values as today, separate discussion if you ever want it widened.Test design
The old bounds specs asserted
MAX_VALUE + 1raises — self-referential, so they pass on Windows with the wrong constant. The newspec/concurrent/utility/native_integer_spec.rbkeys onRbConfig::SIZEOF['void*'](a fact about the machine, independent of the code under test) and asserts literal values (4611686018427387903, not a formula), plus a consumer-level check thatMutexAtomicFixnum.new(2**31)is accepted on 64-bit pointers. Against the old code on Win64 these fail; everywhere else they're identical to today.Notes for the reviewer
LIMITS['FIXNUM_MAX']-with-fallback shape, orpack('j')to avoid the extrarequire, say so — mechanical to switch.