4 ms·
What would be the point? For example, what would you gain by having a C compiler that compiled to bytecode? It would be amazingly low level (C is just an assemb
by haspok 3y ago
What would be the point? For example, what would you gain by having a C compiler that compiled to bytecode? It would be amazingly low level (C is just an assembler with macros) yet amazingly non-performant. And of course you'd need to port libc et al to do anything non-trivial.
Don't forget that the JVM already has ways to communicate with native programs (JNI originally, but now a new FFI is in the works), so if you depended on any native code you could still use it.
- circuit10 3y agoThere are some advantages to it, at least if the bytecode is designed for it like WebAssembly is. You get portability and the loss of performance isn’t always that bad (WASM is maybe 70%ish as fast as native though that will depend on the workload and VM implementation), and you can reuse existing code. But the JVM isn’t really designed for it
- JohnFen 3y ago> WASM is maybe 70%ish as fast as native That counts as bad performance in my book.
- circuit10 3y agoIt’s not “amazingly non-performant” though. I assume the comment was thinking of something dynamic being run through an interpreter, which might be 1-10% as performant as native, but if you design the bytecode to be statically compilable and simple you can do a lot better. A 30%ish performance hit really isn’t bad for perfect cross-platform compatibility, determinism, and sandboxing for free, and the gap will close as it matures
- JohnFen 3y agoTrue, it's not amazingly poor. But the performance hit is very discouraging nonetheless.
- an-unknown 3y ago> What would be the point? For example, what would you gain by having a C compiler that compiled to bytecode? You would use it for the same thing that you can do with GraalVM Enterprise today: use native libraries written in C/Fortran/… from your other JVM code in a sandboxed way, without any possibility that the entire VM can crash due to memory corruption bugs in the C/Fortran/… code.
- kaba0 3y agoC is not too low-level at all. More low-level than Java, but no more than C++/Rust and other low-level languages. It’s hardly an assembler with macros in this century — it’s just the compiler at O3 doing so many mental acrobatics to make you believe that lie.
- haspok 3y agoI respectfully disagree. The mental model of writing assembly code and C code are very close - you can write the best C code if you think about how you would translate it to CPU instructions in your head. As a matter of fact, you said it yourself in a neighbouring thread that all C needs is a large array - I cannot imagine how can you get any lower than that: mapping almost 1:1 to the general memory model of a CPU executing instructions with some addressable memory. C++ has classes and templates, Rust has... a lot of things, they are definitely higher up in terms of abstractions built into the language.
- kaba0 3y agoRe C++/Rust: That’s expressivity, which is a different axis. C can’t control cache behavior, has no SIMD control, and no threading support (non-standard extensions doesn’t count) It maps well to PDP-11, but that has barely any similarity to modern CPUs. For what its worth, one might argue that C++ and Rust are lower level, as they can even control some of the above listed functions. As for “closeness to generated assembly”, as I said, at O3 the generated code doesn’t resemble the source at all — it might not even execute anything your wrote, it may have calculated the result at compile time and will just return the result/look it up in a map at runtime.
- dzaima 3y agoCache is a microarchitectural thing. There's no "controlling" it without explicitly knowing the properties of the caches of the running processor (size, latency, associativity, replacement policy, and whatever other quirks the hardware designers decide to add) and building your code around it, at which point nothing will be able to do it in a "standard" way (unless your standard hard-codes all the past, present, and future architectures, which, good luck). SIMD isn't really feasible to fully do in a standard way either. Without specific knowledge of the target, you can easily write SIMD-looking code that ends up slower than a scalar equivalent (e.g. if you do any non-constant shuffle on x86-64 pre-SSSE3 (i.e. the default), you'll get utterly awful results. On ARM NEON, a non-constant i32x4 shuffle is gonna be quite awful too). Threading - <threads.h> is a standard header, no? (granted, it doesn't appear to be used much, but it does exist) And, sure, every statement/expression/operator of yours doesn't end up always literally mapping to a single assembly instruction, but there's pretty much always a way it could, and quite often it does (and in the cases where it doesn't, it (usually) maps to something better than what you wrote). The main thing that doesn't is macros, but those are extremely trivially expandable.