ruby-changes:46349
From: shyouhei <ko1@a...>
Date: Mon, 24 Apr 2017 10:40:57 +0900 (JST)
Subject: [ruby-changes:46349] shyouhei:r58463 (trunk): revert newhash refactoring
shyouhei 2017-04-24 10:40:51 +0900 (Mon, 24 Apr 2017) New Revision: 58463 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=58463 Log: revert newhash refactoring We need to fix GC bug before merging this. Revert revisions 58452, 58435, 58434, 58428, 58427 in this order. Modified files: trunk/hash.c trunk/insns.def trunk/internal.h trunk/vm.c Index: insns.def =================================================================== --- insns.def (revision 58462) +++ insns.def (revision 58463) @@ -492,13 +492,16 @@ newhash https://github.com/ruby/ruby/blob/trunk/insns.def#L492 (...) (VALUE val) // inc += 1 - num; { + rb_num_t i; + RUBY_DTRACE_CREATE_HOOK(HASH, num); - if (num) { - val = rb_hash_new_from_values(num, STACK_ADDR_FROM_TOP(num)); - } - else { - val = rb_hash_new(); + val = rb_hash_new(); + + for (i = num; i > 0; i -= 2) { + const VALUE v = TOPN(i - 2); + const VALUE k = TOPN(i - 1); + rb_hash_aset(val, k, v); } POPN(num); } Index: vm.c =================================================================== --- vm.c (revision 58462) +++ vm.c (revision 58463) @@ -2646,6 +2646,7 @@ m_core_set_postexe(VALUE self) https://github.com/ruby/ruby/blob/trunk/vm.c#L2646 return Qnil; } +static VALUE core_hash_merge_ary(VALUE hash, VALUE ary); static VALUE core_hash_from_ary(VALUE ary); static VALUE core_hash_merge_kwd(int argc, VALUE *argv); @@ -2655,6 +2656,7 @@ core_hash_merge(VALUE hash, long argc, c https://github.com/ruby/ruby/blob/trunk/vm.c#L2656 long i; Check_Type(hash, T_HASH); + VM_ASSERT(argc % 2 == 0); for (i=0; i<argc; i+=2) { rb_hash_aset(hash, argv[i], argv[i+1]); } @@ -2672,18 +2674,27 @@ m_core_hash_from_ary(VALUE self, VALUE a https://github.com/ruby/ruby/blob/trunk/vm.c#L2674 static VALUE core_hash_from_ary(VALUE ary) { - long n; + VALUE hash = rb_hash_new(); + RUBY_DTRACE_CREATE_HOOK(HASH, (Check_Type(ary, T_ARRAY), RARRAY_LEN(ary))); + return core_hash_merge_ary(hash, ary); +} + +#if 0 +static VALUE +m_core_hash_merge_ary(VALUE self, VALUE hash, VALUE ary) +{ + REWIND_CFP(core_hash_merge_ary(hash, ary)); + return hash; +} +#endif + +static VALUE +core_hash_merge_ary(VALUE hash, VALUE ary) +{ Check_Type(ary, T_ARRAY); - n = RARRAY_LEN(ary); - RUBY_DTRACE_CREATE_HOOK(HASH, n); - if (n) { - VM_ASSERT(n % 2 == 0); - return rb_hash_new_from_values(n, RARRAY_PTR(ary)); - } - else { - return rb_hash_new(); - } + core_hash_merge(hash, RARRAY_LEN(ary), RARRAY_CONST_PTR(ary)); + return hash; } static VALUE Index: internal.h =================================================================== --- internal.h (revision 58462) +++ internal.h (revision 58463) @@ -1236,7 +1236,6 @@ VALUE rb_hash_rehash(VALUE hash); https://github.com/ruby/ruby/blob/trunk/internal.h#L1236 int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val); #define HASH_DELETED FL_USER1 #define HASH_PROC_DEFAULT FL_USER2 -extern VALUE rb_hash_new_from_values(long, const VALUE *); /* inits.c */ void rb_call_inits(void); Index: hash.c =================================================================== --- hash.c (revision 58462) +++ hash.c (revision 58463) @@ -626,110 +626,6 @@ rb_hash_initialize(int argc, VALUE *argv https://github.com/ruby/ruby/blob/trunk/hash.c#L626 return hash; } -static inline VALUE -hash_alloc_from_st(VALUE klass, st_table *ntbl) -{ - VALUE h = hash_alloc(klass); - RHASH(h)->ntbl = ntbl; - return h; -} - -static inline void -hash_insert_raw(VALUE hash, st_table *tbl, VALUE key, VALUE val) -{ - st_data_t v = (st_data_t)val; - st_data_t k = (rb_obj_class(key) == rb_cString) ? - (st_data_t)rb_str_new_frozen(key) : - (st_data_t)key; - - st_insert(tbl, k, v); - RB_OBJ_WRITTEN(hash, Qundef, key); - RB_OBJ_WRITTEN(hash, Qundef, val); -} - -static VALUE -rb_hash_new_from_values_with_klass(long argc, const VALUE *argv, VALUE klass) -{ - long i; - st_table *t; - VALUE v; - - if (argc % 2) { - rb_raise(rb_eArgError, "odd number of arguments for Hash"); - } - - t = st_init_table_with_size(&objhash, argc / 2); - v = hash_alloc_from_st(klass, t); - - for (i = 0; i < argc; /* */) { - VALUE key = argv[i++]; - VALUE val = argv[i++]; - - hash_insert_raw(v, t, key, val); - } - return v; -} - -VALUE -rb_hash_new_from_values(long argc, const VALUE *argv) -{ - return rb_hash_new_from_values_with_klass(argc, argv, rb_cHash); -} - -static VALUE -rb_hash_new_from_object(VALUE klass, VALUE obj) -{ - VALUE tmp = rb_hash_s_try_convert(Qnil, obj); - if (!NIL_P(tmp)) { - VALUE hash = hash_alloc(klass); - if (RHASH(tmp)->ntbl) { - RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl); - } - return hash; - } - - tmp = rb_check_array_type(obj); - if (!NIL_P(tmp)) { - long i; - long len = RARRAY_LEN(tmp); - st_table *tbl = len ? st_init_table_with_size(&objhash, len) : NULL; - VALUE hv = hash_alloc_from_st(klass, tbl);; - - for (i = 0; i < len; ++i) { - VALUE e = RARRAY_AREF(tmp, i); - VALUE v = rb_check_array_type(e); - VALUE key, val = Qnil; - - if (NIL_P(v)) { -#if 0 /* refix in the next release */ - rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)", - rb_builtin_class_name(e), i); - -#else - rb_warn("wrong element type %s at %ld (expected array)", - rb_builtin_class_name(e), i); - rb_warn("ignoring wrong elements is deprecated, remove them explicitly"); - rb_warn("this causes ArgumentError in the next release"); - continue; -#endif - } - switch (RARRAY_LEN(v)) { - default: - rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)", - RARRAY_LEN(v)); - case 2: - val = RARRAY_AREF(v, 1); - case 1: - key = RARRAY_AREF(v, 0); - hash_insert_raw(hv, tbl, key, val); - } - } - return hv; - } - - rb_raise(rb_eArgError, "odd number of arguments for Hash"); -} - /* * call-seq: * Hash[ key, value, ... ] -> new_hash @@ -753,11 +649,69 @@ rb_hash_new_from_object(VALUE klass, VAL https://github.com/ruby/ruby/blob/trunk/hash.c#L649 static VALUE rb_hash_s_create(int argc, VALUE *argv, VALUE klass) { - switch (argc) { - case 0: return hash_alloc(klass); - case 1: return rb_hash_new_from_object(klass, argv[0]); - default: return rb_hash_new_from_values_with_klass(argc, argv, klass); + VALUE hash, tmp; + int i; + + if (argc == 1) { + tmp = rb_hash_s_try_convert(Qnil, argv[0]); + if (!NIL_P(tmp)) { + hash = hash_alloc(klass); + if (RHASH(tmp)->ntbl) { + RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl); + } + return hash; + } + + tmp = rb_check_array_type(argv[0]); + if (!NIL_P(tmp)) { + long i; + + hash = hash_alloc(klass); + for (i = 0; i < RARRAY_LEN(tmp); ++i) { + VALUE e = RARRAY_AREF(tmp, i); + VALUE v = rb_check_array_type(e); + VALUE key, val = Qnil; + + if (NIL_P(v)) { +#if 0 /* refix in the next release */ + rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)", + rb_builtin_class_name(e), i); + +#else + rb_warn("wrong element type %s at %ld (expected array)", + rb_builtin_class_name(e), i); + rb_warn("ignoring wrong elements is deprecated, remove them explicitly"); + rb_warn("this causes ArgumentError in the next release"); + continue; +#endif + } + switch (RARRAY_LEN(v)) { + default: + rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)", + RARRAY_LEN(v)); + case 2: + val = RARRAY_AREF(v, 1); + case 1: + key = RARRAY_AREF(v, 0); + rb_hash_aset(hash, key, val); + } + } + return hash; + } } + if (argc % 2 != 0) { + rb_raise(rb_eArgError, "odd number of arguments for Hash"); + } + + hash = hash_alloc(klass); + if (argc > 0) { + RHASH(hash)->ntbl = st_init_table_with_size(&objhash, argc / 2); + } + for (i=0; i<argc; i+=2) { + rb_hash_aset(hash, argv[i], argv[i + 1]); + } + + return hash; } static VALUE -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/