On 02/08/2014 06:52 PM, Brian Goetz wrote:
can you be a little more specific and provide the way
foo.volatile.compareAndSet is compiled with this example:
Hey, the JEP isn't even out of draft yet! Stop asking hard questions.
:)
The current strawman, though, is to expose direct (CP-ready) MH forms
(Lookup API / constant pool format TBD) for field get/set with fence,
array element get/set with fence, field CAS, and array element CAS.
Then the static compiler translates
foo.volatile.cAS(n,m)
as
LDC #MH[lookupFieldCASer(foo)]
aload n
aload m
invokevirtual "invokeExact"
wow, you bring out the big guns !
I see a big issue with this approach, it requires to change the JVM spec
each time you want to add a new operation.
Moreover, overloads of LDC are usually re-written by JVMs has private
opcodes, so why not directly use new opcodes,
it will take less space in the classfile too.
That said, having new opcodes is an interesting idea because it can
solve several issues that make by example Unsafe.compareAndSwap slower
than the C equivalent, Unsafe.compareAndSwapObject update card marks
even if it's not necessary and the pattern 'if
(foo.volatile.compareAndSet())' should be recognized by the JIT and the
information of the branch taken should be ignored (to avoid
de-optimization on re-try).
but updating the JVM spec each time you want a new operation seems a no
go for me.
Rémi
class Linked {
volatile Node head;
public void add(String element) {
for(;;) {
Node oldHead = head.volatile.get();
Node newNode = new Node(element, oldHead);
if (head.volatile.compareAndSet(oldHead, newNode)) {
return;
}
}
}
}
I will be very happy to see how you solve the different issues because
i've also spent some times thinking on how the .volatile syntax can be
implemented:
- what is the signature of the method compareAndSet, and how you
fight the generics erasure ?
- how do you remove the extra-level of indirection if head is a
VolatileXXX,
because accessing to the value is this.head.payload and not
this.head ?
- what LinkedClass.class.getDeclaredField("head").getType() returns ?
regards,
Rémi