From d9d1b20d3997a7ebf6216913f4e758a0c6f173e2 Mon Sep 17 00:00:00 2001 From: normal Date: Tue, 23 Jun 2015 23:40:53 +0000 Subject: [PATCH] ext/socket/ancdata.c (bsock_recvmsg_internal): reduce stack use Using 8K stack is probably too much. As reference, ALLOCV falls back to heap allocation at a mere 1K. Since bsock_recvmsg_internal is a function which will always allocate and can trigger GC, it is in our best interest to minimize stack usage to avoid scanning 8K of stack on GC. [ruby-core:69595] [Feature #11263] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51003 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ ext/socket/ancdata.c | 38 +++++++++++++------------------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 23f4e680d4..e78a3db4ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Jun 24 08:28:15 2015 Eric Wong + + * ext/socket/ancdata.c (bsock_recvmsg_internal): reduce stack use + [ruby-core:69595] [Feature #11263] + Tue Jun 23 14:32:42 2015 Nobuyoshi Nakada * error.c (name_err_receiver): raise ArgumentError if no receiver diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index 614c8f31de..d0290ba07a 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -1498,7 +1498,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) struct msghdr mh; struct iovec iov; union_sockaddr namebuf; - char datbuf0[4096], *datbuf; + char *datbuf; VALUE dat_str = Qnil; VALUE ret; ssize_t ss; @@ -1506,10 +1506,6 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) struct cmsghdr *cmh; size_t maxctllen; - union { - char bytes[4096]; - struct cmsghdr align; - } ctlbuf0; char *ctlbuf; VALUE ctl_str = Qnil; int family; @@ -1519,9 +1515,9 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) rb_scan_args(argc, argv, "03:", &vmaxdatlen, &vflags, &vmaxctllen, &vopts); - maxdatlen = NIL_P(vmaxdatlen) ? sizeof(datbuf0) : NUM2SIZET(vmaxdatlen); + maxdatlen = NIL_P(vmaxdatlen) ? 4096 : NUM2SIZET(vmaxdatlen); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - maxctllen = NIL_P(vmaxctllen) ? sizeof(ctlbuf0) : NUM2SIZET(vmaxctllen); + maxctllen = NIL_P(vmaxctllen) ? 4096 : NUM2SIZET(vmaxctllen); #else if (!NIL_P(vmaxctllen)) rb_raise(rb_eArgError, "control message not supported"); @@ -1561,26 +1557,18 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) #endif retry: - if (maxdatlen <= sizeof(datbuf0)) - datbuf = datbuf0; - else { - if (NIL_P(dat_str)) - dat_str = rb_str_tmp_new(maxdatlen); - else - rb_str_resize(dat_str, maxdatlen); - datbuf = RSTRING_PTR(dat_str); - } + if (NIL_P(dat_str)) + dat_str = rb_str_tmp_new(maxdatlen); + else + rb_str_resize(dat_str, maxdatlen); + datbuf = RSTRING_PTR(dat_str); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - if (maxctllen <= sizeof(ctlbuf0)) - ctlbuf = ctlbuf0.bytes; - else { - if (NIL_P(ctl_str)) - ctl_str = rb_str_tmp_new(maxctllen); - else - rb_str_resize(ctl_str, maxctllen); - ctlbuf = RSTRING_PTR(ctl_str); - } + if (NIL_P(ctl_str)) + ctl_str = rb_str_tmp_new(maxctllen); + else + rb_str_resize(ctl_str, maxctllen); + ctlbuf = RSTRING_PTR(ctl_str); #endif memset(&mh, 0, sizeof(mh));