4 ms·
The drop flag is only generated for types that implement the `Drop` trait. Furthermore, there's work [0] that will shift the drop flag out of the value onto the
by erickt 10y ago
The drop flag is only generated for types that implement the `Drop` trait. Furthermore, there's work [0] that will shift the drop flag out of the value onto the call stack frame, and then even only in situations where the compiler cannot statically prove that that the type will be dropped or not. This should save a lot of memory, and potentially open up a whole host of optimizations.
[0]: https://github.com/rust-lang/rust/issues/34398 https://github.com/rust-lang/rust/issues/34398
- millstone 10y agoYes, that's good. Swift also aggressively elides reference count modifications, and will stack-allocate class types if the lifetime can be proven.
- pcwalton 10y agoIt is silly to try to equate the drop flags with atomic reference counting on the heap. We could statically eliminate the drop flag entirely if we wanted to, with aggressive tail duplication. (It's not worth it, though, because the drop flag never shows up in profiles, so the code size bloat would be a cure worse than the disease.) Swift can never eliminate the runtime overhead of garbage collection. That's because, at a language level, Rust has static lifetime semantics and Swift has dynamic semantics.
- millstone 10y agoWhoa! I simply observed that both Rust and Swift eliminate their respective forms of reference counting when the lifetimes are statically known. The optimization is analogous, even if the nature of the reference counting is very different, as you say. To be sure, the proper Rust analog of Swift classes is Rc/Arc, not drop flags. > Swift can never eliminate the runtime overhead of garbage collection. That's because, at a language level, Rust has static lifetime semantics and Swift has dynamic semantics. Would you agree that Rust can never eliminate the runtime overhead of dynamic dispatch, because trait objects, at a language level, require dynamic dispatch? I would not agree: Rust programmers routinely eliminate it by sticking to the statically-dispatched areas of the language. Likewise, Swift programmers routinely avoid the runtime overhead of reference counting by using structs and not classes.
- Manishearth 10y ago> Would you agree that Rust can never eliminate the runtime overhead of dynamic dispatch, because trait objects, at a language level, require dynamic dispatch? I would not agree: Rust programmers routinely eliminate it by sticking to the statically-dispatched areas of the language. Likewise, Swift programmers routinely avoid the runtime overhead of reference counting by using structs and not classes. Sharing is something that is pretty necessary in programming; you are severely limited in what you can do without sharing. Trait objects are not, and are pretty rare in Rust. I often see people using enums over trait objects, and only sticking to trait objects for creating extensible APIs. Rust provides a way of sharing that does not involve any extra runtime overhead, which gets used often. Swift does have nice optimizations to value-typeify things, but without a finer-grained distinction between the kind of sharing you want to do to hint the compiler, this will be vastly limited as compared to Rust giving an explicit choice between borrows and Rc.
- millstone 10y agoWhen I hear sharing I think of shared ownership, and Rust steers you strongly away from that. See for example the awkwardness of global or thread-local variables in Rust. If you are referring to borrowing, Swift's answer is not class types, but inout. inout is not as flexible as Rust references, but it does not use reference counting. In most places where a Rust function would return a mutable reference, the analogous Swift function would take a closure that accepts that something as an inout.
- Manishearth 10y agoRight, I refer to the concept of sharing data without necessarily involving shared ownership. I am aware of inout, but like you said it's not as flexible. I find myself reaching for class types in Swift a lot more than in Rust. inout works for sharing that is extremely local, but more complicated sharing in larger codebases is hard.
- winstonewert 10y agoIt is silly to equate drop flags with atomic reference counting on the heap. It would be sillier to define automatic memory management in terms of conditional releases, (as you seem to have done) and then insist that Rust's conditional releases don't really count. Clearly, it is not really the fact that the releases are conditional that makes the difference. What is your actual definition of automatic memory management? What, in your view, is the actual semantic difference between a language that has automatic memory management and one that does not?
- Manishearth 10y agoSwift cannot implement ARC without conditional releases. Rust can. What Rust effectively does is compile an if statement into something a tiny bit more complicated (two if statements, really), in certain conditions. It doesn't need to. The if statement uses function-local information known statically, so it could be compiled in a different way without the drop flag. Basically, the condition already existed, Rust just inserts another one instead of piggybacking on the one inserted by the programmer. ARC needs new conditionals everywhere, and whether or not something will be cleared is often not obvious without looking at the whole program, and even then it could be undecidable. I can't answer for Patrick, but I don't see the term "automatic memory management" as useful as distinction, I look at it more as a spectrum, and Rust/C++ fall squarely on the "more manual" end of that.
- winstonewert 10y ago"I can't answer for Patrick, but I don't see the term "automatic memory management" as useful as distinction, I look at it more as a spectrum, and Rust/C++ fall squarely on the "more manual" end of that." I agree 100%. My objection was to the assertion that Rust and Swift were completely different because Swift was garbage collected and Rust was not. That's just not a helpful way of looking at it, because in many ways Swift's strategy is closer to Rust's then Java's.
- Manishearth 10y agoRight, which is why in my other comment I explained why the memory management strategies make them different, and make that difference important :) type system wise they are pretty comparable otherwise; As a Rustacean who is used to nice type systems, Swift's type system is a pleasure to work with.