diff options
author | Jean Boussier <jean.boussier@gmail.com> | 2023-03-06 15:03:56 +0100 |
---|---|---|
committer | Jean Boussier <jean.boussier@gmail.com> | 2023-03-06 15:05:39 +0100 |
commit | cae3095fd1c782660baf5aa1f8aa40415d032799 (patch) | |
tree | 66f48a687527d08ad7670c51537daa82fa64a13f /ext/ffi_c/Struct.h | |
parent | b5c043e0cad70790d336af80b1320083742da756 (diff) | |
download | ffi-cae3095fd1c782660baf5aa1f8aa40415d032799.tar.gz |
Implement Write Barrier and dsize for FFI::StructLayout
And FFI::StructLayout::Field
Write barrier protected objects are allowed to be promoted to the old generation,
which means they only get marked on major GC.
The downside is that the RB_BJ_WRITE macro MUST be used to set references,
otherwise the referenced object may be garbaged collected.
This commit also implement a `dsize` function so that these instance
report a more relevant size in various memory profilers.
I had to get rid of the `memset(0)` in `struct_layout_mark` has with Write Barriers
it's not guaranteed that the layout will be marked before `fieldName` is moved.
I don't think it was a good fix anyway, it's better to mark these VALUE so the GC pin
them. I think we could go back to an `st_table` and mark only the keys with `rb_mark_set`.
But I didn't want to go down this rabbit hole.
Diffstat (limited to 'ext/ffi_c/Struct.h')
-rw-r--r-- | ext/ffi_c/Struct.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/ext/ffi_c/Struct.h b/ext/ffi_c/Struct.h index 1cba8bb..8e9491b 100644 --- a/ext/ffi_c/Struct.h +++ b/ext/ffi_c/Struct.h @@ -78,11 +78,12 @@ extern "C" { * This avoids full ruby hash lookups for repeated lookups. */ #define FIELD_CACHE_LOOKUP(this, sym) ( &(this)->cache_row[((sym) >> 8) & 0xff] ) + #define FIELD_CACHE_ROWS 0x100 struct field_cache_entry { VALUE fieldName; StructField *field; - } cache_row[0x100]; + } cache_row[FIELD_CACHE_ROWS]; /** The number of reference tracking fields in this struct */ int referenceFieldCount; |