Commit eed1d413 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #975 from kmod/perf8

pyxl_bench allocation reductions
parents a4b0a153 0724433e
...@@ -3538,13 +3538,12 @@ _pair(Py_ssize_t i1, Py_ssize_t i2) ...@@ -3538,13 +3538,12 @@ _pair(Py_ssize_t i1, Py_ssize_t i2)
} }
static PyObject* static PyObject*
match_span(MatchObject* self, PyObject* args) match_span(MatchObject* self, PyObject* index_)
{ {
Py_ssize_t index; Py_ssize_t index;
PyObject* index_ = Py_False; /* zero */ if (!index_)
if (!PyArg_UnpackTuple(args, "span", 0, 1, &index_)) index_ = Py_False; /* zero */
return NULL;
index = match_getindex(self, index_); index = match_getindex(self, index_);
...@@ -3682,7 +3681,7 @@ static PyMethodDef match_methods[] = { ...@@ -3682,7 +3681,7 @@ static PyMethodDef match_methods[] = {
{"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc}, {"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc},
{"start", (PyCFunction) match_start, METH_VARARGS, match_start_doc}, {"start", (PyCFunction) match_start, METH_VARARGS, match_start_doc},
{"end", (PyCFunction) match_end, METH_VARARGS, match_end_doc}, {"end", (PyCFunction) match_end, METH_VARARGS, match_end_doc},
{"span", (PyCFunction) match_span, METH_VARARGS, match_span_doc}, {"span", (PyCFunction) match_span, METH_O | METH_D1, match_span_doc},
{"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS, {"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS,
match_groups_doc}, match_groups_doc},
{"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS, {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS,
......
...@@ -222,12 +222,13 @@ IO_creadline(PyObject *self, char **output) { ...@@ -222,12 +222,13 @@ IO_creadline(PyObject *self, char **output) {
} }
static PyObject * static PyObject *
IO_readline(IOobject *self, PyObject *args) { IO_readline(IOobject *self, PyObject *m_obj) {
int n, m=-1; int n, m=-1;
char *output; char *output;
if (args) // Pyston change:
if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL; if (m_obj)
if (!PyArg_ParseSingle(m_obj, 1, "readline", "i", &m)) return NULL;
if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL; if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
if (m >= 0 && m < n) { if (m >= 0 && m < n) {
...@@ -514,7 +515,7 @@ static struct PyMethodDef O_methods[] = { ...@@ -514,7 +515,7 @@ static struct PyMethodDef O_methods[] = {
{"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__}, {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
{"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__}, {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__},
{"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__}, {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__},
{"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__}, {"readline", (PyCFunction)IO_readline, /* Pyston change: */ METH_O | METH_D1, IO_readline__doc__},
{"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__}, {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
{"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__}, {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
{"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__}, {"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__},
...@@ -621,7 +622,7 @@ static struct PyMethodDef I_methods[] = { ...@@ -621,7 +622,7 @@ static struct PyMethodDef I_methods[] = {
{"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__}, {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
{"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__}, {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__},
{"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__}, {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__},
{"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__}, {"readline", (PyCFunction)IO_readline, /* Pyston change: */ METH_O | METH_D1, IO_readline__doc__},
{"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__}, {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
{"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__}, {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
{"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__}, {"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__},
...@@ -684,11 +685,8 @@ newIobject(PyObject *s) { ...@@ -684,11 +685,8 @@ newIobject(PyObject *s) {
PyObject *args; PyObject *args;
int result; int result;
args = Py_BuildValue("(O)", s); // Pyston change:
if (args == NULL) result = PyArg_ParseSingle(s, 1, "StringIO", "s*", &buf);
return NULL;
result = PyArg_ParseTuple(args, "s*:StringIO", &buf);
Py_DECREF(args);
if (!result) if (!result)
return NULL; return NULL;
...@@ -713,11 +711,7 @@ PyDoc_STRVAR(IO_StringIO__doc__, ...@@ -713,11 +711,7 @@ PyDoc_STRVAR(IO_StringIO__doc__,
"StringIO([s]) -- Return a StringIO-like stream for reading or writing"); "StringIO([s]) -- Return a StringIO-like stream for reading or writing");
static PyObject * static PyObject *
IO_StringIO(PyObject *self, PyObject *args) { IO_StringIO(PyObject *self, PyObject *s) {
PyObject *s=0;
if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
if (s) return newIobject(s); if (s) return newIobject(s);
return newOobject(128); return newOobject(128);
} }
...@@ -726,7 +720,7 @@ IO_StringIO(PyObject *self, PyObject *args) { ...@@ -726,7 +720,7 @@ IO_StringIO(PyObject *self, PyObject *args) {
static struct PyMethodDef IO_methods[] = { static struct PyMethodDef IO_methods[] = {
{"StringIO", (PyCFunction)IO_StringIO, {"StringIO", (PyCFunction)IO_StringIO,
METH_VARARGS, IO_StringIO__doc__}, /* Pyston change: */ METH_O | METH_D1, IO_StringIO__doc__},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
......
...@@ -161,12 +161,20 @@ cleanup_buffer(PyObject *self) ...@@ -161,12 +161,20 @@ cleanup_buffer(PyObject *self)
} }
} }
// A special cleanup "list" that specifies that we don't need to keep track of cleanups.
// This is useful for vgetsingle, where there are no partial-failure cases that require
// keeping track of cleanups.
#define NOCLEANUP ((PyObject**)1)
static int static int
addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr) addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
{ {
PyObject *cobj; PyObject *cobj;
const char *name; const char *name;
if (freelist == NOCLEANUP)
return 0;
if (!*freelist) { if (!*freelist) {
*freelist = PyList_New(0); *freelist = PyList_New(0);
if (!*freelist) { if (!*freelist) {
...@@ -569,22 +577,15 @@ float_argument_error(PyObject *arg) ...@@ -569,22 +577,15 @@ float_argument_error(PyObject *arg)
return 0; return 0;
} }
int _PyArg_ParseSingle_SizeT(PyObject* obj, int arg_idx, const char* fname, const char* format, ...) { int vgetsingle(PyObject* obj, int arg_idx, const char* fname, const char* format, va_list *v_pa, int flags) {
va_list va;
char* msg; char* msg;
char msgbuf[256]; char msgbuf[256];
assert(format[0] != '\0'); assert(format[0] != '\0');
assert(format[0] != '('); assert(format[0] != '(');
assert(format[0] != '|'); assert(format[0] != '|');
assert(format[0] != '|');
assert(format[1] != '*'); // would need to pass a non-null freelist msg = convertsimple(obj, &format, v_pa, flags, msgbuf, sizeof(msgbuf), NOCLEANUP);
assert(format[0] != 'e'); // would need to pass a non-null freelist
va_start(va, format);
msg = convertsimple(obj, &format, &va, FLAG_SIZE_T, msgbuf, sizeof(msgbuf), NULL);
va_end(va);
if (msg) { if (msg) {
int levels[1]; int levels[1];
...@@ -598,6 +599,26 @@ int _PyArg_ParseSingle_SizeT(PyObject* obj, int arg_idx, const char* fname, cons ...@@ -598,6 +599,26 @@ int _PyArg_ParseSingle_SizeT(PyObject* obj, int arg_idx, const char* fname, cons
return 1; return 1;
} }
int PyArg_ParseSingle(PyObject* obj, int arg_idx, const char* fname, const char* format, ...) {
va_list va;
va_start(va, format);
int r = vgetsingle(obj, arg_idx, fname, format, &va, 0);
va_end(va);
return r;
}
int _PyArg_ParseSingle_SizeT(PyObject* obj, int arg_idx, const char* fname, const char* format, ...) {
va_list va;
va_start(va, format);
int r = vgetsingle(obj, arg_idx, fname, format, &va, FLAG_SIZE_T);
va_end(va);
return r;
}
/* Convert a non-tuple argument. Return NULL if conversion went OK, /* Convert a non-tuple argument. Return NULL if conversion went OK,
or a string with a message describing the failure. The message is or a string with a message describing the failure. The message is
formatted as "must be <desired type>, not <actual type>". formatted as "must be <desired type>, not <actual type>".
......
...@@ -423,8 +423,6 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons ...@@ -423,8 +423,6 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons
Box* passthrough = static_cast<Box*>(self); Box* passthrough = static_cast<Box*>(self);
while (methods && methods->ml_name) { while (methods && methods->ml_name) {
RELEASE_ASSERT((methods->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0, "%d",
methods->ml_flags);
module->giveAttr(methods->ml_name, new BoxedCApiFunction(methods, passthrough, boxString(name))); module->giveAttr(methods->ml_name, new BoxedCApiFunction(methods, passthrough, boxString(name)));
methods++; methods++;
......
...@@ -1509,6 +1509,7 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa ...@@ -1509,6 +1509,7 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
auto func = self->method_def->ml_meth; auto func = self->method_def->ml_meth;
ParamReceiveSpec paramspec(0, 0, true, false); ParamReceiveSpec paramspec(0, 0, true, false);
Box** defaults = NULL;
if (flags == METH_VARARGS) { if (flags == METH_VARARGS) {
paramspec = ParamReceiveSpec(0, 0, true, false); paramspec = ParamReceiveSpec(0, 0, true, false);
} else if (flags == (METH_VARARGS | METH_KEYWORDS)) { } else if (flags == (METH_VARARGS | METH_KEYWORDS)) {
...@@ -1519,6 +1520,27 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa ...@@ -1519,6 +1520,27 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
paramspec = ParamReceiveSpec(1, 0, false, false); paramspec = ParamReceiveSpec(1, 0, false, false);
} else if (flags == METH_OLDARGS) { } else if (flags == METH_OLDARGS) {
paramspec = ParamReceiveSpec(1, 0, false, false); paramspec = ParamReceiveSpec(1, 0, false, false);
} else if ((flags & ~(METH_O3 | METH_D3)) == 0) {
int num_args = 0;
if (flags & METH_O)
num_args++;
if (flags & METH_O2)
num_args += 2;
int num_defaults = 0;
if (flags & METH_D1)
num_defaults++;
if (flags & METH_D2)
num_defaults += 2;
paramspec = ParamReceiveSpec(num_args, num_defaults, false, false);
if (num_defaults) {
static Box* _defaults[] = { NULL, NULL, NULL };
assert(num_defaults <= 3);
defaults = _defaults;
}
assert(paramspec.totalReceived() <= 3); // would need to allocate oargs
} else { } else {
RELEASE_ASSERT(0, "0x%x", flags); RELEASE_ASSERT(0, "0x%x", flags);
} }
...@@ -1549,8 +1571,8 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa ...@@ -1549,8 +1571,8 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
} }
bool rewrite_success = false; bool rewrite_success = false;
rearrangeArguments(paramspec, NULL, self->method_def->ml_name, NULL, rewrite_args, rewrite_success, argspec, arg1, rearrangeArguments(paramspec, NULL, self->method_def->ml_name, defaults, rewrite_args, rewrite_success, argspec,
arg2, arg3, args, oargs, keyword_names); arg1, arg2, arg3, args, oargs, keyword_names);
if (!rewrite_success) if (!rewrite_success)
rewrite_args = NULL; rewrite_args = NULL;
...@@ -1578,6 +1600,22 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa ...@@ -1578,6 +1600,22 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
rtn = (Box*)func(self->passthrough, arg1); rtn = (Box*)func(self->passthrough, arg1);
if (rewrite_args) if (rewrite_args)
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1); rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1);
} else if ((flags & ~(METH_O3 | METH_D3)) == 0) {
assert(paramspec.totalReceived() <= 3); // would need to pass through oargs
rtn = ((Box * (*)(Box*, Box*, Box*, Box*))func)(self->passthrough, arg1, arg2, arg3);
if (rewrite_args) {
if (paramspec.totalReceived() == 1)
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1);
else if (paramspec.totalReceived() == 2)
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough,
rewrite_args->arg1, rewrite_args->arg2);
else if (paramspec.totalReceived() == 3)
rewrite_args->out_rtn = rewrite_args->rewriter->call(
true, (void*)func, r_passthrough, rewrite_args->arg1, rewrite_args->arg2, rewrite_args->arg3);
else
abort();
}
} else if (flags == METH_OLDARGS) { } else if (flags == METH_OLDARGS) {
/* the really old style */ /* the really old style */
......
...@@ -3569,7 +3569,20 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3569,7 +3569,20 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
} }
} }
Box* ovarargs = BoxedTuple::create(unused_positional.size(), unused_positional.data()); Box* ovarargs;
if (argspec.num_args == 0 && paramspec.num_args == 0 && (!varargs || varargs->cls == tuple_cls)) {
// We probably could have cut out a lot more of the overhead in this case:
assert(varargs_size == unused_positional.size());
if (!varargs)
ovarargs = EmptyTuple;
else
ovarargs = varargs;
} else {
ovarargs = BoxedTuple::create(unused_positional.size(), unused_positional.data());
}
assert(ovarargs->cls == tuple_cls);
getArg(varargs_idx, oarg1, oarg2, oarg3, oargs) = ovarargs; getArg(varargs_idx, oarg1, oarg2, oarg3, oargs) = ovarargs;
} else if (unused_positional.size()) { } else if (unused_positional.size()) {
raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%ld given)", func_name_cb(), paramspec.num_args, raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%ld given)", func_name_cb(), paramspec.num_args,
......
...@@ -1867,7 +1867,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) { ...@@ -1867,7 +1867,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
std::string s = self->s(); std::string s = self->s();
bool single_char = old->size() == 1; bool single_char = old->size() == 1;
for (int num_replaced = 0; num_replaced < max_replaces || max_replaces < 0; ++num_replaced) { int num_replaced = 0;
for (; num_replaced < max_replaces || max_replaces < 0; ++num_replaced) {
if (single_char) if (single_char)
start_pos = s.find(old->s()[0], start_pos); start_pos = s.find(old->s()[0], start_pos);
else else
...@@ -1878,6 +1879,10 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) { ...@@ -1878,6 +1879,10 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
s.replace(start_pos, old->size(), new_->s()); s.replace(start_pos, old->size(), new_->s());
start_pos += new_->size(); // Handles case where 'to' is a substring of 'from' start_pos += new_->size(); // Handles case where 'to' is a substring of 'from'
} }
if (num_replaced == 0 && self->cls == str_cls)
return self;
return boxString(s); return boxString(s);
} }
......
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