4

X86-64、Linux、Windows。

ある種の「タグポインタの無料起動」を作成したいと考えてください。基本的に、同じ実際のメモリブロックを指すが、ビットが異なる2つのポインタが必要です。(たとえば、1ビットをGCコレクションまたはその他の理由で使用したい)。

intptr_t ptr = malloc() 
intptr_t ptr2 = map(ptr | GC_FLAG_REACHABLE) //some magic call

int* p = int*(ptr);
int* p2 = int*(ptr2);
*p = 10;
*p2 = 20;
assert(*p == 20)
assert(p != p2)
4

3 に答える 3

2

同じメモリ ( mmapPOSIX では Ignacio が言及しているようにMapViewOfFile、Windows では) を複数の仮想アドレスにマッピングすると、興味深いコヒーレンシー パズルが得られる場合があります (あるアドレスでの書き込みは、別のアドレスでの読み取り時に表示されますか?)。またはそうでないかもしれません。すべてのプラットフォームの保証が何であるかはわかりません。

より一般的には、ポインターに数ビットを予約し、必要に応じてシフトします。

すべてのオブジェクトが 8 バイト境界に整列している場合、ポインタの最下位 3 ビットにタグを格納し、逆参照する前にそれらをマスクするのが一般的です (thkala が言及しているように)。16 バイトや 32 バイトなど、より高いアラインメントを選択すると、タグ付けに使用できる最下位ビットが 3 ビットまたは 5 ビットになります。同様に、タグ付けのためにいくつかの最上位ビットを選択し、逆参照する前にそれらをシフトオフします。(たとえば、IEEE-754 float (2 23値) または double (2 51値)のシグナリング NaN にポインターをパッキングする場合など、非連続ビットが使用されることがあります)。

ポインターのハイエンドを続けると、x86-64 の現在の実装では、64 ビット ポインター (0x0000000000000000-0x00007fffffffffff + 0xffff800000000000-0xffffffffffffffff) のうち最大で 48 ビットしか使用されず、Linux と Windows は最初の範囲のアドレスのみをユーザー空間に配布します。安全にマスクできる上位 17 ビットを残します。(ただし、これは移植性がなく、将来もそのままであることが保証されているわけではありません。)

もう 1 つのアプローチは、「ポインター」を考慮するのをやめて、JVM が-XX:+UseCompressedOops. 512MB のプールを割り当て、8 バイトに整列されたオブジェクトを格納している場合、2 26個の可能なオブジェクトの場所があるため、32 の値にはインデックスに加えて 6 ビットの余裕があります。逆参照では、別の場所に保存されている配列のベース アドレスに、アラインメントを掛けたインデックスを追加する必要があります (すべての「ポインター」で同じです)。注意深く見ると、これは単に前の手法の一般化にすぎません (常にベースが 0 で、実際のポインターと整列します)。

于 2012-06-03T21:32:39.977 に答える
2

Linux では、同じファイルを 2 回 mmap() します。Windowsでも同じですが、そのための独自の機能セットがあります。

于 2012-06-02T06:23:43.823 に答える
1

むかしむかし、次の手法を使用してポインターに予備のビットを含める Prolog 実装に取り​​組みました。

  • アラインメントがわかっているメモリ領域を割り当てます。malloc()通常、4 バイトまたは 8 バイトのアラインメントでメモリを割り当てます。必要に応じて、posix_memalign()配置サイズが大きい領域を取得するために使用します。

  • 結果のポインターは複数のバイトの間隔に整列されますが、バイト単位で正確なアドレスを表すため、メモリ領域ポインターで定義によりゼロになる予備ビットがいくつかあります。たとえば、4 バイト アラインメントでは、ポインターの LSB 側に 2 つのスペア ビットが提供されます。

  • |これらのビットでフラグをOR ( ) すると、タグ付きポインターが作成されます。

  • メモリ アクセスにポインタを使用する前に、ポインタを適切にマスクするように注意している限り、まったく問題ありません。

于 2012-06-03T18:29:45.493 に答える