Skip to content

Commit

Permalink
Refactor how object IDs work for special consts
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
peterzhu2118 committed Apr 12, 2024
1 parent 3629d4d commit edec690
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 22 deletions.
42 changes: 21 additions & 21 deletions gc.c
Expand Up @@ -3460,8 +3460,8 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
}


#define OBJ_ID_INCREMENT (sizeof(RVALUE) / 2)
#define OBJ_ID_INITIAL (OBJ_ID_INCREMENT * 2)
#define OBJ_ID_INCREMENT (sizeof(RVALUE))
#define OBJ_ID_INITIAL (OBJ_ID_INCREMENT)

static int
object_id_cmp(st_data_t x, st_data_t y)
Expand Down Expand Up @@ -4468,25 +4468,28 @@ id2ref(VALUE objid)
#define NUM2PTR(x) NUM2ULL(x)
#endif
rb_objspace_t *objspace = &rb_objspace;
VALUE ptr;
void *p0;

objid = rb_to_int(objid);
if (FIXNUM_P(objid) || rb_big_size(objid) <= SIZEOF_VOIDP) {
ptr = NUM2PTR(objid);
if (ptr == Qtrue) return Qtrue;
if (ptr == Qfalse) return Qfalse;
if (NIL_P(ptr)) return Qnil;
if (FIXNUM_P(ptr)) return ptr;
if (FLONUM_P(ptr)) return ptr;
VALUE ptr = NUM2PTR(objid);
if (SPECIAL_CONST_P(ptr)) {
if (ptr == Qtrue) return Qtrue;
if (ptr == Qfalse) return Qfalse;
if (NIL_P(ptr)) return Qnil;
if (FIXNUM_P(ptr)) return ptr;
if (FLONUM_P(ptr)) return ptr;

if (SYMBOL_P(ptr)) {
// Check that the symbol is valid
if (rb_static_id_valid_p(SYM2ID(ptr))) {
return ptr;
}
else {
rb_raise(rb_eRangeError, "%p is not symbol id value", (void *)ptr);
}
}

ptr = obj_id_to_ref(objid);
if ((ptr % sizeof(RVALUE)) == (4 << 2)) {
ID symid = ptr / sizeof(RVALUE);
p0 = (void *)ptr;
if (!rb_static_id_valid_p(symid))
rb_raise(rb_eRangeError, "%p is not symbol id value", p0);
return ID2SYM(symid);
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is not id value", rb_int2str(objid, 10));
}
}

Expand Down Expand Up @@ -4519,10 +4522,7 @@ os_id2ref(VALUE os, VALUE objid)
static VALUE
rb_find_object_id(VALUE obj, VALUE (*get_heap_object_id)(VALUE))
{
if (STATIC_SYM_P(obj)) {
return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
}
else if (FLONUM_P(obj)) {
if (FLONUM_P(obj)) {
#if SIZEOF_LONG == SIZEOF_VOIDP
return LONG2NUM((SIGNED_VALUE)obj);
#else
Expand Down
5 changes: 4 additions & 1 deletion test/ruby/test_objectspace.rb
Expand Up @@ -66,8 +66,11 @@ def test_id2ref_invalid_argument
end

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/
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

def test_count_objects
Expand Down

0 comments on commit edec690

Please sign in to comment.