8199462: Use Reference.reachabilityFence in direct ByteBuffer methods
Reviewed-by: psandoz, vlivanov, plevart
This commit is contained in:
parent
f439f2166b
commit
de3604ea0c
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
package java.lang.ref;
|
package java.lang.ref;
|
||||||
|
|
||||||
import jdk.internal.vm.annotation.DontInline;
|
import jdk.internal.vm.annotation.ForceInline;
|
||||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||||
import jdk.internal.misc.JavaLangRefAccess;
|
import jdk.internal.misc.JavaLangRefAccess;
|
||||||
import jdk.internal.misc.SharedSecrets;
|
import jdk.internal.misc.SharedSecrets;
|
||||||
@ -420,10 +420,12 @@ public abstract class Reference<T> {
|
|||||||
* @param ref the reference. If {@code null}, this method has no effect.
|
* @param ref the reference. If {@code null}, this method has no effect.
|
||||||
* @since 9
|
* @since 9
|
||||||
*/
|
*/
|
||||||
@DontInline
|
@ForceInline
|
||||||
public static void reachabilityFence(Object ref) {
|
public static void reachabilityFence(Object ref) {
|
||||||
// Does nothing, because this method is annotated with @DontInline
|
// Does nothing. This method is annotated with @ForceInline to eliminate
|
||||||
// HotSpot needs to retain the ref and not GC it before a call to this
|
// most of the overhead that using @DontInline would cause with the
|
||||||
// method
|
// HotSpot JVM, when this fence is used in a wide variety of situations.
|
||||||
|
// HotSpot JVM retains the ref and does not GC it before a call to
|
||||||
|
// this method, because the JIT-compilers do not have GC-only safepoints.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -32,24 +32,40 @@ class XXX {
|
|||||||
#if[rw]
|
#if[rw]
|
||||||
|
|
||||||
private $type$ get$Type$(long a) {
|
private $type$ get$Type$(long a) {
|
||||||
|
try {
|
||||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(null, a, bigEndian);
|
$memtype$ x = UNSAFE.get$Memtype$Unaligned(null, a, bigEndian);
|
||||||
return $fromBits$(x);
|
return $fromBits$(x);
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public $type$ get$Type$() {
|
public $type$ get$Type$() {
|
||||||
|
try {
|
||||||
return get$Type$(ix(nextGetIndex($BYTES_PER_VALUE$)));
|
return get$Type$(ix(nextGetIndex($BYTES_PER_VALUE$)));
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public $type$ get$Type$(int i) {
|
public $type$ get$Type$(int i) {
|
||||||
|
try {
|
||||||
return get$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$)));
|
return get$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$)));
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#end[rw]
|
#end[rw]
|
||||||
|
|
||||||
private ByteBuffer put$Type$(long a, $type$ x) {
|
private ByteBuffer put$Type$(long a, $type$ x) {
|
||||||
#if[rw]
|
#if[rw]
|
||||||
|
try {
|
||||||
$memtype$ y = $toBits$(x);
|
$memtype$ y = $toBits$(x);
|
||||||
UNSAFE.put$Memtype$Unaligned(null, a, y, bigEndian);
|
UNSAFE.put$Memtype$Unaligned(null, a, y, bigEndian);
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
#else[rw]
|
#else[rw]
|
||||||
throw new ReadOnlyBufferException();
|
throw new ReadOnlyBufferException();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,6 +28,7 @@
|
|||||||
package java.nio;
|
package java.nio;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.lang.ref.Reference;
|
||||||
import jdk.internal.misc.VM;
|
import jdk.internal.misc.VM;
|
||||||
import jdk.internal.ref.Cleaner;
|
import jdk.internal.ref.Cleaner;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
@ -257,16 +258,28 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
}
|
}
|
||||||
|
|
||||||
public $type$ get() {
|
public $type$ get() {
|
||||||
|
try {
|
||||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(nextGetIndex()))));
|
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(nextGetIndex()))));
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public $type$ get(int i) {
|
public $type$ get(int i) {
|
||||||
|
try {
|
||||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(checkIndex(i)))));
|
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(checkIndex(i)))));
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if[streamableType]
|
#if[streamableType]
|
||||||
$type$ getUnchecked(int i) {
|
$type$ getUnchecked(int i) {
|
||||||
|
try {
|
||||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(i))));
|
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(i))));
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#end[streamableType]
|
#end[streamableType]
|
||||||
|
|
||||||
@ -282,6 +295,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
throw new BufferUnderflowException();
|
throw new BufferUnderflowException();
|
||||||
|
|
||||||
long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||||
|
try {
|
||||||
#if[!byte]
|
#if[!byte]
|
||||||
if (order() != ByteOrder.nativeOrder())
|
if (order() != ByteOrder.nativeOrder())
|
||||||
UNSAFE.copySwapMemory(null,
|
UNSAFE.copySwapMemory(null,
|
||||||
@ -297,6 +311,9 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
dst,
|
dst,
|
||||||
dstOffset,
|
dstOffset,
|
||||||
(long)length << $LG_BYTES_PER_VALUE$);
|
(long)length << $LG_BYTES_PER_VALUE$);
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
position(pos + length);
|
position(pos + length);
|
||||||
} else {
|
} else {
|
||||||
super.get(dst, offset, length);
|
super.get(dst, offset, length);
|
||||||
@ -311,7 +328,11 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
|
|
||||||
public $Type$Buffer put($type$ x) {
|
public $Type$Buffer put($type$ x) {
|
||||||
#if[rw]
|
#if[rw]
|
||||||
|
try {
|
||||||
UNSAFE.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
|
UNSAFE.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
#else[rw]
|
#else[rw]
|
||||||
throw new ReadOnlyBufferException();
|
throw new ReadOnlyBufferException();
|
||||||
@ -320,7 +341,11 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
|
|
||||||
public $Type$Buffer put(int i, $type$ x) {
|
public $Type$Buffer put(int i, $type$ x) {
|
||||||
#if[rw]
|
#if[rw]
|
||||||
|
try {
|
||||||
UNSAFE.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
|
UNSAFE.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
#else[rw]
|
#else[rw]
|
||||||
throw new ReadOnlyBufferException();
|
throw new ReadOnlyBufferException();
|
||||||
@ -346,7 +371,12 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
|
|
||||||
if (srem > rem)
|
if (srem > rem)
|
||||||
throw new BufferOverflowException();
|
throw new BufferOverflowException();
|
||||||
|
try {
|
||||||
UNSAFE.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$);
|
UNSAFE.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$);
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(sb);
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
sb.position(spos + srem);
|
sb.position(spos + srem);
|
||||||
position(pos + srem);
|
position(pos + srem);
|
||||||
} else if (src.hb != null) {
|
} else if (src.hb != null) {
|
||||||
@ -380,6 +410,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
throw new BufferOverflowException();
|
throw new BufferOverflowException();
|
||||||
|
|
||||||
long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||||
|
try {
|
||||||
#if[!byte]
|
#if[!byte]
|
||||||
if (order() != ByteOrder.nativeOrder())
|
if (order() != ByteOrder.nativeOrder())
|
||||||
UNSAFE.copySwapMemory(src,
|
UNSAFE.copySwapMemory(src,
|
||||||
@ -395,6 +426,9 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
null,
|
null,
|
||||||
ix(pos),
|
ix(pos),
|
||||||
(long)length << $LG_BYTES_PER_VALUE$);
|
(long)length << $LG_BYTES_PER_VALUE$);
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
position(pos + length);
|
position(pos + length);
|
||||||
} else {
|
} else {
|
||||||
super.put(src, offset, length);
|
super.put(src, offset, length);
|
||||||
@ -411,8 +445,11 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
int lim = limit();
|
int lim = limit();
|
||||||
assert (pos <= lim);
|
assert (pos <= lim);
|
||||||
int rem = (pos <= lim ? lim - pos : 0);
|
int rem = (pos <= lim ? lim - pos : 0);
|
||||||
|
try {
|
||||||
UNSAFE.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
|
UNSAFE.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
position(rem);
|
position(rem);
|
||||||
limit(capacity());
|
limit(capacity());
|
||||||
discardMark();
|
discardMark();
|
||||||
@ -497,19 +534,6 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
|
|
||||||
|
|
||||||
#if[byte]
|
#if[byte]
|
||||||
|
|
||||||
byte _get(int i) { // package-private
|
|
||||||
return UNSAFE.getByte(address + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _put(int i, byte b) { // package-private
|
|
||||||
#if[rw]
|
|
||||||
UNSAFE.putByte(address + i, b);
|
|
||||||
#else[rw]
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
#end[rw]
|
|
||||||
}
|
|
||||||
|
|
||||||
// #BIN
|
// #BIN
|
||||||
//
|
//
|
||||||
// Binary-data access methods for short, char, int, long, float,
|
// Binary-data access methods for short, char, int, long, float,
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package java.nio;
|
package java.nio;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.lang.ref.Reference;
|
||||||
import jdk.internal.misc.Unsafe;
|
import jdk.internal.misc.Unsafe;
|
||||||
|
|
||||||
|
|
||||||
@ -166,10 +167,16 @@ public abstract class MappedByteBuffer
|
|||||||
int count = Bits.pageCount(length);
|
int count = Bits.pageCount(length);
|
||||||
long a = mappingAddress(offset);
|
long a = mappingAddress(offset);
|
||||||
byte x = 0;
|
byte x = 0;
|
||||||
|
try {
|
||||||
for (int i=0; i<count; i++) {
|
for (int i=0; i<count; i++) {
|
||||||
|
// TODO consider changing to getByteOpaque thus avoiding
|
||||||
|
// dead code elimination and the need to calculate a checksum
|
||||||
x ^= unsafe.getByte(a);
|
x ^= unsafe.getByte(a);
|
||||||
a += ps;
|
a += ps;
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
if (unused != 0)
|
if (unused != 0)
|
||||||
unused = x;
|
unused = x;
|
||||||
|
|
||||||
|
@ -1749,11 +1749,6 @@ public abstract class $Type$Buffer
|
|||||||
|
|
||||||
abstract ByteBuffer slice(int pos, int lim);
|
abstract ByteBuffer slice(int pos, int lim);
|
||||||
|
|
||||||
// Unchecked accessors, for use by ByteBufferAs-X-Buffer classes
|
|
||||||
//
|
|
||||||
abstract byte _get(int i); // package-private
|
|
||||||
abstract void _put(int i, byte b); // package-private
|
|
||||||
|
|
||||||
// #BIN
|
// #BIN
|
||||||
//
|
//
|
||||||
// Binary-data access methods for short, char, int, long, float,
|
// Binary-data access methods for short, char, int, long, float,
|
||||||
|
@ -122,9 +122,11 @@ public class ReachabilityFenceTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference.reachabilityFence(o);
|
try {
|
||||||
|
|
||||||
return finalized.get();
|
return finalized.get();
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyFinalizeable {
|
private static class MyFinalizeable {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user