Unasafe.putOdered -> Unsafe.releasePut
Paul Sandoz
paul.sandoz at oracle.com
Mon Mar 2 11:54:57 UTC 2015
On Mar 2, 2015, at 12:07 PM, David Holmes <david.holmes at oracle.com> wrote:
> Hi Paul,
>
> This is more a question for core-libs and the users of this Unsafe API.
I wanted to check here first because of work done in [1] and because this is where there is most experience with the Unsafe implementation. I don't want to change the semantics of existing Unsafe methods.
Note that the VarHandle work will expose using release/acquire names, where the former implementation defers to Unsafe.putOrdered*, and the later to relaxed plus explicit load fence.
> Sometimes the implementation of unsafe doesn't exactly match the API, so we need to check what the intended API semantics are.
>
I believe things align naming-wise at least from eyeballing C2 code i.e. Unsafe.putOrdered* is a form of release-store like that of OrderAccess::release_store and Unsafe.storeFence is a form of release-fence like that of OrderAccess::release.
src/share/vm/opto/library_call.cpp:
bool LibraryCallKit::inline_unsafe_ordered_store(BasicType type) {
...
insert_mem_bar(Op_MemBarRelease);
insert_mem_bar(Op_MemBarCPUOrder);
// Ensure that the store is atomic for longs:
const bool require_atomic_access = true;
Node* store;
if (type == T_OBJECT) // reference stores need a store barrier.
store = store_oop_to_unknown(control(), base, adr, adr_type, val, type, MemNode::release);
else {
store = store_to_memory(control(), adr, val, type, adr_type, MemNode::release, require_atomic_access);
}
insert_mem_bar(Op_MemBarCPUOrder);
return true;
}
bool LibraryCallKit::inline_unsafe_fence(vmIntrinsics::ID id) {
// Regardless of form, don't allow previous ld/st to move down,
// then issue acquire, release, or volatile mem_bar.
insert_mem_bar(Op_MemBarCPUOrder);
switch(id) {
case vmIntrinsics::_loadFence:
insert_mem_bar(Op_LoadFence);
return true;
case vmIntrinsics::_storeFence:
insert_mem_bar(Op_StoreFence);
return true;
case vmIntrinsics::_fullFence:
insert_mem_bar(Op_MemBarVolatile);
return true;
default:
fatal_unexpected_iid(id);
return false;
}
}
src/cpu/x86/vm/x86_32.ad:
instruct membar_release() %{
match(MemBarRelease);
match(StoreFence);
ins_cost(400);
size(0);
format %{ "MEMBAR-release ! (empty encoding)" %}
ins_encode( );
ins_pipe(empty);
%}
...
instruct membar_acquire() %{
match(MemBarAcquire);
match(LoadFence);
ins_cost(400);
size(0);
format %{ "MEMBAR-acquire ! (empty encoding)" %}
ins_encode();
ins_pipe(empty);
%}
...
instruct membar_volatile(eFlagsReg cr) %{
match(MemBarVolatile);
effect(KILL cr);
ins_cost(400);
format %{
$$template
if (os::is_MP()) {
$$emit$$"LOCK ADDL [ESP + #0], 0\t! membar_volatile"
} else {
$$emit$$"MEMBAR-volatile ! (empty encoding)"
}
%}
ins_encode %{
__ membar(Assembler::StoreLoad);
%}
ins_pipe(pipe_slow);
%}
Paul.
More information about the hotspot-dev
mailing list