summaryrefslogtreecommitdiff
path: root/ext/ffi_c/Struct.h
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2023-03-06 15:03:56 +0100
committerJean Boussier <jean.boussier@gmail.com>2023-03-06 15:05:39 +0100
commitcae3095fd1c782660baf5aa1f8aa40415d032799 (patch)
tree66f48a687527d08ad7670c51537daa82fa64a13f /ext/ffi_c/Struct.h
parentb5c043e0cad70790d336af80b1320083742da756 (diff)
downloadffi-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.h3
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;