|
40 | 40 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__GT__;
|
41 | 41 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__LE__;
|
42 | 42 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__LT__;
|
| 43 | +import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETITEM__; |
43 | 44 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError;
|
44 | 45 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.MemoryError;
|
45 | 46 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError;
|
|
62 | 63 | import com.oracle.graal.python.PythonLanguage;
|
63 | 64 | import com.oracle.graal.python.builtins.PythonBuiltinClassType;
|
64 | 65 | import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
|
| 66 | +import com.oracle.graal.python.builtins.objects.array.PArray; |
| 67 | +import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; |
| 68 | +import com.oracle.graal.python.builtins.objects.bytes.PByteArray; |
| 69 | +import com.oracle.graal.python.builtins.objects.bytes.PBytes; |
| 70 | +import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; |
65 | 71 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes;
|
66 | 72 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
|
67 | 73 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ToSulongNode;
|
@@ -1416,6 +1422,52 @@ protected static boolean isBasicSequenceStorage(Object o) {
|
1416 | 1422 | }
|
1417 | 1423 | }
|
1418 | 1424 |
|
| 1425 | + @ImportStatic(PGuards.class) |
| 1426 | + public abstract static class BytesMemcpyNode extends PNodeWithContext { |
| 1427 | + |
| 1428 | + public abstract void execute(VirtualFrame frame, Object dest, int destOffset, byte[] src, int srcOffset, int len); |
| 1429 | + |
| 1430 | + protected static boolean isByteSequenceStorage(PByteArray bytes) { |
| 1431 | + return bytes.getSequenceStorage() instanceof ByteSequenceStorage; |
| 1432 | + } |
| 1433 | + |
| 1434 | + protected static boolean isSimple(Object bytes) { |
| 1435 | + return bytes instanceof PByteArray && isByteSequenceStorage((PByteArray) bytes); |
| 1436 | + } |
| 1437 | + |
| 1438 | + @Specialization(guards = "isByteSequenceStorage(dest)") |
| 1439 | + void doBytes(PByteArray dest, int destOffset, byte[] src, int srcOffset, int len, |
| 1440 | + @Cached SequenceStorageNodes.GetInternalArrayNode internalArray, |
| 1441 | + @Cached ConditionProfile profile) { |
| 1442 | + if (profile.profile(len > 0)) { |
| 1443 | + byte[] internal = (byte[]) internalArray.execute(dest.getSequenceStorage()); |
| 1444 | + PythonUtils.arraycopy(src, srcOffset, internal, destOffset, len); |
| 1445 | + } |
| 1446 | + } |
| 1447 | + |
| 1448 | + @Specialization |
| 1449 | + void doBytes(PArray dest, int destOffset, byte[] src, int srcOffset, int len, |
| 1450 | + @Cached ConditionProfile profile) { |
| 1451 | + if (profile.profile(len > 0)) { |
| 1452 | + PythonUtils.arraycopy(src, srcOffset, dest.getBuffer(), destOffset, len); |
| 1453 | + } |
| 1454 | + } |
| 1455 | + |
| 1456 | + @Specialization(guards = {"!isSimple(dest)", "!isArray(dest)"}, limit = "2") |
| 1457 | + void doGeneric(VirtualFrame frame, Object dest, int destOffset, byte[] src, int srcOffset, int len, |
| 1458 | + @Cached PythonObjectFactory factory, |
| 1459 | + @CachedLibrary("dest") PythonObjectLibrary lib) { |
| 1460 | + PSlice slice = factory.createIntSlice(destOffset, destOffset + len, 1); |
| 1461 | + PBytes bytes; |
| 1462 | + if (src.length != len) { |
| 1463 | + bytes = factory.createBytes(Arrays.copyOfRange(src, srcOffset, srcOffset + len)); |
| 1464 | + } else { |
| 1465 | + bytes = factory.createBytes(src); |
| 1466 | + } |
| 1467 | + lib.lookupAndCallRegularMethod(dest, frame, __SETITEM__, slice, bytes); |
| 1468 | + } |
| 1469 | + } |
| 1470 | + |
1419 | 1471 | @GenerateUncached
|
1420 | 1472 | @ImportStatic(SequenceStorageBaseNode.class)
|
1421 | 1473 | abstract static class SetStorageSliceNode extends Node {
|
@@ -2086,9 +2138,37 @@ public static CmpNode createEq() {
|
2086 | 2138 | }
|
2087 | 2139 |
|
2088 | 2140 | /**
|
2089 |
| - * Use this node to get the internal byte array of the storage (if possible). It will avoid |
2090 |
| - * copying any data but this also means that the returned byte array may be larger than the |
2091 |
| - * number of actual elements. So, you must also consider the sequence storage's size. |
| 2141 | + * Will try to get the internal byte[]. Otherwise, it will get a copy. Please note that the |
| 2142 | + * actual length of the storage and the internal storage might differ. |
| 2143 | + */ |
| 2144 | + public abstract static class GetInternalBytesNode extends PNodeWithContext { |
| 2145 | + |
| 2146 | + public abstract byte[] execute(Object bytes); |
| 2147 | + |
| 2148 | + protected static boolean isByteSequenceStorage(PBytesLike bytes) { |
| 2149 | + return bytes.getSequenceStorage() instanceof ByteSequenceStorage; |
| 2150 | + } |
| 2151 | + |
| 2152 | + protected static boolean isSimple(Object bytes) { |
| 2153 | + return bytes instanceof PBytesLike && isByteSequenceStorage((PBytesLike) bytes); |
| 2154 | + } |
| 2155 | + |
| 2156 | + @Specialization(guards = "isByteSequenceStorage(bytes)") |
| 2157 | + byte[] doBytes(PBytesLike bytes, |
| 2158 | + @Cached SequenceStorageNodes.GetInternalArrayNode internalArray) { |
| 2159 | + return (byte[]) internalArray.execute(bytes.getSequenceStorage()); |
| 2160 | + } |
| 2161 | + |
| 2162 | + @Specialization(guards = "!isSimple(bytes)") |
| 2163 | + byte[] doGeneric(Object bytes, |
| 2164 | + @Cached BytesNodes.ToBytesNode toBytesNode) { |
| 2165 | + return toBytesNode.execute(bytes); |
| 2166 | + } |
| 2167 | + } |
| 2168 | + |
| 2169 | + /** |
| 2170 | + * Use this node to get the internal byte array of the storage (if possible) to avoid copying. |
| 2171 | + * Otherwise, it will create a copy with the exact size of the stored data. |
2092 | 2172 | */
|
2093 | 2173 | @GenerateUncached
|
2094 | 2174 | @ImportStatic(SequenceStorageBaseNode.class)
|
@@ -2983,12 +3063,7 @@ public GeneralizationNode create() {
|
2983 | 3063 | }
|
2984 | 3064 | };
|
2985 | 3065 |
|
2986 |
| - public static final Supplier<GeneralizationNode> CACHED_SUPPLIER = new Supplier<GeneralizationNode>() { |
2987 |
| - @Override |
2988 |
| - public GeneralizationNode get() { |
2989 |
| - return new ByteArrayGeneralizationNode(); |
2990 |
| - } |
2991 |
| - }; |
| 3066 | + public static final Supplier<GeneralizationNode> CACHED_SUPPLIER = () -> new ByteArrayGeneralizationNode(); |
2992 | 3067 |
|
2993 | 3068 | @Override
|
2994 | 3069 | public SequenceStorage execute(SequenceStorage toGeneralize, @SuppressWarnings("unused") Object indicationValue) {
|
@@ -3148,10 +3223,7 @@ protected static boolean isFallbackCase(SequenceStorage s, Object value, IsAssig
|
3148 | 3223 | (value instanceof Byte || value instanceof Integer || value instanceof Long)) {
|
3149 | 3224 | return false;
|
3150 | 3225 | }
|
3151 |
| - if (value instanceof SequenceStorage && isAssignCompatibleNode.execute(s, (SequenceStorage) value)) { |
3152 |
| - return false; |
3153 |
| - } |
3154 |
| - return true; |
| 3226 | + return !(value instanceof SequenceStorage) || !isAssignCompatibleNode.execute(s, (SequenceStorage) value); |
3155 | 3227 | }
|
3156 | 3228 |
|
3157 | 3229 | public static ListGeneralizationNode create() {
|
@@ -3751,8 +3823,7 @@ static void singleStep(SequenceStorage store, SliceInfo sinfo,
|
3751 | 3823 | @Cached ConditionProfile shortCircuitProfile,
|
3752 | 3824 | @Cached LenNode selfLenNode,
|
3753 | 3825 | @Cached SetLenNode setLenNode,
|
3754 |
| - @Cached MemMoveNode memove, |
3755 |
| - @Cached @SuppressWarnings("unused") IsDataTypeCompatibleNode isDataTypeCompatibleNode) { |
| 3826 | + @Cached MemMoveNode memove) { |
3756 | 3827 | int length = selfLenNode.execute(store);
|
3757 | 3828 | int sliceLength = sinfo.sliceLength;
|
3758 | 3829 |
|
@@ -3792,8 +3863,7 @@ static void multipleSteps(SequenceStorage store, SliceInfo sinfo,
|
3792 | 3863 | @Cached EnsureCapacityNode ensureCapacityNode,
|
3793 | 3864 | @Cached LenNode selfLenNode,
|
3794 | 3865 | @Cached SetLenNode setLenNode,
|
3795 |
| - @Cached MemMoveNode memove, |
3796 |
| - @Cached @SuppressWarnings("unused") IsDataTypeCompatibleNode isDataTypeCompatibleNode) { |
| 3866 | + @Cached MemMoveNode memove) { |
3797 | 3867 | multipleSteps(store, sinfo, selfLenNode, setLenNode, ensureCapacityNode, memove);
|
3798 | 3868 | }
|
3799 | 3869 |
|
|
0 commit comments