mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
8234049: Implementation of Memory Access API (Incubator)
Co-authored-by: Vlaidmir Ivanov <vladimir.x.ivanov@oracle.com> Reviewed-by: alanb, psandoz, chegar, rriggs, plevart, briangoetz, jrose, adinn, vlivanov
This commit is contained in:
parent
7cdecd8981
commit
8f4f088a12
59 changed files with 7849 additions and 147 deletions
|
@ -28,7 +28,9 @@ package java.nio;
|
|||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.access.foreign.MemorySegmentProxy;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
|
||||
import java.util.Spliterator;
|
||||
|
||||
|
@ -213,13 +215,26 @@ public abstract class Buffer {
|
|||
// NOTE: hoisted here for speed in JNI GetDirectBufferAddress
|
||||
long address;
|
||||
|
||||
// Used by buffers generated by the memory access API (JEP-370)
|
||||
final MemorySegmentProxy segment;
|
||||
|
||||
|
||||
// Creates a new buffer with given address and capacity.
|
||||
//
|
||||
Buffer(long addr, int cap, MemorySegmentProxy segment) {
|
||||
this.address = addr;
|
||||
this.capacity = cap;
|
||||
this.segment = segment;
|
||||
}
|
||||
|
||||
// Creates a new buffer with the given mark, position, limit, and capacity,
|
||||
// after checking invariants.
|
||||
//
|
||||
Buffer(int mark, int pos, int lim, int cap) { // package-private
|
||||
Buffer(int mark, int pos, int lim, int cap, MemorySegmentProxy segment) { // package-private
|
||||
if (cap < 0)
|
||||
throw createCapacityException(cap);
|
||||
this.capacity = cap;
|
||||
this.segment = segment;
|
||||
limit(lim);
|
||||
position(pos);
|
||||
if (mark >= 0) {
|
||||
|
@ -731,6 +746,13 @@ public abstract class Buffer {
|
|||
mark = -1;
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
final void checkSegment() {
|
||||
if (segment != null) {
|
||||
segment.checkValidState();
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
// setup access to this package in SharedSecrets
|
||||
SharedSecrets.setJavaNioAccess(
|
||||
|
@ -739,6 +761,31 @@ public abstract class Buffer {
|
|||
public JavaNioAccess.BufferPool getDirectBufferPool() {
|
||||
return Bits.BUFFER_POOL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer newDirectByteBuffer(long addr, int cap, Object obj, MemorySegmentProxy segment) {
|
||||
return new DirectByteBuffer(addr, cap, obj, segment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer newHeapByteBuffer(byte[] hb, int offset, int capacity, MemorySegmentProxy segment) {
|
||||
return new HeapByteBuffer(hb, offset, capacity, segment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getBufferBase(ByteBuffer bb) {
|
||||
return bb.base();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBufferAddress(ByteBuffer bb) {
|
||||
return bb.address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkSegment(Buffer buffer) {
|
||||
buffer.checkSegment();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
package java.nio;
|
||||
|
||||
import java.util.Objects;
|
||||
import jdk.internal.access.foreign.MemorySegmentProxy;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
||||
|
@ -40,11 +41,11 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
|
||||
#end[rw]
|
||||
|
||||
ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb) { // package-private
|
||||
ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb, MemorySegmentProxy segment) { // package-private
|
||||
#if[rw]
|
||||
super(-1, 0,
|
||||
bb.remaining() >> $LG_BYTES_PER_VALUE$,
|
||||
bb.remaining() >> $LG_BYTES_PER_VALUE$);
|
||||
bb.remaining() >> $LG_BYTES_PER_VALUE$, segment);
|
||||
this.bb = bb;
|
||||
// enforce limit == capacity
|
||||
int cap = this.capacity();
|
||||
|
@ -53,21 +54,21 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
assert (pos <= cap);
|
||||
address = bb.address;
|
||||
#else[rw]
|
||||
super(bb);
|
||||
super(bb, segment);
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb,
|
||||
int mark, int pos, int lim, int cap,
|
||||
long addr)
|
||||
long addr, MemorySegmentProxy segment)
|
||||
{
|
||||
#if[rw]
|
||||
super(mark, pos, lim, cap);
|
||||
super(mark, pos, lim, cap, segment);
|
||||
this.bb = bb;
|
||||
address = addr;
|
||||
assert address >= bb.address;
|
||||
#else[rw]
|
||||
super(bb, mark, pos, lim, cap, addr);
|
||||
super(bb, mark, pos, lim, cap, addr, segment);
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
|
@ -82,7 +83,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
long addr = byteOffset(pos);
|
||||
return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, -1, 0, rem, rem, addr);
|
||||
return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, -1, 0, rem, rem, addr, segment);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -93,7 +94,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
0,
|
||||
length,
|
||||
length,
|
||||
byteOffset(index));
|
||||
byteOffset(index), segment);
|
||||
}
|
||||
|
||||
public $Type$Buffer duplicate() {
|
||||
|
@ -102,7 +103,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
this.position(),
|
||||
this.limit(),
|
||||
this.capacity(),
|
||||
address);
|
||||
address, segment);
|
||||
}
|
||||
|
||||
public $Type$Buffer asReadOnlyBuffer() {
|
||||
|
@ -112,7 +113,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
this.position(),
|
||||
this.limit(),
|
||||
this.capacity(),
|
||||
address);
|
||||
address, segment);
|
||||
#else[rw]
|
||||
return duplicate();
|
||||
#end[rw]
|
||||
|
@ -130,12 +131,14 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
}
|
||||
|
||||
public $type$ get() {
|
||||
checkSegment();
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(nextGetIndex()),
|
||||
{#if[boB]?true:false});
|
||||
return $fromBits$(x);
|
||||
}
|
||||
|
||||
public $type$ get(int i) {
|
||||
checkSegment();
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)),
|
||||
{#if[boB]?true:false});
|
||||
return $fromBits$(x);
|
||||
|
@ -153,6 +156,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
|
||||
public $Type$Buffer put($type$ x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
$memtype$ y = $toBits$(x);
|
||||
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(nextPutIndex()), y,
|
||||
{#if[boB]?true:false});
|
||||
|
@ -164,6 +168,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
|
||||
public $Type$Buffer put(int i, $type$ x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
$memtype$ y = $toBits$(x);
|
||||
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)), y,
|
||||
{#if[boB]?true:false});
|
||||
|
@ -237,7 +242,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
pos + start,
|
||||
pos + end,
|
||||
capacity(),
|
||||
address);
|
||||
address, segment);
|
||||
}
|
||||
|
||||
#end[char]
|
||||
|
|
|
@ -33,6 +33,7 @@ class XXX {
|
|||
|
||||
private $type$ get$Type$(long a) {
|
||||
try {
|
||||
checkSegment();
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(null, a, bigEndian);
|
||||
return $fromBits$(x);
|
||||
} finally {
|
||||
|
@ -61,6 +62,7 @@ class XXX {
|
|||
private ByteBuffer put$Type$(long a, $type$ x) {
|
||||
#if[rw]
|
||||
try {
|
||||
checkSegment();
|
||||
$memtype$ y = $toBits$(x);
|
||||
UNSAFE.put$Memtype$Unaligned(null, a, y, bigEndian);
|
||||
} finally {
|
||||
|
@ -104,13 +106,13 @@ class XXX {
|
|||
0,
|
||||
size,
|
||||
size,
|
||||
address + off))
|
||||
address + off, segment))
|
||||
: ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$L(this,
|
||||
-1,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
address + off)));
|
||||
address + off, segment)));
|
||||
} else {
|
||||
return (nativeByteOrder
|
||||
? ($Type$Buffer)(new Direct$Type$Buffer$RW$U(this,
|
||||
|
@ -118,13 +120,13 @@ class XXX {
|
|||
0,
|
||||
size,
|
||||
size,
|
||||
off))
|
||||
off, segment))
|
||||
: ($Type$Buffer)(new Direct$Type$Buffer$RW$S(this,
|
||||
-1,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
off)));
|
||||
off, segment)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ package java.nio;
|
|||
import java.io.FileDescriptor;
|
||||
import java.lang.ref.Reference;
|
||||
import java.util.Objects;
|
||||
import jdk.internal.access.foreign.MemorySegmentProxy;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.ref.Cleaner;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
@ -112,7 +113,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
//
|
||||
Direct$Type$Buffer$RW$(int cap) { // package-private
|
||||
#if[rw]
|
||||
super(-1, 0, cap, cap);
|
||||
super(-1, 0, cap, cap, null);
|
||||
boolean pa = VM.isDirectMemoryPageAligned();
|
||||
int ps = Bits.pageSize();
|
||||
long size = Math.max(1L, (long)cap + (pa ? ps : 0));
|
||||
|
@ -145,8 +146,8 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
// Invoked to construct a direct ByteBuffer referring to the block of
|
||||
// memory. A given arbitrary object may also be attached to the buffer.
|
||||
//
|
||||
Direct$Type$Buffer(long addr, int cap, Object ob) {
|
||||
super(-1, 0, cap, cap);
|
||||
Direct$Type$Buffer(long addr, int cap, Object ob, MemorySegmentProxy segment) {
|
||||
super(-1, 0, cap, cap, segment);
|
||||
address = addr;
|
||||
cleaner = null;
|
||||
att = ob;
|
||||
|
@ -156,7 +157,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
// Invoked only by JNI: NewDirectByteBuffer(void*, long)
|
||||
//
|
||||
private Direct$Type$Buffer(long addr, int cap) {
|
||||
super(-1, 0, cap, cap);
|
||||
super(-1, 0, cap, cap, null);
|
||||
address = addr;
|
||||
cleaner = null;
|
||||
att = null;
|
||||
|
@ -169,15 +170,15 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
protected Direct$Type$Buffer$RW$(int cap, long addr,
|
||||
FileDescriptor fd,
|
||||
Runnable unmapper,
|
||||
boolean isSync)
|
||||
boolean isSync, MemorySegmentProxy segment)
|
||||
{
|
||||
#if[rw]
|
||||
super(-1, 0, cap, cap, fd, isSync);
|
||||
super(-1, 0, cap, cap, fd, isSync, segment);
|
||||
address = addr;
|
||||
cleaner = Cleaner.create(this, unmapper);
|
||||
att = null;
|
||||
#else[rw]
|
||||
super(cap, addr, fd, unmapper, isSync);
|
||||
super(cap, addr, fd, unmapper, isSync, segment);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
}
|
||||
|
@ -188,10 +189,10 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
//
|
||||
Direct$Type$Buffer$RW$$BO$(DirectBuffer db, // package-private
|
||||
int mark, int pos, int lim, int cap,
|
||||
int off)
|
||||
int off, MemorySegmentProxy segment)
|
||||
{
|
||||
#if[rw]
|
||||
super(mark, pos, lim, cap);
|
||||
super(mark, pos, lim, cap, segment);
|
||||
address = db.address() + off;
|
||||
#if[byte]
|
||||
cleaner = null;
|
||||
|
@ -199,7 +200,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
Object attachment = db.attachment();
|
||||
att = (attachment == null ? db : attachment);
|
||||
#else[rw]
|
||||
super(db, mark, pos, lim, cap, off);
|
||||
super(db, mark, pos, lim, cap, off, segment);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
}
|
||||
|
@ -216,7 +217,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
int off = (pos << $LG_BYTES_PER_VALUE$);
|
||||
assert (off >= 0);
|
||||
return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off);
|
||||
return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off, segment);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -227,7 +228,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
0,
|
||||
length,
|
||||
length,
|
||||
index);
|
||||
index, segment);
|
||||
}
|
||||
|
||||
public $Type$Buffer duplicate() {
|
||||
|
@ -236,7 +237,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
this.position(),
|
||||
this.limit(),
|
||||
this.capacity(),
|
||||
0);
|
||||
0, segment);
|
||||
}
|
||||
|
||||
public $Type$Buffer asReadOnlyBuffer() {
|
||||
|
@ -246,7 +247,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
this.position(),
|
||||
this.limit(),
|
||||
this.capacity(),
|
||||
0);
|
||||
0, segment);
|
||||
#else[rw]
|
||||
return duplicate();
|
||||
#end[rw]
|
||||
|
@ -264,6 +265,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
public $type$ get() {
|
||||
try {
|
||||
checkSegment();
|
||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(nextGetIndex()))));
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
|
@ -272,6 +274,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
public $type$ get(int i) {
|
||||
try {
|
||||
checkSegment();
|
||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(checkIndex(i)))));
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
|
@ -290,6 +293,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
public $Type$Buffer get($type$[] dst, int offset, int length) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
|
||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||
int pos = position();
|
||||
|
@ -331,6 +335,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||
|
@ -368,6 +373,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
public $Type$Buffer put($type$ x) {
|
||||
#if[rw]
|
||||
try {
|
||||
checkSegment();
|
||||
UNSAFE.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
|
@ -381,6 +387,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
public $Type$Buffer put(int i, $type$ x) {
|
||||
#if[rw]
|
||||
try {
|
||||
checkSegment();
|
||||
UNSAFE.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
|
@ -393,6 +400,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
public $Type$Buffer put($Type$Buffer src) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
if (src instanceof Direct$Type$Buffer$BO$) {
|
||||
if (src == this)
|
||||
throw createSameBufferException();
|
||||
|
@ -439,6 +447,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
public $Type$Buffer put($type$[] src, int offset, int length) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
|
||||
Objects.checkFromIndexSize(offset, length, src.length);
|
||||
int pos = position();
|
||||
|
@ -480,6 +489,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
public $Type$Buffer put(int index, $type$[] src, int offset, int length) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
Objects.checkFromIndexSize(offset, length, src.length);
|
||||
|
@ -577,7 +587,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
pos + start,
|
||||
pos + end,
|
||||
capacity(),
|
||||
offset);
|
||||
offset, segment);
|
||||
}
|
||||
|
||||
#end[char]
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
package java.nio;
|
||||
|
||||
import java.util.Objects;
|
||||
import jdk.internal.access.foreign.MemorySegmentProxy;
|
||||
|
||||
/**
|
||||
#if[rw]
|
||||
|
@ -58,47 +59,47 @@ class Heap$Type$Buffer$RW$
|
|||
#end[rw]
|
||||
*/
|
||||
|
||||
Heap$Type$Buffer$RW$(int cap, int lim) { // package-private
|
||||
Heap$Type$Buffer$RW$(int cap, int lim, MemorySegmentProxy segment) { // package-private
|
||||
#if[rw]
|
||||
super(-1, 0, lim, cap, new $type$[cap], 0);
|
||||
super(-1, 0, lim, cap, new $type$[cap], 0, segment);
|
||||
/*
|
||||
hb = new $type$[cap];
|
||||
offset = 0;
|
||||
*/
|
||||
this.address = ARRAY_BASE_OFFSET;
|
||||
#else[rw]
|
||||
super(cap, lim);
|
||||
super(cap, lim, segment);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private
|
||||
Heap$Type$Buffer$RW$($type$[] buf, int off, int len, MemorySegmentProxy segment) { // package-private
|
||||
#if[rw]
|
||||
super(-1, off, off + len, buf.length, buf, 0);
|
||||
super(-1, off, off + len, buf.length, buf, 0, segment);
|
||||
/*
|
||||
hb = buf;
|
||||
offset = 0;
|
||||
*/
|
||||
this.address = ARRAY_BASE_OFFSET;
|
||||
#else[rw]
|
||||
super(buf, off, len);
|
||||
super(buf, off, len, segment);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
protected Heap$Type$Buffer$RW$($type$[] buf,
|
||||
int mark, int pos, int lim, int cap,
|
||||
int off)
|
||||
int off, MemorySegmentProxy segment)
|
||||
{
|
||||
#if[rw]
|
||||
super(mark, pos, lim, cap, buf, off);
|
||||
super(mark, pos, lim, cap, buf, off, segment);
|
||||
/*
|
||||
hb = buf;
|
||||
offset = off;
|
||||
*/
|
||||
this.address = ARRAY_BASE_OFFSET + off * ARRAY_INDEX_SCALE;
|
||||
#else[rw]
|
||||
super(buf, mark, pos, lim, cap, off);
|
||||
super(buf, mark, pos, lim, cap, off, segment);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
}
|
||||
|
@ -110,7 +111,7 @@ class Heap$Type$Buffer$RW$
|
|||
0,
|
||||
rem,
|
||||
rem,
|
||||
this.position() + offset);
|
||||
this.position() + offset, segment);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -121,7 +122,7 @@ class Heap$Type$Buffer$RW$
|
|||
0,
|
||||
length,
|
||||
length,
|
||||
index + offset);
|
||||
index + offset, segment);
|
||||
}
|
||||
|
||||
public $Type$Buffer duplicate() {
|
||||
|
@ -130,7 +131,7 @@ class Heap$Type$Buffer$RW$
|
|||
this.position(),
|
||||
this.limit(),
|
||||
this.capacity(),
|
||||
offset);
|
||||
offset, segment);
|
||||
}
|
||||
|
||||
public $Type$Buffer asReadOnlyBuffer() {
|
||||
|
@ -140,7 +141,7 @@ class Heap$Type$Buffer$RW$
|
|||
this.position(),
|
||||
this.limit(),
|
||||
this.capacity(),
|
||||
offset);
|
||||
offset, segment);
|
||||
#else[rw]
|
||||
return duplicate();
|
||||
#end[rw]
|
||||
|
@ -159,20 +160,23 @@ class Heap$Type$Buffer$RW$
|
|||
#end[byte]
|
||||
|
||||
public $type$ get() {
|
||||
checkSegment();
|
||||
return hb[ix(nextGetIndex())];
|
||||
}
|
||||
|
||||
public $type$ get(int i) {
|
||||
checkSegment();
|
||||
return hb[ix(checkIndex(i))];
|
||||
}
|
||||
|
||||
#if[streamableType]
|
||||
$type$ getUnchecked(int i) {
|
||||
return hb[ix(i)];
|
||||
return hb[ix(i)];
|
||||
}
|
||||
#end[streamableType]
|
||||
|
||||
public $Type$Buffer get($type$[] dst, int offset, int length) {
|
||||
checkSegment();
|
||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||
int pos = position();
|
||||
if (length > limit() - pos)
|
||||
|
@ -183,6 +187,7 @@ class Heap$Type$Buffer$RW$
|
|||
}
|
||||
|
||||
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
|
||||
checkSegment();
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||
System.arraycopy(hb, ix(index), dst, offset, length);
|
||||
|
@ -201,6 +206,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer put($type$ x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
hb[ix(nextPutIndex())] = x;
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -210,6 +216,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer put(int i, $type$ x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
hb[ix(checkIndex(i))] = x;
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -219,6 +226,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer put($type$[] src, int offset, int length) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
Objects.checkFromIndexSize(offset, length, src.length);
|
||||
int pos = position();
|
||||
if (length > limit() - pos)
|
||||
|
@ -233,6 +241,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer put($Type$Buffer src) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
if (src instanceof Heap$Type$Buffer) {
|
||||
if (src == this)
|
||||
throw createSameBufferException();
|
||||
|
@ -264,6 +273,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer put(int index, $type$[] src, int offset, int length) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
Objects.checkFromIndexSize(offset, length, src.length);
|
||||
System.arraycopy(src, offset, hb, ix(index), length);
|
||||
|
@ -276,6 +286,7 @@ class Heap$Type$Buffer$RW$
|
|||
#if[char]
|
||||
|
||||
public $Type$Buffer put(String src, int start, int end) {
|
||||
checkSegment();
|
||||
int length = end - start;
|
||||
Objects.checkFromIndexSize(start, length, src.length());
|
||||
if (isReadOnly())
|
||||
|
@ -327,6 +338,7 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public char getChar() {
|
||||
checkSegment();
|
||||
return UNSAFE.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
}
|
||||
|
||||
|
@ -338,6 +350,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putChar(char x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
UNSAFE.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -347,6 +360,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putChar(int i, char x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
UNSAFE.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -364,13 +378,13 @@ class Heap$Type$Buffer$RW$
|
|||
0,
|
||||
size,
|
||||
size,
|
||||
addr))
|
||||
addr, segment))
|
||||
: (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this,
|
||||
-1,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
addr)));
|
||||
addr, segment)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -379,10 +393,12 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public short getShort() {
|
||||
checkSegment();
|
||||
return UNSAFE.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
}
|
||||
|
||||
public short getShort(int i) {
|
||||
checkSegment();
|
||||
return UNSAFE.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
|
||||
}
|
||||
|
||||
|
@ -390,6 +406,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putShort(short x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
UNSAFE.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -399,6 +416,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putShort(int i, short x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
UNSAFE.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -416,13 +434,13 @@ class Heap$Type$Buffer$RW$
|
|||
0,
|
||||
size,
|
||||
size,
|
||||
addr))
|
||||
addr, segment))
|
||||
: (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this,
|
||||
-1,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
addr)));
|
||||
addr, segment)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -431,10 +449,12 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public int getInt() {
|
||||
checkSegment();
|
||||
return UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
}
|
||||
|
||||
public int getInt(int i) {
|
||||
checkSegment();
|
||||
return UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
}
|
||||
|
||||
|
@ -442,6 +462,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putInt(int x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -451,6 +472,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putInt(int i, int x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -468,13 +490,13 @@ class Heap$Type$Buffer$RW$
|
|||
0,
|
||||
size,
|
||||
size,
|
||||
addr))
|
||||
addr, segment))
|
||||
: (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this,
|
||||
-1,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
addr)));
|
||||
addr, segment)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -483,10 +505,12 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public long getLong() {
|
||||
checkSegment();
|
||||
return UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
}
|
||||
|
||||
public long getLong(int i) {
|
||||
checkSegment();
|
||||
return UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
}
|
||||
|
||||
|
@ -494,6 +518,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putLong(long x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -503,6 +528,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putLong(int i, long x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -520,13 +546,13 @@ class Heap$Type$Buffer$RW$
|
|||
0,
|
||||
size,
|
||||
size,
|
||||
addr))
|
||||
addr, segment))
|
||||
: (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this,
|
||||
-1,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
addr)));
|
||||
addr, segment)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -535,11 +561,13 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public float getFloat() {
|
||||
checkSegment();
|
||||
int x = UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
return Float.intBitsToFloat(x);
|
||||
}
|
||||
|
||||
public float getFloat(int i) {
|
||||
checkSegment();
|
||||
int x = UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
return Float.intBitsToFloat(x);
|
||||
}
|
||||
|
@ -548,6 +576,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putFloat(float x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
int y = Float.floatToRawIntBits(x);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian);
|
||||
return this;
|
||||
|
@ -558,6 +587,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putFloat(int i, float x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
int y = Float.floatToRawIntBits(x);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
|
||||
return this;
|
||||
|
@ -576,13 +606,13 @@ class Heap$Type$Buffer$RW$
|
|||
0,
|
||||
size,
|
||||
size,
|
||||
addr))
|
||||
addr, segment))
|
||||
: (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this,
|
||||
-1,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
addr)));
|
||||
addr, segment)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -591,11 +621,13 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public double getDouble() {
|
||||
checkSegment();
|
||||
long x = UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
return Double.longBitsToDouble(x);
|
||||
}
|
||||
|
||||
public double getDouble(int i) {
|
||||
checkSegment();
|
||||
long x = UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
return Double.longBitsToDouble(x);
|
||||
}
|
||||
|
@ -604,6 +636,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putDouble(double x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
long y = Double.doubleToRawLongBits(x);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian);
|
||||
return this;
|
||||
|
@ -614,6 +647,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putDouble(int i, double x) {
|
||||
#if[rw]
|
||||
checkSegment();
|
||||
long y = Double.doubleToRawLongBits(x);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
|
||||
return this;
|
||||
|
@ -632,13 +666,13 @@ class Heap$Type$Buffer$RW$
|
|||
0,
|
||||
size,
|
||||
size,
|
||||
addr))
|
||||
addr, segment))
|
||||
: (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this,
|
||||
-1,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
addr)));
|
||||
addr, segment)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -666,7 +700,7 @@ class Heap$Type$Buffer$RW$
|
|||
pos + start,
|
||||
pos + end,
|
||||
capacity(),
|
||||
offset);
|
||||
offset, segment);
|
||||
}
|
||||
|
||||
#end[char]
|
||||
|
|
|
@ -28,6 +28,8 @@ package java.nio;
|
|||
import java.io.FileDescriptor;
|
||||
import java.lang.ref.Reference;
|
||||
import java.util.Objects;
|
||||
|
||||
import jdk.internal.access.foreign.MemorySegmentProxy;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
|
||||
|
@ -88,21 +90,21 @@ public abstract class MappedByteBuffer
|
|||
// This should only be invoked by the DirectByteBuffer constructors
|
||||
//
|
||||
MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
|
||||
FileDescriptor fd, boolean isSync) {
|
||||
super(mark, pos, lim, cap);
|
||||
FileDescriptor fd, boolean isSync, MemorySegmentProxy segment) {
|
||||
super(mark, pos, lim, cap, segment);
|
||||
this.fd = fd;
|
||||
this.isSync = isSync;
|
||||
}
|
||||
|
||||
MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
|
||||
boolean isSync) {
|
||||
super(mark, pos, lim, cap);
|
||||
boolean isSync, MemorySegmentProxy segment) {
|
||||
super(mark, pos, lim, cap, segment);
|
||||
this.fd = null;
|
||||
this.isSync = isSync;
|
||||
}
|
||||
|
||||
MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private
|
||||
super(mark, pos, lim, cap);
|
||||
MappedByteBuffer(int mark, int pos, int lim, int cap, MemorySegmentProxy segment) { // package-private
|
||||
super(mark, pos, lim, cap, segment);
|
||||
this.fd = null;
|
||||
this.isSync = false;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class StringCharBuffer // package-private
|
|||
CharSequence str;
|
||||
|
||||
StringCharBuffer(CharSequence s, int start, int end) { // package-private
|
||||
super(-1, start, end, s.length());
|
||||
super(-1, start, end, s.length(), null);
|
||||
int n = s.length();
|
||||
Objects.checkFromToIndex(start, end, n);
|
||||
str = s;
|
||||
|
@ -68,7 +68,7 @@ class StringCharBuffer // package-private
|
|||
int limit,
|
||||
int cap,
|
||||
int offset) {
|
||||
super(mark, pos, limit, cap, null, offset);
|
||||
super(mark, pos, limit, cap, null, offset, null);
|
||||
str = s;
|
||||
this.isReadOnly = true;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import java.util.stream.$Streamtype$Stream;
|
|||
#end[streamableType]
|
||||
|
||||
import java.util.Objects;
|
||||
import jdk.internal.access.foreign.MemorySegmentProxy;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
|
@ -279,17 +280,25 @@ public abstract class $Type$Buffer
|
|||
// backing array, and array offset
|
||||
//
|
||||
$Type$Buffer(int mark, int pos, int lim, int cap, // package-private
|
||||
$type$[] hb, int offset)
|
||||
$type$[] hb, int offset, MemorySegmentProxy segment)
|
||||
{
|
||||
super(mark, pos, lim, cap);
|
||||
super(mark, pos, lim, cap, segment);
|
||||
this.hb = hb;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
// Creates a new buffer with the given mark, position, limit, and capacity
|
||||
//
|
||||
$Type$Buffer(int mark, int pos, int lim, int cap) { // package-private
|
||||
this(mark, pos, lim, cap, null, 0);
|
||||
$Type$Buffer(int mark, int pos, int lim, int cap, MemorySegmentProxy segment) { // package-private
|
||||
this(mark, pos, lim, cap, null, 0, segment);
|
||||
}
|
||||
|
||||
// Creates a new buffer with given base, address and capacity
|
||||
//
|
||||
$Type$Buffer($type$[] hb, long addr, int cap, MemorySegmentProxy segment) { // package-private
|
||||
super(addr, cap, segment);
|
||||
this.hb = hb;
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -348,7 +357,7 @@ public abstract class $Type$Buffer
|
|||
public static $Type$Buffer allocate(int capacity) {
|
||||
if (capacity < 0)
|
||||
throw createCapacityException(capacity);
|
||||
return new Heap$Type$Buffer(capacity, capacity);
|
||||
return new Heap$Type$Buffer(capacity, capacity, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -393,7 +402,7 @@ public abstract class $Type$Buffer
|
|||
int offset, int length)
|
||||
{
|
||||
try {
|
||||
return new Heap$Type$Buffer(array, offset, length);
|
||||
return new Heap$Type$Buffer(array, offset, length, null);
|
||||
} catch (IllegalArgumentException x) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue