109
109
import com .oracle .graal .python .nodes .object .GetClassNode .GetPythonObjectClassNode ;
110
110
import com .oracle .graal .python .nodes .util .CastToByteNode ;
111
111
import com .oracle .graal .python .nodes .util .CastToJavaByteNode ;
112
+ import com .oracle .graal .python .runtime .PythonContext ;
112
113
import com .oracle .graal .python .runtime .PythonOptions ;
113
114
import com .oracle .graal .python .runtime .exception .PException ;
115
+ import com .oracle .graal .python .runtime .native_memory .NativeBuffer ;
114
116
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
115
117
import com .oracle .graal .python .runtime .sequence .PSequence ;
116
118
import com .oracle .graal .python .runtime .sequence .storage .ArrayBasedSequenceStorage ;
129
131
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage .StorageType ;
130
132
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorageFactory ;
131
133
import com .oracle .graal .python .runtime .sequence .storage .SequenceStoreException ;
134
+ import com .oracle .graal .python .runtime .sequence .storage .NativePrimitiveSequenceStorage ;
135
+ import com .oracle .graal .python .runtime .sequence .storage .NativeIntSequenceStorage ;
132
136
import com .oracle .graal .python .util .BiFunction ;
133
137
import com .oracle .graal .python .util .OverflowException ;
134
138
import com .oracle .graal .python .util .PythonUtils ;
163
167
import com .oracle .truffle .api .profiles .InlinedExactClassProfile ;
164
168
import com .oracle .truffle .api .profiles .InlinedLoopConditionProfile ;
165
169
import com .oracle .truffle .api .strings .TruffleString ;
170
+ import sun .misc .Unsafe ;
166
171
167
172
public abstract class SequenceStorageNodes {
168
173
@@ -610,6 +615,11 @@ protected static Object doObject(ObjectSequenceStorage storage, int idx) {
610
615
return storage .getObjectItemNormalized (idx );
611
616
}
612
617
618
+ @ Specialization
619
+ protected static int doNativeInt (NativeIntSequenceStorage storage , int idx ) {
620
+ return storage .getIntItemNormalized (idx );
621
+ }
622
+
613
623
@ Specialization
614
624
protected static Object doMro (MroSequenceStorage storage , int idx ) {
615
625
return storage .getPythonClassItemNormalized (idx );
@@ -775,6 +785,13 @@ protected static SequenceStorage doMroSequenceStorage(MroSequenceStorage storage
775
785
return new ObjectSequenceStorage (newArray );
776
786
}
777
787
788
+ @ Specialization
789
+ protected static SequenceStorage doNativeInt (NativeIntSequenceStorage storage , int start , int stop , int step , int length ,
790
+ @ Bind ("this" ) Node node ) {
791
+ NativeBuffer sliceValueBuffer = doNativePrimitiveSliceInBound (PythonContext .get (node ), start , step , length , storage );
792
+ return PythonContext .get (node ).nativeBufferContext .createNativeIntStorage (sliceValueBuffer , length );
793
+ }
794
+
778
795
@ Specialization
779
796
protected static SequenceStorage doNativeByte (NativeByteSequenceStorage storage , int start , @ SuppressWarnings ("unused" ) int stop , int step , int length ,
780
797
@ Cached CStructAccess .ReadByteNode readNode ) {
@@ -797,6 +814,27 @@ protected static SequenceStorage doNativeObject(NativeObjectSequenceStorage stor
797
814
return new ObjectSequenceStorage (newArray );
798
815
}
799
816
817
+ private static NativeBuffer doNativePrimitiveSliceInBound (PythonContext pythonCtx , int start , int step , int sliceLength , NativePrimitiveSequenceStorage storage ) {
818
+ var unsafe = pythonCtx .getUnsafe ();
819
+ long itemSize = storage .getItemSize ();
820
+ long sizeInBytes = sliceLength * itemSize ;
821
+ NativeBuffer sliceBuffer = NativeBuffer .allocateNew (sizeInBytes );
822
+
823
+ if (step == 1 ) {
824
+ var startAddress = storage .getValueBufferAddr () + (start * itemSize );
825
+ unsafe .copyMemory (startAddress , sliceBuffer .getMemoryAddress (), sizeInBytes );
826
+ return sliceBuffer ;
827
+ }
828
+
829
+ var stepInBytes = step * itemSize ;
830
+ for (long srcAddr = storage .getValueBufferAddr () + (start * itemSize ), destAddr = sliceBuffer .getMemoryAddress (),
831
+ j = 0 ; j < sliceLength ; srcAddr += stepInBytes , destAddr += itemSize , j ++) {
832
+ unsafe .copyMemory (srcAddr , destAddr , itemSize );
833
+ }
834
+
835
+ return sliceBuffer ;
836
+ }
837
+
800
838
@ NeverDefault
801
839
public static GetItemSliceNode create () {
802
840
return GetItemSliceNodeGen .create ();
@@ -1183,6 +1221,11 @@ protected static void doInt(@SuppressWarnings("unused") Node inliningTarget, Int
1183
1221
storage .setIntItemNormalized (idx , value );
1184
1222
}
1185
1223
1224
+ @ Specialization
1225
+ protected static void doNativeInt (@ SuppressWarnings ("unused" ) Node inliningTarget , NativeIntSequenceStorage storage , int idx , int value ) {
1226
+ storage .setIntItemNormalized (idx , value );
1227
+ }
1228
+
1186
1229
@ Specialization (rewriteOn = OverflowException .class )
1187
1230
protected static void doIntL (@ SuppressWarnings ("unused" ) Node inliningTarget , IntSequenceStorage storage , int idx , long value ) throws OverflowException {
1188
1231
storage .setIntItemNormalized (idx , PInt .intValueExact (value ));
@@ -1515,6 +1558,23 @@ static void doObjectStorage(ObjectSequenceStorage storage) {
1515
1558
storage .reverse ();
1516
1559
}
1517
1560
1561
+ @ Specialization
1562
+ static void doNativePrimitive (Node inliningTarget , NativePrimitiveSequenceStorage storage ) {
1563
+ var length = storage .length ();
1564
+ var unsafe = PythonContext .get (inliningTarget ).getUnsafe ();
1565
+ long itemSize = storage .getItemSize ();
1566
+ long startAddress = storage .getValueBufferAddr ();
1567
+ long endAddress = startAddress + ((length - 1 ) * itemSize );
1568
+ byte [] tempBuffer = new byte [(int ) itemSize ];
1569
+ while (startAddress < endAddress ) {
1570
+ unsafe .copyMemory (null , startAddress , tempBuffer , Unsafe .ARRAY_BYTE_BASE_OFFSET , itemSize );
1571
+ unsafe .copyMemory (endAddress , startAddress , itemSize );
1572
+ unsafe .copyMemory (tempBuffer , Unsafe .ARRAY_BYTE_BASE_OFFSET , null , endAddress , itemSize );
1573
+ startAddress += itemSize ;
1574
+ endAddress -= itemSize ;
1575
+ }
1576
+ }
1577
+
1518
1578
@ Specialization
1519
1579
static void doBoolStorage (BoolSequenceStorage storage ) {
1520
1580
storage .reverse ();
@@ -3083,6 +3143,13 @@ static void doObject(ObjectSequenceStorage storage, int cap) {
3083
3143
storage .ensureCapacity (cap );
3084
3144
}
3085
3145
3146
+ @ Specialization
3147
+ static void doNativePrimitive (NativePrimitiveSequenceStorage storage , int cap ) {
3148
+ if (CompilerDirectives .injectBranchProbability (CompilerDirectives .UNLIKELY_PROBABILITY , cap > storage .getCapacity ())) {
3149
+ storage .reallocate (cap );
3150
+ }
3151
+ }
3152
+
3086
3153
@ Specialization
3087
3154
static void doBool (BoolSequenceStorage storage , int cap ) {
3088
3155
storage .ensureCapacity (cap );
@@ -3177,7 +3244,7 @@ private static int computeNewCapacity(int cap) {
3177
3244
@ GenerateCached (false )
3178
3245
public abstract static class CopyNode extends Node {
3179
3246
3180
- public abstract SequenceStorage execute (Node node , SequenceStorage s );
3247
+ public abstract SequenceStorage execute (Node inliningTarget , SequenceStorage s );
3181
3248
3182
3249
public static SequenceStorage executeUncached (SequenceStorage s ) {
3183
3250
return SequenceStorageNodesFactory .CopyNodeGen .getUncached ().execute (null , s );
@@ -3223,6 +3290,14 @@ static SequenceStorage doMro(MroSequenceStorage storage) {
3223
3290
return new ObjectSequenceStorage (PythonUtils .arrayCopyOf (storage .getInternalClassArray (), storage .length ()));
3224
3291
}
3225
3292
3293
+ @ Specialization
3294
+ static SequenceStorage doNativeInt (Node inliningTarget , NativeIntSequenceStorage storage ) {
3295
+ var nativeContext = PythonContext .get (inliningTarget ).getContext ().nativeBufferContext ;
3296
+ var copiedBuffer = storage .getValueBuffer ().copy ();
3297
+
3298
+ return nativeContext .createNativeIntStorage (copiedBuffer , storage .length ());
3299
+ }
3300
+
3226
3301
@ Specialization
3227
3302
static SequenceStorage doNativeBytes (NativeByteSequenceStorage s ,
3228
3303
@ Shared @ Cached (inline = false ) GetNativeItemScalarNode getItem ) {
@@ -3330,6 +3405,11 @@ static void doNative(NativeSequenceStorage s, int len,
3330
3405
@ Cached (inline = false ) SetNativeLenNode setLen ) {
3331
3406
setLen .execute (s , len );
3332
3407
}
3408
+
3409
+ @ Specialization
3410
+ static void doNativePrimitive (NativePrimitiveSequenceStorage s , int len ) {
3411
+ s .setNewLength (len );
3412
+ }
3333
3413
}
3334
3414
3335
3415
@ GenerateUncached
@@ -3441,15 +3521,15 @@ public abstract static class DeleteItemNode extends SequenceStorageBaseNode {
3441
3521
3442
3522
@ Specialization (guards = "isLastItem(s, idx)" )
3443
3523
static void doLastItem (Node inliningTarget , SequenceStorage s , @ SuppressWarnings ("unused" ) int idx ,
3444
- @ Shared @ Cached SetLenNode setLenNode ) {
3524
+ @ Exclusive @ Cached SetLenNode setLenNode ) {
3445
3525
setLenNode .execute (inliningTarget , s , s .length () - 1 );
3446
3526
}
3447
3527
3448
3528
@ Specialization
3449
3529
static void doGeneric (Node inliningTarget , SequenceStorage s , int idx ,
3450
3530
@ Cached GetItemScalarNode getItemNode ,
3451
3531
@ Cached SetItemScalarNode setItemNode ,
3452
- @ Shared @ Cached SetLenNode setLenNode ) {
3532
+ @ Exclusive @ Cached SetLenNode setLenNode ) {
3453
3533
int len = s .length ();
3454
3534
3455
3535
for (int i = idx ; i < len - 1 ; i ++) {
@@ -3860,9 +3940,29 @@ static SequenceStorage doArrayBasedStorage(Node inliningTarget, ArrayBasedSequen
3860
3940
3861
3941
}
3862
3942
3943
+ // TODO introduce something similar to InsertItemArrayBasedStorageNode
3944
+ @ Specialization
3945
+ static SequenceStorage doNativeInt (Node inliningTarget , NativeIntSequenceStorage storage , int index , int value ,
3946
+ @ Exclusive @ Cached EnsureCapacityNode ensureCapacity ) {
3947
+ int length = storage .length ();
3948
+ var context = PythonContext .get (inliningTarget );
3949
+ var unsafe = context .getUnsafe ();
3950
+ long itemSize = storage .getItemSize ();
3951
+ ensureCapacity .execute (inliningTarget , storage , length + 1 );
3952
+ // shifting tail to the right by one slot
3953
+ long startAddr = storage .getValueBufferAddr () + (index * itemSize );
3954
+ long endAddr = startAddr + itemSize ;
3955
+ long sizeInBytes = (length - index ) * itemSize ;
3956
+ unsafe .copyMemory (startAddr , endAddr , sizeInBytes );
3957
+
3958
+ storage .setIntItemNormalized (index , value );
3959
+ storage .incLength ();
3960
+ return storage ;
3961
+ }
3962
+
3863
3963
@ Specialization
3864
3964
protected static SequenceStorage doNativeStorage (Node inliningTarget , NativeSequenceStorage storage , int index , Object value ,
3865
- @ Cached EnsureCapacityNode ensureCapacityNode ,
3965
+ @ Exclusive @ Cached EnsureCapacityNode ensureCapacityNode ,
3866
3966
@ Cached (inline = false ) GetItemScalarNode getItem ,
3867
3967
@ Cached SetItemScalarNode setItem ) {
3868
3968
int newLength = storage .length () + 1 ;
0 commit comments