-
-
Notifications
You must be signed in to change notification settings - Fork 416
issue 14134 - Free of large array does not work #1168
Conversation
if(bic) | ||
bic.base = null; | ||
|
||
GC.free(info.base); | ||
} | ||
*p = null; |
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.
Should we set *p
to null
if it's not a GC array? How does one realize that delete didn't actually do anything?
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.
Not changing p if it's not freed sounds reasonable. Would that be a change to the language specification? Unfortunately the documentation is pretty short for "delete".
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've moved clearing the passed array into the conditional.
I can live with this, but I would wonder if we should add a check to ensure the array pointer points at the start of the array block. This would be consistent with how GC.free works. |
Yeah, this was also an option mentioned in the bug report comments. It seems only half-correct to check the start pointer, but not the length, though. Both indicate the caller might not actually "own" the array. |
I just notice that we cannot always check the length, because we only have type info for structs with dtors. |
But it's very normal to truncate with The point I was making is that we already have a requirement that GC.free will only work with a block pointer. However, at this point, I'm not too worried since
But in any case, we probably shouldn't spend too much time on this, see previous comment ;) |
I take this back, I see it doesn't actually! (though it could) So yeah, no way to check that unfortunately. |
Both GC.free and delete are unsafe operations exactly because they can delete memory they don't own. Requiring that delete is only called for a "complete" array doesn't make it any safer. |
auto bic = __getBlkInfo(p.ptr); | ||
auto info = bic ? *bic : GC.query(p.ptr); | ||
|
||
if (info.base && (info.attr & BlkAttr.APPENDABLE)) |
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.
Why did you add the appendable check?
I'm just wondering because I want to add thread local caches to the GC and need to sync any bits lazily as it's too expensive otherwise.
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.
Don't you need to know if APPENDABLE is there in order to verify the array to be deleted starts at the right point?
Edit: Forget this comment, he didn't implement that. I agree you don't need APPENDABLE.
That being said, why would this check be improper?
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.
Why did you add the appendable check?
Should we also free anything that was not allocated as an array by the runtime? Running dtors is dangerous in this case, though we could check flags only in case a type info is passed.
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.
Not sure, but I'd tend to check APPENDABLE too, because of this.
class Foo
{
static struct Bar { ~this() {} }
Bar[4] bars;
}
unittest
{
auto foo = new Foo;
auto bars = foo.bars[];
delete bars;
}
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.
Hm... that doesn't seem like the right correlation.
For instance:
auto foo = new Foo[2];
auto bars = foo[0].bars[];
delete bars;
I wonder if the type info to call destuctors shouldn't be read from the GC instead of relying on the static type. I didn't review that system that adds finalizer capability to structs. Is this what it is supposed to do?
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.
It could be used, but it would not allow to manually emplace structs into a byte array and delete them later:
auto foo = new ubyte[2*Bar.sizeof];
auto bars = cast(Bar[])foo;
delete bars;
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.
Well, in that case, you are on your own anyway :)
// delete bars;
bars = null; // let GC destroy... oops
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.
Well, that would not call any destructors. I think that might be expected.
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 don't know whether it's expected or not, but I think I might expect either possibility when I call delete.
What does make the most sense to me is to have delete be a "pre-emptive GC collection," so everything that is done via GC would be done via delete, except synchronously.
In any case, we are spending time debating a to-be-deprecated feature :) Nice to have these discussions though, for when we do actually have to create a replacement.
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.
debating a to-be-deprecated feature
It's probably TBD since 3 years, yet people keep using it.
issue 14134 - Free of large array does not work
@MartinNowak did you accidentally merge this? |
No, it fixes the issue for now. But I thought we might have some more ideas on the topic. |
OK, I just was confused with the lack of auto-merge ;) |
When writing pull requests that fix a bugzilla issue, write the title as:
so that the bugzilla issue ill be automatically marked as fixed when it gets pulled. |
I was not sure this is a fix, it was meant as a contribution towards a fix. Is calling |
https://issues.dlang.org/show_bug.cgi?id=14134
"delete slice" now destroys and frees the full array