[PATCH] Reduce Chance Of Mistakenly Early Backing Memory Cleanup
Ben Walsh
ben_walsh at uk.ibm.com
Thu Feb 1 14:55:42 UTC 2018
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
More information about the core-libs-dev
mailing list