|
4 | 4 | import static com.oracle.graal.python.builtins.modules.ctypes.CtypesNodes.WCHAR_T_SIZE;
|
5 | 5 | import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR;
|
6 | 6 |
|
7 |
| -import java.lang.reflect.Field; |
8 |
| - |
9 | 7 | import com.oracle.graal.python.builtins.modules.ctypes.FFIType;
|
10 | 8 | import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.ByteArrayStorage;
|
11 | 9 | import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.LongPointerStorage;
|
|
25 | 23 | import com.oracle.graal.python.nodes.ErrorMessages;
|
26 | 24 | import com.oracle.graal.python.nodes.PRaiseNode;
|
27 | 25 | import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode;
|
| 26 | +import com.oracle.graal.python.runtime.PythonContext; |
28 | 27 | import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage;
|
29 | 28 | import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage;
|
30 | 29 | import com.oracle.graal.python.util.PythonUtils;
|
31 | 30 | import com.oracle.truffle.api.CompilerDirectives;
|
| 31 | +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; |
32 | 32 | import com.oracle.truffle.api.dsl.Cached;
|
33 | 33 | import com.oracle.truffle.api.dsl.Cached.Shared;
|
34 | 34 | import com.oracle.truffle.api.dsl.Fallback;
|
@@ -95,8 +95,9 @@ static void doPointerArray(Node inliningTarget, byte[] dst, int dstOffset, Memor
|
95 | 95 | }
|
96 | 96 |
|
97 | 97 | @Specialization
|
98 |
| - static void doNativeMemory(byte[] dst, int dstOffset, @SuppressWarnings("unused") MemoryBlock srcMemory, LongPointerStorage src, int srcOffset, int size) { |
99 |
| - UNSAFE.copyMemory(null, src.pointer + srcOffset, dst, byteArrayOffset(dstOffset), size); |
| 98 | + static void doNativeMemory(Node inliningTarget, byte[] dst, int dstOffset, @SuppressWarnings("unused") MemoryBlock srcMemory, LongPointerStorage src, int srcOffset, int size) { |
| 99 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 100 | + unsafe.copyMemory(null, src.pointer + srcOffset, dst, byteArrayOffset(dstOffset), size); |
100 | 101 | }
|
101 | 102 | }
|
102 | 103 |
|
@@ -128,8 +129,9 @@ static byte doMemoryView(@SuppressWarnings("unused") MemoryBlock memory, MemoryV
|
128 | 129 | }
|
129 | 130 |
|
130 | 131 | @Specialization
|
131 |
| - static byte doNativeMemory(@SuppressWarnings("unused") MemoryBlock memory, LongPointerStorage storage, int offset) { |
132 |
| - return UNSAFE.getByte(storage.pointer + offset); |
| 132 | + static byte doNativeMemory(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock memory, LongPointerStorage storage, int offset) { |
| 133 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 134 | + return unsafe.getByte(storage.pointer + offset); |
133 | 135 | }
|
134 | 136 |
|
135 | 137 | @Fallback
|
@@ -163,8 +165,9 @@ static short doZero(@SuppressWarnings("unused") MemoryBlock memory, ZeroStorage
|
163 | 165 | }
|
164 | 166 |
|
165 | 167 | @Specialization
|
166 |
| - static short doNativeMemory(@SuppressWarnings("unused") MemoryBlock memory, LongPointerStorage storage, int offset) { |
167 |
| - return UNSAFE.getShort(storage.pointer + offset); |
| 168 | + static short doNativeMemory(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock memory, LongPointerStorage storage, int offset) { |
| 169 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 170 | + return unsafe.getShort(storage.pointer + offset); |
168 | 171 | }
|
169 | 172 |
|
170 | 173 | @Fallback
|
@@ -198,8 +201,9 @@ static int doZero(@SuppressWarnings("unused") MemoryBlock memory, ZeroStorage st
|
198 | 201 | }
|
199 | 202 |
|
200 | 203 | @Specialization
|
201 |
| - static int doNativeMemory(@SuppressWarnings("unused") MemoryBlock memory, LongPointerStorage storage, int offset) { |
202 |
| - return UNSAFE.getInt(storage.pointer + offset); |
| 204 | + static int doNativeMemory(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock memory, LongPointerStorage storage, int offset) { |
| 205 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 206 | + return unsafe.getInt(storage.pointer + offset); |
203 | 207 | }
|
204 | 208 |
|
205 | 209 | @Fallback
|
@@ -233,8 +237,9 @@ static long doZero(@SuppressWarnings("unused") MemoryBlock memory, ZeroStorage s
|
233 | 237 | }
|
234 | 238 |
|
235 | 239 | @Specialization
|
236 |
| - static long doNativeMemory(@SuppressWarnings("unused") MemoryBlock memory, LongPointerStorage storage, int offset) { |
237 |
| - return UNSAFE.getLong(storage.pointer + offset); |
| 240 | + static long doNativeMemory(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock memory, LongPointerStorage storage, int offset) { |
| 241 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 242 | + return unsafe.getLong(storage.pointer + offset); |
238 | 243 | }
|
239 | 244 |
|
240 | 245 | @Fallback
|
@@ -283,8 +288,9 @@ static void doMemoryView(@SuppressWarnings("unused") MemoryBlock dstMemory, Memo
|
283 | 288 | }
|
284 | 289 |
|
285 | 290 | @Specialization
|
286 |
| - static void doNativeMemory(@SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, byte[] src, int srcOffset, int size) { |
287 |
| - UNSAFE.copyMemory(src, byteArrayOffset(srcOffset), null, dst.pointer + dstOffset, size); |
| 291 | + static void doNativeMemory(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, byte[] src, int srcOffset, int size) { |
| 292 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 293 | + unsafe.copyMemory(src, byteArrayOffset(srcOffset), null, dst.pointer + dstOffset, size); |
288 | 294 | }
|
289 | 295 |
|
290 | 296 | @Specialization
|
@@ -318,8 +324,9 @@ static void doZero(MemoryBlock dstMemory, ZeroStorage dst, int dstOffset, byte v
|
318 | 324 | }
|
319 | 325 |
|
320 | 326 | @Specialization
|
321 |
| - static void doNativeMemory(@SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, byte value) { |
322 |
| - UNSAFE.putByte(dst.pointer + dstOffset, value); |
| 327 | + static void doNativeMemory(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, byte value) { |
| 328 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 329 | + unsafe.putByte(dst.pointer + dstOffset, value); |
323 | 330 | }
|
324 | 331 |
|
325 | 332 | @Fallback
|
@@ -352,8 +359,9 @@ static void doZero(MemoryBlock dstMemory, ZeroStorage dst, int dstOffset, short
|
352 | 359 | }
|
353 | 360 |
|
354 | 361 | @Specialization
|
355 |
| - static void doNativeMemory(@SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, short value) { |
356 |
| - UNSAFE.putShort(dst.pointer + dstOffset, value); |
| 362 | + static void doNativeMemory(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, short value) { |
| 363 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 364 | + unsafe.putShort(dst.pointer + dstOffset, value); |
357 | 365 | }
|
358 | 366 |
|
359 | 367 | @Fallback
|
@@ -388,8 +396,9 @@ static void doZero(MemoryBlock dstMemory, ZeroStorage dst, int dstOffset, int va
|
388 | 396 | }
|
389 | 397 |
|
390 | 398 | @Specialization
|
391 |
| - static void doNativeMemory(@SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, int value) { |
392 |
| - UNSAFE.putInt(dst.pointer + dstOffset, value); |
| 399 | + static void doNativeMemory(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, int value) { |
| 400 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 401 | + unsafe.putInt(dst.pointer + dstOffset, value); |
393 | 402 | }
|
394 | 403 |
|
395 | 404 | @Fallback
|
@@ -431,8 +440,9 @@ static void doPointerArray(@SuppressWarnings("unused") MemoryBlock dstMemory, Po
|
431 | 440 | }
|
432 | 441 |
|
433 | 442 | @Specialization
|
434 |
| - static void doNativeMemory(@SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, long value) { |
435 |
| - UNSAFE.putLong(dst.pointer + dstOffset, value); |
| 443 | + static void doNativeMemory(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock dstMemory, LongPointerStorage dst, int dstOffset, long value) { |
| 444 | + Unsafe unsafe = PythonContext.get(inliningTarget).getUnsafe(); |
| 445 | + unsafe.putLong(dst.pointer + dstOffset, value); |
436 | 446 | }
|
437 | 447 |
|
438 | 448 | @Fallback
|
@@ -574,35 +584,35 @@ static long doNativePointer(@SuppressWarnings("unused") MemoryBlock memory, Long
|
574 | 584 | }
|
575 | 585 |
|
576 | 586 | @Specialization
|
577 |
| - static long doBytes(MemoryBlock memory, ByteArrayStorage storage, int offset) { |
| 587 | + static long doBytes(Node inliningTarget, MemoryBlock memory, ByteArrayStorage storage, int offset) { |
578 | 588 | int len = storage.bytes.length;
|
579 |
| - // TODO check permissions |
580 | 589 | // We need to copy the whole memory block to keep the pointer offsets consistent
|
581 |
| - long pointer = UNSAFE.allocateMemory(len); |
582 |
| - UNSAFE.copyMemory(storage.bytes, byteArrayOffset(0), null, pointer, len); |
| 590 | + PythonContext context = PythonContext.get(inliningTarget); |
| 591 | + long pointer = context.allocateNativeMemory(len); |
| 592 | + context.getUnsafe().copyMemory(storage.bytes, byteArrayOffset(0), null, pointer, len); |
583 | 593 | memory.storage = new LongPointerStorage(pointer);
|
584 | 594 | return pointer + offset;
|
585 | 595 | }
|
586 | 596 |
|
587 | 597 | @Specialization
|
588 |
| - static long doZero(MemoryBlock memory, ZeroStorage storage, int offset) { |
| 598 | + static long doZero(Node inliningTarget, MemoryBlock memory, ZeroStorage storage, int offset) { |
589 | 599 | int len = storage.size;
|
590 |
| - // TODO check permissions |
591 |
| - long pointer = UNSAFE.allocateMemory(len); |
592 |
| - UNSAFE.setMemory(pointer, len, (byte) 0); |
| 600 | + PythonContext context = PythonContext.get(inliningTarget); |
| 601 | + long pointer = context.allocateNativeMemory(len); |
| 602 | + context.getUnsafe().setMemory(pointer, len, (byte) 0); |
593 | 603 | memory.storage = new LongPointerStorage(pointer);
|
594 | 604 | return pointer + offset;
|
595 | 605 | }
|
596 | 606 |
|
597 | 607 | @Specialization
|
598 | 608 | static long doPointerArray(Node inliningTarget, MemoryBlock memory, PointerArrayStorage storage, int offset,
|
599 | 609 | @Cached(inline = false) GetPointerValueAsLongNode toNativeNode) {
|
600 |
| - // TODO check permissions |
601 |
| - long pointer = UNSAFE.allocateMemory(storage.pointers.length * 8L); |
| 610 | + PythonContext context = PythonContext.get(inliningTarget); |
| 611 | + long pointer = context.allocateNativeMemory(storage.pointers.length * 8L); |
602 | 612 | for (int i = 0; i < storage.pointers.length; i++) {
|
603 | 613 | Pointer itemPointer = storage.pointers[i];
|
604 | 614 | long subpointer = toNativeNode.execute(inliningTarget, itemPointer.memory, itemPointer.memory.storage, itemPointer.offset);
|
605 |
| - UNSAFE.putLong(pointer + i * 8L, subpointer); |
| 615 | + context.getUnsafe().putLong(pointer + i * 8L, subpointer); |
606 | 616 | }
|
607 | 617 | memory.storage = new LongPointerStorage(pointer);
|
608 | 618 | return pointer + offset;
|
@@ -686,9 +696,10 @@ public final void execute(Node inliningTarget, Pointer pointer) {
|
686 | 696 | abstract void execute(Node inliningTarget, Storage storage, int offset);
|
687 | 697 |
|
688 | 698 | @Specialization
|
689 |
| - void doNativeMemory(LongPointerStorage storage, int offset) { |
690 |
| - // TODO check permissions |
691 |
| - UNSAFE.freeMemory(storage.pointer + offset); |
| 699 | + @TruffleBoundary |
| 700 | + void doNativeMemory(Node inliningTarget, LongPointerStorage storage, int offset) { |
| 701 | + PythonContext context = PythonContext.get(inliningTarget); |
| 702 | + context.freeNativeMemory(storage.pointer + offset); |
692 | 703 | }
|
693 | 704 |
|
694 | 705 | @Specialization
|
@@ -886,22 +897,6 @@ static ByteArrayStorage convert(Node inliningTarget, MemoryBlock memory, Pointer
|
886 | 897 | }
|
887 | 898 | }
|
888 | 899 |
|
889 |
| - private static Unsafe UNSAFE = getUnsafe(); |
890 |
| - |
891 |
| - private static Unsafe getUnsafe() { |
892 |
| - try { |
893 |
| - return Unsafe.getUnsafe(); |
894 |
| - } catch (SecurityException e) { |
895 |
| - } |
896 |
| - try { |
897 |
| - Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); |
898 |
| - theUnsafeInstance.setAccessible(true); |
899 |
| - return (Unsafe) theUnsafeInstance.get(Unsafe.class); |
900 |
| - } catch (Exception e) { |
901 |
| - throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); |
902 |
| - } |
903 |
| - } |
904 |
| - |
905 | 900 | private static long byteArrayOffset(int offset) {
|
906 | 901 | return (long) Unsafe.ARRAY_BYTE_BASE_OFFSET + (long) Unsafe.ARRAY_BYTE_INDEX_SCALE * (long) offset;
|
907 | 902 | }
|
|
0 commit comments