Embed File::Stat objects

They are very short lived and fit in a 160B slot.
This commit is contained in:
Jean Boussier 2023-11-22 13:36:10 +01:00 committed by Jean Boussier
parent 0f24ecf17a
commit 4f031a745d

75
file.c
View File

@ -483,28 +483,29 @@ apply2files(int (*func)(const char *, void *), int argc, VALUE *argv, void *arg)
return LONG2FIX(argc); return LONG2FIX(argc);
} }
static size_t
stat_memsize(const void *p)
{
return sizeof(struct stat);
}
static const rb_data_type_t stat_data_type = { static const rb_data_type_t stat_data_type = {
"stat", "stat",
{NULL, RUBY_TYPED_DEFAULT_FREE, stat_memsize,}, {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED NULL,
RUBY_TYPED_DEFAULT_FREE,
NULL, // No external memory to report
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
};
struct rb_stat {
struct stat stat;
bool initialized;
}; };
static VALUE static VALUE
stat_new_0(VALUE klass, const struct stat *st) stat_new_0(VALUE klass, const struct stat *st)
{ {
struct stat *nst = 0; struct rb_stat *rb_st;
VALUE obj = TypedData_Wrap_Struct(klass, &stat_data_type, 0); VALUE obj = TypedData_Make_Struct(klass, struct rb_stat, &stat_data_type, rb_st);
if (st) { if (st) {
nst = ALLOC(struct stat); rb_st->stat = *st;
*nst = *st; rb_st->initialized = true;
RTYPEDDATA_DATA(obj) = nst;
} }
return obj; return obj;
} }
@ -518,10 +519,10 @@ rb_stat_new(const struct stat *st)
static struct stat* static struct stat*
get_stat(VALUE self) get_stat(VALUE self)
{ {
struct stat* st; struct rb_stat* rb_st;
TypedData_Get_Struct(self, struct stat, &stat_data_type, st); TypedData_Get_Struct(self, struct rb_stat, &stat_data_type, rb_st);
if (!st) rb_raise(rb_eTypeError, "uninitialized File::Stat"); if (!rb_st->initialized) rb_raise(rb_eTypeError, "uninitialized File::Stat");
return st; return &rb_st->stat;
} }
static struct timespec stat_mtimespec(const struct stat *st); static struct timespec stat_mtimespec(const struct stat *st);
@ -1092,9 +1093,9 @@ rb_stat_inspect(VALUE self)
#endif #endif
}; };
struct stat* st; struct rb_stat* rb_st;
TypedData_Get_Struct(self, struct stat, &stat_data_type, st); TypedData_Get_Struct(self, struct rb_stat, &stat_data_type, rb_st);
if (!st) { if (!rb_st->initialized) {
return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self)); return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self));
} }
@ -5557,7 +5558,7 @@ rb_stat_s_alloc(VALUE klass)
static VALUE static VALUE
rb_stat_init(VALUE obj, VALUE fname) rb_stat_init(VALUE obj, VALUE fname)
{ {
struct stat st, *nst; struct stat st;
FilePathValue(fname); FilePathValue(fname);
fname = rb_str_encode_ospath(fname); fname = rb_str_encode_ospath(fname);
@ -5565,13 +5566,11 @@ rb_stat_init(VALUE obj, VALUE fname)
rb_sys_fail_path(fname); rb_sys_fail_path(fname);
} }
if (DATA_PTR(obj)) { struct rb_stat *rb_st;
xfree(DATA_PTR(obj)); TypedData_Get_Struct(obj, struct rb_stat, &stat_data_type, rb_st);
DATA_PTR(obj) = NULL;
} rb_st->stat = st;
nst = ALLOC(struct stat); rb_st->initialized = true;
*nst = st;
DATA_PTR(obj) = nst;
return Qnil; return Qnil;
} }
@ -5580,19 +5579,15 @@ rb_stat_init(VALUE obj, VALUE fname)
static VALUE static VALUE
rb_stat_init_copy(VALUE copy, VALUE orig) rb_stat_init_copy(VALUE copy, VALUE orig)
{ {
struct stat *nst;
if (!OBJ_INIT_COPY(copy, orig)) return copy; if (!OBJ_INIT_COPY(copy, orig)) return copy;
if (DATA_PTR(copy)) {
xfree(DATA_PTR(copy));
DATA_PTR(copy) = 0;
}
if (DATA_PTR(orig)) {
nst = ALLOC(struct stat);
*nst = *(struct stat*)DATA_PTR(orig);
DATA_PTR(copy) = nst;
}
struct rb_stat *orig_rb_st;
TypedData_Get_Struct(orig, struct rb_stat, &stat_data_type, orig_rb_st);
struct rb_stat *copy_rb_st;
TypedData_Get_Struct(copy, struct rb_stat, &stat_data_type, copy_rb_st);
*copy_rb_st = *orig_rb_st;
return copy; return copy;
} }