mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
gc.c: extract mrb_obj_alloc_core() for internal allocation
split mrb_obj_alloc() into type-validation wrapper and allocation core (mrb_obj_alloc_core). internal callers (mrb_proc_new, mrb_env_new) use the core directly, skipping 15+ lines of type validation per allocation. most impactful for workloads with heavy Proc/Env allocation (lambda calculus, block-intensive code). Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -279,4 +279,7 @@ mrb_value mrb_bint_abs(mrb_state *mrb, mrb_value x);
|
||||
void mrb_task_mark_all(mrb_state *mrb);
|
||||
#endif
|
||||
|
||||
/* Internal object allocation without type validation (gc.c) */
|
||||
struct RBasic* mrb_obj_alloc_core(mrb_state*, enum mrb_vtype, struct RClass*);
|
||||
|
||||
#endif /* MRUBY_INTERNAL_H */
|
||||
|
||||
@@ -563,38 +563,14 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
|
||||
ARY_SET_LEN(a, w);
|
||||
}
|
||||
|
||||
MRB_API struct RBasic*
|
||||
mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
|
||||
/* Core allocation without type validation.
|
||||
Used internally by mrb_proc_new, mrb_env_new, etc. */
|
||||
struct RBasic*
|
||||
mrb_obj_alloc_core(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
|
||||
{
|
||||
static const RVALUE RVALUE_zero = { { { NULL, MRB_TT_FALSE } } };
|
||||
mrb_gc *gc = &mrb->gc;
|
||||
|
||||
if (cls) {
|
||||
enum mrb_vtype tt;
|
||||
|
||||
switch (cls->tt) {
|
||||
case MRB_TT_CLASS:
|
||||
case MRB_TT_SCLASS:
|
||||
case MRB_TT_MODULE:
|
||||
case MRB_TT_ENV:
|
||||
break;
|
||||
default:
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "allocation failure");
|
||||
}
|
||||
tt = MRB_INSTANCE_TT(cls);
|
||||
if (ttype != MRB_TT_SCLASS &&
|
||||
ttype != MRB_TT_ICLASS &&
|
||||
ttype != MRB_TT_ENV &&
|
||||
ttype != MRB_TT_BIGINT &&
|
||||
ttype != tt &&
|
||||
!(cls == mrb->object_class && (ttype == MRB_TT_CPTR || ttype == MRB_TT_CDATA || ttype == MRB_TT_ISTRUCT))) {
|
||||
mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls);
|
||||
}
|
||||
}
|
||||
if (ttype <= MRB_TT_FREE) {
|
||||
mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C (type %d)", cls, (int)ttype);
|
||||
}
|
||||
|
||||
#ifdef MRB_GC_STRESS
|
||||
mrb_full_gc(mrb);
|
||||
#endif
|
||||
@@ -625,6 +601,37 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
|
||||
return &p->as.basic;
|
||||
}
|
||||
|
||||
MRB_API struct RBasic*
|
||||
mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
|
||||
{
|
||||
if (cls) {
|
||||
enum mrb_vtype tt;
|
||||
|
||||
switch (cls->tt) {
|
||||
case MRB_TT_CLASS:
|
||||
case MRB_TT_SCLASS:
|
||||
case MRB_TT_MODULE:
|
||||
case MRB_TT_ENV:
|
||||
break;
|
||||
default:
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "allocation failure");
|
||||
}
|
||||
tt = MRB_INSTANCE_TT(cls);
|
||||
if (ttype != MRB_TT_SCLASS &&
|
||||
ttype != MRB_TT_ICLASS &&
|
||||
ttype != MRB_TT_ENV &&
|
||||
ttype != MRB_TT_BIGINT &&
|
||||
ttype != tt &&
|
||||
!(cls == mrb->object_class && (ttype == MRB_TT_CPTR || ttype == MRB_TT_CDATA || ttype == MRB_TT_ISTRUCT))) {
|
||||
mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls);
|
||||
}
|
||||
}
|
||||
if (ttype <= MRB_TT_FREE) {
|
||||
mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C (type %d)", cls, (int)ttype);
|
||||
}
|
||||
return mrb_obj_alloc_core(mrb, ttype, cls);
|
||||
}
|
||||
|
||||
static inline void
|
||||
add_gray_list(mrb_gc *gc, struct RBasic *obj)
|
||||
{
|
||||
|
||||
+2
-2
@@ -47,7 +47,7 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep)
|
||||
struct RProc *p;
|
||||
mrb_callinfo *ci = mrb->c->ci;
|
||||
|
||||
p = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class);
|
||||
p = (struct RProc*)mrb_obj_alloc_core(mrb, MRB_TT_PROC, mrb->proc_class);
|
||||
if (ci) {
|
||||
struct RClass *tc = NULL;
|
||||
|
||||
@@ -76,7 +76,7 @@ mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks
|
||||
int n = ci->n;
|
||||
int nk = ci->nk;
|
||||
|
||||
e = MRB_OBJ_ALLOC(mrb, MRB_TT_ENV, NULL);
|
||||
e = (struct REnv*)mrb_obj_alloc_core(mrb, MRB_TT_ENV, NULL);
|
||||
e->c = tc;
|
||||
MRB_ENV_SET_LEN(e, nstacks);
|
||||
bidx += (n == 15) ? 1 : n;
|
||||
|
||||
Reference in New Issue
Block a user