mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
implement JNI methods needed by AWT
These include PushLocalFrame, PopLocalFrame, NewDirectByteBuffer, GetDirectBufferAddress, and GetDirectBufferCapacity.
This commit is contained in:
parent
2642a167e2
commit
01be4b23bb
87
classpath/java/nio/ArrayByteBuffer.java
Normal file
87
classpath/java/nio/ArrayByteBuffer.java
Normal file
@ -0,0 +1,87 @@
|
||||
/* Copyright (c) 2008-2012, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.nio;
|
||||
|
||||
class ArrayByteBuffer extends ByteBuffer {
|
||||
private final byte[] array;
|
||||
private final int arrayOffset;
|
||||
|
||||
ArrayByteBuffer(byte[] array, int offset, int length, boolean readOnly) {
|
||||
super(readOnly);
|
||||
|
||||
this.array = array;
|
||||
this.arrayOffset = offset;
|
||||
this.capacity = length;
|
||||
this.limit = length;
|
||||
this.position = 0;
|
||||
}
|
||||
|
||||
public ByteBuffer asReadOnlyBuffer() {
|
||||
ByteBuffer b = new ArrayByteBuffer(array, arrayOffset, capacity, true);
|
||||
b.position(position());
|
||||
b.limit(limit());
|
||||
return b;
|
||||
}
|
||||
|
||||
public byte[] array() {
|
||||
return array;
|
||||
}
|
||||
|
||||
public ByteBuffer slice() {
|
||||
return new ArrayByteBuffer
|
||||
(array, arrayOffset + position, remaining(), true);
|
||||
}
|
||||
|
||||
public int arrayOffset() {
|
||||
return arrayOffset;
|
||||
}
|
||||
|
||||
protected void doPut(int position, byte val) {
|
||||
array[arrayOffset + position] = val;
|
||||
}
|
||||
|
||||
public ByteBuffer put(ByteBuffer src) {
|
||||
checkPut(position, src.remaining());
|
||||
src.get(array, arrayOffset + position, src.remaining());
|
||||
position += src.remaining();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer put(byte[] src, int offset, int length) {
|
||||
checkPut(position, length);
|
||||
|
||||
System.arraycopy(src, offset, array, arrayOffset + position, length);
|
||||
position += length;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer get(byte[] dst, int offset, int length) {
|
||||
checkGet(position, length);
|
||||
|
||||
System.arraycopy(array, arrayOffset + position, dst, offset, length);
|
||||
position += length;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected byte doGet(int position) {
|
||||
return array[arrayOffset+position];
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "(ArrayByteBuffer with array: " + array
|
||||
+ " arrayOffset: " + arrayOffset
|
||||
+ " position: " + position
|
||||
+ " limit: " + limit
|
||||
+ " capacity: " + capacity + ")";
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2008-2011, Avian Contributors
|
||||
/* Copyright (c) 2008-2012, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
@ -10,13 +10,22 @@
|
||||
|
||||
package java.nio;
|
||||
|
||||
public class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
|
||||
private final byte[] array;
|
||||
private int arrayOffset;
|
||||
public abstract class ByteBuffer
|
||||
extends Buffer
|
||||
implements Comparable<ByteBuffer>
|
||||
{
|
||||
private final boolean readOnly;
|
||||
|
||||
protected ByteBuffer(boolean readOnly) {
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
public static ByteBuffer allocate(int capacity) {
|
||||
return new ByteBuffer(new byte[capacity], 0, capacity, false);
|
||||
return new ArrayByteBuffer(new byte[capacity], 0, capacity, false);
|
||||
}
|
||||
|
||||
public static ByteBuffer allocateDirect(int capacity) {
|
||||
return FixedArrayByteBuffer.make(capacity);
|
||||
}
|
||||
|
||||
public static ByteBuffer wrap(byte[] array) {
|
||||
@ -24,23 +33,51 @@ public class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
|
||||
}
|
||||
|
||||
public static ByteBuffer wrap(byte[] array, int offset, int length) {
|
||||
return new ByteBuffer(array, offset, length, false);
|
||||
return new ArrayByteBuffer(array, offset, length, false);
|
||||
}
|
||||
|
||||
private ByteBuffer(byte[] array, int offset, int length, boolean readOnly) {
|
||||
this.array = array;
|
||||
this.readOnly = readOnly;
|
||||
arrayOffset = offset;
|
||||
capacity = length;
|
||||
limit = capacity;
|
||||
position = 0;
|
||||
public abstract ByteBuffer asReadOnlyBuffer();
|
||||
|
||||
public abstract ByteBuffer slice();
|
||||
|
||||
protected abstract void doPut(int offset, byte val);
|
||||
|
||||
public abstract ByteBuffer put(byte[] arr, int offset, int len);
|
||||
|
||||
protected abstract byte doGet(int offset);
|
||||
|
||||
public abstract ByteBuffer get(byte[] dst, int offset, int length);
|
||||
|
||||
public boolean hasArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ByteBuffer asReadOnlyBuffer() {
|
||||
ByteBuffer b = new ByteBuffer(array, arrayOffset, capacity, true);
|
||||
b.position(position());
|
||||
b.limit(limit());
|
||||
return b;
|
||||
public ByteBuffer compact() {
|
||||
if (position != 0) {
|
||||
ByteBuffer b = slice();
|
||||
position = 0;
|
||||
put(b);
|
||||
}
|
||||
|
||||
position = remaining();
|
||||
limit(capacity());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer put(ByteBuffer src) {
|
||||
if (src.hasArray()) {
|
||||
checkPut(position, src.remaining());
|
||||
|
||||
put(src.array(), src.arrayOffset() + src.position, src.remaining());
|
||||
src.position(src.position() + src.remaining());
|
||||
|
||||
return this;
|
||||
} else {
|
||||
byte[] buffer = new byte[src.remaining()];
|
||||
src.get(buffer);
|
||||
return put(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public int compareTo(ByteBuffer o) {
|
||||
@ -60,37 +97,22 @@ public class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
|
||||
}
|
||||
|
||||
public byte[] array() {
|
||||
return array;
|
||||
}
|
||||
|
||||
public ByteBuffer slice() {
|
||||
return new ByteBuffer(array, arrayOffset + position, remaining(), true);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public int arrayOffset() {
|
||||
return arrayOffset;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public ByteBuffer compact() {
|
||||
if (position != 0) {
|
||||
System.arraycopy(array, arrayOffset+position, array, arrayOffset, remaining());
|
||||
}
|
||||
position=remaining();
|
||||
limit(capacity());
|
||||
|
||||
public ByteBuffer put(int offset, byte val) {
|
||||
checkPut(offset, 1);
|
||||
doPut(offset, val);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer put(byte val) {
|
||||
checkPut(1);
|
||||
array[arrayOffset+(position++)] = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer put(ByteBuffer src) {
|
||||
checkPut(src.remaining());
|
||||
put(src.array, src.arrayOffset + src.position, src.remaining());
|
||||
src.position += src.remaining();
|
||||
put(position, val);
|
||||
++ position;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -98,125 +120,122 @@ public class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
|
||||
return put(arr, 0, arr.length);
|
||||
}
|
||||
|
||||
public ByteBuffer put(byte[] arr, int offset, int len) {
|
||||
checkPut(len);
|
||||
System.arraycopy(arr, offset, array, arrayOffset+position, len);
|
||||
position += len;
|
||||
public ByteBuffer putLong(int position, long val) {
|
||||
checkPut(position, 8);
|
||||
|
||||
doPut(position , (byte) ((val >> 56) & 0xff));
|
||||
doPut(position + 1, (byte) ((val >> 48) & 0xff));
|
||||
doPut(position + 2, (byte) ((val >> 40) & 0xff));
|
||||
doPut(position + 3, (byte) ((val >> 32) & 0xff));
|
||||
doPut(position + 4, (byte) ((val >> 24) & 0xff));
|
||||
doPut(position + 5, (byte) ((val >> 16) & 0xff));
|
||||
doPut(position + 6, (byte) ((val >> 8) & 0xff));
|
||||
doPut(position + 7, (byte) ((val ) & 0xff));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer putInt(int position, int val) {
|
||||
checkPut(position, 4);
|
||||
array[arrayOffset+position] = (byte)((val >> 24) & 0xff);
|
||||
array[arrayOffset+position+1] = (byte)((val >> 16) & 0xff);
|
||||
array[arrayOffset+position+2] = (byte)((val >> 8) & 0xff);
|
||||
array[arrayOffset+position+3] = (byte)((val ) & 0xff);
|
||||
|
||||
doPut(position , (byte) ((val >> 24) & 0xff));
|
||||
doPut(position + 1, (byte) ((val >> 16) & 0xff));
|
||||
doPut(position + 2, (byte) ((val >> 8) & 0xff));
|
||||
doPut(position + 3, (byte) ((val ) & 0xff));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer putShort(int position, short val) {
|
||||
checkPut(position, 2);
|
||||
|
||||
doPut(position , (byte) ((val >> 8) & 0xff));
|
||||
doPut(position + 1, (byte) ((val ) & 0xff));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer putLong(long val) {
|
||||
putLong(position, val);
|
||||
position += 8;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer putInt(int val) {
|
||||
checkPut(4);
|
||||
putInt(position, val);
|
||||
position += 4;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer putShort(short val) {
|
||||
checkPut(2);
|
||||
put((byte)((val >> 8) & 0xff));
|
||||
put((byte)(val & 0xff));
|
||||
putShort(position, val);
|
||||
position += 2;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer putLong(long val) {
|
||||
checkPut(8);
|
||||
putInt((int)(val >> 32));
|
||||
putInt((int)val);
|
||||
return this;
|
||||
}
|
||||
|
||||
public byte get() {
|
||||
checkGet(1);
|
||||
return array[arrayOffset+(position++)];
|
||||
public byte get(int position) {
|
||||
checkGet(position, 1);
|
||||
return doGet(position);
|
||||
}
|
||||
|
||||
public ByteBuffer get(byte[] dst) {
|
||||
return get(dst, 0, dst.length);
|
||||
}
|
||||
|
||||
public ByteBuffer get(byte[] dst, int offset, int length) {
|
||||
checkGet(length);
|
||||
System.arraycopy(array, arrayOffset + position, dst, offset, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
public long getLong(int position) {
|
||||
checkGet(position, 8);
|
||||
|
||||
public byte get(int position) {
|
||||
checkGet(position, 1);
|
||||
return array[arrayOffset+position];
|
||||
return (((long) (doGet(position ) & 0xFF)) << 56)
|
||||
| (((long) (doGet(position + 1) & 0xFF)) << 48)
|
||||
| (((long) (doGet(position + 2) & 0xFF)) << 40)
|
||||
| (((long) (doGet(position + 3) & 0xFF)) << 32)
|
||||
| (((long) (doGet(position + 4) & 0xFF)) << 24)
|
||||
| (((long) (doGet(position + 5) & 0xFF)) << 16)
|
||||
| (((long) (doGet(position + 6) & 0xFF)) << 8)
|
||||
| (((long) (doGet(position + 7) & 0xFF)) );
|
||||
}
|
||||
|
||||
public int getInt(int position) {
|
||||
checkGet(position, 4);
|
||||
|
||||
int p = arrayOffset + position;
|
||||
return ((array[p] & 0xFF) << 24)
|
||||
| ((array[p + 1] & 0xFF) << 16)
|
||||
| ((array[p + 2] & 0xFF) << 8)
|
||||
| ((array[p + 3] & 0xFF));
|
||||
return (((int) (doGet(position ) & 0xFF)) << 24)
|
||||
| (((int) (doGet(position + 1) & 0xFF)) << 16)
|
||||
| (((int) (doGet(position + 2) & 0xFF)) << 8)
|
||||
| (((int) (doGet(position + 3) & 0xFF)) );
|
||||
}
|
||||
|
||||
public short getShort(int position) {
|
||||
checkGet(position, 2);
|
||||
|
||||
int p = arrayOffset + position;
|
||||
return (short) (((array[p] & 0xFF) << 8) | ((array[p + 1] & 0xFF)));
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
checkGet(4);
|
||||
int i = get() << 24;
|
||||
i |= (get() & 0xff) << 16;
|
||||
i |= (get() & 0xff) << 8;
|
||||
i |= (get() & 0xff);
|
||||
return i;
|
||||
}
|
||||
|
||||
public short getShort() {
|
||||
checkGet(2);
|
||||
short s = (short)(get() << 8);
|
||||
s |= get() & 0xff;
|
||||
return s;
|
||||
return (short) (( ((int) (doGet(position ) & 0xFF)) << 8)
|
||||
| (((int) (doGet(position + 1) & 0xFF)) ));
|
||||
}
|
||||
|
||||
public long getLong() {
|
||||
checkGet(8);
|
||||
long l = (long)getInt() << 32;
|
||||
l |= (long)getInt() & 0xffffffffL;
|
||||
return l;
|
||||
long r = getLong(position);
|
||||
position += 8;
|
||||
return r;
|
||||
}
|
||||
|
||||
private void checkPut(int amount) {
|
||||
if (readOnly) throw new ReadOnlyBufferException();
|
||||
if (amount > limit-position) throw new IndexOutOfBoundsException();
|
||||
public int getInt() {
|
||||
int r = getInt(position);
|
||||
position += 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
private void checkPut(int position, int amount) {
|
||||
public short getShort() {
|
||||
short r = getShort(position);
|
||||
position += 2;
|
||||
return r;
|
||||
}
|
||||
|
||||
protected void checkPut(int position, int amount) {
|
||||
if (readOnly) throw new ReadOnlyBufferException();
|
||||
if (position < 0 || position+amount > limit)
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
private void checkGet(int amount) {
|
||||
protected void checkGet(int position, int amount) {
|
||||
if (amount > limit-position) throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
private void checkGet(int position, int amount) {
|
||||
if (position < 0 || position+amount > limit)
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "(ByteBuffer with array: " + array + " arrayOffset: " + arrayOffset + " position: " + position + " remaining; " + remaining() + ")";
|
||||
}
|
||||
}
|
||||
|
105
classpath/java/nio/DirectByteBuffer.java
Normal file
105
classpath/java/nio/DirectByteBuffer.java
Normal file
@ -0,0 +1,105 @@
|
||||
/* Copyright (c) 2008-2012, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.nio;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
class DirectByteBuffer extends ByteBuffer {
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private static final int baseOffset = unsafe.arrayBaseOffset(byte[].class);
|
||||
|
||||
protected final long address;
|
||||
|
||||
protected DirectByteBuffer(long address, int capacity, boolean readOnly) {
|
||||
super(readOnly);
|
||||
|
||||
this.address = address;
|
||||
this.capacity = capacity;
|
||||
this.limit = capacity;
|
||||
this.position = 0;
|
||||
}
|
||||
|
||||
protected DirectByteBuffer(long address, int capacity) {
|
||||
this(address, capacity, false);
|
||||
}
|
||||
|
||||
public ByteBuffer asReadOnlyBuffer() {
|
||||
ByteBuffer b = new DirectByteBuffer(address, capacity, true);
|
||||
b.position(position());
|
||||
b.limit(limit());
|
||||
return b;
|
||||
}
|
||||
|
||||
public ByteBuffer slice() {
|
||||
return new DirectByteBuffer(address + position, remaining(), true);
|
||||
}
|
||||
|
||||
protected void doPut(int position, byte val) {
|
||||
unsafe.putByte(address + position, val);
|
||||
}
|
||||
|
||||
public ByteBuffer put(ByteBuffer src) {
|
||||
if (src instanceof DirectByteBuffer) {
|
||||
checkPut(position, src.remaining());
|
||||
|
||||
DirectByteBuffer b = (DirectByteBuffer) src;
|
||||
|
||||
unsafe.copyMemory
|
||||
(b.address + b.position, address + position, b.remaining());
|
||||
|
||||
position += b.remaining();
|
||||
b.position += b.remaining();
|
||||
|
||||
return this;
|
||||
} else {
|
||||
return super.put(src);
|
||||
}
|
||||
}
|
||||
|
||||
public ByteBuffer put(byte[] src, int offset, int length) {
|
||||
if (offset < 0 || offset + length > src.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
checkPut(position, length);
|
||||
|
||||
unsafe.copyMemory
|
||||
(src, baseOffset + offset, null, address + position, length);
|
||||
|
||||
position += length;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer get(byte[] dst, int offset, int length) {
|
||||
if (offset < 0 || offset + length > dst.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
checkGet(position, length);
|
||||
|
||||
unsafe.copyMemory
|
||||
(null, address + position, dst, baseOffset + offset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected byte doGet(int position) {
|
||||
return unsafe.getByte(address + position);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "(DirectByteBuffer with address: " + address
|
||||
+ " position: " + position
|
||||
+ " limit: " + limit
|
||||
+ " capacity: " + capacity + ")";
|
||||
}
|
||||
}
|
58
classpath/java/nio/FixedArrayByteBuffer.java
Normal file
58
classpath/java/nio/FixedArrayByteBuffer.java
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (c) 2008-2012, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.nio;
|
||||
|
||||
class FixedArrayByteBuffer extends DirectByteBuffer {
|
||||
private final byte[] array;
|
||||
private final int arrayOffset;
|
||||
|
||||
private FixedArrayByteBuffer(long address,
|
||||
byte[] array,
|
||||
int offset,
|
||||
int capacity,
|
||||
boolean readOnly)
|
||||
{
|
||||
super(address, capacity, readOnly);
|
||||
|
||||
this.array = array;
|
||||
this.arrayOffset = offset;
|
||||
}
|
||||
|
||||
public static FixedArrayByteBuffer make(int capacity) {
|
||||
long[] address = new long[1];
|
||||
byte[] array = allocateFixed(capacity, address);
|
||||
return new FixedArrayByteBuffer(address[0], array, 0, capacity, false);
|
||||
}
|
||||
|
||||
private static native byte[] allocateFixed(int capacity, long[] address);
|
||||
|
||||
public ByteBuffer asReadOnlyBuffer() {
|
||||
ByteBuffer b = new FixedArrayByteBuffer
|
||||
(address, array, arrayOffset, capacity, true);
|
||||
b.position(position());
|
||||
b.limit(limit());
|
||||
return b;
|
||||
}
|
||||
|
||||
public ByteBuffer slice() {
|
||||
return new FixedArrayByteBuffer
|
||||
(address + position, array, arrayOffset + position, remaining(), true);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "(FixedArrayByteBuffer with address: " + address
|
||||
+ " array: " + array
|
||||
+ " arrayOffset: " + arrayOffset
|
||||
+ " position: " + position
|
||||
+ " limit: " + limit
|
||||
+ " capacity: " + capacity + ")";
|
||||
}
|
||||
}
|
@ -47,4 +47,14 @@ public final class Unsafe {
|
||||
public native long getAddress(long address);
|
||||
|
||||
public native void putAddress(long address, long x);
|
||||
|
||||
public native int arrayBaseOffset(Class arrayClass);
|
||||
|
||||
public native void copyMemory(Object srcBase, long srcOffset,
|
||||
Object destBase, long destOffset,
|
||||
long count);
|
||||
|
||||
public void copyMemory(long src, long dst, long count) {
|
||||
copyMemory(null, src, null, dst, count);
|
||||
}
|
||||
}
|
||||
|
@ -511,3 +511,55 @@ Avian_sun_misc_Unsafe_getAddress__J
|
||||
|
||||
return *reinterpret_cast<intptr_t*>(p);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Avian_sun_misc_Unsafe_copyMemory
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
object srcBase = reinterpret_cast<object>(arguments[1]);
|
||||
int64_t srcOffset; memcpy(&srcOffset, arguments + 2, 8);
|
||||
object dstBase = reinterpret_cast<object>(arguments[4]);
|
||||
int64_t dstOffset; memcpy(&dstOffset, arguments + 5, 8);
|
||||
int64_t count; memcpy(&count, arguments + 7, 8);
|
||||
|
||||
PROTECT(t, srcBase);
|
||||
PROTECT(t, dstBase);
|
||||
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
void* src = srcBase
|
||||
? &cast<uint8_t>(srcBase, srcOffset)
|
||||
: reinterpret_cast<uint8_t*>(srcOffset);
|
||||
|
||||
void* dst = dstBase
|
||||
? &cast<uint8_t>(dstBase, dstOffset)
|
||||
: reinterpret_cast<uint8_t*>(dstOffset);
|
||||
|
||||
memcpy(dst, src, count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_sun_misc_Unsafe_arrayBaseOffset
|
||||
(Thread*, object, uintptr_t*)
|
||||
{
|
||||
return ArrayBody;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_java_nio_FixedArrayByteBuffer_allocateFixed
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
int capacity = arguments[0];
|
||||
object address = reinterpret_cast<object>(arguments[1]);
|
||||
PROTECT(t, address);
|
||||
|
||||
object array = allocate3
|
||||
(t, t->m->heap, Machine::FixedAllocation, ArrayBody + capacity, false);
|
||||
|
||||
setObjectClass(t, array, type(t, Machine::ByteArrayType));
|
||||
byteArrayLength(t, array) = capacity;
|
||||
|
||||
longArrayBody(t, address, 0) = reinterpret_cast<intptr_t>(array) + ArrayBody;
|
||||
|
||||
return reinterpret_cast<intptr_t>(array);
|
||||
}
|
||||
|
@ -2396,13 +2396,6 @@ Avian_sun_misc_Unsafe_staticFieldOffset
|
||||
(t, jclassVmClass(t, jfieldClazz(t, jfield))), jfieldSlot(t, jfield)));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_sun_misc_Unsafe_arrayBaseOffset
|
||||
(Thread*, object, uintptr_t*)
|
||||
{
|
||||
return BytesPerWord * 2;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_sun_misc_Unsafe_arrayIndexScale
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
@ -2522,6 +2515,14 @@ Avian_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J
|
||||
return cast<int64_t>(o, offset);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J
|
||||
(Thread* t, object method, uintptr_t* arguments)
|
||||
{
|
||||
return Avian_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J
|
||||
(t, method, arguments);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_sun_misc_Unsafe_getLongVolatile
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
@ -2784,32 +2785,6 @@ Avian_sun_misc_Unsafe_park
|
||||
monitorRelease(t, local::interruptLock(t, t->javaThread));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Avian_sun_misc_Unsafe_copyMemory
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
object srcBase = reinterpret_cast<object>(arguments[1]);
|
||||
int64_t srcOffset; memcpy(&srcOffset, arguments + 2, 8);
|
||||
object dstBase = reinterpret_cast<object>(arguments[4]);
|
||||
int64_t dstOffset; memcpy(&dstOffset, arguments + 5, 8);
|
||||
int64_t count; memcpy(&count, arguments + 7, 8);
|
||||
|
||||
PROTECT(t, srcBase);
|
||||
PROTECT(t, dstBase);
|
||||
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
void* src = srcBase
|
||||
? &cast<uint8_t>(srcBase, srcOffset)
|
||||
: reinterpret_cast<uint8_t*>(srcOffset);
|
||||
|
||||
void* dst = dstBase
|
||||
? &cast<uint8_t>(dstBase, dstOffset)
|
||||
: reinterpret_cast<uint8_t*>(dstOffset);
|
||||
|
||||
memcpy(dst, src, count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Avian_sun_misc_Unsafe_monitorEnter
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
@ -3023,6 +2998,8 @@ jvmInitProperties(Thread* t, uintptr_t* arguments)
|
||||
local::setProperty(t, method, *properties, "java.vm.vendor",
|
||||
"Avian Contributors");
|
||||
|
||||
local::setProperty(t, method, *properties, "java.vm.name","Avian");
|
||||
|
||||
local::setProperty
|
||||
(t, method, *properties, "java.home",
|
||||
static_cast<local::MyClasspath*>(t->m->classpath)->javaHome);
|
||||
|
@ -202,6 +202,17 @@ class MyThread: public Thread {
|
||||
bool methodIsMostRecent;
|
||||
};
|
||||
|
||||
class ReferenceFrame {
|
||||
public:
|
||||
ReferenceFrame(ReferenceFrame* next, Reference* reference):
|
||||
next(next),
|
||||
reference(reference)
|
||||
{ }
|
||||
|
||||
ReferenceFrame* next;
|
||||
Reference* reference;
|
||||
};
|
||||
|
||||
static void doTransition(MyThread* t, void* ip, void* stack,
|
||||
object continuation, MyThread::CallTrace* trace)
|
||||
{
|
||||
@ -255,6 +266,7 @@ class MyThread: public Thread {
|
||||
transition(0),
|
||||
traceContext(0),
|
||||
stackLimit(0),
|
||||
referenceFrame(0),
|
||||
methodLockIsClean(true)
|
||||
{
|
||||
arch->acquire();
|
||||
@ -280,6 +292,7 @@ class MyThread: public Thread {
|
||||
Context* transition;
|
||||
TraceContext* traceContext;
|
||||
uintptr_t stackLimit;
|
||||
ReferenceFrame* referenceFrame;
|
||||
bool methodLockIsClean;
|
||||
};
|
||||
|
||||
@ -8778,6 +8791,32 @@ class MyProcessor: public Processor {
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool
|
||||
pushLocalFrame(Thread* vmt, unsigned)
|
||||
{
|
||||
MyThread* t = static_cast<MyThread*>(vmt);
|
||||
|
||||
t->referenceFrame = new
|
||||
(t->m->heap->allocate(sizeof(MyThread::ReferenceFrame)))
|
||||
MyThread::ReferenceFrame(t->referenceFrame, t->reference);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void
|
||||
popLocalFrame(Thread* vmt)
|
||||
{
|
||||
MyThread* t = static_cast<MyThread*>(vmt);
|
||||
|
||||
MyThread::ReferenceFrame* f = t->referenceFrame;
|
||||
t->referenceFrame = f->next;
|
||||
while (t->reference != f->reference) {
|
||||
vm::dispose(t, t->reference);
|
||||
}
|
||||
|
||||
t->m->heap->free(f, sizeof(MyThread::ReferenceFrame));
|
||||
}
|
||||
|
||||
virtual object
|
||||
invokeArray(Thread* t, object method, object this_, object arguments)
|
||||
{
|
||||
|
@ -28,18 +28,31 @@ const unsigned FrameFootprint = 4;
|
||||
|
||||
class Thread: public vm::Thread {
|
||||
public:
|
||||
class ReferenceFrame {
|
||||
public:
|
||||
ReferenceFrame(ReferenceFrame* next, unsigned sp):
|
||||
next(next),
|
||||
sp(sp)
|
||||
{ }
|
||||
|
||||
ReferenceFrame* next;
|
||||
unsigned sp;
|
||||
};
|
||||
|
||||
Thread(Machine* m, object javaThread, vm::Thread* parent):
|
||||
vm::Thread(m, javaThread, parent),
|
||||
ip(0),
|
||||
sp(0),
|
||||
frame(-1),
|
||||
code(0)
|
||||
code(0),
|
||||
referenceFrame(0)
|
||||
{ }
|
||||
|
||||
unsigned ip;
|
||||
unsigned sp;
|
||||
int frame;
|
||||
object code;
|
||||
ReferenceFrame* referenceFrame;
|
||||
uintptr_t stack[0];
|
||||
};
|
||||
|
||||
@ -3010,6 +3023,34 @@ class MyProcessor: public Processor {
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool
|
||||
pushLocalFrame(vm::Thread* vmt, unsigned capacity)
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(vmt);
|
||||
|
||||
if (t->sp + capacity < stackSizeInWords(t) / 2) {
|
||||
t->referenceFrame = new
|
||||
(t->m->heap->allocate(sizeof(Thread::ReferenceFrame)))
|
||||
Thread::ReferenceFrame(t->referenceFrame, t->sp);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void
|
||||
popLocalFrame(vm::Thread* vmt)
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(vmt);
|
||||
|
||||
Thread::ReferenceFrame* f = t->referenceFrame;
|
||||
t->referenceFrame = f->next;
|
||||
t->sp = f->sp;
|
||||
|
||||
t->m->heap->free(f, sizeof(Thread::ReferenceFrame));
|
||||
}
|
||||
|
||||
virtual object
|
||||
invokeArray(vm::Thread* vmt, object method, object this_, object arguments)
|
||||
{
|
||||
|
@ -407,24 +407,6 @@ ExceptionCheck(Thread* t)
|
||||
return t->exception != 0;
|
||||
}
|
||||
|
||||
jobject JNICALL
|
||||
NewDirectByteBuffer(Thread*, void*, jlong)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* JNICALL
|
||||
GetDirectBufferAddress(Thread*, jobject)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
jlong JNICALL
|
||||
GetDirectBufferCapacity(Thread*, jobject)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
getObjectClass(Thread* t, uintptr_t* arguments)
|
||||
{
|
||||
@ -439,7 +421,7 @@ GetObjectClass(Thread* t, jobject o)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o) };
|
||||
|
||||
return reinterpret_cast<jobject>(run(t, getObjectClass, arguments));
|
||||
return reinterpret_cast<jclass>(run(t, getObjectClass, arguments));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
@ -3154,6 +3136,8 @@ GetPrimitiveArrayCritical(Thread* t, jarray array, jboolean* isCopy)
|
||||
*isCopy = true;
|
||||
}
|
||||
|
||||
expect(t, *array);
|
||||
|
||||
return reinterpret_cast<uintptr_t*>(*array) + 2;
|
||||
}
|
||||
|
||||
@ -3276,6 +3260,66 @@ IsSameObject(Thread* t, jobject a, jobject b)
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
pushLocalFrame(Thread* t, uintptr_t* arguments)
|
||||
{
|
||||
if (t->m->processor->pushLocalFrame(t, arguments[0])) {
|
||||
return 1;
|
||||
} else {
|
||||
throw_(t, root(t, Machine::OutOfMemoryError));
|
||||
}
|
||||
}
|
||||
|
||||
jint JNICALL
|
||||
PushLocalFrame(Thread* t, jint capacity)
|
||||
{
|
||||
uintptr_t arguments[] = { static_cast<uintptr_t>(capacity) };
|
||||
|
||||
return run(t, pushLocalFrame, arguments) ? 0 : -1;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
popLocalFrame(Thread* t, uintptr_t* arguments)
|
||||
{
|
||||
object result = *reinterpret_cast<jobject>(arguments[0]);
|
||||
PROTECT(t, result);
|
||||
|
||||
t->m->processor->popLocalFrame(t);
|
||||
|
||||
return reinterpret_cast<uint64_t>(makeLocalReference(t, result));
|
||||
}
|
||||
|
||||
jobject JNICALL
|
||||
PopLocalFrame(Thread* t, jobject result)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(result) };
|
||||
|
||||
return reinterpret_cast<jobject>(run(t, popLocalFrame, arguments));
|
||||
}
|
||||
|
||||
jobject JNICALL
|
||||
NewDirectByteBuffer(Thread* t, void* p, jlong capacity)
|
||||
{
|
||||
jclass c = FindClass(t, "java/nio/DirectByteBuffer");
|
||||
return NewObject(t, c, GetMethodID(t, c, "<init>", "(JI)V"),
|
||||
reinterpret_cast<jlong>(p),
|
||||
static_cast<jint>(capacity));
|
||||
}
|
||||
|
||||
void* JNICALL
|
||||
GetDirectBufferAddress(Thread* t, jobject b)
|
||||
{
|
||||
return reinterpret_cast<void*>
|
||||
(GetLongField(t, b, GetFieldID(t, GetObjectClass(t, b), "address", "J")));
|
||||
}
|
||||
|
||||
jlong JNICALL
|
||||
GetDirectBufferCapacity(Thread* t, jobject b)
|
||||
{
|
||||
return GetIntField
|
||||
(t, b, GetFieldID(t, GetObjectClass(t, b), "capacity", "I"));
|
||||
}
|
||||
|
||||
struct JavaVMOption {
|
||||
char* optionString;
|
||||
void* extraInfo;
|
||||
@ -3556,6 +3600,8 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
||||
envTable->MonitorExit = local::MonitorExit;
|
||||
envTable->GetJavaVM = local::GetJavaVM;
|
||||
envTable->IsSameObject = local::IsSameObject;
|
||||
envTable->PushLocalFrame = local::PushLocalFrame;
|
||||
envTable->PopLocalFrame = local::PopLocalFrame;
|
||||
}
|
||||
|
||||
} // namespace vm
|
||||
|
@ -103,6 +103,12 @@ class Processor {
|
||||
virtual void
|
||||
disposeLocalReference(Thread* t, object* r) = 0;
|
||||
|
||||
virtual bool
|
||||
pushLocalFrame(Thread* t, unsigned capacity) = 0;
|
||||
|
||||
virtual void
|
||||
popLocalFrame(Thread* t) = 0;
|
||||
|
||||
virtual object
|
||||
invokeArray(Thread* t, object method, object this_, object arguments) = 0;
|
||||
|
||||
|
15
test/jni.cpp
15
test/jni.cpp
@ -36,3 +36,18 @@ Java_JNI_addMix
|
||||
return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13
|
||||
+ a14 + a15 + a16 + a17 + a18 + a19 + a20;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_Buffers_allocateNative(JNIEnv* e, jclass, jint capacity)
|
||||
{
|
||||
void* p = allocate(e, capacity);
|
||||
if (p == 0) return 0;
|
||||
|
||||
return e->NewDirectByteBuffer(p, capacity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_Buffers_freeNative(JNIEnv* e, jclass, jobject b)
|
||||
{
|
||||
free(e->GetDirectBufferAddress(b));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user