Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Calendar
  - Forums
  - IRC
  - Community Discord
  - Wiki
  - GitHub
  - Issues
  - Get involved
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# rt.lifetime

This module contains all functions related to an object's lifetime: allocation, resizing, deallocation, and finalization.
License:
Distributed under the Boost Software License 1.0. (See accompanying file LICENSE)
Authors:
Walter Bright, Sean Kelly, Steven Schveighoffer

Source rt/lifetime.d

void* `_d_allocmemory`(size_t `sz`);
  Allocate memory using the garbage collector
  DMD uses this to allocate closures:

      void f(byte[24] x)
      {
          return () => x; // `x` is on stack, must be moved to heap to keep it alive
      }

  Parameters:

  size_t `sz` | number of bytes to allocate

  Returns:
  pointer to `sz` bytes of free, uninitialized memory, managed by the GC.
Object `_d_newclass`(const ClassInfo `ci`);
  Create a new class instance.
  Allocates memory and sets fields to their initial value, but does not call a constructor.

      new Object() // _d_newclass(typeid(Object))

  Parameters:

  ClassInfo `ci` | TypeInfo_Class object, to provide instance size and initial bytes to copy

  Returns:
  newly created object
void `_d_delinterface`(void** `p`);
void `_d_delclass`(Object* `p`);
pure nothrow bool `__setArrayAllocLength`(ref BlkInfo `info`, size_t `newlength`, bool `isshared`, const TypeInfo `tinext`, size_t `oldlength` = ~0);
  Set the allocated length of the array block. This is called any time an array is appended to or its length is set.
  The allocated block looks like this for blocks < PAGESIZE:
  |elem0|elem1|elem2|...|elemN-1|emptyspace|N*elemsize|
  The size of the allocated length at the end depends on the block size:
  a block of 16 to 256 bytes has an 8-bit length.
  a block with 512 to pagesize/2 bytes has a 16-bit length.
  For blocks >= pagesize, the length is a size_t and is at the beginning of the block. The reason we have to do this is because the block can extend into more pages, so we cannot trust the block length if it sits at the end of the block, because it might have just been extended. If we can prove in the future that the block is unshared, we may be able to change this, but I'm not sure it's important.
  In order to do put the length at the front, we have to provide 16 bytes buffer space in case the block has to be aligned properly. In x86, certain SSE instructions will only work if the data is 16-byte aligned. In addition, we need the sentinel byte to prevent accidental pointers to the next block. Because of the extra overhead, we only do this for page size and above, where the overhead is minimal compared to the block size.
  So for those blocks, it looks like:
  |N*elemsize|padding|elem0|elem1|...|elemN-1|emptyspace|sentinelbyte|
  where elem0 starts 16 bytes after the first byte.
nothrow BlkInfo* `__getBlkInfo`(void* `interior`);
  Get the cached block info of an interior pointer. Returns null if the interior pointer's block is not cached.

  NOTE The base ptr in this struct can be cleared asynchronously by the GC, so any use of the returned BlkInfo should copy it and then check the base ptr of the copy before actually using it.

  TODO Change this function so the caller doesn't have to be aware of this issue. Either return by value and expect the caller to always check the base ptr as an indication of whether the struct is valid, or set the BlkInfo as a side-effect and return a bool to indicate success.

void `_d_arrayshrinkfit`(const TypeInfo `ti`, void[] `arr`);
  Shrink the "allocated" length of an array to be the exact size of the array.
  It doesn't matter what the current allocated length of the array is, the user is telling the runtime that he knows what he is doing.
  Parameters:

  TypeInfo `ti` | TypeInfo of array type
  void[] `arr` | array to shrink. Its .length is element length, not byte length, despite void type

size_t `_d_arraysetcapacity`(const TypeInfo `ti`, size_t `newcapacity`, void[]* `p`);
  Set the array capacity.
  If the array capacity isn't currently large enough to hold the requested capacity (in number of elements), then the array is resized/reallocated to the appropriate size.
  Pass in a requested capacity of 0 to get the current capacity.
  Parameters:

  TypeInfo `ti` | type info of element type
  size_t `newcapacity` | requested new capacity
  void[]* `p` | pointer to array to set. Its length is left unchanged.

  Returns:
  the number of elements that can actually be stored once the resizing is done
pure nothrow void[] `_d_newarrayU`(scope const TypeInfo `ti`, size_t `length`);
pure nothrow void[] `_d_newarrayT`(const TypeInfo `ti`, size_t `length`);
pure nothrow void[] `_d_newarrayiT`(const TypeInfo `ti`, size_t `length`);
  Allocate an array with the garbage collector.
  Has three variants:
  - `_d_newarrayU` leave elements uninitialized
  - `_d_newarrayT` initializes to 0 (e.g new int[])
  - `_d_newarrayiT` initializes based on initializer retrieved from TypeInfo (e.g new float[])
  Parameters:

  TypeInfo `ti` | the type of the resulting array, (may also be the corresponding array.ptr type)
  size_t `length` | .`length` of resulting array

  Returns:
  newly allocated array
void[] `_d_newarraymTX`(const TypeInfo `ti`, size_t[] `dims`);
void[] `_d_newarraymiTX`(const TypeInfo `ti`, size_t[] `dims`);
  Create a new multi-dimensional array
  Has two variants:
  - `_d_newarraymTX` which initializes to 0
  - `_d_newarraymiTX` which initializes elements based on TypeInfo

      void main()
      {
          new int[][](10, 20);
          // _d_newarraymTX(typeid(float), [10, 20]);

          new float[][][](10, 20, 30);
          // _d_newarraymiTX(typeid(float), [10, 20, 30]);
      }

  Parameters:

  TypeInfo `ti` | TypeInfo of the array type
  size_t[] `dims` | array length values for each dimension

  Returns:
  newly allocated array
pure nothrow void* `_d_newitemU`(scope const TypeInfo `_ti`);
pure nothrow void* `_d_newitemT`(in TypeInfo `_ti`);
  Allocate an uninitialized non-array item.
  This is an optimization to avoid things needed for arrays like the _arrayPad(size).
  - `_d_newitemU` leaves the item uninitialized
  - `_d_newitemT` zero initializes the item
  - _d_newitemiT uses a non-zero initializer from TypeInfo
  Used to allocate struct instances on the heap.

      struct Sz {int x = 0;}
      struct Si {int x = 3;}

      void main()
      {
          new Sz(); // _d_newitemT(typeid(Sz))
          new Si(); // _d_newitemiT(typeid(Si))
      }

  Parameters:

  TypeInfo `_ti` | TypeInfo of item to allocate

  Returns:
  newly allocated item
pure nothrow void* `_d_newitemiT`(in TypeInfo `_ti`);
  Same as above, for item with non-zero initializer.
void `_d_delmemory`(void** `p`);
void `_d_callinterfacefinalizer`(void* `p`);
void `_d_callfinalizer`(void* `p`);
void `rt_setCollectHandler`(CollectHandler `h`);
CollectHandler `rt_getCollectHandler`();
nothrow int `rt_hasFinalizerInSegment`(void* `p`, size_t `size`, uint `attr`, in void[] `segment`);
nothrow void `rt_finalize2`(void* `p`, bool `det` = true, bool `resetMemory` = true);
nothrow void `rt_finalize`(void* `p`, bool `det` = true);
  Backwards compatibility
void[] `_d_arraysetlengthT`(const TypeInfo `ti`, size_t `newlength`, void[]* `p`);
void[] `_d_arraysetlengthiT`(const TypeInfo `ti`, size_t `newlength`, void[]* `p`);
  Resize a dynamic array by setting the .length property
  Newly created elements are initialized to their default value.
  Has two variants:
  - `_d_arraysetlengthT` for arrays with elements that initialize to 0
  - `_d_arraysetlengthiT` for non-zero initializers retrieved from TypeInfo

      void main()
      {
          int[] a = [1, 2];
          a.length = 3; // gets lowered to `_d_arraysetlengthT(typeid(int[]), 3, &a)`
      }

  Parameters:

  TypeInfo `ti` | TypeInfo of array
  size_t `newlength` | new value for the array's .length
  void[]* `p` | pointer to array to update the .length of. While it's cast to void[], its .length is still treated as element length.

  Returns:
  *`p` after being updated
size_t `newCapacity`(size_t `newlength`, size_t `size`);
  Given an array of length `size` that needs to be expanded to `newlength`, compute a new capacity.
  Better version by Dave Fladebo: This uses an inverse logorithmic algorithm to pre-allocate a bit more space for larger arrays.
  - Arrays smaller than PAGESIZE bytes are left as-is, so for the most
  common cases, memory allocation is 1 to 1. The small overhead added doesn't affect small array perf. (it's virtually the same as current).
  - Larger arrays have some space pre-allocated.
  - As the arrays grow, the relative pre-allocated space shrinks.
  - The logorithmic algorithm allocates relatively more space for
  mid-size arrays, making it very fast for medium arrays (for mid-to-large arrays, this turns out to be quite a bit faster than the equivalent realloc() code in C, on Linux at least. Small arrays are just as fast as GCC).
  - Perhaps most importantly, overall memory usage and stress on the GC
  is decreased significantly for demanding environments.
  Parameters:

  size_t `newlength` | new .length
  size_t `size` | old .length

  Returns:
  new capacity for array
byte[] `_d_arrayappendcTX`(const TypeInfo `ti`, ref return scope byte[] `px`, size_t `n`);
  Extend an array by n elements.
  Caller must initialize those elements.
  Parameters:

  TypeInfo `ti` | type info of array type (not element type)
  byte[] `px` | array to append to, cast to byte[] while keeping the same .length. Will be updated.
  size_t `n` | number of elements to append

  Returns:
  `px` after being appended to
void[] `_d_arrayappendcd`(ref byte[] `x`, dchar `c`);
  Append dchar to char[], converting UTF-32 to UTF-8

      void main()
      {
          char[] s;
          s ~= 'α';
      }

  Parameters:

  byte[] `x` | array to append to cast to byte[]. Will be modified.
  dchar `c` | dchar to append

  Returns:
  updated `x` cast to void[]
void[] `_d_arrayappendwd`(ref byte[] `x`, dchar `c`);
  Append dchar to wchar[], converting UTF-32 to UTF-16

      void main()
      {
          dchar x;
          wchar[] s;
          s ~= 'α';
      }

  Parameters:

  byte[] `x` | array to append to cast to byte[]. Will be modified.
  dchar `c` | dchar to append

  Returns:
  updated `x` cast to void[]
byte[] `_d_arraycatT`(const TypeInfo `ti`, byte[] `x`, byte[] `y`);
  Concatenate two arrays into a new array

      void main()
      {
          int[] x = [10, 20, 30];
          int[] y = [40, 50];
          int[] c = x ~ y; // _d_arraycatT(typeid(int[]), (cast(byte*) x)[0..x.length], (cast(byte*) y)[0..y.length]);
      }

  Parameters:

  TypeInfo `ti` | type that the two arrays share
  byte[] `x` | left hand side array casted to byte[]. Despite this cast, its .length is original element length, not byte length
  byte[] `y` | right hand side array casted to byte[]. Despite this cast, its .length is original element length, not byte length

  Returns:
  resulting concatenated array, with .length equal to new element length despite byte type
void[] `_d_arraycatnTX`(const TypeInfo `ti`, scope byte[][] `arrs`);
  Concatenate multiple arrays at once
  This is more efficient than repeatedly concatenating pairs of arrays because the total size is known in advance.

      void main()
      {
          int[] a, b, c;
          int[] res = a ~ b ~ c;
          // _d_arraycatnTX(typeid(int[]),
          //    [(cast(byte*)a.ptr)[0..a.length], (cast(byte*)b.ptr)[0..b.length], (cast(byte*)c.ptr)[0..c.length]]);
      }

  Parameters:

  TypeInfo `ti` | type of arrays to concatenate and resulting array
  byte[][] `arrs` | array of arrays to concatenate, cast to byte[] while keeping .length the same

  Returns:
  newly created concatenated array, .length equal to the total element length despite void type
void* `_d_arrayliteralTX`(const TypeInfo `ti`, size_t `length`);
  Allocate an array literal
  Rely on the caller to do the initialization of the array.

      int[] getArr()
      {
          return [10, 20];
          // auto res = cast(int*) _d_arrayliteralTX(typeid(int[]), 2);
          // res[0] = 10;
          // res[1] = 20;
          // return res[0..2];
      }

  Parameters:

  TypeInfo `ti` | TypeInfo of resulting array type
  size_t `length` | .`length` of array literal

  Returns:
  pointer to allocated array

Copyright © 1999-2023 by the D Language Foundation | Page generated by Ddoc on Sun Jan 1 02:20:43 2023