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

Reply via email to