Mercurial > hg > graal-jvmci-8
changeset 20864:43b3db5e8a9e
UnsafeArrayType(Writer|Reader): Use naturally aligned Unsafe access (Important for SPARC)
author | Stefan Anzinger <stefan.anzinger@oracle.com> |
---|---|
date | Thu, 09 Apr 2015 15:35:29 +0200 |
parents | 4dbbc4b3bb4d |
children | 98af261f22f0 |
files | graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/UnsafeArrayTypeReader.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/UnsafeArrayTypeWriter.java |
diffstat | 2 files changed, 81 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/UnsafeArrayTypeReader.java Thu Apr 09 13:27:37 2015 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/UnsafeArrayTypeReader.java Thu Apr 09 15:35:29 2015 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.common.util; +import java.nio.*; + import sun.misc.*; import com.oracle.graal.compiler.common.*; @@ -41,23 +43,44 @@ } public static int getS2(byte[] data, long byteIndex) { - return UnsafeAccess.unsafe.getShort(data, readOffset(data, byteIndex, Short.BYTES)); + if (byteIndex % Short.BYTES == 0) { + return UnsafeAccess.unsafe.getShort(data, readOffset(data, byteIndex, Short.BYTES)); + } else { + ByteBuffer buf = ByteBuffer.wrap(new byte[Short.BYTES]); + buf.put((byte) getU1(data, byteIndex)); + buf.put((byte) getU1(data, byteIndex + Byte.BYTES)); + return buf.getShort(0); + } } public static int getU2(byte[] data, long byteIndex) { - return UnsafeAccess.unsafe.getShort(data, readOffset(data, byteIndex, Short.BYTES)) & 0xFFFF; + return getS2(data, byteIndex) & 0xFFFF; } public static int getS4(byte[] data, long byteIndex) { - return UnsafeAccess.unsafe.getInt(data, readOffset(data, byteIndex, Integer.BYTES)); + if (byteIndex % Integer.BYTES == 0) { + return UnsafeAccess.unsafe.getInt(data, readOffset(data, byteIndex, Integer.BYTES)); + } else { + ByteBuffer buf = ByteBuffer.wrap(new byte[Integer.BYTES]); + buf.putShort((short) getS2(data, byteIndex)); + buf.putShort((short) getS2(data, byteIndex + Short.BYTES)); + return buf.getInt(0); + } } public static long getU4(byte[] data, long byteIndex) { - return UnsafeAccess.unsafe.getInt(data, readOffset(data, byteIndex, Integer.BYTES)) & 0xFFFFFFFFL; + return getS4(data, byteIndex) & 0xFFFFFFFFL; } public static long getLong(byte[] data, long byteIndex) { - return UnsafeAccess.unsafe.getLong(data, readOffset(data, byteIndex, Long.BYTES)); + if (byteIndex % Long.BYTES == 0) { + return UnsafeAccess.unsafe.getLong(data, readOffset(data, byteIndex, Long.BYTES)); + } else { + ByteBuffer buf = ByteBuffer.wrap(new byte[Long.BYTES]); + buf.putInt(getS4(data, byteIndex)); + buf.putInt(getS4(data, byteIndex + Integer.BYTES)); + return buf.getLong(0); + } } private static long readOffset(byte[] data, long byteIndex, int numBytes) {
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/UnsafeArrayTypeWriter.java Thu Apr 09 13:27:37 2015 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/UnsafeArrayTypeWriter.java Thu Apr 09 15:35:29 2015 +0200 @@ -22,6 +22,10 @@ */ package com.oracle.graal.compiler.common.util; +import static com.oracle.graal.compiler.common.util.TypeConversion.*; + +import java.nio.*; + import sun.misc.*; import com.oracle.graal.compiler.common.*; @@ -72,43 +76,79 @@ @Override public void putS1(long value) { long offset = writeOffset(Byte.BYTES); - UnsafeAccess.unsafe.putByte(writeChunk.data, offset, TypeConversion.asS1(value)); + UnsafeAccess.unsafe.putByte(writeChunk.data, offset, asS1(value)); + commitWrite(Byte.BYTES); } @Override public void putU1(long value) { long offset = writeOffset(Byte.BYTES); - UnsafeAccess.unsafe.putByte(writeChunk.data, offset, TypeConversion.asU1(value)); + UnsafeAccess.unsafe.putByte(writeChunk.data, offset, asU1(value)); + commitWrite(Byte.BYTES); } @Override public void putS2(long value) { long offset = writeOffset(Short.BYTES); - UnsafeAccess.unsafe.putShort(writeChunk.data, offset, TypeConversion.asS2(value)); + if (offset % Short.BYTES == 0) { + UnsafeAccess.unsafe.putShort(writeChunk.data, offset, asS2(value)); + commitWrite(Short.BYTES); + } else { + ByteBuffer buf = ByteBuffer.wrap(new byte[Short.BYTES]); + buf.putShort(asS2(value)); + putS1(buf.get(0)); + putS1(buf.get(Byte.BYTES)); + } } @Override public void putU2(long value) { - long offset = writeOffset(Short.BYTES); - UnsafeAccess.unsafe.putShort(writeChunk.data, offset, TypeConversion.asU2(value)); + putS2(asU2(value)); } @Override public void putS4(long value) { long offset = writeOffset(Integer.BYTES); - UnsafeAccess.unsafe.putInt(writeChunk.data, offset, TypeConversion.asS4(value)); + if (offset % Integer.BYTES == 0) { + UnsafeAccess.unsafe.putInt(writeChunk.data, offset, asS4(value)); + commitWrite(Integer.BYTES); + } else { + ByteBuffer buf = ByteBuffer.wrap(new byte[Integer.BYTES]); + buf.putInt(asS4(value)); + if (offset % Short.BYTES == 0) { + putS2(buf.getShort(0)); + putS2(buf.getShort(2)); + } else { + putS1(buf.get(0)); + putS2(buf.getShort(1)); + putS1(buf.get(3)); + } + } } @Override public void putU4(long value) { - long offset = writeOffset(Integer.BYTES); - UnsafeAccess.unsafe.putInt(writeChunk.data, offset, TypeConversion.asU4(value)); + putS4(asU4(value)); } @Override public void putS8(long value) { long offset = writeOffset(Long.BYTES); - UnsafeAccess.unsafe.putLong(writeChunk.data, offset, value); + if (offset % Long.BYTES == 0) { + UnsafeAccess.unsafe.putLong(writeChunk.data, offset, value); + commitWrite(Long.BYTES); + } else { + ByteBuffer buf = ByteBuffer.wrap(new byte[Long.BYTES]); + buf.putLong(value); + if (offset % Integer.BYTES == 0) { + putS4(buf.getInt(0)); + putS4(buf.getInt(4)); + } else { + putS2(buf.getShort(0)); + putS4(buf.getInt(2)); + putS2(buf.getShort(6)); + } + } } private long writeOffset(int writeBytes) { @@ -121,10 +161,12 @@ assert Unsafe.ARRAY_BYTE_INDEX_SCALE == 1; long result = writeChunk.size + Unsafe.ARRAY_BYTE_BASE_OFFSET; + return result; + } + + private void commitWrite(int writeBytes) { totalSize += writeBytes; writeChunk.size += writeBytes; assert writeChunk.size <= writeChunk.data.length; - - return result; } }