3

我已经在 J​​amVM 上工作了两周,这是一个小而强大的 Java 虚拟机。

现在我试图弄清楚内存是如何实现的,但我遇到了两个 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

在回答你的第一个问题。从手册页

fd 应该是一个有效的文件描述符,除非设置了 MAP_ANONYMOUS。如果设置了 MAP_ANONYMOUS,则 fd 在 Linux 上被忽略。但是,如果指定了 MAP_ANONYMOUS(或 MAP_ANON),某些实现要求 fd 为 -1,并且可移植应用程序应确保这一点。

所以它是-1,因为MAP_ANONYMOUS正在使用。

于 2011-06-17T13:32:40.327 回答
2

当您有一个想要映射到内存的打开文件时,您可以使用文件描述符。在这种情况下,您正在创建一个匿名映射(一个不受文件支持的映射),因此不需要文件描述符。有些实现忽略fd匿名地图,有些要求它是-1。

第二个问题是语法错误(可能是错字)。它可能应该是这样的:

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

在这种情况下,OBJECT_GRAIN将是 2 的幂,这是与该幂对齐的一种方式。例如,如果它是 8,那么~(OBJECT_GRAIN-1)将是~7( ,即),当它与一个值进行与运算时,可用于将该值强制为小于或等于它的 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 回答