summaryrefslogtreecommitdiff
path: root/file.c
diff options
context:
space:
mode:
authorJean Boussier <[email protected]>2023-11-22 13:36:10 +0100
committerJean Boussier <[email protected]>2023-11-22 14:52:32 +0100
commit4f031a745d528e0a8a626c340787c7c3ab9ea143 (patch)
tree477d0b127e1c13125063aa2f054eb8846350e13e /file.c
parent0f24ecf17ae43a9c2501d0f3e5b2a6d829fcdd7f (diff)
Embed File::Stat objects
They are very short lived and fit in a 160B slot.
Diffstat (limited to 'file.c')
-rw-r--r--file.c75
1 files changed, 35 insertions, 40 deletions
diff --git a/file.c b/file.c
index 6a314c8069..8a537c50f1 100644
--- a/file.c
+++ b/file.c
@@ -483,28 +483,29 @@ apply2files(int (*func)(const char *, void *), int argc, VALUE *argv, void *arg)
return LONG2FIX(argc);
}
-static size_t
-stat_memsize(const void *p)
-{
- return sizeof(struct stat);
-}
-
static const rb_data_type_t stat_data_type = {
"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
stat_new_0(VALUE klass, const struct stat *st)
{
- struct stat *nst = 0;
- VALUE obj = TypedData_Wrap_Struct(klass, &stat_data_type, 0);
-
+ struct rb_stat *rb_st;
+ VALUE obj = TypedData_Make_Struct(klass, struct rb_stat, &stat_data_type, rb_st);
if (st) {
- nst = ALLOC(struct stat);
- *nst = *st;
- RTYPEDDATA_DATA(obj) = nst;
+ rb_st->stat = *st;
+ rb_st->initialized = true;
}
return obj;
}
@@ -518,10 +519,10 @@ rb_stat_new(const struct stat *st)
static struct stat*
get_stat(VALUE self)
{
- struct stat* st;
- TypedData_Get_Struct(self, struct stat, &stat_data_type, st);
- if (!st) rb_raise(rb_eTypeError, "uninitialized File::Stat");
- return st;
+ struct rb_stat* rb_st;
+ TypedData_Get_Struct(self, struct rb_stat, &stat_data_type, rb_st);
+ if (!rb_st->initialized) rb_raise(rb_eTypeError, "uninitialized File::Stat");
+ return &rb_st->stat;
}
static struct timespec stat_mtimespec(const struct stat *st);
@@ -1092,9 +1093,9 @@ rb_stat_inspect(VALUE self)
#endif
};
- struct stat* st;
- TypedData_Get_Struct(self, struct stat, &stat_data_type, st);
- if (!st) {
+ struct rb_stat* rb_st;
+ TypedData_Get_Struct(self, struct rb_stat, &stat_data_type, rb_st);
+ if (!rb_st->initialized) {
return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self));
}
@@ -5557,7 +5558,7 @@ rb_stat_s_alloc(VALUE klass)
static VALUE
rb_stat_init(VALUE obj, VALUE fname)
{
- struct stat st, *nst;
+ struct stat st;
FilePathValue(fname);
fname = rb_str_encode_ospath(fname);
@@ -5565,13 +5566,11 @@ rb_stat_init(VALUE obj, VALUE fname)
rb_sys_fail_path(fname);
}
- if (DATA_PTR(obj)) {
- xfree(DATA_PTR(obj));
- DATA_PTR(obj) = NULL;
- }
- nst = ALLOC(struct stat);
- *nst = st;
- DATA_PTR(obj) = nst;
+ struct rb_stat *rb_st;
+ TypedData_Get_Struct(obj, struct rb_stat, &stat_data_type, rb_st);
+
+ rb_st->stat = st;
+ rb_st->initialized = true;
return Qnil;
}
@@ -5580,19 +5579,15 @@ rb_stat_init(VALUE obj, VALUE fname)
static VALUE
rb_stat_init_copy(VALUE copy, VALUE orig)
{
- struct stat *nst;
-
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;
}