Merge "Fix DirectByteBufferAlignment"
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceDirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceDirectByteBufferTest.java
index c00694a..967af33 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceDirectByteBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceDirectByteBufferTest.java
@@ -4,9 +4,9 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,7 +21,7 @@
protected void setUp() throws Exception {
super.setUp();
- buf.position(1).limit(BUFFER_LENGTH-1);
+ buf.position(1);
buf = buf.slice();
baseBuf = buf;
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceSliceDirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceSliceDirectByteBufferTest.java
new file mode 100644
index 0000000..b5e5b11
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceSliceDirectByteBufferTest.java
@@ -0,0 +1,34 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class SliceSliceDirectByteBufferTest extends DirectByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf.position(1);
+ buf = buf.slice();
+ buf.position(1);
+ buf = buf.slice();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/ojluni/src/main/java/java/nio/ByteBuffer.java b/ojluni/src/main/java/java/nio/ByteBuffer.java
index 0434994..b8f2aa0 100644
--- a/ojluni/src/main/java/java/nio/ByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBuffer.java
@@ -27,7 +27,7 @@
package java.nio;
-
+import dalvik.system.VMRuntime;
/**
@@ -304,7 +304,14 @@
if (capacity < 0) {
throw new IllegalArgumentException("capacity < 0: " + capacity);
}
- return new DirectByteBuffer(capacity);
+
+ VMRuntime runtime = VMRuntime.getRuntime();
+ byte[] hb = (byte[])runtime.newNonMovableArray(byte.class, capacity + 7);
+ long address = runtime.addressOf(hb);
+ // Offset is set to handle the alignment
+ // http://b/16449607
+ int offset = (int)(((address + 7) & ~(long)7) - address);
+ return new DirectByteBuffer(capacity, address, hb, offset);
}
diff --git a/ojluni/src/main/java/java/nio/DirectByteBuffer.java b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
index 51f63c6..a5b9e0c 100644
--- a/ojluni/src/main/java/java/nio/DirectByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
@@ -31,7 +31,6 @@
import sun.nio.ch.DirectBuffer;
import libcore.io.SizeOf;
import libcore.io.Memory;
-import dalvik.system.VMRuntime;
class DirectByteBuffer extends MappedByteBuffer
implements DirectBuffer {
@@ -53,15 +52,16 @@
private Cleaner cleaner;
+ private long actualAddress;
+
public Cleaner cleaner() { return cleaner; }
- DirectByteBuffer(int capacity) {
- super(-1, 0, capacity, capacity, (byte[]) VMRuntime.getRuntime()
- .newNonMovableArray(byte.class, capacity), 0);
- VMRuntime runtime = VMRuntime.getRuntime();
- address = runtime.addressOf(hb);
+ DirectByteBuffer(int capacity, long address, byte[] hb, int offset) {
+ super(-1, 0, capacity, capacity, hb, offset);
// Only have references to java objects, no need for a cleaner since the GC will do all
// the work.
+ this.address = address + offset;
+ this.actualAddress = address;
cleaner = null;
this.isReadOnly = false;
att = null;
@@ -70,6 +70,7 @@
DirectByteBuffer(long addr, int cap, Object ob) {
super(-1, 0, cap, cap);
address = addr;
+ actualAddress = addr;
cleaner = null;
att = ob;
}
@@ -79,6 +80,7 @@
private DirectByteBuffer(long addr, int cap) {
super(-1, 0, cap, cap);
address = addr;
+ actualAddress = addr;
cleaner = null;
att = null;
}
@@ -98,6 +100,7 @@
super(-1, 0, cap, cap, fd);
this.isReadOnly = isReadOnly;
address = addr;
+ actualAddress = addr;
cleaner = Cleaner.create(this, unmapper);
att = null;
}
@@ -115,7 +118,8 @@
int off, boolean isReadOnly) {
super(mark, pos, lim, cap, db.hb, off);
this.isReadOnly = isReadOnly;
- address = db.address() + off;
+ address = db.address;
+ actualAddress = db.actualAddress;
cleaner = null;
att = db;
}
@@ -124,11 +128,11 @@
if (!isAccessible) {
throw new IllegalStateException("buffer is inaccessible");
}
- int pos = this.position();
- int lim = this.limit();
+ int pos = position();
+ int lim = limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
- int off = (pos << 0);
+ int off = (pos << 0) + offset;
assert (off >= 0);
return new DirectByteBuffer(this, -1, 0, rem, rem, off, isReadOnly);
}
@@ -142,7 +146,7 @@
this.position(),
this.limit(),
this.capacity(),
- 0,
+ offset,
isReadOnly);
}
@@ -155,7 +159,7 @@
this.position(),
this.limit(),
this.capacity(),
- 0,
+ offset,
true);
}
@@ -164,10 +168,10 @@
}
private long ix(int i) {
- return address + (i << 0);
+ return actualAddress + offset + (i << 0);
}
- public byte get(long a) {
+ private byte get(long a) {
return Memory.peekByte(a);
}
@@ -175,14 +179,14 @@
if (!isAccessible) {
throw new IllegalStateException("buffer is inaccessible");
}
- return get(address + nextGetIndex());
+ return get(ix(nextGetIndex()));
}
public byte get(int i) {
if (!isAccessible) {
throw new IllegalStateException("buffer is inaccessible");
}
- return get(address + checkIndex(i));
+ return get(ix(checkIndex(i)));
}
public ByteBuffer get(byte[] dst, int dstOffset, int length) {
@@ -196,7 +200,7 @@
int rem = (pos <= lim ? lim - pos : 0);
if (length > rem)
throw new BufferUnderflowException();
- Memory.peekByteArray(address + pos,
+ Memory.peekByteArray(ix(pos),
dst, dstOffset, length);
position = pos + length;
return this;
@@ -265,7 +269,7 @@
int rem = (pos <= lim ? lim - pos : 0);
if (length > rem)
throw new BufferOverflowException();
- Memory.pokeByteArray(address + pos,
+ Memory.pokeByteArray(ix(pos),
src, srcOffset, length);
position = pos + length;
return this;
@@ -282,7 +286,7 @@
int lim = limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
- Memory.memmove(this, 0, this, position, remaining());
+ System.arraycopy(hb, position + offset, hb, offset, remaining());
position(rem);
limit(capacity());
discardMark();
@@ -320,7 +324,7 @@
if (newPosition > limit()) {
throw new BufferUnderflowException();
}
- char x = (char) Memory.peekShort(address + position, !nativeByteOrder);
+ char x = (char) Memory.peekShort(ix(position), !nativeByteOrder);
position = newPosition;
return x;
}
@@ -330,7 +334,7 @@
throw new IllegalStateException("buffer is inaccessible");
}
checkIndex(i, SizeOf.CHAR);
- char x = (char)Memory.peekShort(address + i, !nativeByteOrder);
+ char x = (char)Memory.peekShort(ix(i), !nativeByteOrder);
return x;
}