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

Fix Spesh Memory Leaks #941

Merged
merged 3 commits into from Sep 3, 2018
Merged

Fix Spesh Memory Leaks #941

merged 3 commits into from Sep 3, 2018

Conversation

bdw
Copy link
Contributor

@bdw bdw commented Aug 15, 2018

Spesh memory management is mostly simple except for the cases where it isn't.
We create spesh graphs in three ways:

  • From a spesh plan (i.e. the original bytecode)
  • From a spesh candidate, when inlining
  • From a known invocant, when we do not have a pre-existing specialization, when inlining.

When we generate a spesh candidate, we transfer ownership of allocated memory (e.g. for inlines, handlers, local type maps, spesh slots) to that candidate.

I found that we had a number of leaks coming from the third case, and that they were not straightforward to fix. The code assumed that inlinees came from spesh candidates and that the spesh candidate would therefore own the allocated memory, and not free it. But in the third case there is no spesh candidate, so those fields would leak.

I fixed this in two ways:

  • I made sure the inlinee graph was destroyed directly after inlining. The memory allocated by the region allocator (for the graph nodes that are merged into the inliner) is merged into the inliner region allocator.
  • I made sure we free all allocated fields, if and only if they are different from the ones allocated for the spesh candidate, so that we don't free those that are still in use.

Further, there is a fix for the FSA, so that the per-thread FSA freelist is cleaned up before freeing the memory of the FSA allocator as a whole.

If we cleanup the main thread (with it's per-thread FSA free list) after
cleaning up the FSA itself, that corresponds to a use-after-free, and we
should not.
After we've inlined a graph the inliner claims ownership over the memory
of the inlinee. With this patch, we destroy the original graph, which
should simplify lifetime management. The memory region list is merged with
the inliners graph so that the memory allocated for the inlinee nodes
is not freed.
Many allocated things either come from a spesh candidate or from
malloc (or realloc). Or they are assigned to a spesh candidate.
So the only way to really know if they are shared with a spesh candidate
(or static frame) is by checking if they are pointer-equal.

ASAN leaksanitizer is finally clean now for me.
@bdw bdw self-assigned this Aug 15, 2018
@bdw bdw requested review from timo and jnthn August 15, 2018 17:18
@AlexDaniel
Copy link
Contributor

Not sure how I feel about this in terms of the upcoming release. Less memory leaks is nice, but current moar+nqp+rakudo seems to be very stable and ready for the release. Merging this after the release sounds much safer to me, but I'd let @jnthn++ judge (I'll likely run toaster again a bit later, so we still have a chance to sneak some stuff in).

@coke
Copy link
Collaborator

coke commented Aug 15, 2018

+1 for post-release merge.

@jnthn
Copy link
Member

jnthn commented Aug 15, 2018

This looks good, but I agree it's probably most sensible to hold off until after the release, given it's not so trivial a change that I can say "this can't possibly be wrong". :-)

I have a couple of fixes that are in the same boat, fwiw: they fix deopt bugs that could theoretically occur on master (even if I didn't ever observe that happening), but are involved enough to carry a small risk of bringing their own issue. I'm happy to lean towards "devil we know" for both those fixes and this PR.

@bdw
Copy link
Contributor Author

bdw commented Aug 15, 2018

Thank you for the review. I will merge after the release.

Maybe for the future, it is better to have an (explicitly stable) pre-release branch than to lock development on master for an indefinite time.

@AlexDaniel
Copy link
Contributor

@bdw there is a post-release branch https://github.com/MoarVM/MoarVM/tree/postrelease-opts and you can merge this PR there.

@bdw
Copy link
Contributor Author

bdw commented Aug 16, 2018

That is literally the opposite of what I meant 😄
Either way, there is clear need for a branch that is 'open for development', and one that is stable for release.
So whether we call the one master and the other release, or the first 'postrelease' or 'development', and the second 'master', matters not very much, but we should probably do something for it.

@bdw bdw merged commit 96b88eb into master Sep 3, 2018
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.

None yet

4 participants