-
-
Notifications
You must be signed in to change notification settings - Fork 608
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
Implement nogc framework (warn about GC allocations) #1886
Conversation
|
Don't forget library calls in the backend that may do some allocation! |
|
@ibuclaw do you have an example/ hint where I should start looking? EDIT: Seems I also forgot all built-in properties like |
|
closed till I find some time to actually finish this. |
|
Any update on this? |
|
I've had a look over and all cases are covered. Just needs to be cleaned up here or there. ... Oh, and rebased. |
|
@AndrejMitrovic thanks for reminding me about this pull request ;-) I've now moved all checks to the frontend and implemented the checks in the same way as There is one important question left: What should we do for these cases:
I need some feedback here. We have these options:
|
|
Regarding exceptions - druntime should really store exception instances in TLS and modify them before throwing instead of allocating new instance each time (unless I am missing some dangerous consequence) |
Exception chaining? |
|
(Sorry, seems I need to reopen the pull request to make github refresh the commits...) |
This is a deprecated feature, and currently only happens during |
|
@Dicebot some D code assumes that exceptions have 'unique' references. Exception chaining as mentioned by @yebblies is one thing, but fiber code also assume that (it stores a reference to the exception which is then rethrown in the thread context...) Getting exceptions completely GC-free is a difficult problem. If you only care about performance it's not a big problem as you want to avoid exceptions anyway. But if you don't have a GC and still want to use exceptions I only see two solutions:
|
|
Is exception chaining expected to work with But even for normal ones - what prevents from duplication the instance at point where it is supposed to be stored in chain? Fiber example should be OK assuming you don't yield in process of exception handling which is hardly a good idea anyway. I am a bit worried about it because this is relatively common pattern in performance-caring D code, including one that uses fibers. If there are any issues I may need to update some code base :) |
|
Updated, now handles BTW: What's the best way to add test cases for this pull? As |
|
Does nogc emit any diagnostics? You can usually check multiple diagnostics in a file (although I think there's an upper limit above which dmd will stop emitting diagnostics). grep for |
| return this; | ||
| } | ||
|
|
||
| if (elements && elements->dim != 0 && sc->func |
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.
This code looks like an exact duplicate of the one above it. Why not put it in a single place before if (type)?
| if (elements && elements->dim != 0 && sc->func | ||
| && sc->func->setGCUse (loc, "Array literals cause gc allocation")) | ||
| { | ||
| error("Can not use array literals in @nogc code"); |
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.
Array literals do not allocate if they are typed as static arrays.
|
Is this going to error on this? It really shouldn't. int main()
{
return [1, 2, 3][1];
} |
I agree with you. And I also think following case should also be allowed even in nogc semantics. enum n = () { auto a = [1,2,3]; return a[0] + a[1] + a[2]; }();Indeed to realize it, we should also implement a compiler feature to skip codegen for CTFE-only functions. But it will allow to use full power of D language in the compile-time code. |
Right now spec does not guarantee that this won't allocate unless I have missed some change to it so it should error until such guarantees are provided. |
The spec doesn't much of anything. Constfolding is an unavoidable part of D. |
|
This is certainly looking better. I do strongly suspect the visitor stuff can be done without inheriting from |
|
The only reason for inheriting int[4] arr = [1,2,3,4];This code is handled in e2ir.c, and it simply does not visit as Iain suggested would work, but DMD does allocate in these cases. |
|
What's the status of this? cc @jpf91 |
|
Updated. Merged all visitors into one. It seems I was wrong and dmd doesn't allocate in the array literal cases that were discussed at last, so there's no need to have separate visitors. |
|
As we have vcomlumns now I could improve the messages though.
Is there some pull request for this |
| @@ -2077,6 +2079,23 @@ void FuncDeclaration::semantic3(Scope *sc) | |||
| f->trust = TRUSTsafe; | |||
| } | |||
|
|
|||
| if (frequire) | |||
| checkGC(this, frequire); | |||
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.
I wonder whether the use of GC in the in/out clauses could/should be tolerated.
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.
I guess we could allow that, as GC is allowed in asserts as well and contracts are quite similar.
(At some point we might want to have some way to complain about all GC allocations though: If we implement the betterC idea at some point we'll have to error for all GC allocations, as the runtime won't even have a GC)
|
Nice though I didn't see where transitivity was checked on a hasty pass. Also there is no test of the actual |
|
@andralex this only adds (That's also the reason why there are no transitivity checks yet - they're not necessary with |
The following known allocations are intentionally not handled: * AssertExp * CmpExp * AssignExp: Calls _d_arrayassign * Hidden function errors: Are already deprecated * SwitchErrorStatement All these cases only allocate by throwing exceptions and disallowing them would impact user code a lot. In order to really solve such issues we need some way to throw exceptions without GC-allocation. Also not handled are indirect calls to user-defined functions which may allocate (calling postblits in array assignment for example). As this commit does not provide a way to mark a function as @nogc there's no way to know if such functions actually allocate. These indirect calls to user defined functions must be revisited when a @nogc attribute is introduced.
|
I like having |
|
This PR is incomplete, as for example it does not handle covariance/contravariance, but I'm pulling it as a good start. |
Implement nogc framework (warn about GC allocations)
|
Thanks. |
|
Not a fan of the half-baked |
|
There should be a spec pull (or well, a documentation pull) for the @gc/@nogc stuff. |
|
No, any trace of |
|
@klickverbot @Dicebot I'll open a pull request later today to remove the unnecessary @AndrejMitrovic there's no change to the spec, no attribute was introduced. There's some code which is not necessary for -vgc and I'll remove that. |
|
Thanks! |
|
The commentary blew up and is hard to keep track of, but is |
|
@jpf91: Thanks. It's not a big deal, but I'm afraid that if people finally decide to implement |
|
@klickverbot
My long-term plans are adding some simple function reachability analysis and implement |
|
I know that this PR is incomplete. I plan to work on improving it. |
|
Ekk, the MSVC project files weren't updated with this PR to include |
|
@Orvid: It would be great if you could find the time submit a pull request yourself, since not everybody here uses MSVC. |
This pull request adds the foundation for
nogcrelated functionality.It implements the basics to track if a function uses the GC in exactly the same way as
@safe/@trusted/@system.On top of that it adds
-vgcswitch which will print all implicit gc allocations, similar to-vtls-nogcswitch which will make all implicit GC accesses in the current module an errorIt currently does not help if functions like
GC.mallocor other functions which allocate are called. In order to detect this a@nogcattribute is needed. This pull requests implements the basics for@nogcincluding inference in templated methods, but it does not implement the@nogcattribute in the parser. I'll leave that for another pull request.The following known allocations are intentionally not handled:
All these cases only allocate by throwing exceptions
and disallowing them would impact user code a lot. In
order to really solve such issues we need some way to
throw exceptions without GC-allocation.
Also not handled are indirect calls to user-defined
functions which may allocate (calling postblits in
array assignment for example). As this commit does
not provide a way to mark a function as @nogc there's
no way to know if such functions actually allocate.
These indirect calls to user defined functions must
be revisited when a @nogc attribute is introduced.