Update to description of JEP 193: Enhanced Volatiles

Georges Gomes georges.gomes at gmail.com
Thu Oct 30 20:37:43 UTC 2014


Hi Paul

This looks really good this way. IMHO much better than previous proposal.
My only concern would be around refactorings. I guess it's only an IDE
problem...
But it needs to be manageable by IDE.
In that sense, Remy's proposal is slightly easier to manage by the IDEs no?

Regards
Georges



On Thu Oct 30 2014 at 8:59:13 PM Remi Forax <forax at univ-mlv.fr> wrote:

>
> On 10/30/2014 04:53 PM, Paul Sandoz wrote:
> > On Oct 30, 2014, at 4:47 PM, Remi Forax <forax at univ-mlv.fr> wrote:
> >
> >> On 10/30/2014 03:02 PM, Paul Sandoz wrote:
> >>> Hi,
> >>>
> >>> I have, with the help of Brian, Doug and John, updated the description
> of JEP 193: Enhanced Volatiles to reflect our current thinking based on:
> >>>
> >>> - the prototype implementation in valhalla;
> >>> - performance measurements of that implementation; and
> >>> - investigations related to signature polymorphic methods and
> invokedynamic.
> >>>
> >>> Thanks,
> >>> Paul.
> >> I seems that the changes are not propagated to the JEP yet,
> >> but there are available throught the corresponding bug:
> >>   https://bugs.openjdk.java.net/browse/JDK-8046183
> >>
> > Doh! thanks, i forgot to send the link out,
> > Paul,
>
> Here is a kind of counter-proposal because I think that there is a far
> simpler and more secure API.
>
> I think that instead of having to first instantiate an object
> (VarHandle) and then call a method on it,
> this can be done in one method.
>
> |public  class  Safe  {
>      @Intrinsic
>       public  staticObject  get(Object receiver, String fieldName) { }|
> ||     @Intrinsic
>       public  staticObject  getRelaxed(Object receiver, String fieldName)
> { }|
>      ||||@Intrinsic||
>      ||||public  staticObject  getAcquire(Object receiver, String
> fieldName) { }|||
> ||||||     @Intrinsic|||
>      ||||public  staticObject  getRelaxed(Object receiver, String
> fieldName) { }|||
> |||||     @Intrinsic||||
>      ||||public  staticObject  |||||||getSequential|(Object receiver,
> String fieldName) { }||
> |
> ||||||     @Intrinsic|||||
>      |||public  static  void  set(|||||||Object receiver, String
> fieldName|||, Object value) { }|
>      // and all other related variations
>
>    ...
> }|
>
> and this is how to use it:
>
> class  Foo  {
>
> |    int i;
>
>      public void acquire() {
>       |||boolean  r=  (boolean)Safe.compareAndSet(this, "i",  0,  1);
>       ...
> |    }
> }|
>
>
> At compile time, the compiler checks that a method Safe.compareAndSet
> with compatible parameter types exists
> but instead of generating an invokestatic, it generates an invokedynamic
> which uses the signature of the actual callsite.
> Using the actual types in the signature allows to avoid unnecessary
> boxing while
> keeping the typechecking rules simples (they are not changed !) as
> explained in the current draft of JEP 193.
>
> This API doesn't use any object to represent a field but uses a String
> as field name, you may think that
> 1) this mean that the field will be queried each time:
>      It doesn't has to. invokedynamic allow to install a dynamic check
> that will test that the string doesn't change
>      from one call to another. This check will be removed by the JIT
> because the string never change
>      (if the string change, the best is to throw a runtime exception
> like IllegalArgumentException explaining
>       that the field name must be a constant).
> 2) that using a String is not typesafe. Having a typesafe API is hard
> here, because the type of a field
>      is not something you can get at compile time, there is no field
> reference syntax in Java (no Foo::i),
>      so a String seems to be a good practical choice.
>
> And this API has a true real advantage compared to the VarHandle API,
> this API is inherently more secure.
> A VarHandle or any object representing a field will have some special
> security credential because it can access
> to a field without having to check at runtime if the field is visible
> from where the call is done (for performance reason).
>  From my own experience, it's too easy to make this kind of object too
> visible introduced a security hole without
> even doing something hard.
> By not reifying the access to a field as an object, the API is more
> secure with the restriction
> that a method can only access to the field of the class that contains
> the call to the API.
>
> In term of implementation, the compiler will generate this bytecode for
> the class Foo:
>
> ||class  Foo  {
>
> |    int i;
>
>      public void acquire() {
>       invokedynamic "compareAndSet" (Foo;String;II)Z
>         BSM =||java.lang.invoke.SafeMetaProtocol|||.bootstrap(
> Lookup;String;MethodType;MethodHandle)
>         ARG = MH(||||||Safe.compareAndSet(||Object;String;Object;Object;)
>       istore 0||||
>       ...
> |    }
> }|
>
> and from the JLS perspective, the compiler will recognize that the
> method inside Safe
> are special because there are annotated by an annotation that has a
> meta-annotation
> named BootstrapMethod that specifies the bootstrap method that should be
> used
> when emitting the invokedynamic call.
>
> ||||
>
> @BootstrapMethod(type=java.lang.invoke.SafeMetaProtocol.class,
> name="bootstrap")
> @interface Intrinsic {
>    // empty
> }
>
> cheers,
> Rémi
>
>


More information about the valhalla-dev mailing list