2004-11-24 Jeroen Frijters <address@bogus.example.com>

* java/nio/DirectByteBufferImpl.java
	(ReadOnly): New inner subclass.
	(ReadWrite): New inner subclass.
	(owner): Made final and private.
	(address): Made final.
	(DirectByteBufferImpl(int)): New constructor.
	(DirectByteBufferImpl(Object,RawData,int,int,int)): New constructor.
	(DirectByteBufferImpl(Object,RawData,int,int,int,boolean)): Removed.
	(allocate): Modified to instantiate ReadWrite subclass.
	(finalize): Fixed to only free the buffer, if we own it.
	(put): Removed read-only check.
	(slice, duplicate): Modified to instantiate appropriate subclass.
	(isReadOnly): Removed.
	* java/nio/MappedByteBufferImpl.java
	(slice, duplicate): Modified to instantiate appropriate
	DirectByteBufferImpl subclass.

From-SVN: r91147
This commit is contained in:
Jeroen Frijters 2004-11-24 11:11:46 +00:00 committed by Michael Koch
parent 11dde1bb18
commit b4345a57d8
3 changed files with 121 additions and 34 deletions

View file

@ -1,3 +1,22 @@
2004-11-24 Jeroen Frijters <address@bogus.example.com>
* java/nio/DirectByteBufferImpl.java
(ReadOnly): New inner subclass.
(ReadWrite): New inner subclass.
(owner): Made final and private.
(address): Made final.
(DirectByteBufferImpl(int)): New constructor.
(DirectByteBufferImpl(Object,RawData,int,int,int)): New constructor.
(DirectByteBufferImpl(Object,RawData,int,int,int,boolean)): Removed.
(allocate): Modified to instantiate ReadWrite subclass.
(finalize): Fixed to only free the buffer, if we own it.
(put): Removed read-only check.
(slice, duplicate): Modified to instantiate appropriate subclass.
(isReadOnly): Removed.
* java/nio/MappedByteBufferImpl.java
(slice, duplicate): Modified to instantiate appropriate
DirectByteBufferImpl subclass.
2004-11-24 Michael Koch <konqueror@gmx.de> 2004-11-24 Michael Koch <konqueror@gmx.de>
* gnu/java/nio/NIOServerSocket.java: Added email to @author tag. * gnu/java/nio/NIOServerSocket.java: Added email to @author tag.

View file

@ -40,27 +40,82 @@ package java.nio;
import gnu.gcj.RawData; import gnu.gcj.RawData;
final class DirectByteBufferImpl extends ByteBuffer abstract class DirectByteBufferImpl extends ByteBuffer
{ {
/** Used by MappedByteBufferImpl and when slicing to prevent premature GC. */ /** The owner is used to keep alive the object that actually owns the
protected Object owner; * memory. There are three possibilities:
* 1) owner == this: We allocated the memory and we should free it,
* but *only* in finalize (if we've been sliced
* other objects will also have access to the
* memory).
* 2) owner == null: The byte buffer was created thru
* JNI.NewDirectByteBuffer. The JNI code is
* responsible for freeing the memory.
* 3) owner == some other object: The other object allocated the
* memory and should free it.
*/
private final Object owner;
final RawData address;
RawData address; final static class ReadOnly extends DirectByteBufferImpl
private boolean readOnly;
public DirectByteBufferImpl(RawData address, long len)
{ {
this(null, address, (int) len, (int) len, 0, false); ReadOnly(Object owner, RawData address,
int capacity, int limit,
int position)
{
super(owner, address, capacity, limit, position);
}
public ByteBuffer put(byte value)
{
throw new ReadOnlyBufferException ();
}
public ByteBuffer put(int index, byte value)
{
throw new ReadOnlyBufferException ();
}
public boolean isReadOnly()
{
return true;
}
} }
public DirectByteBufferImpl(Object owner, RawData address, final static class ReadWrite extends DirectByteBufferImpl
int capacity, int limit, {
int position, boolean readOnly) ReadWrite(int capacity)
{
super(capacity);
}
ReadWrite(Object owner, RawData address,
int capacity, int limit,
int position)
{
super(owner, address, capacity, limit, position);
}
public boolean isReadOnly()
{
return false;
}
}
DirectByteBufferImpl(int capacity)
{
super(capacity, capacity, 0, -1);
this.owner = this;
this.address = VMDirectByteBuffer.allocate(capacity);
}
DirectByteBufferImpl(Object owner, RawData address,
int capacity, int limit,
int position)
{ {
super(capacity, limit, position, -1); super(capacity, limit, position, -1);
this.address = address;
this.readOnly = readOnly;
this.owner = owner; this.owner = owner;
this.address = address;
} }
/** /**
@ -68,13 +123,13 @@ final class DirectByteBufferImpl extends ByteBuffer
*/ */
public static ByteBuffer allocate(int capacity) public static ByteBuffer allocate(int capacity)
{ {
return new DirectByteBufferImpl(VMDirectByteBuffer.allocate(capacity), return new DirectByteBufferImpl.ReadWrite(capacity);
capacity);
} }
protected void finalize() throws Throwable protected void finalize() throws Throwable
{ {
VMDirectByteBuffer.free(address); if (owner == this)
VMDirectByteBuffer.free(address);
} }
public byte get() public byte get()
@ -108,7 +163,6 @@ final class DirectByteBufferImpl extends ByteBuffer
public ByteBuffer put(byte value) public ByteBuffer put(byte value)
{ {
checkIfReadOnly();
checkForOverflow(); checkForOverflow();
int pos = position(); int pos = position();
@ -119,7 +173,6 @@ final class DirectByteBufferImpl extends ByteBuffer
public ByteBuffer put(int index, byte value) public ByteBuffer put(int index, byte value)
{ {
checkIfReadOnly();
checkIndex(index); checkIndex(index);
VMDirectByteBuffer.put(address, index, value); VMDirectByteBuffer.put(address, index, value);
@ -147,9 +200,14 @@ final class DirectByteBufferImpl extends ByteBuffer
public ByteBuffer slice() public ByteBuffer slice()
{ {
int rem = remaining(); int rem = remaining();
return new DirectByteBufferImpl if (isReadOnly())
return new DirectByteBufferImpl.ReadOnly
(owner, VMDirectByteBuffer.adjustAddress(address, position()), (owner, VMDirectByteBuffer.adjustAddress(address, position()),
rem, rem, 0, isReadOnly()); rem, rem, 0);
else
return new DirectByteBufferImpl.ReadWrite
(owner, VMDirectByteBuffer.adjustAddress(address, position()),
rem, rem, 0);
} }
private ByteBuffer duplicate(boolean readOnly) private ByteBuffer duplicate(boolean readOnly)
@ -158,9 +216,14 @@ final class DirectByteBufferImpl extends ByteBuffer
reset(); reset();
int mark = position(); int mark = position();
position(pos); position(pos);
DirectByteBufferImpl result DirectByteBufferImpl result;
= new DirectByteBufferImpl(owner, address, capacity(), limit(), if (readOnly)
pos, readOnly); result = new DirectByteBufferImpl.ReadOnly(owner, address, capacity(),
limit(), pos);
else
result = new DirectByteBufferImpl.ReadWrite(owner, address, capacity(),
limit(), pos);
if (mark != pos) if (mark != pos)
{ {
result.position(mark); result.position(mark);
@ -180,11 +243,6 @@ final class DirectByteBufferImpl extends ByteBuffer
return duplicate(true); return duplicate(true);
} }
public boolean isReadOnly()
{
return readOnly;
}
public boolean isDirect() public boolean isDirect()
{ {
return true; return true;

View file

@ -138,9 +138,14 @@ final class MappedByteBufferImpl extends MappedByteBuffer
public ByteBuffer slice() public ByteBuffer slice()
{ {
int rem = remaining(); int rem = remaining();
return new DirectByteBufferImpl if (isReadOnly())
return new DirectByteBufferImpl.ReadOnly
(this, VMDirectByteBuffer.adjustAddress(address, position()), (this, VMDirectByteBuffer.adjustAddress(address, position()),
rem, rem, 0, isReadOnly()); rem, rem, 0);
else
return new DirectByteBufferImpl.ReadWrite
(this, VMDirectByteBuffer.adjustAddress(address, position()),
rem, rem, 0);
} }
private ByteBuffer duplicate(boolean readOnly) private ByteBuffer duplicate(boolean readOnly)
@ -149,9 +154,14 @@ final class MappedByteBufferImpl extends MappedByteBuffer
reset(); reset();
int mark = position(); int mark = position();
position(pos); position(pos);
DirectByteBufferImpl result DirectByteBufferImpl result;
= new DirectByteBufferImpl(this, address, capacity(), limit(), if (readOnly)
pos, readOnly); result = new DirectByteBufferImpl.ReadOnly(this, address, capacity(),
limit(), pos);
else
result = new DirectByteBufferImpl.ReadWrite(this, address, capacity(),
limit(), pos);
if (mark != pos) if (mark != pos)
{ {
result.position(mark); result.position(mark);