> Looking at Servo it appears that unsafe code is used all over the place including in very core parts:
That's a very misleading characterization. It's less than 1% of the code. And it should be in core parts: those are the parts that are carefully audited and the parts that safe abstractions are built around.
We need unsafe primarily for the FFI layer, just as you do in any language. Bindings to a JIT would be no less safe in Java. You just have to write "unsafe" to call FFI functions in Rust, because we want to make it easier to audit that code.
> combined with a lot of the auto-vectorisation optimisations being added at the moment by Intel it feels like at that point a performance competitive rendering engine written in entirely memory safe code would become realistic
Any compiler developer will tell you that pinning your hopes on autovectorization is a lost cause. And you need a lot more than SIMD to write a competitive browser engine. (SIMD isn't the reason we write unsafe.) What I'd like to know is how you propose to write a JIT in safe code, without trusting that the JIT is implemented correctly. There are ways to potentially do that in theory (proof carrying code), but they're way beyond anything you've mentioned.
It may be less than 1% of the code by lines, but it's a large codebase. My point was that simply searching for the word "unsafe" in the code threw up 21 pages of results. That's not a rarely used feature.
By "core code" I meant the first results are things like layout code, a file called string_list.rs, string_multimap.rs etc. That doesn't sound like stuff at the edges to me.
Any compiler developer will tell you that pinning your hopes on autovectorization is a lost cause
I didn't mean that's the only thing that's needed, I think value types would be by far the biggest needle-mover there. But there's quite a lot of auto-vectorisation going on in the latest JIT compilers, a surprising amount (some of it not released yet).
What I'd like to know is how you propose to write a JIT in safe code, without trusting that the JIT is implemented correctly
Obviously if you're compiling code, the compiler has to generate safe outputs. But take a look at how the Graal/Truffle frameworks do it. Graal is a JIT compiler implemented entirely in Java. It generates machine code that's then handed off to the JVM for execution. Truffle sits on top and uses aggressive partial evaluation to convert AST interpreters for dynamic scripting languages into JIT compilers automatically. They have a Javascript implementation that's comparable to V8 in speed, and you can interop with it through safe APIs. Again, the entire compiler/JIT stack is written entirely in a safe language: eventually the CPU jumps to the result, but the code itself is all written in a safe way.
I wrote the layout code you're talking about. There is no unsafe in the layout algorithms, just in the work-stealing deque and the logic to share DOM nodes over to the layout thread. You can think of both as low-level generic memory management primitives, essentially as a GC. We do not allow the layout logic to be unsafe.
As for string lists and such, those are core collections. Again, those are low-level primitives and relatively easy to prove safe. We should be migrating more of that code to the safe language, but it never causes problems in practice. That's because the "build simple abstractions out of unsafe primitives and keep the complicated code safe" approach works. (We have empirical evidence that it works, you know. There are incredibly few segfaults in Servo relative to any other browser engine we've worked on.)
I am convinced that writing in Java would not make the browser any safer. All you'd do is to move some unsafe code from the engine to HotSpot. The only real effect it would have is that the word "unsafe" would not appear as often in the code.
> It generates machine code that's then handed off to the JVM for execution.
And there is absolutely no difference between that and what Servo/SpiderMonkey does, because you're trusting the millions of lines of code in HotSpot. Servo is just being explicit about the lack of safety when touching the JIT.
That's a very misleading characterization. It's less than 1% of the code. And it should be in core parts: those are the parts that are carefully audited and the parts that safe abstractions are built around.
We need unsafe primarily for the FFI layer, just as you do in any language. Bindings to a JIT would be no less safe in Java. You just have to write "unsafe" to call FFI functions in Rust, because we want to make it easier to audit that code.
> combined with a lot of the auto-vectorisation optimisations being added at the moment by Intel it feels like at that point a performance competitive rendering engine written in entirely memory safe code would become realistic
Any compiler developer will tell you that pinning your hopes on autovectorization is a lost cause. And you need a lot more than SIMD to write a competitive browser engine. (SIMD isn't the reason we write unsafe.) What I'd like to know is how you propose to write a JIT in safe code, without trusting that the JIT is implemented correctly. There are ways to potentially do that in theory (proof carrying code), but they're way beyond anything you've mentioned.