optimize string construction from literal

This commit is contained in:
Yuichi Nishiwaki 2016-02-08 02:31:45 +09:00
parent 0d8d7d5b91
commit 3e4abf8949
8 changed files with 48 additions and 36 deletions

View File

@ -17,7 +17,7 @@ pic_system_cmdline(pic_state *pic)
for (i = 0; i < pic->argc; ++i) { for (i = 0; i < pic->argc; ++i) {
size_t ai = pic_gc_arena_preserve(pic); 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); pic_gc_arena_restore(pic, ai);
} }
@ -84,7 +84,7 @@ pic_system_getenv(pic_state *pic)
if (val == NULL) if (val == NULL)
return pic_nil_value(); return pic_nil_value();
else else
return pic_obj_value(pic_make_str_cstr(pic, val)); return pic_obj_value(pic_make_cstr(pic, val));
} }
static pic_value static pic_value
@ -108,7 +108,7 @@ pic_system_getenvs(pic_state *pic)
; ;
key = pic_make_str(pic, *envp, i); 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 */ /* push */
data = pic_acons(pic, pic_obj_value(key), pic_obj_value(val), data); data = pic_acons(pic, pic_obj_value(key), pic_obj_value(val), data);

View File

@ -19,7 +19,7 @@ pic_rl_readline(pic_state *pic)
result = readline(prompt); result = readline(prompt);
if(result) if(result)
return pic_obj_value(pic_make_str_cstr(pic, result)); return pic_obj_value(pic_make_cstr(pic, result));
else else
return pic_eof_object(); return pic_eof_object();
} }
@ -87,7 +87,7 @@ pic_rl_current_history(pic_state *pic)
{ {
pic_get_args(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 static pic_value
@ -100,7 +100,7 @@ pic_rl_history_get(pic_state *pic)
e = history_get(i); 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(); : pic_false_value();
} }
@ -114,7 +114,7 @@ pic_rl_remove_history(pic_state *pic)
e = remove_history(i); 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(); : pic_false_value();
} }
@ -148,7 +148,7 @@ pic_rl_previous_history(pic_state *pic)
e = previous_history(); 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(); : pic_false_value();
} }
@ -161,7 +161,7 @@ pic_rl_next_history(pic_state *pic)
e = next_history(); 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(); : pic_false_value();
} }
@ -240,7 +240,7 @@ pic_rl_history_expand(pic_state *pic)
if(status == -1 || status == 2) if(status == -1 || status == 2)
pic_errorf(pic, "%s\n", result); 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 void

View File

@ -146,7 +146,7 @@ pic_regexp_regexp_split(pic_state *pic)
input += match.rm_eo; 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); return pic_reverse(pic, output);
} }
@ -157,7 +157,7 @@ pic_regexp_regexp_replace(pic_state *pic)
pic_value reg; pic_value reg;
const char *input; const char *input;
regmatch_t match; 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", &reg, &input, &txt); pic_get_args(pic, "ozs", &reg, &input, &txt);

View File

@ -11,18 +11,18 @@ pic_get_backtrace(pic_state *pic)
pic_callinfo *ci; pic_callinfo *ci;
pic_str *trace; pic_str *trace;
trace = pic_make_str(pic, NULL, 0); trace = pic_make_lit(pic, "");
for (ci = pic->ci; ci != pic->cibase; --ci) { for (ci = pic->ci; ci != pic->cibase; --ci) {
struct pic_proc *proc = pic_proc_ptr(ci->fp[0]); 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_lit(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, "(anonymous lambda)"));
if (pic_proc_func_p(proc)) { 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)) { } 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 */
} }
} }

View File

@ -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 = (struct pic_error *)pic_obj_alloc(pic, sizeof(struct pic_error), PIC_TT_ERROR);
e->type = type; e->type = type;
e->msg = pic_make_str_cstr(pic, msg); e->msg = pic_make_cstr(pic, msg);
e->irrs = irrs; e->irrs = irrs;
e->stack = stack; e->stack = stack;

View File

@ -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_p(v) (pic_type(v) == PIC_TT_STRING)
#define pic_str_ptr(o) ((struct pic_string *)pic_ptr(o)) #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(pic_state *, const char *, int);
pic_str *pic_make_str_cstr(pic_state *, const char *); #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); char pic_str_ref(pic_state *, pic_str *, int);
int pic_str_len(pic_str *); int pic_str_len(pic_str *);

View File

@ -26,9 +26,6 @@ struct pic_rope {
#define CHUNK_DECREF(c) do { \ #define CHUNK_DECREF(c) do { \
struct pic_chunk *c_ = (c); \ struct pic_chunk *c_ = (c); \
if (! --c_->refcnt) { \ if (! --c_->refcnt) { \
if (c_->str != c_->buf) { \
pic_free(pic, c_->str); \
} \
pic_free(pic, c_); \ pic_free(pic, c_); \
} \ } \
} while (0) } while (0)
@ -67,6 +64,19 @@ pic_make_chunk(pic_state *pic, const char *str, size_t len)
return c; 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 * static struct pic_rope *
pic_make_rope(pic_state *pic, struct pic_chunk *c) 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 */ 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->refcnt = 1;
c->len = x->weight; c->len = x->weight;
c->str = c->buf; c->str = c->buf;
@ -229,16 +239,17 @@ rope_cstr(pic_state *pic, struct pic_rope *x)
pic_str * pic_str *
pic_make_str(pic_state *pic, const char *str, int len) pic_make_str(pic_state *pic, const char *str, int len)
{ {
if (str == NULL && len > 0) { struct pic_chunk *c;
pic_errorf(pic, "zero length specified against NULL ptr");
}
return pic_make_string(pic, pic_make_rope(pic, pic_make_chunk(pic, str, len)));
}
pic_str * if (len > 0) {
pic_make_str_cstr(pic_state *pic, const char *cstr) c = pic_make_chunk(pic, str, len);
{ } else {
return pic_make_str(pic, cstr, strlen(cstr)); if (len == 0) {
str = "";
}
c = pic_make_chunk_lit(pic, str, -len);
}
return pic_make_string(pic, pic_make_rope(pic, c));
} }
int int
@ -512,7 +523,7 @@ pic_str_string_append(pic_state *pic)
pic_get_args(pic, "*", &argc, &argv); pic_get_args(pic, "*", &argc, &argv);
str = pic_make_str(pic, NULL, 0); str = pic_make_lit(pic, "");
for (i = 0; i < argc; ++i) { for (i = 0; i < argc; ++i) {
if (! pic_str_p(argv[i])) { if (! pic_str_p(argv[i])) {
pic_errorf(pic, "type error"); pic_errorf(pic, "type error");
@ -616,7 +627,7 @@ pic_str_list_to_string(pic_state *pic)
pic_get_args(pic, "o", &list); pic_get_args(pic, "o", &list);
if (pic_length(pic, list) == 0) { 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)); buf = pic_malloc(pic, pic_length(pic, list));

View File

@ -104,7 +104,7 @@ pic_symbol_symbol_to_string(pic_state *pic)
pic_get_args(pic, "m", &sym); 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 static pic_value