This contribution forms a partial solution to the problem detailed here - http://thevirtualmachinist.blogspot.ca/2011/07/subtle-issue-of-reachability.html .
In this context, this contribution provides "markers" such that a suitably "aware" compiler can reduce the chances of such a problem occurring with each of the Direct<Type>Buffer<RW><BO> objects and MappedByteBuffer object. The reachabilityFences may prevent crashes / exceptions due to cleaning up the backing memory before the user has finished using the pointer. Any compiler not suitably "aware" could be modified to make use of the "markers". I would like to pair with a sponsor to contribute this patch ... ------------------------------------------------------------------------------------------------------------------- diff -r d51e64840b4f src/java.base/share/classes/java/nio/Direct-X-Buffer-bin.java.template --- a/src/java.base/share/classes/java/nio/Direct-X-Buffer-bin.java.template Wed Jan 31 12:04:53 2018 +0800 +++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer-bin.java.template Thu Feb 01 11:30:10 2018 +0000 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -33,15 +33,21 @@ private $type$ get$Type$(long a) { $memtype$ x = UNSAFE.get$Memtype$Unaligned(null, a, bigEndian); - return $fromBits$(x); + $type$ y = $fromBits$(x); + Reference.reachabilityFence(this); + return y; } public $type$ get$Type$() { - return get$Type$(ix(nextGetIndex($BYTES_PER_VALUE$))); + $type$ y = get$Type$(ix(nextGetIndex($BYTES_PER_VALUE$))); + Reference.reachabilityFence(this); + return y; } public $type$ get$Type$(int i) { - return get$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$))); + $type$ y = get$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$))); + Reference.reachabilityFence(this); + return y; } #end[rw] @@ -50,6 +56,7 @@ #if[rw] $memtype$ y = $toBits$(x); UNSAFE.put$Memtype$Unaligned(null, a, y, bigEndian); + Reference.reachabilityFence(this); return this; #else[rw] throw new ReadOnlyBufferException(); diff -r d51e64840b4f src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template --- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Wed Jan 31 12:04:53 2018 +0800 +++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Thu Feb 01 11:30:10 2018 +0000 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ package java.nio; import java.io.FileDescriptor; +import java.lang.ref.Reference; import jdk.internal.misc.VM; import jdk.internal.ref.Cleaner; import sun.nio.ch.DirectBuffer; @@ -312,6 +313,7 @@ public $Type$Buffer put($type$ x) { #if[rw] UNSAFE.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x))); + Reference.reachabilityFence(this); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -321,6 +323,7 @@ public $Type$Buffer put(int i, $type$ x) { #if[rw] UNSAFE.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x))); + Reference.reachabilityFence(this); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -347,6 +350,7 @@ if (srem > rem) throw new BufferOverflowException(); UNSAFE.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$); + Reference.reachabilityFence(this); sb.position(spos + srem); position(pos + srem); } else if (src.hb != null) { @@ -413,6 +417,7 @@ int rem = (pos <= lim ? lim - pos : 0); UNSAFE.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$); + Reference.reachabilityFence(this); position(rem); limit(capacity()); discardMark(); @@ -505,6 +510,7 @@ void _put(int i, byte b) { // package-private #if[rw] UNSAFE.putByte(address + i, b); + Reference.reachabilityFence(this); #else[rw] throw new ReadOnlyBufferException(); #end[rw] diff -r d51e64840b4f src/java.base/share/classes/java/nio/MappedByteBuffer.java --- a/src/java.base/share/classes/java/nio/MappedByteBuffer.java Wed Jan 31 12:04:53 2018 +0800 +++ b/src/java.base/share/classes/java/nio/MappedByteBuffer.java Thu Feb 01 11:30:10 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, 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. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package java.nio; import java.io.FileDescriptor; +import java.lang.ref.Reference; import jdk.internal.misc.Unsafe; @@ -164,6 +165,7 @@ // is computed as we go along to prevent the compiler from otherwise // considering the loop as dead code. Unsafe unsafe = Unsafe.getUnsafe(); + Reference.reachabilityFence(this); int ps = Bits.pageSize(); int count = Bits.pageCount(length); long a = mappingAddress(offset); ------------------------------------------------------------------------------------------------------------------- Regards, Ben Walsh Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU