ruby-changes:67754
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:01:26 +0900 (JST)
Subject: [ruby-changes:67754] 8b0dbca2f4 (master): include/ruby/internal/core/rarray.h: add doxygen
https://git.ruby-lang.org/ruby.git/commit/?id=8b0dbca2f4 From 8b0dbca2f41228ed0c7adb2ae592aea722a440c4 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: Wed, 3 Feb 2021 16:39:38 +0900 Subject: include/ruby/internal/core/rarray.h: add doxygen Must not be a bad idea to improve documents. [ci skip] --- include/ruby/internal/core/rarray.h | 340 ++++++++++++++++++++++++++++++++++-- internal/array.h | 4 - 2 files changed, 330 insertions(+), 14 deletions(-) diff --git a/include/ruby/internal/core/rarray.h b/include/ruby/internal/core/rarray.h index 61db40d..9f1d050 100644 --- a/include/ruby/internal/core/rarray.h +++ b/include/ruby/internal/core/rarray.h @@ -35,11 +35,26 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/core/rarray.h#L35 #include "ruby/internal/value_type.h" #include "ruby/assert.h" +/** + * @private + * @warning Do not touch this macro. + * @warning It is an implementation detail. + * @warning The value of this macro must match for ruby itself and all + * extension libraries, otherwise serious memory corruption shall + * occur. + */ #ifndef USE_TRANSIENT_HEAP # define USE_TRANSIENT_HEAP 1 #endif +/** + * Convenient casting macro. + * + * @param obj An object, which is in fact an ::RArray. + * @return The passed object casted to ::RArray. + */ #define RARRAY(obj) RBIMPL_CAST((struct RArray *)(obj)) +/** @cond INTERNAL_MACRO */ #define RARRAY_EMBED_FLAG RARRAY_EMBED_FLAG #define RARRAY_EMBED_LEN_MASK RARRAY_EMBED_LEN_MASK #define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX @@ -49,9 +64,10 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/core/rarray.h#L64 #else # define RARRAY_TRANSIENT_FLAG 0 #endif -#define RARRAY_LEN rb_array_len -#define RARRAY_CONST_PTR rb_array_const_ptr -#define RARRAY_CONST_PTR_TRANSIENT rb_array_const_ptr_transient +/** @endcond */ +#define RARRAY_LEN rb_array_len /**< @alias{rb_array_len} */ +#define RARRAY_CONST_PTR rb_array_const_ptr /**< @alias{rb_array_const_ptr} */ +#define RARRAY_CONST_PTR_TRANSIENT rb_array_const_ptr_transient /**< @alias{rb_array_const_ptr_transient} */ /** @cond INTERNAL_MACRO */ #if defined(__fcc__) || defined(__fcc_version) || \ @@ -69,28 +85,117 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/core/rarray.h#L85 #define RARRAY_PTR RARRAY_PTR /** @endcond */ +/** + * @private + * + * Bits that you can set to ::RBasic::flags. + * + * @warning These enums are not the only bits we use for arrays. + * + * @internal + * + * Unlike strings, flag usages for arrays are scattered across the entire + * source codes. @shyouhei doesn't know the complete list. But what is listed + * here is at least incomplete. + */ enum ruby_rarray_flags { + /** + * This flag has something to do with memory footprint. If the array is + * "small" enough, ruby tries to be creative to abuse padding bits of + * struct ::RArray for storing its contents. This flag denotes that + * situation. + * + * @warning This bit has to be considered read-only. Setting/clearing + * this bit without corresponding fix up must cause immediate + * SEGV. Also, internal structures of an array change + * dynamically and transparently throughout of its lifetime. + * Don't assume it being persistent. + * + * @internal + * + * 3rd parties must not be aware that there even is more than one way to + * store array elements. It was a bad idea to expose this to them. + */ RARRAY_EMBED_FLAG = RUBY_FL_USER1, + /* RUBY_FL_USER2 is for ELTS_SHARED */ + + /** + * When an array employs embedded strategy (see ::RARRAY_EMBED_FLAG), these + * bits are used to store the number of elements actually filled into + * ::RArray::ary. + * + * @internal + * + * 3rd parties must not be aware that there even is more than one way to + * store array elements. It was a bad idea to expose this to them. + */ RARRAY_EMBED_LEN_MASK = RUBY_FL_USER4 | RUBY_FL_USER3 #if USE_TRANSIENT_HEAP , + + /** + * This flag has something to do with an array's "transiency". A transient + * array is an array of young generation (of generational GC), who stores + * its elements inside of dedicated memory pages called a transient heap. + * Not every young generation share that storage scheme, but elder + * generations must no join. + * + * @internal + * + * 3rd parties must not be aware that there even is more than one way to + * store array elements. It was a bad idea to expose this to them. + */ RARRAY_TRANSIENT_FLAG = RUBY_FL_USER13 #endif }; +/** + * This is an enum because GDB wants it (rather than a macro). People need not + * bother. + */ enum ruby_rarray_consts { + /** Where ::RARRAY_EMBED_LEN_MASK resides. */ RARRAY_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 3, + + /** Max possible number elements that can be embedded. */ RARRAY_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE) }; +/** Ruby's array. */ struct RArray { + + /** Basic part, including flags and class. */ struct RBasic basic; + + /** Array's specific fields. */ union { + + /** + * Arrays that use separated memory region for elements use this + * pattern. + */ struct { + + /** Number of elements of the array. */ long len; + + /** Auxiliary info. */ union { + + /** + * Capacity of `*ptr`. A continuous memory region of at least + * `capa` elements is expected to exist at `*ptr`. This can be + * bigger than `len`. + */ long capa; + + /** + * Parent of the array. Nowadays arrays can share their + * backend memory regions each other, constructing gigantic + * nest of objects. This situation is called "shared", and + * this is the field to control such properties. + */ #if defined(__clang__) /* <- clang++ is sane */ || \ !defined(__cplusplus) /* <- C99 is sane */ || \ (__cplusplus > 199711L) /* <- C++11 is sane */ @@ -98,22 +203,77 @@ struct RArray { https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/core/rarray.h#L203 #endif VALUE shared_root; } aux; + + /** + * Pointer to the C array that holds the elements of the array. In + * the old days each array had dedicated memory regions. That is + * no longer true today, but there still are arrays of such + * properties. This field could be used to point such things. + */ const VALUE *ptr; } heap; + + /** + * Embedded elements. When an array is short enough, it uses this area + * to store its elements. In this case the length is encoded into the + * flags. + */ const VALUE ary[RARRAY_EMBED_LEN_MAX]; } as; }; RBIMPL_SYMBOL_EXPORT_BEGIN() +/** + * @private + * + * Declares a section of code where raw pointers are used. This is an + * implementation detail of #RARRAY_PTR_USE. People don't use it directly. + * + * @param[in] ary An object of ::RArray. + * @return `ary`'s backend C array. + */ VALUE *rb_ary_ptr_use_start(VALUE ary); + +/** + * @private + * + * Declares an end of a section formerly started by rb_ary_ptr_use_start(). + * This is an implementation detail of #RARRAY_PTR_USE. People don't use it + * directly. + * + * @param[in] a An object of ::RArray. + */ void rb_ary_ptr_use_end(VALUE a); + #if USE_TRANSIENT_HEAP +/** + * Destructively converts an array of transient backend into ordinal one. + * + * @param[out] a An object of ::RArray. + * @pre `a` must be a transient array. + * @post `a` gets out of transient heap, destructively. + */ void rb_ary_detransient(VALUE a); #endif RBIMPL_SYMBOL_EXPORT_END() RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_ARTIFICIAL() +/** + * Queries the length of the array. + * + * @param[in] ary Array in question. + * @return Its number of elements. + * @pre `ary` must be an instance of ::RArray, and must has its + * ::RARRAY_EMBED_FLAG flag set. + * + * @internal + * + * This was a macro before. It was inevitable to be public, since macros are + * global constructs. But should it be forever? Now that it is a function, + * @shyouhei thinks it could just be eliminated, hidden into implementation + * details. + */ static inline long RARRAY_EMBED_LEN(VALUE ary) { @@ -127,6 +287,13 @@ RARRAY_EMBED_LEN(VALUE ary) https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/core/rarray.h#L287 } RBIMPL_ATTR_PURE_UNLESS_DEBUG() +/** + * Queries the length of the array. + * + * @param[in] a Array in question. + * @return Its number of elements. + * @pre `a` must be an instance of ::RArray. + */ static inline long rb_array_len(VALUE a) { @@ -141,6 +308,18 @@ rb_array_len(VALUE a) https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/core/rarray.h#L308 } RBIMPL_ATTR_ARTIFICIAL() +/** + * Identical to rb_array_len(), except it differs for the return type. + * + * @param[in] ary Array in question. + * @exception rb_eRangeError Too long. + * @return Its number of elements. + * @pre `ary` must be an instance of ::RArray. + * + * @internal + * + * This API seems redundant but has actual usages. + */ static inline int RARRAY_LENINT(VALUE ary) { @@ -149,6 +328,19 (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/