Re: Make new Object() backward compatible

2021-05-09 Thread forax
- Mail original -
> De: "Brian Goetz" 
> À: "Remi Forax" , "valhalla-spec-experts" 
> 
> Envoyé: Dimanche 9 Mai 2021 17:04:31
> Objet: Re: Make new Object() backward compatible

>> The logical conclusion is that java.lang.Object is a parametric class with a
>> parameter saying if it should implement IdentityObject or not.
> 
> Magic hammer, meet nail :)

New tool, new tricks :)

Given that we want two classes for java.lang.Object, seeing them as one being a 
specialization of the other is not too outrageous.

> 
> To be explicit, what you're suggesting is something like
> 
>     class Object { ... }
> 
> where an identity class extends Object and a primitive class
> extends Object (and most interfaces remain parametric in ID.)

yes

> 
> Its conceptually elegant, and we've discussed it before; in theory
> parametricity could range over things other than types, such as
> constants, identity-ness, etc (e.g., the ref and val projections could
> be species).  But to apply it to a problem as prosaic as this seems like
> cracking a walnut with a two-ton bomb.  (I don't thing this is what you
> want to teach on day 1.)

It seems that you are thinking that i want to introduce a special syntax just 
for specializing java.lang.Object, I don't.

I'm not proposing to change to the source code of Object.java, only the 
bytecode.
The compiler will insert the SpecializationAnchor (and the attribute that adds 
the identity-ness) without needing any language support.

The VM can also dynamically insert the SpecializationAnchor, but modifying 
javac to get the bytecode we want seems an easier path.

Rémi


Re: Make new Object() backward compatible

2021-05-09 Thread Brian Goetz





The logical conclusion is that java.lang.Object is a parametric class with a 
parameter saying if it should implement IdentityObject or not.


Magic hammer, meet nail :)

To be explicit, what you're suggesting is something like

    class Object { ... }

where an identity class extends Object and a primitive class 
extends Object (and most interfaces remain parametric in ID.)


Its conceptually elegant, and we've discussed it before; in theory 
parametricity could range over things other than types, such as 
constants, identity-ness, etc (e.g., the ref and val projections could 
be species).  But to apply it to a problem as prosaic as this seems like 
cracking a walnut with a two-ton bomb.  (I don't thing this is what you 
want to teach on day 1.)





Make new Object() backward compatible

2021-05-09 Thread Remi Forax
I think there is a way to avoid all the issues we have with new Object().

The problem:
  We want to inject the interface IdentityObject on all classes that are 
neither a "no field" abstract class nor a primtive class.
  But java.lang.Object acts as a "no field" abstract class but it's not an 
abstract class.

Clearly, there are two java.lang.Object, the one which is the root of all 
classes (the "no field" abstract one) and the one which can be instantiated 
that should implements IdentityObject.

The logical conclusion is that java.lang.Object is a parametric class with a 
parameter saying if it should implement IdentityObject or not.

The "raw" version does not implement IdentityObject, that the one used when a 
class extends Object.
The parameterized version implements IdentityObject and is the one used by new 
Object()

So the classfile Object.class should contain a SpecializationAnchor, and being 
a "no field" class or not is an attribute that references the Anchor.

To maintain backward compatibility, when the VM sees the opcode NEW 
java/lang/Object, it adds a new constant pool entry of kind 
SpecializationLinkage that reference java/lang/Object with a constant asking 
for version that implements IdentityObject and rewrite NEW java/lang/Object to 
NEW Linkage(java/lang/Object).

Obviously, there is the bootstraping issue with the code in java.lang.invoke 
making the BSM working not be initialized at the time java.lang.Object need to 
be available, so the VM has to inject the binding early as if it was resolved 
by the BSM but i think it's workable.

When the VM starts, if there are some new Object() executedbefore the code of 
java.lang.invoke is ready, those code can be rewritten to use a special class 
defined in the JDK for that like
  package jdk.internal.whatever;
  class LockObject { }

Even if it's not strictly necessary, javac can be changed to emit the 
Linkage(java/lang/Object) each time a new Object() is needed to the rewriting 
by the VM described above need to be done only for the classfiles that are 
using previous versions.

I believe this change is fully source and binary compatible and nice property 
is that 
  new Object().getClass() == Object.class
is still true.

Rémi