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

Skip to content

Save one VALUE per embedded RTypedData #13190

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

Merged
Merged
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
18 changes: 9 additions & 9 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,7 @@ rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FU
{
RUBY_ASSERT_ALWAYS(dfree != (RUBY_DATA_FUNC)1);
if (klass) rb_data_object_check(klass);
return newobj_of(GET_RACTOR(), klass, T_DATA, (VALUE)dmark, (VALUE)dfree, (VALUE)datap, !dmark, sizeof(struct RTypedData));
return newobj_of(GET_RACTOR(), klass, T_DATA, (VALUE)dmark, (VALUE)datap, (VALUE)dfree, !dmark, sizeof(struct RTypedData));
}

VALUE
Expand All @@ -1081,7 +1081,7 @@ typed_data_alloc(VALUE klass, VALUE typed_flag, void *datap, const rb_data_type_
RBIMPL_NONNULL_ARG(type);
if (klass) rb_data_object_check(klass);
bool wb_protected = (type->flags & RUBY_FL_WB_PROTECTED) || !type->function.dmark;
return newobj_of(GET_RACTOR(), klass, T_DATA, (VALUE)type, 1 | typed_flag, (VALUE)datap, wb_protected, size);
return newobj_of(GET_RACTOR(), klass, T_DATA, ((VALUE)type) | IS_TYPED_DATA | typed_flag, (VALUE)datap, 0, wb_protected, size);
}

VALUE
Expand Down Expand Up @@ -1177,8 +1177,8 @@ rb_data_free(void *objspace, VALUE obj)
void (*dfree)(void *);

if (RTYPEDDATA_P(obj)) {
free_immediately = (RTYPEDDATA(obj)->type->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0;
dfree = RTYPEDDATA(obj)->type->function.dfree;
free_immediately = (RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0;
dfree = RTYPEDDATA_TYPE(obj)->function.dfree;
}
else {
dfree = RDATA(obj)->dfree;
Expand Down Expand Up @@ -2660,7 +2660,7 @@ rb_gc_mark_roots(void *objspace, const char **categoryp)
#undef MARK_CHECKPOINT
}

#define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA(d)->type->function.dmark
#define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA_TYPE(d)->function.dmark

void
rb_gc_mark_children(void *objspace, VALUE obj)
Expand Down Expand Up @@ -2780,7 +2780,7 @@ rb_gc_mark_children(void *objspace, VALUE obj)
void *const ptr = RTYPEDDATA_P(obj) ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);

if (ptr) {
if (RTYPEDDATA_P(obj) && gc_declarative_marking_p(RTYPEDDATA(obj)->type)) {
if (RTYPEDDATA_P(obj) && gc_declarative_marking_p(RTYPEDDATA_TYPE(obj))) {
size_t *offset_list = TYPED_DATA_REFS_OFFSET_LIST(obj);

for (size_t offset = *offset_list; offset != RUBY_REF_END; offset = *offset_list++) {
Expand All @@ -2789,7 +2789,7 @@ rb_gc_mark_children(void *objspace, VALUE obj)
}
else {
RUBY_DATA_FUNC mark_func = RTYPEDDATA_P(obj) ?
RTYPEDDATA(obj)->type->function.dmark :
RTYPEDDATA_TYPE(obj)->function.dmark :
RDATA(obj)->dmark;
if (mark_func) (*mark_func)(ptr);
}
Expand Down Expand Up @@ -3717,7 +3717,7 @@ rb_gc_update_object_references(void *objspace, VALUE obj)
{
void *const ptr = RTYPEDDATA_P(obj) ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
if (ptr) {
if (RTYPEDDATA_P(obj) && gc_declarative_marking_p(RTYPEDDATA(obj)->type)) {
if (RTYPEDDATA_P(obj) && gc_declarative_marking_p(RTYPEDDATA_TYPE(obj))) {
size_t *offset_list = TYPED_DATA_REFS_OFFSET_LIST(obj);

for (size_t offset = *offset_list; offset != RUBY_REF_END; offset = *offset_list++) {
Expand All @@ -3726,7 +3726,7 @@ rb_gc_update_object_references(void *objspace, VALUE obj)
}
}
else if (RTYPEDDATA_P(obj)) {
RUBY_DATA_FUNC compact_func = RTYPEDDATA(obj)->type->function.dcompact;
RUBY_DATA_FUNC compact_func = RTYPEDDATA_TYPE(obj)->function.dcompact;
if (compact_func) (*compact_func)(ptr);
}
}
Expand Down
9 changes: 6 additions & 3 deletions include/ruby/internal/core/rdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ struct RData {
*/
RUBY_DATA_FUNC dmark;

/** Pointer to the actual C level struct that you want to wrap.
* This is in between dmark and dfree to allow DATA_PTR to continue
* to work for both RData and non-embedded RTypedData.
*/
void *data;

/**
* This function is called when the object is no longer used. You need to
* do whatever necessary to avoid memory leaks.
Expand All @@ -141,9 +147,6 @@ struct RData {
* impossible at that moment (that is why GC runs).
*/
RUBY_DATA_FUNC dfree;

/** Pointer to the actual C level struct that you want to wrap. */
void *data;
};

RBIMPL_SYMBOL_EXPORT_BEGIN()
Expand Down
26 changes: 13 additions & 13 deletions include/ruby/internal/core/rtypeddata.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@
#define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1
/** @endcond */

#define TYPED_DATA_EMBEDDED 2
#define IS_TYPED_DATA ((VALUE)1)
#define TYPED_DATA_EMBEDDED ((VALUE)2)
#define TYPED_DATA_PTR_FLAGS ((VALUE)3)
#define TYPED_DATA_PTR_MASK (~TYPED_DATA_PTR_FLAGS)

/**
* @private
Expand Down Expand Up @@ -353,18 +356,16 @@ struct RTypedData {
struct RBasic basic;

/**
* This is a `const rb_data_type_t *const` value, with the low bits set:
*
* 1: Always set, to differentiate RTypedData from RData.
* 2: Set if object is embedded.
*
* This field stores various information about how Ruby should handle a
* data. This roughly resembles a Ruby level class (apart from method
* definition etc.)
*/
const rb_data_type_t *const type;

/**
* This has to be always 1.
*
* @internal
*/
const VALUE typed_flag;
const VALUE type;

/** Pointer to the actual C level struct that you want to wrap. */
void *data;
Expand Down Expand Up @@ -525,7 +526,7 @@ RTYPEDDATA_EMBEDDED_P(VALUE obj)
}
#endif

return RTYPEDDATA(obj)->typed_flag & TYPED_DATA_EMBEDDED;
return (RTYPEDDATA(obj)->type) & TYPED_DATA_EMBEDDED;
}

static inline void *
Expand Down Expand Up @@ -561,8 +562,7 @@ RBIMPL_ATTR_ARTIFICIAL()
static inline bool
rbimpl_rtypeddata_p(VALUE obj)
{
VALUE typed_flag = RTYPEDDATA(obj)->typed_flag;
return typed_flag != 0 && typed_flag <= 3;
return RTYPEDDATA(obj)->type & IS_TYPED_DATA;
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
Expand Down Expand Up @@ -608,7 +608,7 @@ RTYPEDDATA_TYPE(VALUE obj)
}
#endif

return RTYPEDDATA(obj)->type;
return (const struct rb_data_type_struct *)(RTYPEDDATA(obj)->type & TYPED_DATA_PTR_MASK);
}

/**
Expand Down
Loading