From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS198093 171.25.193.0/24 X-Spam-Status: No, score=-2.2 required=3.0 tests=AWL,BAYES_00,RCVD_IN_XBL shortcircuit=no autolearn=no version=3.3.2 X-Original-To: spew@80x24.org Received: from 80x24.org (tor-exit4-readme.dfri.se [171.25.193.78]) by dcvr.yhbt.net (Postfix) with ESMTP id CAB7A1F82C for ; Tue, 3 Nov 2015 03:39:36 +0000 (UTC) From: Eric Wong To: spew@80x24.org Subject: [PATCH] wip id_table conversion: too big Date: Tue, 3 Nov 2015 03:39:33 +0000 Message-Id: <20151103033933.17664-1-e@80x24.org> List-Id: 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