Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MRB_ALLOCV() for temporary memory allocation #4853

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/mrbconf.h
Expand Up @@ -120,6 +120,9 @@
/* fixed size state atexit stack */
//#define MRB_FIXED_STATE_ATEXIT_STACK

/* maximum size to allocate on the stack in MRB_ALLOCV */
//#define MRB_ALLOCV_ON_STACK_MAX 256

/* -DMRB_DISABLE_XXXX to drop following features */
//#define MRB_DISABLE_STDIO /* use of stdio */

Expand Down
39 changes: 39 additions & 0 deletions include/mruby.h
Expand Up @@ -1355,6 +1355,45 @@ MRB_API void mrb_show_copyright(mrb_state *mrb);

MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...);

/*
* MRB_ALLOCV(mrb, type, var, n)
*
* Define `type *var` variable and assign temporarily allocated memory for
* _n_ objects of type _type_. If the allocation size is less than or equal
* to `MRB_ALLOCV_ON_STACK_MAX`, allocate on the stack, otherwise use
* `mrb_alloca()`.
*/
#ifndef MRB_ALLOCV_ON_STACK_MAX
# define MRB_ALLOCV_ON_STACK_MAX 256
#endif
#ifdef _WIN32
# include <malloc.h>
# if MRB_ALLOCV_ON_STACK_MAX > _ALLOCA_S_THRESHOLD
# define MRB_ALLOCV_ON_STACK_MAX _ALLOCA_S_THRESHOLD
# endif
#endif
#if defined __clang__ && __clang_major__ >= 4 || \
defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 7
# define MRB_ALLOCV(mrb, type, var, n) \
_MRB_ALLOCV(mrb, type, var, n, \
__builtin_alloca_with_align(sizeof(type)*(n), __alignof__(type)*CHAR_BIT))
#elif defined _WIN32
# define MRB_ALLOCV(mrb, type, var, n) \
_MRB_ALLOCV(mrb, type, var, n, _alloca(sizeof(type)*(n)))
#elif defined __STDC_NO_VLA__
# define MRB_ALLOCV(mrb, type, var, n) \
type _MRB_ALLOCV_ON_STACK_BUFFER(var)[MRB_ALLOCV_ON_STACK_MAX/sizeof(type)]; \
_MRB_ALLOCV(mrb, type, var, n, _MRB_ALLOCV_ON_STACK_BUFFER(var))
#else
# define MRB_ALLOCV(mrb, type, var, n) \
type _MRB_ALLOCV_ON_STACK_BUFFER(var)[n]; \
_MRB_ALLOCV(mrb, type, var, n, _MRB_ALLOCV_ON_STACK_BUFFER(var))
#endif
#define _MRB_ALLOCV(mrb, type, var, n, on_stack_expr) \
type *var = (type*)(MRB_ALLOCV_ON_STACK_MAX < sizeof(type)*(n) ? \
mrb_alloca(mrb, sizeof(type)*(n)) : on_stack_expr)
#define _MRB_ALLOCV_ON_STACK_BUFFER(var) mrb_allocv_on_stack_buffer_##var##__

#if 0
/* memcpy and memset does not work with gdb reverse-next on my box */
/* use naive memcpy and memset instead */
Expand Down
18 changes: 2 additions & 16 deletions mrbgems/mruby-struct/src/struct.c
Expand Up @@ -123,29 +123,15 @@ mrb_struct_ref(mrb_state *mrb, mrb_value obj)
static mrb_sym
mrb_id_attrset(mrb_state *mrb, mrb_sym id)
{
#define ONSTACK_ALLOC_MAX 32
#define ONSTACK_STRLEN_MAX (ONSTACK_ALLOC_MAX - 1) /* '=' character */

const char *name;
char *buf;
mrb_int len;
mrb_sym mid;
char onstack[ONSTACK_ALLOC_MAX];
const char *name = mrb_sym_name_len(mrb, id, &len);
MRB_ALLOCV(mrb, char, buf, len+1);

name = mrb_sym_name_len(mrb, id, &len);
if (len > ONSTACK_STRLEN_MAX) {
buf = (char *)mrb_malloc(mrb, (size_t)len+1);
}
else {
buf = onstack;
}
memcpy(buf, name, (size_t)len);
buf[len] = '=';

mid = mrb_intern(mrb, buf, len+1);
if (buf != onstack) {
mrb_free(mrb, buf);
}
return mid;
}

Expand Down
5 changes: 1 addition & 4 deletions src/class.c
Expand Up @@ -1407,18 +1407,15 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
return m;
}

#define ONSTACK_ALLOC_MAX 32

static mrb_sym
prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char *suffix)
{
char onstack[ONSTACK_ALLOC_MAX];
mrb_int sym_len;
const char *sym_str = mrb_sym_name_len(mrb, sym, &sym_len);
size_t prefix_len = prefix ? strlen(prefix) : 0;
size_t suffix_len = suffix ? strlen(suffix) : 0;
size_t name_len = sym_len + prefix_len + suffix_len;
char *buf = name_len > sizeof(onstack) ? (char *)mrb_alloca(mrb, name_len) : onstack;
MRB_ALLOCV(mrb, char, buf, name_len);
char *p = buf;

if (prefix_len > 0) {
Expand Down