Hi Brian,

On 04/19/2015 02:06 PM, Brian Goetz wrote:
Thanks Remi.

I’d like to separate this discussion into two components: implementation and 
API.  Let’s talk about API first.  We did give a fair amount of thought to the 
sigpoly-vs-typesafe API question.

VarHandles allow you to abstract data access over several dimensions:
  - location kind: static field, instance field, array element, native pointer, 
etc
  - variable type: int, long, Object, etc
  - access kind: relaxed, ordered, volatile, etc

Both your approach and ours follow the same route for access kind: separate 
methods for each kind of access.

Your approach unrolls the variable type dimension as well; this is a tradeoff 
of client-side type-safety for API surface area.  There’s a valid discussion to 
be had here about the pros and cons of each.

Where the biggest difference is in location kind.  Your approach is built 
around “instance field” as being the preferred location kind, and levering the 
rest into that shape (i.e., use null as receiver for static fields.)  This is 
obviously great for instance fields, acceptable for static fields, bad for 
array elements, and probably not so good for native access.  To really get type 
safety, we’d probably have to add new interfaces for 
{Static,Instance,Array,Native}VarHandle, further increasing the surface area of 
the API.  Also, this is very different from the approach taken by MH, where 
there is a single polymorphic invoke method, rather than n*m*k methods for 
different combinations of (kind, type, access).

I've voluntarily separated the cases Static/Instance from the cases Array/Native because while I start to have a good idea on how to make former calls safe and fast, i have no good answer about the later calls. Moreover, the Array case has a non empty intersection with the Array 2.0 proposal and I'm not sure how those two things mix together.


The thing that pushed us over the edge is that value types are coming.  With value 
types, one can create type-safe, zero-cost, specialized wrappers for 
{Static,Instance,Array,Native}VarHandle<T> that wrap an underlying VH; because 
these wrappers can be values, they can provide type safety with no indirection or 
footprint costs.

All of these wrappers are specialized wrappers, or wrappers with a very specific semantics, some may have sense on value type, some don't, by example, a CAS require a specific hardware support so doing a CAS on any value type is impossible.

  So it seemed better to provide a simple, clean, low-level API now that 
doesn’t make any assumptions, let the early adopters (mostly us) deal with the 
fact that type safety comes at runtime (just as with MHs), and later provide a 
clean set of value wrappers on top of it.

You can provide generic entry points that fails at runtime but given that those API calls are already tricky, providing more methods but with a good javadoc is in my opinion better than a small clean API that nobody understand.

Anyway, the problem with your API is that for the purpose of the experimentation, you have to introduce a new concept inside Java the language, because currently the semantics of a polymorphic signature method is not the one you want for your API, and adding a new semantics just for the purpose of the experimentation doesn't worst the cost.

And if you still want to introduce a new semantics into Java, having a way to invoke invokedynamic in Java is the one you want :)

cheers,
Rémi

On Apr 12, 2015, at 4:54 PM, Remi Forax <fo...@univ-mlv.fr> wrote:

Hi guys,
I was about to write a blog post explaining why i don't like the way VarHandle 
are currently implemented when it occurs to me that providing another 
implementation may be a more efficient to discuss about implementation.

So my implementation is here,
  https://github.com/forax/varhandle2

the API is typesafe, the implementation is runtime safe and i get mostly the 
same assembly code using unsafe or this VarHandle API.

The idea is that there is no need to add more polymorphic signature methods, a 
good old Java method is enough if it using a method handle under the hood.
All the logic is described using method handles and the only logic written in 
Java is
1) when to create such method handle (the first time a method is called),
    it works like invokedynamic but the method handles are stable instead of 
being constant.
2) how to link all things together to do nullcheck, atomic operation and post 
operation (like fence or sum).

cheers,
Rémi




_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to