4 ms·
Hmm, I am wondering how moving ownership would work in a GC'ed system. You could have arbitrarily many references to the moved object (or subobjects). The slide
by readittwice 10y ago
Hmm, I am wondering how moving ownership would work in a GC'ed system. You could have arbitrarily many references to the moved object (or subobjects). The slides say that an exception is thrown if an object of a different guild is accessed, but doesn't that mean that Ruby needs to check the guild at every object access?
Transfering ownership would probably also mean that Ruby not only needs to move one object but probably all subobjects recursively as well. I assume here that "moving" just means updating the guild field for each object.
Is this really feasible or wouldn't just copying the object be faster... I don't know of any system with gc that uses moving to transfer mutable objects between threads. Do such systems exist? Are there better ways of implementing this?
- chrisseaton 10y ago> The slides say that an exception is thrown if an object of a different guild is accessed, but doesn't that mean that Ruby needs to check the guild at every object access? Ruby is already checking the class of the object on every access. You could combine the guild and the class into a tuple and compare against that instead, so it adds no extra overhead. There is a paper at OOPSLA this year on doing just that http://2016.splashcon.org/event/splash-2016-oopsla-efficient-and-thread-safe-objects-for-dynamically-typed-languages http://2016.splashcon.org/event/splash-2016-oopsla-efficient...
- VeejayRampay 10y agoHi Chris, you've mentioned that you didn't like discussing design choices made or attempted to be made in Ruby in the past, preferring to focus on the technical side of implementing the language, so no worries if you don't want to weigh in on this, but how do you feel about this proposal in general, in terms of feasibility and upside/downside of the technique described?
- chrisseaton 10y agoYes I think it looks like a very sensible way forward. It will let the VM share and optimise a lot behind the scenes but provide the illusion of clean isolation between the parallel guilds.
- VeejayRampay 10y agoGlad to hear it. And thanks for all the hard work on the language I use every day.
- aardvark179 10y agoI can't comment on that paper since it doesn't appear to be available publicly yet, so I'm just going to talk about guilds as proposed. Adding a guild word to each object header is certainly a way to check ownership, and should be a cheap check to perform in the interpreter, but will obviously add some extra overhead to standard program execution. The thing that concerns me is that explicit ownership passing can introduce as many bugs as it solves. If I have two objects A and B, with A holding a reference to B, then I can freeze A and freely pass it between guilds, but if I try and touch B I'll get an error until that too has been frozen or its ownership transferred. The same problems occurs with explicit ownership transfer of a non-frozen A, which leaves you with the slower option of a deep-copy or a recursive ownership transfer which can have equally unexpected consequences. The "Ruby global data" slide also gives me the scream heebie-jeebies, as did finding stack overflow answers on how to unfreeze objects in MRI. I'm sure nothing will go wrong. :-) Having said all that, it probably can work nicely for the common use cases of balancing requests between a group of worker guilds where the request is a simple data structure whose ownership can be safely transferred, but it would be hard to do a general work stealing solution that was always safe.
- chrisseaton 10y agoIf you want to read the paper now I'm sure the authors will email you a draft.
- Roboprog 10y agoThings might generate an error, but they shouldn't just quietly munge stuff. God knows how many times I've had to clean up Java servlet stuff that cross-talked between threads. Yuck. I really hope they make this work in Ruby 3. If you program in a "functional" style anyway, this approach ("relaxed Erlang" style messaging) should fit nicely, as you would not be mutating things willy-nilly anyway. Of course, FP practices are a hard sell to the "OOP is the one true abstraction" (COBOL with encapsulated DATA DIVISIONSs) crowd.
- parenthephobia 10y ago> Adding a guild word to each object header is certainly a way to check ownership, and should be a cheap check to perform in the interpreter, but will obviously add some extra overhead to standard program execution It needn't be done this way. When an object is invalidated it could have its class pointer sneakily changed into a special "invalid object" class. Any attempt to do anything concrete with the object would be rebuffed, but normal object accesses wouldn't be changed. > The thing that concerns me is that explicit ownership passing can introduce as many bugs as it solves. If I have two objects A and B, with A holding a reference to B, then I can freeze A and freely pass it between guilds, but if I try and touch B I'll get an error until that too has been frozen or its ownership transferred. At least you get an error. Ultimately, the only alternative with comparable performance is sharing mutable references. That avoids this specific problem but is open to the full assortment of problems that can occur with concurrent mutable state, many of which aren't automatically detectable in principle. > The "Ruby global data" slide also gives me the scream heebie-jeebies, as did finding stack overflow answers on how to unfreeze objects in MRI. I'm sure nothing will go wrong. :-) If this proposal is adopted it's a simple matter to prohibit unfreezing objects that have been shared. :) Not that it would really be necessarily. If you're reaching into MRI's internals to unfreeze an object, then it's up to you to make sure that things don't break.
- Roboprog 10y agoHmm. I was under the impression that when you transferred the membership of an object, the "guild-local" or local lexical scope variable would be nulled out. Little to check if that's the case.
- ergl 10y agoThat's exactly what Pony (http://www.ponylang.org/ http://www.ponylang.org/) does. It has a gc, with all the actors in the system communicating through shared memory. It uses the concept of 'capabilities' to check the owner of any given reference and disallow read or write permissions to other objects / actors.
- rurban 10y agoWell, yes. But the pony capabilities system checks ownership at compile-time already and has a much faster GC and smaller objects (actors), while in Ruby 3 you defer the deadlock or race errors to run-time.
- _ko1 10y agoIt's magic of transferring membership. I omitted details on slides.