On Tuesday, February 10, 2015 at 3:10:33 AM UTC+1, Jameson wrote: > > > > On Mon Feb 09 2015 at 7:59:20 PM <[email protected] <javascript:>> wrote: > >> >> >> On Tuesday, February 10, 2015 at 1:25:15 AM UTC+11, Simon Danisch wrote: >>> >>> Someone else has to answer this. I suppose it's not that bad. The >>> immutables are getting copied into the heap allocated memory from the >>> array, which should be fairly okay to mutate?! >>> But I seriously don't know the details on this. From a semantic >>> viewpoint it's definitely not okay! >>> >> >> WARNING: if you use unsafe practices to mutate an immutable object you >> enter the realms of undefined behaviour where the compiler/runtime can do >> anything it likes from sending your details to Scammers-R-Us to eating your >> shorts. Seriously if anything in the compiler optimisations, the runtime >> or garbage collector is changed to depend on immutables being, well, >> immutable, then it will cause unknown issues. And there is no guarantee >> that this hasn't happened already, just your specific code hasn't hit it >> ... yet. >> > Semantically, modifying a field of the immutable in the array is the same > as reading the whole thing, creating a new immutable with one field > modified, and writing it back to the array. The only thing you are likely > missing by hacking unsafe_store in this manner is a missing TBAA > annotation. That's fairly unlikely to matter here though (more about this > below). > >> >> Things that may be an issue include: >> >> 1. Julia now has a generational GC, does it assume immutable >> intergenerational pointers cannot change and doesn't rescan for them? >> > If your type contains pointers to other non-isbits types, you are probably > just as well off using a type. They are stored the same. Only `isbits` > types get the special inline-storage behavior. > > >> >> 2. Does the compiler generate the correct GC write barriers for unsafe >> operations and does it ignore immutables since they can't change? >> > No, it doesn't generate write barriers during calls to unsafe_store. > Although if you are writing bits data inside the immutable, it hardly > matters, since it doesn't need a write barrier to do that. > > >> >> 3. Do optimisations use copies of immutables as implied in the manual, so >> you don't mutate what you think you mutate? >> > Quite frequently. But if you mutate the array data, you mutate the array > data, no questions asked. What you definitely shouldn't do is grab a > pointer to your immutable (via pointer_from_objref) and try to mutate > that (but trying to grab a pointer to an immutable should become an error > in a future version of Julia anyways). > > >> >> 4. Does the generated code *not* use copies where it normally might, >> since it doesn't matter if the object is immutable, so again you don't >> mutate what you expected to? >> > This is possible. But it would require LLVM to decide that the array slot > itself couldn't have been re-assigned. Any intervening function call is > typically enough to block optimization on assuming the array data hasn't > changed. But TBAA (type-based alias analysis) is probably more likely to > bite you here, since LLVM won't consider the offset store to affect the > immutable type it lives inside. > >> >> 1. and 2. require the GC to run during the lifetime of the mutated >> immutable, maybe you have been lucky and that hasn't happened ... yet. >> >> 3. and 4. the behaviour depends on what other use is made of the >> immutable, again maybe you have been lucky. >> >> As for passing immutables to C, well was always going to be risky, C just >> doesn't understand immutable. If as suggested by Jameson mutables are >> layout compatible with C then the faster the habit of using immutables for >> that dies the better. >> > There's nothing risky about it. Types have the same layout and the same > behavior when getting passed to C regardless of whether they are declared > mutable or immutable. The ccall code hardly even checks the `.mutable` > field of the type (and that code hopefully will be deprecated soon, since > it doesn't really benefit the user). > > Often, however, `immutable` provides a better representation of a C-struct > and is therefore necessary for compatibility (unless the only usages of the > type are by-pointer). > > The updated documentation I mentioned above is part of my > ccall-enhancement pull request (which makes calling c functions that > require or return by-value structs actually work correctly). It can be read > at: > > https://github.com/JuliaLang/julia/blob/jn/ccall3/doc/manual/calling-c-and-fortran-code.rst > . >
I got a 404 error for that... can you please update the link? What has happened in the meantime to your PR (what is the #?) Thanks, Scott
