Commit 2b45543b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #871 from undingen/perf_pyxl3_clean

misc small perf improvments
parents 5c70bb30 d5a166cb
......@@ -1180,7 +1180,9 @@ entrance:
ctx->pattern[1], ctx->pattern[2]));
/* install new repeat context */
ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));
// Pyston change: use malloc
// ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));
ctx->u.rep = (SRE_REPEAT*) malloc(sizeof(*ctx->u.rep));
if (!ctx->u.rep) {
PyErr_NoMemory();
RETURN_FAILURE;
......@@ -1194,7 +1196,9 @@ entrance:
state->ptr = ctx->ptr;
DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]);
state->repeat = ctx->u.rep->prev;
PyObject_FREE(ctx->u.rep);
// Pyston change: use malloc
// PyObject_FREE(ctx->u.rep);
free(ctx->u.rep);
if (ret) {
RETURN_ON_ERROR(ret);
......
......@@ -118,17 +118,18 @@
#include "Python.h"
// Pyston change: disable custom memory managment because it confuses our GC
#define Py_USING_MEMORY_DEBUGGER 1
/* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile
the following code */
#ifndef PY_NO_SHORT_FLOAT_REPR
#include "float.h"
#define MALLOC PyMem_Malloc
#define FREE PyMem_Free
// Pyston change: use normal malloc allocator because it's faster and we can't use the GC
// because the custom memory managment functions inside this file are not compatible with it.
// #define MALLOC PyMem_Malloc
// #define FREE PyMem_Free
#define MALLOC malloc
#define FREE free
/* This code should also work for ARM mixed-endian format on little-endian
machines, where doubles have byte order 45670123 (in increasing address
......
......@@ -588,27 +588,95 @@ Box* setattrFunc(Box* obj, Box* _str, Box* value) {
return None;
}
Box* hasattr(Box* obj, Box* _str) {
static Box* hasattrFuncHelper(Box* return_val) noexcept {
if (return_val)
return True;
if (PyErr_Occurred()) {
if (!PyErr_ExceptionMatches(PyExc_Exception))
return NULL;
PyErr_Clear();
}
return False;
}
template <ExceptionStyle S>
Box* hasattrFuncInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1,
Box* arg2, Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) {
bool rewrite_success = false;
rearrangeArguments(ParamReceiveSpec(2, 0, false, false), NULL, "hasattr", NULL, rewrite_args, rewrite_success,
argspec, arg1, arg2, arg3, args, NULL, keyword_names);
if (!rewrite_success)
rewrite_args = NULL;
Box* obj = arg1;
Box* _str = arg2;
if (rewrite_args) {
// We need to make sure that the attribute string will be the same.
// Even though the passed string might not be the exact attribute name
// that we end up looking up (because we need to encode it or intern it),
// guarding on that object means (for strings and unicode) that the string
// value is fixed.
if (!PyString_CheckExact(_str) && !PyUnicode_CheckExact(_str))
rewrite_args = NULL;
else
rewrite_args->arg2->addGuard((intptr_t)arg2);
}
try {
_str = coerceUnicodeToStr(_str);
} catch (ExcInfo e) {
if (S == CAPI) {
setCAPIException(e);
return NULL;
} else
throw e;
}
if (_str->cls != str_cls) {
if (!PyString_Check(_str)) {
if (S == CAPI) {
PyErr_SetString(TypeError, "hasattr(): attribute name must be string");
return NULL;
} else
raiseExcHelper(TypeError, "hasattr(): attribute name must be string");
}
BoxedString* str = static_cast<BoxedString*>(_str);
if (!PyString_CHECK_INTERNED(str))
internStringMortalInplace(str);
Box* attr;
try {
attr = getattrInternal<ExceptionStyle::CXX>(obj, str, NULL);
} catch (ExcInfo e) {
if (e.matches(Exception))
return False;
throw e;
Box* rtn;
RewriterVar* r_rtn;
if (rewrite_args) {
GetattrRewriteArgs grewrite_args(rewrite_args->rewriter, rewrite_args->arg1, rewrite_args->destination);
rtn = getattrInternal<CAPI>(obj, str, &grewrite_args);
if (!grewrite_args.out_success)
rewrite_args = NULL;
else {
if (!rtn && !PyErr_Occurred())
r_rtn = rewrite_args->rewriter->loadConst(0);
else
r_rtn = grewrite_args.out_rtn;
}
} else {
rtn = getattrInternal<CAPI>(obj, str, NULL);
}
Box* rtn = attr ? True : False;
return rtn;
if (rewrite_args) {
RewriterVar* final_rtn = rewrite_args->rewriter->call(false, (void*)hasattrFuncHelper, r_rtn);
if (S == CXX)
rewrite_args->rewriter->checkAndThrowCAPIException(final_rtn);
rewrite_args->out_success = true;
rewrite_args->out_rtn = final_rtn;
}
Box* r = hasattrFuncHelper(rtn);
if (S == CXX && !r)
throwCAPIException();
return r;
}
Box* map2(Box* f, Box* container) {
......@@ -1547,8 +1615,10 @@ void setupBuiltins() {
"setattr",
new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)setattrFunc, UNKNOWN, 3, 0, false, false), "setattr"));
Box* hasattr_obj = new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)hasattr, BOXED_BOOL, 2), "hasattr");
builtins_module->giveAttr("hasattr", hasattr_obj);
auto hasattr_func = createRTFunction(2, 0, false, false);
hasattr_func->internal_callable.capi_val = &hasattrFuncInternal<CAPI>;
hasattr_func->internal_callable.cxx_val = &hasattrFuncInternal<CXX>;
builtins_module->giveAttr("hasattr", new BoxedBuiltinFunctionOrMethod(hasattr_func, "hasattr"));
builtins_module->giveAttr("pow", new BoxedBuiltinFunctionOrMethod(
boxRTFunction((void*)powFunc, UNKNOWN, 3, 1, false, false), "pow", { None }));
......
......@@ -698,6 +698,22 @@ Box* listIAdd(BoxedList* self, Box* _rhs) {
return self;
}
if (_rhs->cls == tuple_cls) {
BoxedTuple* rhs = static_cast<BoxedTuple*>(_rhs);
int s1 = self->size;
int s2 = rhs->ob_size;
if (s2 == 0)
return self;
self->ensure(s1 + s2);
memcpy(self->elts->elts + s1, rhs->elts, sizeof(self->elts->elts[0]) * s2);
self->size = s1 + s2;
return self;
}
RELEASE_ASSERT(_rhs != self, "unsupported");
for (auto* b : _rhs->pyElements())
......@@ -971,9 +987,7 @@ Box* listInit(BoxedList* self, Box* container) {
assert(PyList_Check(self));
if (container != None) {
for (Box* e : container->pyElements()) {
listAppendInternal(self, e);
}
listIAdd(self, container);
}
return None;
......
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