Commit 209350e6 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #980 from undingen/pyxl2_2

Misc pyxl2 perf improvements continued
parents 045a4279 9c5f4985
...@@ -456,7 +456,7 @@ struct _typeobject { ...@@ -456,7 +456,7 @@ struct _typeobject {
void* _hcls; void* _hcls;
void* _hcattrs; void* _hcattrs;
char _ics[32]; char _ics[40];
void* _gcvisit_func; void* _gcvisit_func;
int _attrs_offset; int _attrs_offset;
char _flags[7]; // These are bools in C++ char _flags[7]; // These are bools in C++
......
...@@ -7221,15 +7221,20 @@ old replaced by new. If the optional argument count is\n\ ...@@ -7221,15 +7221,20 @@ old replaced by new. If the optional argument count is\n\
given, only the first count occurrences are replaced."); given, only the first count occurrences are replaced.");
static PyObject* static PyObject*
unicode_replace(PyUnicodeObject *self, PyObject *args) // Pyston change: don't use varags calling convention
// unicode_replace(PyUnicodeObject *self, PyObject *args)
unicode_replace(PyUnicodeObject *self, PyUnicodeObject *str1, PyUnicodeObject* str2, PyObject** args)
{ {
PyUnicodeObject *str1; PyObject* _maxcount = args[0];
PyUnicodeObject *str2;
Py_ssize_t maxcount = -1; Py_ssize_t maxcount = -1;
PyObject *result; PyObject *result;
if (!PyArg_ParseTuple(args, "OO|n:replace", &str1, &str2, &maxcount)) // Pyston change: don't use varags calling convention
// if (!PyArg_ParseTuple(args, "OO|n:replace", &str1, &str2, &maxcount))
// return NULL;
if (_maxcount && !PyArg_ParseSingle(_maxcount, 3, "replace", "n", &maxcount))
return NULL; return NULL;
str1 = (PyUnicodeObject *)PyUnicode_FromObject((PyObject *)str1); str1 = (PyUnicodeObject *)PyUnicode_FromObject((PyObject *)str1);
if (str1 == NULL) if (str1 == NULL)
return NULL; return NULL;
...@@ -7832,7 +7837,7 @@ unicode_getnewargs(PyUnicodeObject *v) ...@@ -7832,7 +7837,7 @@ unicode_getnewargs(PyUnicodeObject *v)
static PyMethodDef unicode_methods[] = { static PyMethodDef unicode_methods[] = {
{"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__}, {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__},
{"replace", (PyCFunction) unicode_replace, METH_VARARGS, replace__doc__}, {"replace", (PyCFunction) unicode_replace, METH_O3 | METH_D1, replace__doc__},
{"split", (PyCFunction) unicode_split, METH_VARARGS, split__doc__}, {"split", (PyCFunction) unicode_split, METH_VARARGS, split__doc__},
{"rsplit", (PyCFunction) unicode_rsplit, METH_VARARGS, rsplit__doc__}, {"rsplit", (PyCFunction) unicode_rsplit, METH_VARARGS, rsplit__doc__},
{"join", (PyCFunction) unicode_join, METH_O, join__doc__}, {"join", (PyCFunction) unicode_join, METH_O, join__doc__},
......
...@@ -1014,24 +1014,26 @@ Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs* ...@@ -1014,24 +1014,26 @@ Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs*
return res; return res;
} else if (return_convention == ReturnConvention::NO_RETURN) { } else if (return_convention == ReturnConvention::NO_RETURN) {
assert(!res); assert(!res);
} else if (return_convention == ReturnConvention::CAPI_RETURN) { } else if (return_convention == ReturnConvention::CAPI_RETURN
|| return_convention == ReturnConvention::NOEXC_POSSIBLE) {
// If we get a CAPI return, we probably did a function call, and these guards // If we get a CAPI return, we probably did a function call, and these guards
// will probably just make the rewrite fail: // will probably just make the rewrite fail:
if (res) { if (res) {
rtn->addGuardNotEq(0); rtn->addGuardNotEq(0);
rewrite_args->setReturn(rtn, ReturnConvention::HAS_RETURN); rewrite_args->setReturn(rtn, ReturnConvention::HAS_RETURN);
return res; return res;
} else } else {
rtn->addGuard(0); // this could set a CAPI exception and we won't clear it inside the rewrite.
rewrite_args = 0;
}
} else { } else {
assert(return_convention == ReturnConvention::NOEXC_POSSIBLE); RELEASE_ASSERT(0, "");
rewrite_args = NULL;
} }
} }
} else { } else {
try { try {
assert(!PyType_Check(self)); // There would be a getattribute assert(!PyType_Check(self)); // There would be a getattribute
res = getattrInternalGeneric<false, rewritable>(self, name, NULL, false, false, NULL, NULL); res = getattrInternalGeneric<false, NOT_REWRITABLE>(self, name, NULL, false, false, NULL, NULL);
} catch (ExcInfo e) { } catch (ExcInfo e) {
if (!e.matches(AttributeError)) { if (!e.matches(AttributeError)) {
if (S == CAPI) { if (S == CAPI) {
......
...@@ -1273,7 +1273,6 @@ void setupList() { ...@@ -1273,7 +1273,6 @@ void setupList() {
static PyMappingMethods list_as_mapping; static PyMappingMethods list_as_mapping;
list_cls->tp_as_mapping = &list_as_mapping; list_cls->tp_as_mapping = &list_as_mapping;
list_cls->tp_iter = listIter;
list_iterator_cls = BoxedClass::create(type_cls, object_cls, &BoxedListIterator::gcHandler, 0, 0, list_iterator_cls = BoxedClass::create(type_cls, object_cls, &BoxedListIterator::gcHandler, 0, 0,
sizeof(BoxedListIterator), false, "listiterator"); sizeof(BoxedListIterator), false, "listiterator");
list_reverse_iterator_cls = BoxedClass::create(type_cls, object_cls, &BoxedListIterator::gcHandler, 0, 0, list_reverse_iterator_cls = BoxedClass::create(type_cls, object_cls, &BoxedListIterator::gcHandler, 0, 0,
...@@ -1356,6 +1355,7 @@ void setupList() { ...@@ -1356,6 +1355,7 @@ void setupList() {
list_cls->giveAttr("__hash__", None); list_cls->giveAttr("__hash__", None);
list_cls->freeze(); list_cls->freeze();
list_cls->tp_iter = listIter;
list_cls->tp_as_sequence->sq_length = list_length; list_cls->tp_as_sequence->sq_length = list_length;
list_cls->tp_as_sequence->sq_concat = (binaryfunc)list_concat; list_cls->tp_as_sequence->sq_concat = (binaryfunc)list_concat;
......
...@@ -5729,8 +5729,7 @@ Box* getiter(Box* o) { ...@@ -5729,8 +5729,7 @@ Box* getiter(Box* o) {
if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_ITER) && type->tp_iter != slot_tp_iter && type->tp_iter) { if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_ITER) && type->tp_iter != slot_tp_iter && type->tp_iter) {
r = type->tp_iter(o); r = type->tp_iter(o);
} else { } else {
static BoxedString* iter_str = internStringImmortal("__iter__"); r = type->callIterIC(o);
r = callattrInternal0<CXX, NOT_REWRITABLE>(o, iter_str, LookupScope::CLASS_ONLY, NULL, ArgPassSpec(0));
} }
if (r) { if (r) {
if (!PyIter_Check(r)) { if (!PyIter_Check(r)) {
......
...@@ -290,6 +290,20 @@ Box* BoxedClass::callReprIC(Box* obj) { ...@@ -290,6 +290,20 @@ Box* BoxedClass::callReprIC(Box* obj) {
return ic->call(obj, repr_str, callattr_flags, nullptr, nullptr, nullptr, nullptr, nullptr); return ic->call(obj, repr_str, callattr_flags, nullptr, nullptr, nullptr, nullptr, nullptr);
} }
Box* BoxedClass::callIterIC(Box* obj) {
assert(obj->cls == this);
auto ic = iter_ic.get();
if (!ic) {
ic = new CallattrIC();
iter_ic.reset(ic);
}
static BoxedString* iter_str = internStringImmortal("__iter__");
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
return ic->call(obj, iter_str, callattr_flags, nullptr, nullptr, nullptr, nullptr, nullptr);
}
bool BoxedClass::callNonzeroIC(Box* obj) { bool BoxedClass::callNonzeroIC(Box* obj) {
assert(obj->cls == this); assert(obj->cls == this);
......
...@@ -194,11 +194,12 @@ public: ...@@ -194,11 +194,12 @@ public:
// TODO: these don't actually get deallocated right now // TODO: these don't actually get deallocated right now
std::unique_ptr<CallattrCapiIC> next_ic; std::unique_ptr<CallattrCapiIC> next_ic;
std::unique_ptr<CallattrIC> hasnext_ic, repr_ic; std::unique_ptr<CallattrIC> hasnext_ic, repr_ic, iter_ic;
std::unique_ptr<NonzeroIC> nonzero_ic; std::unique_ptr<NonzeroIC> nonzero_ic;
Box* callHasnextIC(Box* obj, bool null_on_nonexistent); Box* callHasnextIC(Box* obj, bool null_on_nonexistent);
Box* call_nextIC(Box* obj) noexcept; Box* call_nextIC(Box* obj) noexcept;
Box* callReprIC(Box* obj); Box* callReprIC(Box* obj);
Box* callIterIC(Box* obj);
bool callNonzeroIC(Box* obj); bool callNonzeroIC(Box* obj);
gcvisit_func gc_visit; gcvisit_func gc_visit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment