Commit 6e6f13e6 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Don't call getGlobalsModule() when creating a function

This causes us to do some unwinding which ends up showing up
in the stats.  We have the globals dict available, so just use
that.

Things are a bit complicated because we use "globals==NULL" to
signify certain things, but the asserts seem to be panning out so
I think it's ok.
parent f6168fcf
......@@ -339,7 +339,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__");
......@@ -350,8 +352,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:
......@@ -361,7 +373,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__");
......@@ -375,10 +400,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
......@@ -515,9 +537,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);
......@@ -738,7 +739,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