Skip to content

Commit 6386d8b

Browse files
committed
Migrate zlib native support to NativeAccess
1 parent 492f348 commit 6386d8b

13 files changed

Lines changed: 617 additions & 886 deletions

File tree

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/NativeZlibCompObject.java‎

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -41,35 +41,39 @@
4141
package com.oracle.graal.python.builtins.modules.zlib;
4242

4343
import com.oracle.graal.python.runtime.NFIZlibSupport;
44-
import com.oracle.truffle.api.CompilerDirectives;
44+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4545
import com.oracle.truffle.api.object.Shape;
4646

47-
// Note: some IDEs mark this class as inaccessible in PFactory, but changing this to
48-
// public will cause a warning: [this-escape] possible 'this' escape before subclass is fully
49-
// initialized
5047
public final class NativeZlibCompObject extends ZLibCompObject {
5148
private NFIZlibSupport.Pointer pointer;
5249
byte[] lastInput;
5350

54-
public NativeZlibCompObject(Object cls, Shape instanceShape, Object zst, NFIZlibSupport zlibSupport) {
51+
public NativeZlibCompObject(Object cls, Shape instanceShape, long zst, NFIZlibSupport zlibSupport) {
5552
super(cls, instanceShape);
5653
this.pointer = new NFIZlibSupport.Pointer(this, zst, zlibSupport);
57-
this.lastInput = null;
5854
}
5955

60-
public Object getZst() {
61-
assert pointer != null;
62-
return pointer.getReference();
56+
public long getZst() {
57+
NFIZlibSupport.Pointer p = pointer;
58+
assert p != null && !p.isReleased();
59+
return p.getPointer();
6360
}
6461

65-
@CompilerDirectives.TruffleBoundary
62+
@TruffleBoundary
6663
public void markReleased() {
67-
if (isInitialized) {
68-
synchronized (this) {
69-
isInitialized = false;
70-
pointer.markReleased();
71-
pointer = null;
64+
NFIZlibSupport.Pointer p;
65+
synchronized (this) {
66+
if (!isInitialized) {
67+
assert pointer == null || pointer.isReleased();
68+
return;
7269
}
70+
assert pointer != null && !pointer.isReleased();
71+
isInitialized = false;
72+
p = pointer;
73+
pointer = null;
74+
assert !isInitialized;
7375
}
76+
boolean markedReleased = p.markReleased();
77+
assert markedReleased || p.isReleased();
7478
}
7579
}

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibCompObject.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -51,7 +51,7 @@ public abstract class ZLibCompObject extends PythonBuiltinObject {
5151
private PBytes unusedData;
5252
private PBytes unconsumedTail;
5353

54-
public ZLibCompObject(Object cls, Shape instanceShape) {
54+
protected ZLibCompObject(Object cls, Shape instanceShape) {
5555
super(cls, instanceShape);
5656
this.isInitialized = true;
5757
this.eof = false;

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibModuleBuiltins.java‎

Lines changed: 33 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -46,7 +46,6 @@
4646
import static com.oracle.graal.python.nodes.ErrorMessages.EXPECTED_BYTESLIKE_GOT_P;
4747
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
4848
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ZLibError;
49-
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
5049
import static com.oracle.graal.python.util.PythonUtils.crc32;
5150
import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
5251
import static java.util.zip.Deflater.DEFAULT_COMPRESSION;
@@ -57,9 +56,9 @@
5756

5857
import com.oracle.graal.python.PythonLanguage;
5958
import com.oracle.graal.python.annotations.ArgumentClinic;
59+
import com.oracle.graal.python.annotations.Builtin;
6060
import com.oracle.graal.python.annotations.ClinicConverterFactory;
6161
import com.oracle.graal.python.annotations.ClinicConverterFactory.UseDefaultForNone;
62-
import com.oracle.graal.python.annotations.Builtin;
6362
import com.oracle.graal.python.builtins.CoreFunctions;
6463
import com.oracle.graal.python.builtins.Python3Core;
6564
import com.oracle.graal.python.builtins.PythonBuiltins;
@@ -85,7 +84,6 @@
8584
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
8685
import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData;
8786
import com.oracle.graal.python.runtime.NFIZlibSupport;
88-
import com.oracle.graal.python.runtime.NativeLibrary;
8987
import com.oracle.graal.python.runtime.PythonContext;
9088
import com.oracle.graal.python.runtime.object.PFactory;
9189
import com.oracle.graal.python.util.PythonUtils;
@@ -103,8 +101,6 @@
103101
import com.oracle.truffle.api.dsl.NonIdempotent;
104102
import com.oracle.truffle.api.dsl.Specialization;
105103
import com.oracle.truffle.api.frame.VirtualFrame;
106-
import com.oracle.truffle.api.interop.InteropLibrary;
107-
import com.oracle.truffle.api.interop.UnsupportedMessageException;
108104
import com.oracle.truffle.api.library.CachedLibrary;
109105
import com.oracle.truffle.api.nodes.Node;
110106
import com.oracle.truffle.api.strings.TruffleString;
@@ -186,38 +182,27 @@ public void initialize(Python3Core core) {
186182
@Override
187183
public void postInitialize(Python3Core core) {
188184
super.postInitialize(core);
189-
NFIZlibSupport zlibSupport = core.getContext().getNFIZlibSupport();
185+
NFIZlibSupport zlibSupport = core.getContext().getNativeZlibSupport();
190186
PythonModule zlibModule = core.lookupBuiltinModule(T_ZLIB);
191187
// isAvailable() checked already if native access is allowed
192188
TruffleString ver = T_JDK_ZLIB_VERSION;
193189
TruffleString rtver = T_JDK_ZLIB_VERSION;
194190
if (zlibSupport.isAvailable()) {
195191
try {
196-
ver = asString(zlibSupport.zlibVersion());
197-
rtver = asString(zlibSupport.zlibRuntimeVersion());
192+
ver = zlibSupport.zlibVersion();
193+
rtver = zlibSupport.zlibRuntimeVersion();
198194
zlibModule.setAttribute(tsLiteral("Z_PARTIAL_FLUSH"), Z_PARTIAL_FLUSH);
199195
zlibModule.setAttribute(tsLiteral("Z_BLOCK"), Z_BLOCK);
200196
zlibModule.setAttribute(tsLiteral("Z_TREES"), Z_TREES);
201-
} catch (NativeLibrary.NativeLibraryCannotBeLoaded e) {
202-
zlibSupport.notAvailable();
197+
} catch (UnsupportedOperationException e) {
198+
zlibSupport.setNotAvailable();
203199
// ignore and proceed without native zlib support and use jdk's.
204200
}
205201
}
206202
zlibModule.setAttribute(tsLiteral("ZLIB_VERSION"), ver);
207203
zlibModule.setAttribute(tsLiteral("ZLIB_RUNTIME_VERSION"), rtver);
208204
}
209205

210-
private static TruffleString asString(Object o) {
211-
if (o != null) {
212-
try {
213-
return InteropLibrary.getUncached().asTruffleString(o).switchEncodingUncached(TS_ENCODING);
214-
} catch (UnsupportedMessageException e) {
215-
// pass through
216-
}
217-
}
218-
return null;
219-
}
220-
221206
@ImportStatic(MathGuards.class)
222207
public abstract static class ExpectIntNode extends ArgumentCastNode {
223208
private final Object defaultValue;
@@ -330,7 +315,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
330315

331316
@NonIdempotent
332317
protected boolean useNative() {
333-
return PythonContext.get(this).getNFIZlibSupport().isAvailable();
318+
return PythonContext.get(this).getNativeZlibSupport().isAvailable();
334319
}
335320

336321
@Specialization
@@ -349,19 +334,17 @@ static long doCRC32(byte[] data) {
349334
@Specialization(guards = "useNative()")
350335
long doNativeBytes(PBytesLike data, int value,
351336
@Bind Node inliningTarget,
352-
@Shared("b") @Cached SequenceStorageNodes.GetInternalBytesNode toBytes,
353-
@Shared @Cached NativeLibrary.InvokeNativeFunction invoke) {
337+
@Shared("b") @Cached SequenceStorageNodes.GetInternalBytesNode toBytes) {
354338
byte[] bytes = toBytes.execute(inliningTarget, data);
355339
int len = data.getSequenceStorage().length();
356-
return nativeCrc32(bytes, len, value, invoke);
340+
return nativeCrc32(bytes, len, value);
357341
}
358342

359343
@Specialization(guards = {"useNative()", "!isBytes(data)"})
360344
long doNativeObject(VirtualFrame frame, Object data, int value,
361-
@Shared("bb") @Cached ToBytesNode toBytesNode,
362-
@Shared @Cached NativeLibrary.InvokeNativeFunction invoke) {
345+
@Shared("bb") @Cached ToBytesNode toBytesNode) {
363346
byte[] bytes = toBytesNode.execute(frame, data);
364-
return nativeCrc32(bytes, bytes.length, value, invoke);
347+
return nativeCrc32(bytes, bytes.length, value);
365348
}
366349

367350
@Specialization(guards = "!useNative()")
@@ -386,10 +369,9 @@ static long error(Object data, @SuppressWarnings("unused") Object value,
386369
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, EXPECTED_BYTESLIKE_GOT_P, data);
387370
}
388371

389-
long nativeCrc32(byte[] bytes, int len, int value,
390-
NativeLibrary.InvokeNativeFunction invoke) {
372+
long nativeCrc32(byte[] bytes, int len, int value) {
391373
PythonContext ctxt = getContext();
392-
int signedVal = (int) ctxt.getNFIZlibSupport().crc32(value, bytes, len, invoke);
374+
int signedVal = (int) ctxt.getNativeZlibSupport().crc32(value, bytes, len);
393375
return signedVal & 0xFFFFFFFFL;
394376
}
395377
}
@@ -410,7 +392,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
410392

411393
@NonIdempotent
412394
protected boolean useNative() {
413-
return getContext().getNFIZlibSupport().isAvailable();
395+
return getContext().getNativeZlibSupport().isAvailable();
414396
}
415397

416398
@Specialization
@@ -429,19 +411,17 @@ private static long doAdler32(byte[] bytes) {
429411
@Specialization(guards = "useNative()")
430412
long doNativeBytes(PBytesLike data, int value,
431413
@Bind Node inliningTarget,
432-
@Shared("b") @Cached SequenceStorageNodes.GetInternalBytesNode toBytes,
433-
@Shared @Cached NativeLibrary.InvokeNativeFunction invoke) {
414+
@Shared("b") @Cached SequenceStorageNodes.GetInternalBytesNode toBytes) {
434415
byte[] bytes = toBytes.execute(inliningTarget, data);
435416
int len = data.getSequenceStorage().length();
436-
return nativeAdler32(bytes, len, value, PythonContext.get(this), invoke);
417+
return nativeAdler32(bytes, len, value, PythonContext.get(this));
437418
}
438419

439420
@Specialization(guards = {"useNative()", "!isBytes(data)"})
440421
long doNativeObject(VirtualFrame frame, Object data, int value,
441-
@Shared("bb") @Cached ToBytesNode toBytesNode,
442-
@Shared @Cached NativeLibrary.InvokeNativeFunction invoke) {
422+
@Shared("bb") @Cached ToBytesNode toBytesNode) {
443423
byte[] bytes = toBytesNode.execute(frame, data);
444-
return nativeAdler32(bytes, bytes.length, value, PythonContext.get(this), invoke);
424+
return nativeAdler32(bytes, bytes.length, value, PythonContext.get(this));
445425
}
446426

447427
@Specialization(guards = "!useNative()")
@@ -461,9 +441,8 @@ long doJavaObject(VirtualFrame frame, Object data, int value,
461441
}
462442

463443
long nativeAdler32(byte[] bytes, int len, int value,
464-
PythonContext ctxt,
465-
NativeLibrary.InvokeNativeFunction invoke) {
466-
int signedVal = (int) ctxt.getNFIZlibSupport().adler32(value, bytes, len, invoke);
444+
PythonContext ctxt) {
445+
int signedVal = (int) ctxt.getNativeZlibSupport().adler32(value, bytes, len);
467446
return signedVal & 0xFFFFFFFFL;
468447
}
469448

@@ -523,7 +502,7 @@ abstract static class CompressInnerNode extends Node {
523502

524503
@NonIdempotent
525504
protected boolean useNative() {
526-
return PythonContext.get(this).getNFIZlibSupport().isAvailable();
505+
return PythonContext.get(this).getNativeZlibSupport().isAvailable();
527506
}
528507

529508
protected static boolean isValidLevel(int level) {
@@ -591,7 +570,7 @@ abstract static class DecompressInnerNode extends Node {
591570

592571
@NonIdempotent
593572
protected boolean useNative() {
594-
return PythonContext.get(this).getNFIZlibSupport().isAvailable();
573+
return PythonContext.get(this).getNativeZlibSupport().isAvailable();
595574
}
596575

597576
@Specialization(guards = "useNative()")
@@ -628,7 +607,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
628607

629608
@NonIdempotent
630609
protected boolean useNative() {
631-
return PythonContext.get(this).getNFIZlibSupport().isAvailable();
610+
return PythonContext.get(this).getNativeZlibSupport().isAvailable();
632611
}
633612

634613
protected static boolean isValidWBitRange(int wbits) {
@@ -639,18 +618,16 @@ protected static boolean isValidWBitRange(int wbits) {
639618
static Object doNative(int level, int method, int wbits, int memLevel, int strategy, byte[] zdict,
640619
@Bind Node inliningTarget,
641620
@Bind PythonLanguage language,
642-
@Cached NativeLibrary.InvokeNativeFunction createCompObject,
643-
@Cached NativeLibrary.InvokeNativeFunction compressObjInit,
644621
@Cached ZlibNodes.ZlibNativeErrorHandling errorHandling) {
645-
NFIZlibSupport zlibSupport = PythonContext.get(inliningTarget).getNFIZlibSupport();
646-
Object zst = zlibSupport.createCompObject(createCompObject);
622+
NFIZlibSupport zlibSupport = PythonContext.get(inliningTarget).getNativeZlibSupport();
623+
long zst = zlibSupport.createCompObject();
647624

648625
int err;
649626
if (zdict.length > 0) {
650627
err = zlibSupport.compressObjInitWithDict(zst, level, method, wbits, memLevel, strategy,
651-
zdict, zdict.length, compressObjInit);
628+
zdict, zdict.length);
652629
} else {
653-
err = zlibSupport.compressObjInit(zst, level, method, wbits, memLevel, strategy, compressObjInit);
630+
err = zlibSupport.compressObjInit(zst, level, method, wbits, memLevel, strategy);
654631
}
655632
if (err != Z_OK) {
656633
errorHandling.execute(inliningTarget, zst, err, zlibSupport, true);
@@ -700,7 +677,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
700677

701678
@NonIdempotent
702679
protected boolean useNative() {
703-
return PythonContext.get(this).getNFIZlibSupport().isAvailable();
680+
return PythonContext.get(this).getNativeZlibSupport().isAvailable();
704681
}
705682

706683
protected static boolean isValidWBitRange(int wbits) {
@@ -711,17 +688,15 @@ protected static boolean isValidWBitRange(int wbits) {
711688
static Object doNative(int wbits, byte[] zdict,
712689
@Bind Node inliningTarget,
713690
@Bind PythonContext context,
714-
@Cached NativeLibrary.InvokeNativeFunction createCompObject,
715-
@Cached NativeLibrary.InvokeNativeFunction decompressObjInit,
716691
@Cached ZlibNodes.ZlibNativeErrorHandling errorHandling) {
717-
NFIZlibSupport zlibSupport = context.getNFIZlibSupport();
718-
Object zst = zlibSupport.createCompObject(createCompObject);
692+
NFIZlibSupport zlibSupport = context.getNativeZlibSupport();
693+
long zst = zlibSupport.createCompObject();
719694

720695
int err;
721696
if (zdict.length > 0) {
722-
err = zlibSupport.decompressObjInitWithDict(zst, wbits, zdict, zdict.length, decompressObjInit);
697+
err = zlibSupport.decompressObjInitWithDict(zst, wbits, zdict, zdict.length);
723698
} else {
724-
err = zlibSupport.decompressObjInit(zst, wbits, decompressObjInit);
699+
err = zlibSupport.decompressObjInit(zst, wbits);
725700
}
726701
if (err != Z_OK) {
727702
errorHandling.execute(inliningTarget, zst, err, zlibSupport, true);

0 commit comments

Comments
 (0)