summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-09-30 23:48:57 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-09-30 23:48:57 +0900
commitb72e94fa6bae6c9a35c90b4ecedc1f90cdb9a490 (patch)
tree08c13caecf740d0d4b972d75f65d6abb17d063bb /src
parentbbf24b84630eb3b3e18b04bcabd088ad22353957 (diff)
downloadmruby-b72e94fa6bae6c9a35c90b4ecedc1f90cdb9a490.tar.gz
mruby-b72e94fa6bae6c9a35c90b4ecedc1f90cdb9a490.zip
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).
Diffstat (limited to 'src')
-rw-r--r--src/string.c31
-rw-r--r--src/symbol.c2
2 files changed, 22 insertions, 11 deletions
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;
}