Skip to content

Commit b72e94f

Browse files
committed
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).
1 parent bbf24b8 commit b72e94f

4 files changed

Lines changed: 38 additions & 11 deletions

File tree

include/mrbconf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
/* initial size for IV khash; ignored when MRB_USE_IV_SEGLIST is set */
3939
//#define MRB_IVHASH_INIT_SIZE 8
4040

41+
/* if _etext and _edata available, mruby can reduce memory used by symbols */
42+
//#define MRB_USE_ETEXT_EDATA
43+
4144
/* turn off generational GC by default */
4245
//#define MRB_GC_TURN_OFF_GENERATIONAL
4346

include/mruby/value.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,17 @@ mrb_undef_value(void)
211211
return v;
212212
}
213213

214+
#ifdef MRB_USE_ETEXT_EDATA
215+
extern char _etext[];
216+
extern char _edata[];
217+
218+
static inline mrb_bool
219+
mrb_ro_data_p(const char *p)
220+
{
221+
return _etext < p && p < _edata;
222+
}
223+
#else
224+
# define mrb_ro_data_p(p) FALSE
225+
#endif
226+
214227
#endif /* MRUBY_VALUE_H */

src/string.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,31 @@ mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len)
140140

141141
#define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class))
142142

143+
static struct RString*
144+
str_new_static(mrb_state *mrb, const char *p, size_t len)
145+
{
146+
struct RString *s;
147+
148+
if (len >= MRB_INT_MAX) {
149+
mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
150+
}
151+
s = mrb_obj_alloc_string(mrb);
152+
s->as.heap.len = len;
153+
s->as.heap.aux.capa = 0; /* nofree */
154+
s->as.heap.ptr = (char *)p;
155+
s->flags = MRB_STR_NOFREE;
156+
157+
return s;
158+
}
159+
143160
static struct RString*
144161
str_new(mrb_state *mrb, const char *p, size_t len)
145162
{
146163
struct RString *s;
147164

165+
if (mrb_ro_data_p(p)) {
166+
return str_new_static(mrb, p, len);
167+
}
148168
s = mrb_obj_alloc_string(mrb);
149169
if (len < RSTRING_EMBED_LEN_MAX) {
150170
RSTR_SET_EMBED_FLAG(s);
@@ -282,16 +302,7 @@ mrb_str_new_cstr(mrb_state *mrb, const char *p)
282302
MRB_API mrb_value
283303
mrb_str_new_static(mrb_state *mrb, const char *p, size_t len)
284304
{
285-
struct RString *s;
286-
287-
if (len >= MRB_INT_MAX) {
288-
mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
289-
}
290-
s = mrb_obj_alloc_string(mrb);
291-
s->as.heap.len = len;
292-
s->as.heap.aux.capa = 0; /* nofree */
293-
s->as.heap.ptr = (char *)p;
294-
s->flags = MRB_STR_NOFREE;
305+
struct RString *s = str_new_static(mrb, p, len);
295306
return mrb_obj_value(s);
296307
}
297308

src/symbol.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
7373
}
7474
sname = &mrb->symtbl[sym];
7575
sname->len = (uint16_t)len;
76-
if (lit) {
76+
if (lit || mrb_ro_data_p(name)) {
7777
sname->name = name;
7878
sname->lit = TRUE;
7979
}

0 commit comments

Comments
 (0)