diff --git a/encoding.c b/encoding.c index e377b5dab1b050..a49f3b6b3adc0f 100644 --- a/encoding.c +++ b/encoding.c @@ -1944,10 +1944,10 @@ static VALUE rb_enc_aliases(VALUE klass) { VALUE aliases[2]; - aliases[0] = rb_hash_new(); aliases[1] = rb_ary_new(); GLOBAL_ENC_TABLE_LOCKING(enc_table) { + aliases[0] = rb_hash_new_capa(st_table_size(enc_table->names)); st_foreach(enc_table->names, rb_enc_aliases_enc_i, (st_data_t)aliases); } diff --git a/error.c b/error.c index 7fc45b7225e3d7..923249ebe56fab 100644 --- a/error.c +++ b/error.c @@ -366,7 +366,7 @@ rb_warn_category(VALUE str, VALUE category) else { VALUE args[2]; args[0] = str; - args[1] = rb_hash_new(); + args[1] = rb_hash_new_capa(1); rb_hash_aset(args[1], sym_category, category); return rb_funcallv_kw(rb_mWarning, id_warn, 2, args, RB_PASS_KEYWORDS); } @@ -1734,7 +1734,7 @@ exc_full_message(int argc, VALUE *argv, VALUE exc) order = check_order_keyword(opt); { - if (NIL_P(opt)) opt = rb_hash_new(); + if (NIL_P(opt)) opt = rb_hash_new_capa(1); rb_hash_aset(opt, sym_highlight, highlight); } diff --git a/eval_error.c b/eval_error.c index f7a69c070ecb75..373f0d14074f0f 100644 --- a/eval_error.c +++ b/eval_error.c @@ -378,7 +378,7 @@ rb_ec_error_print_detailed0(rb_execution_context_t *const ec, const VALUE errinf volatile bool written = false; volatile VALUE emesg = emesg0; - volatile VALUE opt = rb_hash_new(); + volatile VALUE opt = rb_hash_new_capa(1); volatile VALUE highlight = rb_stderr_tty_p() ? Qtrue : Qfalse; rb_hash_aset(opt, ID2SYM(rb_intern_const("highlight")), highlight); diff --git a/gc.c b/gc.c index 993ccdd5446224..d21019dbab24c7 100644 --- a/gc.c +++ b/gc.c @@ -2731,7 +2731,7 @@ count_objects(int argc, VALUE *argv, VALUE os) rb_gc_impl_each_object(rb_gc_get_objspace(), count_objects_i, &data); if (NIL_P(hash)) { - hash = rb_hash_new(); + hash = rb_hash_new_capa(2 + T_MASK); } else if (!RHASH_EMPTY_P(hash)) { rb_hash_stlike_foreach(hash, set_zero, hash); diff --git a/hash.c b/hash.c index 57afe795a4b433..e8e97a80f80e75 100644 --- a/hash.c +++ b/hash.c @@ -1507,6 +1507,18 @@ hash_alloc_capa(VALUE klass, VALUE flags, VALUE ifnone, size_t size, bool frozen return hash; } +static VALUE +hash_hidden_new(size_t size) +{ + return hash_alloc_capa(0, 0, Qnil, size, false); +} + +VALUE +rb_hash_alloc_copy(VALUE klass, VALUE src) +{ + return hash_alloc_capa(klass, 0, Qnil, RHASH_SIZE(src), false); +} + static VALUE hash_alloc(VALUE klass) { @@ -1530,12 +1542,6 @@ empty_hash_alloc(VALUE klass) return hash_alloc(klass); } -VALUE -rb_hash_new(void) -{ - return hash_alloc(rb_cHash); -} - static VALUE copy_compare_by_id(VALUE hash, VALUE basis) { @@ -1551,6 +1557,12 @@ rb_hash_new_capa(long capa) return hash_alloc_capa(rb_cHash, 0, Qnil, capa, false); } +VALUE +rb_hash_new(void) +{ + return rb_hash_new_capa(0); +} + VALUE rb_hash_alloc_fixed_size(VALUE klass, st_index_t size) { @@ -2714,7 +2726,7 @@ rb_hash_slice(int argc, VALUE *argv, VALUE hash) VALUE key, value, result; if (argc == 0 || RHASH_EMPTY_P(hash)) { - return copy_compare_by_id(rb_hash_new(), hash); + return copy_compare_by_id(rb_hash_new_capa(0), hash); } result = copy_compare_by_id(rb_hash_new_capa(argc), hash); @@ -3378,7 +3390,7 @@ rb_hash_transform_keys(int argc, VALUE *argv, VALUE hash) else { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); } - result = rb_hash_new(); + result = rb_hash_new_capa(RHASH_SIZE(hash)); if (!RHASH_EMPTY_P(hash)) { if (transarg.trans) { transarg.result = result; @@ -3505,7 +3517,7 @@ rb_hash_transform_keys_bang(int argc, VALUE *argv, VALUE hash) rb_hash_modify_check(hash); if (!RHASH_TABLE_EMPTY_P(hash)) { long i; - VALUE new_keys = hash_alloc(0); + VALUE new_keys = hash_hidden_new(RHASH_SIZE(hash)); VALUE pairs = rb_ary_hidden_new(RHASH_SIZE(hash) * 2); rb_hash_foreach(hash, flatten_i, pairs); for (i = 0; i < RARRAY_LEN(pairs); i += 2) { @@ -3531,7 +3543,6 @@ rb_hash_transform_keys_bang(int argc, VALUE *argv, VALUE hash) rb_hash_aset(new_keys, new_key, Qnil); } rb_ary_clear(pairs); - rb_hash_clear(new_keys); } compact_after_delete(hash); return hash; @@ -4800,7 +4811,7 @@ rb_hash_compare_by_id_p(VALUE hash) VALUE rb_ident_hash_new(void) { - VALUE hash = rb_hash_new(); + VALUE hash = rb_hash_new_capa(0); hash_st_table_init(hash, &identhash, 0); rb_gc_register_pinning_obj(hash); return hash; @@ -4809,7 +4820,7 @@ rb_ident_hash_new(void) VALUE rb_ident_hash_new_capa(long size) { - VALUE hash = rb_hash_new(); + VALUE hash = rb_hash_new_capa(0); hash_st_table_init(hash, &identhash, size); rb_gc_register_pinning_obj(hash); return hash; @@ -6220,9 +6231,6 @@ env_slice(int argc, VALUE *argv, VALUE _) int i; VALUE key, value, result; - if (argc == 0) { - return rb_hash_new(); - } result = rb_hash_new_capa(argc); for (i = 0; i < argc; i++) { @@ -6607,14 +6615,26 @@ env_key(VALUE dmy, VALUE value) return str; } +static inline size_t +environ_size(char **env) +{ + size_t size = 0; + while (*env) { + size += 1; + env++; + } + return size; +} + static VALUE env_to_hash(void) { - VALUE hash = rb_hash_new(); + VALUE hash; rb_encoding *enc = env_encoding(); ENV_LOCKING() { char **env = GET_ENVIRON(environ); + hash = rb_hash_new_capa(environ_size(env)); while (*env) { char *s = strchr(*env, '='); if (s) { diff --git a/insns.def b/insns.def index 3ad378081a4cac..553d1e4b242b06 100644 --- a/insns.def +++ b/insns.def @@ -592,7 +592,7 @@ newhash val = rb_hash_new_with_bulk_insert(num, STACK_ADDR_FROM_TOP(num)); } else { - val = rb_hash_new(); + val = rb_hash_new_capa(0); } } diff --git a/object.c b/object.c index bd53644a1c37a6..27b8654a7383ad 100644 --- a/object.c +++ b/object.c @@ -26,6 +26,7 @@ #include "internal/class.h" #include "internal/error.h" #include "internal/eval.h" +#include "internal/hash.h" #include "internal/inits.h" #include "internal/numeric.h" #include "internal/object.h" @@ -484,7 +485,7 @@ clone_freeze_kwarg_hash(VALUE *cache, VALUE freeze_value) { VALUE h = RUBY_ATOMIC_VALUE_LOAD(*cache); if (!h) { - h = rb_hash_new(); + h = rb_hash_alloc_fixed_size(rb_cHash, 1); rb_hash_aset(h, ID2SYM(idFreeze), freeze_value); rb_obj_freeze(h); rb_vm_register_global_object(h); /* pin before publishing */ @@ -1461,7 +1462,7 @@ nil_to_a(VALUE obj) static VALUE nil_to_h(VALUE obj) { - return rb_hash_new(); + return rb_hash_new_capa(0); } /* @@ -4023,11 +4024,11 @@ rb_Hash(VALUE val) { VALUE tmp; - if (NIL_P(val)) return rb_hash_new(); + if (NIL_P(val)) return rb_hash_new_capa(0); tmp = rb_check_hash_type(val); if (NIL_P(tmp)) { if (RB_TYPE_P(val, T_ARRAY) && RARRAY_LEN(val) == 0) - return rb_hash_new(); + return rb_hash_new_capa(0); rb_cant_convert(val, "Hash"); } return tmp;