Ruby: include/ruby/internal/memory.h File Reference

Ruby 3.3.6p108 (2024-11-05 revision 75015d4c1f6965b5e85e96fb309f1f2129f933c0)

Data Structures | Macros | Functions
memory.h File Reference

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/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"`

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`.
#define | RB_GC_GUARD(v)
| Prevents premature destruction of local objects.
#define | RB_ALLOC_N(type, n)
| Convenient macro that allocates an array of n elements.
#define | RB_ALLOC(type)
| Shorthand of RB_ALLOC_N with `n=1`.
#define | RB_ZALLOC_N(type, n)
| Identical to RB_ALLOC_N() but also nullifies the allocated region before returning.
#define | RB_ZALLOC(type)
| Shorthand of RB_ZALLOC_N with `n=1`.
#define | RB_REALLOC_N(var, type, n)
| Convenient macro that reallocates an array with a new size.
#define | ALLOCA_N(type, n)
#define | RB_ALLOCV(v, n)
| Identical to RB_ALLOCV_N(), except that it allocates a number of bytes and returns a void* .
#define | RB_ALLOCV_N(type, v, n)
| Allocates a memory region, possibly on stack.
#define | RB_ALLOCV_END(v)
| Polite way to declare that the given array is not used any longer.
#define | MEMZERO(p, type, n)
| Handy macro to erase a region of memory.
#define | MEMCPY(p1, p2, type, n)
| Handy macro to call memcpy.
#define | MEMMOVE(p1, p2, type, n)
| Handy macro to call memmove.
#define | MEMCMP(p1, p2, type, n)
| Handy macro to call memcmp.
#define | ALLOC_N RB_ALLOC_N
| Old name of RB_ALLOC_N.
#define | ALLOC RB_ALLOC
| Old name of RB_ALLOC.
#define | ZALLOC_N RB_ZALLOC_N
| Old name of RB_ZALLOC_N.
#define | ZALLOC RB_ZALLOC
| Old name of RB_ZALLOC.
#define | REALLOC_N RB_REALLOC_N
| Old name of RB_REALLOC_N.
#define | ALLOCV RB_ALLOCV
| Old name of RB_ALLOCV.
#define | ALLOCV_N RB_ALLOCV_N
| Old name of RB_ALLOCV_N.
#define | ALLOCV_END RB_ALLOCV_END
| Old name of RB_ALLOCV_END.

## 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().
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

Copyright
  This file is a part of the programming language Ruby. Permission is hereby granted, to either redistribute and/or modify this file, provided that the conditions mentioned in the file COPYING are met. Consult the file for details.

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,
|  |  | n )

Value:
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

  type | Type of array elements.
  n | Length of the array.

Returns
  A pointer on stack.

Definition at line 286 of file memory.h.

Referenced by rb_apply(), rb_funcall(), rb_str_buf_cat_ascii(), rb_str_concat(), and rb_yield_values().

## ◆ MEMCMP

#define MEMCMP | ( |  | p1,
|  |  | p2,
|  |  | type,
|  |  | n )

Value:
memcmp((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))

Handy macro to call memcmp.

Parameters

  p1 | Target LHS.
  p2 | Target RHS.
  type | Type of `p1[0]`
  n | Length of `p1`.

Return values

  <0 | `p1` is "less" than `p2`.
  0 | `p1` is equal to `p2`.
  >0 | `p1` is "greater" than `p2`.

Definition at line 391 of file memory.h.

Referenced by rb_big_eq(), and rb_big_eql().

## ◆ MEMCPY

#define MEMCPY | ( |  | p1,
|  |  | p2,
|  |  | type,
|  |  | n )

Value:
ruby_nonempty_memcpy((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))

Handy macro to call memcpy.

Parameters

  p1 | Destination pointer.
  p2 | Source pointer.
  type | Type of `p2[0]`
  n | Length of `p2`.

Returns
  `p1`.

Postcondition
  First `n` elements of `p2` are copied into `p1`.

Definition at line 366 of file memory.h.

Referenced by rb_apply(), rb_ary_resize(), rb_big_clone(), rb_econv_set_replacement(), rb_integer_unpack(), and rb_str_resize().

## ◆ MEMMOVE

#define MEMMOVE | ( |  | p1,
|  |  | p2,
|  |  | type,
|  |  | n )

Value:
memmove((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))

Handy macro to call memmove.

Parameters

  p1 | Destination pointer.
  p2 | Source pointer.
  type | Type of `p2[0]`
  n | Length of `p2`.

Returns
  `p1`.

Postcondition
  First `n` elements of `p2` are copied into `p1`.

Definition at line 378 of file memory.h.

Referenced by rb_ary_delete_at(), rb_econv_insert_output(), and rb_io_ungetc().

## ◆ MEMZERO

#define MEMZERO | ( |  | p,
|  |  | type,
|  |  | n )

Value:
memset((p), 0, rbimpl_size_mul_or_raise(sizeof(type), (n)))

Handy macro to erase a region of memory.

Parameters

  p | Target pointer.
  type | Type of `p[0]`
  n | Length of `p`.

Returns
  `p`.

Postcondition
  First `n` elements of `p` are squashed.

Definition at line 354 of file memory.h.

## ◆ RB_ALLOC

#define RB_ALLOC | ( |  | type | ) |

Value:
RBIMPL_CAST((type *)ruby_xmalloc(sizeof(type)))

Shorthand of RB_ALLOC_N with `n=1`.

Parameters

  type | Type of allocation.

Exceptions

  rb_eNoMemError | No 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 207 of file memory.h.

## ◆ RB_ALLOC_N

#define RB_ALLOC_N | ( |  | type,
|  |  | n )

Value:
RBIMPL_CAST((type *)ruby_xmalloc2((n), sizeof(type)))

Convenient macro that allocates an array of n elements.

Parameters

  type | Type of array elements.
  n | Length of the array.

Exceptions

  rb_eNoMemError | No space left for allocation.
  rb_eArgError | Integer 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 193 of file memory.h.

## ◆ RB_ALLOCV

#define RB_ALLOCV | ( |  | v,
|  |  | n )

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

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

Parameters

  v | A variable to hold the just-in-case opaque Ruby object.
  n | Size of allocation, in bytes.

Returns
  A void pointer to `n` bytes storage.

Note
  `n` may be evaluated twice.

Definition at line 298 of file memory.h.

## ◆ RB_ALLOCV_END

#define RB_ALLOCV_END | ( |  | v | ) |

Value:
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

  v | A variable previously passed to either RB_ALLOCV/RB_ALLOCV_N.

Definition at line 343 of file memory.h.

## ◆ RB_ALLOCV_N

#define RB_ALLOCV_N | ( |  | type,
|  |  | v,
|  |  | n )

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))))
rb_alloc_tmp_buffer2
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:640

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>
VALUE
foo(int n)
{
VALUE v;
auto ptr = RB_ALLOCV(struct tms, v, n);
...
// no need to free `ptr`.
}
RB_ALLOCV
#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:298
tms
Definition win32.h:700
VALUE
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

  type | The type of array elements.
  v | A variable to hold the just-in-case opaque Ruby object.
  n | Number of elements requested to allocate.

Returns
  An array of `n` elements of `type`.

Note
  `n` may be evaluated twice.

Definition at line 330 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
rb_str_cat_cstr
#define rb_str_cat_cstr(buf, str)
Identical to rb_str_cat(), except it assumes the passed pointer is a pointer to a C string.
Definition string.h:1656
rb_str_new_cstr
#define rb_str_new_cstr(str)
Identical to rb_str_new, except it assumes the passed pointer is a pointer to a C string.
Definition string.h:1514
RB_GC_GUARD
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
Definition memory.h:161

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

  v | A variable of VALUE type.

Postcondition
  `v` is still alive.

Definition at line 161 of file memory.h.

Referenced by rb_apply(), rb_autoload_load(), rb_big_and(), rb_big_or(), rb_big_xor(), rb_define_hooked_variable(), rb_econv_substr_append(), rb_env_clear(), rb_f_exec(), rb_find_file(), rb_find_file_ext(), rb_gc_register_address(), rb_integer_pack(), rb_path_to_class(), rb_proc_call_kw(), rb_proc_call_with_block_kw(), rb_reg_prepare_re(), rb_str_buf_append(), rb_str_format(), rb_str_plus(), rb_str_subpos(), rb_struct_initialize(), rb_yield_splat(), rb_yield_splat_kw(), and ruby_getcwd().

## ◆ RB_REALLOC_N

#define RB_REALLOC_N | ( |  | var,
|  |  | type,
|  |  | n )

Value:
((var) = RBIMPL_CAST((type *)ruby_xrealloc2((void *)(var), (n), sizeof(type))))

Convenient macro that reallocates an array with a new size.

Parameters

  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().
  type | Type of allocation.
  n | Requested new size of each element.

Exceptions

  rb_eNoMemError | No space left for allocation.
  rb_eArgError | Integer 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 276 of file memory.h.

## ◆ RB_ZALLOC

#define RB_ZALLOC | ( |  | type | ) |

Value:
(RB_ZALLOC_N(type, 1))
RB_ZALLOC_N
#define RB_ZALLOC_N(type, n)
Identical to RB_ALLOC_N() but also nullifies the allocated region before returning.
Definition memory.h:228

Shorthand of RB_ZALLOC_N with `n=1`.

Parameters

  type | Type of allocation.

Exceptions

  rb_eNoMemError | No 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 243 of file memory.h.

## ◆ RB_ZALLOC_N

#define RB_ZALLOC_N | ( |  | type,
|  |  | n )

Value:
RBIMPL_CAST((type *)ruby_xcalloc((n), sizeof(type)))

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

Parameters

  type | Type of array elements.
  n | Length of the array.

Exceptions

  rb_eNoMemError | No space left for allocation.
  rb_eArgError | Integer 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 228 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 107 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] | store | Pointer to a variable.
  [in] | count | Number of elements in an array.
  [in] | elsize | Size of each elements.

Returns
  Region of `count` * `elsize` bytes.

Postcondition
  `store` holds the corresponding tmp buffer object.

Definition at line 640 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] | a | Arbitrary value.
  [in] | b | Arbitrary value.
  [in] | max | Possible maximum value.
  [out] | c | A pointer to return the computation result.

Return values

  1 | `c` is insane.
  0 | `c` is sane.

Postcondition
  `c` holds `a` * `b`, but could be overflowed.

Definition at line 525 of file memory.h.

## ◆ ruby_nonempty_memcpy()

static void * ruby_nonempty_memcpy | ( | void * | dest,
|  | const void * | src,
|  | size_t | n )
| inlinestatic

Definition at line 655 of file memory.h.