3

小さいながらも強力な Java 仮想マシンである JamVM に 2 週間取り組んできました。

現在、メモリがどのように実装されているかを把握しようとしていますが、2 つの C の愚かな問題に悩まされています。

char *mem = (char*)mmap(0, args->max_heap, PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON, -1, 0);

--> -1 パラメータはファイル記述子を表しますが、これはどういう意味ですか? (私はすでに mmap man を読んだことがありますが、見つけられませんでした。おそらく私は誤解していました...)。

heapbase = (char*)(((uintptr_t)mem+HEADER_SIZE+OBJECT_GRAIN-1&)~(OBJECT_GRAIN-1)) HEADER_SIZE;

--> 1& とは? C仕様にはありません...

ありがとう、

ヤン

4

2 に答える 2

4

最初の質問への回答です。マニュアルページから。

MAP_ANONYMOUS が設定されていない限り、fd は有効なファイル記述子である必要があります。MAP_ANONYMOUS が設定されている場合、Linux では fd は無視されます。ただし、一部の実装では、MAP_ANONYMOUS (または MAP_ANON) が指定されている場合は fd を -1 にする必要があり、移植可能なアプリケーションはこれを保証する必要があります。

が使用されているため、-1MAP_ANONYMOUSです。

于 2011-06-17T13:32:40.327 に答える
2

メモリにマップする開いているファイルがある場合は、ファイル記述子を使用します。この場合、匿名のマップ (ファイルによってサポートされていないマップ) を作成しているため、ファイル記述子は必要ありません。fd匿名マップを無視する実装もあれば、-1 にする必要がある実装もあります。

2 番目の質問は構文エラーです (おそらくタイプミス)。おそらく次のようになります。

heapbase = (char*)(((uintptr_t)mem+HEADER_SIZE+OBJECT_GRAIN-1)
    &~(OBJECT_GRAIN-1)) - HEADER_SIZE;

その場合、OBJECT_GRAINは 2 の累乗になり、その累乗に合わせる方法です。たとえば、8 の場合は~(OBJECT_GRAIN-1)( ~7、これは) になり、値と AND 演算すると、その値をそれ以下の 8 の倍数に強制するために使用できます。~00...001112~11...110002

実際、これは間違いなくどこか (必ずしもあなたではない) の転記エラーです。なぜなら、ここから JamVM をダウンロードしてを調べるとsrc/alloc.c、次のようになるからです。

void initialiseAlloc(InitArgs *args) {
    char *mem = (char*)mmap(0, args->max_heap, PROT_READ|PROT_WRITE,
                                               MAP_PRIVATE|MAP_ANON, -1, 0);
    :
    << a couple of irrelevant lines >>
    :    
    /* Align heapbase so that start of heap + HEADER_SIZE is object aligned */
    heapbase = (char*)(((uintptr_t)mem+HEADER_SIZE+OBJECT_GRAIN-1)&
               ~(OBJECT_GRAIN-1))-HEADER_SIZE;

(あなたのバージョンには、転写の問題を示す-直前の も欠落していることに注意してください)。HEADER_SIZE

于 2011-06-17T13:34:42.380 に答える