[前][次][番号順一覧][スレッド一覧]

ruby-changes:67719

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:00:53 +0900 (JST)
Subject: [ruby-changes:67719] 4397e737c5 (master): include/ruby/internal/memory.h: add doxygen

https://git.ruby-lang.org/ruby.git/commit/?id=4397e737c5

From 4397e737c57a0722499669f3c60693d2cdeba609 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Tue, 19 Jan 2021 12:55:16 +0900
Subject: include/ruby/internal/memory.h: add doxygen

Must not be a bad idea to improve documents. [ci skip]
---
 include/ruby/internal/memory.h | 427 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 408 insertions(+), 19 deletions(-)

diff --git a/include/ruby/internal/memory.h b/include/ruby/internal/memory.h
index 407b6a9..aa34644 100644
--- a/include/ruby/internal/memory.h
+++ b/include/ruby/internal/memory.h
@@ -62,6 +62,8 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/memory.h#L62
 #include "ruby/backward/2/assume.h"
 #include "ruby/defines.h"
 
+/** @cond INTENAL_MACRO  */
+
 /* Make alloca work the best possible way.  */
 #if defined(alloca)
 # /* Take that. */
@@ -75,18 +77,86 @@ extern "C" void *alloca(size_t); https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/memory.h#L77
 extern void *alloca();
 #endif
 
-#if defined(HAVE_INT128_T) && SIZEOF_SIZE_T <= 8
+/** @endcond  */
+
+#if defined(__DOXYGEN__)
+/**
+ * @private
+ *
+ * Type that is as twice wider as  size_t.  This is an implementation detail of
+ * rb_mul_size_overflow().  People should not use it.   This is not a good name
+ * either.
+ */
+typedef uint128_t DSIZE_T;
+#elif defined(HAVE_INT128_T) && SIZEOF_SIZE_T <= 8
 # define DSIZE_T uint128_t
 #elif SIZEOF_SIZE_T * 2 <= SIZEOF_LONG_LONG
 # define DSIZE_T unsigned LONG_LONG
 #endif
 
+/**
+ * @private
+ *
+ * Maximum  possible  number  of  bytes  that  #RB_ALLOCV  can  allocate  using
+ * `alloca`.  Anything  beyond this  is allocated  using rb_alloc_tmp_buffer().
+ * This selection is transparent to users.  People don't have to bother.
+ */
 #ifdef C_ALLOCA
 # define RUBY_ALLOCV_LIMIT 0
 #else
 # define RUBY_ALLOCV_LIMIT 1024
 #endif
 
+/**
+ * Prevents premature  destruction of local objects.   Ruby's garbage collector
+ * is conservative; it  scans the C level machine stack  as well.  Possible in-
+ * use Ruby  objects must  remain visible  on stack, to  be properly  marked as
+ * such.  However  contemporary C  compilers do not  interface well  with this.
+ * Consider the following example:
+ *
+ * ```CXX
+ * auto s = rb_str_new_cstr(" world");
+ * auto sptr = RSTRING_PTR(s);
+ * auto t = rb_str_new_cstr("hello,"); // Possible GC invocation
+ * auto u = rb_str_cat_cstr(t, sptr);
+ *
+ * RB_GC_GUARD(s); // ensure `s` (and thus `sptr`) do not get GC-ed
+ * ```
+ *
+ * Here, without the #RB_GC_GUARD, the last use of `s` is _before_ the last use
+ * of `sptr`.  Compilers  could thus think `s` and `t`  are allowed to overlap.
+ * That would eliminate `s`  from the stack, while `sptr` is  still in use.  If
+ * our GC  ran at  that very moment,  `s` gets swept  out, which  also destroys
+ * `sptr`.  Boom!  You got a SEGV.
+ *
+ * In order  to prevent this scenario  #RB_GC_GUARD must be placed  _after_ the
+ * last use of `sptr`.  Placing  #RB_GC_GUARD before dereferencing `sptr` would
+ * be of no use.
+ *
+ * #RB_GC_GUARD would  not be  necessary at  all in the  above example  if non-
+ * inlined  function  calls are  made  on  the  `s`  variable 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:
+ *
+ *  - the intent of the macro use is clear.
+ *
+ *  - #RB_GC_GUARD only affects its call  site.  OTOH `volatile` generates some
+ *    extra code every time the variable is used, hurting optimisation.
+ *
+ *  - `volatile` implementations  may be  buggy/inconsistent in  some compilers
+ *    and   architectures.     #RB_GC_GUARD   is   customisable    for   broken
+ *    systems/compilers without negatively affecting other systems.
+ *
+ *  - C++  since C++20  deprecates  `volatile`.  If  you  write your  extension
+ *    library in that language there is no escape but to use this macro.
+ *
+ * @param  v  A variable of ::VALUE type.
+ * @post   `v` is still alive.
+ */
 #ifdef __GNUC__
 #define RB_GC_GUARD(v) \
     (*__extension__ ({ \
@@ -101,65 +171,316 @@ extern void *alloca(); https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/memory.h#L171
 #define RB_GC_GUARD(v) (*rb_gc_guarded_ptr_val(&(v),(v)))
 #endif
 
-/* Casts needed because void* is NOT compaible with others in C++. */
+/* Casts needed because void* is NOT compatible with others in C++. */
+
+/**
+ * Convenient macro that allocates an array of n elements.
+ *
+ * @param      type            Type of array elements.
+ * @param      n               Length of the array.
+ * @exception  rb_eNoMemError  No space left for allocation.
+ * @exception  rb_eArgError    Integer overflow trying  to calculate the length
+ *                             of continuous  memory region of `n`  elements of
+ *                             `type`.
+ * @return     Storage  instance  that  is  capable of  storing  at  least  `n`
+ *             elements of type `type`.
+ * @note       It doesn't return NULL, even when `n` is zero.
+ * @warning    The return  value shall  be invalidated  exactly once  by either
+ *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
+ *             failure to pass it to system free(), because the system and Ruby
+ *             might or might not share the same malloc() implementation.
+ */
 #define RB_ALLOC_N(type,n)  RBIMPL_CAST((type *)ruby_xmalloc2((n), sizeof(type)))
+
+/**
+ * Shorthand of #RB_ALLOC_N with `n=1`.
+ *
+ * @param      type            Type of allocation.
+ * @exception  rb_eNoMemError  No space left for allocation.
+ * @return     Storage instance that can hold an `type` object.
+ * @note       It doesn't return NULL.
+ * @warning    The return  value shall  be invalidated  exactly once  by either
+ *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
+ *             failure to pass it to system free(), because the system and Ruby
+ *             might or might not share the same malloc() implementation.
+ */
 #define RB_ALLOC(type)      RBIMPL_CAST((type *)ruby_xmalloc(sizeof(type)))
+
+/**
+ * Identical to  #RB_ALLOC_N() but also  nullifies the allocated  region before
+ * returning.
+ *
+ * @param      type            Type of array elements.
+ * @param      n               Length of the array.
+ * @exception  rb_eNoMemError  No space left for allocation.
+ * @exception  rb_eArgError    Integer overflow trying  to calculate the length
+ *                             of continuous  memory region of `n`  elements of
+ *                             `type`.
+ * @return     Storage  instance  that  is  capable of  storing  at  least  `n`
+ *             elements of type `type`.
+ * @post       Returned array is filled with zeros.
+ * @note       It doesn't return NULL, even when `n` is zero.
+ * @warning    The return  value shall  be invalidated  exactly once  by either
+ *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
+ *             failure to pass it to system free(), because the system and Ruby
+ *             might or might not share the same malloc() implementation.
+ */
 #define RB_ZALLOC_N(type,n) RBIMPL_CAST((type *)ruby_xcalloc((n), sizeof(type)))
+
+/**
+ * Shorthand of #RB_ZALLOC_N with `n=1`.
+ *
+ * @param      type            Type of allocation.
+ * @exception  rb_eNoMemError  No space left for allocation.
+ * @return     Storage instance that can hold an `type` object.
+ * @post       Returned object is filled with zeros.
+ * @note       It doesn't return NULL.
+ * @warning    The return  value shall  be invalidated  exactly once  by either
+ *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
+ *             failure to pass it to system free(), because the system and Ruby
+ *             might or might not share the same malloc() implementation.
+ */
 #define RB_ZALLOC(type)     (RB_ZALLOC_N(type, 1))
+
+/**
+ * Convenient macro that reallocates an array with a new size.
+ *
+ * @param      var             A variable of `type`,  which points to a storage
+ *                             instance  that  was   previously  returned  from
+ *                             either
+ *                               - ruby_xmalloc(),
+ *                               - ruby_xmalloc2(),
+ *                               - ruby_xcalloc(),
+ *                               - ruby_xrealloc(), or
+ *                               - ruby_xrealloc2().
+ * @param      type            Type of allocation.
+ * @param      n               Requested new size of each element.
+ * @exception  rb_eNoMemError  No space left for  allocation.
+ * @exception  rb_eArgError    Integer overflow trying  to calculate the length
+ *                             of continuous  memory region of `n`  elements of
+ *                             `type`.
+ * @return     Storage  instance  that  is  capable of  storing  at  least  `n`
+ *             elements of type `type`.
+ * @pre        The passed variable must point to a valid live storage instance.
+ *             It is a  failure to pass a variable that  holds an already-freed
+ *             pointer.
+ * @note       It doesn't return NULL, even when `n` is zero.
+ * @warning    Do not  assume anything  on the alignment  of the  return value.
+ *             There is  no guarantee  that it  inherits the  passed argument's
+ *             one.
+ * @warning    The return  value shall  be invalidated  exactly once  by either
+ *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
+ *             failure to pass it to system free(), because the system and Ruby
+ *             mig (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]