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

Ruby 3.2.5p208 (2024-07-26 revision 31d0f1a2e7dbfb60731d1f05b868e1d578cda493)

Macros | Functions
xmalloc.h File Reference

Declares ruby_xmalloc(). More...

`#include "ruby/internal/config.h"`
`#include "ruby/internal/attr/alloc_size.h"`
`#include "ruby/internal/attr/nodiscard.h"`
`#include "ruby/internal/attr/noexcept.h"`
`#include "ruby/internal/attr/restrict.h"`
`#include "ruby/internal/attr/returns_nonnull.h"`
`#include "ruby/internal/dllexport.h"`

Go to the source code of this file.

## Macros
#define | USE_GC_MALLOC_OBJ_INFO_DETAILS 0
#define | xmalloc ruby_xmalloc
| Old name of ruby_xmalloc.
#define | xmalloc2 ruby_xmalloc2
| Old name of ruby_xmalloc2.
#define | xcalloc ruby_xcalloc
| Old name of ruby_xcalloc.
#define | xrealloc ruby_xrealloc
| Old name of ruby_xrealloc.
#define | xrealloc2 ruby_xrealloc2
| Old name of ruby_xrealloc2.
#define | xfree ruby_xfree
| Old name of ruby_xfree.

## Functions
void * | ruby_xmalloc (size_t size)
| Allocates a storage instance.
void * | ruby_xmalloc2 (size_t nelems, size_t elemsiz)
| Identical to ruby_xmalloc(), except it allocates `nelems` * `elemsiz` bytes.
void * | ruby_xcalloc (size_t nelems, size_t elemsiz)
| Identical to ruby_xmalloc2(), except it returns a zero-filled storage instance.
void * | ruby_xrealloc (void *ptr, size_t newsiz)
| Resize the storage instance.
void * | ruby_xrealloc2 (void *ptr, size_t newelems, size_t newsiz)
| Identical to ruby_xrealloc(), except it resizes the given storage instance to `newelems` * `newsiz` bytes.
void | ruby_xfree (void *ptr)
| Deallocates a storage instance.

## Detailed Description

Declares ruby_xmalloc().

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 xmalloc.h.

## Macro Definition Documentation

## ◆ USE_GC_MALLOC_OBJ_INFO_DETAILS

#define USE_GC_MALLOC_OBJ_INFO_DETAILS 0

Warning
  Do not touch this macro.
  It is an implementation detail.
  It was a failure at the first place to let you know about it.
  The value of this macro must match for ruby itself and all extension libraries, otherwise serious memory corruption shall occur.

Definition at line 50 of file xmalloc.h.

## Function Documentation

## ◆ ruby_xcalloc()

void * ruby_xcalloc | ( | size_t | nelems,
|  | size_t | elemsiz )

Identical to ruby_xmalloc2(), except it returns a zero-filled storage instance.

It can also be seen as a routine identical to ruby_xmalloc(), except it calls calloc() instead of malloc().

Parameters

  [in] | nelems | Number of elements.
  [in] | elemsiz | Size of an element.

Exceptions

  rb_eNoMemError | No space left for allocation.
  rb_eArgError | `nelems` * `elemsiz` would overflow.

Returns
  A valid pointer to an allocated storage instance; which has at least `nelems` * `elemsiz` bytes width, with appropriate alignment detected by the underlying calloc() routine.

Postcondition
  The returned storage instance is filled with zeros.

Note
  It doesn't return NULL.
  Unlike some calloc() implementations, it allocates something and returns a meaningful value even when `nelems` or `elemsiz` or both are 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 14777 of file gc.c.

## ◆ ruby_xfree()

void ruby_xfree | ( | void * | ptr | ) |

Deallocates a storage instance.

Parameters

  [out] | ptr | Either NULL, or a valid pointer previously returned from one of: ruby_xmalloc(), ruby_xmalloc2(), ruby_xcalloc(), ruby_xrealloc(), or ruby_xrealloc2().

Precondition
  The passed pointer must point to a valid live storage instance. It is a failure to pass an already freed pointer.

Postcondition
  The storage instance pointed by the passed pointer gets invalidated; it is no longer addressable.

Warning
  Every single storage instance that was previously allocated by either ruby_xmalloc(), ruby_xmalloc2(), ruby_xcalloc(), ruby_xrealloc(), or ruby_xrealloc2() shall be invalidated exactly once by either passing it to ruby_xfree(), or passing it to either ruby_xrealloc(), ruby_xrealloc2() then check the return value for invalidation.
  Do not pass anything other than pointers described above. For instance pointers returned from malloc() or mmap() shall not be passed to this function, because the underlying memory management mechanism could differ.
  Do not pass any invalid pointers to this function e.g. by calling it twice with a same argument.

Definition at line 12670 of file gc.c.

## ◆ ruby_xmalloc()

void * ruby_xmalloc | ( | size_t | size | ) |

Allocates a storage instance.

It is largely the same as system malloc(), except:

- It raises Ruby exceptions instead of returning NULL, and
- In case of `ENOMEM` it tries to GC to make some room.

Parameters

  [in] | size | Requested amount of memory.

Exceptions

  rb_eNoMemError | No space left for `size` bytes allocation.

Returns
  A valid pointer to an allocated storage instance; which has at least `size` bytes width, with appropriate alignment detected by the underlying malloc() routine.

Note
  It doesn't return NULL.
  Unlike some malloc() implementations, it allocates something and returns a meaningful value even when `size` is equal to 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 14757 of file gc.c.

## ◆ ruby_xmalloc2()

void * ruby_xmalloc2 | ( | size_t | nelems,
|  | size_t | elemsiz )

Identical to ruby_xmalloc(), except it allocates `nelems` * `elemsiz` bytes.

This is needed because the multiplication could integer overflow. On such situations Ruby does not try to allocate at all but raises Ruby level exceptions instead. If there is no integer overflow the behaviour is exactly the same as `ruby_xmalloc(nelems*elemsiz)`.

Parameters

  [in] | nelems | Number of elements.
  [in] | elemsiz | Size of an element.

Exceptions

  rb_eNoMemError | No space left for allocation.
  rb_eArgError | `nelems` * `elemsiz` would overflow.

Returns
  A valid pointer to an allocated storage instance; which has at least `nelems` * `elemsiz` bytes width, with appropriate alignment detected by the underlying malloc() routine.

Note
  It doesn't return NULL.
  Unlike some malloc() implementations, it allocates something and returns a meaningful value even when `nelems` or `elemsiz` or both are 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 14767 of file gc.c.

## ◆ ruby_xrealloc()

void * ruby_xrealloc | ( | void * | ptr,
|  | size_t | newsiz )

Resize the storage instance.

Parameters

  [in] | ptr | A valid pointer to a storage instance that was previously returned from either: ruby_xmalloc(), ruby_xmalloc2(), ruby_xcalloc(), ruby_xrealloc(), or ruby_xrealloc2().
  [in] | newsiz | Requested new amount of memory.

Exceptions

  rb_eNoMemError | No space left for `newsiz` bytes allocation.

Returns
  A valid pointer to a (possibly newly allocated) storage instance; which has at least `newsiz` bytes width, with appropriate alignment detected by the underlying realloc() routine.

Precondition
  The passed pointer must point to a valid live storage instance. It is a failure to pass an already freed pointer.

Postcondition
  In case the function returns the passed pointer as-is, the storage instance that the pointer holds is either grown or shrunken to have at least `newsiz` bytes. Otherwise a valid pointer to a newly allocated storage instance is returned. In this case `ptr` is invalidated as if it was passed to ruby_xfree().

Note
  It doesn't return NULL.

Warning
  Unlike some realloc() implementations, passing zero to `newsiz` is not the same as calling ruby_xfree(), because this function never returns NULL. Something meaningful still returns then.
  It is a failure not to check the return value. Do not assume anything on it. It could be either identical to, or distinct form the passed argument.
  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 14787 of file gc.c.

## ◆ ruby_xrealloc2()

void * ruby_xrealloc2 | ( | void * | ptr,
|  | size_t | newelems,
|  | size_t | newsiz )

Identical to ruby_xrealloc(), except it resizes the given storage instance to `newelems` * `newsiz` bytes.

This is needed because the multiplication could integer overflow. On such situations Ruby does not try to touch the contents of argument pointer at all but raises Ruby level exceptions instead. If there is no integer overflow the behaviour is exactly the same as `ruby_xrealloc(ptr,nelems*elemsiz)`.

This is roughly the same as reallocarray() function that OpenBSD etc. provides, but also interacts with our GC.

Parameters

  [in] | ptr | A valid pointer to a storage instance that was previously returned from either: ruby_xmalloc(), ruby_xmalloc2(), ruby_xcalloc(), ruby_xrealloc(), or ruby_xrealloc2().
  [in] | newelems | Requested new number of elements.
  [in] | newsiz | Requested new size of each element.

Exceptions

  rb_eNoMemError | No space left for allocation.
  rb_eArgError | `newelems` * `newsiz` would overflow.

Returns
  A valid pointer to a (possibly newly allocated) storage instance; which has at least `newelems` * `newsiz` bytes width, with appropriate alignment detected by the underlying realloc() routine.

Precondition
  The passed pointer must point to a valid live storage instance. It is a failure to pass an already freed pointer.

Postcondition
  In case the function returns the passed pointer as-is, the storage instance that the pointer holds is either grown or shrunken to have at least `newelems` * `newsiz` bytes. Otherwise a valid pointer to a newly allocated storage instance is returned. In this case `ptr` is invalidated as if it was passed to ruby_xfree().

Note
  It doesn't return NULL.

Warning
  Unlike some realloc() implementations, passing zero to either `newelems` or `elemsiz` are not the same as calling ruby_xfree(), because this function never returns NULL. Something meaningful still returns then.
  It is a failure not to check the return value. Do not assume anything on it. It could be either identical to, or distinct form the passed argument.
  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 14797 of file gc.c.