From f26d00d9e81b102fababdd9c0d1b886fab30e35a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 27 Jul 2017 12:46:51 +0900 Subject: Embed small size array elements in the heap. It reduces the memory consumption and sometimes improve the performance as well. For example, the consumed memory size of `bench/bm_ao_render.rb` is reduced from 1.2GB to 1GB, and its total execution time become 18.795 sec from 22.229 sec. --- include/mruby/array.h | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/mruby/array.h b/include/mruby/array.h index e553faf92..bd3124d8c 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -21,22 +21,48 @@ typedef struct mrb_shared_array { mrb_value *ptr; } mrb_shared_array; +#define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value))) struct RArray { MRB_OBJECT_HEADER; - mrb_int len; union { - mrb_int capa; - mrb_shared_array *shared; - } aux; - mrb_value *ptr; + struct { + mrb_int len; + union { + mrb_int capa; + mrb_shared_array *shared; + } aux; + mrb_value *ptr; + } heap; + mrb_value embed[MRB_ARY_EMBED_LEN_MAX]; + } as; }; #define mrb_ary_ptr(v) ((struct RArray*)(mrb_ptr(v))) #define mrb_ary_value(p) mrb_obj_value((void*)(p)) #define RARRAY(v) ((struct RArray*)(mrb_ptr(v))) -#define RARRAY_LEN(a) (RARRAY(a)->len) -#define RARRAY_PTR(a) ((const mrb_value*)RARRAY(a)->ptr) +#define MRB_ARY_EMBED 4 +#define MRB_ARY_EMBED_MASK 3 +#define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED) +#define ARY_SET_EMBED_FLAG(a) ((a)->flags |= MRB_ARY_EMBED) +#define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED|MRB_ARY_EMBED_MASK)) +#define ARY_EMBED_LEN(a) ((a)->flags & MRB_ARY_EMBED_MASK) +#define ARY_SET_EMBED_LEN(a,len) (a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((len)&MRB_ARY_EMBED_MASK); +#define ARY_EMBED_PTR(a) (&((a)->as.embed[0])) + +#define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len) +#define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr) +#define RARRAY_LEN(a) ARY_LEN(RARRAY(a)) +#define RARRAY_PTR(a) ARY_PTR(RARRAY(a)) +#define ARY_SET_LEN(a,n) do {\ + if (ARY_EMBED_P(a)) {\ + mrb_assert((n) <= MRB_ARY_EMBED_LEN_MAX); \ + ARY_SET_EMBED_LEN(a,n);\ + }\ + else\ + (a)->as.heap.len = (n);\ +} while (0) +#define ARY_CAPA(a) (ARY_EMBED_P(a)?MRB_ARY_EMBED_LEN_MAX:(a)->as.heap.aux.capa) #define MRB_ARY_SHARED 256 #define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED) #define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED) -- cgit v1.2.3