dumping ground for random patches and texts
 help / color / mirror / Atom feed
* [PATCH] wip id_table conversion: too big
@ 2015-11-03  3:39 Eric Wong
  0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2015-11-03  3:39 UTC (permalink / raw)
  To: spew

Bah, split this shit out...
---
 class.c             |  22 +--
 gc.c                |  30 ++--
 include/ruby/ruby.h |   2 +-
 internal.h          |   7 +-
 marshal.c           |   2 +-
 variable.c          | 390 +++++++++++++++++++++++++++-------------------------
 vm_insnhelper.c     |  13 +-
 7 files changed, 249 insertions(+), 217 deletions(-)

diff --git a/class.c b/class.c
index 7a9db63..f7c8c86 100644
--- a/class.c
+++ b/class.c
@@ -324,7 +324,7 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
     RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig));
     RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
     if (RCLASS_IV_TBL(clone)) {
-	st_free_table(RCLASS_IV_TBL(clone));
+	rb_id_table_free(RCLASS_IV_TBL(clone));
 	RCLASS_IV_TBL(clone) = 0;
     }
     if (RCLASS_CONST_TBL(clone)) {
@@ -333,15 +333,15 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
     }
     RCLASS_M_TBL(clone) = 0;
     if (RCLASS_IV_TBL(orig)) {
-	st_data_t id;
+	ID id;
 
-	RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(orig));
+	RCLASS_IV_TBL(clone) = rb_id_table_copy(clone, RCLASS_IV_TBL(orig));
 	CONST_ID(id, "__tmp_classpath__");
-	st_delete(RCLASS_IV_TBL(clone), &id, 0);
+	rb_id_table_delete(RCLASS_IV_TBL(clone), id);
 	CONST_ID(id, "__classpath__");
-	st_delete(RCLASS_IV_TBL(clone), &id, 0);
+	rb_id_table_delete(RCLASS_IV_TBL(clone), id);
 	CONST_ID(id, "__classid__");
-	st_delete(RCLASS_IV_TBL(clone), &id, 0);
+	rb_id_table_delete(RCLASS_IV_TBL(clone), id);
     }
     if (RCLASS_CONST_TBL(orig)) {
 	struct clone_const_arg arg;
@@ -378,6 +378,7 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
     else {
 	/* copy singleton(unnamed) class */
 	VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
+	struct rb_id_table *orig_tbl;
 
 	if (BUILTIN_TYPE(obj) == T_CLASS) {
 	    RBASIC_SET_CLASS(clone, clone);
@@ -388,8 +389,9 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
 
 	RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass));
 	RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator;
-	if (RCLASS_IV_TBL(klass)) {
-	    RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(klass));
+	orig_tbl = RCLASS_IV_TBL(klass);
+	if (orig_tbl) {
+	    RCLASS_IV_TBL(clone) = rb_id_table_copy(clone, orig_tbl);
 	}
 	if (RCLASS_CONST_TBL(klass)) {
 	    struct clone_const_arg arg;
@@ -424,7 +426,7 @@ rb_singleton_class_attached(VALUE klass, VALUE obj)
 {
     if (FL_TEST(klass, FL_SINGLETON)) {
 	if (!RCLASS_IV_TBL(klass)) {
-	    RCLASS_IV_TBL(klass) = st_init_numtable();
+	    RCLASS_IV_TBL(klass) = rb_id_table_create(0);
 	}
 	rb_class_ivar_set(klass, id_attached, obj);
     }
@@ -807,7 +809,7 @@ rb_include_class_new(VALUE module, VALUE super)
 	module = RBASIC(module)->klass;
     }
     if (!RCLASS_IV_TBL(module)) {
-	RCLASS_IV_TBL(module) = st_init_numtable();
+	RCLASS_IV_TBL(module) = rb_id_table_create(0);
     }
     if (!RCLASS_CONST_TBL(module)) {
 	RCLASS_CONST_TBL(module) = st_init_numtable();
diff --git a/gc.c b/gc.c
index 1f8c849..9b54ec9 100644
--- a/gc.c
+++ b/gc.c
@@ -2077,13 +2077,13 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
       case T_CLASS:
 	rb_id_table_free(RCLASS_M_TBL(obj));
 	if (RCLASS_IV_TBL(obj)) {
-	    st_free_table(RCLASS_IV_TBL(obj));
+	    rb_id_table_free(RCLASS_IV_TBL(obj));
 	}
 	if (RCLASS_CONST_TBL(obj)) {
 	    rb_free_const_table(RCLASS_CONST_TBL(obj));
 	}
 	if (RCLASS_IV_INDEX_TBL(obj)) {
-	    st_free_table(RCLASS_IV_INDEX_TBL(obj));
+	    rb_id_table_free(RCLASS_IV_INDEX_TBL(obj));
 	}
 	if (RCLASS_EXT(obj)->subclasses) {
 	    if (BUILTIN_TYPE(obj) == T_MODULE) {
@@ -3072,13 +3072,13 @@ obj_memsize_of(VALUE obj, int use_all_types)
 	}
 	if (RCLASS_EXT(obj)) {
 	    if (RCLASS_IV_TBL(obj)) {
-		size += st_memsize(RCLASS_IV_TBL(obj));
+		size += rb_id_table_memsize(RCLASS_IV_TBL(obj));
 	    }
 	    if (RCLASS_IV_INDEX_TBL(obj)) {
-		size += st_memsize(RCLASS_IV_INDEX_TBL(obj));
+		size += rb_id_table_memsize(RCLASS_IV_INDEX_TBL(obj));
 	    }
 	    if (RCLASS(obj)->ptr->iv_tbl) {
-		size += st_memsize(RCLASS(obj)->ptr->iv_tbl);
+		size += rb_id_table_memsize(RCLASS(obj)->ptr->iv_tbl);
 	    }
 	    if (RCLASS(obj)->ptr->const_tbl) {
 		size += st_memsize(RCLASS(obj)->ptr->const_tbl);
@@ -4032,22 +4032,26 @@ mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
 }
 
 static enum rb_id_table_iterator_result
-mark_method_entry_i(VALUE me, void *data)
+mark_id_tbl_entry_i(VALUE val, void *data)
 {
     rb_objspace_t *objspace = (rb_objspace_t *)data;
 
-    gc_mark(objspace, me);
+    gc_mark(objspace, val);
     return ID_TABLE_CONTINUE;
 }
 
 static void
-mark_m_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
+mark_id_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
 {
     if (tbl) {
-	rb_id_table_foreach_values(tbl, mark_method_entry_i, objspace);
+	rb_id_table_foreach_values(tbl, mark_id_tbl_entry_i, objspace);
     }
 }
 
+RUBY_ALIAS_FUNCTION(
+		mark_m_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl),
+		mark_id_tbl, (objspace, tbl));
+
 static int
 mark_const_entry_i(st_data_t key, st_data_t value, st_data_t data)
 {
@@ -4130,6 +4134,12 @@ rb_mark_tbl(st_table *tbl)
     mark_tbl(&rb_objspace, tbl);
 }
 
+void
+rb_mark_id_table(struct rb_id_table *tbl)
+{
+    mark_id_tbl(&rb_objspace, tbl);
+}
+
 static void
 gc_mark_maybe(rb_objspace_t *objspace, VALUE obj)
 {
@@ -4383,7 +4393,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
       case T_MODULE:
 	mark_m_tbl(objspace, RCLASS_M_TBL(obj));
 	if (!RCLASS_EXT(obj)) break;
-	mark_tbl(objspace, RCLASS_IV_TBL(obj));
+	mark_id_tbl(objspace, RCLASS_IV_TBL(obj));
 	mark_const_tbl(objspace, RCLASS_CONST_TBL(obj));
 	gc_mark(objspace, RCLASS_SUPER((VALUE)obj));
 	break;
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index 52f27a7..6486344 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -903,7 +903,7 @@ struct RObject {
 	struct {
 	    long numiv; /* only uses 32-bits */
 	    VALUE *ivptr;
-            struct st_table *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
+            void *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
 	} heap;
 	VALUE ary[ROBJECT_EMBED_LEN_MAX];
     } as;
diff --git a/internal.h b/internal.h
index d135035..b4787f9 100644
--- a/internal.h
+++ b/internal.h
@@ -461,8 +461,8 @@ typedef unsigned long rb_serial_t;
 #endif
 
 struct rb_classext_struct {
-    struct st_table *iv_index_tbl;
-    struct st_table *iv_tbl;
+    struct rb_id_table *iv_index_tbl;
+    struct rb_id_table *iv_tbl;
     struct st_table *const_tbl;
     struct rb_id_table *callable_m_tbl;
     rb_subclass_entry_t *subclasses;
@@ -787,6 +787,7 @@ NORETURN(void rb_syserr_fail_path_in(const char *func_name, int err, VALUE path)
 #endif
 
 /* gc.c */
+void rb_mark_id_table(struct rb_id_table *);
 extern VALUE *ruby_initial_gc_stress_ptr;
 extern int ruby_disable_gc;
 void Init_heap(void);
@@ -1318,7 +1319,7 @@ void rb_gc_mark_global_tbl(void);
 void rb_mark_generic_ivar(VALUE);
 VALUE rb_const_missing(VALUE klass, VALUE name);
 int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
-st_table *rb_st_copy(VALUE obj, struct st_table *orig_tbl);
+struct rb_id_table *rb_id_table_copy(VALUE obj, struct rb_id_table *orig_tbl);
 
 /* gc.c (export) */
 VALUE rb_wb_protected_newobj_of(VALUE, VALUE);
diff --git a/marshal.c b/marshal.c
index 752f053..9b4a026 100644
--- a/marshal.c
+++ b/marshal.c
@@ -483,7 +483,7 @@ hash_each(VALUE key, VALUE value, struct dump_call_arg *arg)
 
 #define SINGLETON_DUMP_UNABLE_P(klass) \
     (rb_id_table_size(RCLASS_M_TBL(klass)) > 0 || \
-     (RCLASS_IV_TBL(klass) && RCLASS_IV_TBL(klass)->num_entries > 1))
+     (RCLASS_IV_TBL(klass) && rb_id_table_size(RCLASS_IV_TBL(klass)) > 1))
 
 static void
 w_extended(VALUE klass, struct dump_arg *arg, int check)
diff --git a/variable.c b/variable.c
index 000c48d..fba4d02 100644
--- a/variable.c
+++ b/variable.c
@@ -36,10 +36,10 @@ struct gen_ivtbl {
 
 struct ivar_update {
     union {
-	st_table *iv_index_tbl;
+	struct rb_id_table *iv_index_tbl;
 	struct gen_ivtbl *ivtbl;
     } u;
-    st_data_t index;
+    long index;
     int extended;
 };
 
@@ -72,11 +72,11 @@ fc_path(struct fc_result *fc, ID name)
 
     path = rb_id2str(name);
     while (fc) {
-	st_data_t n;
+	VALUE n;
 	if (fc->track == rb_cObject) break;
 	if (RCLASS_IV_TBL(fc->track) &&
-	    st_lookup(RCLASS_IV_TBL(fc->track), (st_data_t)classpath, &n)) {
-	    tmp = rb_str_dup((VALUE)n);
+	    rb_id_table_lookup(RCLASS_IV_TBL(fc->track), classpath, &n)) {
+	    tmp = rb_str_dup(n);
 	    rb_str_cat2(tmp, "::");
 	    rb_str_append(tmp, path);
 	    path = tmp;
@@ -155,13 +155,12 @@ find_class_path(VALUE klass, ID preferred)
 	st_foreach_safe(RCLASS_CONST_TBL(rb_cObject), fc_i, (st_data_t)&arg);
     }
     if (arg.path) {
-	st_data_t tmp = tmp_classpath;
 	if (!RCLASS_IV_TBL(klass)) {
-	    RCLASS_IV_TBL(klass) = st_init_numtable();
+	    RCLASS_IV_TBL(klass) = rb_id_table_create(0);
 	}
 	rb_class_ivar_set(klass, classpath, arg.path);
 
-	st_delete(RCLASS_IV_TBL(klass), &tmp, 0);
+	rb_id_table_delete(RCLASS_IV_TBL(klass), tmp_classpath);
 	return arg.path;
     }
     return Qnil;
@@ -178,16 +177,17 @@ static VALUE
 classname(VALUE klass, int *permanent)
 {
     VALUE path = Qnil;
-    st_data_t n;
+    VALUE n;
+    struct rb_id_table *tbl;
 
     if (!klass) klass = rb_cObject;
     *permanent = 1;
-    if (RCLASS_IV_TBL(klass)) {
-	if (!st_lookup(RCLASS_IV_TBL(klass), (st_data_t)classpath, &n)) {
+    tbl = RCLASS_IV_TBL(klass);
+    if (tbl) {
+	if (!rb_id_table_lookup(tbl, classpath, &n)) {
 	    ID cid = 0;
-	    if (st_lookup(RCLASS_IV_TBL(klass), (st_data_t)classid, &n)) {
-		VALUE cname = (VALUE)n;
-		cid = rb_check_id(&cname);
+	    if (rb_id_table_lookup(tbl, classid, &n)) {
+		cid = rb_check_id(&n);
 		if (cid) path = find_class_path(klass, cid);
 	    }
 	    if (NIL_P(path)) {
@@ -197,7 +197,7 @@ classname(VALUE klass, int *permanent)
 		if (!cid) {
 		    return Qnil;
 		}
-		if (!st_lookup(RCLASS_IV_TBL(klass), (st_data_t)tmp_classpath, &n)) {
+		if (!rb_id_table_lookup(tbl, tmp_classpath, &n)) {
 		    path = rb_id2str(cid);
 		    return path;
 		}
@@ -259,15 +259,15 @@ static VALUE
 rb_tmp_class_path(VALUE klass, int *permanent, path_cache_func cache_path)
 {
     VALUE path = classname(klass, permanent);
-    st_data_t n = (st_data_t)path;
+    VALUE n = path;
 
     if (!NIL_P(path)) {
 	return path;
     }
-    if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),
-					  (st_data_t)tmp_classpath, &n)) {
+    if (RCLASS_IV_TBL(klass) && rb_id_table_lookup(RCLASS_IV_TBL(klass),
+					           tmp_classpath, &n)) {
 	*permanent = 0;
-	return (VALUE)n;
+	return n;
     }
     else {
 	if (RB_TYPE_P(klass, T_MODULE)) {
@@ -317,12 +317,12 @@ rb_class_path_no_cache(VALUE klass)
 VALUE
 rb_class_path_cached(VALUE klass)
 {
-    st_table *ivtbl = RCLASS_IV_TBL(klass);
-    st_data_t n;
+    struct rb_id_table *ivtbl = RCLASS_IV_TBL(klass);
+    VALUE n;
 
     if (!ivtbl) return Qnil;
-    if (st_lookup(ivtbl, (st_data_t)classpath, &n)) return (VALUE)n;
-    if (st_lookup(ivtbl, (st_data_t)tmp_classpath, &n)) return (VALUE)n;
+    if (rb_id_table_lookup(ivtbl, classpath, &n)) return n;
+    if (rb_id_table_lookup(ivtbl, tmp_classpath, &n)) return n;
     return Qnil;
 }
 
@@ -954,10 +954,10 @@ struct gen_ivar_compat_tbl {
     st_table *tbl;
 };
 
-static int
-gen_ivar_compat_tbl_i(st_data_t id, st_data_t index, st_data_t arg)
+static enum rb_id_table_iterator_result
+gen_ivar_compat_tbl_i(ID id, VALUE index, void *arg)
 {
-    struct gen_ivar_compat_tbl *a = (struct gen_ivar_compat_tbl *)arg;
+    struct gen_ivar_compat_tbl *a = arg;
 
     if ((long)index < a->ivtbl->numiv) {
 	VALUE val = a->ivtbl->ivptr[index];
@@ -965,7 +965,7 @@ gen_ivar_compat_tbl_i(st_data_t id, st_data_t index, st_data_t arg)
 	    st_add_direct(a->tbl, id, (st_data_t)val);
 	}
     }
-    return ST_CONTINUE;
+    return ID_TABLE_CONTINUE;
 }
 
 static int
@@ -984,7 +984,7 @@ gen_ivtbl_get(VALUE obj, struct gen_ivtbl **ivtbl)
 st_table*
 rb_generic_ivar_table(VALUE obj)
 {
-    st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
+    struct rb_id_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
     struct gen_ivar_compat_tbl a;
     st_data_t d;
 
@@ -1007,7 +1007,7 @@ rb_generic_ivar_table(VALUE obj)
 	d = (st_data_t)a.tbl;
 	st_add_direct(generic_iv_tbl_compat, (st_data_t)obj, d);
     }
-    st_foreach_safe(iv_index_tbl, gen_ivar_compat_tbl_i, (st_data_t)&a);
+    rb_id_table_foreach(iv_index_tbl, gen_ivar_compat_tbl_i, &a);
 
     return a.tbl;
 }
@@ -1018,10 +1018,11 @@ generic_ivar_delete(VALUE obj, ID id, VALUE undef)
     struct gen_ivtbl *ivtbl;
 
     if (gen_ivtbl_get(obj, &ivtbl)) {
-	st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
-	st_data_t index;
+	struct rb_id_table *iv_index_tbl;
+	VALUE index;
 
-	if (st_lookup(iv_index_tbl, (st_data_t)id, &index)) {
+	iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
+	if (rb_id_table_lookup(iv_index_tbl, id, &index)) {
 	    if ((long)index < ivtbl->numiv) {
 		VALUE ret = ivtbl->ivptr[index];
 
@@ -1039,10 +1040,11 @@ generic_ivar_get(VALUE obj, ID id, VALUE undef)
     struct gen_ivtbl *ivtbl;
 
     if (gen_ivtbl_get(obj, &ivtbl)) {
-	st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
-	st_data_t index;
+	struct rb_id_table *iv_index_tbl;
+	VALUE index;
 
-	if (st_lookup(iv_index_tbl, (st_data_t)id, &index)) {
+	iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
+	if (rb_id_table_lookup(iv_index_tbl, id, &index)) {
 	    if ((long)index < ivtbl->numiv) {
 		VALUE ret = ivtbl->ivptr[index];
 
@@ -1088,10 +1090,11 @@ static long
 iv_index_tbl_newsize(struct ivar_update *ivup)
 {
     long newsize = (ivup->index+1) + (ivup->index+1)/4; /* (index+1)*1.25 */
+    size_t n;
 
     if (!ivup->extended &&
-        ivup->u.iv_index_tbl->num_entries < (st_index_t)newsize) {
-        newsize = ivup->u.iv_index_tbl->num_entries;
+        (n = rb_id_table_size(ivup->u.iv_index_tbl)) < (st_index_t)newsize) {
+        newsize = (long)n;
     }
     return newsize;
 }
@@ -1128,11 +1131,11 @@ static VALUE
 generic_ivar_defined(VALUE obj, ID id)
 {
     struct gen_ivtbl *ivtbl;
-    st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
-    st_data_t index;
+    struct rb_id_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
+    VALUE index;
 
     if (!iv_index_tbl) return Qfalse;
-    if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) return Qfalse;
+    if (!rb_id_table_lookup(iv_index_tbl, id, &index)) return Qfalse;
     if (!gen_ivtbl_get(obj, &ivtbl)) return Qfalse;
 
     if (((long)index < ivtbl->numiv) && (ivtbl->ivptr[index] != Qundef))
@@ -1145,12 +1148,11 @@ static int
 generic_ivar_remove(VALUE obj, ID id, VALUE *valp)
 {
     struct gen_ivtbl *ivtbl;
-    st_data_t key = (st_data_t)id;
-    st_data_t index;
-    st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
+    VALUE index;
+    struct rb_id_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
 
     if (!iv_index_tbl) return 0;
-    if (!st_lookup(iv_index_tbl, key, &index)) return 0;
+    if (!rb_id_table_lookup(iv_index_tbl, id, &index)) return 0;
     if (!gen_ivtbl_get(obj, &ivtbl)) return 0;
 
     if ((long)index < ivtbl->numiv) {
@@ -1229,18 +1231,18 @@ VALUE
 rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
 {
     VALUE val, *ptr;
-    struct st_table *iv_index_tbl;
+    struct rb_id_table *tbl;
     long len;
-    st_data_t index;
+    VALUE index;
 
     if (SPECIAL_CONST_P(obj)) return undef;
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
         len = ROBJECT_NUMIV(obj);
         ptr = ROBJECT_IVPTR(obj);
-        iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
-        if (!iv_index_tbl) break;
-        if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
+        tbl = ROBJECT_IV_INDEX_TBL(obj);
+        if (!tbl) break;
+        if (!rb_id_table_lookup(tbl, id, &index)) break;
         if (len <= (long)index) break;
         val = ptr[index];
         if (val != Qundef)
@@ -1248,9 +1250,9 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
 	break;
       case T_CLASS:
       case T_MODULE:
-	if (RCLASS_IV_TBL(obj) &&
-		st_lookup(RCLASS_IV_TBL(obj), (st_data_t)id, &index))
-	    return (VALUE)index;
+	tbl = RCLASS_IV_TBL(obj);
+	if (tbl && rb_id_table_lookup(tbl, id, &index))
+	    return index;
 	break;
       default:
 	if (FL_TEST(obj, FL_EXIVAR))
@@ -1283,18 +1285,18 @@ static VALUE
 rb_ivar_delete(VALUE obj, ID id, VALUE undef)
 {
     VALUE val, *ptr;
-    struct st_table *iv_index_tbl;
+    struct rb_id_table *tbl;
     long len;
-    st_data_t index;
+    VALUE index;
 
     rb_check_frozen(obj);
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
         len = ROBJECT_NUMIV(obj);
         ptr = ROBJECT_IVPTR(obj);
-        iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
-        if (!iv_index_tbl) break;
-        if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
+        tbl = ROBJECT_IV_INDEX_TBL(obj);
+        if (!tbl) break;
+        if (!rb_id_table_lookup(tbl, id, &index)) break;
         if (len <= (long)index) break;
         val = ptr[index];
         ptr[index] = Qundef;
@@ -1303,9 +1305,9 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef)
 	break;
       case T_CLASS:
       case T_MODULE:
-	if (RCLASS_IV_TBL(obj) &&
-		st_delete(RCLASS_IV_TBL(obj), (st_data_t *)&id, &index))
-	    return (VALUE)index;
+	tbl = RCLASS_IV_TBL(obj);
+	if (tbl && rb_id_table_lookup(tbl, id, &index))
+	    return index;
 	break;
       default:
 	if (FL_TEST(obj, FL_EXIVAR))
@@ -1321,14 +1323,14 @@ rb_attr_delete(VALUE obj, ID id)
     return rb_ivar_delete(obj, id, Qnil);
 }
 
-static st_table *
+static struct rb_id_table *
 iv_index_tbl_make(VALUE obj)
 {
     VALUE klass = rb_obj_class(obj);
-    st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(klass);
+    struct rb_id_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(klass);
 
     if (!iv_index_tbl) {
-	iv_index_tbl = RCLASS_IV_INDEX_TBL(klass) = st_init_numtable();
+	iv_index_tbl = RCLASS_IV_INDEX_TBL(klass) = rb_id_table_create(0);
     }
 
     return iv_index_tbl;
@@ -1337,14 +1339,14 @@ iv_index_tbl_make(VALUE obj)
 static void
 iv_index_tbl_extend(struct ivar_update *ivup, ID id)
 {
-    if (st_lookup(ivup->u.iv_index_tbl, (st_data_t)id, &ivup->index)) {
+    if (rb_id_table_lookup(ivup->u.iv_index_tbl, id, (VALUE *)&ivup->index)) {
 	return;
     }
-    if (ivup->u.iv_index_tbl->num_entries >= INT_MAX) {
+    if (rb_id_table_size(ivup->u.iv_index_tbl) >= INT_MAX) {
 	rb_raise(rb_eArgError, "too many instance variables");
     }
-    ivup->index = (st_data_t)ivup->u.iv_index_tbl->num_entries;
-    st_add_direct(ivup->u.iv_index_tbl, (st_data_t)id, ivup->index);
+    ivup->index = (long)rb_id_table_size(ivup->u.iv_index_tbl);
+    rb_id_table_insert(ivup->u.iv_index_tbl, id, (VALUE)ivup->index);
     ivup->extended = 1;
 }
 
@@ -1411,7 +1413,7 @@ rb_ivar_set(VALUE obj, ID id, VALUE val)
 	break;
       case T_CLASS:
       case T_MODULE:
-	if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = st_init_numtable();
+	if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = rb_id_table_create(0);
 	rb_class_ivar_set(obj, id, val);
         break;
       default:
@@ -1425,15 +1427,15 @@ VALUE
 rb_ivar_defined(VALUE obj, ID id)
 {
     VALUE val;
-    struct st_table *iv_index_tbl;
-    st_data_t index;
+    struct rb_id_table *tbl;
+    VALUE index;
 
     if (SPECIAL_CONST_P(obj)) return Qfalse;
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
-        iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
-        if (!iv_index_tbl) break;
-        if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
+        tbl = ROBJECT_IV_INDEX_TBL(obj);
+        if (!tbl) break;
+        if (!rb_id_table_lookup(tbl, id, &index)) break;
         if (ROBJECT_NUMIV(obj) <= (long)index) break;
         val = ROBJECT_IVPTR(obj)[index];
         if (val != Qundef)
@@ -1441,7 +1443,8 @@ rb_ivar_defined(VALUE obj, ID id)
 	break;
       case T_CLASS:
       case T_MODULE:
-	if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), (st_data_t)id, 0))
+	tbl = RCLASS_IV_TBL(obj);
+	if (tbl && rb_id_table_lookup(tbl, id, &index))
 	    return Qtrue;
 	break;
       default:
@@ -1458,26 +1461,26 @@ struct obj_ivar_tag {
     st_data_t arg;
 };
 
-static int
-obj_ivar_i(st_data_t key, st_data_t index, st_data_t arg)
+static enum rb_id_table_iterator_result
+obj_ivar_i(ID key, VALUE index, void *arg)
 {
-    struct obj_ivar_tag *data = (struct obj_ivar_tag *)arg;
+    struct obj_ivar_tag *data = arg;
+
     if ((long)index < ROBJECT_NUMIV(data->obj)) {
         VALUE val = ROBJECT_IVPTR(data->obj)[(long)index];
         if (val != Qundef) {
-            return (data->func)((ID)key, val, data->arg);
+            return (data->func)(key, val, data->arg);
         }
     }
-    return ST_CONTINUE;
+    return ID_TABLE_CONTINUE;
 }
 
 static void
 obj_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
 {
-    st_table *tbl;
     struct obj_ivar_tag data;
+    struct rb_id_table *tbl = ROBJECT_IV_INDEX_TBL(obj);
 
-    tbl = ROBJECT_IV_INDEX_TBL(obj);
     if (!tbl)
         return;
 
@@ -1485,7 +1488,7 @@ obj_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
     data.func = (int (*)(ID key, VALUE val, st_data_t arg))func;
     data.arg = arg;
 
-    st_foreach_safe(tbl, obj_ivar_i, (st_data_t)&data);
+    rb_id_table_foreach(tbl, obj_ivar_i, &data);
 }
 
 struct gen_ivar_tag {
@@ -1494,25 +1497,25 @@ struct gen_ivar_tag {
     st_data_t arg;
 };
 
-static int
-gen_ivar_each_i(st_data_t key, st_data_t index, st_data_t data)
+static enum rb_id_table_iterator_result
+gen_ivar_each_i(ID key, VALUE index, void *data)
 {
-    struct gen_ivar_tag *arg = (struct gen_ivar_tag *)data;
+    struct gen_ivar_tag *arg = data;
 
     if ((long)index < arg->ivtbl->numiv) {
         VALUE val = arg->ivtbl->ivptr[index];
         if (val != Qundef) {
-            return (arg->func)((ID)key, val, arg->arg);
+            return (arg->func)(key, val, arg->arg);
         }
     }
-    return ST_CONTINUE;
+    return ID_TABLE_CONTINUE;
 }
 
 static void
-gen_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
+gen_ivar_each(VALUE obj, rb_id_table_foreach_func_t *func, st_data_t arg)
 {
     struct gen_ivar_tag data;
-    st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
+    struct rb_id_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
 
     if (!iv_index_tbl) return;
     if (!gen_ivtbl_get(obj, &data.ivtbl)) return;
@@ -1520,19 +1523,19 @@ gen_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
     data.func = (int (*)(ID key, VALUE val, st_data_t arg))func;
     data.arg = arg;
 
-    st_foreach_safe(iv_index_tbl, gen_ivar_each_i, (st_data_t)&data);
+    rb_id_table_foreach(iv_index_tbl, gen_ivar_each_i, &data);
 }
 
 struct givar_copy {
     VALUE obj;
-    st_table *iv_index_tbl;
+    struct rb_id_table *iv_index_tbl;
     struct gen_ivtbl *ivtbl;
 };
 
-static int
-gen_ivar_copy(ID id, VALUE val, st_data_t arg)
+static enum rb_id_table_iterator_result
+gen_ivar_copy(ID id, VALUE val, void *arg)
 {
-    struct givar_copy *c = (struct givar_copy *)arg;
+    struct givar_copy *c = arg;
     struct ivar_update ivup;
 
     ivup.extended = 0;
@@ -1547,7 +1550,7 @@ gen_ivar_copy(ID id, VALUE val, st_data_t arg)
 
     RB_OBJ_WRITTEN(c->obj, Qundef, val);
 
-    return ST_CONTINUE;
+    return ID_TABLE_CONTINUE;
 }
 
 void
@@ -1603,12 +1606,14 @@ rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
       case T_CLASS:
       case T_MODULE:
 	if (RCLASS_IV_TBL(obj)) {
-	    st_foreach_safe(RCLASS_IV_TBL(obj), func, arg);
+	    rb_id_table_foreach(RCLASS_IV_TBL(obj),
+	       (rb_id_table_foreach_func_t *)func,
+	       (void *)arg);
 	}
 	break;
       default:
 	if (FL_TEST(obj, FL_EXIVAR)) {
-	    gen_ivar_each(obj, func, arg);
+	    gen_ivar_each(obj, (rb_id_table_foreach_func_t *)func, arg);
 	}
 	break;
     }
@@ -1617,14 +1622,14 @@ rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
 st_index_t
 rb_ivar_count(VALUE obj)
 {
-    st_table *tbl;
+    struct rb_id_table *tbl;
 
     if (SPECIAL_CONST_P(obj)) return 0;
 
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
 	if ((tbl = ROBJECT_IV_INDEX_TBL(obj)) != 0) {
-	    st_index_t i, count, num = tbl->num_entries;
+	    size_t i, count, num = rb_id_table_size(tbl);
 	    const VALUE *const ivptr = ROBJECT_IVPTR(obj);
 	    for (i = count = 0; i < num; ++i) {
 		if (ivptr[i] != Qundef) {
@@ -1637,7 +1642,7 @@ rb_ivar_count(VALUE obj)
       case T_CLASS:
       case T_MODULE:
 	if ((tbl = RCLASS_IV_TBL(obj)) != 0) {
-	    return tbl->num_entries;
+	    return rb_id_table_size(tbl);
 	}
 	break;
       default:
@@ -1740,9 +1745,8 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name)
 {
     VALUE val = Qnil;
     const ID id = id_for_var(obj, name, an, instance);
-    st_data_t n, v;
-    struct st_table *iv_index_tbl;
-    st_data_t index;
+    struct rb_id_table *iv_tbl;
+    VALUE index;
 
     rb_check_frozen(obj);
     if (!id) {
@@ -1751,9 +1755,9 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name)
 
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
-        iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
-        if (!iv_index_tbl) break;
-        if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
+        iv_tbl = ROBJECT_IV_INDEX_TBL(obj);
+        if (!iv_tbl) break;
+        if (!rb_id_table_lookup(iv_tbl, id, &index)) break;
         if (ROBJECT_NUMIV(obj) <= (long)index) break;
         val = ROBJECT_IVPTR(obj)[index];
         if (val != Qundef) {
@@ -1763,9 +1767,11 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name)
 	break;
       case T_CLASS:
       case T_MODULE:
-	n = id;
-	if (RCLASS_IV_TBL(obj) && st_delete(RCLASS_IV_TBL(obj), &n, &v)) {
-	    return (VALUE)v;
+	iv_tbl = RCLASS_IV_TBL(obj);
+	if (!iv_tbl) break;
+	if (rb_id_table_lookup(iv_tbl, id, &val)) {
+	    rb_id_table_delete(iv_tbl, id);
+	    return val;
 	}
 	break;
       default:
@@ -1852,20 +1858,20 @@ rb_mod_const_missing(VALUE klass, VALUE name)
 static void
 autoload_mark(void *ptr)
 {
-    rb_mark_tbl((st_table *)ptr);
+    rb_mark_id_table((struct rb_id_table *)ptr);
 }
 
 static void
 autoload_free(void *ptr)
 {
-    st_free_table((st_table *)ptr);
+    rb_id_table_free((struct rb_id_table *)ptr);
 }
 
 static size_t
 autoload_memsize(const void *ptr)
 {
-    const st_table *tbl = ptr;
-    return st_memsize(tbl);
+    const struct rb_id_table *tbl = ptr;
+    return rb_id_table_memsize(tbl);
 }
 
 static const rb_data_type_t autoload_data_type = {
@@ -1875,20 +1881,20 @@ static const rb_data_type_t autoload_data_type = {
 };
 
 #define check_autoload_table(av) \
-    (struct st_table *)rb_check_typeddata((av), &autoload_data_type)
+    (struct rb_id_table *)rb_check_typeddata((av), &autoload_data_type)
 
 static VALUE
 autoload_data(VALUE mod, ID id)
 {
-    struct st_table *tbl;
-    st_data_t val;
+    struct rb_id_table *tbl;
+    VALUE val;
 
-    if (!st_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
-	    !(tbl = check_autoload_table((VALUE)val)) ||
-	    !st_lookup(tbl, (st_data_t)id, &val)) {
+    if (!rb_id_table_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
+	    !(tbl = check_autoload_table(val)) ||
+	    !rb_id_table_lookup(tbl, id, &val)) {
 	return 0;
     }
-    return (VALUE)val;
+    return val;
 }
 
 /* always on stack, no need to mark */
@@ -1937,9 +1943,9 @@ static const rb_data_type_t autoload_data_i_type = {
 void
 rb_autoload(VALUE mod, ID id, const char *file)
 {
-    st_data_t av;
+    VALUE av;
     VALUE ad, fn;
-    struct st_table *tbl;
+    struct rb_id_table *tbl;
     struct autoload_data_i *ele;
     rb_const_entry_t *ce;
 
@@ -1958,15 +1964,15 @@ rb_autoload(VALUE mod, ID id, const char *file)
 
     rb_const_set(mod, id, Qundef);
     tbl = RCLASS_IV_TBL(mod);
-    if (tbl && st_lookup(tbl, (st_data_t)autoload, &av)) {
-	tbl = check_autoload_table((VALUE)av);
+    if (tbl && rb_id_table_lookup(tbl, autoload, &av)) {
+	tbl = check_autoload_table(av);
     }
     else {
-	if (!tbl) tbl = RCLASS_IV_TBL(mod) = st_init_numtable();
-	av = (st_data_t)TypedData_Wrap_Struct(0, &autoload_data_type, 0);
-	st_add_direct(tbl, (st_data_t)autoload, av);
+	if (!tbl) tbl = RCLASS_IV_TBL(mod) = rb_id_table_create(0);
+	av = TypedData_Wrap_Struct(0, &autoload_data_type, 0);
+	rb_id_table_insert(tbl, autoload, av);
 	RB_OBJ_WRITTEN(mod, Qnil, av);
-	DATA_PTR(av) = tbl = st_init_numtable();
+	DATA_PTR(av) = tbl = rb_id_table_create(0);
     }
     fn = rb_str_new2(file);
     FL_UNSET(fn, FL_TAINT);
@@ -1977,22 +1983,21 @@ rb_autoload(VALUE mod, ID id, const char *file)
     ele->safe_level = rb_safe_level();
     ele->value = Qundef;
     ele->state = 0;
-    st_insert(tbl, (st_data_t)id, (st_data_t)ad);
+    rb_id_table_insert(tbl, id, ad);
 }
 
 static void
 autoload_delete(VALUE mod, ID id)
 {
-    st_data_t val, load = 0, n = id;
+    VALUE val;
 
-    if (st_lookup(RCLASS_IV_TBL(mod), (st_data_t)autoload, &val)) {
-	struct st_table *tbl = check_autoload_table((VALUE)val);
+    if (rb_id_table_lookup(RCLASS_IV_TBL(mod), autoload, &val)) {
+	struct rb_id_table *tbl = check_autoload_table(val);
 
-	st_delete(tbl, &n, &load);
+	rb_id_table_delete(tbl, id);
 
-	if (tbl->num_entries == 0) {
-	    n = autoload;
-	    st_delete(RCLASS_IV_TBL(mod), &n, &val);
+	if (rb_id_table_size(tbl) == 0) {
+	    rb_id_table_delete(RCLASS_IV_TBL(mod), autoload);
 	}
     }
 }
@@ -2742,10 +2747,10 @@ original_module(VALUE c)
 }
 
 static int
-cvar_lookup_at(VALUE klass, ID id, st_data_t *v)
+cvar_lookup_at(VALUE klass, ID id, VALUE *v)
 {
     if (!RCLASS_IV_TBL(klass)) return 0;
-    return st_lookup(RCLASS_IV_TBL(klass), (st_data_t)id, v);
+    return rb_id_table_lookup(RCLASS_IV_TBL(klass), id, v);
 }
 
 static VALUE
@@ -2776,20 +2781,19 @@ void
 rb_cvar_set(VALUE klass, ID id, VALUE val)
 {
     VALUE tmp, front = 0, target = 0;
+    VALUE ignore;
 
     tmp = klass;
-    CVAR_LOOKUP(0, {if (!front) front = klass; target = klass;});
+    CVAR_LOOKUP(&ignore, {if (!front) front = klass; target = klass;});
     if (target) {
 	if (front && target != front) {
-	    st_data_t did = id;
-
 	    if (RTEST(ruby_verbose)) {
 		rb_warning("class variable %"PRIsVALUE" of %"PRIsVALUE" is overtaken by %"PRIsVALUE"",
 			   QUOTE_ID(id), rb_class_name(original_module(front)),
 			   rb_class_name(original_module(target)));
 	    }
 	    if (BUILTIN_TYPE(front) == T_CLASS) {
-		st_delete(RCLASS_IV_TBL(front),&did,0);
+		rb_id_table_delete(RCLASS_IV_TBL(front), id);
 	    }
 	}
     }
@@ -2799,7 +2803,7 @@ rb_cvar_set(VALUE klass, ID id, VALUE val)
 
     check_before_mod_set(target, id, val, "class variable");
     if (!RCLASS_IV_TBL(target)) {
-	RCLASS_IV_TBL(target) = st_init_numtable();
+	RCLASS_IV_TBL(target) = rb_id_table_create(0);
     }
 
     rb_class_ivar_set(target, id, val);
@@ -2809,7 +2813,7 @@ VALUE
 rb_cvar_get(VALUE klass, ID id)
 {
     VALUE tmp, front = 0, target = 0;
-    st_data_t value;
+    VALUE value;
 
     tmp = klass;
     CVAR_LOOKUP(&value, {if (!front) front = klass; target = klass;});
@@ -2818,15 +2822,13 @@ rb_cvar_get(VALUE klass, ID id)
 			  tmp, ID2SYM(id));
     }
     if (front && target != front) {
-	st_data_t did = id;
-
 	if (RTEST(ruby_verbose)) {
 	    rb_warning("class variable %"PRIsVALUE" of %"PRIsVALUE" is overtaken by %"PRIsVALUE"",
 		       QUOTE_ID(id), rb_class_name(original_module(front)),
 		       rb_class_name(original_module(target)));
 	}
 	if (BUILTIN_TYPE(front) == T_CLASS) {
-	    st_delete(RCLASS_IV_TBL(front),&did,0);
+	    rb_id_table_delete(RCLASS_IV_TBL(front), id);
 	}
     }
     return (VALUE)value;
@@ -2835,8 +2837,9 @@ rb_cvar_get(VALUE klass, ID id)
 VALUE
 rb_cvar_defined(VALUE klass, ID id)
 {
+    VALUE ignore;
     if (!klass) return Qfalse;
-    CVAR_LOOKUP(0,return Qtrue);
+    CVAR_LOOKUP(&ignore,return Qtrue);
     return Qfalse;
 }
 
@@ -2872,33 +2875,35 @@ rb_define_class_variable(VALUE klass, const char *name, VALUE val)
     rb_cvar_set(klass, id, val);
 }
 
-static int
-cv_i(st_data_t k, st_data_t v, st_data_t a)
+static enum rb_id_table_iterator_result
+cv_i(ID key, VALUE v, void *a)
 {
-    ID key = (ID)k;
-    st_table *tbl = (st_table *)a;
+    struct rb_id_table *tbl = a;
+    VALUE ignored;
 
     if (rb_is_class_id(key)) {
-	st_update(tbl, (st_data_t)key, cv_i_update, 0);
+	if (!rb_id_table_lookup(tbl, key, &ignored)) {
+	    rb_id_table_insert(tbl, key, (VALUE)a);
+	}
     }
-    return ST_CONTINUE;
+    return ID_TABLE_CONTINUE;
 }
 
-static void*
-mod_cvar_at(VALUE mod, void *data)
+static struct rb_id_table *
+mod_cvar_at(VALUE mod, struct rb_id_table *data)
 {
-    st_table *tbl = data;
+    struct rb_id_table *tbl = data;
     if (!tbl) {
-	tbl = st_init_numtable();
+	tbl = rb_id_table_create(0);
     }
     if (RCLASS_IV_TBL(mod)) {
-	st_foreach_safe(RCLASS_IV_TBL(mod), cv_i, (st_data_t)tbl);
+	rb_id_table_foreach(RCLASS_IV_TBL(mod), cv_i, tbl);
     }
     return tbl;
 }
 
-static void*
-mod_cvar_of(VALUE mod, void *data)
+static struct rb_id_table *
+mod_cvar_of(VALUE mod, struct rb_id_table *data)
 {
     VALUE tmp = mod;
     for (;;) {
@@ -2909,24 +2914,22 @@ mod_cvar_of(VALUE mod, void *data)
     return data;
 }
 
-static int
-cv_list_i(st_data_t key, st_data_t value, VALUE ary)
+static enum rb_id_table_iterator_result
+cv_list_i(ID sym, VALUE ignored, void *ary)
 {
-    ID sym = (ID)key;
-    rb_ary_push(ary, ID2SYM(sym));
-    return ST_CONTINUE;
+    rb_ary_push((VALUE)ary, ID2SYM(sym));
+    return ID_TABLE_CONTINUE;
 }
 
 static VALUE
-cvar_list(void *data)
+cvar_list(struct rb_id_table *tbl)
 {
-    st_table *tbl = data;
     VALUE ary;
 
     if (!tbl) return rb_ary_new2(0);
-    ary = rb_ary_new2(tbl->num_entries);
-    st_foreach_safe(tbl, cv_list_i, ary);
-    st_free_table(tbl);
+    ary = rb_ary_new2(rb_id_table_size(tbl));
+    rb_id_table_foreach(tbl, cv_list_i, (void*)ary);
+    rb_id_table_free(tbl);
 
     return ary;
 }
@@ -2955,7 +2958,7 @@ VALUE
 rb_mod_class_variables(int argc, const VALUE *argv, VALUE mod)
 {
     VALUE inherit;
-    st_table *tbl;
+    struct rb_id_table *tbl;
 
     if (argc == 0) {
 	inherit = Qtrue;
@@ -2996,7 +2999,8 @@ VALUE
 rb_mod_remove_cvar(VALUE mod, VALUE name)
 {
     const ID id = id_for_var_message(mod, name, class, "wrong class variable name %1$s");
-    st_data_t val, n = id;
+    VALUE val;
+    struct rb_id_table *tbl;
 
     if (!id) {
       not_defined:
@@ -3004,8 +3008,10 @@ rb_mod_remove_cvar(VALUE mod, VALUE name)
 			  mod, name);
     }
     rb_check_frozen(mod);
-    if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), &n, &val)) {
-	return (VALUE)val;
+    tbl = RCLASS_IV_TBL(mod);
+    if (tbl && rb_id_table_lookup(tbl, id, &val)) {
+	rb_id_table_delete(tbl, id);
+	return val;
     }
     if (rb_cvar_defined(mod, id)) {
 	rb_name_err_raise("cannot remove %1$s for %2$s", mod, ID2SYM(id));
@@ -3033,25 +3039,37 @@ rb_iv_set(VALUE obj, const char *name, VALUE val)
 int
 rb_class_ivar_set(VALUE obj, ID key, VALUE value)
 {
-    st_table *tbl = RCLASS_IV_TBL(obj);
-    int result = st_insert(tbl, (st_data_t)key, (st_data_t)value);
+    int result = rb_id_table_insert(RCLASS_IV_TBL(obj), key, value);
     RB_OBJ_WRITTEN(obj, Qundef, value);
     return result;
 }
 
-static int
-tbl_copy_i(st_data_t key, st_data_t value, st_data_t data)
+struct tbl_copy {
+    VALUE obj;
+    struct rb_id_table *new_tbl;
+};
+
+static enum rb_id_table_iterator_result
+tbl_copy_i(ID id, VALUE value, void *ptr)
 {
-    RB_OBJ_WRITTEN((VALUE)data, Qundef, (VALUE)value);
-    return ST_CONTINUE;
+    struct tbl_copy *c = ptr;
+
+    rb_id_table_insert(c->new_tbl, id, value);
+    RB_OBJ_WRITTEN(c->obj, Qundef, value);
+
+    return ID_TABLE_CONTINUE;
 }
 
-st_table *
-rb_st_copy(VALUE obj, struct st_table *orig_tbl)
+struct rb_id_table *
+rb_id_table_copy(VALUE obj, struct rb_id_table *orig_tbl)
 {
-    st_table *new_tbl = st_copy(orig_tbl);
-    st_foreach(new_tbl, tbl_copy_i, (st_data_t)obj);
-    return new_tbl;
+    struct tbl_copy c;
+
+    c.obj = obj;
+    c.new_tbl = rb_id_table_create(0);
+    rb_id_table_foreach(orig_tbl, tbl_copy_i, &c);
+
+    return c.new_tbl;
 }
 
 rb_const_entry_t *
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 4130c17..d919de3 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -15,6 +15,7 @@
 #include "internal.h"
 #include "probes.h"
 #include "probes_helper.h"
+#include "id_table.h"
 
 /* control stack frame */
 
@@ -754,11 +755,11 @@ vm_getivar(VALUE obj, ID id, IC ic, struct rb_call_cache *cc, int is_attr)
 	    }
 	}
 	else {
-	    st_data_t index;
-	    struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
+	    VALUE index;
+	    struct rb_id_table *tbl = ROBJECT_IV_INDEX_TBL(obj);
 
-	    if (iv_index_tbl) {
-		if (st_lookup(iv_index_tbl, id, &index)) {
+	    if (tbl) {
+		if (rb_id_table_lookup(tbl, id, &index)) {
 		    if ((long)index < len) {
 			val = ptr[index];
 		    }
@@ -809,9 +810,9 @@ vm_setivar(VALUE obj, ID id, VALUE val, IC ic, struct rb_call_cache *cc, int is_
 	    }
 	}
 	else {
-	    struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
+	    struct rb_id_table *tbl = ROBJECT_IV_INDEX_TBL(obj);
 
-	    if (iv_index_tbl && st_lookup(iv_index_tbl, (st_data_t)id, &index)) {
+	    if (tbl && rb_id_table_lookup(tbl, id, (VALUE *)&index)) {
 		if (!is_attr) {
 		    ic->ic_value.index = index;
 		    ic->ic_serial = RCLASS_SERIAL(klass);
-- 
EW


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-11-03  3:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-03  3:39 [PATCH] wip id_table conversion: too big Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).