Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed reference counting from IncrementalBuilder; now relies on GC. #6863

Merged
merged 11 commits into from
May 31, 2019

Conversation

TIHan
Copy link
Contributor

@TIHan TIHan commented May 25, 2019

IB (IncrementalBuilder) was responsible for keeping TcImports and itself alive using referencing counting.

Now this removes reference counting from IB.
Allows TcImports to dispose of type providers and binary readers when the GC is about to collect it by leveraging the finalizer, override x.Finalize () = ...

The main reason for doing this is that it removes complexity:

  • You had to worry about decrementing IB's reference count.
  • There was invasive checks spread throughout FCS about whether an IB was alive or not.
  • Calling into an IB or TcImports that was disposed would throw an assert and that's bad news. In uncommon circumstances, this could happen and it's unclear how it does.
    • It would more likely happen when we tried to evict IBs from the IB cache. This hurts our ability to get cache eviction for IBs working again, this time with in-memory cross project referencing.

Now, this is completely swept away. Lifetime is GC. If you want TcImports alive, you simply hold onto it. This will pave the path for a stateless / snapshot model for FCS as we will stop thinking about explicitly disposing of resources.


A few cons:

  • There are a few hacks to accommodate working with old type providers that had an enforced contract dictated by TypeProviderSDK's reflection code. See try use ReferencedAssemblies fsprojects/FSharp.TypeProviders.SDK#305. The reflection code has been removed and type providers that use the newer TypeProviderSDK will not be bound by such a contract.

  • One downside is that disposal is not deterministic. Type provider resources will not eagerly be disposed of. This isn't necessarily a problem; most of everything is on the GC and in Gen2 at this point anyway. It will mean that any native resources a type provider might have, will now take a bit longer for it to get cleaned up; but it's not going to be a problem as Dispose will eventually be called for a type provider when TcImports is about to be collected. Trust the GC.


Remaining work:

  • Tests

@cartermp cartermp mentioned this pull request May 26, 2019
10 tasks
static member BuildFrameworkTcImports (ctok, tcConfigP: TcConfigProvider, frameworkDLLs, nonFrameworkDLLs) =
cancellable {

let tcConfig = tcConfigP.Get ctok
let tcResolutions = TcAssemblyResolutions.BuildFromPriorResolutions(ctok, tcConfig, frameworkDLLs, [])
let tcAltResolutions = TcAssemblyResolutions.BuildFromPriorResolutions(ctok, tcConfig, nonFrameworkDLLs, [])

// Note: TcImports are disposable - the caller owns this object and must dispose
let frameworkTcImports = new TcImports(tcConfigP, tcResolutions, None, None)
let frameworkTcImports = new TcImports(tcConfigP, tcResolutions, None, None, tcConfig.typeProviderThread)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels a little weird to pass tcConfig.typeProviderThread like this when I can just get it off of tcConfigP? The reason was that when using tcConfigP in order to get a tcConfig, you needed a CompilationThreadToken, which wouldn't be available to me on Dispose.

Copy link
Contributor

@dsyme dsyme left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor comments, but basically this looks great!

src/fsharp/CompileOps.fs Outdated Show resolved Hide resolved
@TIHan TIHan merged commit 4a695e7 into dotnet:master May 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants