英文:
Suitability of D for writing a Tracing JIT Compiler?
问题
我想为我设计的编程语言编写一个解释器和追踪JIT。我已经有多年的C++编程经验,但我一直在思考也许有更好的新选择。在我使用C++的时候,我最让人沮丧的事情之一就是不得不使用头文件来处理笨拙的单遍编译器模型。问题是,并不是所有的语言都适合这个目的。对于我的追踪JIT,我需要能够将可执行代码写入内存,并让解释器调用该代码。我还需要生成的代码能够回调到宿主函数。
我开始研究Go,并发现该语言具有指针,但没有指针算术。这立即让我感到非常困扰。我可能想要编写自己的分配器和垃圾收集器。我需要严格控制我的语言对象在内存中的布局,并能够获取特定字段的地址并写入它们。除非有办法解决这个问题,否则Go似乎不够底层。
D语言似乎很有前途。它具有指针算术和调用D的ABI的清晰概述。我听说过很多好的东西。它还具有垃圾收集,这对于编译器编写很好,但我仍然有一些不确定的事情:
-
D是否有标准库可以将内存块标记为可执行?
-
如果我分配了一个我想要自己管理的大块内存,并且有一堆指针指向那里,这会对D的垃圾收集器造成问题吗?
-
根据你的经验,D与C代码的互操作性如何?加载C动态库并调用其中的函数是否相对容易?
最后,还有整个支持方面。在这里使用D的人,工具链有多好?有什么问题吗?有人在D中编写过JIT编译器吗?如果有,体验如何?
英文:
I'd like to write an interpreter and tracing JIT for a programming language I'm designing. I already have many years of experience programming in C++, but I've been wondering if perhaps newer alternatives might be better. One of the things I found most frustrating, back in my C++ days, was having to use header files to deal with the clunky one-pass compiler model. The problem is that not all languages are equally suited for this purpose. For my tracing JIT, I need to be able to write executable code into memory and have the interpreter call to that code. I will also need the generated code to be able to call back into host functions.
I started looking at Go and saw that the language had pointers but no pointer arithmetic. This immediately struck me as a huge issue. I may well want to write my own allocator and garbage collector. I will need to closely control the way my language objects are laid out in memory and be able to get the address of specific fields and write to them. Unless there's ways to deal with this, it kind of seems like Go fails to be low-level enough for my purposes.
The D language seems promising. It has pointer arithmetic and a clear outline of the ABI needed to call in and out of D. I've heard lots of good things about it. It also has garbage collection which is nice for compiler writing, but I still have a few things I'm not sure about:
-
Does D have standard libs that will allow me to mark chunks of memory as executable?
-
If I allocate a big chunk of memory that I want to manage myself, with my own GC, and have a bunch of pointers going into there, will this pose problems with D's garbage collector?
-
How well does D interoperate with C code, in your experience? Is loading C dynamic libraries and calling into them fairly easy?
Finally, there's the whole support aspect. For those who have used D on linux here, how good is the toolchain? Any issues? Has anyone written a JIT compiler in D, and if so, how was the experience?
答案1
得分: 5
-
我相信是这样的,如果我没记错的话,请参考
core.memory.GC
。 -
不,不应该。只需调用
malloc
或者你需要的其他函数,并确保GC不会看到它。 -
是的,与C代码进行互操作非常容易。
注意:你可能也不希望依赖GC,因为它不是“精确的”(即如果你运气不好,可能会泄漏内存)。但对于小块数据来说,通常没问题。
英文:
-
I believe so, see
core.memory.GC
if I remember right. -
No, it shouldn't. Just call
malloc
or whatever you need, and make sure the GC doesn't see it. -
Yes, it's pretty easy to interoperate with C code.
Caveat: You probably don't want to rely on the GC either, since it's not 'precise' (i.e. can and does leak memory if you're unlucky). But for small blocks of data it's usually fine.
答案2
得分: 4
Go允许指针算术运算,但是你必须导入unsafe
包来实现(或者使用C函数)。指针算术是常见的bug来源,Go还有其他机制,比如切片,提供了安全的方式来执行一些在C中需要指针算术的活动。使用unsafe
,你可以将任何指针转换为uintptr
,然后再转回来,而uintptr
是一个普通的数值类型,允许你进行算术运算。
英文:
Go does allow pointer arithmetic, but you must import the unsafe
package to do so (or use a C function). Pointer arithmetic is a common source of bugs, and Go has other mechanisms, like slices, which provide safe ways to do some of the same activities that require pointer arithmetic in C. With unsafe
you can cast any pointer to a uintptr
and back, and uintptr
is an ordinary numeric type, which allows you do do arithmetic.
答案3
得分: 2
已经有一个非常严肃的JIT编译器,是用D语言完成的。我强烈推荐你去看看http://lycus.org/,尤其是关于MCI项目的页面-http://github.com/lycus/mci。MCI文档会给你更多信息。正如你所看到的,MCI不仅仅是一个JIT,它还有自己的(比我见过的任何其他东西都好)IR、优化器、验证器等等...
英文:
There is already a JIT compiler, very serious one, done in D. I highly recommend taking a look at http://lycus.org/ , more specifically pages about the MCI project - http://github.com/lycus/mci . MCI documentation will give you some more information. As you will see, MCI is more than just a JIT, it has its own (better than anything else I have seen) IR, optimizer, verifier, etc...
答案4
得分: 2
我开始研究Go语言,并发现该语言具有指针,但没有指针算术。这立即让我感到非常困扰。
显然,你还没有尝试过这种语言。它在没有任何“指针算术”的情况下工作得非常好。如果你真的需要打破规则,总是可以使用“unsafe”包,它允许你做任何事情。
我可能想要编写自己的分配器和垃圾收集器。我需要密切控制语言对象在内存中的布局,并能够获取特定字段的地址并对其进行写入。
我自己还没有编写过分配器或垃圾收集器,但你可以获取结构体字段的地址。所有的Go数据结构都是简单易控制和理解的。请参阅http://research.swtch.com/godata进行简短介绍。此外,大小和对齐保证是语言的一部分,详情请见http://golang.org/ref/spec#Size_and_alignment_guarantees。如果没有其他办法,你总是可以转向C或汇编语言。
在我看来,你应该尝试实现一些小任务,看看Go是否符合你的要求。随时在http://groups.google.com/group/golang-nuts提问。
Alex
英文:
> I started looking at Go and saw that the language had pointers but no pointer arithmetic. This immediately struck me as a huge issue.
You, obviously, haven't tried the language. It works pretty well without any "pointer arithmetic". If you really need to bend rules, there is always "unsafe" package that will allow you to do anything.
> I may well want to write my own allocator and garbage collector. I will need to closely control the way my language objects are laid out in memory and be able to get the address of specific fields and write to them.
I haven't written allocatior or garbage collector myself, but you can take address of a field of a structure. All Go data structures are simple and easy to control and reason about. See http://research.swtch.com/godata for short introduction. Also size and aligment guarantees are part of the language http://golang.org/ref/spec#Size_and_alignment_guarantees. If nothing else, you could always jump into C or asm.
IMHO, you should try to implement some small task to see if Go fits your requirements. Feel free to ask questions at http://groups.google.com/group/golang-nuts.
Alex
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论