--- old/src/java.base/share/classes/jdk/internal/misc/Unsafe.java 2018-08-20 11:53:44.610447131 +0100
+++ new/src/java.base/share/classes/jdk/internal/misc/Unsafe.java 2018-08-20 11:53:44.320446267 +0100
@@ -918,6 +918,89 @@
checkPointer(null, address);
}
+ /**
+ * ensure writeback of a specified virtual memory address range
+ * from cache to physical memory. all bytes in the address range
+ * are guaranteed to have been written back to physical memory on
+ * return from this call i.e. subsequently executed store
+ * instructions are guaranteed not to be visible before the
+ * writeback is completed.
+ *
+ * @param address
+ * the lowest byte address that must be guaranteed written
+ * back to memory. bytes at lower addresses may also be
+ * written back.
+ *
+ * @param length
+ * the length in bytes of the region starting at address
+ * that must be guaranteed written back to memory.
+ *
+ * @throws RuntimeException if the arguments are invalid
+ * (Note: after optimization, invalid inputs may
+ * go undetected, which will lead to unpredictable
+ * behavior)
+ *
+ * @since 12
+ */
+
+ public void writebackMemory(long address, long length)
+ {
+ checkWritebackMemory(address, length);
+
+ // perform any required pre-writeback barrier
+ writebackPreSync0();
+
+ // write back one cache line at a time
+ long line = (address & CACHE_LINE_MASK);
+ long end = address + length;
+ while (line < end) {
+ writeback0(line);
+ line += CACHE_LINE_FLUSH_SIZE;
+ }
+
+ // perform any required post-writeback barrier
+ writebackPostSync0();
+ }
+
+ /**
+ * Validate the arguments to writebackMemory
+ *
+ * @throws RuntimeException if the arguments are invalid
+ * (Note: after optimization, invalid inputs may
+ * go undetected, which will lead to unpredictable
+ * behavior)
+ */
+ private void checkWritebackMemory(long address, long length)
+ {
+ checkNativeAddress(address);
+ checkSize(length);
+ }
+
+ /**
+ * The size of an L1 data cache line which will be a power of two.
+ */
+ private static final long CACHE_LINE_FLUSH_SIZE = (long)theUnsafe.dataCacheLineFlushSize0();
+ private static final long CACHE_LINE_MASK = ~(CACHE_LINE_FLUSH_SIZE - 1);
+
+ /**
+ * primitive operation forcing writeback of a single cache line.
+ *
+ * @param address
+ * the start address of the cache line to be written back
+ */
+ // native used to write back an individual cache line starting at
+ // the supplied address
+ @HotSpotIntrinsicCandidate
+ private native void writeback0(long address);
+ // native used to serialise writeback operations relative to
+ // preceding memory writes
+ @HotSpotIntrinsicCandidate
+ private native void writebackPreSync0();
+ // native used to serialise writeback operations relative to
+ // following memory writes
+ @HotSpotIntrinsicCandidate
+ private native void writebackPostSync0();
+
/// random queries
/**
@@ -1172,7 +1255,6 @@
*/
public native int pageSize();
-
/// random trusted operations from JNI:
/**
@@ -3712,6 +3794,7 @@
private native int arrayBaseOffset0(Class> arrayClass);
private native int arrayIndexScale0(Class> arrayClass);
private native int addressSize0();
+ private native int dataCacheLineFlushSize0();
private native Class> defineAnonymousClass0(Class> hostClass, byte[] data, Object[] cpPatches);
private native int getLoadAverage0(double[] loadavg, int nelems);
private native boolean unalignedAccess0();