mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* gc.c: align VALUE with sizeof(RVALUE) globally.
(is_pointer_to_heap): check alignment out of loop. (id2ref): avoid collision between symbols and objects. (rb_obj_id): ditto. moved from object.c. [ruby-talk:178364] [ruby-core:7401] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10013 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b6572b6873
commit
ecebbcce1f
4 changed files with 101 additions and 53 deletions
|
@ -1,3 +1,11 @@
|
|||
Thu Mar 2 14:12:26 2006 Tanaka Akira <akr@m17n.org>
|
||||
|
||||
* gc.c: align VALUE with sizeof(RVALUE) globally.
|
||||
(is_pointer_to_heap): check alignment out of loop.
|
||||
(id2ref): avoid collision between symbols and objects.
|
||||
(rb_obj_id): ditto. moved from object.c.
|
||||
[ruby-talk:178364] [ruby-core:7401]
|
||||
|
||||
Thu Mar 2 12:55:16 2006 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
|
||||
|
||||
* win32/win32.c (filetime_to_unixtime): should set tm_isdst to -1.
|
||||
|
|
102
gc.c
102
gc.c
|
@ -344,6 +344,7 @@ static RVALUE *deferred_final_list = 0;
|
|||
|
||||
#define HEAPS_INCREMENT 10
|
||||
static struct heaps_slot {
|
||||
void *membase;
|
||||
RVALUE *slot;
|
||||
int limit;
|
||||
} *heaps;
|
||||
|
@ -381,8 +382,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 +390,13 @@ add_heap(void)
|
|||
heap_slots = HEAP_MIN_SLOTS;
|
||||
continue;
|
||||
}
|
||||
heaps[heaps_used].membase = p;
|
||||
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 +632,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;
|
||||
|
@ -1019,7 +1026,7 @@ free_unused_heaps(void)
|
|||
|
||||
for (i = j = 1; j < heaps_used; i++) {
|
||||
if (heaps[i].limit == 0) {
|
||||
free(heaps[i].slot);
|
||||
free(heaps[i].membase);
|
||||
heaps_used--;
|
||||
}
|
||||
else {
|
||||
|
@ -1905,7 +1912,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 +1923,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 % sizeof(RVALUE)) == (4 << 2)) {
|
||||
ID symid = objid / sizeof(RVALUE);
|
||||
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);
|
||||
}
|
||||
|
@ -1937,6 +1948,73 @@ id2ref(VALUE obj, VALUE id)
|
|||
return (VALUE)ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Document-method: __id__
|
||||
* Document-method: object_id
|
||||
*
|
||||
* call-seq:
|
||||
* obj.__id__ => fixnum
|
||||
* obj.object_id => fixnum
|
||||
*
|
||||
* Returns an integer identifier for <i>obj</i>. The same number will
|
||||
* be returned on all calls to <code>id</code> for a given object, and
|
||||
* no two active objects will share an id.
|
||||
* <code>Object#object_id</code> is a different concept from the
|
||||
* <code>:name</code> notation, which returns the symbol id of
|
||||
* <code>name</code>. Replaces the deprecated <code>Object#id</code>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.hash => fixnum
|
||||
*
|
||||
* Generates a <code>Fixnum</code> hash value for this object. This
|
||||
* function must have the property that <code>a.eql?(b)</code> implies
|
||||
* <code>a.hash == b.hash</code>. The hash value is used by class
|
||||
* <code>Hash</code>. Any hash value that exceeds the capacity of a
|
||||
* <code>Fixnum</code> will be truncated before being used.
|
||||
*/
|
||||
|
||||
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 sizeof(RVALUE))
|
||||
* fixnum fffffffffffffffffffffffffffffff1
|
||||
*
|
||||
* object_id space
|
||||
* LSB
|
||||
* false 00000000000000000000000000000000
|
||||
* true 00000000000000000000000000000010
|
||||
* nil 00000000000000000000000000000100
|
||||
* undef 00000000000000000000000000000110
|
||||
* symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4)
|
||||
* object oooooooooooooooooooooooooooooo0 o...o % A = 0
|
||||
* fixnum fffffffffffffffffffffffffffffff1 bignum if required
|
||||
*
|
||||
* where A = sizeof(RVALUE)/4
|
||||
*
|
||||
* sizeof(RVALUE) is
|
||||
* 20 if 32-bit, double is 4-byte aligned
|
||||
* 24 if 32-bit, double is 8-byte aligned
|
||||
* 40 if 64-bit
|
||||
*/
|
||||
if (TYPE(obj) == T_SYMBOL) {
|
||||
return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
|
||||
}
|
||||
if (SPECIAL_CONST_P(obj)) {
|
||||
return LONG2NUM((long)obj);
|
||||
}
|
||||
return (VALUE)((long)obj|FIXNUM_FLAG);
|
||||
}
|
||||
|
||||
/*
|
||||
* The <code>GC</code> module provides an interface to Ruby's mark and
|
||||
* sweep garbage collection mechanism. Some of the underlying methods
|
||||
|
@ -1978,4 +2056,8 @@ Init_GC(void)
|
|||
|
||||
rb_global_variable(&nomem_error);
|
||||
nomem_error = rb_exc_new2(rb_eNoMemError, "failed to allocate memory");
|
||||
|
||||
rb_define_method(rb_mKernel, "hash", rb_obj_id, 0);
|
||||
rb_define_method(rb_mKernel, "__id__", rb_obj_id, 0);
|
||||
rb_define_method(rb_mKernel, "object_id", rb_obj_id, 0);
|
||||
}
|
||||
|
|
42
object.c
42
object.c
|
@ -95,45 +95,6 @@ rb_obj_equal(VALUE obj1, VALUE obj2)
|
|||
return Qfalse;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Document-method: __id__
|
||||
* Document-method: object_id
|
||||
*
|
||||
* call-seq:
|
||||
* obj.__id__ => fixnum
|
||||
* obj.object_id => fixnum
|
||||
*
|
||||
* Returns an integer identifier for <i>obj</i>. The same number will
|
||||
* be returned on all calls to <code>id</code> for a given object, and
|
||||
* no two active objects will share an id.
|
||||
* <code>Object#object_id</code> is a different concept from the
|
||||
* <code>:name</code> notation, which returns the symbol id of
|
||||
* <code>name</code>. Replaces the deprecated <code>Object#id</code>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.hash => fixnum
|
||||
*
|
||||
* Generates a <code>Fixnum</code> hash value for this object. This
|
||||
* function must have the property that <code>a.eql?(b)</code> implies
|
||||
* <code>a.hash == b.hash</code>. The hash value is used by class
|
||||
* <code>Hash</code>. Any hash value that exceeds the capacity of a
|
||||
* <code>Fixnum</code> will be truncated before being used.
|
||||
*/
|
||||
|
||||
VALUE
|
||||
rb_obj_id(VALUE obj)
|
||||
{
|
||||
if (SPECIAL_CONST_P(obj)) {
|
||||
return LONG2NUM((long)obj);
|
||||
}
|
||||
return (VALUE)((long)obj|FIXNUM_FLAG);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_class_real(VALUE cl)
|
||||
{
|
||||
|
@ -2418,9 +2379,6 @@ Init_Object(void)
|
|||
|
||||
rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1);
|
||||
|
||||
rb_define_method(rb_mKernel, "hash", rb_obj_id, 0);
|
||||
rb_define_method(rb_mKernel, "__id__", rb_obj_id, 0);
|
||||
rb_define_method(rb_mKernel, "object_id", rb_obj_id, 0);
|
||||
rb_define_method(rb_mKernel, "class", rb_obj_class, 0);
|
||||
|
||||
rb_define_method(rb_mKernel, "clone", rb_obj_clone, 0);
|
||||
|
|
2
ruby.h
2
ruby.h
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue