summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--include/ruby/ruby.h5
-rw-r--r--object.c2
-rw-r--r--variable.c61
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 <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>
* 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) {