From 8f842d71e98d7da744c4518afbdd49fe06b6a49a Mon Sep 17 00:00:00 2001 From: akr Date: Wed, 13 Feb 2008 11:52:46 +0000 Subject: * include/ruby/ruby.h (RObject): add iv_index_tbl for shortcut of RCLASS_IV_INDEX_TBL(rb_obj_class(obj)). (ROBJECT_IV_INDEX_TBL): defined. * object.c (init_copy): initialize iv_index_tbl in struct RObject. * variable.c (ivar_get): use ROBJECT_IV_INDEX_TBL. (rb_ivar_defined): ditto. (obj_ivar_each): ditto. (rb_obj_remove_instance_variable): ditto. (rb_ivar_set): update iv_index_tbl in struct RObject. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15458 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 14 ++++++++++++ include/ruby/ruby.h | 5 +++++ object.c | 2 ++ variable.c | 61 ++++++++++++++++++++++++++++++----------------------- 4 files changed, 56 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 996863a77c..fa351cbec9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Wed Feb 13 20:48:50 2008 Tanaka Akira + + * include/ruby/ruby.h (RObject): add iv_index_tbl for shortcut of + RCLASS_IV_INDEX_TBL(rb_obj_class(obj)). + (ROBJECT_IV_INDEX_TBL): defined. + + * object.c (init_copy): initialize iv_index_tbl in struct RObject. + + * variable.c (ivar_get): use ROBJECT_IV_INDEX_TBL. + (rb_ivar_defined): ditto. + (obj_ivar_each): ditto. + (rb_obj_remove_instance_variable): ditto. + (rb_ivar_set): update iv_index_tbl in struct RObject. + Wed Feb 13 16:21:48 2008 NARUSE, Yui * lib/uri/generic.rb: revert r15442. 2nd argument of String#sub parse diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index ecc9bfd923..2ba47ab9f5 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -398,6 +398,7 @@ struct RObject { struct { long len; VALUE *ptr; + struct st_table *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */ } heap; VALUE ary[ROBJECT_EMBED_LEN_MAX]; } as; @@ -411,6 +412,10 @@ struct RObject { ((RBASIC(o)->flags & ROBJECT_EMBED) ? \ ROBJECT(o)->as.ary : \ ROBJECT(o)->as.heap.ptr) +#define ROBJECT_IV_INDEX_TBL(o) \ + ((RBASIC(o)->flags & ROBJECT_EMBED) ? \ + RCLASS_IV_INDEX_TBL(rb_obj_class(o)) : \ + ROBJECT(o)->as.heap.iv_index_tbl) struct RValues { struct RBasic basic; diff --git a/object.c b/object.c index dc8c3bb3b4..5b2715b798 100644 --- a/object.c +++ b/object.c @@ -170,6 +170,7 @@ init_copy(VALUE dest, VALUE obj) xfree(ROBJECT_PTR(dest)); ROBJECT(dest)->as.heap.ptr = 0; ROBJECT(dest)->as.heap.len = 0; + ROBJECT(dest)->as.heap.iv_index_tbl = 0; } if (RBASIC(obj)->flags & ROBJECT_EMBED) { MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX); @@ -181,6 +182,7 @@ init_copy(VALUE dest, VALUE obj) MEMCPY(ptr, ROBJECT(obj)->as.heap.ptr, VALUE, len); ROBJECT(dest)->as.heap.ptr = ptr; ROBJECT(dest)->as.heap.len = len; + ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl; RBASIC(dest)->flags &= ~ROBJECT_EMBED; } break; diff --git a/variable.c b/variable.c index f2c63abd14..8639f8b378 100644 --- a/variable.c +++ b/variable.c @@ -932,17 +932,20 @@ clear: static VALUE ivar_get(VALUE obj, ID id, int warn) { - VALUE val; - VALUE klass; + VALUE val, *ptr; + struct st_table *iv_index_tbl; + long len; st_data_t index; switch (TYPE(obj)) { case T_OBJECT: - klass = rb_obj_class(obj); - if (!RCLASS_IV_INDEX_TBL(klass)) break; - if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break; - if (ROBJECT_LEN(obj) <= index) break; - val = ROBJECT_PTR(obj)[index]; + len = ROBJECT_LEN(obj); + ptr = ROBJECT_PTR(obj); + iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj); + if (!iv_index_tbl) break; + if (!st_lookup(iv_index_tbl, id, &index)) break; + if (len <= index) break; + val = ptr[index]; if (val != Qundef) return val; break; @@ -977,7 +980,7 @@ rb_attr_get(VALUE obj, ID id) VALUE rb_ivar_set(VALUE obj, ID id, VALUE val) { - VALUE klass; + struct st_table *iv_index_tbl; st_data_t index; long i, len; int ivar_extended; @@ -987,13 +990,18 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) if (OBJ_FROZEN(obj)) rb_error_frozen("object"); switch (TYPE(obj)) { case T_OBJECT: - klass = rb_obj_class(obj); - if (!RCLASS_IV_INDEX_TBL(klass)) - RCLASS_IV_INDEX_TBL(klass) = st_init_numtable(); + iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj); + if (!iv_index_tbl) { + VALUE klass = rb_obj_class(obj); + iv_index_tbl = RCLASS_IV_INDEX_TBL(klass); + if (!iv_index_tbl) { + iv_index_tbl = RCLASS_IV_INDEX_TBL(klass) = st_init_numtable(); + } + } ivar_extended = 0; - if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) { - index = RCLASS_IV_INDEX_TBL(klass)->num_entries; - st_add_direct(RCLASS_IV_INDEX_TBL(klass), id, index); + if (!st_lookup(iv_index_tbl, id, &index)) { + index = iv_index_tbl->num_entries; + st_add_direct(iv_index_tbl, id, index); ivar_extended = 1; } len = ROBJECT_LEN(obj); @@ -1010,8 +1018,8 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) VALUE *newptr; long newsize = (index+1) + (index+1)/4; /* (index+1)*1.25 */ if (!ivar_extended && - RCLASS_IV_INDEX_TBL(klass)->num_entries < newsize) { - newsize = RCLASS_IV_INDEX_TBL(klass)->num_entries; + iv_index_tbl->num_entries < newsize) { + newsize = iv_index_tbl->num_entries; } if (RBASIC(obj)->flags & ROBJECT_EMBED) { newptr = ALLOC_N(VALUE, newsize); @@ -1026,6 +1034,7 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) for (; len < newsize; len++) newptr[len] = Qundef; ROBJECT(obj)->as.heap.len = newsize; + ROBJECT(obj)->as.heap.iv_index_tbl = iv_index_tbl; } } ROBJECT_PTR(obj)[index] = val; @@ -1045,13 +1054,14 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) VALUE rb_ivar_defined(VALUE obj, ID id) { - VALUE klass, val; + VALUE val; + struct st_table *iv_index_tbl; st_data_t index; switch (TYPE(obj)) { case T_OBJECT: - klass = rb_obj_class(obj); - if (!RCLASS_IV_INDEX_TBL(klass)) break; - if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break; + iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj); + if (!iv_index_tbl) break; + if (!st_lookup(iv_index_tbl, id, &index)) break; if (ROBJECT_LEN(obj) <= index) break; val = ROBJECT_PTR(obj)[index]; if (val != Qundef) @@ -1091,11 +1101,10 @@ obj_ivar_i(ID key, VALUE index, struct obj_ivar_tag *data) static void obj_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg) { - VALUE klass = rb_obj_class(obj); st_table *tbl; struct obj_ivar_tag data; - tbl = RCLASS_IV_INDEX_TBL(klass); + tbl = ROBJECT_IV_INDEX_TBL(obj); if (!tbl) return; @@ -1194,7 +1203,7 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name) { VALUE val = Qnil; ID id = rb_to_id(name); - VALUE klass; + struct st_table *iv_index_tbl; st_data_t index; if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4) @@ -1206,9 +1215,9 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name) switch (TYPE(obj)) { case T_OBJECT: - klass = rb_obj_class(obj); - if (!RCLASS_IV_INDEX_TBL(klass)) break; - if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break; + iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj); + if (!iv_index_tbl) break; + if (!st_lookup(iv_index_tbl, id, &index)) break; if (ROBJECT_LEN(obj) <= index) break; val = ROBJECT_PTR(obj)[index]; if (val != Qundef) { -- cgit v1.2.3