mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
time: rearrange+pack vtm and time_object structs
struct time_object shrinks from 88 to 46 bytes on my 64-bit system. * configure.in: use -Wno-packed-bitfield-compat for GCC 4.4+ use __attribute__((packed)) if available * timev.h: shrink and pack struct vtm * time.c: pack struct time_object and adjust/introduce helpers [ruby-core:60794] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ba5ed845b3
commit
b2f3063cae
4 changed files with 74 additions and 37 deletions
|
@ -1,3 +1,11 @@
|
|||
Mon Feb 24 12:37:51 2014 Eric Wong <e@80x24.org>
|
||||
|
||||
* configure.in: use -Wno-packed-bitfield-compat for GCC 4.4+
|
||||
use __attribute__((packed)) if available
|
||||
* timev.h: shrink and pack struct vtm
|
||||
* time.c: pack struct time_object and adjust/introduce helpers
|
||||
[ruby-core:60794]
|
||||
|
||||
Sun Feb 23 17:55:50 2014 Kouhei Sutou <kou@cozmixng.org>
|
||||
|
||||
* lib/rexml/xmltokens.rb: Add missing non ASCII valid characters
|
||||
|
|
10
configure.in
10
configure.in
|
@ -746,6 +746,7 @@ if test "$GCC:${warnflags+set}:no" = yes::no; then
|
|||
-Werror=implicit-function-declaration \
|
||||
-Werror=division-by-zero \
|
||||
-Werror=deprecated-declarations \
|
||||
-Wno-packed-bitfield-compat \
|
||||
$extra_warning \
|
||||
; do
|
||||
if test "$particular_werror_flags" != yes; then
|
||||
|
@ -1271,6 +1272,15 @@ RUBY_CHECK_SIZEOF(double)
|
|||
RUBY_CHECK_SIZEOF(time_t, [long "long long"], [], [@%:@include <time.h>])
|
||||
RUBY_CHECK_SIZEOF(clock_t, [], [], [@%:@include <time.h>])
|
||||
|
||||
AC_CACHE_CHECK(packed struct attribute, rb_cv_packed_struct,
|
||||
[AC_TRY_COMPILE([struct { int a; } __attribute__((packed));], [],
|
||||
[rb_cv_packed_struct=yes], [rb_cv_packed_struct=no])])
|
||||
if test "$rb_cv_packed_struct" = yes; then
|
||||
AC_DEFINE_UNQUOTED(PACKED_STRUCT, __attribute__((packed)))
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(PACKED_STRUCT,)
|
||||
fi
|
||||
|
||||
AC_DEFUN([RUBY_CHECK_PRINTF_PREFIX], [
|
||||
AC_CACHE_CHECK([for printf prefix for $1], [rb_cv_pri_prefix_]AS_TR_SH($1),[
|
||||
[rb_cv_pri_prefix_]AS_TR_SH($1)=[NONE]
|
||||
|
|
75
time.c
75
time.c
|
@ -40,6 +40,9 @@ static ID id_eq, id_ne, id_quo, id_div, id_cmp, id_lshift;
|
|||
#define NMOD(x,y) ((y)-(-((x)+1)%(y))-1)
|
||||
#define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
|
||||
#define MOD(n,d) ((n)<0 ? NMOD((n),(d)) : (n)%(d))
|
||||
#define VTM_WDAY_INITVAL (7)
|
||||
#define VTM_ISDST_INITVAL (3)
|
||||
#define TO_GMT_INITVAL (3)
|
||||
|
||||
static int
|
||||
eq(VALUE x, VALUE y)
|
||||
|
@ -757,12 +760,13 @@ VALUE rb_cTime;
|
|||
static VALUE time_utc_offset _((VALUE));
|
||||
|
||||
static int obj2int(VALUE obj);
|
||||
static uint32_t obj2ubits(VALUE obj, size_t bits);
|
||||
static VALUE obj2vint(VALUE obj);
|
||||
static int month_arg(VALUE arg);
|
||||
static uint32_t month_arg(VALUE arg);
|
||||
static VALUE validate_utc_offset(VALUE utc_offset);
|
||||
static VALUE validate_zone_name(VALUE zone_name);
|
||||
static void validate_vtm(struct vtm *vtm);
|
||||
static int obj2subsecx(VALUE obj, VALUE *subsecx);
|
||||
static uint32_t obj2subsecx(VALUE obj, VALUE *subsecx);
|
||||
|
||||
static VALUE time_gmtime(VALUE);
|
||||
static VALUE time_localtime(VALUE);
|
||||
|
@ -1739,15 +1743,15 @@ localtimew(wideval_t timew, struct vtm *result)
|
|||
struct time_object {
|
||||
wideval_t timew; /* time_t value * TIME_SCALE. possibly Rational. */
|
||||
struct vtm vtm;
|
||||
int gmt; /* 0:utc 1:localtime 2:fixoff */
|
||||
int tm_got;
|
||||
};
|
||||
uint8_t gmt:3; /* 0:utc 1:localtime 2:fixoff 3:init */
|
||||
uint8_t tm_got:1;
|
||||
} PACKED_STRUCT;
|
||||
|
||||
#define GetTimeval(obj, tobj) ((tobj) = get_timeval(obj))
|
||||
#define GetNewTimeval(obj, tobj) ((tobj) = get_new_timeval(obj))
|
||||
|
||||
#define IsTimeval(obj) rb_typeddata_is_kind_of((obj), &time_data_type)
|
||||
#define TIME_INIT_P(tobj) ((tobj)->gmt != -1)
|
||||
#define TIME_INIT_P(tobj) ((tobj)->gmt != TO_GMT_INITVAL)
|
||||
|
||||
#define TIME_UTC_P(tobj) ((tobj)->gmt == 1)
|
||||
#define TIME_SET_UTC(tobj) ((tobj)->gmt = 1)
|
||||
|
@ -1811,7 +1815,7 @@ time_s_alloc(VALUE klass)
|
|||
struct time_object *tobj;
|
||||
|
||||
obj = TypedData_Make_Struct(klass, struct time_object, &time_data_type, tobj);
|
||||
tobj->gmt = -1;
|
||||
tobj->gmt = TO_GMT_INITVAL;
|
||||
tobj->tm_got=0;
|
||||
tobj->timew = WINT2FIXWV(0);
|
||||
|
||||
|
@ -2114,7 +2118,7 @@ time_init_1(int argc, VALUE *argv, VALUE time)
|
|||
VALUE v[7];
|
||||
struct time_object *tobj;
|
||||
|
||||
vtm.wday = -1;
|
||||
vtm.wday = VTM_WDAY_INITVAL;
|
||||
vtm.yday = 0;
|
||||
vtm.zone = "";
|
||||
|
||||
|
@ -2125,16 +2129,16 @@ time_init_1(int argc, VALUE *argv, VALUE time)
|
|||
|
||||
vtm.mon = NIL_P(v[1]) ? 1 : month_arg(v[1]);
|
||||
|
||||
vtm.mday = NIL_P(v[2]) ? 1 : obj2int(v[2]);
|
||||
vtm.mday = NIL_P(v[2]) ? 1 : obj2ubits(v[2], 5);
|
||||
|
||||
vtm.hour = NIL_P(v[3]) ? 0 : obj2int(v[3]);
|
||||
vtm.hour = NIL_P(v[3]) ? 0 : obj2ubits(v[3], 5);
|
||||
|
||||
vtm.min = NIL_P(v[4]) ? 0 : obj2int(v[4]);
|
||||
vtm.min = NIL_P(v[4]) ? 0 : obj2ubits(v[4], 6);
|
||||
|
||||
vtm.subsecx = INT2FIX(0);
|
||||
vtm.sec = NIL_P(v[5]) ? 0 : obj2subsecx(v[5], &vtm.subsecx);
|
||||
|
||||
vtm.isdst = -1;
|
||||
vtm.isdst = VTM_ISDST_INITVAL;
|
||||
vtm.utc_offset = Qnil;
|
||||
if (!NIL_P(v[6])) {
|
||||
VALUE arg = v[6];
|
||||
|
@ -2520,6 +2524,22 @@ obj2int(VALUE obj)
|
|||
return NUM2INT(obj);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
obj2ubits(VALUE obj, size_t bits)
|
||||
{
|
||||
static const uint32_t u32max = (uint32_t)-1;
|
||||
const uint32_t usable_mask = ~(u32max << bits);
|
||||
uint32_t rv;
|
||||
int tmp = obj2int(obj);
|
||||
|
||||
if (tmp < 0)
|
||||
rb_raise(rb_eArgError, "argument out of range");
|
||||
rv = tmp;
|
||||
if ((rv & usable_mask) != rv)
|
||||
rb_raise(rb_eArgError, "argument out of range");
|
||||
return rv;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
obj2vint(VALUE obj)
|
||||
{
|
||||
|
@ -2533,7 +2553,7 @@ obj2vint(VALUE obj)
|
|||
return obj;
|
||||
}
|
||||
|
||||
static int
|
||||
static uint32_t
|
||||
obj2subsecx(VALUE obj, VALUE *subsecx)
|
||||
{
|
||||
VALUE subsec;
|
||||
|
@ -2541,12 +2561,11 @@ obj2subsecx(VALUE obj, VALUE *subsecx)
|
|||
if (RB_TYPE_P(obj, T_STRING)) {
|
||||
obj = rb_str_to_inum(obj, 10, FALSE);
|
||||
*subsecx = INT2FIX(0);
|
||||
return NUM2INT(obj);
|
||||
} else {
|
||||
divmodv(num_exact(obj), INT2FIX(1), &obj, &subsec);
|
||||
*subsecx = w2v(rb_time_magnify(v2w(subsec)));
|
||||
}
|
||||
|
||||
divmodv(num_exact(obj), INT2FIX(1), &obj, &subsec);
|
||||
*subsecx = w2v(rb_time_magnify(v2w(subsec)));
|
||||
return NUM2INT(obj);
|
||||
return obj2ubits(obj, 6); /* vtm->sec */
|
||||
}
|
||||
|
||||
static long
|
||||
|
@ -2559,7 +2578,7 @@ usec2subsecx(VALUE obj)
|
|||
return mulquo(num_exact(obj), INT2FIX(TIME_SCALE), INT2FIX(1000000));
|
||||
}
|
||||
|
||||
static int
|
||||
static uint32_t
|
||||
month_arg(VALUE arg)
|
||||
{
|
||||
int i, mon;
|
||||
|
@ -2578,12 +2597,12 @@ month_arg(VALUE arg)
|
|||
char c = RSTRING_PTR(s)[0];
|
||||
|
||||
if ('0' <= c && c <= '9') {
|
||||
mon = obj2int(s);
|
||||
mon = obj2ubits(s, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mon = obj2int(arg);
|
||||
mon = obj2ubits(arg, 4);
|
||||
}
|
||||
return mon;
|
||||
}
|
||||
|
@ -2649,8 +2668,8 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm)
|
|||
rb_scan_args(argc, argv, "17", &v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6],&v[7]);
|
||||
/* v[6] may be usec or zone (parsedate) */
|
||||
/* v[7] is wday (parsedate; ignored) */
|
||||
vtm->wday = -1;
|
||||
vtm->isdst = -1;
|
||||
vtm->wday = VTM_WDAY_INITVAL;
|
||||
vtm->isdst = VTM_ISDST_INITVAL;
|
||||
}
|
||||
|
||||
vtm->year = obj2vint(v[0]);
|
||||
|
@ -2666,15 +2685,15 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm)
|
|||
vtm->mday = 1;
|
||||
}
|
||||
else {
|
||||
vtm->mday = obj2int(v[2]);
|
||||
vtm->mday = obj2ubits(v[2], 5);
|
||||
}
|
||||
|
||||
vtm->hour = NIL_P(v[3])?0:obj2int(v[3]);
|
||||
vtm->hour = NIL_P(v[3])?0:obj2ubits(v[3], 5);
|
||||
|
||||
vtm->min = NIL_P(v[4])?0:obj2int(v[4]);
|
||||
vtm->min = NIL_P(v[4])?0:obj2ubits(v[4], 6);
|
||||
|
||||
if (!NIL_P(v[6]) && argc == 7) {
|
||||
vtm->sec = NIL_P(v[5])?0:obj2int(v[5]);
|
||||
vtm->sec = NIL_P(v[5])?0:obj2ubits(v[5],6);
|
||||
vtm->subsecx = usec2subsecx(v[6]);
|
||||
}
|
||||
else {
|
||||
|
@ -3999,7 +4018,7 @@ time_wday(VALUE time)
|
|||
|
||||
GetTimeval(time, tobj);
|
||||
MAKE_TM(time, tobj);
|
||||
return INT2FIX(tobj->vtm.wday);
|
||||
return INT2FIX((int)tobj->vtm.wday);
|
||||
}
|
||||
|
||||
#define wday_p(n) {\
|
||||
|
|
18
timev.h
18
timev.h
|
@ -3,18 +3,18 @@
|
|||
|
||||
struct vtm {
|
||||
VALUE year; /* 2000 for example. Integer. */
|
||||
int mon; /* 1..12 */
|
||||
int mday; /* 1..31 */
|
||||
int hour; /* 0..23 */
|
||||
int min; /* 0..59 */
|
||||
int sec; /* 0..60 */
|
||||
VALUE subsecx; /* 0 <= subsecx < TIME_SCALE. possibly Rational. */
|
||||
VALUE utc_offset; /* -3600 as -01:00 for example. possibly Rational. */
|
||||
int wday; /* 0:Sunday, 1:Monday, ..., 6:Saturday */
|
||||
int yday; /* 1..366 */
|
||||
int isdst; /* 0:StandardTime 1:DayLightSavingTime */
|
||||
const char *zone; /* "JST", "EST", "EDT", etc. */
|
||||
};
|
||||
uint16_t yday:9; /* 1..366 */
|
||||
uint8_t mon:4; /* 1..12 */
|
||||
uint8_t mday:5; /* 1..31 */
|
||||
uint8_t hour:5; /* 0..23 */
|
||||
uint8_t min:6; /* 0..59 */
|
||||
uint8_t sec:6; /* 0..60 */
|
||||
uint8_t wday:3; /* 0:Sunday, 1:Monday, ..., 6:Saturday 7:init */
|
||||
uint8_t isdst:2; /* 0:StandardTime 1:DayLightSavingTime 3:init */
|
||||
} PACKED_STRUCT;
|
||||
|
||||
#define TIME_SCALE 1000000000
|
||||
|
||||
|
|
Loading…
Reference in a new issue