Skip to content

Commit 42f043c

Browse files
committed
merge revision(s) 56ecc24: [Backport #20868]
[Bug #20868] Fix Method#hash to not change after compaction The hash value of a Method must remain constant after a compaction, otherwise it may not work as the key in a hash table. For example: def a; end # Need this method here because otherwise the iseq may be on the C stack # which would get pinned and not move during compaction def get_hash method(:a).hash end puts get_hash # => 2993401401091578131 GC.verify_compaction_references(expand_heap: true, toward: :empty) puts get_hash # => -2162775864511574135
1 parent 2330146 commit 42f043c

3 files changed

Lines changed: 23 additions & 2 deletions

File tree

test/ruby/test_method.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,27 @@ def o.foo; end
209209
assert_kind_of(String, o.method(:foo).hash.to_s)
210210
end
211211

212+
def test_hash_does_not_change_after_compaction
213+
omit "compaction is not supported on this platform" unless GC.respond_to?(:compact)
214+
215+
# iseq backed method
216+
assert_separately([], <<~RUBY)
217+
def a; end
218+
219+
# Need this method here because otherwise the iseq may be on the C stack
220+
# which would get pinned and not move during compaction
221+
def get_hash
222+
method(:a).hash
223+
end
224+
225+
hash = get_hash
226+
227+
GC.verify_compaction_references(expand_heap: true, toward: :empty)
228+
229+
assert_equal(hash, get_hash)
230+
RUBY
231+
end
232+
212233
def test_owner
213234
c = Class.new do
214235
def foo; end

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
1212
#define RUBY_VERSION_TEENY 6
1313
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
14-
#define RUBY_PATCHLEVEL 109
14+
#define RUBY_PATCHLEVEL 110
1515

1616
#include "ruby/version.h"
1717
#include "ruby/internal/abi.h"

vm_method.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2237,7 +2237,7 @@ rb_hash_method_definition(st_index_t hash, const rb_method_definition_t *def)
22372237

22382238
switch (def->type) {
22392239
case VM_METHOD_TYPE_ISEQ:
2240-
return rb_hash_uint(hash, (st_index_t)def->body.iseq.iseqptr);
2240+
return rb_hash_uint(hash, (st_index_t)def->body.iseq.iseqptr->body);
22412241
case VM_METHOD_TYPE_CFUNC:
22422242
hash = rb_hash_uint(hash, (st_index_t)def->body.cfunc.func);
22432243
return rb_hash_uint(hash, def->body.cfunc.argc);

0 commit comments

Comments
 (0)