Actions
Feature #20589
closedResize array in `rb_ary_freeze` and use `rb_ary_freeze` internally for arrays
    Feature #20589:
    Resize array in `rb_ary_freeze` and use `rb_ary_freeze` internally for arrays
  
Status:
Closed
Assignee:
-
Target version:
-
Description
GitHub PR https://github.com/ruby/ruby/pull/11030
This is a redo of https://github.com/ruby/ruby/pull/2640 and a new issue for the array portion of https://bugs.ruby-lang.org/issues/16291 because both are stale.
This change proposes the following:
- Call ary_shrink_capafromrb_ary_freezeto resize arrays before freezing (if they are not embedded, not shared, and not a shared root).
- Update callers to use rb_ary_freezeinstead ofrb_obj_freezeinternally in CRuby/
- Add an assertion to ary_heap_reallocthat ensures frozen arrays are not being reallocated.\
The orignal issue implemented this for performance reasons, which are still valid. However, additionally this ensures that frozen arrays are not being passed to ary_heap_realloc and also ensures the capacity is set with ARY_SET_CAPA in ary_shrink_capa. Previously, because ARY_SET_CAPA was not called, ary_heap_realloc would get called after the array was frozen (when that is unnecessary).
Array memsize before and after this change:
Before:
$ require 'objspace'
=> false
$ a = (1..5).to_a
=> [1, 2, 3, 4, 5]
$ ObjectSpace.memsize_of(a)
=> 200
$ a.freeze
=> [1, 2, 3, 4, 5]
$ ObjectSpace.memsize_of(a)
=> 200
After:
$ require 'objspace'
=> false
$ a = (1..5).to_a
=> [1, 2, 3, 4, 5]
$ ObjectSpace.memsize_of(a)
=> 200
$ a.freeze
=> [1, 2, 3, 4, 5]
$ ObjectSpace.memsize_of(a)
=> 80
Actions