-
-
Notifications
You must be signed in to change notification settings - Fork 421
Conversation
|
Could you please clean up the commits for this? Using |
|
Hm... this looks like it will fail if you try to reserve or use capacity on a shared array. I think if you remove the pure nothrow attributes from the template, it should become automatically pure/nothrow depending on the arguments passed. EDIT: I guess just removing pure should be fine, let the complier automatically decide whether it's pure or not. |
|
Also, some additional unit tests to show that it can be used in pure functions (and on shared arrays, even though I should have put them in originally...) would be good. |
|
Can you explain what the benefit is for splitting arraysetcapacity into two functions? |
|
I don't like the idea of adding to the cache on checking capacity. The cache is strictly for appending. If you are not appending, or extending the length, the cache should be left alone. This could be a good reason to split out the functions :) |
|
What's the difference between this and #147? |
|
Oh right, I forgot completely about that. One major difference (but is easily fixed in #147) is I didn't think about whether shared arrays could have capacity/reserve called on them. Another major difference is the splitting of the functions, but I'm not sure that's necessary yet. |
To the best of my knowledge, the compiler can not automatically decide whether it's pure or not (halting problem). That said, I'm starting to feel the need for conditional function attributes. (i.e. I'm pure if my caller is pure, or Func is pure, etc)
How often does one check the capacity of an array and then not call reserve/set the length/append?
In retrospect, fairly little. arraygetcapacity is a more streamlined and optimized (i.e. faster) but I don't know if that's worth the code duplication. In design, capacity is honestly nothrow while reserve can throw out of memory errors. In coding, I had thought getting a stripped down function working as pure nothrow would be easier. Doing so had the side benefit catch a Issue 7523 :)
Minor differences: I also added @trusted to capacity / reserve and nothrow attributes to various parts of lifetime.d which might improve the generated code. |
|
|
|
Accessing capacity can help you make a decision on whether to call assumeSafeAppend or not. a non-zero capacity means there is no valid data in the array after the given slice. |
|
So something like: if(arr.capacity > 0) {
arr.length = 0;
arr.assumeSafeAppend;
} else { ... }Personally I think appender(arr).clear;would probably be the better design choice, but I understand the need. |
|
I updated the patch with some unittests and removed the duplicate function and the extra cache updates. I also updated reserve to work with shared arrays; capacity worked as is. (which may be a DMD bug, but that's a separate issue.) |
|
This does not currently compile. I get src/rt/lifetime.d(698): Error: gc_extend is not nothrow when I try and compile it on 64-bit Linux. |
|
And from the looks of it, you're going to have to mark everything and its grandmother in the GC code |
|
We can probably get around this by marking the prototypes nothrow, they are extern(C). But in the end, we really should mark all the GC functions nothrow. |
|
Thank you, jmdavis, for testing the patch. I don't have time this weekend to look into the issue in detail, but will do so on Monday. If I might ask, where you using DMD 2.058 or 2.059 beta? |
|
@sandford I used the latest from head (that's what always should be used when submitting and testing pull requests, because that's what they get merged into) and that should match the current beta. |
|
@jmdavis Well, the head is always moving :) That said, I've updated to today's 2.059 beta and the head revisions of druntime and phobos. And it would appear that despite these functions not being marked nothrow, everything compiles on Win32. This is probably a compiler bug of some kind. I went ahead and added pure and nothrow to all of the GC function prototypes in lifetime.d. The pull request has been updated. |
|
I just tried to compile this again on my 64-bit Linux box, and I get this
MODEL=32 compiles fine, but MODEL=64 doesn't. So, there are now fewer compilation errors there there were before, but there are still compilation errors. And looking at the pull tester, it looks like this pull request is failing on all platforms. On the 64-bit plaftorms, it's failing due to the errors above, and on everything else, it's failing because it causes dmd's tests to fail. |
|
Thank you. I've only been testing with the phobos and druntime unittests, but I guess I should also get a more extensive test environment setup as well as a 64-bit platform (since it is behaving substantially differently). For now, I think I'll close this pull request until its ready on all systems. |
Patch for Issue 6333 - The 'capacity' function is not pure/nothrow/@safe.
http://d.puremagic.com/issues/show_bug.cgi?id=6333
Adds a new _d_arraygetcapacity function which is copy / pasted / streamlined from _d_arraysetcapacity. Both _d_arraygetcapacity and _d_arraysetcapacity now always update the block cache if it is okay to do so and the info block wasn't already present.
nothrow has been added to the definitions of the get/set functions and their dependents with the exception of the raw GC calls.
pure is enabled by a hack in object.di and object_.d which defines the extern(C) as being pure. (This same trick is used to cast the GC as pure nothrow inside lifetime.d). Technically, neither of these routines are strictly pure, but then again, neither is new T[n].