diff options
| author | Yukihiro Matsumoto <[email protected]> | 2012-06-03 22:59:40 +0900 |
|---|---|---|
| committer | Yukihiro Matsumoto <[email protected]> | 2012-06-03 22:59:40 +0900 |
| commit | 3be1c8890774c04d65bbed87914e9453d1496eed (patch) | |
| tree | f4c5a74cfce4d9650aa92e1289ddfcbc4903746d /src | |
| parent | e66587439a0b2026ad56ba3548245a6d25d62b67 (diff) | |
| download | mruby-3be1c8890774c04d65bbed87914e9453d1496eed.tar.gz mruby-3be1c8890774c04d65bbed87914e9453d1496eed.zip | |
str_modify() revives string buffer kept in shared structure if refcnt == 1
Diffstat (limited to 'src')
| -rw-r--r-- | src/string.c | 32 |
1 files changed, 19 insertions, 13 deletions
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); } } |
