4343import static com .oracle .truffle .api .CompilerDirectives .SLOWPATH_PROBABILITY ;
4444import static com .oracle .truffle .api .CompilerDirectives .injectBranchProbability ;
4545
46+ import java .lang .reflect .Field ;
4647import java .util .Arrays ;
4748import java .util .concurrent .atomic .AtomicReferenceArray ;
4849import java .util .logging .Level ;
4950
51+ import org .graalvm .nativeimage .ImageInfo ;
52+
5053import com .oracle .graal .python .PythonLanguage ;
5154import com .oracle .graal .python .builtins .modules .GraalPythonModuleBuiltins ;
5255import com .oracle .graal .python .builtins .objects .bytes .BytesUtils ;
7780import com .oracle .truffle .api .nodes .Node ;
7881import com .oracle .truffle .api .source .Source ;
7982import 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