summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mrbconf.h3
-rw-r--r--include/mruby/value.h13
-rw-r--r--src/string.c31
-rw-r--r--src/symbol.c2
4 files changed, 38 insertions, 11 deletions
diff --git a/include/mrbconf.h b/include/mrbconf.h
index 3564f6ec5..0195ae96f 100644
--- a/include/mrbconf.h
+++ b/include/mrbconf.h
@@ -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
diff --git a/include/mruby/value.h b/include/mruby/value.h
index f85cdd644..09d00302e 100644
--- a/include/mruby/value.h
+++ b/include/mruby/value.h
@@ -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 */
diff --git a/src/string.c b/src/string.c
index c1041f4be..63c0e4573 100644
--- a/src/string.c
+++ b/src/string.c
@@ -141,10 +141,30 @@ 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);
}
diff --git a/src/symbol.c b/src/symbol.c
index 98c258503..0bcb26adf 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -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;
}