Skip to content

Conversation

@TIHan
Copy link
Contributor

@TIHan TIHan commented Jan 17, 2020

This moves the disposal of some of the resources that TcImports uses to another object. The reason why is because we do not want TcImports itself to override Finalize as that causes TcImports to survive longer on collections. Instead, the object responsible for disposing will be surviving longer. Therefore, allows TcImports to be collected sooner.

let mutable ccuInfos: ImportedAssembly list = []
let mutable ccuTable: NameMap<ImportedAssembly> = NameMap.empty
let mutable disposeActions = []
let disposeActions = ResizeArray()
Copy link
Contributor

Choose a reason for hiding this comment

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

This remind me of something I was looking at:

type Trace =
{ mutable actions: ((unit -> unit) * (unit -> unit)) list }
static member New () = { actions = [] }
member t.Undo () = List.iter (fun (_, a) -> a ()) t.actions
member t.Push f undo = t.actions <- (f, undo) :: t.actions

this is used a lot in ResolveOverloading and is probably short lived so not the same kind of usage pattern.

I was wondering about the impact of all allocations happening in ResolveOverloading as many things are based on exception objects, I guess just as a convenience to make the error message, but this is only useful when failing to resolve an overload which is a corner case rather than the default.

This happens while checking each of the candidates, and there are several passes (using trace objects), since Exception is a very large object, generally larger itself than the few references we end up needing once the resolution failed to assemble our own exceptions, I intuit that lots of allocations could be saved there, but I also intuit that the refactoring of the data structures wouldn't be a low hanging fruit.

In any case, exciting to see the work you are doing dealing with allocations in the compiler 👍.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would wonder too. I've seen this kind of pattern as well in other places. It depends on what the use case is. You can think of this pattern like simply swapping state rather than changing it underneath (which is what ResizeArray) does.

For this PR in particular, using the list state swapping pattern is fine but I need a reference to the actual state without capturing TcImports inside the object doing the disposal. I would have to make this a ref cell which I didn't want, and chose ResizeArray instead.

@cartermp cartermp merged commit 45d9b1a into dotnet:master Jan 17, 2020
nosami pushed a commit to xamarin/visualfsharp that referenced this pull request Feb 23, 2021
* Move Finalize from TcImports to another object responsible for disposing of TcImports resources

* Use ResizeArray
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