On Wed, Jul 6, 2011 at 3:51 PM, Kenneth Uildriks <kennethuil at gmail.com>wrote:> On Wed, Jul 6, 2011 at 5:24 PM, Talin <viridia at gmail.com> wrote: > > > One approach would be to extend the current scheme to work with SSA > values, > > possibly using a new intrinsic. This is somewhat problematic because you > > can't really have a 'do-nothing' function on SSA values - the result of > the > > function is always going to be a copy of the value, not the original > value > > that was passed in. > > That doesn't seem like a huge problem. In the common case, the > "marked" SSA value and the "unmarked" original wouldn't be live > simultaneously. Uses of the unmarked version reachable from the mark > intrinsic can either be treated as a separate value or just left > undefined. > > It makes sense to also add an "unmark" intrinsic to define when the > SSA stack root goes out of scope >That's an interesting suggestion. I realized, however, that there's another advantage to using type-based marking rather than an intrinsic - it allows you to declare function parameters as stack roots. Depending on the calling convention, some of the parameters to a function will be located on the stack while others will be passed in registers. The ones already in memory ought to be able to be traced right where they are, but unfortunately there's no way to mark them as roots with the intrinsic method - which means that the frontend has to copy the parameters into an alloca and then mark that as a root. -- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110706/e68b0a7c/attachment.html>
On Wed, Jul 6, 2011 at 9:21 PM, Talin <viridia at gmail.com> wrote:> That's an interesting suggestion. > I realized, however, that there's another advantage to using type-based > marking rather than an intrinsic - it allows you to declare function > parameters as stack roots. Depending on the calling convention, some of the > parameters to a function will be located on the stack while others will be > passed in registers. The ones already in memory ought to be able to be > traced right where they are, but unfortunately there's no way to mark them > as roots with the intrinsic method - which means that the frontend has to > copy the parameters into an alloca and then mark that as a root. > -- > -- Talin >You don't need function parameters to be stack roots. You already have a stack root for those values in the calling function, right? Anyway, declaring the function parameters as stack roots means that you *must* pass pointers into the GC heap to those functions, whether or not it makes any difference to the function itself. That means, among other things, that optimization passes for turning GC allocations into pool allocations or local allocations become more complicated.
On 8 July 2011 00:07, Kenneth Uildriks <kennethuil at gmail.com> wrote:> You don't need function parameters to be stack roots. You already > have a stack root for those values in the calling function, right?Allowing parameters themselves to be stack roots allows an object that the calling function itself no longer needs to be collected once the called function (and everyone else, obviously) is done with it. It would also make tail calls easier to support: if parameters can't be stack roots, the called function would have to copy each pointer parameter to a stack root before doing anything else, or at least make sure the GC doesn't kick in before it does so. And it would have to do so whether or not it's ever actually tail called, because it (usually) can't know who calls it and how.> Anyway, declaring the function parameters as stack roots means that > you *must* pass pointers into the GC heap to those functions, whether > or not it makes any difference to the function itself. That means, > among other things, that optimization passes for turning GC > allocations into pool allocations or local allocations become more > complicated.Not if the GC is smart enough to ignore pointers that don't point into its heap. This shouldn't be that much extra work to achieve because it needs to figure out what object a pointer points to anyway (at least if interior pointers are allowed). If a pointer doesn't point to an object it knows about, it can simply be ignored. This does depend on the structure of the GC heap though: if the GC knows beforehand which pointers point into its own heap the "figure out what object it points to" algorithm may be able to use some tricks that aren't safe otherwise.