Hacker News new | ask | show | jobs
by int_19h 1356 days ago
Go doesn't have bytecode interpreter or JIT, but it still needs a VM, if only for green threads.
1 comments

Not every runtime environment is a virtual machine...
That's true, but I would argue that any runtime with custom green threads is.
Would you consider the C runtime a virtual machine once you link against libdill or use OpenMP? If not, why not? If so, well, then we just disagree on the term 'virtual machine'. My litmus test would be the presence of some sort of well-defined instruction set.
A quick look at libdill indicates that concurrency there is cooperative, so it's not green threads, either. So, that's just a library.

OpenMP uses OS threads, doesn't it?

When you have coroutines that can be preempted, without explicit yielding in the source code, that's the line at which I would consider it a VM. Basically, it's a VM if some userspace code (JIT, GC, scheduler etc) runs in the background and does things to your code.

I don't think there's a definitive interpretation of VM, so this is all arguable. But e.g. Java and C# are generally considered VM languages even if AOT-compiled, despite the fact that there's no bytecode involved past that point.

Historically, goroutines worked like in libdill, only passing control to the scheduler on certain calls. So did the Go runtime suddenly become a VM at version 1.14, when preemption was added?

And why the distinction between OS threads and green threads? Sure, in case of OS threads, it's not the language runtime that does the scheduling, but that just means that the operating system is now our virtual machine.

I would argue that what makes a language runtime a virtual machine is not the presence of a garbage collector, a jit compiler, or a scheduler (with or without preemption), but that it has well-defined semantics in terms of something that looks a bit like a real machine - hence the name! In particular, there's a set of instructions it understands. In case of the JVM, the instruction set is defined in the Java Virtual Machine Specification (with Java bytecode its representation), in case of the CLR, it's defined in the Common Language Infrastructure specification (with CIL bytecode its representation), in case of Smalltalk, it's defined in the Blue Book, in case of WASM, in the WebAssembly core specification.

Then you can sure list some differences between go's and JVM's runtime.
Most relevant in context of our discussion: The JVM is a (virtual) stack machine with its own instruction set and semantics specified in the Java Virtual Machine Specification. As far as I'm aware, something equivalent does not exist for Go, or as an internal implementation detail at best (some intermediate representation might potentially qualify if you squint at it the right way).
That's also an implementation detail, because the majority of execution time happens in native code with a native GC "managing it" the exact same way, not by interpreting abstract virtual machine instructions.
It's not an implementation detail, the interface is mandatory and public (Java bytecode).