зеркало из https://github.com/github/ruby.git
Embed File::Stat objects
They are very short lived and fit in a 160B slot.
This commit is contained in:
Родитель
0f24ecf17a
Коммит
4f031a745d
75
file.c
75
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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче