In article <87irr047sx.fsf / m17n.org>, Tanaka Akira <akr / m17n.org> writes: > c) align objects 20bytes. map symbols to non-20bytes aligned value. Implementation: Index: gc.c =================================================================== RCS file: /src/ruby/gc.c,v retrieving revision 1.233 diff -u -p -r1.233 gc.c --- gc.c 13 Feb 2006 04:53:21 -0000 1.233 +++ gc.c 28 Feb 2006 05:11:07 -0000 @@ -381,8 +381,7 @@ add_heap(void) } for (;;) { - RUBY_CRITICAL(p = heaps[heaps_used].slot = (RVALUE*)malloc(sizeof(RVALUE)*heap_slots)); - heaps[heaps_used].limit = heap_slots; + RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); if (p == 0) { if (heap_slots == HEAP_MIN_SLOTS) { rb_memerror(); @@ -390,6 +389,12 @@ add_heap(void) heap_slots = HEAP_MIN_SLOTS; continue; } + if ((VALUE)p % sizeof(RVALUE) == 0) + heap_slots += 1; + else + p = (RVALUE*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p % sizeof(RVALUE))); + heaps[heaps_used].slot = p; + heaps[heaps_used].limit = heap_slots; break; } pend = p + heap_slots; @@ -625,12 +630,12 @@ is_pointer_to_heap(void *ptr) register long i; if (p < lomem || p > himem) return Qfalse; + if ((VALUE)p % sizeof(RVALUE) != 0) return Qfalse; /* check if p looks like a pointer */ for (i=0; i < heaps_used; i++) { heap_org = heaps[i].slot; - if (heap_org <= p && p < heap_org + heaps[i].limit && - ((((char*)p)-((char*)heap_org))%sizeof(RVALUE)) == 0) + if (heap_org <= p && p < heap_org + heaps[i].limit) return Qtrue; } return Qfalse; @@ -1905,7 +1910,7 @@ rb_gc_call_finalizer_at_exit(void) */ static VALUE -id2ref(VALUE obj, VALUE id) +id2ref(VALUE obj, VALUE objid) { #if SIZEOF_LONG == SIZEOF_VOIDP #define NUM2PTR(x) NUM2ULONG(x) @@ -1916,18 +1921,22 @@ id2ref(VALUE obj, VALUE id) void *p0; rb_secure(4); - ptr = NUM2PTR(id); + ptr = NUM2PTR(objid); p0 = (void *)ptr; if (ptr == Qtrue) return Qtrue; if (ptr == Qfalse) return Qfalse; if (ptr == Qnil) return Qnil; if (FIXNUM_P(ptr)) return (VALUE)ptr; - if (SYMBOL_P(ptr) && rb_id2name(SYM2ID((VALUE)ptr)) != 0) { - return (VALUE)ptr; + + if (((objid >> 2) % 5) == 4) { + ID symid = (objid >> 2) / 5; + if (rb_id2name(symid) == 0) + rb_raise(rb_eRangeError, "%p is not symbol id value", p0); + return ID2SYM(symid); } - ptr = id ^ FIXNUM_FLAG; /* unset FIXNUM_FLAG */ + ptr = objid ^ FIXNUM_FLAG; /* unset FIXNUM_FLAG */ if (!is_pointer_to_heap((void *)ptr)|| BUILTIN_TYPE(ptr) >= T_BLOCK) { rb_raise(rb_eRangeError, "%p is not id value", p0); } Index: object.c =================================================================== RCS file: /src/ruby/object.c,v retrieving revision 1.183 diff -u -p -r1.183 object.c --- object.c 17 Jan 2006 14:05:49 -0000 1.183 +++ object.c 28 Feb 2006 05:11:07 -0000 @@ -128,6 +128,30 @@ rb_obj_equal(VALUE obj1, VALUE obj2) VALUE rb_obj_id(VALUE obj) { + /* + * 32-bit VALUE space + * MSB ------------------------ LSB + * false 00000000000000000000000000000000 + * true 00000000000000000000000000000010 + * nil 00000000000000000000000000000100 + * undef 00000000000000000000000000000110 + * symbol ssssssssssssssssssssssss00001110 + * object oooooooooooooooooooooooooooooo00 = 0 (mod 20 = sizeof(RVALUE)) + * fixnum fffffffffffffffffffffffffffffff1 + * + * object_id space + * LSB + * false 00000000000000000000000000000000 + * true 00000000000000000000000000000010 + * nil 00000000000000000000000000000100 + * undef 00000000000000000000000000000110 + * symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % 5 = 4 (S...S = s...s * 5 + 4) + * object oooooooooooooooooooooooooooooo0 o...o % 5 = 0 + * fixnum fffffffffffffffffffffffffffffff1 bignum if required + */ + if (TYPE(obj) == T_SYMBOL) { + return ((SYM2ID(obj) * 5 + 4) << 2) | FIXNUM_FLAG; + } if (SPECIAL_CONST_P(obj)) { return LONG2NUM((long)obj); } Index: ruby.h =================================================================== RCS file: /src/ruby/ruby.h,v retrieving revision 1.133 diff -u -p -r1.133 ruby.h --- ruby.h 5 Feb 2006 15:06:41 -0000 1.133 +++ ruby.h 28 Feb 2006 05:11:07 -0000 @@ -184,7 +184,7 @@ VALUE rb_ull2inum(unsigned LONG_LONG); #define SYMBOL_FLAG 0x0e #define SYMBOL_P(x) (((VALUE)(x)&0xff)==SYMBOL_FLAG) #define ID2SYM(x) ((VALUE)(((long)(x))<<8|SYMBOL_FLAG)) -#define SYM2ID(x) RSHIFT((long)x,8) +#define SYM2ID(x) RSHIFT((VALUE)x,8) /* special contants - i.e. non-zero and non-fixnum constants */ #define Qfalse ((VALUE)0) -- Tanaka Akira