[前][次][番号順一覧][スレッド一覧]

ruby-changes:53239

From: ko1 <ko1@a...>
Date: Wed, 31 Oct 2018 07:11:57 +0900 (JST)
Subject: [ruby-changes:53239] ko1:r65454 (trunk): support theap for T_HASH. [Feature #14989]

ko1	2018-10-31 07:11:51 +0900 (Wed, 31 Oct 2018)

  New Revision: 65454

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=65454

  Log:
    support theap for T_HASH. [Feature #14989]
    
    * hash.c, internal.h: support theap for small Hash.
      Introduce RHASH_ARRAY (li_table) besides st_table and small Hash
      (<=8 entries) are managed by an array data structure.
      This array data can be managed by theap.
      If st_table is needed, then converting array data to st_table data.
    
      For st_table using code, we prepare "stlike" APIs which accepts hash value
      and are very similar to st_ APIs.
    
      This work is based on the GSoC achievement
      by tacinight <tacingiht@g...> and refined by ko1.

  Modified files:
    trunk/.gdbinit
    trunk/array.c
    trunk/class.c
    trunk/compile.c
    trunk/debug_counter.h
    trunk/ext/objspace/objspace.c
    trunk/gc.c
    trunk/hash.c
    trunk/include/ruby/intern.h
    trunk/include/ruby/ruby.h
    trunk/include/ruby/st.h
    trunk/internal.h
    trunk/marshal.c
    trunk/mjit_worker.c
    trunk/process.c
    trunk/st.c
    trunk/test/ruby/test_time.rb
    trunk/thread.c
    trunk/transient_heap.c
    trunk/transient_heap.h
    trunk/vm_eval.c
    trunk/vm_insnhelper.c
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 65453)
+++ vm_insnhelper.c	(revision 65454)
@@ -3327,7 +3327,7 @@ vm_case_dispatch(CDHASH hash, OFFSET els https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3327
 		    key = FIXABLE(kval) ? LONG2FIX((long)kval) : rb_dbl2big(kval);
 		}
 	    }
-	    if (st_lookup(RHASH_TBL_RAW(hash), key, &val)) {
+	    if (rb_hash_stlike_lookup(hash, key, &val)) {
 		return FIX2LONG((VALUE)val);
 	    }
 	    else {
Index: gc.c
===================================================================
--- gc.c	(revision 65453)
+++ gc.c	(revision 65454)
@@ -2265,23 +2265,43 @@ obj_free(rb_objspace_t *objspace, VALUE https://github.com/ruby/ruby/blob/trunk/gc.c#L2265
         rb_ary_free(obj);
 	break;
       case T_HASH:
-	if (RANY(obj)->as.hash.ntbl) {
 #if USE_DEBUG_COUNTER
-            if (RHASH_SIZE(obj) >= 8) {
-                RB_DEBUG_COUNTER_INC(obj_hash_ge8);
-            }
-            if (RHASH_SIZE(obj) >= 4) {
-                RB_DEBUG_COUNTER_INC(obj_hash_ge4);
-            }
-            else {
-                RB_DEBUG_COUNTER_INC(obj_hash_under4);
-            }
-#endif
-            st_free_table(RANY(obj)->as.hash.ntbl);
-	}
+        if (RHASH_SIZE(obj) >= 8) {
+            RB_DEBUG_COUNTER_INC(obj_hash_ge8);
+        }
+        else if (RHASH_SIZE(obj) >= 4) {
+            RB_DEBUG_COUNTER_INC(obj_hash_ge4);
+        }
+        else if (RHASH_SIZE(obj) >= 1) {
+            RB_DEBUG_COUNTER_INC(obj_hash_under4);
+        }
         else {
             RB_DEBUG_COUNTER_INC(obj_hash_empty);
         }
+
+        if (RHASH_ARRAY_P(obj)) {
+            RB_DEBUG_COUNTER_INC(obj_hash_array);
+        }
+        else {
+            RB_DEBUG_COUNTER_INC(obj_hash_st);
+        }
+#endif
+        if (/* RHASH_ARRAY_P(obj) */ !FL_TEST_RAW(obj, RHASH_ST_TABLE_FLAG)) {
+            li_table *tab = RHASH(obj)->as.li;
+
+            if (tab) {
+                if (RHASH_TRANSIENT_P(obj)) {
+                    RB_DEBUG_COUNTER_INC(obj_hash_transient);
+                }
+                else {
+                    ruby_xfree(tab);
+                }
+            }
+        }
+        else {
+            GC_ASSERT(RHASH_TABLE_P(obj));
+            st_free_table(RHASH(obj)->as.st);
+        }
 	break;
       case T_REGEXP:
 	if (RANY(obj)->as.regexp.ptr) {
@@ -3337,8 +3357,12 @@ obj_memsize_of(VALUE obj, int use_all_ty https://github.com/ruby/ruby/blob/trunk/gc.c#L3357
 	size += rb_ary_memsize(obj);
 	break;
       case T_HASH:
-	if (RHASH(obj)->ntbl) {
-	    size += st_memsize(RHASH(obj)->ntbl);
+        if (RHASH_ARRAY_P(obj)) {
+	    size += sizeof(li_table);
+	}
+	else {
+            VM_ASSERT(RHASH_ST_TABLE(obj) != NULL);
+	    size += st_memsize(RHASH_ST_TABLE(obj));
 	}
 	break;
       case T_REGEXP:
@@ -3491,7 +3515,7 @@ count_objects(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/gc.c#L3515
         hash = rb_hash_new();
     }
     else if (!RHASH_EMPTY_P(hash)) {
-        st_foreach(RHASH_TBL_RAW(hash), set_zero, hash);
+        rb_hash_stlike_foreach(hash, set_zero, hash);
     }
     rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total));
     rb_hash_aset(hash, ID2SYM(rb_intern("FREE")), SIZET2NUM(freed));
@@ -4225,7 +4249,23 @@ mark_keyvalue(st_data_t key, st_data_t v https://github.com/ruby/ruby/blob/trunk/gc.c#L4249
 }
 
 static void
-mark_hash(rb_objspace_t *objspace, st_table *tbl)
+mark_hash(rb_objspace_t *objspace, VALUE hash)
+{
+    rb_hash_stlike_foreach(hash, mark_keyvalue, (st_data_t)objspace);
+
+    if (RHASH_ARRAY_P(hash)) {
+        if (objspace->mark_func_data == NULL && RHASH_TRANSIENT_P(hash)) {
+            rb_transient_heap_mark(hash, RHASH_ARRAY(hash));
+        }
+    }
+    else {
+        VM_ASSERT(!RHASH_TRANSIENT_P(hash));
+    }
+    gc_mark(objspace, RHASH(hash)->ifnone);
+}
+
+static void
+mark_st(rb_objspace_t *objspace, st_table *tbl)
 {
     if (!tbl) return;
     st_foreach(tbl, mark_keyvalue, (st_data_t)objspace);
@@ -4234,7 +4274,7 @@ mark_hash(rb_objspace_t *objspace, st_ta https://github.com/ruby/ruby/blob/trunk/gc.c#L4274
 void
 rb_mark_hash(st_table *tbl)
 {
-    mark_hash(&rb_objspace, tbl);
+    mark_st(&rb_objspace, tbl);
 }
 
 static void
@@ -4699,8 +4739,7 @@ gc_mark_children(rb_objspace_t *objspace https://github.com/ruby/ruby/blob/trunk/gc.c#L4739
 	break;
 
       case T_HASH:
-	mark_hash(objspace, any->as.hash.ntbl);
-	gc_mark(objspace, any->as.hash.ifnone);
+	mark_hash(objspace, obj);
 	break;
 
       case T_STRING:
@@ -9582,6 +9621,13 @@ rb_raw_obj_info(char *buff, const int bu https://github.com/ruby/ruby/blob/trunk/gc.c#L9621
 {
     if (SPECIAL_CONST_P(obj)) {
 	snprintf(buff, buff_size, "%s", obj_type_name(obj));
+
+        if (FIXNUM_P(obj)) {
+            snprintf(buff, buff_size, "%s %ld", buff, FIX2LONG(obj));
+        }
+        else if (SYMBOL_P(obj)) {
+            snprintf(buff, buff_size, "%s %s", buff, rb_id2name(SYM2ID(obj)));
+        }
     }
     else {
 #define TF(c) ((c) != 0 ? "true" : "false")
@@ -9658,6 +9704,13 @@ rb_raw_obj_info(char *buff, const int bu https://github.com/ruby/ruby/blob/trunk/gc.c#L9704
 	    snprintf(buff, buff_size, "%s %s", buff, RSTRING_PTR(obj));
 	    break;
 	  }
+          case T_HASH: {
+              snprintf(buff, buff_size, "%s [%c%c] %d", buff,
+                       RHASH_ARRAY_P(obj) ? 'A' : 'S',
+                       RHASH_TRANSIENT_P(obj) ? 'T' : ' ',
+                       (int)RHASH_SIZE(obj));
+              break;
+          }
 	  case T_CLASS: {
 	    VALUE class_path = rb_class_path_cached(obj);
 	    if (!NIL_P(class_path)) {
Index: .gdbinit
===================================================================
--- .gdbinit	(revision 65453)
+++ .gdbinit	(revision 65454)
@@ -156,8 +156,12 @@ define rp https://github.com/ruby/ruby/blob/trunk/.gdbinit#L156
   else
   if ($flags & RUBY_T_MASK) == RUBY_T_HASH
     printf "%sT_HASH%s: ", $color_type, $color_end,
-    if ((struct RHash *)($arg0))->ntbl
-      printf "len=%ld ", ((struct RHash *)($arg0))->ntbl->num_entries
+    if (((struct RHash *)($arg0))->basic->flags & RHASH_ST_TABLE_FLAG)
+      printf "st len=%ld ", ((struct RHash *)($arg0))->as.st->num_entries
+    else
+      printf "li len=%ld bound=%ld ", \
+        ((((struct RHash *)($arg0))->basic->flags & RHASH_ARRAY_LEN_MASK) >> RHASH_ARRAY_LEN_SHIFT), \
+        ((((struct RHash *)($arg0))->basic->flags & RHASH_ARRAY_BOUND_MASK) >> RHASH_ARRAY_BOUND_SHIFT)
     end
     print (struct RHash *)($arg0)
   else
Index: array.c
===================================================================
--- array.c	(revision 65453)
+++ array.c	(revision 65454)
@@ -4420,11 +4420,11 @@ static inline void https://github.com/ruby/ruby/blob/trunk/array.c#L4420
 ary_recycle_hash(VALUE hash)
 {
     assert(RBASIC_CLASS(hash) == 0);
-    if (RHASH(hash)->ntbl) {
-	st_table *tbl = RHASH(hash)->ntbl;
+    if (RHASH_TABLE_P(hash)) {
+	st_table *tbl = RHASH_ST_TABLE(hash);
 	st_free_table(tbl);
+	RHASH_CLEAR(hash);
     }
-    rb_gc_force_recycle(hash);
 }
 
 /*
@@ -4467,7 +4467,7 @@ rb_ary_diff(VALUE ary1, VALUE ary2) https://github.com/ruby/ruby/blob/trunk/array.c#L4467
 
     hash = ary_make_hash(ary2);
     for (i=0; i<RARRAY_LEN(ary1); i++) {
-	if (st_lookup(rb_hash_tbl_raw(hash), RARRAY_AREF(ary1, i), 0)) continue;
+	if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;
 	rb_ary_push(ary3, rb_ary_elt(ary1, i));
     }
     ary_recycle_hash(hash);
@@ -4515,7 +4515,7 @@ rb_ary_difference_multi(int argc, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L4515
         VALUE elt = rb_ary_elt(ary, i);
         for (j = 0; j < argc; j++){
             if (is_hash[j]) {
-                if (st_lookup(rb_hash_tbl_raw(argv[j]), RARRAY_AREF(ary, i), 0))
+                if (rb_hash_stlike_lookup(argv[j], RARRAY_AREF(ary, i), NULL))
                     break;
             }
             else {
@@ -4551,7 +4551,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L4551
 rb_ary_and(VALUE ary1, VALUE ary2)
 {
     VALUE hash, ary3, v;
-    st_table *table;
     st_data_t vv;
     long i;
 
@@ -4570,12 +4569,11 @@ rb_ary_and(VALUE ary1, VALUE ary2) https://github.com/ruby/ruby/blob/trunk/array.c#L4569
     }
 
     hash = ary_make_hash(ary2);
-    table = rb_hash_tbl_raw(hash);
 
     for (i=0; i<RARRAY_LEN(ary1); i++) {
 	v = RARRAY_AREF(ary1, i);
 	vv = (st_data_t)v;
-	if (st_delete(table, &vv, 0)) {
+	if (rb_hash_stlike_delete(hash, &vv, 0)) {
 	    rb_ary_push(ary3, v);
 	}
     }
@@ -4609,7 +4607,7 @@ rb_ary_union_hash(VALUE hash, VALUE ary2 https://github.com/ruby/ruby/blob/trunk/array.c#L4607
     long i;
     for (i = 0; i < RARRAY_LEN(ary2); i++) {
         VALUE elt = RARRAY_AREF(ary2, i);
-        if (!st_update(RHASH_TBL_RAW(hash), (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
+        if (!rb_hash_stlike_update(hash, (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
             RB_OBJ_WRITTEN(hash, Qundef, elt);
         }
     }
@@ -4866,7 +4864,7 @@ rb_ary_uniq_bang(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L4864
 	FL_SET_EMBED(ary);
     }
     ary_resize_capa(ary, hash_size);
-    st_foreach(rb_hash_tbl_raw(hash), push_value, ary);
+    rb_hash_foreach(hash, push_value, ary);
     ary_recycle_hash(hash);
 
     return ary;
Index: ext/objspace/objspace.c
===================================================================
--- ext/objspace/objspace.c	(revision 65453)
+++ ext/objspace/objspace.c	(revision 65454)
@@ -824,7 +824,7 @@ static int https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L824
 collect_values_of_values(VALUE category, VALUE category_objects, VALUE categories)
 {
     VALUE ary = rb_ary_new();
-    st_foreach(rb_hash_tbl(category_objects), collect_values, ary);
+    rb_hash_foreach(category_objects, collect_values, ary);
     rb_hash_aset(categories, category, ary);
     return ST_CONTINUE;
 }
Index: compile.c
===================================================================
--- compile.c	(revision 65453)
+++ compile.c	(revision 65454)
@@ -5017,7 +5017,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L5017
     INIT_ANCHOR(body_seq);
     INIT_ANCHOR(cond_seq);
 
-    rb_hash_tbl_raw(literals)->type = &cdhash_type;
+    RHASH_TBL_RAW(literals)->type = &cdhash_type;
 
     CHECK(COMPILE(head, "case base", node->nd_head));
 
@@ -7990,7 +7990,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L7990
 			    int i;
 			    VALUE map = rb_hash_new_with_size(RARRAY_LEN(op)/2);
 
-			    rb_hash_tbl_raw(map)->type = &cdhash_type;
+			    RHASH_TBL_RAW(map)->type = &cdhash_type;
 			    op = rb_to_array_type(op);
 			    for (i=0; i<RARRAY_LEN(op); i+=2) {
 				VALUE key = RARRAY_AREF(op, i);
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 65453)
+++ vm_eval.c	(revision 65454)
@@ -2035,10 +2035,9 @@ static void https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L2035
 local_var_list_add(const struct local_var_list *vars, ID lid)
 {
     if (lid && rb_is_local_id(lid)) {
-	/* should skip temporary variable */
-	st_table *tbl = RHASH_TBL_RAW(vars->tbl);
-	st_data_t idx = 0;	/* tbl->num_entries */
-	st_update(tbl, ID2SYM(lid), local_var_list_update, idx);
+        /* should skip temporary variable */
+        st_data_t idx = 0;	/* tbl->num_entries */
+        rb_hash_stlike_update(vars->tbl, ID2SYM(lid), local_var_list_update, idx);
     }
 }
 
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 65453)
+++ include/ruby/ruby.h	(revision 65454)
@@ -1088,11 +1088,13 @@ struct RRegexp { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1088
 #define RREGEXP_SRC_LEN(r) RSTRING_LEN(RREGEXP(r)->src)
 #define RREGEXP_SRC_END(r) RSTRING_END(RREGEXP(r)->src)
 
-/* RHASH_TBL allocates st_table if not available. */
-#define RHASH_TBL(h) rb_hash_tbl(h)
+/* RHash is defined at internal.h */
+size_t rb_hash_size_num(VALUE hash);
+
+#define RHASH_TBL(h) rb_hash_tbl(h, __FILE__, __LINE__)
 #define RHASH_ITER_LEV(h) rb_hash_iter_lev(h)
 #define RHASH_IFNONE(h) rb_hash_ifnone(h)
-#define RHASH_SIZE(h) NUM2SIZET(rb_hash_size(h))
+#define RHASH_SIZE(h) rb_hash_size_num(h)
 #define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)
 #define RHASH_SET_IFNONE(h, ifnone) rb_hash_set_ifnone((VALUE)h, ifnone)
 
Index: include/ruby/st.h
===================================================================
--- include/ruby/st.h	(revision 65453)
+++ include/ruby/st.h	(revision 65454)
@@ -143,7 +143,7 @@ CONSTFUNC(st_index_t st_hash_end(st_inde https://github.com/ruby/ruby/blob/trunk/include/ruby/st.h#L143
 CONSTFUNC(st_index_t st_hash_start(st_index_t h));
 #define st_hash_start(h) ((st_index_t)(h))
 
-void rb_hash_bulk_insert(long, const VALUE *, VALUE);
+void rb_hash_bulk_insert_into_st_table(long, const VALUE *, VALUE);
 
 RUBY_SYMBOL_EXPORT_END
 
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 65453)
+++ include/ruby/intern.h	(revision 65454)
@@ -520,11 +520,12 @@ VALUE rb_hash_delete(VALUE,VALUE); https://github.com/ruby/ruby/blob/trunk/include/ruby/intern.h#L520
 VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone);
 typedef VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value);
 VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func);
-struct st_table *rb_hash_tbl(VALUE);
+struct st_table *rb_hash_tbl(VALUE, const char *file, int line);
 int rb_path_check(const char*);
 int rb_env_path_tainted(void);
 VALUE rb_env_clear(void);
 VALUE rb_hash_size(VALUE);
+void rb_hash_free(VALUE);
 /* io.c */
 #define rb_defout rb_stdout
 RUBY_EXTERN VALUE rb_fs;
Index: test/ruby/test_time.rb
===================================================================
--- test/ruby/test_time.rb	(revision 65453)
+++ test/ruby/test_time.rb	(revision 65454)
@@ -1138,6 +1138,7 @@ class TestTime < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_time.rb#L1138
     case size
     when 20 then expect = 50
     when 40 then expect = 86
+    when 48 then expect = 94
     else
       flunk "Unsupported RVALUE_SIZE=#{size}, update test_memsize"
     end
Index: transient_heap.c
===================================================================
--- transient_heap.c	(revision 65453)
+++ transient_heap.c	(revision 65454)
@@ -353,9 +353,10 @@ rb_transient_heap_alloc(VALUE obj, size_ https://github.com/ruby/ruby/blob/trunk/transient_heap.c#L353
     struct transient_heap* theap = transient_heap_get();
     size_t size = ROUND_UP(req_size + sizeof(struct transient_alloc_header), TRANSIENT_HEAP_ALLOC_ALIGN);
 
-    TH_ASSERT(RB_TYPE_P(obj, T_ARRAY) ||
+    TH_ASSERT(RB_TYPE_P(obj, T_ARRAY)  ||
               RB_TYPE_P(obj, T_OBJECT) ||
-              RB_TYPE_P(obj, T_STRUCT)); /* supported types */
+              RB_TYPE_P(obj, T_STRUCT) ||
+              RB_TYPE_P(obj, T_HASH)); /* supported types */
 
     if (size > TRANSIENT_HEAP_ALLOC_MAX) {
         if (TRANSIENT_HEAP_DEBUG >= 3) fprintf(stderr, "rb_transient_heap_alloc: [too big: %ld] %s\n", (long)size, rb_obj_info(obj));
@@ -458,7 +459,6 @@ alloc_header_to_block_verbose(struct tra https://github.com/ruby/ruby/blob/trunk/transient_heap.c#L459
     else {
         return NULL;
     }
-    return block;
 }
 
 static struct transient_alloc_header *
@@ -508,7 +508,7 @@ void https://github.com/ruby/ruby/blob/trunk/transient_heap.c#L508
 rb_transient_heap_mark(VALUE obj, const void *ptr)
 {
     struct transient_alloc_header *header = ptr_to_alloc_header(ptr);
-
+    if (header->magic != TRANSIENT_HEAP_ALLOC_MAGIC) rb_bug("rb_transient_heap_mark: wrong header, %s (%p)", rb_obj_info(obj), ptr);
     if (TRANSIENT_HEAP_DEBUG >= 3) fprintf(stderr, "rb_transient_heap_mark: %s (%p)\n", rb_obj_info(obj), ptr);
 
 #if TRANSIENT_HEAP_CHECK_MODE > 0
@@ -522,7 +522,7 @@ rb_transient_heap_mark(VALUE obj, const https://github.com/ruby/ruby/blob/trunk/transient_heap.c#L522
             rb_bug("rb_transient_heap_mark: magic is broken");
         }
         else if (header->obj != obj) {
-            transient_heap_dump(theap);
+            // transient_heap_dump(theap);
             rb_bug("rb_transient_heap_mark: unmatch (%s is stored, but %s is given)\n",
                    rb_obj_info(header->obj), rb_obj_info(obj));
         }
@@ -566,6 +566,15 @@ transient_heap_ptr(VALUE obj, int error) https://github.com/ruby/ruby/blob/trunk/transient_heap.c#L566
             ptr = rb_struct_const_heap_ptr(obj);
         }
         break;
+      case T_HASH:
+        if (RHASH_TRANSIENT_P(obj)) {
+            TH_ASSERT(RHASH_ARRAY_P(obj));
+	    ptr = (VALUE *)(RHASH(obj)->as.li);
+	}
+	else {
+	    ptr = NULL;
+	}
+	break;
       default:
         if (error) {
             rb_bug("transient_heap_ptr: unknown obj %s\n", rb_obj_info(obj));
@@ -657,6 +666,8 @@ transient_heap_block_evacuate(struct tra https://github.com/ruby/ruby/blob/trunk/transient_heap.c#L666
     while (marked_index >= 0) {
         struct transient_alloc_header *header = alloc_header(block, marked_index);
         VALUE obj = header->obj;
+	TH_ASSERT(header->magic == TRANSIENT_HEAP_ALLOC_MAGIC);
+	if (header->magic != TRANSIENT_HEAP_ALLOC_MAGIC) rb_bug("rb_transient_heap_mark: wrong header %s\n", rb_obj_info(obj));
 
         if (TRANSIENT_HEAP_DEBUG >= 3) fprintf(stderr, " * transient_heap_block_evacuate %p %s\n", header, rb_obj_info(obj));
 
@@ -673,8 +684,11 @@ transient_heap_block_evacuate(struct tra https://github.com/ruby/ruby/blob/trunk/transient_heap.c#L684
               case T_STRUCT:
                 rb_struct_transient_heap_evacuate(obj, !TRANSIENT_HEAP_DEBUG_DONT_PROMOTE);
                 break;
+              case T_HASH:
+                rb_hash_transient_heap_evacuate(obj, !TRANSIENT_HEAP_DEBUG_DONT_PROMOTE);
+                break;
               default:
-                rb_bug("unsupporeted");
+                rb_bug("unsupporeted: %s\n", rb_obj_info(obj));
             }
             header->obj = Qundef; /* for debug */
         }
Index: thread.c
===================================================================
--- thread.c	(revision 65453)
+++ thread.c	(revision 65454)
@@ -3492,11 +3492,11 @@ rb_thread_variable_p(VALUE thread, VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L3492
 
     locals = rb_ivar_get(thread, id_locals);
 
-    if (!RHASH(locals)->ntbl)
+    if (rb_hash_lookup(locals, ID2SYM(id)) != Qnil) {
+        return Qtrue;
+    }
+    else {
         return Qfalse;
-
-    if (st_lookup(RHASH(locals)->ntbl, ID2SYM(id), 0)) {
-	return Qtrue;
     }
 
     return Qfalse;
@@ -4349,7 +4349,7 @@ rb_clear_coverages(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L4349
 {
     VALUE coverages = rb_get_coverages();
     if (RTEST(coverages)) {
-	st_foreach(rb_hash_tbl_raw(coverages), clear_coverage_i, 0);
+        rb_hash_foreach(coverages, clear_coverage_i, 0);
     }
 }
 
Index: transient_heap.h
===================================================================
--- transient_heap.h	(revision 65453)
+++ transient_heap.h	(revision 65454)
@@ -32,9 +32,9 @@ void rb_transient_heap_dump(void); https://github.com/ruby/ruby/blob/trunk/transient_heap.h#L32
 void rb_transient_heap_verify(void);
 int  rb_transient_heap_managed_ptr_p(const void *ptr);
 
-/* evacuate functions */
+/* evacuate functions for each type */
 void rb_ary_transient_heap_evacuate(VALUE ary, int promote);
 void rb_obj_transient_heap_evacuate(VALUE obj, int promote);
+void rb_hash_transient_heap_evacuate(VALUE hash, int promote);
 void rb_struct_transient_heap_evacuate(VALUE st, int promote);
-
 #endif
Index: process.c
=================================================================== (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]