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)
}
static PyObject*
match_span(MatchObject* self, PyObject* args)
match_span(MatchObject* self, PyObject* index_)
{
Py_ssize_t index;
PyObject* index_ = Py_False; /* zero */
if (!PyArg_UnpackTuple(args, "span", 0, 1, &index_))
return NULL;
if (!index_)
index_ = Py_False; /* zero */
index = match_getindex(self, index_);
......@@ -3682,7 +3681,7 @@ static PyMethodDef match_methods[] = {
{"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc},
{"start", (PyCFunction) match_start, METH_VARARGS, match_start_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,
match_groups_doc},
{"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS,
......
......@@ -222,12 +222,13 @@ IO_creadline(PyObject *self, char **output) {
}
static PyObject *
IO_readline(IOobject *self, PyObject *args) {
IO_readline(IOobject *self, PyObject *m_obj) {
int n, m=-1;
char *output;
if (args)
if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
// Pyston change:
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 (m >= 0 && m < n) {
......@@ -514,7 +515,7 @@ static struct PyMethodDef O_methods[] = {
{"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
{"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__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__},
{"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
{"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__},
......@@ -621,7 +622,7 @@ static struct PyMethodDef I_methods[] = {
{"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
{"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__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__},
{"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
{"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__},
......@@ -684,11 +685,8 @@ newIobject(PyObject *s) {
PyObject *args;
int result;
args = Py_BuildValue("(O)", s);
if (args == NULL)
return NULL;
result = PyArg_ParseTuple(args, "s*:StringIO", &buf);
Py_DECREF(args);
// Pyston change:
result = PyArg_ParseSingle(s, 1, "StringIO", "s*", &buf);
if (!result)
return NULL;
......@@ -713,11 +711,7 @@ PyDoc_STRVAR(IO_StringIO__doc__,
"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
static PyObject *
IO_StringIO(PyObject *self, PyObject *args) {
PyObject *s=0;
if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
IO_StringIO(PyObject *self, PyObject *s) {
if (s) return newIobject(s);
return newOobject(128);
}
......@@ -726,7 +720,7 @@ IO_StringIO(PyObject *self, PyObject *args) {
static struct PyMethodDef IO_methods[] = {
{"StringIO", (PyCFunction)IO_StringIO,
METH_VARARGS, IO_StringIO__doc__},
/* Pyston change: */ METH_O | METH_D1, IO_StringIO__doc__},
{NULL, NULL} /* sentinel */
};
......
......@@ -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
addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
{
PyObject *cobj;
const char *name;
if (freelist == NOCLEANUP)
return 0;
if (!*freelist) {
*freelist = PyList_New(0);
if (!*freelist) {
......@@ -569,22 +577,15 @@ float_argument_error(PyObject *arg)
return 0;
}
int _PyArg_ParseSingle_SizeT(PyObject* obj, int arg_idx, const char* fname, const char* format, ...) {
va_list va;
int vgetsingle(PyObject* obj, int arg_idx, const char* fname, const char* format, va_list *v_pa, int flags) {
char* msg;
char msgbuf[256];
assert(format[0] != '\0');
assert(format[0] != '(');
assert(format[0] != '|');
assert(format[0] != '|');
assert(format[1] != '*'); // would need to pass a non-null freelist
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);
msg = convertsimple(obj, &format, v_pa, flags, msgbuf, sizeof(msgbuf), NOCLEANUP);
if (msg) {
int levels[1];
......@@ -598,6 +599,26 @@ int _PyArg_ParseSingle_SizeT(PyObject* obj, int arg_idx, const char* fname, cons
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,
or a string with a message describing the failure. The message is
formatted as "must be <desired type>, not <actual type>".
......
......@@ -423,8 +423,6 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons
Box* passthrough = static_cast<Box*>(self);
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)));
methods++;
......
......@@ -1509,6 +1509,7 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
auto func = self->method_def->ml_meth;
ParamReceiveSpec paramspec(0, 0, true, false);
Box** defaults = NULL;
if (flags == METH_VARARGS) {
paramspec = ParamReceiveSpec(0, 0, true, false);
} else if (flags == (METH_VARARGS | METH_KEYWORDS)) {
......@@ -1519,6 +1520,27 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
paramspec = ParamReceiveSpec(1, 0, false, false);
} else if (flags == METH_OLDARGS) {
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 {
RELEASE_ASSERT(0, "0x%x", flags);
}
......@@ -1549,8 +1571,8 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
}
bool rewrite_success = false;
rearrangeArguments(paramspec, NULL, self->method_def->ml_name, NULL, rewrite_args, rewrite_success, argspec, arg1,
arg2, arg3, args, oargs, keyword_names);
rearrangeArguments(paramspec, NULL, self->method_def->ml_name, defaults, rewrite_args, rewrite_success, argspec,
arg1, arg2, arg3, args, oargs, keyword_names);
if (!rewrite_success)
rewrite_args = NULL;
......@@ -1578,6 +1600,22 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
rtn = (Box*)func(self->passthrough, arg1);
if (rewrite_args)
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) {
/* the really old style */
......
......@@ -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;
} else if (unused_positional.size()) {
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) {
std::string s = self->s();
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)
start_pos = s.find(old->s()[0], start_pos);
else
......@@ -1878,6 +1879,10 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
s.replace(start_pos, old->size(), new_->s());
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);
}
......
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