Skip to content

Commit 9c1a9e0

Browse files
steve-sotethal
authored andcommitted
Use Unsafe to implement mmap in NFIPosixBackend
1 parent 46549d7 commit 9c1a9e0

File tree

2 files changed

+43
-38
lines changed

2 files changed

+43
-38
lines changed

graalpython/com.oracle.graal.python.cext/posix/posix.c

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -522,31 +522,19 @@ int32_t call_system(const char *pathname) {
522522
return system(pathname);
523523
}
524524

525-
void *call_mmap(int64_t length, int32_t prot, int32_t flags, int32_t fd, int64_t offset) {
525+
int64_t call_mmap(int64_t length, int32_t prot, int32_t flags, int32_t fd, int64_t offset) {
526526
void *result = mmap(NULL, length, prot, flags, fd, offset);
527-
return result == MAP_FAILED ? NULL : result;
527+
return result == MAP_FAILED ? 0 : (int64_t) result;
528528
}
529529

530-
int32_t call_munmap(void* address, int64_t length) {
531-
return munmap(address, length);
530+
int32_t call_munmap(int64_t address, int64_t length) {
531+
return munmap((void *) address, length);
532532
}
533533

534-
void call_msync(void* address, int64_t offset, int64_t length) {
534+
void call_msync(int64_t address, int64_t offset, int64_t length) {
535535
// TODO: can be generalized to also accept different flags,
536536
// but MS_SYNC and such seem to be defined to different values across systems
537-
msync(address + offset, length, MS_SYNC);
538-
}
539-
540-
int8_t read_byte(int8_t *address, int64_t index) {
541-
return address[index];
542-
}
543-
544-
void write_bytes(int8_t *address, int8_t* buffer, int64_t index, int32_t length) {
545-
memcpy(address + index, buffer, length);
546-
}
547-
548-
void read_bytes(int8_t *address, int8_t* buffer, int64_t index, int32_t length) {
549-
memcpy(buffer, address + index, length);
537+
msync(((int8_t *) address) + offset, length, MS_SYNC);
550538
}
551539

552540
int32_t get_errno() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NFIPosixSupport.java

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,13 @@
4343
import static com.oracle.truffle.api.CompilerDirectives.SLOWPATH_PROBABILITY;
4444
import static com.oracle.truffle.api.CompilerDirectives.injectBranchProbability;
4545

46+
import java.lang.reflect.Field;
4647
import java.util.Arrays;
4748
import java.util.concurrent.atomic.AtomicReferenceArray;
4849
import java.util.logging.Level;
4950

51+
import org.graalvm.nativeimage.ImageInfo;
52+
5053
import com.oracle.graal.python.PythonLanguage;
5154
import com.oracle.graal.python.builtins.modules.GraalPythonModuleBuiltins;
5255
import com.oracle.graal.python.builtins.objects.bytes.BytesUtils;
@@ -77,7 +80,8 @@
7780
import com.oracle.truffle.api.nodes.Node;
7881
import com.oracle.truffle.api.source.Source;
7982
import com.oracle.truffle.llvm.api.Toolchain;
80-
import org.graalvm.nativeimage.ImageInfo;
83+
84+
import sun.misc.Unsafe;
8185

8286
/**
8387
* Implementation that invokes the native POSIX functions directly using NFI. This requires either
@@ -96,15 +100,28 @@ public final class NFIPosixSupport extends PosixSupport {
96100

97101
private static final TruffleLogger LOGGER = PythonLanguage.getLogger(NFIPosixSupport.class);
98102

103+
private static final Unsafe UNSAFE = initUnsafe();
104+
105+
private static Unsafe initUnsafe() {
106+
try {
107+
return Unsafe.getUnsafe();
108+
} catch (SecurityException se) {
109+
try {
110+
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
111+
theUnsafe.setAccessible(true);
112+
return (Unsafe) theUnsafe.get(Unsafe.class);
113+
} catch (Exception e) {
114+
throw new UnsupportedOperationException("Cannot initialize Unsafe for the native POSIX backend", e);
115+
}
116+
}
117+
}
118+
99119
private enum PosixNativeFunction {
100120
get_errno("():sint32"),
101121
set_errno("(sint32):void"),
102-
read_byte("(pointer, sint64):sint8"),
103-
read_bytes("(pointer, [sint8], sint64, sint32):void"),
104-
write_bytes("(pointer, [sint8], sint64, sint32):void"),
105-
call_mmap("(sint64, sint32, sint32, sint32, sint64):pointer"),
106-
call_munmap("(pointer, sint64):sint32"),
107-
call_msync("(pointer, sint64, sint64):void"),
122+
call_mmap("(sint64, sint32, sint32, sint32, sint64):sint64"),
123+
call_munmap("(sint64, sint64):sint32"),
124+
call_msync("(sint64, sint64, sint64):void"),
108125
call_strerror("(sint32, [sint8], sint32):void"),
109126
call_getpid("():sint64"),
110127
call_umask("(sint32):sint32"),
@@ -1155,10 +1172,10 @@ private static long encodeCStringArray(byte[] data, long startOffset, long[] off
11551172
}
11561173

11571174
private static final class MMapHandle {
1158-
private final Object pointer;
1175+
private final long pointer;
11591176
private final long length;
11601177

1161-
public MMapHandle(Object pointer, long length) {
1178+
public MMapHandle(long pointer, long length) {
11621179
this.pointer = pointer;
11631180
this.length = length;
11641181
}
@@ -1167,39 +1184,39 @@ public MMapHandle(Object pointer, long length) {
11671184
@ExportMessage
11681185
public Object mmap(long length, int prot, int flags, int fd, long offset,
11691186
@Shared("invoke") @Cached InvokeNativeFunction invokeNode) throws PosixException {
1170-
Object address = invokeNode.call(this, PosixNativeFunction.call_mmap, length, prot, flags, fd, offset);
1171-
if (invokeNode.getResultInterop().isNull(address)) {
1187+
long address = invokeNode.callLong(this, PosixNativeFunction.call_mmap, length, prot, flags, fd, offset);
1188+
if (address == 0) {
11721189
throw newPosixException(invokeNode, getErrno(invokeNode));
11731190
}
11741191
return new MMapHandle(address, length);
11751192
}
11761193

11771194
@ExportMessage
1178-
public byte mmapReadByte(Object mmap, long index,
1179-
@Shared("invoke") @Cached InvokeNativeFunction invokeNode) {
1195+
@SuppressWarnings("static-method")
1196+
public byte mmapReadByte(Object mmap, long index) {
11801197
MMapHandle handle = (MMapHandle) mmap;
11811198
if (index < 0 || index >= handle.length) {
11821199
CompilerDirectives.transferToInterpreterAndInvalidate();
11831200
throw new IndexOutOfBoundsException();
11841201
}
1185-
return invokeNode.callByte(this, PosixNativeFunction.read_byte, handle.pointer, index);
1202+
return UNSAFE.getByte(handle.pointer + index);
11861203
}
11871204

11881205
@ExportMessage
1189-
public int mmapReadBytes(Object mmap, long index, byte[] bytes, int length,
1190-
@Shared("invoke") @Cached InvokeNativeFunction invokeNode) {
1206+
@SuppressWarnings("static-method")
1207+
public int mmapReadBytes(Object mmap, long index, byte[] bytes, int length) {
11911208
MMapHandle handle = (MMapHandle) mmap;
11921209
checkIndexAndLen(handle, index, length);
1193-
invokeNode.call(this, PosixNativeFunction.read_bytes, handle.pointer, wrap(bytes), index, length);
1210+
UNSAFE.copyMemory(null, handle.pointer + index, bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, length);
11941211
return length;
11951212
}
11961213

11971214
@ExportMessage
1198-
public void mmapWriteBytes(Object mmap, long index, byte[] bytes, int length,
1199-
@Shared("invoke") @Cached InvokeNativeFunction invokeNode) {
1215+
@SuppressWarnings("static-method")
1216+
public void mmapWriteBytes(Object mmap, long index, byte[] bytes, int length) {
12001217
MMapHandle handle = (MMapHandle) mmap;
12011218
checkIndexAndLen(handle, index, length);
1202-
invokeNode.call(this, PosixNativeFunction.write_bytes, handle.pointer, wrap(bytes), index, length);
1219+
UNSAFE.copyMemory(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, handle.pointer + index, length);
12031220
}
12041221

12051222
@ExportMessage

0 commit comments

Comments
 (0)