You may want to look at Blazor Webassembly (https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blaz...) and Blazor United (https://devblogs.microsoft.com/dotnet/asp-net-core-updates-i...)
They scrapped the old CLR and started over with a new "CLR Core".
Then they ported the new CLR Core along with the framework BCL to webassembly and has the CLR running in the browser, upon which they built Blazor Webassembly.
So you can now target the CLR and have your code run in the browser.
And now they are making progress on Blazor Unified where components can start of as server-side rendered exclusively and transparently and automatically move to webassembly rendering within the same application or page. It really is crazy stuff.
Typescript is not the only thing going on in MS Engineering.
What you describe is the result of different philosophies/priorities. CLR focuses on static compile-time optimization, while the JVM is a highly dynamic construct with unmatched runtime analysis. In the 90s, there was a hope that with sufficient escape analysis, the need for user-defined primitives would vanish, which is why value types have not been done prior.
By themselves, accessing values via stack and not by reference is technically trivial. The problem lies in backporting that kind of stuff.
Maybe, it might also be the results of bad design decisions.
> highly dynamic construct with unmatched runtime analysis
As someone who spend quite a bit of time working on custom optimization around hotspot, i failed to see how anyone can describe the current state of the JVM ( J9 is a bit better) as unmatched. V8 and some some extend Julialang have much strong dynamic analysis.
> CLR focuses on static compile-time optimization
Sources ?
Most assuredly not. Back in the 90s, the cost of loading memory and performing a CPU instruction was essentially equal. Today, fetching data from RAM takes 100x longer than a CPU instruction. This makes locality of data absolutely crucial and is a consequence of computing throughput increasing, but latency remaining stagnant (think of it like a database transaction).
With focus on garbage collection, it made sense to throw everything into the heap and use runtime analysis to inline as much as possible. Nobody has forseen how such hardware fundamentals would change over the next decades.
As far as I'm concerned, the proposed JVM spec for value types is the most promising model I have seen anywhere. Instead of a binary choice between entities in the heap and values on the stack, you have a more granular control with incremental benefits and constraints.
> As someone who spend quite a bit of time working on custom optimization around hotspot, i failed to see how anyone can describe the current state of the JVM ( J9 is a bit better) as unmatched. V8 and some some extend Julialang have much strong dynamic analysis.
Didn't know that, probably worth looking into. Though, I wonder how much you can compare V8 and the JVM, given the fundamental difference between a static and dynamic language.
> CLR focuses on static compile-time optimization
I thought that was common knowledge. I mean, does the latest CLR perform any significant amount of runtime optimizations? From what I've read the CLR makes sue of cpu-specific instructions such as SIMD, but no cache/layout optimizations or any inlining during runtime.
https://learn.microsoft.com/en-us/archive/blogs/davidnotario...
As far as I know, Java offers no way to mark objects as stack-allocated, but C# does. Spans in C# allow programmers to produce subarrays without copying. Enums in C# are stack-allocated, unlike Java. So on, so forth. None of this is a huge deal for Java since some of the best GCs in the world are implemented atop the JVM. But I do think C# offers its workarounds when GC performance gets in the way.
The way I have seen it described somewhere: C# has a slightly higher performance ceiling, but a naive application may very well run faster in Java.