-
Notifications
You must be signed in to change notification settings - Fork 785
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
Conversation
…ed reference counting in incremental builder. Builders can only be invalidated by a type provider, not anything else.
src/fsharp/CompileOps.fs
Outdated
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) |
There was a problem hiding this comment.
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
.
There was a problem hiding this 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!
IB (
IncrementalBuilder
) was responsible for keepingTcImports
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:
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.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 whenTcImports
is about to be collected. Trust the GC.Remaining work: