Refactor how object IDs work for special consts

We don't need to treat static symbols in any special way since they
can't be confused with other special consts or GC managed objects.
This commit is contained in:
Peter Zhu 2024-04-11 14:30:30 -04:00
parent 3629d4df66
commit edec690e03
2 changed files with 25 additions and 22 deletions

32
gc.c
View File

@ -3460,8 +3460,8 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
} }
#define OBJ_ID_INCREMENT (sizeof(RVALUE) / 2) #define OBJ_ID_INCREMENT (sizeof(RVALUE))
#define OBJ_ID_INITIAL (OBJ_ID_INCREMENT * 2) #define OBJ_ID_INITIAL (OBJ_ID_INCREMENT)
static int static int
object_id_cmp(st_data_t x, st_data_t y) object_id_cmp(st_data_t x, st_data_t y)
@ -4468,25 +4468,28 @@ id2ref(VALUE objid)
#define NUM2PTR(x) NUM2ULL(x) #define NUM2PTR(x) NUM2ULL(x)
#endif #endif
rb_objspace_t *objspace = &rb_objspace; rb_objspace_t *objspace = &rb_objspace;
VALUE ptr;
void *p0;
objid = rb_to_int(objid); objid = rb_to_int(objid);
if (FIXNUM_P(objid) || rb_big_size(objid) <= SIZEOF_VOIDP) { if (FIXNUM_P(objid) || rb_big_size(objid) <= SIZEOF_VOIDP) {
ptr = NUM2PTR(objid); VALUE ptr = NUM2PTR(objid);
if (SPECIAL_CONST_P(ptr)) {
if (ptr == Qtrue) return Qtrue; if (ptr == Qtrue) return Qtrue;
if (ptr == Qfalse) return Qfalse; if (ptr == Qfalse) return Qfalse;
if (NIL_P(ptr)) return Qnil; if (NIL_P(ptr)) return Qnil;
if (FIXNUM_P(ptr)) return ptr; if (FIXNUM_P(ptr)) return ptr;
if (FLONUM_P(ptr)) return ptr; if (FLONUM_P(ptr)) return ptr;
ptr = obj_id_to_ref(objid); if (SYMBOL_P(ptr)) {
if ((ptr % sizeof(RVALUE)) == (4 << 2)) { // Check that the symbol is valid
ID symid = ptr / sizeof(RVALUE); if (rb_static_id_valid_p(SYM2ID(ptr))) {
p0 = (void *)ptr; return ptr;
if (!rb_static_id_valid_p(symid)) }
rb_raise(rb_eRangeError, "%p is not symbol id value", p0); else {
return ID2SYM(symid); rb_raise(rb_eRangeError, "%p is not symbol id value", (void *)ptr);
}
}
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is not id value", rb_int2str(objid, 10));
} }
} }
@ -4519,10 +4522,7 @@ os_id2ref(VALUE os, VALUE objid)
static VALUE static VALUE
rb_find_object_id(VALUE obj, VALUE (*get_heap_object_id)(VALUE)) rb_find_object_id(VALUE obj, VALUE (*get_heap_object_id)(VALUE))
{ {
if (STATIC_SYM_P(obj)) { if (FLONUM_P(obj)) {
return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
}
else if (FLONUM_P(obj)) {
#if SIZEOF_LONG == SIZEOF_VOIDP #if SIZEOF_LONG == SIZEOF_VOIDP
return LONG2NUM((SIGNED_VALUE)obj); return LONG2NUM((SIGNED_VALUE)obj);
#else #else

View File

@ -66,8 +66,11 @@ End
end end
def test_id2ref_invalid_symbol_id def test_id2ref_invalid_symbol_id
# RB_STATIC_SYM_P checks for static symbols by checking that the bottom
# 8 bits of the object is equal to RUBY_SYMBOL_FLAG, so we need to make
# sure that the bottom 8 bits remain unchanged.
msg = /is not symbol id value/ msg = /is not symbol id value/
assert_raise_with_message(RangeError, msg) { ObjectSpace._id2ref(:a.object_id + GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]) } assert_raise_with_message(RangeError, msg) { ObjectSpace._id2ref(:a.object_id + 256) }
end end
def test_count_objects def test_count_objects