Yeah - I worked on that build team probably at the same place you did!
I think for a lot of users it's more important that the monorepo devenv be reproducible than be specifically local or specifically remote. It's certainly easier to pull this off when it's a remote devserver that gets regularly imaged.
> Yeah - I worked on that build team probably at the same place you did!
I did not work at that place but the story sounds very familiar – I believe there might have been a blog post about that remote development environment here on HN some time ago?
It is. A few key assumptions are based into the runtime, namely that the GC is a generational GC with contiguous regions and that the GC doesn't need a read barrier, among many other things. There's a bunch of assembly in the runtime that embeds some implementation details of the GC in a way that's hard to decouple. The API came about by untangling the GC and the rest of the runtime; it took a lot of work and the resulting API probably isn't what we'd choose if we were building a GC with it in mind from day 1, but the whole scheme of sideloading a GC works pretty well.
* https://github.com/immunant/c2rust - Inputs are C headers and source, outputs Rust code that is semantically equivalent to the C (modulo bugs, etc.)
* https://github.com/eqrion/cbindgen/ - Inputs are Rust source, outputs C/C++ headers that can be used to interoperate with the types and functions exposed by Rust
There is a top-level CLI verb called `refresh` that explicitly checks Pulumi's idea of the state of the world against the actual state of the world. If there's a diff, Pulumi reconciles the diff by updating its own state. `pulumi update` does not do this by default, but you can run `pulumi refresh` at any time to verify that your state has not drifted from reality.
The .NET GC hands out "allocation contexts" to every thread. An allocation context is little more than two pointers: the bump pointer and the bump pointer limit. If the runtime allocates too much and exceeds the bump pointer limit, it asks the .NET GC for a "quantum" of memory (usually a few KB). Each quantum that the GC gives out is guaranteed to be free of pinned objects - it'll find a contiguous block of memory to hand out.
Pins on the ephemeral segment are generally bad in that the quantum allocator has to be aware of them and squeeze objects between them.
The GC is not permitted to eagerly move pinned objects out of the heap. This is because there are two ways an object can be pinned: a pinning GC handle or a stack scan reports a local as pinned (e.g. the "fixed" keyword in C#). The GC does not know until a GC is already in progress that an object has been pinned and, at that point, it's not legal to move the object so it must stay where it is at the current point in time.
This /is/ geared heavily towards improving the .NET Core story. The purpose of this spec is to provide library authors with a set of APIs that they can expect will exist on .NET Standard 2.0-implementing runtimes (a list of which are supplied). This allows library authors to write code that works when deployed across multiple implementations and it allows application writers to trust that their dependencies will work on the platform of their choice.
Two major implementations of .NET Standard 2.0 are the traditional .NET Framework and .NET Core, so libraries targeting .NET Standard 2.0 can be used on both platforms without modification.
Now that Microsoft itself (and Mono + Xamarin) has multiple implementations of the CLI, it's spec'd the API surface area that is to be expected across the multiple implementations (since this is explicitly not covered in detail in ECMA335) - hence the name, .NET Standard.
When you throw an exception on the CLR, it will 1) walk the stack looking for candidate catch blocks, and 2) if it finds one, it will long jump to that catch block, destroying all stack frames between the frame that threw the exception and the frame for the function that contains the catch block.
Exception filters are a CLR feature that modify this process a little. Now, when an exception is thrown, it still walks the stack looking for candidate catch blocks, but whenever it identifies a candidate, it will call the exception filter function (a function from exn -> bool, where exn is the exception being caught by the Catch block). If the function returns false, the CLR will disregard this candidate catch block and continue searching. C# 6.0 merely added some syntax that exposed this functionality of the CLR, the language itself isn't doing this.
I think for a lot of users it's more important that the monorepo devenv be reproducible than be specifically local or specifically remote. It's certainly easier to pull this off when it's a remote devserver that gets regularly imaged.