From 8a1fc65c88dee174940735bb46074c72ac47ce61 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 31 Jan 2011 17:05:48 -0800 Subject: autopush: optimize away ivar usage under MRI We know that all versions of MRI have a small RFile structure that is allocated in the same object slots as other Ruby types and also zeroed on allocation. This optimization enables us to fall back to using ivars in case MRI changes or if we're used on other Rubies. --- ext/kgio/autopush.c | 21 +++++++++++++++++++++ ext/kgio/extconf.rb | 8 ++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ext/kgio/autopush.c b/ext/kgio/autopush.c index fa24055..cc83fdb 100644 --- a/ext/kgio/autopush.c +++ b/ext/kgio/autopush.c @@ -38,6 +38,26 @@ enum autopush_state { AUTOPUSH_STATE_ACCEPTOR = 3 }; +#if defined(R_CAST) && \ + defined(HAVE_TYPE_STRUCT_RFILE) && \ + defined(HAVE_TYPE_STRUCT_ROBJECT) && \ + ((SIZEOF_STRUCT_RFILE + SIZEOF_INT) <= (SIZEOF_STRUCT_ROBJECT)) + +struct AutopushSocket { + struct RFile rfile; + enum autopush_state autopush_state; +}; + +static enum autopush_state state_get(VALUE io) +{ + return ((struct AutopushSocket *)(io))->autopush_state; +} + +static void state_set(VALUE io, enum autopush_state state) +{ + ((struct AutopushSocket *)(io))->autopush_state = state; +} +#else static enum autopush_state state_get(VALUE io) { VALUE val; @@ -53,6 +73,7 @@ static void state_set(VALUE io, enum autopush_state state) { rb_ivar_set(io, id_autopush_state, INT2NUM(state)); } +#endif /* IVAR fallback */ static enum autopush_state detect_acceptor_state(VALUE io); static void push_pending_data(VALUE io); diff --git a/ext/kgio/extconf.rb b/ext/kgio/extconf.rb index dcc1418..e7220a4 100644 --- a/ext/kgio/extconf.rb +++ b/ext/kgio/extconf.rb @@ -3,8 +3,9 @@ $CPPFLAGS << ' -D_GNU_SOURCE' have_func('accept4', %w(sys/socket.h)) if have_header('ruby/io.h') - have_struct_member("rb_io_t", "fd", "ruby/io.h") - have_struct_member("rb_io_t", "mode", "ruby/io.h") + rubyio = %w(ruby.h ruby/io.h) + have_struct_member("rb_io_t", "fd", rubyio) + have_struct_member("rb_io_t", "mode", rubyio) else rubyio = %w(ruby.h rubyio.h) rb_io_t = have_type("OpenFile", rubyio) ? "OpenFile" : "rb_io_t" @@ -13,6 +14,9 @@ else have_struct_member(rb_io_t, "mode", rubyio) have_func('rb_fdopen') end +have_type("struct RFile", rubyio) and check_sizeof("struct RFile", rubyio) +have_type("struct RObject") and check_sizeof("struct RObject") +check_sizeof("int") have_func('rb_io_ascii8bit_binmode') have_func('rb_thread_blocking_region') have_func('rb_str_set_len') -- cgit v1.2.3-24-ge0c7