Skip to content

[Feature #19406] Allow declarative definition of references for rb_typed_data_struct #7153

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 5 commits into from
Mar 17, 2023

Conversation

eightbitraptor
Copy link
Contributor

@eightbitraptor eightbitraptor commented Jan 19, 2023

When using rb_data_type_struct to wrap a C struct, that C struct can
contain VALUE references to other Ruby objects.

If this is the case then one must also define dmark and optionally
dcompact callbacks in order to allow these objects to be correctly
handled by the GC. This is suboptimal as it requires GC related logic to
be implemented by extension developers. This can be a cause of subtle
bugs when references are not marked of updated correctly inside these
callbacks.

This commit provides an alternative approach, useful in the simple case
where the C struct contains VALUE members (ie. there isn't any
conditional logic, or data structure manipulation required to traverse
these references).

In this case references can be defined using a declarative syntax
as a list of edges (or, pointers to references).

A flag can be set on the rb_data_type_struct to notify the GC that
declarative references are being used, and a list of those references
can be assigned to the arbitrary data pointer on the
rb_data_type_struct.

Macros are also provided for simple declaration of the reference list,
and building edges.

To avoid having to also find space in the struct to define a length for
the references list, I've chosed to always terminate the references list
with RUBY_REF_END - defined as UINTPTR_MAX. My assumption is that no
single struct will ever be large enough that UINTPTR_MAX is actually a
valid reference.

This PR also provides example implementations for dir_data and
enumerator

TODO (Post merge)

  • Implement for more types

@eightbitraptor eightbitraptor force-pushed the mvh-declarative-marking branch from bc6408d to ee142f1 Compare January 19, 2023 19:38
@eightbitraptor eightbitraptor force-pushed the mvh-declarative-marking branch from 69779ab to e749822 Compare January 24, 2023 20:46
@eightbitraptor eightbitraptor force-pushed the mvh-declarative-marking branch 7 times, most recently from 56e6b0f to bd48a53 Compare February 3, 2023 09:33
@eightbitraptor eightbitraptor changed the title Allow declarative definition of references for rb_typed_data_struct [Feature 19406] Allow declarative definition of references for rb_typed_data_struct Feb 3, 2023
@eightbitraptor eightbitraptor changed the title [Feature 19406] Allow declarative definition of references for rb_typed_data_struct [Feature #19406] Allow declarative definition of references for rb_typed_data_struct Feb 3, 2023
@eightbitraptor eightbitraptor marked this pull request as ready for review February 13, 2023 12:44
@eightbitraptor eightbitraptor force-pushed the mvh-declarative-marking branch from bd48a53 to 6515578 Compare February 13, 2023 12:46
@eightbitraptor eightbitraptor force-pushed the mvh-declarative-marking branch 2 times, most recently from 7b1b866 to 80c5389 Compare March 10, 2023 12:49
@eightbitraptor eightbitraptor force-pushed the mvh-declarative-marking branch 7 times, most recently from 7d0685f to c7b9830 Compare March 16, 2023 22:27
When using rb_data_type_struct to wrap a C struct, that C struct can
contain VALUE references to other Ruby objects.

If this is the case then one must also define dmark and optionally
dcompact callbacks in order to allow these objects to be correctly
handled by the GC. This is suboptimal as it requires GC related logic to
be implemented by extension developers. This can be a cause of subtle
bugs when references are not marked of updated correctly inside these
callbacks.

This commit provides an alternative approach, useful in the simple case
where the C struct contains VALUE members (ie. there isn't any
conditional logic, or data structure manipulation required to traverse
these references).

In this case references can be defined using a declarative syntax
as a list of edges (or, pointers to references).

A flag can be set on the rb_data_type_struct to notify the GC that
declarative references are being used, and a list of those references
can be assigned to the dmark pointer instead of a function callback, on
the rb_data_type_struct.

Macros are also provided for simple declaration of the reference list,
and building edges.

To avoid having to also find space in the struct to define a length for
the references list, I've chosed to always terminate the references list
with RUBY_REF_END - defined as UINTPTR_MAX. My assumption is that no
single struct will ever be large enough that UINTPTR_MAX is actually a
valid reference.
@eightbitraptor eightbitraptor force-pushed the mvh-declarative-marking branch from c7b9830 to 34dff0f Compare March 17, 2023 13:42
@eightbitraptor eightbitraptor merged commit 5897a6f into ruby:master Mar 17, 2023
@eightbitraptor eightbitraptor deleted the mvh-declarative-marking branch March 17, 2023 19:20
Comment on lines +47 to +48
#define REF_EDGE(s, p) (offsetof(struct s, p))
#define REFS_LIST_PTR(l) ((RUBY_DATA_FUNC)l)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why these are not RUBY_ prefixed?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi

Comment on lines +50 to +51
#define RUBY_REFERENCES_START(t) static size_t t[] = {
#define RUBY_REFERENCES_END RUBY_REF_END, };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hiding braces inside macros make editors confused.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi

@nobu
Copy link
Member

nobu commented Nov 30, 2023

#9078

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants