Thanks to visit codestin.com
Credit goes to github.com

Skip to content

WIP: Add shape_id to RBasic under 32 bit #13341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions class.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,13 @@
* 2: RCLASS_PRIME_CLASSEXT_PRIME_WRITABLE
* This class's prime classext is the only classext and writable from any namespaces.
* If unset, the prime classext is writable only from the root namespace.
* if !SHAPE_IN_BASIC_FLAGS
* 4-19: SHAPE_FLAG_MASK
* Shape ID for the class.
* endif
*/

/* Flags of T_ICLASS
*
* 2: RCLASS_PRIME_CLASSEXT_PRIME_WRITABLE
* This module's prime classext is the only classext and writable from any namespaces.
* If unset, the prime classext is writable only from the root namespace.
* if !SHAPE_IN_BASIC_FLAGS
* 4-19: SHAPE_FLAG_MASK
* Shape ID. This is set but not used.
* endif
*/

/* Flags of T_MODULE
Expand All @@ -71,10 +63,6 @@
* If unset, the prime classext is writable only from the root namespace.
* 3: RMODULE_IS_REFINEMENT
* Module is used for refinements.
* if !SHAPE_IN_BASIC_FLAGS
* 4-19: SHAPE_FLAG_MASK
* Shape ID for the module.
* endif
*/

#define METACLASS_OF(k) RBASIC(k)->klass
Expand Down
3 changes: 2 additions & 1 deletion gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
unsigned int
rb_gc_vm_lock(void)
{
unsigned int lev;
unsigned int lev = 0;
RB_VM_LOCK_ENTER_LEV(&lev);
return lev;
}
Expand Down Expand Up @@ -1964,6 +1964,7 @@ build_id2ref_i(VALUE obj, void *data)
}
break;
case T_IMEMO:
case T_NONE:
break;
default:
if (rb_shape_obj_has_id(obj)) {
Expand Down
8 changes: 6 additions & 2 deletions gc/default/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -2107,6 +2107,9 @@ newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace,
#endif
RBASIC(obj)->flags = flags;
*((VALUE *)&RBASIC(obj)->klass) = klass;
#if RBASIC_SHAPE_ID_FIELD
RBASIC(obj)->shape_id = 0;
#endif

int t = flags & RUBY_T_MASK;
if (t == T_CLASS || t == T_MODULE || t == T_ICLASS) {
Expand Down Expand Up @@ -2949,7 +2952,7 @@ rb_gc_impl_shutdown_free_objects(void *objspace_ptr)
if (RB_BUILTIN_TYPE(vp) != T_NONE) {
rb_gc_obj_free_vm_weak_references(vp);
if (rb_gc_obj_free(objspace, vp)) {
RBASIC(vp)->flags = 0;
RBASIC_RESET_FLAGS(vp);
}
}
}
Expand Down Expand Up @@ -3023,7 +3026,7 @@ rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr)
if (rb_gc_shutdown_call_finalizer_p(vp)) {
rb_gc_obj_free_vm_weak_references(vp);
if (rb_gc_obj_free(objspace, vp)) {
RBASIC(vp)->flags = 0;
RBASIC_RESET_FLAGS(vp);
}
}
}
Expand Down Expand Up @@ -9342,6 +9345,7 @@ rb_gc_impl_init(void)
VALUE gc_constants = rb_hash_new();
rb_hash_aset(gc_constants, ID2SYM(rb_intern("DEBUG")), GC_DEBUG ? Qtrue : Qfalse);
rb_hash_aset(gc_constants, ID2SYM(rb_intern("BASE_SLOT_SIZE")), SIZET2NUM(BASE_SLOT_SIZE - RVALUE_OVERHEAD));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("RBASIC_SIZE")), SIZET2NUM(sizeof(struct RBasic)));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("RVALUE_OVERHEAD")), SIZET2NUM(RVALUE_OVERHEAD));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("HEAP_PAGE_OBJ_LIMIT")), SIZET2NUM(HEAP_PAGE_OBJ_LIMIT));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("HEAP_PAGE_BITMAP_SIZE")), SIZET2NUM(HEAP_PAGE_BITMAP_SIZE));
Expand Down
2 changes: 1 addition & 1 deletion gc/mmtk/mmtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr)

if (rb_gc_shutdown_call_finalizer_p(obj)) {
rb_gc_obj_free(objspace_ptr, obj);
RBASIC(obj)->flags = 0;
RBASIC_RESET_FLAGS(obj);
}
}
mmtk_free_raw_vec_of_obj_ref(registered_candidates);
Expand Down
22 changes: 22 additions & 0 deletions include/ruby/internal/core/rbasic.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ enum ruby_rvalue_flags {
RVALUE_EMBED_LEN_MAX = RBIMPL_RVALUE_EMBED_LEN_MAX
};

#if (SIZEOF_VALUE < SIZEOF_UINT64_T)
#define RBASIC_SHAPE_ID_FIELD 1
#else
#define RBASIC_SHAPE_ID_FIELD 0
#endif

/**
* Ruby object's base components. All Ruby objects have them in common.
*/
Expand Down Expand Up @@ -85,6 +91,10 @@ RBasic {
*/
const VALUE klass;

#if RBASIC_SHAPE_ID_FIELD
VALUE shape_id;
#endif

#ifdef __cplusplus
public:
RBIMPL_ATTR_CONSTEXPR(CXX11)
Expand All @@ -100,6 +110,9 @@ RBasic {
RBasic() :
flags(RBIMPL_VALUE_NULL),
klass(RBIMPL_VALUE_NULL)
#if RBASIC_SHAPE_ID_FIELD
, shape_id(RBIMPL_VALUE_NULL)
#endif
{
}
#endif
Expand Down Expand Up @@ -153,4 +166,13 @@ RBASIC_CLASS(VALUE obj)
return RBASIC(obj)->klass;
}

static inline void
RBASIC_RESET_FLAGS(VALUE obj)
{
RBASIC(obj)->flags = 0;
#if RBASIC_SHAPE_ID_FIELD
RBASIC(obj)->shape_id = 0;
#endif
}

#endif /* RBIMPL_RBASIC_H */
2 changes: 1 addition & 1 deletion internal/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ RCLASS_FIELDS_COUNT(VALUE obj)
return count;
}
else {
return RSHAPE(RCLASS_SHAPE_ID(obj))->next_field_index;
return RSHAPE(RBASIC_SHAPE_ID(obj))->next_field_index;
}
}

Expand Down
7 changes: 1 addition & 6 deletions object.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@
* The object has its instance variables embedded (the array of
* instance variables directly follow the object, rather than being
* on a separately allocated buffer).
* if !SHAPE_IN_BASIC_FLAGS
* 4-19: SHAPE_FLAG_MASK
* Shape ID for the object.
* endif
*/

/*!
Expand Down Expand Up @@ -134,8 +130,7 @@ rb_class_allocate_instance(VALUE klass)

RUBY_ASSERT(rb_obj_shape(obj)->type == SHAPE_ROOT);

// Set the shape to the specific T_OBJECT shape.
ROBJECT_SET_SHAPE_ID(obj, rb_shape_root(rb_gc_heap_id_for_size(size)));
RBASIC_SET_SHAPE_ID(obj, rb_shape_root(rb_gc_heap_id_for_size(size)));

#if RUBY_DEBUG
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
Expand Down
5 changes: 3 additions & 2 deletions ractor.c
Original file line number Diff line number Diff line change
Expand Up @@ -3679,8 +3679,9 @@ move_leave(VALUE obj, struct obj_traverse_replace_data *data)
}

// Avoid mutations using bind_call, etc.
MEMZERO((char *)obj + sizeof(struct RBasic), char, size - sizeof(struct RBasic));
RBASIC(obj)->flags = T_OBJECT | FL_FREEZE;
MEMZERO((char *)obj, char, sizeof(struct RBasic));
RBASIC(obj)->flags = T_OBJECT | FL_FREEZE | ROBJECT_EMBED;
//RBASIC(obj)->shape_id = 0
RBASIC_SET_CLASS_RAW(obj, rb_cRactorMovedObject);
return traverse_cont;
}
Expand Down
17 changes: 0 additions & 17 deletions shape.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,31 +347,14 @@ rb_shape_lookup(shape_id_t shape_id)
return &GET_SHAPE_TREE()->shape_list[shape_id];
}

#if !SHAPE_IN_BASIC_FLAGS
shape_id_t rb_generic_shape_id(VALUE obj);
#endif

RUBY_FUNC_EXPORTED shape_id_t
rb_obj_shape_id(VALUE obj)
{
if (RB_SPECIAL_CONST_P(obj)) {
return SPECIAL_CONST_SHAPE_ID;
}

#if SHAPE_IN_BASIC_FLAGS
return RBASIC_SHAPE_ID(obj);
#else
switch (BUILTIN_TYPE(obj)) {
case T_OBJECT:
return ROBJECT_SHAPE_ID(obj);
break;
case T_CLASS:
case T_MODULE:
return RCLASS_SHAPE_ID(obj);
default:
return rb_generic_shape_id(obj);
}
#endif
}

size_t
Expand Down
61 changes: 11 additions & 50 deletions shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
#if (SIZEOF_UINT64_T <= SIZEOF_VALUE)

#define SIZEOF_SHAPE_T 4
#define SHAPE_IN_BASIC_FLAGS 1
typedef uint32_t attr_index_t;
typedef uint32_t shape_id_t;
# define SHAPE_ID_NUM_BITS 32

#else

#define SIZEOF_SHAPE_T 2
#define SHAPE_IN_BASIC_FLAGS 0
typedef uint16_t attr_index_t;
typedef uint16_t shape_id_t;
# define SHAPE_ID_NUM_BITS 16
Expand Down Expand Up @@ -91,65 +89,30 @@ rb_current_shape_tree(void)
#define GET_SHAPE_TREE() rb_current_shape_tree()

static inline shape_id_t
get_shape_id_from_flags(VALUE obj)
RBASIC_SHAPE_ID(VALUE obj)
{
RUBY_ASSERT(!RB_SPECIAL_CONST_P(obj));
RUBY_ASSERT(!RB_TYPE_P(obj, T_IMEMO));
#if RBASIC_SHAPE_ID_FIELD
return (shape_id_t)((RBASIC(obj)->shape_id));
#else
return (shape_id_t)((RBASIC(obj)->flags) >> SHAPE_FLAG_SHIFT);
#endif
}

static inline void
set_shape_id_in_flags(VALUE obj, shape_id_t shape_id)
RBASIC_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{
RUBY_ASSERT(!RB_SPECIAL_CONST_P(obj));
RUBY_ASSERT(!RB_TYPE_P(obj, T_IMEMO));
#if RBASIC_SHAPE_ID_FIELD
RBASIC(obj)->shape_id = (VALUE)shape_id;
#else
// Ractors are occupying the upper 32 bits of flags, but only in debug mode
// Object shapes are occupying top bits
RBASIC(obj)->flags &= SHAPE_FLAG_MASK;
RBASIC(obj)->flags |= ((VALUE)(shape_id) << SHAPE_FLAG_SHIFT);
}


#if SHAPE_IN_BASIC_FLAGS
static inline shape_id_t
RBASIC_SHAPE_ID(VALUE obj)
{
return get_shape_id_from_flags(obj);
}

static inline void
RBASIC_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{
set_shape_id_in_flags(obj, shape_id);
}
#endif

static inline shape_id_t
ROBJECT_SHAPE_ID(VALUE obj)
{
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
return get_shape_id_from_flags(obj);
}

static inline void
ROBJECT_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
set_shape_id_in_flags(obj, shape_id);
}

static inline shape_id_t
RCLASS_SHAPE_ID(VALUE obj)
{
RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
return get_shape_id_from_flags(obj);
}

static inline void
RCLASS_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{
RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
set_shape_id_in_flags(obj, shape_id);
}

#define RSHAPE rb_shape_lookup
Expand Down Expand Up @@ -203,7 +166,7 @@ ROBJECT_FIELDS_CAPACITY(VALUE obj)
// Asking for capacity doesn't make sense when the object is using
// a hash table for storing instance variables
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
return RSHAPE(ROBJECT_SHAPE_ID(obj))->capacity;
return RSHAPE(RBASIC_SHAPE_ID(obj))->capacity;
}

static inline st_table *
Expand All @@ -222,8 +185,6 @@ ROBJECT_SET_FIELDS_HASH(VALUE obj, const st_table *tbl)
ROBJECT(obj)->as.heap.fields = (VALUE *)tbl;
}

size_t rb_id_table_size(const struct rb_id_table *tbl);

static inline uint32_t
ROBJECT_FIELDS_COUNT(VALUE obj)
{
Expand All @@ -233,7 +194,7 @@ ROBJECT_FIELDS_COUNT(VALUE obj)
else {
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
return RSHAPE(ROBJECT_SHAPE_ID(obj))->next_field_index;
return RSHAPE(RBASIC_SHAPE_ID(obj))->next_field_index;
}
}

Expand Down
2 changes: 2 additions & 0 deletions string.c
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,8 @@ setup_fake_str(struct RString *fake_str, const char *name, long len, int encidx)
{
fake_str->basic.flags = T_STRING|RSTRING_NOEMBED|STR_NOFREE|STR_FAKESTR;

rb_shape_set_shape_id((VALUE)fake_str, 0);

if (!name) {
RUBY_ASSERT_ALWAYS(len == 0);
name = "";
Expand Down
2 changes: 1 addition & 1 deletion test/-ext-/string/test_capacity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def capa(str)
end

def embed_header_size
3 * RbConfig::SIZEOF['void*']
GC::INTERNAL_CONSTANTS[:RBASIC_SIZE] + RbConfig::SIZEOF['void*']
end

def max_embed_len
Expand Down
Loading
Loading