Commit fc8b1d26 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #680 from kmod/perf

rewrite some tp_call cases, and reduce calls to getTopPythonFrame
parents 04c38db9 6e6f13e6
......@@ -904,7 +904,7 @@ $(CMAKE_SETUP_GCC):
cd $(CMAKE_DIR_GCC); CC='$(GCC)' CXX='$(GPP)' cmake -GNinja $(SRC_DIR) -DCMAKE_BUILD_TYPE=Debug $(CMAKE_VALGRIND)
.PHONY: pyston_gcc
pyston_gcc: $(CMAKE_SETUP_GCC)
$(NINJA) -C $(CMAKE_DIR_DBG_GCC) pyston copy_stdlib copy_libpyston sharedmods ext_pyston ext_cpython $(NINJAFLAGS)
$(NINJA) -C $(CMAKE_DIR_DBG_GCC) pyston copy_stdlib copy_libpyston $(CMAKE_SHAREDMODS) ext_cpython $(NINJAFLAGS)
ln -sf $(CMAKE_DIR_DBG_GCC)/pyston pyston_gcc
.PHONY: format check_format
......
......@@ -18,6 +18,7 @@
#include "capi/types.h"
#include "runtime/classobj.h"
#include "runtime/objmodel.h"
#include "runtime/rewrite_args.h"
namespace pyston {
......@@ -2997,6 +2998,45 @@ extern "C" void PyType_Modified(PyTypeObject* type) noexcept {
// We don't cache anything yet that would need to be invalidated:
}
static Box* tppProxyToTpCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2,
Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) {
ParamReceiveSpec paramspec(0, 0, true, true);
if (!argspec.has_kwargs && argspec.num_keywords == 0) {
paramspec.takes_kwargs = false;
}
bool rewrite_success = false;
Box* oarg1, * oarg2 = NULL, *oarg3, ** oargs = NULL;
rearrangeArguments(paramspec, NULL, "", NULL, rewrite_args, rewrite_success, argspec, arg1, arg2, arg3, args,
keyword_names, oarg1, oarg2, oarg3, oargs);
if (!rewrite_success)
rewrite_args = NULL;
if (rewrite_args) {
if (!paramspec.takes_kwargs)
rewrite_args->arg2 = rewrite_args->rewriter->loadConst(0, Location::forArg(2));
// Currently, guard that the value of tp_call didn't change, and then
// emit a call to the current function address.
// It might be better to just load the current value of tp_call and call it
// (after guarding it's not null), or maybe not. But the rewriter doesn't currently
// support calling a RewriterVar (can only call fixed function addresses).
RewriterVar* r_cls = rewrite_args->obj->getAttr(offsetof(Box, cls));
r_cls->addAttrGuard(offsetof(BoxedClass, tp_call), (intptr_t)self->cls->tp_call);
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)self->cls->tp_call, rewrite_args->obj,
rewrite_args->arg1, rewrite_args->arg2);
rewrite_args->rewriter->call(true, (void*)checkAndThrowCAPIException);
rewrite_args->out_success = true;
}
Box* r = self->cls->tp_call(self, oarg1, oarg2);
if (!r)
throwCAPIException();
return r;
}
extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
ASSERT(!cls->is_pyston_class, "should not call this on Pyston classes");
......@@ -3044,9 +3084,9 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
cls->tp_dict = cls->getAttrWrapper();
assert(cls->tp_name);
// tp_name
// tp_basicsize, tp_itemsize
// tp_doc
if (cls->tp_call)
cls->tpp_call = tppProxyToTpCall;
try {
add_operators(cls);
......
......@@ -335,7 +335,9 @@ std::string builtinStr("__builtin__");
extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f)
: in_weakreflist(NULL), f(f), closure(NULL), ndefaults(0), defaults(NULL), modname(NULL), name(NULL), doc(NULL) {
if (f->source) {
this->modname = PyDict_GetItemString(getGlobalsDict(), "__name__");
assert(f->source->scoping->areGlobalsFromModule());
Box* globals_for_name = f->source->parent_module;
this->modname = globals_for_name->getattr("__name__");
this->doc = f->source->getDocString();
} else {
this->modname = PyString_InternFromString("__builtin__");
......@@ -346,8 +348,18 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f)
}
extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f, std::initializer_list<Box*> defaults,
BoxedClosure* closure)
: in_weakreflist(NULL), f(f), closure(closure), ndefaults(0), defaults(NULL), modname(NULL), name(NULL), doc(NULL) {
BoxedClosure* closure, Box* globals)
: in_weakreflist(NULL),
f(f),
closure(closure),
globals(globals),
ndefaults(0),
defaults(NULL),
modname(NULL),
name(NULL),
doc(NULL) {
assert((!globals) == (!f->source || f->source->scoping->areGlobalsFromModule()));
if (defaults.size()) {
// make sure to initialize defaults first, since the GC behavior is triggered by ndefaults,
// and a GC can happen within this constructor:
......@@ -357,7 +369,20 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f, std::initializer_
}
if (f->source) {
this->modname = PyDict_GetItemString(getGlobalsDict(), "__name__");
Box* globals_for_name = globals;
if (!globals_for_name) {
assert(f->source->scoping->areGlobalsFromModule());
globals_for_name = f->source->parent_module;
}
if (globals_for_name->cls == module_cls) {
this->modname = globals_for_name->getattr("__name__");
} else {
static Box* name_str = PyString_InternFromString("__name__");
this->modname = PyDict_GetItem(globals_for_name, name_str);
}
// It's ok for modname to be NULL
this->doc = f->source->getDocString();
} else {
this->modname = PyString_InternFromString("__builtin__");
......@@ -371,10 +396,7 @@ BoxedFunction::BoxedFunction(CLFunction* f) : BoxedFunction(f, {}) {
}
BoxedFunction::BoxedFunction(CLFunction* f, std::initializer_list<Box*> defaults, BoxedClosure* closure, Box* globals)
: BoxedFunctionBase(f, defaults, closure) {
assert((!globals) == (!f->source || f->source->scoping->areGlobalsFromModule()));
this->globals = globals;
: BoxedFunctionBase(f, defaults, closure, globals) {
// TODO eventually we want this to assert(f->source), I think, but there are still
// some builtin functions that are BoxedFunctions but really ought to be a type that
......@@ -511,9 +533,8 @@ void BoxedModule::gcHandler(GCVisitor* v, Box* b) {
// This mustn't throw; our IR generator generates calls to it without "invoke" even when there are exception handlers /
// finally-blocks in scope.
// TODO: should we use C++11 `noexcept' here?
extern "C" Box* boxCLFunction(CLFunction* f, BoxedClosure* closure, Box* globals,
std::initializer_list<Box*> defaults) {
std::initializer_list<Box*> defaults) noexcept {
STAT_TIMER(t0, "us_timer_boxclfunction", 10);
if (closure)
......
......@@ -129,7 +129,8 @@ char* getWriteableStringContents(BoxedString* s);
extern "C" void listAppendInternal(Box* self, Box* v);
extern "C" void listAppendArrayInternal(Box* self, Box** v, int nelts);
extern "C" Box* boxCLFunction(CLFunction* f, BoxedClosure* closure, Box* globals, std::initializer_list<Box*> defaults);
extern "C" Box* boxCLFunction(CLFunction* f, BoxedClosure* closure, Box* globals,
std::initializer_list<Box*> defaults) noexcept;
extern "C" CLFunction* unboxCLFunction(Box* b);
extern "C" Box* createUserClass(BoxedString* name, Box* base, Box* attr_dict);
extern "C" double unboxFloat(Box* b);
......@@ -748,7 +749,8 @@ public:
Box* doc; // __doc__
BoxedFunctionBase(CLFunction* f);
BoxedFunctionBase(CLFunction* f, std::initializer_list<Box*> defaults, BoxedClosure* closure = NULL);
BoxedFunctionBase(CLFunction* f, std::initializer_list<Box*> defaults, BoxedClosure* closure = NULL,
Box* globals = NULL);
};
class BoxedFunction : public BoxedFunctionBase {
......
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