On Thu, Oct 31, 2013 at 2:05 AM, Jonathan S. Shapiro <[email protected]>wrote:
> On Tue, Oct 29, 2013 at 10:24 PM, Ben Kloosterman <[email protected]>wrote: > >> I Think by the time you add a header you have added a lot of complexity >> for little gain. eg C Interop or mapping directly to structures such as IP >> headers become Impossible. You can add the header to the top but then you >> need to find the base object all the time and access it..certainly not >> elegant. >> > > In the usual implementation, the object reference points to the first > content word of the object, not to the header. I'm also not sure what the > interop problem really is here, since C doesn't have (and cannot express) > objects to begin with. Finally, when you are dealing with C you are dealing > with pointers, not object references. That's a whole different kettle of > fish, because pinning and liveness-dominance requirements apply in that > case. > > > But there is no usual implimentation for an internal object header.. where do you put them ? eg Obj Header Internal Header 1.. Internal Header 2.. Field1 Value type 1 Value type 2 Field 3 Here you can map the data onto C but you have variable sized object header.. Obj Header Field1 Internal Header 1.. Value type 1 Internal Header 2.. Value type 2 Field 3 Here you cant map the whole object onto a C object ( or say a network packet header) as the C object doesnt have the header so you need fancy marshalling avoiding it is one of the main drivers for embedded nonboxed arrays . > > The C# method of storing no interior references has some merit . Value >> types are copied by value , they can be passed by reference ( register) >> but are never stored as a reference. >> > > It helps to use "object reference" and "by reference" when you are > discussing the two together. They mean completely different things, and > it's really easy to get the discussion confused. > yep ,, we also need a better term for non boxed array ..as these need not be in an object maybe embedded array. And value types embedded objects ? > > Unfortunately, this is *exactly* the case we need to be concerned about, > and the C# solution doesn't help. From the implementation perspective, > passing by reference is just syntactic sugar for an [potentially interior] > object reference. You know that there is a dominating exterior object > reference that is live, so you don't need to *mark* the by-ref > references, but in a relocating collector you still need to relocate them. > That can be done with fat pointers, I suppose. As you note, one advantage > of by-reference is that it is a non-leaking reference, so you don't have to > worry about them propagating into the heap. > C# is relocating and I dont think uses fat pointers. Maybe because gen0 and gen1 collections ( which are fast ) still stop the world so they can just scan the stack and find these reference ( we have the object reference and object size ) so you can either go the fat pointer / slice route or maybe search the stack for these ( a bit like your find the block and work back but in this case you search the stackmap) > > >> Slices are interior pointers and have the same issue... >> > > I suspect that a slice is stored as a base pointer and an offset. > Yep .. and is needed for 32 bit but its considerably more efficient to use a mask in a 64 bit pointer . D went down the route of having a 3 seperate field slice and pretty much lost all the benefits. > > >> I still think at least for v1 embedded unboxed arrays should be ref types >> or value types restricted to having no references it makes things a lot >> more simpler and can be extended later... >> > > Except it doesn't meet the requirements for one of the early things I need > to build. > Java has no value types at all and is pretty fast , its not needed just an optomization .. Such an optomization ( and im guessing its the compiler ) can definetly wait till v2. You may find like C# that value types are very rarely used due to some unforseen reason which is why i carefully stated why they were not used in C# very often. > > >> Like the read barrier removal i take it the read locks are only needed >> while the collector is running... >> > > Read locks are required whenever two *mutators* may run concurrently and > the object is mutable. If no read lock is present, you can't detect > contention when one thread or the other upgrades to a write lock. > Obviously you don't need read locks on immutable objects. You're not > locking out the collector here. > Which means in a single threaded context ( with the collector on another thread) if it can be identified you dont need the lock. > > > "*read* references to the same object in the same mutator's current >> call frame to become dead" sounds pretty bad... >> > > It's not that bad, but thanks for saying this, because it made me realized > I said the wrong thing. They aren't dead, but they have to be checked for > forwarding. The simple solution is just to move the write barrier as far up > as you can, because then the references are known-good. > > For a while, I thought this might eliminate the need for read barriers > altogether, but I was mistaken. In case it sparks something, here was the > thought: > > The intuition was that forwarding doesn't matter until the first mutate. > Either the first mutate happens on another thread (in which case you'll > later take a read or write lock) or the mutate is performed on *your* thread. > When a write barrier encounters a forwarded object, it performs a > forwarding check on the entire current frame and installs a stack barrier. > > > The missing part of this story is that it doesn't address forwarded > pointers that get loaded out of objects residing in the heap. If you have > to do read locking, you can deal with it then, but otherwise those remain > an issue. Note that taking a read lock amounts to a read barrier. > > > So how does it remove the read barrier ? Isnt checking the lock ( not just taking it ) a read barrier ? Its very complex and im struggling to follow it ( as i dont have time to read up on all this at the moment) but it seems strange to me that such an expensive mechanism (read barrier /locks) is needed for something that runs so rare and mainly to assist in defragmentation of the heap ( except for the nursery the moves are very low) Is the treatment worse the disease (fragmentation causing extra memory ) . Isnt a simple but short stop the world almost as effective , and for the Nursery sweep in parralel ? Then you only need a write barrier for heap objects references to Nursery which is pretty cheap. Possibly you can remove most of the Nursery pauses by using a write barrier and relying on Thread local nurseries ( we discussed some mechanisms ) . Ben
_______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
