[ruby-core:126293] [Ruby Feature#22232] Deprecate `RHASH_TBL` and associated APIs
Issue #22232 has been reported by byroot (Jean Boussier). ---------------------------------------- Feature #22232: Deprecate `RHASH_TBL` and associated APIs https://bugs.ruby-lang.org/issues/22232 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- I would like to deprecate `RHASH_TBL` and `RHASH_TBL_RAW`. ### Problem These API take a `RHash` instance and return its associated `st_table *`. If the Hash isn't backed by an `st_table` it will force convert it. I think it's a bad API because: - It allows to mutate the hash without triggering write barriers (dangerous). - Using it on a Hash backed by an `ar_table` blow memory usage. - It restrict evolution of RHash, as we must always be able to convert a Hash into a public `st_table`. There are various optimizations that would make sense for `RHash` but that would break the public `ruby/st.h` API, as such, in the future we may want to essentially fork `ruby/st.h` to have a distinct internal version dedicated to `RHash`. Just to give an example, `st_table.type` is very wasteful for RHash, as it's a full length 8B pointer that has only 2 possible values. It would be way more efficient to pass it as an argument every time, and get rid of some pointer chasing. With the possible future introduction of arbitrary length allocation in the GC, we might also want RHash to allocate its bins and entries with the GC rather than malloc. Both those ideas aren't possible to implement (or much harder) if we need to support `RHASH_TBL`. ### Impact I need to figure out how to use the gem search server, but a preliminary search on GitHub didn't show a lot of usage, it's a relatively rare API and if there are use cases that currently necessitate using `st_*` functions on RHash we should define equivalent `rb_hash_` functions to replace them. -- https://bugs.ruby-lang.org/
Issue #22232 has been updated by byroot (Jean Boussier). The raw codesearch result https://gist.github.com/byroot/547f2b19e63efd0b2c974ff1f584751c, but it contains a lot of false positive, as many old gems seems to have: ```c #ifndef RHASH_TBL #define RHASH_TBL(x) RHASH->tbl #endif ``` But then never use it. That seems to be some cargo culting that date back to circa Ruby 1.8. There is a few more false positive caused by gems embedded `mruby`. The cleaned up list it at the bottom of this comment. What I see: - Mostly very old gems. - I see no API that isn't covered by `rb_hash_` function (`st_foreach`, `st_insert`, `st_lookup`, `st_num_entries`). - So fixing the deprecations should be relatively trivial. - I don't recognize any popular gems, except perhaps `byebug`. ``` 2013-05-03 RocketAMF-ouvrages-1.0.0/ext/rocketamf_ext/class_mapping.c: st_foreach(RHASH_TBL(props), mapping_populate_iter, (st_data_t)args); 2013-05-03 RocketAMF-ouvrages-1.0.0/ext/rocketamf_ext/class_mapping.c: st_foreach(RHASH_TBL(dynamic_props), mapping_populate_iter, (st_data_t)args); 2014-06-12 breakout_parser-0.0.31/ext/breakout_parser/parser.y: if (st_lookup(RHASH_TBL(meta_attributes), rb_str_new2(ticket_id), &meta_attributes_hash) == 1) { 2014-06-12 breakout_parser-0.0.31/ext/breakout_parser/parser.y: st_foreach(RHASH_TBL(meta_attributes_hash), iterate_attributes_hash, result); 2026-01-15 byebug-13.0.0/ext/byebug/byebug.c: || RHASH_TBL(catchpoints)->num_entries == 0) 2025-12-22 carray-2.0.1/ext/carray_utils.c: if (st_lookup(RHASH_TBL(hash), key, 0)) { 2012-02-22 cast_off-0.4.1/lib/cast_off/compile/translator.rb: sampling_table = RHASH_TBL(hash); 2012-02-22 cast_off-0.4.1/lib/cast_off/compile/translator.rb: hash = RHASH_TBL(hashval); 2012-02-22 cast_off-0.4.1/lib/cast_off/compile/translator.rb: mtbl = RHASH_TBL(mtblval); 2012-02-22 cast_off-0.4.1/lib/cast_off/compile/translator.rb: method_id_hash = RHASH_TBL(method_id_hashval); 2012-02-22 cast_off-0.4.1/lib/cast_off/compile/translator.rb: hash = RHASH_TBL(hashval); 2010-04-26 coupa-libxml-ruby-1.1.4/ext/libxml/ruby_xml_xpath_context.c: st_foreach(RHASH_TBL(nslist), iterate_ns_hash, self); 2016-06-21 coverage_peek-0.1.1/ext/coverage_peek/coverage_peek.c: st_foreach(RHASH_TBL(coverages), coverage_peek_result_i, ncoverages); 2016-06-21 coverage_peek-0.1.1/ext/coverage_peek/coverage_peek.c: st_foreach(RHASH_TBL(coverages), coverage_peek_result_filtered_i, ncoverages); 2016-01-01 covet-0.1.1/ext/covet_coverage/covet_coverage.c: st_foreach(RHASH_TBL(coverages), coverage_peek_result_i, ncoverages); 2016-01-01 covet-0.1.1/ext/covet_coverage/covet_coverage.c: st_foreach(RHASH_TBL(coverages), coverage_result_i, ncoverages); 2025-02-03 debase-0.2.9/ext/breakpoint.c: if (catchpoints == Qnil /*|| st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0)*/) 2014-05-27 debugger-1.6.8/ext/ruby_debug/192/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2014-05-27 debugger-1.6.8/ext/ruby_debug/192/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2014-05-27 debugger-1.6.8/ext/ruby_debug/193/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2014-05-27 debugger-1.6.8/ext/ruby_debug/193/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2014-05-27 debugger-1.6.8/ext/ruby_debug/200/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2014-05-27 debugger-1.6.8/ext/ruby_debug/200/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2014-05-27 debugger-1.6.8/ext/ruby_debug/210/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2014-05-27 debugger-1.6.8/ext/ruby_debug/210/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2014-05-27 debugger-1.6.8/ext/ruby_debug/211/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2014-05-27 debugger-1.6.8/ext/ruby_debug/211/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2017-11-02 fast_slice-1.0.1/ext/fast_slice/fast_slice.c: if (!RHASH_TBL(hash)) 2017-11-02 fast_slice-1.0.1/ext/fast_slice/fast_slice.c: if (st_lookup(RHASH_TBL(hash), key, 0)) { 2009-01-31 genki-json-1.1.4.1/ext/json/ext/generator/generator.c: long depth, len = RHASH_TBL(self)->num_entries; 2009-01-31 genki-json-1.1.4.1/ext/json/ext/generator/generator.c: long len = RHASH_TBL(self)->num_entries; 2009-01-31 genki-json-1.1.4.1/ext/json/ext/generator/generator.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2009-01-31 genki-json-1.1.4.1/ext/json/ext/generator/generator.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2009-01-31 genki-json-1.1.4.1/ext/json/ext/parser/parser.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2009-01-31 genki-json-1.1.4.1/ext/json/ext/parser/parser.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2009-01-31 genki-json-1.1.4.1/ext/json/ext/parser/parser.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2009-01-31 genki-json-1.1.4.1/ext/json/ext/parser/parser.rl: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2009-01-31 genki-json-1.1.4.1/ext/json/ext/parser/parser.rl: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2009-01-31 genki-json-1.1.4.1/ext/json/ext/parser/parser.rl: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2009-12-23 ghazel-slim-attributes-0.7.6.1/ext/slim_attrib_ext.c: if (REAL_HASH_EXISTS) return (st_lookup(RHASH_TBL(rb_ivar_get(obj, real_hash_id)), name, 0) ? Qtrue : Qfalse); 2009-12-23 ghazel-slim-attributes-0.7.6.1/ext/slim_attrib_ext.c: else if (st_lookup(RHASH_TBL(field_indexes), name, 0)) return Qtrue; 2011-05-24 globegit-postgresql-plruby-0.5.4/src/plpl.c: st_insert(RHASH_TBL(plruby_classes), vid, Qfalse); 2011-05-24 globegit-postgresql-plruby-0.5.4/src/plpl.c: st_insert(RHASH_TBL(plruby_classes), vid, klass); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: return (struct LOC_st_stable_entry*)RHASH_TBL(hash)->entries; 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), a, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), b, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), a, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), a, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), a, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), b, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), b, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), a, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: if (compare_any_values(val, other)) { st_insert(RHASH_TBL(hsh), val, Qtrue); } 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), a, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), a, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), b, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), a, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), a, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: st_insert(RHASH_TBL(MEMO_HASH), b, Qtrue); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: tbl = RHASH_TBL(hash); 2018-06-26 immutable_set-0.1.0/ext/immutable_set/immutable_set.c: new_tbl = RHASH_TBL(new_hash); 2009-05-16 jameskilton-rice-1.2.0/test/test_Hash.cpp: ASSERT_EQUAL(0, RHASH_TBL(h.value())->num_entries); 2009-05-16 jameskilton-rice-1.2.0/test/test_Hash.cpp: ASSERT_EQUAL(0, RHASH_TBL(h.value())->num_entries); 2009-05-16 jameskilton-rice-1.2.0/test/test_Hash.cpp: ASSERT_EQUAL(0, RHASH_TBL(h.value())->num_entries); 2010-10-20 libxml-ruby-r19mingw-1.1.4/ext/libxml/ruby_xml_xpath_context.c: st_foreach(RHASH_TBL(nslist), iterate_ns_hash, self); 2015-06-07 list-0.2.0/ext/list/list.c: if (st_lookup(RHASH_TBL(hash), c->value, 0)) continue; 2015-06-07 list-0.2.0/ext/list/list.c: table = RHASH_TBL(hash); 2015-06-07 list-0.2.0/ext/list/list.c: if (st_delete(RHASH_TBL(hash), &vv, 0)) { 2015-06-07 list-0.2.0/ext/list/list.c: if (st_delete(RHASH_TBL(hash), &vv, 0)) { 2026-07-06 micro-lite-gem-0.0.1/byebug-13.0.0/ext/byebug/byebug.c: || RHASH_TBL(catchpoints)->num_entries == 0) 2017-04-04 mrpin-amf-2.1.12/ext/rocketamf_ext/class_mapping.c: st_foreach(RHASH_TBL(props), mapping_populate_iter, (st_data_t)args); 2017-04-04 mrpin-amf-2.1.12/ext/rocketamf_ext/class_mapping.c: st_foreach(RHASH_TBL(dynamic_props), mapping_populate_iter, (st_data_t)args); 2015-01-01 mrpin-rocketamf-2.0.1/ext/rocketamf_ext/class_mapping.c: st_foreach(RHASH_TBL(props), mapping_populate_iter, (st_data_t)args); 2015-01-01 mrpin-rocketamf-2.0.1/ext/rocketamf_ext/class_mapping.c: st_foreach(RHASH_TBL(dynamic_props), mapping_populate_iter, (st_data_t)args); 2013-03-07 needy_debugger-1.4.0/ext/ruby_debug/192/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2013-03-07 needy_debugger-1.4.0/ext/ruby_debug/192/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2013-03-07 needy_debugger-1.4.0/ext/ruby_debug/193/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2013-03-07 needy_debugger-1.4.0/ext/ruby_debug/193/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2013-03-07 needy_debugger-1.4.0/ext/ruby_debug/200/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2013-03-07 needy_debugger-1.4.0/ext/ruby_debug/200/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2009-09-21 osx-plist-1.0.3/ext/plist/plist.c: // RHASH_TBL exists in ruby 1.8.7 but not ruby 1.8.6 2009-09-21 osx-plist-1.0.3/ext/plist/plist.c:#ifdef RHASH_TBL 2009-09-21 osx-plist-1.0.3/ext/plist/plist.c: st_table *tbl = RHASH_TBL(obj); 1980-01-02 pgsql-1.11/lib/conn.c: st_foreach( RHASH_TBL( params), &set_connect_params, (st_data_t) ptrs); 2011-10-06 plist4r-1.2.2/ext/osx_plist/plist.c: st_table *tbl = RHASH_TBL(obj); 2013-02-25 rbtree2-0.0.3/ext/rbtree.c: st_foreach(RHASH_TBL(tmp), hash_to_rbtree_i, rbtree); 2013-02-25 rbtree2-0.0.3/ext/rbtree.c: st_insert(RHASH_TBL((VALUE)hash), GET_KEY(node), GET_VAL(node)); 1980-01-02 rbtree3-1.1.0/rbtree.c: st_foreach(RHASH_TBL(tmp), hash_to_rbtree_i, rbtree); 1980-01-02 rbtree3-1.1.0/rbtree.c: st_insert(RHASH_TBL((long)hash), GET_KEY(node), GET_VAL(node)); 2015-08-11 rhack-1.4.0/ext/curb/curb_multi.c: RHASH_TBL(rbcm->requests)->num_entries) { 2015-08-11 rhack-1.4.0/ext/curb/curb_multi.c: } while (!(RHASH_TBL(rbcm->requests)->num_entries)); 2024-02-15 rhodes-7.6.0/platform/shared/ruby/array.c: if (!st_update(RHASH_TBL_RAW(hash), (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) { 2024-02-15 rhodes-7.6.0/platform/shared/ruby/gc.c: st_foreach(RHASH_TBL_RAW(hash), set_zero, hash); 2024-02-15 rhodes-7.6.0/platform/shared/ruby/process.c: st_table *stenv = RHASH_TBL_RAW(envtbl); 2024-02-15 rhodes-7.6.0/platform/shared/ruby/process.c: st_foreach(RHASH_TBL_RAW(envtbl), fill_envp_buf_i, (st_data_t)envp_buf); 2024-02-15 rhodes-7.6.0/platform/shared/ruby/struct.c: st_table *tbl = RHASH_TBL(list); 2024-02-15 rhodes-7.6.0/platform/shared/ruby/struct.c: tbl = RHASH_TBL(rest); 2024-02-15 rhodes-7.6.0/platform/shared/ruby/vm_eval.c: st_table *tbl = RHASH_TBL_RAW(vars->tbl); 2010-09-16 rice-jdguyot-1.4.0/test/test_Hash.cpp: ASSERT_EQUAL(0, RHASH_TBL(h.value())->num_entries); 2010-09-16 rice-jdguyot-1.4.0/test/test_Hash.cpp: ASSERT_EQUAL(0, RHASH_TBL(h.value())->num_entries); 2010-09-16 rice-jdguyot-1.4.0/test/test_Hash.cpp: ASSERT_EQUAL(0, RHASH_TBL(h.value())->num_entries); 2024-05-01 rjb-1.7.3/ext/rjb.c: st_foreach(RHASH_TBL(rjb_loaded_classes), clear_classes, 0); 2024-05-01 rjb-1.7.3/ext/rjb.c: st_insert(RHASH_TBL(rjb_loaded_classes), clsname, self); 2024-05-01 rjb-1.7.3/ext/rjbexception.c: st_insert(RHASH_TBL(rjb_loaded_classes), cname, rexp); 2016-02-10 rmtools-2.5.0/ext/rmtools.cpp: if (st_lookup(RHASH_TBL(hash), el, 0)) continue; 2016-02-10 rmtools-2.5.0/ext/rmtools.cpp: if (st_lookup(RHASH_TBL(res_hash), res, 0)) continue; 2016-02-10 rmtools-2.5.0/ext/rmtools.cpp: if (st_lookup(RHASH_TBL(hash), key, 0)) 2016-02-10 rmtools-2.5.0/ext/rmtools.cpp: if (st_lookup(RHASH_TBL(hash), key, &val)) 2011-04-02 ruby-debug-base19-0.11.25/ext/ruby_debug/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2011-04-02 ruby-debug-base19-0.11.25/ext/ruby_debug/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2009-09-08 ruby-debug-base193-0.0.1/ext/ruby_debug/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0 2009-09-08 ruby-debug-base193-0.0.1/ext/ruby_debug/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0 2017-12-12 ruby-debug-base19x-0.11.32/ext/ruby_debug/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0) 2017-12-12 ruby-debug-base19x-0.11.32/ext/ruby_debug/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0) 2017-08-03 ruby_deep_clone-0.8.0/ext/deep_clone/deep_clone.c: if(st_lookup(RHASH_TBL(tracker), id, 0)) 2012-11-22 rubyosa19-0.6.2/ext/rubyosa/rbosa_sdef.c: if (RHASH_TBL(hash)->num_entries > 0) { 2025-02-05 runger_byebug-11.4.0/ext/byebug/byebug.c: || RHASH_TBL(catchpoints)->num_entries == 0) 2014-04-01 scalm-RocketAMF-1.0.0/ext/rocketamf_ext/class_mapping.c: st_foreach(RHASH_TBL(props), mapping_populate_iter, (st_data_t)args); 2014-04-01 scalm-RocketAMF-1.0.0/ext/rocketamf_ext/class_mapping.c: st_foreach(RHASH_TBL(dynamic_props), mapping_populate_iter, (st_data_t)args); 2009-09-22 sdsykes-slim-attributes-0.6.6/ext/slim_attrib_ext.c: if (REAL_HASH_EXISTS) return (st_lookup(RHASH_TBL(rb_ivar_get(obj, real_hash_id)), name, 0) ? Qtrue : Qfalse); 2009-09-22 sdsykes-slim-attributes-0.6.6/ext/slim_attrib_ext.c: else return (st_lookup(RHASH_TBL(field_indexes), name, 0) ? Qtrue : Qfalse); 2011-02-27 shoes-3.0.1/req/json/ext/generator/generator.c: long depth, len = RHASH_TBL(self)->num_entries; 2011-02-27 shoes-3.0.1/req/json/ext/generator/generator.c: long len = RHASH_TBL(self)->num_entries; 2011-02-27 shoes-3.0.1/req/json/ext/generator/generator.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2011-02-27 shoes-3.0.1/req/json/ext/generator/generator.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2011-02-27 shoes-3.0.1/req/json/ext/parser/parser.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2011-02-27 shoes-3.0.1/req/json/ext/parser/parser.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2011-02-27 shoes-3.0.1/req/json/ext/parser/parser.c: if (st_lookup(RHASH_TBL(opts), tmp, 0)) { 2009-12-23 slim-attributes-0.7.7/ext/slim_attrib_ext.c: if (REAL_HASH_EXISTS) return (st_lookup(RHASH_TBL(rb_ivar_get(obj, real_hash_id)), name, 0) ? Qtrue : Qfalse); 2009-12-23 slim-attributes-0.7.7/ext/slim_attrib_ext.c: else if (st_lookup(RHASH_TBL(field_indexes), name, 0)) return Qtrue; 2014-12-12 snapshot_coverage-1.0.0/ext/snapshot_coverage/snapshot_coverage.c: st_foreach(RHASH_TBL(coverages), coverage_result_i, ncoverages); 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/array.c: if (st_lookup(RHASH_TBL(hash), RARRAY_PTR(ary1)[i], 0)) continue; 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/array.c: if (st_delete(RHASH_TBL(hash), (st_data_t*)&vv, 0)) { 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/array.c: if (st_delete(RHASH_TBL(hash), (st_data_t*)&vv, 0)) { 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/array.c: if (st_delete(RHASH_TBL(hash), (st_data_t*)&vv, 0)) { 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/array.c: st_foreach(RHASH_TBL(hash), push_value, ary); 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/array.c: if (st_delete(RHASH_TBL(hash), &vv, 0)) { 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/array.c: st_foreach(RHASH_TBL(hash), push_value, uniq); 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/array.c: if (st_delete(RHASH_TBL(hash), &vv, 0)) { 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/compile.c: RHASH_TBL(map)->type = &cdhash_type; 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/gc.c: st_foreach(RHASH_TBL(hash), set_zero, hash); 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/process.c: st_foreach(RHASH_TBL(opthash), check_exec_options_i, (st_data_t)e); 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/process.c: st_foreach(RHASH_TBL(hash), check_exec_env_i, (st_data_t)env); 2016-05-23 tauplatform-1.0.3/platform/shared/ruby/thread.c: st_foreach(RHASH_TBL(coverages), clear_coverage_i, 0); 2009-09-08 tddium-ruby-debug-base19-0.12.1/ext/ruby_debug/ruby_debug.c: st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0 2009-09-08 tddium-ruby-debug-base19-0.12.1/ext/ruby_debug/ruby_debug.c: (RHASH_TBL(rdebug_catchpoints)->num_entries) == 0 2010-02-19 tk_as_gem-0.1.0/ext/tkutil/tkutil.c: st_foreach(RHASH_TBL(keys), to_strkey, new_keys); 2010-02-19 tk_as_gem-0.1.0/ext/tkutil/tkutil.c: st_foreach(RHASH_TBL(hash), push_kv, args); 2010-02-19 tk_as_gem-0.1.0/ext/tkutil/tkutil.c: st_foreach(RHASH_TBL(hash), push_kv_enc, args); 2015-04-12 what_to_run-1.0.2/ext/coverage_peeker/coverage_peeker.c: st_foreach(RHASH_TBL(coverages), coverage_peek_result_i, ncoverages); 2011-06-21 wurlinc-rice-1.4.0.4/test/test_Hash.cpp: ASSERT_EQUAL(0, RHASH_TBL(h.value())->num_entries); 2011-06-21 wurlinc-rice-1.4.0.4/test/test_Hash.cpp: ASSERT_EQUAL(0, RHASH_TBL(h.value())->num_entries); 2011-06-21 wurlinc-rice-1.4.0.4/test/test_Hash.cpp: ASSERT_EQUAL(0, RHASH_TBL(h.value())->num_entries); ``` ---------------------------------------- Feature #22232: Deprecate `RHASH_TBL` and associated APIs https://bugs.ruby-lang.org/issues/22232#change-118395 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- I would like to deprecate `RHASH_TBL` and `RHASH_TBL_RAW`. ### Problem These API take a `RHash` instance and return its associated `st_table *`. If the Hash isn't backed by an `st_table` it will force convert it. I think it's a bad API because: - It allows to mutate the hash without triggering write barriers (dangerous). - Using it on a Hash backed by an `ar_table` blow memory usage. - It restrict evolution of RHash, as we must always be able to convert a Hash into a public `st_table`. There are various optimizations that would make sense for `RHash` but that would break the public `ruby/st.h` API, as such, in the future we may want to essentially fork `ruby/st.h` to have a distinct internal version dedicated to `RHash`. Just to give an example, `st_table.type` is very wasteful for RHash, as it's a full length 8B pointer that has only 2 possible values. It would be way more efficient to pass it as an argument every time, and get rid of some pointer chasing. With the possible future introduction of arbitrary length allocation in the GC, we might also want RHash to allocate its bins and entries with the GC rather than malloc. Both those ideas aren't possible to implement (or much harder) if we need to support `RHASH_TBL`. ### Impact I need to figure out how to use the gem search server, but a preliminary search on GitHub didn't show a lot of usage, it's a relatively rare API and if there are use cases that currently necessitate using `st_*` functions on RHash we should define equivalent `rb_hash_` functions to replace them. -- https://bugs.ruby-lang.org/
Issue #22232 has been updated by byroot (Jean Boussier). For `rb_hash_bulk_insert_into_st_table` which probably was never intended to be public API, there is only a single hit, and it's clearly a misuse, it should use `rb_hash_bulk_insert: https://github.com/redcode/Z80-Ruby/blob/master/ext/z80/z80.c#L527-L560 ``` $ gem-codesearch rb_hash_bulk_insert_into_st_table 2024-01-05 z80-0.3.2/ext/z80/z80.c: rb_hash_bulk_insert_into_st_table(Z_ARRAY_SIZE(kv), kv, hash); ``` ---------------------------------------- Feature #22232: Deprecate `RHASH_TBL` and associated APIs https://bugs.ruby-lang.org/issues/22232#change-118399 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- I would like to deprecate `RHASH_TBL`, `RHASH_TBL_RAW` and `rb_hash_bulk_insert_into_st_table`. ### Problem These API take a `RHash` instance and return its associated `st_table *`. If the Hash isn't backed by an `st_table` it will force convert it. I think it's a bad API because: - It allows to mutate the hash without triggering write barriers (dangerous). - Using it on a Hash backed by an `ar_table` blow memory usage. - It restrict evolution of RHash, as we must always be able to convert a Hash into a public `st_table`. There are various optimizations that would make sense for `RHash` but that would break the public `ruby/st.h` API, as such, in the future we may want to essentially fork `ruby/st.h` to have a distinct internal version dedicated to `RHash`. Just to give an example, `st_table.type` is very wasteful for RHash, as it's a full length 8B pointer that has only 2 possible values. It would be way more efficient to pass it as an argument every time, and get rid of some pointer chasing. With the possible future introduction of arbitrary length allocation in the GC, we might also want RHash to allocate its bins and entries with the GC rather than malloc. Both those ideas aren't possible to implement (or much harder) if we need to support `RHASH_TBL`. ### Impact I need to figure out how to use the gem search server, but a preliminary search on GitHub didn't show a lot of usage, it's a relatively rare API and if there are use cases that currently necessitate using `st_*` functions on RHash we should define equivalent `rb_hash_` functions to replace them. -- https://bugs.ruby-lang.org/
participants (1)
-
byroot (Jean Boussier)