43
43
import static com .oracle .truffle .api .CompilerDirectives .SLOWPATH_PROBABILITY ;
44
44
import static com .oracle .truffle .api .CompilerDirectives .injectBranchProbability ;
45
45
46
+ import java .lang .reflect .Field ;
46
47
import java .util .Arrays ;
47
48
import java .util .concurrent .atomic .AtomicReferenceArray ;
48
49
import java .util .logging .Level ;
49
50
51
+ import org .graalvm .nativeimage .ImageInfo ;
52
+
50
53
import com .oracle .graal .python .PythonLanguage ;
51
54
import com .oracle .graal .python .builtins .modules .GraalPythonModuleBuiltins ;
52
55
import com .oracle .graal .python .builtins .objects .bytes .BytesUtils ;
77
80
import com .oracle .truffle .api .nodes .Node ;
78
81
import com .oracle .truffle .api .source .Source ;
79
82
import com .oracle .truffle .llvm .api .Toolchain ;
80
- import org .graalvm .nativeimage .ImageInfo ;
83
+
84
+ import sun .misc .Unsafe ;
81
85
82
86
/**
83
87
* Implementation that invokes the native POSIX functions directly using NFI. This requires either
@@ -96,15 +100,28 @@ public final class NFIPosixSupport extends PosixSupport {
96
100
97
101
private static final TruffleLogger LOGGER = PythonLanguage .getLogger (NFIPosixSupport .class );
98
102
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
+
99
119
private enum PosixNativeFunction {
100
120
get_errno ("():sint32" ),
101
121
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" ),
108
125
call_strerror ("(sint32, [sint8], sint32):void" ),
109
126
call_getpid ("():sint64" ),
110
127
call_umask ("(sint32):sint32" ),
@@ -1155,10 +1172,10 @@ private static long encodeCStringArray(byte[] data, long startOffset, long[] off
1155
1172
}
1156
1173
1157
1174
private static final class MMapHandle {
1158
- private final Object pointer ;
1175
+ private final long pointer ;
1159
1176
private final long length ;
1160
1177
1161
- public MMapHandle (Object pointer , long length ) {
1178
+ public MMapHandle (long pointer , long length ) {
1162
1179
this .pointer = pointer ;
1163
1180
this .length = length ;
1164
1181
}
@@ -1167,39 +1184,39 @@ public MMapHandle(Object pointer, long length) {
1167
1184
@ ExportMessage
1168
1185
public Object mmap (long length , int prot , int flags , int fd , long offset ,
1169
1186
@ 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 ) {
1172
1189
throw newPosixException (invokeNode , getErrno (invokeNode ));
1173
1190
}
1174
1191
return new MMapHandle (address , length );
1175
1192
}
1176
1193
1177
1194
@ 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 ) {
1180
1197
MMapHandle handle = (MMapHandle ) mmap ;
1181
1198
if (index < 0 || index >= handle .length ) {
1182
1199
CompilerDirectives .transferToInterpreterAndInvalidate ();
1183
1200
throw new IndexOutOfBoundsException ();
1184
1201
}
1185
- return invokeNode . callByte ( this , PosixNativeFunction . read_byte , handle .pointer , index );
1202
+ return UNSAFE . getByte ( handle .pointer + index );
1186
1203
}
1187
1204
1188
1205
@ 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 ) {
1191
1208
MMapHandle handle = (MMapHandle ) mmap ;
1192
1209
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 );
1194
1211
return length ;
1195
1212
}
1196
1213
1197
1214
@ 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 ) {
1200
1217
MMapHandle handle = (MMapHandle ) mmap ;
1201
1218
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 );
1203
1220
}
1204
1221
1205
1222
@ ExportMessage
0 commit comments