是否可以为移动的GC实现生成带有类型信息的ansi C函数?

是否可以为移动的GC实现生成带有类型信息的ansi C函数?,c,gcc,compiler-construction,garbage-collection,c99,C,Gcc,Compiler Construction,Garbage Collection,C99,我想知道有什么方法可以将键入信息添加到生成的C方法中。我正在将一种更高级的编程语言转换为C语言,我想添加一个移动垃圾收集器。然而,要做到这一点,我需要方法变量具有类型信息,否则我可以修改一个看起来像指针的原语值 一种明显的方法是将所有(原语和非原语)变量封装在一个结构中,该结构有一个额外的(enum)变量用于键入信息,但是这会导致内存和性能开销,传输的代码就是用于嵌入式平台的。如果我接受内存开销,显而易见的选择是对所有对象使用堆句柄,然后我就能够自由移动堆块。然而,我想知道是否有一种更有效更好的

我想知道有什么方法可以将键入信息添加到生成的C方法中。我正在将一种更高级的编程语言转换为C语言,我想添加一个移动垃圾收集器。然而,要做到这一点,我需要方法变量具有类型信息,否则我可以修改一个看起来像指针的原语值

一种明显的方法是将所有(原语和非原语)变量封装在一个结构中,该结构有一个额外的(enum)变量用于键入信息,但是这会导致内存和性能开销,传输的代码就是用于嵌入式平台的。如果我接受内存开销,显而易见的选择是对所有对象使用堆句柄,然后我就能够自由移动堆块。然而,我想知道是否有一种更有效更好的方法

我已经提出了一个潜在的解决方案,即根据变量是否为原语(我可以在transpiler中这样做),对它们进行预删除和分组,并在最后为每个方法添加一个偏移变量(我需要在扫描堆栈区域时能够准确地找到它),这告诉我非原语变量的开始和结束位置,所以我只能扫描它们。这意味着每个方法将使用额外的16/32位(取决于arch)内存,但是这仍然比堆句柄方法具有更高的内存效率

例如:

void my_func() {
  int i = 5;
  int z = 3;
  bool b = false;
  void* person;
  void* person_info = ...;
  .... // logic
  volatile int offset = 0x034;
}
我的目标是实现跨GCC编译器的通用功能,因此我关注的是:

  • 编译器能否根据变量在中的声明方式对变量重新排序 源代码
  • 我可以强制编译器在 方法的堆栈帧(使用volatile)
  • 扫描堆栈时,我能准确地找到偏移量吗

我希望避免汇编,这样这种方法(默认情况下)可以跨多个平台工作,但是我对方法持开放态度,即使它们涉及汇编(如果它们是可靠的)。

键入信息可能以某种方式编码在C函数名中;这是通过C++和其他实现方式调用的,

实际上,由于所有的C代码都是生成的,所以您可以决定采用不同的约定:生成长的C标识符,这些标识符实际上是唯一的,并且在程序范围内是随机的,例如
tiziw_7oa7eIzzcxv03TmmZ
,并将其键入信息保存在其他地方(例如某些数据库)。在Linux上,这种方法对and+(当然还有or)都很友好,因此在and项目中都使用这种方法

打字信息实际上是和s联系在一起的。例如,传递浮点或指针的命令不同

阅读或至少阅读p.威尔逊的调查。您可以决定使用带标记的整数而不是装箱,您可以决定使用保守的GC(例如)而不是精确的GC。在我的旧项目中,我为一个通用复制GC生成了C或C++代码。在和中都使用了类似的技术

既然你正在转机到C,也要考虑其他选项,比如OR。调查和调查

还研究其他Transpiler(C编译器)的实现,包括和

GCC编译器能否根据变量在源代码中的声明方式对其重新排序

当然可以,这取决于您所要求的优化。有些变量甚至不存在于二进制文件中(例如,那些留在寄存器中的变量)

我是否可以强制编译器将一些数据放入方法的堆栈框架(使用volatile)

最好生成一个包含所有语言变量的
struct
变量,并将优化留给编译器。你会感到惊讶(见报告草稿)

扫描堆栈时,我能准确地找到偏移量吗

这是最困难的,取决于很多因素(例如,如果在生成的C代码上使用
-O1
-O3
运行
gcc
;在某些情况下,最新的gcc(例如,在x86-64 Linux上)能够进行优化;通过使用
gcc-O3-S-fverbose asm
进行编译进行检查,然后查看生成的汇编程序代码)。如果您接受一些小型目标处理器和特定于编译器的技巧,这是可行的。请研究编译器的实现

发送给我(至
basile@starynkevitch.net
)一封讨论电子邮件。请在其中提及您的问题的URL

如果你想拥有一个高效的多线程复制GC,事情会变得非常棘手。问题是你能负担多少年的开发费用

如果您的语言中有异常,也要非常小心。您可以非常小心地生成对
longjmp
的调用

当然,你看我的

使用传输技术,邪恶在于细节

在Linux上(特别是!)请参阅我的程序。它演示了在Linux x86-64笔记本电脑上,实际上可以生成数十万个-ed

研究也实施了,至少是为了启发


<> P.S.一个完全架构中立和操作系统无关的转发器的梦想是一个幻觉。< /P> < P>类型信息可以以C函数的名称进行编码,这是由C++和其他实现方式调用的。 实际上,由于所有的C代码都是生成的,所以您可以决定采用不同的约定:生成长的C标识符,这些标识符实际上是唯一的,并且在程序范围内是随机的,例如
tiziw_7oa7eIzzcxv03TmmZ
,并将其键入信息保存在其他地方(例如某些数据库).在Linux上,这种方法对and+(当然还有or)都是友好的,因此在and项目中都使用这种方法

键入信息实际上与和有关。例如,传递浮点或指针的命令不同

阅读