Skip to content

Commit bb0a256

Browse files
committed
remove Number.doubleValue() call - avoid megamorphism for svm
1 parent 91c92b6 commit bb0a256

File tree

1 file changed

+97
-63
lines changed

1 file changed

+97
-63
lines changed

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

Lines changed: 97 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@
4444
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
4545
import com.oracle.graal.python.runtime.exception.PException;
4646
import com.oracle.graal.python.runtime.sequence.PSequence;
47-
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
48-
import com.oracle.truffle.api.CompilerDirectives;
4947
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5048
import com.oracle.truffle.api.dsl.Cached;
5149
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -103,69 +101,110 @@ PArray arrayWithSequenceInitializer(PythonClass cls, String typeCode, String str
103101
return factory().createArray(cls, str.toCharArray());
104102
}
105103

106-
/**
107-
* @param cls
108-
*/
109-
@Specialization
110-
PArray arrayWithSequenceInitializer(PythonClass cls, String typeCode, PSequence initializer,
104+
protected boolean isIntArray(String typeCode) {
105+
return typeCode.charAt(0) == 'i';
106+
}
107+
108+
protected boolean isByteArray(String typeCode) {
109+
return typeCode.charAt(0) == 'b';
110+
}
111+
112+
protected boolean isDoubleArray(String typeCode) {
113+
return typeCode.charAt(0) == 'd';
114+
}
115+
116+
@Specialization(guards = "isByteArray(typeCode)")
117+
PArray arrayByteInitializer(PythonClass cls, @SuppressWarnings("unused") String typeCode, PSequence initializer,
111118
@Cached("create()") GetIteratorNode getIterator,
112119
@Cached("create()") GetNextNode next,
113120
@Cached("createBinaryProfile()") ConditionProfile errorProfile) {
114-
SequenceStorage store;
115-
switch (typeCode.charAt(0)) {
116-
case 'i':
117-
Object iter = getIterator.executeWith(initializer);
118-
int[] intArray = new int[initializer.len()];
119-
int i = 0;
120-
121-
while (true) {
122-
Object nextValue;
123-
try {
124-
nextValue = next.execute(iter);
125-
} catch (PException e) {
126-
e.expectStopIteration(getCore(), errorProfile);
127-
break;
128-
}
129-
if (nextValue instanceof Integer) {
130-
intArray[i++] = (int) nextValue;
131-
} else {
132-
CompilerDirectives.transferToInterpreter();
133-
operandTypeError();
134-
}
121+
Object iter = getIterator.executeWith(initializer);
122+
int i = 0;
123+
byte[] byteArray = new byte[initializer.len()];
124+
125+
while (true) {
126+
Object nextValue;
127+
try {
128+
nextValue = next.execute(iter);
129+
} catch (PException e) {
130+
e.expectStopIteration(getCore(), errorProfile);
131+
break;
132+
}
133+
134+
if (nextValue instanceof Byte) {
135+
byteArray[i++] = (byte) nextValue;
136+
}
137+
if (nextValue instanceof Integer) {
138+
int intValue = (int) nextValue;
139+
if (0 <= intValue && intValue <= 255) {
140+
byteArray[i++] = (byte) intValue;
141+
} else {
142+
throw raise(ValueError, "signed char is greater than maximum");
135143
}
144+
} else {
145+
throw raise(ValueError, "integer argument expected, got %p", nextValue);
146+
}
147+
}
136148

137-
return factory().createArray(cls, intArray);
138-
case 'd':
139-
store = initializer.getSequenceStorage();
140-
double[] doubleArray = new double[store.length()];
141-
142-
for (i = 0; i < doubleArray.length; i++) {
143-
Object val = store.getItemNormalized(i);
144-
if (val instanceof Number) {
145-
doubleArray[i] = ((Number) val).doubleValue();
146-
} else {
147-
throw raise(ValueError, "double value expected");
148-
}
149-
}
149+
return factory().createArray(cls, byteArray);
150+
}
150151

151-
return factory().createArray(cls, doubleArray);
152-
case 'b':
153-
store = initializer.getSequenceStorage();
154-
byte[] byteArray = new byte[store.length()];
155-
156-
for (i = 0; i < byteArray.length; i++) {
157-
Object val = store.getItemNormalized(i);
158-
if (val instanceof Number) {
159-
byteArray[i] = ((Number) val).byteValue();
160-
} else {
161-
throw raise(ValueError, "byte value expected");
162-
}
163-
}
152+
@Specialization(guards = "isIntArray(typeCode)")
153+
PArray arrayIntInitializer(PythonClass cls, @SuppressWarnings("unused") String typeCode, PSequence initializer,
154+
@Cached("create()") GetIteratorNode getIterator,
155+
@Cached("create()") GetNextNode next,
156+
@Cached("createBinaryProfile()") ConditionProfile errorProfile) {
157+
Object iter = getIterator.executeWith(initializer);
158+
int i = 0;
159+
160+
int[] intArray = new int[initializer.len()];
161+
162+
while (true) {
163+
Object nextValue;
164+
try {
165+
nextValue = next.execute(iter);
166+
} catch (PException e) {
167+
e.expectStopIteration(getCore(), errorProfile);
168+
break;
169+
}
170+
if (nextValue instanceof Integer) {
171+
intArray[i++] = (int) nextValue;
172+
} else {
173+
throw raise(ValueError, "integer argument expected, got %p", nextValue);
174+
}
175+
}
164176

165-
return factory().createArray(cls, byteArray);
166-
default:
167-
return null;
177+
return factory().createArray(cls, intArray);
178+
}
179+
180+
@Specialization(guards = "isDoubleArray(typeCode)")
181+
PArray arrayDoubleInitializer(PythonClass cls, @SuppressWarnings("unused") String typeCode, PSequence initializer,
182+
@Cached("create()") GetIteratorNode getIterator,
183+
@Cached("create()") GetNextNode next,
184+
@Cached("createBinaryProfile()") ConditionProfile errorProfile) {
185+
Object iter = getIterator.executeWith(initializer);
186+
int i = 0;
187+
188+
double[] doubleArray = new double[initializer.len()];
189+
190+
while (true) {
191+
Object nextValue;
192+
try {
193+
nextValue = next.execute(iter);
194+
} catch (PException e) {
195+
e.expectStopIteration(getCore(), errorProfile);
196+
break;
197+
}
198+
if (nextValue instanceof Integer) {
199+
doubleArray[i++] = ((Integer) nextValue).doubleValue();
200+
} else if (nextValue instanceof Double) {
201+
doubleArray[i++] = (double) nextValue;
202+
} else {
203+
throw raise(ValueError, "double value expected");
204+
}
168205
}
206+
207+
return factory().createArray(cls, doubleArray);
169208
}
170209

171210
@Specialization
@@ -191,12 +230,7 @@ private PArray makeEmptyArray(PythonClass cls, char type) {
191230

192231
@TruffleBoundary
193232
private void typeError(String typeCode, Object initializer) {
194-
throw raise(TypeError, "unsupported operand type: %s %s and 'array.array'", typeCode, initializer);
195-
}
196-
197-
@TruffleBoundary
198-
private static void operandTypeError() {
199-
throw new RuntimeException("Unexpected argument type for array() ");
233+
throw raise(TypeError, "cannot use a %p to initialize an array with typecode '%s'", initializer, typeCode);
200234
}
201235
}
202236
}

0 commit comments

Comments
 (0)