Jo Shields 8b9b85e7f5 Imported Upstream version 3.10.0
Former-commit-id: 172c8e3c300b39d5785c7a3e8dfb08ebdbc1a99b
2014-10-04 11:27:48 +01:00

278 lines
6.9 KiB
C#

/*
Copyright (C) 2007-2013 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using IKVM.Internal;
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
[SecurityCritical]
static class Java_java_nio_Bits
{
public static void copyFromShortArray(object src, long srcPos, long dstAddr, long length)
{
#if !FIRST_PASS
short[] shortArray = src as short[];
if (shortArray != null)
{
int index = ((int)srcPos) >> 1;
while (length > 0)
{
short v = java.lang.Short.reverseBytes(shortArray[index++]);
Marshal.WriteInt16((IntPtr)dstAddr, v);
dstAddr += 2;
length -= 2;
}
}
else
{
char[] charArray = (char[])src;
int index = ((int)srcPos) >> 1;
while (length > 0)
{
short v = java.lang.Short.reverseBytes((short)charArray[index++]);
Marshal.WriteInt16((IntPtr)dstAddr, v);
dstAddr += 2;
length -= 2;
}
}
#endif
}
public static void copyToShortArray(long srcAddr, object dst, long dstPos, long length)
{
#if !FIRST_PASS
short[] shortArray = dst as short[];
if (shortArray != null)
{
int index = ((int)dstPos) >> 1;
while (length > 0)
{
short v = Marshal.ReadInt16((IntPtr)srcAddr);
shortArray[index++] = java.lang.Short.reverseBytes(v);
srcAddr += 2;
length -= 2;
}
}
else
{
char[] charArray = (char[])dst;
int index = ((int)dstPos) >> 1;
while (length > 0)
{
short v = Marshal.ReadInt16((IntPtr)srcAddr);
charArray[index++] = (char)java.lang.Short.reverseBytes(v);
srcAddr += 2;
length -= 2;
}
}
#endif
}
public static void copyFromIntArray(object src, long srcPos, long dstAddr, long length)
{
#if !FIRST_PASS
int[] intArray = src as int[];
if (intArray != null)
{
int index = ((int)srcPos) >> 2;
while (length > 0)
{
int v = java.lang.Integer.reverseBytes(intArray[index++]);
Marshal.WriteInt32((IntPtr)dstAddr, v);
dstAddr += 4;
length -= 4;
}
}
else
{
float[] floatArray = (float[])src;
int index = ((int)srcPos) >> 2;
while (length > 0)
{
int v = java.lang.Integer.reverseBytes(java.lang.Float.floatToRawIntBits(floatArray[index++]));
Marshal.WriteInt32((IntPtr)dstAddr, v);
dstAddr += 4;
length -= 4;
}
}
#endif
}
public static void copyToIntArray(long srcAddr, object dst, long dstPos, long length)
{
#if !FIRST_PASS
int[] intArray = dst as int[];
if (intArray != null)
{
int index = ((int)dstPos) >> 2;
while (length > 0)
{
int v = Marshal.ReadInt32((IntPtr)srcAddr);
intArray[index++] = java.lang.Integer.reverseBytes(v);
srcAddr += 4;
length -= 4;
}
}
else
{
float[] floatArray = (float[])dst;
int index = ((int)dstPos) >> 2;
while (length > 0)
{
int v = Marshal.ReadInt32((IntPtr)srcAddr);
floatArray[index++] = java.lang.Float.intBitsToFloat(java.lang.Integer.reverseBytes(v));
srcAddr += 4;
length -= 4;
}
}
#endif
}
public static void copyFromLongArray(object src, long srcPos, long dstAddr, long length)
{
#if !FIRST_PASS
long[] longArray = src as long[];
if (longArray != null)
{
int index = ((int)srcPos) >> 3;
while (length > 0)
{
long v = java.lang.Long.reverseBytes(longArray[index++]);
Marshal.WriteInt64((IntPtr)dstAddr, v);
dstAddr += 8;
length -= 8;
}
}
else
{
double[] doubleArray = (double[])src;
int index = ((int)srcPos) >> 3;
while (length > 0)
{
long v = java.lang.Long.reverseBytes(BitConverter.DoubleToInt64Bits(doubleArray[index++]));
Marshal.WriteInt64((IntPtr)dstAddr, v);
dstAddr += 8;
length -= 8;
}
}
#endif
}
public static void copyToLongArray(long srcAddr, object dst, long dstPos, long length)
{
#if !FIRST_PASS
long[] longArray = dst as long[];
if (longArray != null)
{
int index = ((int)dstPos) >> 3;
while (length > 0)
{
long v = Marshal.ReadInt64((IntPtr)srcAddr);
longArray[index++] = java.lang.Long.reverseBytes(v);
srcAddr += 8;
length -= 8;
}
}
else
{
double[] doubleArray = (double[])dst;
int index = ((int)dstPos) >> 3;
while (length > 0)
{
long v = Marshal.ReadInt64((IntPtr)srcAddr);
doubleArray[index++] = BitConverter.Int64BitsToDouble(java.lang.Long.reverseBytes(v));
srcAddr += 8;
length -= 8;
}
}
#endif
}
}
static class Java_java_nio_MappedByteBuffer
{
private static volatile int bogusField;
public static bool isLoaded0(object thisMappedByteBuffer, long address, long length, int pageCount)
{
// on Windows, JDK simply returns false, so we can get away with that too.
return false;
}
[SecuritySafeCritical]
public static void load0(object thisMappedByteBuffer, long address, long length)
{
int bogus = bogusField;
while (length > 0)
{
// touch a byte in every page
bogus += Marshal.ReadByte((IntPtr)address);
length -= 4096;
address += 4096;
}
// do a volatile store of the sum of the bytes to make sure the reads don't get optimized out
bogusField = bogus;
GC.KeepAlive(thisMappedByteBuffer);
}
[SecuritySafeCritical]
public static void force0(object thisMappedByteBuffer, object fd, long address, long length)
{
if (JVM.IsUnix)
{
ikvm_msync((IntPtr)address, (int)length);
GC.KeepAlive(thisMappedByteBuffer);
}
else
{
// according to the JDK sources, FlushViewOfFile can fail with an ERROR_LOCK_VIOLATION error,
// so like the JDK, we retry up to three times if that happens.
for (int i = 0; i < 3; i++)
{
if (FlushViewOfFile((IntPtr)address, (IntPtr)length) != 0)
{
GC.KeepAlive(thisMappedByteBuffer);
return;
}
const int ERROR_LOCK_VIOLATION = 33;
if (Marshal.GetLastWin32Error() != ERROR_LOCK_VIOLATION)
{
break;
}
}
#if !FIRST_PASS
throw new java.io.IOException("Flush failed");
#endif
}
}
[DllImport("kernel32", SetLastError = true)]
private static extern int FlushViewOfFile(IntPtr lpBaseAddress, IntPtr dwNumberOfBytesToFlush);
[DllImport("ikvm-native")]
private static extern int ikvm_msync(IntPtr address, int size);
}