Ruby  3.4.0dev (2024-11-22 revision 37a72b0150ec36b4ea27175039afc28c62207b0c)
Data Structures | Macros | Functions
memory.h File Reference

(37a72b0150ec36b4ea27175039afc28c62207b0c)

Memory management stuff. More...

#include "ruby/internal/config.h"
#include "ruby/internal/attr/alloc_size.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/stdalign.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/stdckdint.h"
#include "ruby/internal/xmalloc.h"
#include "ruby/backward/2/limits.h"
#include "ruby/backward/2/long_long.h"
#include "ruby/backward/2/assume.h"
#include "ruby/defines.h"
Include dependency graph for memory.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define RUBY_ALLOCV_LIMIT   1024
 Maximum possible number of bytes that RB_ALLOCV can allocate using alloca. More...
 
#define RB_GC_GUARD(v)
 Prevents premature destruction of local objects. More...
 
#define RB_ALLOC_N(type, n)   RBIMPL_CAST((type *)ruby_xmalloc2((n), sizeof(type)))
 Convenient macro that allocates an array of n elements. More...
 
#define RB_ALLOC(type)   RBIMPL_CAST((type *)ruby_xmalloc(sizeof(type)))
 Shorthand of RB_ALLOC_N with n=1. More...
 
#define RB_ZALLOC_N(type, n)   RBIMPL_CAST((type *)ruby_xcalloc((n), sizeof(type)))
 Identical to RB_ALLOC_N() but also nullifies the allocated region before returning. More...
 
#define RB_ZALLOC(type)   (RB_ZALLOC_N(type, 1))
 Shorthand of RB_ZALLOC_N with n=1. More...
 
#define RB_REALLOC_N(var, type, n)    ((var) = RBIMPL_CAST((type *)ruby_xrealloc2((void *)(var), (n), sizeof(type))))
 Convenient macro that reallocates an array with a new size. More...
 
#define ALLOCA_N(type, n)    RBIMPL_CAST((type *)alloca(rbimpl_size_mul_or_raise(sizeof(type), (n))))
 
#define RB_ALLOCV(v, n)
 Identical to RB_ALLOCV_N(), except that it allocates a number of bytes and returns a void* . More...
 
#define RB_ALLOCV_N(type, v, n)
 Allocates a memory region, possibly on stack. More...
 
#define RB_ALLOCV_END(v)   rb_free_tmp_buffer(&(v))
 Polite way to declare that the given array is not used any longer. More...
 
#define MEMZERO(p, type, n)   memset((p), 0, rbimpl_size_mul_or_raise(sizeof(type), (n)))
 Handy macro to erase a region of memory. More...
 
#define MEMCPY(p1, p2, type, n)   ruby_nonempty_memcpy((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
 Handy macro to call memcpy. More...
 
#define MEMMOVE(p1, p2, type, n)   memmove((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
 Handy macro to call memmove. More...
 
#define MEMCMP(p1, p2, type, n)   memcmp((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
 Handy macro to call memcmp. More...
 
#define ALLOC_N   RB_ALLOC_N
 Old name of RB_ALLOC_N. More...
 
#define ALLOC   RB_ALLOC
 Old name of RB_ALLOC. More...
 
#define ZALLOC_N   RB_ZALLOC_N
 Old name of RB_ZALLOC_N. More...
 
#define ZALLOC   RB_ZALLOC
 Old name of RB_ZALLOC. More...
 
#define REALLOC_N   RB_REALLOC_N
 Old name of RB_REALLOC_N. More...
 
#define ALLOCV   RB_ALLOCV
 Old name of RB_ALLOCV. More...
 
#define ALLOCV_N   RB_ALLOCV_N
 Old name of RB_ALLOCV_N. More...
 
#define ALLOCV_END   RB_ALLOCV_END
 Old name of RB_ALLOCV_END. More...
 

Functions

static int rb_mul_size_overflow (size_t a, size_t b, size_t max, size_t *c)
 
static void * rb_alloc_tmp_buffer2 (volatile VALUE *store, long count, size_t elsize)
 This is an implementation detail of RB_ALLOCV_N(). More...
 
static void * ruby_nonempty_memcpy (void *dest, const void *src, size_t n)
 

Detailed Description

Memory management stuff.

Author
Ruby developers ruby-.nosp@m.core.nosp@m.@ruby.nosp@m.-lan.nosp@m.g.org
Warning
Symbols prefixed with either RBIMPL or rbimpl are implementation details. Don't take them as canon. They could rapidly appear then vanish. The name (path) of this header file is also an implementation detail. Do not expect it to persist at the place it is now. Developers are free to move it anywhere anytime at will.
Note
To ruby-core: remember that this header can be possibly recursively included from extension libraries written in C++. Do not expect for instance __VA_ARGS__ is always available. We assume C99 for ruby itself but we don't assume languages of extension libraries. They could be written in C++98.

Definition in file memory.h.

Macro Definition Documentation

◆ ALLOCA_N

#define ALLOCA_N (   type,
 
)     RBIMPL_CAST((type *)alloca(rbimpl_size_mul_or_raise(sizeof(type), (n))))
Deprecated:
This macro is dangerous (does not bother stack overflow at all).

RB_ALLOCV is the modern way to do the same thing.

Parameters
typeType of array elements.
nLength of the array.
Returns
A pointer on stack.

Definition at line 287 of file memory.h.

◆ MEMCMP

#define MEMCMP (   p1,
  p2,
  type,
 
)    memcmp((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))

Handy macro to call memcmp.

Parameters
p1Target LHS.
p2Target RHS.
typeType of p1[0]
nLength of p1.
Return values
<0`p1` is "less" than `p2`.
0`p1` is equal to `p2`.
>0p1 is "greater" than p2.

Definition at line 392 of file memory.h.

◆ MEMCPY

#define MEMCPY (   p1,
  p2,
  type,
 
)    ruby_nonempty_memcpy((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))

Handy macro to call memcpy.

Parameters
p1Destination pointer.
p2Source pointer.
typeType of p2[0]
nLength of p2.
Returns
p1.
Postcondition
First n elements of p2 are copied into p1.

Definition at line 367 of file memory.h.

◆ MEMMOVE

#define MEMMOVE (   p1,
  p2,
  type,
 
)    memmove((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))

Handy macro to call memmove.

Parameters
p1Destination pointer.
p2Source pointer.
typeType of p2[0]
nLength of p2.
Returns
p1.
Postcondition
First n elements of p2 are copied into p1.

Definition at line 379 of file memory.h.

◆ MEMZERO

#define MEMZERO (   p,
  type,
 
)    memset((p), 0, rbimpl_size_mul_or_raise(sizeof(type), (n)))

Handy macro to erase a region of memory.

Parameters
pTarget pointer.
typeType of p[0]
nLength of p.
Returns
p.
Postcondition
First n elements of p are squashed.

Definition at line 355 of file memory.h.

◆ RB_ALLOC

#define RB_ALLOC (   type)    RBIMPL_CAST((type *)ruby_xmalloc(sizeof(type)))

Shorthand of RB_ALLOC_N with n=1.

Parameters
typeType of allocation.
Exceptions
rb_eNoMemErrorNo space left for allocation.
Returns
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.

Definition at line 208 of file memory.h.

◆ RB_ALLOC_N

#define RB_ALLOC_N (   type,
 
)    RBIMPL_CAST((type *)ruby_xmalloc2((n), sizeof(type)))

Convenient macro that allocates an array of n elements.

Parameters
typeType of array elements.
nLength of the array.
Exceptions
rb_eNoMemErrorNo space left for allocation.
rb_eArgErrorInteger overflow trying to calculate the length of continuous memory region of n elements of type.
Returns
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.

Definition at line 194 of file memory.h.

◆ RB_ALLOCV

#define RB_ALLOCV (   v,
 
)
Value:
((n) < RUBY_ALLOCV_LIMIT ? \
((v) = 0, alloca(n)) : \
rb_alloc_tmp_buffer(&(v), (n)))
#define RUBY_ALLOCV_LIMIT
Maximum possible number of bytes that RB_ALLOCV can allocate using alloca.
Definition: memory.h:108

Identical to RB_ALLOCV_N(), except that it allocates a number of bytes and returns a void* .

Parameters
vA variable to hold the just-in-case opaque Ruby object.
nSize of allocation, in bytes.
Returns
A void pointer to n bytes storage.
Note
n may be evaluated twice.

Definition at line 299 of file memory.h.

◆ RB_ALLOCV_END

#define RB_ALLOCV_END (   v)    rb_free_tmp_buffer(&(v))

Polite way to declare that the given array is not used any longer.

Calling this not mandatory. Our GC can baby-sit you. However it is not a very bad idea to use it when possible. Doing so could reduce memory footprint.

Parameters
vA variable previously passed to either RB_ALLOCV/RB_ALLOCV_N.

Definition at line 344 of file memory.h.

◆ RB_ALLOCV_N

#define RB_ALLOCV_N (   type,
  v,
 
)
Value:
RBIMPL_CAST((type *) \
(((size_t)(n) < RUBY_ALLOCV_LIMIT / sizeof(type)) ? \
((v) = 0, alloca((n) * sizeof(type))) : \
rb_alloc_tmp_buffer2(&(v), (n), sizeof(type))))
static void * rb_alloc_tmp_buffer2(volatile VALUE *store, long count, size_t elsize)
This is an implementation detail of RB_ALLOCV_N().
Definition: memory.h:644
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56

Allocates a memory region, possibly on stack.

If the given size exceeds RUBY_ALLOCV_LIMIT, it allocates a dedicated opaque ruby object instead and let our GC sweep that region after use. Either way you can fire-and-forget.

#include <sys/types.h>
foo(int n)
{
VALUE v;
auto ptr = RB_ALLOCV(struct tms, v, n);
...
// no need to free `ptr`.
}
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
Definition: io.h:2
#define RB_ALLOCV(v, n)
Identical to RB_ALLOCV_N(), except that it allocates a number of bytes and returns a void* .
Definition: memory.h:299
Definition: win32.h:701
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40

If you want to be super-duper polite you can also explicitly state the end of use of such memory region by calling RB_ALLOCV_END().

Parameters
typeThe type of array elements.
vA variable to hold the just-in-case opaque Ruby object.
nNumber of elements requested to allocate.
Returns
An array of n elements of type.
Note
n may be evaluated twice.

Definition at line 331 of file memory.h.

◆ RB_GC_GUARD

#define RB_GC_GUARD (   v)
Value:
(*__extension__ ({ \
volatile VALUE *rb_gc_guarded_ptr = &(v); \
__asm__("" : : "m"(rb_gc_guarded_ptr)); \
rb_gc_guarded_ptr; \
}))

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:

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
VALUE rb_str_new_cstr(const char *ptr)
Identical to rb_str_new(), except it assumes the passed pointer is a pointer to a C string.
Definition: string.c:1074
VALUE rb_str_cat_cstr(VALUE dst, const char *src)
Identical to rb_str_cat(), except it assumes the passed pointer is a pointer to a C string.
Definition: string.c:3455
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
Definition: memory.h:162
static char * RSTRING_PTR(VALUE str)
Queries the contents pointer of the string.
Definition: rstring.h:416

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.
Parameters
vA variable of VALUE type.
Postcondition
v is still alive.

Definition at line 162 of file memory.h.

◆ RB_REALLOC_N

#define RB_REALLOC_N (   var,
  type,
 
)     ((var) = RBIMPL_CAST((type *)ruby_xrealloc2((void *)(var), (n), sizeof(type))))

Convenient macro that reallocates an array with a new size.

Parameters
varA variable of type, which points to a storage instance that was previously returned from either
typeType of allocation.
nRequested new size of each element.
Exceptions
rb_eNoMemErrorNo space left for allocation.
rb_eArgErrorInteger overflow trying to calculate the length of continuous memory region of n elements of type.
Returns
Storage instance that is capable of storing at least n elements of type type.
Precondition
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.
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.

Definition at line 277 of file memory.h.

◆ RB_ZALLOC

#define RB_ZALLOC (   type)    (RB_ZALLOC_N(type, 1))

Shorthand of RB_ZALLOC_N with n=1.

Parameters
typeType of allocation.
Exceptions
rb_eNoMemErrorNo space left for allocation.
Returns
Storage instance that can hold an type object.
Postcondition
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.

Definition at line 244 of file memory.h.

◆ RB_ZALLOC_N

#define RB_ZALLOC_N (   type,
 
)    RBIMPL_CAST((type *)ruby_xcalloc((n), sizeof(type)))

Identical to RB_ALLOC_N() but also nullifies the allocated region before returning.

Parameters
typeType of array elements.
nLength of the array.
Exceptions
rb_eNoMemErrorNo space left for allocation.
rb_eArgErrorInteger overflow trying to calculate the length of continuous memory region of n elements of type.
Returns
Storage instance that is capable of storing at least n elements of type type.
Postcondition
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.

Definition at line 229 of file memory.h.

◆ RUBY_ALLOCV_LIMIT

#define RUBY_ALLOCV_LIMIT   1024

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.

Definition at line 108 of file memory.h.

Function Documentation

◆ rb_alloc_tmp_buffer2()

static void* rb_alloc_tmp_buffer2 ( volatile VALUE store,
long  count,
size_t  elsize 
)
inlinestatic

This is an implementation detail of RB_ALLOCV_N().

People don't use this directly.

Parameters
[out]storePointer to a variable.
[in]countNumber of elements in an array.
[in]elsizeSize of each elements.
Returns
Region of count * elsize bytes.
Postcondition
store holds the corresponding tmp buffer object.

Definition at line 644 of file memory.h.

◆ rb_mul_size_overflow()

static int rb_mul_size_overflow ( size_t  a,
size_t  b,
size_t  max,
size_t *  c 
)
inlinestatic
Deprecated:
This function was an implementation detail of old RB_ALLOCV_N().

We no longer use it. @shyouhei suspects that there are no actual usage now. However it was not marked as private before. We cannot delete it any longer.

Parameters
[in]aArbitrary value.
[in]bArbitrary value.
[in]maxPossible maximum value.
[out]cA pointer to return the computation result.
Return values
1c is insane.
0c is sane.
Postcondition
c holds a * b, but could be overflowed.

Definition at line 526 of file memory.h.