Skip to content

Commit

Permalink
Add write barriers to PG::Coder and derivations
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
larskanis committed Mar 29, 2023
1 parent 43b80fb commit 113ee1a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 16 deletions.
12 changes: 7 additions & 5 deletions ext/pg_coder.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pg_coder_init_encoder( VALUE self )
this->enc_func = NULL;
}
this->dec_func = NULL;
this->coder_obj = self;
RB_OBJ_WRITE(self, &this->coder_obj, self);
this->oid = 0;
this->format = 0;
this->flags = 0;
Expand All @@ -54,7 +54,7 @@ pg_coder_init_decoder( VALUE self )
} else {
this->dec_func = NULL;
}
this->coder_obj = self;
RB_OBJ_WRITE(self, &this->coder_obj, self);
this->oid = 0;
this->format = 0;
this->flags = 0;
Expand Down Expand Up @@ -99,7 +99,9 @@ const rb_data_type_t pg_coder_type = {
},
0,
0,
RUBY_TYPED_FREE_IMMEDIATELY,
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
// macro to update VALUE references, as to trigger write barriers.
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

static VALUE
Expand All @@ -121,7 +123,7 @@ static const rb_data_type_t pg_composite_coder_type = {
},
&pg_coder_type,
0,
RUBY_TYPED_FREE_IMMEDIATELY,
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

static VALUE
Expand Down Expand Up @@ -452,7 +454,7 @@ static const rb_data_type_t pg_coder_cfunc_type = {
},
0,
0,
RUBY_TYPED_FREE_IMMEDIATELY,
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

VALUE
Expand Down
14 changes: 7 additions & 7 deletions ext/pg_copy_coder.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static const rb_data_type_t pg_copycoder_type = {
},
&pg_coder_type,
0,
RUBY_TYPED_FREE_IMMEDIATELY,
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

static VALUE
Expand All @@ -64,9 +64,9 @@ pg_copycoder_encoder_allocate( VALUE klass )
t_pg_copycoder *this;
VALUE self = TypedData_Make_Struct( klass, t_pg_copycoder, &pg_copycoder_type, this );
pg_coder_init_encoder( self );
this->typemap = pg_typemap_all_strings;
RB_OBJ_WRITE(self, &this->typemap, pg_typemap_all_strings);
this->delimiter = '\t';
this->null_string = rb_str_new_cstr("\\N");
RB_OBJ_WRITE(self, &this->null_string, rb_str_new_cstr("\\N"));
return self;
}

Expand All @@ -76,9 +76,9 @@ pg_copycoder_decoder_allocate( VALUE klass )
t_pg_copycoder *this;
VALUE self = TypedData_Make_Struct( klass, t_pg_copycoder, &pg_copycoder_type, this );
pg_coder_init_decoder( self );
this->typemap = pg_typemap_all_strings;
RB_OBJ_WRITE(self, &this->typemap, pg_typemap_all_strings);
this->delimiter = '\t';
this->null_string = rb_str_new_cstr("\\N");
RB_OBJ_WRITE(self, &this->null_string, rb_str_new_cstr("\\N"));
return self;
}

Expand Down Expand Up @@ -128,7 +128,7 @@ pg_copycoder_null_string_set(VALUE self, VALUE null_string)
{
t_pg_copycoder *this = RTYPEDDATA_DATA(self);
StringValue(null_string);
this->null_string = null_string;
RB_OBJ_WRITE(self, &this->null_string, null_string);
return null_string;
}

Expand Down Expand Up @@ -162,7 +162,7 @@ pg_copycoder_type_map_set(VALUE self, VALUE type_map)
rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::TypeMap)",
rb_obj_classname( type_map ) );
}
this->typemap = type_map;
RB_OBJ_WRITE(self, &this->typemap, type_map);

return type_map;
}
Expand Down
8 changes: 4 additions & 4 deletions ext/pg_record_coder.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static const rb_data_type_t pg_recordcoder_type = {
},
&pg_coder_type,
0,
RUBY_TYPED_FREE_IMMEDIATELY,
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

static VALUE
Expand All @@ -56,7 +56,7 @@ pg_recordcoder_encoder_allocate( VALUE klass )
t_pg_recordcoder *this;
VALUE self = TypedData_Make_Struct( klass, t_pg_recordcoder, &pg_recordcoder_type, this );
pg_coder_init_encoder( self );
this->typemap = pg_typemap_all_strings;
RB_OBJ_WRITE(self, &this->typemap, pg_typemap_all_strings);
return self;
}

Expand All @@ -66,7 +66,7 @@ pg_recordcoder_decoder_allocate( VALUE klass )
t_pg_recordcoder *this;
VALUE self = TypedData_Make_Struct( klass, t_pg_recordcoder, &pg_recordcoder_type, this );
pg_coder_init_decoder( self );
this->typemap = pg_typemap_all_strings;
RB_OBJ_WRITE(self, &this->typemap, pg_typemap_all_strings);
return self;
}

Expand All @@ -90,7 +90,7 @@ pg_recordcoder_type_map_set(VALUE self, VALUE type_map)
rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::TypeMap)",
rb_obj_classname( type_map ) );
}
this->typemap = type_map;
RB_OBJ_WRITE(self, &this->typemap, type_map);

return type_map;
}
Expand Down

0 comments on commit 113ee1a

Please sign in to comment.