* 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
This commit is contained in:
akr 2008-02-13 11:52:46 +00:00
parent f09eb27660
commit 8f842d71e9
4 changed files with 56 additions and 26 deletions

View File

@ -1,3 +1,17 @@
Wed Feb 13 20:48:50 2008 Tanaka Akira <akr@fsij.org>
* 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 <naruse@ruby-lang.org> Wed Feb 13 16:21:48 2008 NARUSE, Yui <naruse@ruby-lang.org>
* lib/uri/generic.rb: revert r15442. 2nd argument of String#sub parse * lib/uri/generic.rb: revert r15442. 2nd argument of String#sub parse

View File

@ -398,6 +398,7 @@ struct RObject {
struct { struct {
long len; long len;
VALUE *ptr; VALUE *ptr;
struct st_table *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
} heap; } heap;
VALUE ary[ROBJECT_EMBED_LEN_MAX]; VALUE ary[ROBJECT_EMBED_LEN_MAX];
} as; } as;
@ -411,6 +412,10 @@ struct RObject {
((RBASIC(o)->flags & ROBJECT_EMBED) ? \ ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
ROBJECT(o)->as.ary : \ ROBJECT(o)->as.ary : \
ROBJECT(o)->as.heap.ptr) 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 RValues {
struct RBasic basic; struct RBasic basic;

View File

@ -170,6 +170,7 @@ init_copy(VALUE dest, VALUE obj)
xfree(ROBJECT_PTR(dest)); xfree(ROBJECT_PTR(dest));
ROBJECT(dest)->as.heap.ptr = 0; ROBJECT(dest)->as.heap.ptr = 0;
ROBJECT(dest)->as.heap.len = 0; ROBJECT(dest)->as.heap.len = 0;
ROBJECT(dest)->as.heap.iv_index_tbl = 0;
} }
if (RBASIC(obj)->flags & ROBJECT_EMBED) { if (RBASIC(obj)->flags & ROBJECT_EMBED) {
MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX); 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); MEMCPY(ptr, ROBJECT(obj)->as.heap.ptr, VALUE, len);
ROBJECT(dest)->as.heap.ptr = ptr; ROBJECT(dest)->as.heap.ptr = ptr;
ROBJECT(dest)->as.heap.len = len; 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; RBASIC(dest)->flags &= ~ROBJECT_EMBED;
} }
break; break;

View File

@ -932,17 +932,20 @@ clear:
static VALUE static VALUE
ivar_get(VALUE obj, ID id, int warn) ivar_get(VALUE obj, ID id, int warn)
{ {
VALUE val; VALUE val, *ptr;
VALUE klass; struct st_table *iv_index_tbl;
long len;
st_data_t index; st_data_t index;
switch (TYPE(obj)) { switch (TYPE(obj)) {
case T_OBJECT: case T_OBJECT:
klass = rb_obj_class(obj); len = ROBJECT_LEN(obj);
if (!RCLASS_IV_INDEX_TBL(klass)) break; ptr = ROBJECT_PTR(obj);
if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break; iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
if (ROBJECT_LEN(obj) <= index) break; if (!iv_index_tbl) break;
val = ROBJECT_PTR(obj)[index]; if (!st_lookup(iv_index_tbl, id, &index)) break;
if (len <= index) break;
val = ptr[index];
if (val != Qundef) if (val != Qundef)
return val; return val;
break; break;
@ -977,7 +980,7 @@ rb_attr_get(VALUE obj, ID id)
VALUE VALUE
rb_ivar_set(VALUE obj, ID id, VALUE val) rb_ivar_set(VALUE obj, ID id, VALUE val)
{ {
VALUE klass; struct st_table *iv_index_tbl;
st_data_t index; st_data_t index;
long i, len; long i, len;
int ivar_extended; int ivar_extended;
@ -987,13 +990,18 @@ rb_ivar_set(VALUE obj, ID id, VALUE val)
if (OBJ_FROZEN(obj)) rb_error_frozen("object"); if (OBJ_FROZEN(obj)) rb_error_frozen("object");
switch (TYPE(obj)) { switch (TYPE(obj)) {
case T_OBJECT: case T_OBJECT:
klass = rb_obj_class(obj); iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
if (!RCLASS_IV_INDEX_TBL(klass)) if (!iv_index_tbl) {
RCLASS_IV_INDEX_TBL(klass) = st_init_numtable(); 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; ivar_extended = 0;
if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) { if (!st_lookup(iv_index_tbl, id, &index)) {
index = RCLASS_IV_INDEX_TBL(klass)->num_entries; index = iv_index_tbl->num_entries;
st_add_direct(RCLASS_IV_INDEX_TBL(klass), id, index); st_add_direct(iv_index_tbl, id, index);
ivar_extended = 1; ivar_extended = 1;
} }
len = ROBJECT_LEN(obj); len = ROBJECT_LEN(obj);
@ -1010,8 +1018,8 @@ rb_ivar_set(VALUE obj, ID id, VALUE val)
VALUE *newptr; VALUE *newptr;
long newsize = (index+1) + (index+1)/4; /* (index+1)*1.25 */ long newsize = (index+1) + (index+1)/4; /* (index+1)*1.25 */
if (!ivar_extended && if (!ivar_extended &&
RCLASS_IV_INDEX_TBL(klass)->num_entries < newsize) { iv_index_tbl->num_entries < newsize) {
newsize = RCLASS_IV_INDEX_TBL(klass)->num_entries; newsize = iv_index_tbl->num_entries;
} }
if (RBASIC(obj)->flags & ROBJECT_EMBED) { if (RBASIC(obj)->flags & ROBJECT_EMBED) {
newptr = ALLOC_N(VALUE, newsize); newptr = ALLOC_N(VALUE, newsize);
@ -1026,6 +1034,7 @@ rb_ivar_set(VALUE obj, ID id, VALUE val)
for (; len < newsize; len++) for (; len < newsize; len++)
newptr[len] = Qundef; newptr[len] = Qundef;
ROBJECT(obj)->as.heap.len = newsize; ROBJECT(obj)->as.heap.len = newsize;
ROBJECT(obj)->as.heap.iv_index_tbl = iv_index_tbl;
} }
} }
ROBJECT_PTR(obj)[index] = val; ROBJECT_PTR(obj)[index] = val;
@ -1045,13 +1054,14 @@ rb_ivar_set(VALUE obj, ID id, VALUE val)
VALUE VALUE
rb_ivar_defined(VALUE obj, ID id) rb_ivar_defined(VALUE obj, ID id)
{ {
VALUE klass, val; VALUE val;
struct st_table *iv_index_tbl;
st_data_t index; st_data_t index;
switch (TYPE(obj)) { switch (TYPE(obj)) {
case T_OBJECT: case T_OBJECT:
klass = rb_obj_class(obj); iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
if (!RCLASS_IV_INDEX_TBL(klass)) break; if (!iv_index_tbl) break;
if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break; if (!st_lookup(iv_index_tbl, id, &index)) break;
if (ROBJECT_LEN(obj) <= index) break; if (ROBJECT_LEN(obj) <= index) break;
val = ROBJECT_PTR(obj)[index]; val = ROBJECT_PTR(obj)[index];
if (val != Qundef) if (val != Qundef)
@ -1091,11 +1101,10 @@ obj_ivar_i(ID key, VALUE index, struct obj_ivar_tag *data)
static void static void
obj_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg) obj_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
{ {
VALUE klass = rb_obj_class(obj);
st_table *tbl; st_table *tbl;
struct obj_ivar_tag data; struct obj_ivar_tag data;
tbl = RCLASS_IV_INDEX_TBL(klass); tbl = ROBJECT_IV_INDEX_TBL(obj);
if (!tbl) if (!tbl)
return; return;
@ -1194,7 +1203,7 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name)
{ {
VALUE val = Qnil; VALUE val = Qnil;
ID id = rb_to_id(name); ID id = rb_to_id(name);
VALUE klass; struct st_table *iv_index_tbl;
st_data_t index; st_data_t index;
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4) if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
@ -1206,9 +1215,9 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name)
switch (TYPE(obj)) { switch (TYPE(obj)) {
case T_OBJECT: case T_OBJECT:
klass = rb_obj_class(obj); iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
if (!RCLASS_IV_INDEX_TBL(klass)) break; if (!iv_index_tbl) break;
if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break; if (!st_lookup(iv_index_tbl, id, &index)) break;
if (ROBJECT_LEN(obj) <= index) break; if (ROBJECT_LEN(obj) <= index) break;
val = ROBJECT_PTR(obj)[index]; val = ROBJECT_PTR(obj)[index];
if (val != Qundef) { if (val != Qundef) {