Skip to content

Commit

Permalink
Implement Write Barrier for RMatch objects
Browse files Browse the repository at this point in the history
They only have two references.
  • Loading branch information
byroot committed Feb 10, 2023
1 parent 11e0f62 commit 4629895
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
11 changes: 11 additions & 0 deletions include/ruby/internal/rgengc.h
Expand Up @@ -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
*
Expand Down
25 changes: 12 additions & 13 deletions re.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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)))
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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!
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 4629895

Please sign in to comment.