From 3be1c8890774c04d65bbed87914e9453d1496eed Mon Sep 17 00:00:00 2001 From: Yukihiro Matsumoto Date: Sun, 3 Jun 2012 22:59:40 +0900 Subject: str_modify() revives string buffer kept in shared structure if refcnt == 1 --- src/string.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/string.c b/src/string.c index d7749c27b..d09d8942b 100644 --- a/src/string.c +++ b/src/string.c @@ -57,23 +57,29 @@ static void str_modify(mrb_state *mrb, struct RString *s) { if (s->flags & MRB_STR_SHARED) { - char *ptr, *p; - long len; struct mrb_shared_string *shared = s->aux.shared; - p = s->buf; - len = s->len; - ptr = mrb_malloc(mrb, sizeof(char)*(len+1)); - if (p) { - memcpy(ptr, p, len); + if (shared->refcnt == 1 && s->buf == shared->buf) { + s->buf = shared->buf; + s->aux.capa = shared->len; + mrb_free(mrb, shared); + } + else { + char *ptr, *p; + long len; + + p = s->buf; + len = s->len; + ptr = mrb_malloc(mrb, len+1); + if (p) { + memcpy(ptr, p, len); + } + ptr[len] = 0; + s->buf = ptr; + s->aux.capa = len; + mrb_str_decref(mrb, shared); } - ptr[len] = 0; - s->buf = ptr; - s->len = len; - s->aux.capa = len; s->flags &= ~MRB_STR_SHARED; - - mrb_str_decref(mrb, shared); } } -- cgit v1.2.3