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.cerl_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_list
的checked 或unchecked 版本。真正构建列表的宏是
#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) 如何构建列表?的主要内容,如果未能解决你的问题,请参考以下文章
Erlang 的抽象机器 BEAM 中使用了哪些操作系统线程?