-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
WIP: on-stack gc allocation #8134
Conversation
👏. Very exciting to see big steps in this direction! |
079423d
to
cebf733
Compare
This is very good progress. But I would greatly prefer to do this in a way that does not require the |
that's not relevant to why i needed the |
The best form of stack allocation removes objects from the gc's reach |
that seems like that would require a better escape analysis pass than currently implemented. my thought is that this can be part of every expr (like also, my hope is that even though the GC can still see these, it saves a lot of effort on managing the allocation and free lists, especially where you are making a lot of small objects in a loop, and then quickly discarding them (since the GC also doesn't count these allocations in its totals) the main benefit of the incremental gc to be relevant here is the ability to have additional flag bits so that reflection can detect whether it has a stack or heap allocated value |
|
you make it sound like this global variable, which helps us malloc memory more efficiently and faster, would make everything slower due to the fact that in certain cases it could be even faster. and that having the general case would make implementing the special case harder, rather than easier. that just doesn't make sense to me. |
Could you explain more about why stack-allocated objects in this scheme get marked by the GC, requiring them to be unmarked eventually? After all, we do technically stack allocate lots of objects already without this issue. Maybe it would help to have the GC identify stack-allocated objects by address range, and not mark them? |
… is safe to do so
2a922d9
to
12fe44f
Compare
@JeffBezanson is this more inline with what you were wanting? (I know that many more optimizations are possible, the question is whether this represents a sufficient improvement to merge). |
6c7c7e3
to
1a4c02f
Compare
@vtjnash forgot about this. About the unmarking, we still have to scan through those stack allocated objects if they contain pointers to non stack memory ? Or do you only stack alloc things where no internal pointer escaped either ? Anyway, if we don't want to unmark them we could keep them marked all the time, as long as they are not the sole root of some other objects. If they are it's a bit more tricky, we could have the write barrier correct this but it requires a few modifications. |
probably both, or whatever you want to suggest |
I still think doing a conservative stack scan is likely a better approach to this, since it simplifies everything greatly (except in the scanning code itself, where the complexity belongs). |
+1 to conservative stack scanning. It seems to me that the chances of a random pointer-like value on the stack pointing exactly at an object large enough to care about freeing are pretty slim. @carnaval, didn't you have the conservative stack scanning approach largely implemented? Could we maybe try it out? |
Does this have any special handling of the finalizer or does it treat finalizer registration as a leak of object pointer? |
Only works with copy_stacks for now. The code is not used anywhere in codegen right now, it can be tested by using (:stknew typ args...) instead of :new. It is essentially the GC side of #8134 but without the global alloca stack & unmarking. Stack objects are kept marked (+young) permanently and are only scanned when coming from the owning task.
Only works with copy_stacks for now. The code is not used anywhere in codegen right now, it can be tested by using (:stknew typ args...) instead of :new. It is essentially the GC side of #8134 but without the global alloca stack & unmarking. Stack objects are kept marked (+young) permanently and are only scanned when coming from the owning task.
Only works with copy_stacks for now. The code is not used anywhere in codegen right now, it can be tested by using (:stknew typ args...) instead of :new. It is essentially the GC side of #8134 but without the global alloca stack & unmarking. Stack objects are kept marked (+young) permanently and are only scanned when coming from the owning task.
Only works with copy_stacks for now. The code is not used anywhere in codegen right now, it can be tested by using (:stknew typ args...) instead of :new. It is essentially the GC side of #8134 but without the global alloca stack & unmarking. Stack objects are kept marked (+young) permanently and are only scanned when coming from the owning task.
This is an improvement to the GC by pre-computing the GC escape analysis and entirely avoiding malloc when it is detected that the value cannot leave the stack frame. In it's current form, this appears to have no impact on the perf tests (as expected), since it doesn't trace values across function calls. Through the addition of a gc-analysis pass to inference.jl, this can be easily improved however. Where this is most helpful is in allocating boxes for ccall for very cheap, allowing the elimination of the
&
special syntax without performance penalty:Some initial function to be merged into base:
And an example:
No
allocobj
!TODO items:
x = new(T, getfield(x,2), getfield(x,1))