hg: mlvm/mlvm/hotspot: value-obj: first cut

Remi Forax forax at univ-mlv.fr
Wed Oct 17 11:12:01 PDT 2012


On 10/17/2012 05:23 PM, David Chase wrote:
> On 2012-10-16, at 5:14 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>
>> Frozen/locked is a runtime property, not a type property so it's harder
>> that that.
>> You have to do a frozen check at the beginning of the method and pray
>> that people
>> will only use it with frozen object and not a not frozen one because in
>> that case, you have to de-optimize.
>> Maybe, you can have two versions on the same method, one with the frozen
>> semantics and
>> one with the boxed one (this is what I have done in JDart).
> I'm still coming up to speed on this, but I thought that the entire point of having value objects
> is so that we would have a non-standard interface for all methods dealing with value objects.
> "Complex", boxed, is received as a single pointer to an object with headers and fields.
> "Complex", unboxed, is received as a pair of double.  The "frozen check" is punted to the caller,
> who in turn may have punted it to his caller, etc, potentially removing the need for all tests.
>
> Or did I read this wrong?
>
> The only place I see a need for a frozen check is when we are interoperating with legacy code
> that is not playing the frozen-object game, and that we want to run with complete legacy compatibility.
> In the case, the slow-and-boxed path also includes a frozen check -- if frozen, unbox the object,
> and head for the fast path, otherwise, stay slow.
>
> >From the notes (value-obj.txt) I see:
>
> 38 - the reference returned from the (unsafe) marking primitive must be used for all future accesses
> 39 - any previous references (including the one passed to the marking primitive) must be unused
> 40  - in practice, this means you must mark an object locked immediately after constructing it
>
> So, allocation of a value-object becomes something along the lines of
>
>    new java/lang/Integer
>    dup
>    iload ...
>    invokespecial java/lang/Integer.<init>(I)V
>    markingPrimitive
>
> But we can't rely on this, hence it is not a true type property.  But we could make it be as-if.
> I think I have to assume some sort of a marker class ("implements PermanentlyLockable").

A bit in the class header (equivalent to implementing 
PermanentLyLockable) means
you have now two classses, the one with the old semantics and the one 
with the new semantics.
If you can have them both at runtime, you make your inlining cache less 
efficient,
it's a problem I've had with PHP.reboot.
Marking the instance seems a better idea.

> Then in bytecode version N+1, the verifier enforces this for all types implementing PL, and
> all methods trucking in PL-implementing objects will by default generated unboxed entrypoints.
>
> Except when dealing with legacy code, it's as good as a type.

100% of the produced code until now is what you call 'legacy' :)

>
> For legacy code, I think we have options.  Simplest is just to box at the boundaries, with lazy
> compilation of boxed versions of PL-handling methods in modern bytecodes.  I'm trying to decide
> if we can do better with flow analysis; I think it has to be non-publishing in the PL types, in addition
> to the other properties.

You have to box and unbox a boundaries and because Java allows 
overriding, an interface can have
two methods one which is implemented with boxing semantics and an other 
which use the frozen semantics.
So you need stub codes in front of method similar to verified/unverified 
entry points.

>
> David

Rémi



More information about the mlvm-dev mailing list