Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ruby: Fix object cache lookups on 32-bit platforms (#13494) #13557

Closed
wants to merge 1 commit into from

Conversation

copybara-service[bot]
Copy link

ruby: Fix object cache lookups on 32-bit platforms (#13494)

#13204 refactored the Ruby object cache to use a key of LL2NUM(key_val) instead of LL2NUM(key_val >> 2). On 32-bit systems, LL2NUM(key_val) returns inconsistent results because a large value has to be stored as a Bignum on the heap. This causes cache lookups to fail.

This commit restores the previous behavior of using ObjectCache_GetKey, which discards the lower 2 bits, which are zero. This enables a key to be stored as a Fixnum on both 32 and 64-bit platforms.

As https://patshaughnessy.net/2014/1/9/how-big-is-a-bignum describes, a Fixnum uses:

  • 1 bit for the FIXNUM_FLAG.
  • 1 bit for the sign flag.

Therefore the largest possible Fixnum value on a 64-bit value is 4611686018427387903 (2^62 - 1). On a 32-bit system, the largest value is 1073741823 (2^30 - 1).

For example, a possible VALUE pointer address on a 32-bit system:

0xff5b4af8 => 4284173048

Dropping the lower 2 bits makes up for the loss of range to these flags. In the example above, we see that shifting by 2 turns the value into a 30-bit number, which can be represented as a Fixnum:

(0xff5b4af8 >> 2) => 1071043262

This bug can also manifest on a 64-bit system if the upper bits are 0xff.

Closes #13481

Closes #13494

COPYBARA_INTEGRATE_REVIEW=#13494 from stanhu:sh-fix-ruby-protobuf-32bit d63122a
FUTURE_COPYBARA_INTEGRATE_REVIEW=#13494 from stanhu:sh-fix-ruby-protobuf-32bit d63122a

#13204 refactored the Ruby object cache to use a key of `LL2NUM(key_val)` instead of `LL2NUM(key_val >> 2)`. On 32-bit systems, `LL2NUM(key_val)` returns inconsistent results because a large value has to be stored as a Bignum on the heap. This causes cache lookups to fail.

This commit restores the previous behavior of using `ObjectCache_GetKey`, which discards the lower 2 bits, which are zero. This enables a key to be stored as a Fixnum on both 32 and 64-bit platforms.

As https://patshaughnessy.net/2014/1/9/how-big-is-a-bignum describes, a Fixnum uses:

* 1 bit for the `FIXNUM_FLAG`.
* 1 bit for the sign flag.

Therefore the largest possible Fixnum value on a 64-bit value is 4611686018427387903 (2^62 - 1). On a 32-bit system, the largest value  is 1073741823 (2^30 - 1).

For example, a possible VALUE pointer address on a 32-bit system:

0xff5b4af8 => 4284173048

Dropping the lower 2 bits makes up for the loss of range to these flags. In the example above, we see that shifting by 2 turns the value into a 30-bit number, which can be represented as a Fixnum:

(0xff5b4af8 >> 2) => 1071043262

This bug can also manifest on a 64-bit system if the upper bits are 0xff.

Closes #13481

Closes #13494

COPYBARA_INTEGRATE_REVIEW=#13494 from stanhu:sh-fix-ruby-protobuf-32bit d63122a
FUTURE_COPYBARA_INTEGRATE_REVIEW=#13494 from stanhu:sh-fix-ruby-protobuf-32bit d63122a
PiperOrigin-RevId: 557216800
@mkruskal-google
Copy link
Member

Auto-closing Copybara pull request

@mkruskal-google mkruskal-google deleted the test_557216800 branch August 24, 2023 23:16
copybara-service bot pushed a commit that referenced this pull request Aug 25, 2023
This was tested locally over a smaller set of PRs, resulting in:
#13557

PiperOrigin-RevId: 560101257
copybara-service bot pushed a commit that referenced this pull request Aug 25, 2023
This was tested locally over a smaller set of PRs, resulting in:
#13557

PiperOrigin-RevId: 560101257
copybara-service bot pushed a commit that referenced this pull request Aug 25, 2023
This was tested locally over a smaller set of PRs, resulting in:
#13557

PiperOrigin-RevId: 560124506
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.

[ruby] Unable to instantiate a descriptor in v3.24.0 on 32-bit system
2 participants