diff options
author | John Hawthorn <john@hawthorn.email> | 2022-08-15 16:14:12 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-15 16:14:12 -0700 |
commit | 0608a9a08693286a7d84845a216927ff2e3c9951 (patch) | |
tree | b3b0f619edd8f90cbfac7c75e5199a2ce141f1c7 /test/ruby | |
parent | e49db0f760722bf44ed2c5b31f67d929e9156dbe (diff) |
Optimize Marshal dump/load for large (> 31-bit) FIXNUM (#6229)
* Optimize Marshal dump of large fixnum
Marshal's FIXNUM type only supports 31-bit fixnums, so on 64-bit
platforms the 63-bit fixnums need to be represented in Marshal's
BIGNUM.
Previously this was done by converting to a bugnum and serializing the
bignum object.
This commit avoids allocating the intermediate bignum object, instead
outputting the T_FIXNUM directly to a Marshal bignum. This maintains the
same representation as the previous implementation, including not using
LINKs for these large fixnums (an artifact of the previous
implementation always allocating a new BIGNUM).
This commit also avoids unnecessary st_lookups on immediate values,
which we know will not be in that table.
* Fastpath for loading FIXNUM from Marshal bignum
* Run update-deps
Notes
Notes:
Merged-By: jhawthorn <john@hawthorn.email>
Diffstat (limited to 'test/ruby')
-rw-r--r-- | test/ruby/test_marshal.rb | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb index 361d18dd4b..fc5cd9e93e 100644 --- a/test/ruby/test_marshal.rb +++ b/test/ruby/test_marshal.rb @@ -33,7 +33,7 @@ class TestMarshal < Test::Unit::TestCase end def test_marshal - a = [1, 2, 3, [4,5,"foo"], {1=>"bar"}, 2.5, fact(30)] + a = [1, 2, 3, 2**32, 2**64, [4,5,"foo"], {1=>"bar"}, 2.5, fact(30)] assert_equal a, Marshal.load(Marshal.dump(a)) [[1,2,3,4], [81, 2, 118, 3146]].each { |w,x,y,z| @@ -47,6 +47,26 @@ class TestMarshal < Test::Unit::TestCase } end + def test_marshal_integers + a = [] + [-2, -1, 0, 1, 2].each do |i| + 0.upto(65).map do |exp| + a << 2**exp + i + end + end + assert_equal a, Marshal.load(Marshal.dump(a)) + + a = [2**32, []]*2 + assert_equal a, Marshal.load(Marshal.dump(a)) + + a = [2**32, 2**32, []]*2 + assert_equal a, Marshal.load(Marshal.dump(a)) + end + + def test_marshal_small_bignum_backref + assert_equal [2**32, 2**32], Marshal.load("\x04\b[\al+\b\x00\x00\x00\x00\x01\x00@\x06") + end + StrClone = String.clone def test_marshal_cloned_class assert_instance_of(StrClone, Marshal.load(Marshal.dump(StrClone.new("abc")))) |