Erlang VM (BEAM) 如何构建列表?

Posted

技术标签:

【中文标题】Erlang VM (BEAM) 如何构建列表?【英文标题】:How is a list constructed by the Erlang VM (BEAM)? 【发布时间】:2015-10-27 07:26:42 【问题描述】:

当我在 Erlang 中创建列表时,例如在 Erlang shell 中:

1> [1, 2].

据我了解,在 vm 中,此列表将表示为单链表。

这个结构是如何由 Erlang 运行时创建的?例如,它是不是这样构造的:

    在内存中创建一个结构来保存一个终止列表的列表 在内存中创建一个结构来保存项目“2”,以及对空列表的引用。 在内存中创建一个结构来保存项目“1”和对项目“2”的引用。

我认为以下 c 和 erlang 代码是完成大部分工作的地方是否正确?

https://github.com/erlang/otp/blob/maint/lib/stdlib/src/lists.erl https://github.com/erlang/otp/blob/maint/erts/emulator/beam/erl_bif_lists.c https://github.com/erlang/otp/blob/maint/erts/emulator/beam/erl_term.h https://github.com/erlang/otp/blob/maint/erts/emulator/beam/erl_term.c

erl_term.h 包含一个宏 make_list 但我还没有找到实现...

【问题讨论】:

【参考方案1】:

Erlang VM 实现 BEAM 使用的技术可以追溯到 60 年代或 70 年代初的第一个 Lisp 实现。它有时被称为标记或类型指针。 (Tags) 这种技术不会将目标的类型存储在目标对象中(在这种情况下列出了 CONS),而是存储在指针本身中,或者在通常是指针的位置保存标量值。它可以节省大量内存,尤其是在 LISP 或 Erlang 等动态类型语言中。 (这在过去很有趣,当时内存非常昂贵,而现在当 CPU 变得比内存快得多并且缓存未命中/命中决定了算法的速度时,它又变得重要了。)作为一个缺点,它也会导致代码有点混乱。处理列表构造的整个部分从line 216 of erl_term.h 开始。你可以注意到有宏

#define _unchecked_make_list(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_LIST)

这是您正在寻找的宏。这是你的make_list。线

_ET_DECLARE_CHECKED(Eterm,make_list,const Eterm*)

在使用ET_DEBUG 编译时会对其进行检查。 (见more details。)宏make_list

#define make_list(x)        _ET_APPLY(make_list,(x))

只会调用make_listcheckedunchecked 版本。真正构建列表的宏是

#define CONS(hp, car, cdr) \
        (CAR(hp)=(car), CDR(hp)=(cdr), make_list(hp))

#define CAR(x)  ((x)[0])
#define CDR(x)  ((x)[1])

列表单元结构只是堆上的两个连续的Uint 值(hp),其地址被压缩标记(参见_unchecked_make_list)。我希望这个描述对你有所帮助。

【讨论】:

非常感谢您的出色回答。如上所述,我想更深入地了解 erlang 实现背后的基本概念。研究这个最小的 lisp 实现是否有助于我理解这些概念:gist.github.com/sanxiyn/523967 @ChrisSnow:这个最小的实现不使用标记技术。它使用类型存储在值对象gist.github.com/sanxiyn/523967#file-lisp-c-L46 中的普通结构 是否有您知道的使用标记技术的 lisp 实现的源代码? @CrisSnow:我不知道目前正在使用它的 LISP 实现。请记住,Erlang 和 LISP 之间存在更多差异,这使得该技术对 Erlang 更有利。最重要的是不可变性,这导致 Erlang 无法创建循环结构,从而导致不同的 GC,不需要任何多余的数据存储在值中。您可以在 Wikipedia 中找到有关 Tagged pointer 的文章,其中包含一些使用 Tagged architecture 的 LISP 机器链接。

以上是关于Erlang VM (BEAM) 如何构建列表?的主要内容,如果未能解决你的问题,请参考以下文章

BEAM(Erlang VM)是一种啥样的虚拟机?

从 Erlang 的列表中构建元组列表

Erlang 的抽象机器 BEAM 中使用了哪些操作系统线程?

erlang beam code文件怎么打开

重新编译Erlang的beam_disasm.file的输出

Erlang学习记录:app demo