Commit 57077ee1 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Cut out some exceptions-creation overhead

Call a combined new+init, and don't create an arg tuple just
to immediately slice into it.
parent 220f702e
...@@ -25,7 +25,7 @@ namespace pyston { ...@@ -25,7 +25,7 @@ namespace pyston {
typedef int (*update_callback)(PyTypeObject*, void*); typedef int (*update_callback)(PyTypeObject*, void*);
static PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) noexcept; PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) noexcept;
extern "C" void conservativeGCHandler(GCVisitor* v, Box* b) noexcept { extern "C" void conservativeGCHandler(GCVisitor* v, Box* b) noexcept {
v->visitPotentialRange((void* const*)b, (void* const*)((char*)b + b->cls->tp_basicsize)); v->visitPotentialRange((void* const*)b, (void* const*)((char*)b + b->cls->tp_basicsize));
...@@ -2001,7 +2001,7 @@ static int recurse_down_subclasses(PyTypeObject* type, PyObject* name, update_ca ...@@ -2001,7 +2001,7 @@ static int recurse_down_subclasses(PyTypeObject* type, PyObject* name, update_ca
return 0; return 0;
} }
static PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) noexcept { /* Pyston change: static */ PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) noexcept {
RELEASE_ASSERT(PyType_Check(self), ""); RELEASE_ASSERT(PyType_Check(self), "");
// ASSERT(self->tp_new != Py_CallPythonNew, "going to get in an infinite loop"); // ASSERT(self->tp_new != Py_CallPythonNew, "going to get in an infinite loop");
......
...@@ -50,6 +50,7 @@ PyObject* slot_mp_subscript(PyObject* self, PyObject* arg1) noexcept; ...@@ -50,6 +50,7 @@ PyObject* slot_mp_subscript(PyObject* self, PyObject* arg1) noexcept;
int slot_sq_contains(PyObject* self, PyObject* value) noexcept; int slot_sq_contains(PyObject* self, PyObject* value) noexcept;
Py_ssize_t slot_sq_length(PyObject* self) noexcept; Py_ssize_t slot_sq_length(PyObject* self) noexcept;
PyObject* slot_tp_getattr_hook(PyObject* self, PyObject* name) noexcept; PyObject* slot_tp_getattr_hook(PyObject* self, PyObject* name) noexcept;
PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) noexcept;
class GetattrRewriteArgs; class GetattrRewriteArgs;
Box* slotTpGetattrHookInternal(Box* self, BoxedString* attr, GetattrRewriteArgs* rewrite_args); Box* slotTpGetattrHookInternal(Box* self, BoxedString* attr, GetattrRewriteArgs* rewrite_args);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h" #include "llvm/Support/Path.h"
#include "capi/typeobject.h"
#include "capi/types.h" #include "capi/types.h"
#include "codegen/unwinding.h" #include "codegen/unwinding.h"
#include "core/threading.h" #include "core/threading.h"
...@@ -1516,6 +1517,29 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa ...@@ -1516,6 +1517,29 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
Box** oargs = NULL; Box** oargs = NULL;
if (func == (void*)tp_new_wrapper) {
assert(PyType_Check(self->passthrough));
BoxedClass* passthrough_cls = static_cast<BoxedClass*>(self->passthrough);
if (passthrough_cls->tp_new == BaseException->tp_new && argspec.num_args >= 1) {
// Optimization: BaseException->tp_new doesn't look at its arguments.
// Don't bother allocating any
assert(paramspec == ParamReceiveSpec(0, 0, true, true));
assert(PyType_Check(arg1));
Box* rtn = BaseException->tp_new(static_cast<BoxedClass*>(arg1), NULL, NULL);
if (rewrite_args) {
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)BaseException->tp_new, rewrite_args->arg1,
rewrite_args->rewriter->loadConst(0, Location::forArg(1)),
rewrite_args->rewriter->loadConst(0, Location::forArg(2)));
rewrite_args->out_success = true;
}
return rtn;
}
// TODO rewrite these cases specially; tp_new_wrapper just slices the args array,
// so we could just rearrangeArguments to the form that it wants and then call tp_new directly.
}
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, NULL, rewrite_args, rewrite_success, argspec, arg1,
arg2, arg3, args, oargs, keyword_names); arg2, arg3, args, oargs, keyword_names);
......
...@@ -408,6 +408,8 @@ extern "C" PyObject* PyTuple_Pack(Py_ssize_t n, ...) noexcept { ...@@ -408,6 +408,8 @@ extern "C" PyObject* PyTuple_Pack(Py_ssize_t n, ...) noexcept {
extern "C" PyObject* PyTuple_New(Py_ssize_t size) noexcept { extern "C" PyObject* PyTuple_New(Py_ssize_t size) noexcept {
RELEASE_ASSERT(size >= 0, ""); RELEASE_ASSERT(size >= 0, "");
if (size == 0)
return EmptyTuple;
return BoxedTuple::create(size); return BoxedTuple::create(size);
} }
......
...@@ -799,7 +799,8 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo ...@@ -799,7 +799,8 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
return unicodeNewHelper(cls, arg2, arg3, oargs); return unicodeNewHelper(cls, arg2, arg3, oargs);
} }
if (cls->tp_new != object_cls->tp_new && cls->tp_new != slot_tp_new && S == CXX) { if (cls->tp_new != object_cls->tp_new && cls->tp_new != slot_tp_new && cls->tp_new != BaseException->tp_new
&& S == CXX) {
// Looks like we're calling an extension class and we're not going to be able to // Looks like we're calling an extension class and we're not going to be able to
// separately rewrite the new + init calls. But we can rewrite the fact that we // separately rewrite the new + init calls. But we can rewrite the fact that we
// should just call the cpython version, which will end up working pretty well. // should just call the cpython version, which will end up working pretty well.
...@@ -955,6 +956,9 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo ...@@ -955,6 +956,9 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
} }
} }
if (cls->tp_new == BaseException->tp_new)
why_rewrite_allowed = VERIFIED;
bool know_first_arg = !argspec.has_starargs && !argspec.has_kwargs && argspec.num_keywords == 0; bool know_first_arg = !argspec.has_starargs && !argspec.has_kwargs && argspec.num_keywords == 0;
if (know_first_arg) { if (know_first_arg) {
......
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