mrbconf.h option MRB_USE_ETEXT_EDATA to reduce memory.

on platforms with _etext and _edata, mruby can distinguish string literals so that it avoids memory allocation to copy them.
for example, on my Linux box (x86 32bit), memory consumed by mrbtest decreased from 8,168,203 to 8,078,848 (reduced 88KB).
parent bbf24b84
......@@ -38,6 +38,9 @@
/* initial size for IV khash; ignored when MRB_USE_IV_SEGLIST is set */
//#define MRB_IVHASH_INIT_SIZE 8
/* if _etext and _edata available, mruby can reduce memory used by symbols */
//#define MRB_USE_ETEXT_EDATA
/* turn off generational GC by default */
//#define MRB_GC_TURN_OFF_GENERATIONAL
......
......@@ -211,4 +211,17 @@ mrb_undef_value(void)
return v;
}
#ifdef MRB_USE_ETEXT_EDATA
extern char _etext[];
extern char _edata[];
static inline mrb_bool
mrb_ro_data_p(const char *p)
{
return _etext < p && p < _edata;
}
#else
# define mrb_ro_data_p(p) FALSE
#endif
#endif /* MRUBY_VALUE_H */
......@@ -140,11 +140,31 @@ mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len)
#define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class))
static struct RString*
str_new_static(mrb_state *mrb, const char *p, size_t len)
{
struct RString *s;
if (len >= MRB_INT_MAX) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
}
s = mrb_obj_alloc_string(mrb);
s->as.heap.len = len;
s->as.heap.aux.capa = 0; /* nofree */
s->as.heap.ptr = (char *)p;
s->flags = MRB_STR_NOFREE;
return s;
}
static struct RString*
str_new(mrb_state *mrb, const char *p, size_t len)
{
struct RString *s;
if (mrb_ro_data_p(p)) {
return str_new_static(mrb, p, len);
}
s = mrb_obj_alloc_string(mrb);
if (len < RSTRING_EMBED_LEN_MAX) {
RSTR_SET_EMBED_FLAG(s);
......@@ -282,16 +302,7 @@ mrb_str_new_cstr(mrb_state *mrb, const char *p)
MRB_API mrb_value
mrb_str_new_static(mrb_state *mrb, const char *p, size_t len)
{
struct RString *s;
if (len >= MRB_INT_MAX) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
}
s = mrb_obj_alloc_string(mrb);
s->as.heap.len = len;
s->as.heap.aux.capa = 0; /* nofree */
s->as.heap.ptr = (char *)p;
s->flags = MRB_STR_NOFREE;
struct RString *s = str_new_static(mrb, p, len);
return mrb_obj_value(s);
}
......
......@@ -73,7 +73,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
}
sname = &mrb->symtbl[sym];
sname->len = (uint16_t)len;
if (lit) {
if (lit || mrb_ro_data_p(name)) {
sname->name = name;
sname->lit = TRUE;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment