-
Notifications
You must be signed in to change notification settings - Fork 13
Optimize allocations with embedded TypedData #852
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
base: Alex/Ruby-owned-graph-alloc
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |||||
| #include "location.h" | ||||||
| #include "reference.h" | ||||||
| #include "ruby/internal/globals.h" | ||||||
| #include "ruby_compat.h" | ||||||
| #include "rustbindings.h" | ||||||
| #include "utils.h" | ||||||
|
|
||||||
|
|
@@ -44,8 +45,13 @@ static void graph_free(void *ptr) { | |||||
| // let the Rust side drop the Graph struct internally. | ||||||
| rdx_graph_drop(ptr); | ||||||
|
|
||||||
| #ifdef HAVE_RUBY_TYPED_EMBEDDABLE | ||||||
| // The storage is embedded in the TypedData Ruby object itself. | ||||||
| // Don't free `ptr`, because the GC will do that for us. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: just to make it clearer which GC it means (I know Rust doesn't have GC, but maybe now everyone reading this knows)
Suggested change
|
||||||
| #else | ||||||
| // Free the TypeData Ruby object itself | ||||||
| xfree(ptr); | ||||||
| #endif | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -59,7 +65,7 @@ const rb_data_type_t graph_type = { | |||||
| }, | ||||||
| .parent = NULL, | ||||||
| .data = NULL, | ||||||
| .flags = RUBY_TYPED_FREE_IMMEDIATELY, | ||||||
| .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE, | ||||||
| }; | ||||||
|
|
||||||
| // Custom allocator for the Graph class. | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| #ifndef RUBYDEX_HANDLE_H | ||
| #define RUBYDEX_HANDLE_H | ||
|
|
||
| #include "ruby.h" | ||
| #include "ruby_compat.h" | ||
|
|
||
| typedef struct { | ||
| VALUE graph_obj; // Ruby Graph object to keep it alive | ||
|
|
@@ -15,23 +15,29 @@ static void handle_mark(void *ptr) { | |
| } | ||
| } | ||
|
|
||
| #ifndef HAVE_RUBY_TYPED_EMBEDDABLE | ||
| static void handle_free(void *ptr) { | ||
| if (ptr) { | ||
| xfree(ptr); | ||
| } | ||
| } | ||
| #endif | ||
|
|
||
| static const rb_data_type_t handle_type = { | ||
| .wrap_struct_name = "RubydexHandle", | ||
| .function = { | ||
| .dmark = handle_mark, | ||
| #ifdef HAVE_RUBY_TYPED_EMBEDDABLE | ||
| .dfree = RUBY_DEFAULT_FREE, | ||
| #else | ||
| .dfree = handle_free, | ||
| #endif | ||
| .dsize = NULL, | ||
| .dcompact = NULL, | ||
| }, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Re: line +33] Do you think you can do this? See this comment inline on Graphite.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That helps us a lot in the GC because it makes the object freeable without calling the handle free function (which is a no-op thanks to embedding)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think so! And then |
||
| .parent = NULL, | ||
| .data = NULL, | ||
| .flags = RUBY_TYPED_FREE_IMMEDIATELY, | ||
| .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE, | ||
| }; | ||
|
|
||
| static VALUE rdxr_handle_alloc(VALUE klass) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #ifndef RUBYDEX_RUBY_COMPAT_H | ||
| #define RUBYDEX_RUBY_COMPAT_H | ||
|
|
||
| #include "ruby.h" | ||
|
|
||
| #ifdef RUBY_TYPED_EMBEDDABLE | ||
| # define HAVE_RUBY_TYPED_EMBEDDABLE 1 | ||
| #else | ||
| # ifdef HAVE_CONST_RUBY_TYPED_EMBEDDABLE | ||
| # define RUBY_TYPED_EMBEDDABLE RUBY_TYPED_EMBEDDABLE | ||
| # define HAVE_RUBY_TYPED_EMBEDDABLE 1 | ||
| # else | ||
| # define RUBY_TYPED_EMBEDDABLE 0 | ||
| # endif | ||
| #endif | ||
|
|
||
| #endif // RUBYDEX_RUBY_COMPAT_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is verbose, but there's so much magic going on here that it's worth documenting.
For one, explicitly mentioning the constant name means that when you search for where
HAVE_CONST_RUBY_TYPED_EMBEDDABLEcomes from, you'll find this.