英語版
このページの英語版を見る

rt.lifetime

このモジュールには、オブジェクトの寿命に関連するすべての関数が含まれている: アロケーション、リサイズ、デアロケーション、ファイナライズ。
License:
Distributed under the Boost Software License 1.0. (See accompanying file LICENSE)
Authors:
Walter Bright, Sean Kelly, Steven Schveighoffer

ソース rt/lifetime.d

void* _d_allocmemory(size_t sz);
ガベージコレクタを使ってメモリを割り当てる
DMDはクロージャの割り当てにこれを使う:
void f(byte[24] x)
{
    return () => x; // `x`はスタック上にある
}
Parameters:
size_t sz 割り当てるバイト数
Returns:
へのポインタ szバイトの、GCによって管理されている、初期化されていない空きメモリ。
Object _d_newclass(const ClassInfo ci);
新しいクラスのインスタンスを作成する。
メモリを確保し、フィールドに初期値を設定するが、コンストラクタは呼び出さない。
new Object() // _d_newclass(typeid(Object))
Parameters:
ClassInfo ci TypeInfo_Class オブジェクトのインスタンスサイズとコピーする初期バイトを指定する。
Returns:
新しく生成されたオブジェクト
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);
配列ブロックの確保された長さを設定する。 これは を呼び出す。
ブロック < PAGESIZE の場合、確保されたブロックは以下のようになる:
|elem0|elem1|elem2|...|elemN-1|emptyspace|N*elemsize|の場合。
最後に割り当てられる長さのサイズはブロックサイズに依存する:
16~256バイトのブロックは8ビット長である。
512~ページサイズ/2バイトのブロックは16ビット長である。
pagesize >= pagesizeのブロックでは、長さはsize_tであり、ブロックの先頭にある。 ブロックの先頭にある。 なぜこのようにしなければならないかというと、ブロックはもっと多くのページに広がる可能性があるからだ。 そのため、ブロックの長さがブロックの末尾にある場合は信用できない。 というのも、ブロックはさらにページが伸びる可能性があるからだ。 もし将来 将来、ブロックが共有されていないことを証明できれば、これを変更できるかもしれない。 しかし、それが重要かどうかはわからない。
長さを先頭に置くためには、ブロックが正しく整列されるように16バイトのバッファスペースを用意しなければならない。 のバッファスペースを用意しなければならない。 x86では、ある種の x86では、ある種のSSE命令は、データが16バイトにアライメントされていなければ動作しない。 さらに さらに、次のブロックへの偶発的なポインタを防ぐために、センチネルバイトが必要である。 余分なオーバーヘッドが発生するため、これはページ・サイズ以上の場合にのみ行う。 ブロック・サイズに比べればオーバーヘッドは最小である。
つまり、これらのブロックでは次のようになる:
|N*elemsize|padding|elem0|elem1|...|elemN-1|emptyspace|sentinelbyte|となる。
ここで、elem0は最初のバイトの16バイト後から始まる。
nothrow BlkInfo* __getBlkInfo(void* interior);
内部ポインタのキャッシュされたブロック情報を取得する。 内部ポインタの 内部ポインタのブロックがキャッシュされていない場合はnullを返す。

備考 この構造体のベースptrは、GCによって非同期にクリアされる可能性がある、 したがって、返されたBlkInfoを使用する場合は、それをコピーし、実際に使用する前にコピーのベースptrをチェックする必要がある。 この構造体のベースptrはGCによって非同期にクリアされる可能性がある。

TODO 呼び出し側がこの問題を意識する必要がないように、この関数を変更する。 問題である。 値で返し、呼び出し元が構造体が有効かどうかの指標としてベースptrを常にチェックするようにする。 を常にチェックすることを期待する。 をセットし、成功を示すboolを返す。

nothrow void _d_arrayshrinkfit(const TypeInfo ti, void[] arr);
配列の"割り当てられた" 長さを縮小して、配列の正確なサイズにする。
配列の現在のアロケートされた長さが何であるかは問題ではない。 ユーザーは、自分が何をしているかを知っていることをランタイムに伝えているのだ。
Parameters:
TypeInfo ti TypeInfo 配列型の
void[] arr 配列を縮小する。void 型であるにもかかわらず、.length はバイト長ではなく要素長である。
size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* p);
配列の容量を設定する。
配列の容量が、要求された容量(要素数)を保持するのに十分な大きさでない場合、配列は縮小される。 配列の容量が、要求された容量(要素数)を保持するのに十分な大きさでない場合、配列は適切な大きさにサイズ変更/再割り当てされる。 は適切なサイズにリサイズ/再割り当てされる。
要求された容量に0を渡すと、現在の容量が得られる。
Parameters:
TypeInfo ti 要素型の型情報
size_t newcapacity 要求された新しい容量
void[]* p 設定する配列へのポインタ。length は変更されない。
Returns:
リサイズが完了したら、実際に格納できる要素数。
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);
ガベージコレクタで配列を確保する。
3つのバリエーションがある:
  • _d_newarrayU要素を初期化しない
  • _d_newarrayT要素を 0 に初期化する (new int[] など)。
  • _d_newarrayiTTypeInfoから取得したイニシャライザに基づいて初期化する (例:new float[])
Parameters:
TypeInfo ti 結果の配列の型(対応するarray.ptr の型でもよい)。
size_t length .length結果の配列の
Returns:
新しく確保された配列
pure nothrow void* _d_newitemU(scope const TypeInfo _ti);
の非テンプレートバージョン。 core.lifetime.d_newitemTの非テンプレート版で 初期化を行わない。以下の場合に必要である。 rt.aaA.allocEntry.
Parameters:
TypeInfo _ti TypeInfo を割り当てるために必要である。
Returns:
新しく割り当てられたアイテム
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, scope const(void)[] segment);
nothrow void rt_finalize2(void* p, bool det = true, bool resetMemory = true);
nothrow void rt_finalize(void* p, bool det = true);
後方互換性
void[] _d_arraysetlengthT(const TypeInfo ti, size_t newlength, void[]* p);

void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p);
.length "プロパティを設定することで、動的配列のサイズを変更する。
新しく作成された要素はデフォルト値に初期化される。
2つのバリエーションがある:
  • _d_arraysetlengthT0に初期化される要素を持つ配列の場合。
  • _d_arraysetlengthiTから取得された 0 以外の初期化子の場合。TypeInfo
void main()
{
    int[] a = [1, 2];
    a.length = 3; // `_d_arraysetlengthT(typeid(int[]), 3, &a)`に引き下げられる
}
Parameters:
TypeInfo ti TypeInfo 配列の
size_t newlength の新しい値。.length
void[]* p .length 。 これはvoid[] にキャストされるが、.length は要素の長さとして扱われる。
Returns:
*p更新後
size_t newCapacity(size_t newlength, size_t size);
長さ sizeに拡張する必要がある。 newlength, に拡張する必要がある長さの配列が与えられたら、新しい容量を計算する。
Dave Fladeboによる改良版: これは、逆対数アルゴリズムを使用して、より大きな配列のために少し多めの領域を事前に割り当てる。 より大きなアレイのために少し多めにスペースを確保する。
  • PAGESIZEバイトより小さい配列はそのまま残される。
メモリ割り当ては1対1である。 追加された小さなオーバーヘッドは、小さな配列の性能には影響しない。 現在とほとんど変わらない)。
  • より大きな配列には、事前に割り当てられた領域がある。
  • 配列が大きくなるにつれて、事前に割り当てられる領域は相対的に小さくなる。
  • 対数アルゴリズムでは、より多くの領域を
対数アルゴリズムは、中型の配列に対して比較的多くの領域を割り当て、中型の配列に対しては非常に高速になる(中型から大型の配列に対しては 中規模から大規模の配列では、これは 少なくともLinux上では、C言語の同等のrealloc()コードよりもかなり高速であることがわかる。小さな配列は GCCと同じくらい速い)。
  • おそらく最も重要なのは、全体的なメモリ使用量とGCへのストレスである。
へのストレスは、要求の多い環境では大幅に減少する。
Parameters:
size_t newlength 新しい.length
size_t size 古い.length
Returns:
配列の新しい容量
byte[] _d_arrayappendcTX(const TypeInfo ti, ref return scope byte[] px, size_t n);
配列を n 個の要素で拡張する。
呼び出し側はこれらの要素を初期化しなければならない。
Parameters:
TypeInfo ti 要素の型ではなく)配列の型の情報。
byte[] px 追加する配列は、同じ.length を維持したまま、byte[] にキャストする。更新される。
size_t n 追加する要素数
Returns:
pxに追加された後
void[] _d_arrayappendcd(ref byte[] x, dchar c);
dcharchar[] に追加する。UTF-32 を UTF-8 に変換する。
void main()
{
    char[] s;
    s ~= 'α';
}
Parameters:
byte[] x を追加してbyte[] にキャストする。
dchar c dchar を追加する
Returns:
更新された xにキャストする。void[]
void[] _d_arrayappendwd(ref byte[] x, dchar c);
dcharwchar[] に追加する。UTF-32 を UTF-16 に変換する。
void main()
{
    dchar x;
    wchar[] s;
    s ~= 'α';
}
Parameters:
byte[] x キャストに追加する配列byte[] を修正した。
dchar c dchar をアペンドする
Returns:
更新された xにキャストする。void[]
void* _d_arrayliteralTX(const TypeInfo ti, size_t length);
配列リテラルを確保する
配列の初期化を呼び出し元に任せる。
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 結果の配列型
size_t length .length配列リテラルの
Returns:
確保された配列へのポインタ