ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: Eric Wong <normalperson@yhbt.net>
To: Ruby developers <ruby-core@ruby-lang.org>
Subject: [ruby-core:60741] Re: volatile usages
Date: Fri, 14 Feb 2014 10:55:43 +0000	[thread overview]
Message-ID: <20140214105542.GA25753@dcvr.yhbt.net> (raw)
In-Reply-To: <52FD820B.90607@ruby-lang.org>

Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:
> (2014/02/13 19:04), Eric Wong wrote:
> > Also, in string.c, I'm not sure if the volatile declaration is enough,
> > using RB_GC_GUARD below seems more correct (and generates smaller code
> > on x86-32, at least):
> 
> LGTM.

Thanks.  I also have a cleaner alternative to Bug #7805.

I think bare volatile use is too misunderstood/often-buggy-in-compilers
to be used for GC safety, so discourage it with RB_GC_GUARD (the lesser
of two evils).

Hopefully this will make the source clearer to other contributors.  We
should also add a section to README.EXT to document RB_GC_GUARD usage.

Something like this, but hopefully more correct, concise and clearer
than what I can write (comments/corrections appreciated):

=== RB_GC_GUARD to protect premature GC

C Ruby currently uses conservative garbage collection, thus VALUE
variables must remain visible on the stack or registers to ensure any
associated data remains usable.  Optimizing C compilers are not designed
with conservative garbage collection in mind, so they may optimize away
the original VALUE even if the code depends on data associated with that
VALUE.

The following example illustrates the use of RB_GC_GUARD to ensure
the contents of sptr remain valid while the second invocation of
rb_str_new_cstr is running.

  VALUE s, w;
  const char *sptr;

  s = rb_str_new_cstr("hello world!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  sptr = RSTRING_PTR(s);
  w = rb_str_new_cstr(sptr + 6); /* Possible GC invocation */

  RB_GC_GUARD(s); /* ensure s (and thus sptr) do not get GC-ed */

In the above example, RB_GC_GUARD must be placed _after_ use of
sptr.  Placing RB_GC_GUARD before dereferencing sptr would be of no use.
RB_GC_GUARD is only effective on the VALUE data type, not converted C
data types.

RB_GC_GUARD would not be necessary at all in the above example if
non-inlined function calls are made on the `s' VALUE after sptr is
dereferenced.  Thus, in the above example, calling any un-inlined
function on `s' such as:

  rb_str_modify(s);

Will ensure `s' stays on the stack or register to prevent a
GC invocation from prematurely freeing it.


Using the RB_GC_GUARD macro is preferable to using the "volatile"
keyword in C.  RB_GC_GUARD has the following advantages:

1) the intent of the macro use is clear

2) RB_GC_GUARD only affects its call site, "volatile" generates some
   extra code every time the variable is used, hurting optimization.

3) "volatile" implementations may be buggy/inconsistent in some
   compilers and architectures. RB_GC_GUARD is customizable for broken
   systems/compilers without those without negatively affecting other
   systems.

-----------------------------------8<----------------------------------

How much would link-time optimization (LTO) affect GC?  I fear it may
require the addition more RB_GC_GUARDs.  Fortunately nobody uses
LTO by default (it is very slow to link/optimize).

  reply	other threads:[~2014-02-14 11:05 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-13 10:04 [ruby-core:60682] volatile usages Eric Wong
2014-02-14  2:40 ` [ruby-core:60688] " Nobuyoshi Nakada
2014-02-14 10:55   ` Eric Wong [this message]
2014-02-15  1:53 ` [ruby-core:60751] " Eric Wong
2014-02-16  4:48   ` [ruby-core:60780] " Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140214105542.GA25753@dcvr.yhbt.net \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).