Implement Write Barrier for RMatch objects

They only have two references.
This commit is contained in:
Jean Boussier 2023-02-10 14:32:46 +01:00 committed by Jean Boussier
parent 11e0f62148
commit 46298955e4
Notes: git 2023-02-10 15:12:49 +00:00
2 changed files with 23 additions and 13 deletions

View file

@ -129,6 +129,17 @@
# define RGENGC_WB_PROTECTED_REGEXP 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RMatch. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_MATCH
# define RGENGC_WB_PROTECTED_MATCH 1
#endif
/**
* @private
*

25
re.c
View file

@ -961,11 +961,11 @@ VALUE rb_cMatch;
static VALUE
match_alloc(VALUE klass)
{
NEWOBJ_OF(match, struct RMatch, klass, T_MATCH);
NEWOBJ_OF(match, struct RMatch, klass, T_MATCH | (RGENGC_WB_PROTECTED_MATCH ? FL_WB_PROTECTED : 0));
match->str = 0;
match->str = Qfalse;
match->rmatch = 0;
match->regexp = 0;
match->regexp = Qfalse;
match->rmatch = ZALLOC(struct rmatch);
return (VALUE)match;
@ -1083,8 +1083,8 @@ match_init_copy(VALUE obj, VALUE orig)
if (!OBJ_INIT_COPY(obj, orig)) return obj;
RMATCH(obj)->str = RMATCH(orig)->str;
RMATCH(obj)->regexp = RMATCH(orig)->regexp;
RB_OBJ_WRITE(obj, &RMATCH(obj)->str, RMATCH(orig)->str);
RB_OBJ_WRITE(obj, &RMATCH(obj)->regexp, RMATCH(orig)->regexp);
rm = RMATCH(obj)->rmatch;
if (rb_reg_region_copy(&rm->regs, RMATCH_REGS(orig)))
@ -1124,7 +1124,7 @@ match_regexp(VALUE match)
if (NIL_P(regexp)) {
VALUE str = rb_reg_nth_match(0, match);
regexp = rb_reg_regcomp(rb_reg_quote(str));
RMATCH(match)->regexp = regexp;
RB_OBJ_WRITE(match, &RMATCH(match)->regexp, regexp);
}
return regexp;
}
@ -1475,8 +1475,8 @@ match_set_string(VALUE m, VALUE string, long pos, long len)
struct RMatch *match = (struct RMatch *)m;
struct rmatch *rmatch = match->rmatch;
match->str = string;
match->regexp = Qnil;
RB_OBJ_WRITE(match, &RMATCH(match)->str, string);
RB_OBJ_WRITE(match, &RMATCH(match)->regexp, Qnil);
int err = onig_region_resize(&rmatch->regs, 1);
if (err) rb_memerror();
rmatch->regs.beg[0] = pos;
@ -1737,7 +1737,7 @@ rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_back
memcpy(RMATCH_REGS(match), regs, sizeof(struct re_registers));
if (set_backref_str) {
RMATCH(match)->str = rb_str_new4(str);
RB_OBJ_WRITE(match, &RMATCH(match)->str, rb_str_new4(str));
}
else {
/* Note that a MatchData object with RMATCH(match)->str == 0 is incomplete!
@ -1747,7 +1747,7 @@ rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_back
rb_obj_hide(match);
}
RMATCH(match)->regexp = re;
RB_OBJ_WRITE(match, &RMATCH(match)->regexp, re);
rb_backref_set(match);
if (set_match) *set_match = match;
@ -1831,9 +1831,8 @@ rb_reg_start_with_p(VALUE re, VALUE str)
if (err) rb_memerror();
}
RMATCH(match)->str = rb_str_new4(str);
RMATCH(match)->regexp = re;
RB_OBJ_WRITE(match, &RMATCH(match)->str, rb_str_new4(str));
RB_OBJ_WRITE(match, &RMATCH(match)->regexp, re);
rb_backref_set(match);
return true;