From 3e4abf89497df95a408c57a23fa5eb1c58e35faf Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Mon, 8 Feb 2016 02:31:45 +0900 Subject: [PATCH] optimize string construction from literal --- contrib/20.r7rs/src/system.c | 6 ++--- contrib/30.readline/src/readline.c | 14 +++++----- contrib/30.regexp/src/regexp.c | 4 +-- extlib/benz/debug.c | 10 +++---- extlib/benz/error.c | 2 +- extlib/benz/include/picrin/string.h | 5 ++-- extlib/benz/string.c | 41 ++++++++++++++++++----------- extlib/benz/symbol.c | 2 +- 8 files changed, 48 insertions(+), 36 deletions(-) diff --git a/contrib/20.r7rs/src/system.c b/contrib/20.r7rs/src/system.c index 12e512dc..63f6f0a4 100644 --- a/contrib/20.r7rs/src/system.c +++ b/contrib/20.r7rs/src/system.c @@ -17,7 +17,7 @@ pic_system_cmdline(pic_state *pic) for (i = 0; i < pic->argc; ++i) { size_t ai = pic_gc_arena_preserve(pic); - v = pic_cons(pic, pic_obj_value(pic_make_str_cstr(pic, pic->argv[i])), v); + v = pic_cons(pic, pic_obj_value(pic_make_cstr(pic, pic->argv[i])), v); pic_gc_arena_restore(pic, ai); } @@ -84,7 +84,7 @@ pic_system_getenv(pic_state *pic) if (val == NULL) return pic_nil_value(); else - return pic_obj_value(pic_make_str_cstr(pic, val)); + return pic_obj_value(pic_make_cstr(pic, val)); } static pic_value @@ -108,7 +108,7 @@ pic_system_getenvs(pic_state *pic) ; key = pic_make_str(pic, *envp, i); - val = pic_make_str_cstr(pic, getenv(pic_str_cstr(pic, key))); + val = pic_make_cstr(pic, getenv(pic_str_cstr(pic, key))); /* push */ data = pic_acons(pic, pic_obj_value(key), pic_obj_value(val), data); diff --git a/contrib/30.readline/src/readline.c b/contrib/30.readline/src/readline.c index 84d3f37f..d6e71d6a 100644 --- a/contrib/30.readline/src/readline.c +++ b/contrib/30.readline/src/readline.c @@ -19,7 +19,7 @@ pic_rl_readline(pic_state *pic) result = readline(prompt); if(result) - return pic_obj_value(pic_make_str_cstr(pic, result)); + return pic_obj_value(pic_make_cstr(pic, result)); else return pic_eof_object(); } @@ -87,7 +87,7 @@ pic_rl_current_history(pic_state *pic) { pic_get_args(pic, ""); - return pic_obj_value(pic_make_str_cstr(pic, current_history()->line)); + return pic_obj_value(pic_make_cstr(pic, current_history()->line)); } static pic_value @@ -100,7 +100,7 @@ pic_rl_history_get(pic_state *pic) e = history_get(i); - return e ? pic_obj_value(pic_make_str_cstr(pic, e->line)) + return e ? pic_obj_value(pic_make_cstr(pic, e->line)) : pic_false_value(); } @@ -114,7 +114,7 @@ pic_rl_remove_history(pic_state *pic) e = remove_history(i); - return e ? pic_obj_value(pic_make_str_cstr(pic, e->line)) + return e ? pic_obj_value(pic_make_cstr(pic, e->line)) : pic_false_value(); } @@ -148,7 +148,7 @@ pic_rl_previous_history(pic_state *pic) e = previous_history(); - return e ? pic_obj_value(pic_make_str_cstr(pic, e->line)) + return e ? pic_obj_value(pic_make_cstr(pic, e->line)) : pic_false_value(); } @@ -161,7 +161,7 @@ pic_rl_next_history(pic_state *pic) e = next_history(); - return e ? pic_obj_value(pic_make_str_cstr(pic, e->line)) + return e ? pic_obj_value(pic_make_cstr(pic, e->line)) : pic_false_value(); } @@ -240,7 +240,7 @@ pic_rl_history_expand(pic_state *pic) if(status == -1 || status == 2) pic_errorf(pic, "%s\n", result); - return pic_obj_value(pic_make_str_cstr(pic, result)); + return pic_obj_value(pic_make_cstr(pic, result)); } void diff --git a/contrib/30.regexp/src/regexp.c b/contrib/30.regexp/src/regexp.c index ce54d65e..2af663dd 100644 --- a/contrib/30.regexp/src/regexp.c +++ b/contrib/30.regexp/src/regexp.c @@ -146,7 +146,7 @@ pic_regexp_regexp_split(pic_state *pic) input += match.rm_eo; } - pic_push(pic, pic_obj_value(pic_make_str_cstr(pic, input)), output); + pic_push(pic, pic_obj_value(pic_make_cstr(pic, input)), output); return pic_reverse(pic, output); } @@ -157,7 +157,7 @@ pic_regexp_regexp_replace(pic_state *pic) pic_value reg; const char *input; regmatch_t match; - pic_str *txt, *output = pic_make_str(pic, NULL, 0); + pic_str *txt, *output = pic_make_lit(pic, ""); pic_get_args(pic, "ozs", ®, &input, &txt); diff --git a/extlib/benz/debug.c b/extlib/benz/debug.c index 7d682f0f..9799692c 100644 --- a/extlib/benz/debug.c +++ b/extlib/benz/debug.c @@ -11,18 +11,18 @@ pic_get_backtrace(pic_state *pic) pic_callinfo *ci; pic_str *trace; - trace = pic_make_str(pic, NULL, 0); + trace = pic_make_lit(pic, ""); for (ci = pic->ci; ci != pic->cibase; --ci) { struct pic_proc *proc = pic_proc_ptr(ci->fp[0]); - trace = pic_str_cat(pic, trace, pic_make_str_cstr(pic, " at ")); - trace = pic_str_cat(pic, trace, pic_make_str_cstr(pic, "(anonymous lambda)")); + trace = pic_str_cat(pic, trace, pic_make_lit(pic, " at ")); + trace = pic_str_cat(pic, trace, pic_make_lit(pic, "(anonymous lambda)")); if (pic_proc_func_p(proc)) { - trace = pic_str_cat(pic, trace, pic_make_str_cstr(pic, " (native function)\n")); + trace = pic_str_cat(pic, trace, pic_make_lit(pic, " (native function)\n")); } else if (pic_proc_irep_p(proc)) { - trace = pic_str_cat(pic, trace, pic_make_str_cstr(pic, " (unknown location)\n")); /* TODO */ + trace = pic_str_cat(pic, trace, pic_make_lit(pic, " (unknown location)\n")); /* TODO */ } } diff --git a/extlib/benz/error.c b/extlib/benz/error.c index 42d3251c..1010b7fe 100644 --- a/extlib/benz/error.c +++ b/extlib/benz/error.c @@ -100,7 +100,7 @@ pic_make_error(pic_state *pic, pic_sym *type, const char *msg, pic_value irrs) e = (struct pic_error *)pic_obj_alloc(pic, sizeof(struct pic_error), PIC_TT_ERROR); e->type = type; - e->msg = pic_make_str_cstr(pic, msg); + e->msg = pic_make_cstr(pic, msg); e->irrs = irrs; e->stack = stack; diff --git a/extlib/benz/include/picrin/string.h b/extlib/benz/include/picrin/string.h index 36389412..2f5e8361 100644 --- a/extlib/benz/include/picrin/string.h +++ b/extlib/benz/include/picrin/string.h @@ -20,8 +20,9 @@ void pic_rope_decref(pic_state *, struct pic_rope *); #define pic_str_p(v) (pic_type(v) == PIC_TT_STRING) #define pic_str_ptr(o) ((struct pic_string *)pic_ptr(o)) -pic_str *pic_make_str(pic_state *, const char * /* nullable */, int); -pic_str *pic_make_str_cstr(pic_state *, const char *); +pic_str *pic_make_str(pic_state *, const char *, int); +#define pic_make_cstr(pic, cstr) pic_make_str(pic, (cstr), strlen(cstr)) +#define pic_make_lit(pic, lit) pic_make_str(pic, "" lit, -((int)sizeof lit - 1)) char pic_str_ref(pic_state *, pic_str *, int); int pic_str_len(pic_str *); diff --git a/extlib/benz/string.c b/extlib/benz/string.c index a5ab3191..0df0d631 100644 --- a/extlib/benz/string.c +++ b/extlib/benz/string.c @@ -26,9 +26,6 @@ struct pic_rope { #define CHUNK_DECREF(c) do { \ struct pic_chunk *c_ = (c); \ if (! --c_->refcnt) { \ - if (c_->str != c_->buf) { \ - pic_free(pic, c_->str); \ - } \ pic_free(pic, c_); \ } \ } while (0) @@ -67,6 +64,19 @@ pic_make_chunk(pic_state *pic, const char *str, size_t len) return c; } +static struct pic_chunk * +pic_make_chunk_lit(pic_state *pic, const char *str, size_t len) +{ + struct pic_chunk *c; + + c = pic_malloc(pic, sizeof(struct pic_chunk)); + c->refcnt = 1; + c->str = (char *)str; + c->len = len; + + return c; +} + static struct pic_rope * pic_make_rope(pic_state *pic, struct pic_chunk *c) { @@ -214,7 +224,7 @@ rope_cstr(pic_state *pic, struct pic_rope *x) return x->chunk->str; /* reuse cached chunk */ } - c = pic_malloc(pic, sizeof(struct pic_chunk) + x->weight); + c = pic_malloc(pic, offsetof(struct pic_chunk, buf) + x->weight + 1); c->refcnt = 1; c->len = x->weight; c->str = c->buf; @@ -229,16 +239,17 @@ rope_cstr(pic_state *pic, struct pic_rope *x) pic_str * pic_make_str(pic_state *pic, const char *str, int len) { - if (str == NULL && len > 0) { - pic_errorf(pic, "zero length specified against NULL ptr"); - } - return pic_make_string(pic, pic_make_rope(pic, pic_make_chunk(pic, str, len))); -} + struct pic_chunk *c; -pic_str * -pic_make_str_cstr(pic_state *pic, const char *cstr) -{ - return pic_make_str(pic, cstr, strlen(cstr)); + if (len > 0) { + c = pic_make_chunk(pic, str, len); + } else { + if (len == 0) { + str = ""; + } + c = pic_make_chunk_lit(pic, str, -len); + } + return pic_make_string(pic, pic_make_rope(pic, c)); } int @@ -512,7 +523,7 @@ pic_str_string_append(pic_state *pic) pic_get_args(pic, "*", &argc, &argv); - str = pic_make_str(pic, NULL, 0); + str = pic_make_lit(pic, ""); for (i = 0; i < argc; ++i) { if (! pic_str_p(argv[i])) { pic_errorf(pic, "type error"); @@ -616,7 +627,7 @@ pic_str_list_to_string(pic_state *pic) pic_get_args(pic, "o", &list); if (pic_length(pic, list) == 0) { - return pic_obj_value(pic_make_str(pic, NULL, 0)); + return pic_obj_value(pic_make_lit(pic, "")); } buf = pic_malloc(pic, pic_length(pic, list)); diff --git a/extlib/benz/symbol.c b/extlib/benz/symbol.c index f42c31cf..3edc4f4a 100644 --- a/extlib/benz/symbol.c +++ b/extlib/benz/symbol.c @@ -104,7 +104,7 @@ pic_symbol_symbol_to_string(pic_state *pic) pic_get_args(pic, "m", &sym); - return pic_obj_value(pic_make_str_cstr(pic, sym->cstr)); + return pic_obj_value(pic_make_cstr(pic, sym->cstr)); } static pic_value