Embed struct rmatch into GC slot (#8097)
This commit is contained in:
parent
460c27dc15
commit
639aa76e82
10
gc.c
10
gc.c
@ -3509,8 +3509,8 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
|
|||||||
if (!rb_data_free(objspace, obj)) return false;
|
if (!rb_data_free(objspace, obj)) return false;
|
||||||
break;
|
break;
|
||||||
case T_MATCH:
|
case T_MATCH:
|
||||||
if (RANY(obj)->as.match.rmatch) {
|
{
|
||||||
struct rmatch *rm = RANY(obj)->as.match.rmatch;
|
rb_matchext_t *rm = RMATCH_EXT(obj);
|
||||||
#if USE_DEBUG_COUNTER
|
#if USE_DEBUG_COUNTER
|
||||||
if (rm->regs.num_regs >= 8) {
|
if (rm->regs.num_regs >= 8) {
|
||||||
RB_DEBUG_COUNTER_INC(obj_match_ge8);
|
RB_DEBUG_COUNTER_INC(obj_match_ge8);
|
||||||
@ -3525,7 +3525,6 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
|
|||||||
onig_region_free(&rm->regs, 0);
|
onig_region_free(&rm->regs, 0);
|
||||||
if (rm->char_offset)
|
if (rm->char_offset)
|
||||||
xfree(rm->char_offset);
|
xfree(rm->char_offset);
|
||||||
xfree(rm);
|
|
||||||
|
|
||||||
RB_DEBUG_COUNTER_INC(obj_match_ptr);
|
RB_DEBUG_COUNTER_INC(obj_match_ptr);
|
||||||
}
|
}
|
||||||
@ -4841,11 +4840,10 @@ obj_memsize_of(VALUE obj, int use_all_types)
|
|||||||
if (use_all_types) size += rb_objspace_data_type_memsize(obj);
|
if (use_all_types) size += rb_objspace_data_type_memsize(obj);
|
||||||
break;
|
break;
|
||||||
case T_MATCH:
|
case T_MATCH:
|
||||||
if (RMATCH(obj)->rmatch) {
|
{
|
||||||
struct rmatch *rm = RMATCH(obj)->rmatch;
|
rb_matchext_t *rm = RMATCH_EXT(obj);
|
||||||
size += onig_region_memsize(&rm->regs);
|
size += onig_region_memsize(&rm->regs);
|
||||||
size += sizeof(struct rmatch_offset) * rm->char_offset_num_allocated;
|
size += sizeof(struct rmatch_offset) * rm->char_offset_num_allocated;
|
||||||
size += sizeof(struct rmatch);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_FILE:
|
case T_FILE:
|
||||||
|
@ -68,7 +68,7 @@ struct rmatch_offset {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Represents a match. */
|
/** Represents a match. */
|
||||||
struct rmatch {
|
struct rb_matchext_struct {
|
||||||
/**
|
/**
|
||||||
* "Registers" of a match. This is a quasi-opaque struct that holds
|
* "Registers" of a match. This is a quasi-opaque struct that holds
|
||||||
* execution result of a match. Roughly resembles `&~`.
|
* execution result of a match. Roughly resembles `&~`.
|
||||||
@ -82,6 +82,8 @@ struct rmatch {
|
|||||||
int char_offset_num_allocated;
|
int char_offset_num_allocated;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct rb_matchext_struct rb_matchext_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regular expression execution context. When a regular expression "matches"
|
* Regular expression execution context. When a regular expression "matches"
|
||||||
* to a string, it generates capture groups etc. This struct holds that info.
|
* to a string, it generates capture groups etc. This struct holds that info.
|
||||||
@ -101,17 +103,14 @@ struct RMatch {
|
|||||||
*/
|
*/
|
||||||
VALUE str;
|
VALUE str;
|
||||||
|
|
||||||
/**
|
|
||||||
* The result of this match.
|
|
||||||
*/
|
|
||||||
struct rmatch *rmatch;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The expression of this match.
|
* The expression of this match.
|
||||||
*/
|
*/
|
||||||
VALUE regexp; /* RRegexp */
|
VALUE regexp; /* RRegexp */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RMATCH_EXT(m) ((rb_matchext_t *)((char *)(m) + sizeof(struct RMatch)))
|
||||||
|
|
||||||
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
|
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
|
||||||
RBIMPL_ATTR_ARTIFICIAL()
|
RBIMPL_ATTR_ARTIFICIAL()
|
||||||
/**
|
/**
|
||||||
@ -139,8 +138,7 @@ static inline struct re_registers *
|
|||||||
RMATCH_REGS(VALUE match)
|
RMATCH_REGS(VALUE match)
|
||||||
{
|
{
|
||||||
RBIMPL_ASSERT_TYPE(match, RUBY_T_MATCH);
|
RBIMPL_ASSERT_TYPE(match, RUBY_T_MATCH);
|
||||||
RBIMPL_ASSERT_OR_ASSUME(RMATCH(match)->rmatch != NULL);
|
return &RMATCH_EXT(match)->regs;
|
||||||
return &RMATCH(match)->rmatch->regs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* RBIMPL_RMATCH_H */
|
#endif /* RBIMPL_RMATCH_H */
|
||||||
|
29
re.c
29
re.c
@ -961,12 +961,13 @@ VALUE rb_cMatch;
|
|||||||
static VALUE
|
static VALUE
|
||||||
match_alloc(VALUE klass)
|
match_alloc(VALUE klass)
|
||||||
{
|
{
|
||||||
NEWOBJ_OF(match, struct RMatch, klass, T_MATCH | (RGENGC_WB_PROTECTED_MATCH ? FL_WB_PROTECTED : 0), sizeof(struct RMatch), 0);
|
size_t alloc_size = sizeof(struct RMatch) + sizeof(rb_matchext_t);
|
||||||
|
VALUE flags = T_MATCH | (RGENGC_WB_PROTECTED_MATCH ? FL_WB_PROTECTED : 0);
|
||||||
|
NEWOBJ_OF(match, struct RMatch, klass, flags, alloc_size, 0);
|
||||||
|
|
||||||
match->str = Qfalse;
|
match->str = Qfalse;
|
||||||
match->rmatch = 0;
|
|
||||||
match->regexp = Qfalse;
|
match->regexp = Qfalse;
|
||||||
match->rmatch = ZALLOC(struct rmatch);
|
memset(RMATCH_EXT(match), 0, sizeof(rb_matchext_t));
|
||||||
|
|
||||||
return (VALUE)match;
|
return (VALUE)match;
|
||||||
}
|
}
|
||||||
@ -1001,7 +1002,7 @@ pair_byte_cmp(const void *pair1, const void *pair2)
|
|||||||
static void
|
static void
|
||||||
update_char_offset(VALUE match)
|
update_char_offset(VALUE match)
|
||||||
{
|
{
|
||||||
struct rmatch *rm = RMATCH(match)->rmatch;
|
rb_matchext_t *rm = RMATCH_EXT(match);
|
||||||
struct re_registers *regs;
|
struct re_registers *regs;
|
||||||
int i, num_regs, num_pos;
|
int i, num_regs, num_pos;
|
||||||
long c;
|
long c;
|
||||||
@ -1079,23 +1080,23 @@ match_check(VALUE match)
|
|||||||
static VALUE
|
static VALUE
|
||||||
match_init_copy(VALUE obj, VALUE orig)
|
match_init_copy(VALUE obj, VALUE orig)
|
||||||
{
|
{
|
||||||
struct rmatch *rm;
|
rb_matchext_t *rm;
|
||||||
|
|
||||||
if (!OBJ_INIT_COPY(obj, orig)) return obj;
|
if (!OBJ_INIT_COPY(obj, orig)) return obj;
|
||||||
|
|
||||||
RB_OBJ_WRITE(obj, &RMATCH(obj)->str, RMATCH(orig)->str);
|
RB_OBJ_WRITE(obj, &RMATCH(obj)->str, RMATCH(orig)->str);
|
||||||
RB_OBJ_WRITE(obj, &RMATCH(obj)->regexp, RMATCH(orig)->regexp);
|
RB_OBJ_WRITE(obj, &RMATCH(obj)->regexp, RMATCH(orig)->regexp);
|
||||||
|
|
||||||
rm = RMATCH(obj)->rmatch;
|
rm = RMATCH_EXT(obj);
|
||||||
if (rb_reg_region_copy(&rm->regs, RMATCH_REGS(orig)))
|
if (rb_reg_region_copy(&rm->regs, RMATCH_REGS(orig)))
|
||||||
rb_memerror();
|
rb_memerror();
|
||||||
|
|
||||||
if (RMATCH(orig)->rmatch->char_offset_num_allocated) {
|
if (RMATCH_EXT(orig)->char_offset_num_allocated) {
|
||||||
if (rm->char_offset_num_allocated < rm->regs.num_regs) {
|
if (rm->char_offset_num_allocated < rm->regs.num_regs) {
|
||||||
REALLOC_N(rm->char_offset, struct rmatch_offset, rm->regs.num_regs);
|
REALLOC_N(rm->char_offset, struct rmatch_offset, rm->regs.num_regs);
|
||||||
rm->char_offset_num_allocated = rm->regs.num_regs;
|
rm->char_offset_num_allocated = rm->regs.num_regs;
|
||||||
}
|
}
|
||||||
MEMCPY(rm->char_offset, RMATCH(orig)->rmatch->char_offset,
|
MEMCPY(rm->char_offset, RMATCH_EXT(orig)->char_offset,
|
||||||
struct rmatch_offset, rm->regs.num_regs);
|
struct rmatch_offset, rm->regs.num_regs);
|
||||||
RB_GC_GUARD(orig);
|
RB_GC_GUARD(orig);
|
||||||
}
|
}
|
||||||
@ -1250,8 +1251,8 @@ match_offset(VALUE match, VALUE n)
|
|||||||
return rb_assoc_new(Qnil, Qnil);
|
return rb_assoc_new(Qnil, Qnil);
|
||||||
|
|
||||||
update_char_offset(match);
|
update_char_offset(match);
|
||||||
return rb_assoc_new(LONG2NUM(RMATCH(match)->rmatch->char_offset[i].beg),
|
return rb_assoc_new(LONG2NUM(RMATCH_EXT(match)->char_offset[i].beg),
|
||||||
LONG2NUM(RMATCH(match)->rmatch->char_offset[i].end));
|
LONG2NUM(RMATCH_EXT(match)->char_offset[i].end));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1309,7 +1310,7 @@ match_begin(VALUE match, VALUE n)
|
|||||||
return Qnil;
|
return Qnil;
|
||||||
|
|
||||||
update_char_offset(match);
|
update_char_offset(match);
|
||||||
return LONG2NUM(RMATCH(match)->rmatch->char_offset[i].beg);
|
return LONG2NUM(RMATCH_EXT(match)->char_offset[i].beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1335,7 +1336,7 @@ match_end(VALUE match, VALUE n)
|
|||||||
return Qnil;
|
return Qnil;
|
||||||
|
|
||||||
update_char_offset(match);
|
update_char_offset(match);
|
||||||
return LONG2NUM(RMATCH(match)->rmatch->char_offset[i].end);
|
return LONG2NUM(RMATCH_EXT(match)->char_offset[i].end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1422,7 +1423,7 @@ match_nth_length(VALUE match, VALUE n)
|
|||||||
|
|
||||||
update_char_offset(match);
|
update_char_offset(match);
|
||||||
const struct rmatch_offset *const ofs =
|
const struct rmatch_offset *const ofs =
|
||||||
&RMATCH(match)->rmatch->char_offset[i];
|
&RMATCH_EXT(match)->char_offset[i];
|
||||||
return LONG2NUM(ofs->end - ofs->beg);
|
return LONG2NUM(ofs->end - ofs->beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1454,7 +1455,7 @@ static void
|
|||||||
match_set_string(VALUE m, VALUE string, long pos, long len)
|
match_set_string(VALUE m, VALUE string, long pos, long len)
|
||||||
{
|
{
|
||||||
struct RMatch *match = (struct RMatch *)m;
|
struct RMatch *match = (struct RMatch *)m;
|
||||||
struct rmatch *rmatch = match->rmatch;
|
rb_matchext_t *rmatch = RMATCH_EXT(match);
|
||||||
|
|
||||||
RB_OBJ_WRITE(match, &RMATCH(match)->str, string);
|
RB_OBJ_WRITE(match, &RMATCH(match)->str, string);
|
||||||
RB_OBJ_WRITE(match, &RMATCH(match)->regexp, Qnil);
|
RB_OBJ_WRITE(match, &RMATCH(match)->regexp, Qnil);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user