Skip to content

Commit 5967cf6

Browse files
committed
[GR-69626] Refactor PString for better footprint
PullRequest: graalpython/3999
2 parents 9005b05 + 53e4a7e commit 5967cf6

29 files changed

+326
-451
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@
123123
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
124124
import com.oracle.graal.python.builtins.objects.object.PythonObject;
125125
import com.oracle.graal.python.builtins.objects.set.PSet;
126-
import com.oracle.graal.python.builtins.objects.str.PString;
127126
import com.oracle.graal.python.builtins.objects.str.StringUtils;
128127
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
129128
import com.oracle.graal.python.lib.OsEnvironGetNode;
@@ -876,7 +875,7 @@ static Object which(Object object) {
876875
detail = whichCallTarget(fn.getCallTarget());
877876
} else if (object instanceof PBuiltinMethod fn) {
878877
detail = whichCallTarget(fn.getBuiltinFunction().getCallTarget());
879-
} else if (object instanceof PSequence sequence && !(object instanceof PString)) {
878+
} else if (object instanceof PSequence sequence) {
880879
detail = sequence.getSequenceStorage();
881880
} else if (object instanceof PArray array) {
882881
detail = array.getSequenceStorage();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -389,9 +389,10 @@ static int doOther(@SuppressWarnings("unused") Object extensionModule) {
389389
}
390390
}
391391

392-
@Builtin(name = "is_builtin", minNumOfPositionalArgs = 1)
392+
@Builtin(name = "is_builtin", minNumOfPositionalArgs = 1, numOfPositionalOnlyArgs = 1, parameterNames = {"name"})
393+
@ArgumentClinic(name = "name", conversion = ClinicConversion.TString)
393394
@GenerateNodeFactory
394-
public abstract static class IsBuiltin extends PythonBuiltinNode {
395+
public abstract static class IsBuiltin extends PythonUnaryClinicBuiltinNode {
395396

396397
@Specialization
397398
@TruffleBoundary
@@ -404,21 +405,9 @@ public int run(TruffleString name) {
404405
}
405406
}
406407

407-
@Specialization
408-
@TruffleBoundary
409-
public int run(PString name,
410-
@Bind Node inliningTarget,
411-
@Cached CastToTruffleStringNode toString) {
412-
try {
413-
return run(toString.execute(inliningTarget, name));
414-
} catch (CannotCastException e) {
415-
throw CompilerDirectives.shouldNotReachHere(e);
416-
}
417-
}
418-
419-
@Fallback
420-
public int run(@SuppressWarnings("unused") Object noName) {
421-
return 0;
408+
@Override
409+
protected ArgumentClinicProvider getArgumentClinic() {
410+
return ImpModuleBuiltinsClinicProviders.IsBuiltinClinicProviderGen.INSTANCE;
422411
}
423412
}
424413

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,20 @@
5555
import com.oracle.graal.python.annotations.ArgumentClinic;
5656
import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
5757
import com.oracle.graal.python.annotations.ArgumentClinic.PrimitiveType;
58+
import com.oracle.graal.python.annotations.Builtin;
5859
import com.oracle.graal.python.annotations.ClinicConverterFactory;
5960
import com.oracle.graal.python.annotations.ClinicConverterFactory.ArgumentName;
6061
import com.oracle.graal.python.annotations.ClinicConverterFactory.BuiltinName;
61-
import com.oracle.graal.python.annotations.Builtin;
62+
import com.oracle.graal.python.annotations.PythonOS;
6263
import com.oracle.graal.python.builtins.CoreFunctions;
6364
import com.oracle.graal.python.builtins.Python3Core;
6465
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
6566
import com.oracle.graal.python.builtins.PythonBuiltins;
66-
import com.oracle.graal.python.annotations.PythonOS;
6767
import com.oracle.graal.python.builtins.modules.SysModuleBuiltins.AuditNode;
6868
import com.oracle.graal.python.builtins.objects.PNone;
6969
import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
7070
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
7171
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
72-
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.LenNode;
7372
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
7473
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode;
7574
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToArrayNode;
@@ -128,7 +127,6 @@
128127
import com.oracle.graal.python.runtime.exception.PException;
129128
import com.oracle.graal.python.runtime.exception.PythonExitException;
130129
import com.oracle.graal.python.runtime.object.PFactory;
131-
import com.oracle.graal.python.runtime.sequence.PSequence;
132130
import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage;
133131
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
134132
import com.oracle.graal.python.util.OverflowException;
@@ -2020,21 +2018,19 @@ static long[] now(VirtualFrame frame, PNone times, PNone ns) {
20202018
@Specialization(guards = {"isNoValue(ns)"})
20212019
static long[] times(VirtualFrame frame, PTuple times, @SuppressWarnings("unused") PNone ns,
20222020
@Bind Node inliningTarget,
2023-
@Exclusive @Cached LenNode lenNode,
2024-
@Shared @Cached("createNotNormalized()") GetItemNode getItemNode,
2021+
@Shared @Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
20252022
@Cached ObjectToTimespecNode objectToTimespecNode,
20262023
@Exclusive @Cached PRaiseNode raiseNode) {
2027-
return convertToTimespec(frame, inliningTarget, times, lenNode, getItemNode, objectToTimespecNode, raiseNode);
2024+
return convertToTimespec(frame, inliningTarget, times, getItemNode, objectToTimespecNode, raiseNode);
20282025
}
20292026

20302027
@Specialization
20312028
static long[] ns(VirtualFrame frame, @SuppressWarnings("unused") PNone times, PTuple ns,
20322029
@Bind Node inliningTarget,
2033-
@Exclusive @Cached LenNode lenNode,
2034-
@Shared @Cached("createNotNormalized()") GetItemNode getItemNode,
2030+
@Shared @Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
20352031
@Cached SplitLongToSAndNsNode splitLongToSAndNsNode,
20362032
@Exclusive @Cached PRaiseNode raiseNode) {
2037-
return convertToTimespec(frame, inliningTarget, ns, lenNode, getItemNode, splitLongToSAndNsNode, raiseNode);
2033+
return convertToTimespec(frame, inliningTarget, ns, getItemNode, splitLongToSAndNsNode, raiseNode);
20382034
}
20392035

20402036
@Specialization(guards = {"!isPNone(times)", "!isNoValue(ns)"})
@@ -2066,14 +2062,15 @@ private static PException timesTupleError(Node inliningTarget, PRaiseNode raiseN
20662062
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_EITHER_OR, "utime", "times", "a tuple of two ints", "None");
20672063
}
20682064

2069-
private static long[] convertToTimespec(VirtualFrame frame, Node inliningTarget, PTuple times, LenNode lenNode, GetItemNode getItemNode, ConvertToTimespecBaseNode convertToTimespecBaseNode,
2070-
PRaiseNode raiseNode) {
2071-
if (lenNode.execute(inliningTarget, times) != 2) {
2065+
private static long[] convertToTimespec(VirtualFrame frame, Node inliningTarget, PTuple times, SequenceStorageNodes.GetItemScalarNode getItemNode,
2066+
ConvertToTimespecBaseNode convertToTimespecBaseNode, PRaiseNode raiseNode) {
2067+
SequenceStorage storage = times.getSequenceStorage();
2068+
if (storage.length() != 2) {
20722069
throw timesTupleError(inliningTarget, raiseNode);
20732070
}
20742071
long[] timespec = new long[4];
2075-
convertToTimespecBaseNode.execute(frame, inliningTarget, getItemNode.execute(times.getSequenceStorage(), 0), timespec, 0);
2076-
convertToTimespecBaseNode.execute(frame, inliningTarget, getItemNode.execute(times.getSequenceStorage(), 1), timespec, 2);
2072+
convertToTimespecBaseNode.execute(frame, inliningTarget, getItemNode.execute(inliningTarget, storage, 0), timespec, 0);
2073+
convertToTimespecBaseNode.execute(frame, inliningTarget, getItemNode.execute(inliningTarget, storage, 1), timespec, 2);
20772074
return timespec;
20782075
}
20792076
}
@@ -3245,17 +3242,19 @@ static void doLong(long value, long[] timespec, int offset) {
32453242
@Specialization(guards = {"!isInteger(value)"})
32463243
static void doGeneric(VirtualFrame frame, Node inliningTarget, Object value, long[] timespec, int offset,
32473244
@Cached PyNumberDivmodNode divmodNode,
3248-
@Cached LenNode lenNode,
32493245
@Cached(value = "createNotNormalized()", inline = false) GetItemNode getItemNode,
32503246
@Cached PyLongAsLongNode asLongNode,
32513247
@Cached PRaiseNode raiseNode) {
32523248
Object divmod = divmodNode.execute(frame, inliningTarget, value, BILLION);
3253-
if (!PGuards.isPTuple(divmod) || lenNode.execute(inliningTarget, (PSequence) divmod) != 2) {
3254-
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_RETURN_2TUPLE, value, divmod);
3249+
if (divmod instanceof PTuple tuple) {
3250+
SequenceStorage storage = tuple.getSequenceStorage();
3251+
if (storage.length() == 2) {
3252+
timespec[offset] = asLongNode.execute(frame, inliningTarget, getItemNode.execute(storage, 0));
3253+
timespec[offset + 1] = asLongNode.execute(frame, inliningTarget, getItemNode.execute(storage, 1));
3254+
return;
3255+
}
32553256
}
3256-
SequenceStorage storage = ((PTuple) divmod).getSequenceStorage();
3257-
timespec[offset] = asLongNode.execute(frame, inliningTarget, getItemNode.execute(storage, 0));
3258-
timespec[offset + 1] = asLongNode.execute(frame, inliningTarget, getItemNode.execute(storage, 1));
3257+
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_RETURN_2TUPLE, value, divmod);
32593258
}
32603259
}
32613260

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454

5555
import com.oracle.graal.python.annotations.ArgumentClinic;
5656
import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
57-
import com.oracle.graal.python.annotations.ClinicConverterFactory;
5857
import com.oracle.graal.python.annotations.Builtin;
58+
import com.oracle.graal.python.annotations.ClinicConverterFactory;
5959
import com.oracle.graal.python.builtins.CoreFunctions;
6060
import com.oracle.graal.python.builtins.PythonBuiltins;
6161
import com.oracle.graal.python.builtins.modules.PosixModuleBuiltins.ObjectToOpaquePathNode;
@@ -67,6 +67,7 @@
6767
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetSequenceStorageNode;
6868
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode;
6969
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
70+
import com.oracle.graal.python.builtins.objects.list.PList;
7071
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
7172
import com.oracle.graal.python.lib.PyObjectGetItem;
7273
import com.oracle.graal.python.lib.PyObjectSizeNode;
@@ -89,7 +90,6 @@
8990
import com.oracle.graal.python.runtime.PythonContext;
9091
import com.oracle.graal.python.runtime.PythonOptions;
9192
import com.oracle.graal.python.runtime.exception.PException;
92-
import com.oracle.graal.python.runtime.sequence.PSequence;
9393
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
9494
import com.oracle.graal.python.util.PythonUtils;
9595
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -132,19 +132,19 @@ static Object[] doSequence(VirtualFrame frame, Object processArgs,
132132
@Cached ObjectToOpaquePathNode objectToOpaquePathNode,
133133
@Cached("createNotNormalized()") GetItemNode getItemNode,
134134
@Cached PRaiseNode raiseNode) {
135-
PSequence argsSequence;
135+
PList argsList;
136136
try {
137-
argsSequence = fastConstructListNode.execute(frame, inliningTarget, processArgs);
137+
argsList = fastConstructListNode.execute(frame, inliningTarget, processArgs);
138138
} catch (PException e) {
139139
e.expect(inliningTarget, TypeError, isBuiltinClassProfile);
140140
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_MUST_BE_S, "argv", "a tuple");
141141
}
142142

143-
SequenceStorage argsStorage = getSequenceStorageNode.execute(inliningTarget, argsSequence);
143+
SequenceStorage argsStorage = getSequenceStorageNode.execute(inliningTarget, argsList);
144144
int len = argsStorage.length();
145145
Object[] argsArray = new Object[len];
146146
for (int i = 0; i < len; ++i) {
147-
SequenceStorage newStorage = getSequenceStorageNode.execute(inliningTarget, argsSequence);
147+
SequenceStorage newStorage = getSequenceStorageNode.execute(inliningTarget, argsList);
148148
if (newStorage != argsStorage || newStorage.length() != len) {
149149
// TODO write a test for this
150150
throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.ARGS_CHANGED_DURING_ITERATION);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SelectModuleBuiltins.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
import com.oracle.graal.python.runtime.PosixSupportLibrary.Timeval;
7777
import com.oracle.graal.python.runtime.exception.PythonErrorType;
7878
import com.oracle.graal.python.runtime.object.PFactory;
79-
import com.oracle.graal.python.runtime.sequence.PSequence;
8079
import com.oracle.graal.python.util.ArrayBuilder;
8180
import com.oracle.graal.python.util.IntArrayBuilder;
8281
import com.oracle.graal.python.util.PythonUtils;
@@ -192,9 +191,9 @@ private static ObjAndFDList seq2set(VirtualFrame frame, Node inliningTarget, Obj
192191
// repeatedly in the loop condition
193192
ArrayBuilder<Object> objects = new ArrayBuilder<>();
194193
IntArrayBuilder fds = new IntArrayBuilder();
195-
PSequence pSequence = constructListNode.execute(frame, inliningTarget, sequence);
194+
PList list = constructListNode.execute(frame, inliningTarget, sequence);
196195
for (int i = 0; i < sizeNode.execute(frame, inliningTarget, sequence); i++) {
197-
Object pythonObject = callGetItemNode.execute(frame, inliningTarget, pSequence, i);
196+
Object pythonObject = callGetItemNode.execute(frame, inliningTarget, list, i);
198197
objects.add(pythonObject);
199198
int fd = asFileDescriptor.execute(frame, inliningTarget, pythonObject);
200199
if (fd >= FD_SETSIZE.value) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@
7777
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.setter;
7878
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.vectorcallfunc;
7979
import static com.oracle.graal.python.nodes.HiddenAttr.METHOD_DEF_PTR;
80-
import static com.oracle.graal.python.nodes.HiddenAttr.NATIVE_STORAGE;
8180
import static com.oracle.graal.python.nodes.HiddenAttr.PROMOTED_START;
8281
import static com.oracle.graal.python.nodes.HiddenAttr.PROMOTED_STEP;
8382
import static com.oracle.graal.python.nodes.HiddenAttr.PROMOTED_STOP;
@@ -111,7 +110,7 @@
111110
import com.oracle.graal.python.builtins.objects.object.PythonObject;
112111
import com.oracle.graal.python.builtins.objects.set.PBaseSet;
113112
import com.oracle.graal.python.builtins.objects.slice.PSlice;
114-
import com.oracle.graal.python.builtins.objects.str.NativeCharSequence;
113+
import com.oracle.graal.python.builtins.objects.str.NativeStringData;
115114
import com.oracle.graal.python.builtins.objects.str.PString;
116115
import com.oracle.graal.python.builtins.objects.str.StringNodes;
117116
import com.oracle.graal.python.builtins.objects.str.StringNodes.StringLenNode;
@@ -167,10 +166,12 @@ abstract static class GraalPyPrivate_Get_PyASCIIObject_state_ascii extends CApiU
167166
int get(PString object,
168167
@Bind Node inliningTarget,
169168
@Cached InlinedConditionProfile storageProfile,
169+
@Cached HiddenAttr.ReadNode readAttrNode,
170170
@Cached TruffleString.GetCodeRangeNode getCodeRangeNode) {
171171
// important: avoid materialization of native sequences
172-
if (storageProfile.profile(inliningTarget, object.isNativeCharSequence())) {
173-
return object.getNativeCharSequence().isAsciiOnly() ? 1 : 0;
172+
NativeStringData nativeData = object.getNativeStringData(inliningTarget, readAttrNode);
173+
if (storageProfile.profile(inliningTarget, nativeData != null)) {
174+
return nativeData.isAscii() ? 1 : 0;
174175
}
175176

176177
TruffleString string = object.getMaterialized();
@@ -205,10 +206,12 @@ abstract static class GraalPyPrivate_Get_PyASCIIObject_state_kind extends CApiUn
205206
static int get(PString object,
206207
@Bind Node inliningTarget,
207208
@Cached InlinedConditionProfile storageProfile,
209+
@Cached HiddenAttr.ReadNode readAttrNode,
208210
@Cached TruffleString.GetCodeRangeNode getCodeRangeNode) {
209211
// important: avoid materialization of native sequences
210-
if (storageProfile.profile(inliningTarget, object.isNativeCharSequence())) {
211-
return object.getNativeCharSequence().getElementSize() & 0b111;
212+
NativeStringData nativeData = object.getNativeStringData(inliningTarget, readAttrNode);
213+
if (storageProfile.profile(inliningTarget, nativeData != null)) {
214+
return nativeData.getCharSize();
212215
}
213216
TruffleString string = object.getMaterialized();
214217
TruffleString.CodeRange range = getCodeRangeNode.execute(string, TS_ENCODING);
@@ -677,10 +680,12 @@ static Object get(PString object,
677680
@Cached TruffleString.SwitchEncodingNode switchEncodingNode,
678681
@Cached CStructAccess.AllocateNode allocateNode,
679682
@Cached CStructAccess.WriteTruffleStringNode writeTruffleStringNode,
680-
@Cached HiddenAttr.WriteNode writeAttribute) {
681-
if (object.isNativeCharSequence()) {
683+
@Cached HiddenAttr.ReadNode readAttrNode,
684+
@Cached HiddenAttr.WriteNode writeAttrNode) {
685+
NativeStringData nativeData = object.getNativeStringData(inliningTarget, readAttrNode);
686+
if (nativeData != null) {
682687
// in this case, we can just return the pointer
683-
return object.getNativeCharSequence().getPtr();
688+
return nativeData.getPtr();
684689
}
685690
TruffleString string = object.getMaterialized();
686691
TruffleString.CodeRange range = getCodeRangeNode.execute(string, TS_ENCODING);
@@ -702,20 +707,14 @@ static Object get(PString object,
702707
encoding = TruffleString.Encoding.UTF_32;
703708
}
704709
string = switchEncodingNode.execute(string, encoding);
705-
int byteLength = string.byteLength(encoding) + /* null terminator */ charSize;
706-
Object ptr = allocateNode.alloc(byteLength);
710+
int byteLength = string.byteLength(encoding);
711+
Object ptr = allocateNode.alloc(byteLength + /* null terminator */ charSize);
707712
writeTruffleStringNode.write(ptr, string, encoding);
708713
/*
709-
* Set native char sequence, so we can just return the pointer the next time.
714+
* Set native data, so we can just return the pointer the next time.
710715
*/
711-
NativeCharSequence nativeSequence = new NativeCharSequence(ptr, string.byteLength(encoding) / charSize, charSize, isAscii);
712-
object.setNativeCharSequence(nativeSequence);
713-
/*
714-
* Create a native sequence storage to manage the lifetime of the native memory.
715-
*
716-
* TODO it would be nicer if the native char sequence could manage its own memory
717-
*/
718-
writeAttribute.execute(inliningTarget, object, NATIVE_STORAGE, NativeByteSequenceStorage.create(ptr, byteLength, byteLength, true));
716+
NativeStringData data = NativeStringData.create(charSize, isAscii, ptr, byteLength);
717+
object.setNativeStringData(inliningTarget, writeAttrNode, data);
719718
return ptr;
720719
}
721720
}

0 commit comments

Comments
 (0)