Commit e7a6c890 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add refcounting to the new frame code

parent 772200b7
......@@ -68,7 +68,7 @@ BoxedCode* FunctionMetadata::getCode() {
if (!code_obj) {
code_obj = new BoxedCode(this);
// FunctionMetadatas don't currently participate in GC. They actually never get freed currently.
//gc::registerPermanentRoot(code_obj);
constants.push_back(code_obj);
}
return code_obj;
}
......
......@@ -268,7 +268,8 @@ void IRGenState::setupFrameInfoVar(llvm::Value* passed_closure, llvm::Value* pas
// (Since this can call into the GC, we have to initialize it to NULL first as we did above.)
this->boxed_locals = builder.CreateCall(g.funcs.createDict);
getRefcounts()->setType(this->boxed_locals, RefType::OWNED);
builder.CreateStore(this->boxed_locals, boxed_locals_gep);
auto inst = builder.CreateStore(this->boxed_locals, boxed_locals_gep);
getRefcounts()->refConsumed(this->boxed_locals, inst);
}
// frame_info.frame_obj = NULL
......@@ -2696,6 +2697,7 @@ public:
if (scope_info->takesClosure()) {
passed_closure = AI;
++AI;
emitter.setType(passed_closure, RefType::BORROWED);
} else {
passed_closure = getNullPtr(g.llvm_closure_type_ptr);
emitter.setType(passed_closure, RefType::BORROWED);
......
......@@ -919,7 +919,8 @@ static BoxedDict* localsForFrame(Box** vregs, CFG* cfg) {
for (auto& l : cfg->sym_vreg_map_user_visible) {
Box* val = vregs[l.second];
if (val) {
rtn->d[l.first.getBox()] = val;
assert(!rtn->d.count(l.first.getBox()));
rtn->d[incref(l.first.getBox())] = incref(val);
}
}
return rtn;
......@@ -963,10 +964,12 @@ Box* FrameInfo::updateBoxedLocals() {
}
if (!frame_info->boxedLocals) {
frame_info->boxedLocals = d;
frame_info->boxedLocals = incref(d);
return d;
}
AUTO_DECREF(d);
// Loop through all the values found above.
// TODO Right now d just has all the python variables that are *initialized*
// But we also need to loop through all the uninitialized variables that we have
......@@ -974,7 +977,8 @@ Box* FrameInfo::updateBoxedLocals() {
if (frame_info->boxedLocals->cls == dict_cls) {
BoxedDict* boxed_locals = (BoxedDict*)frame_info->boxedLocals;
for (auto&& new_elem : d->d) {
boxed_locals->d[new_elem.first] = new_elem.second;
assert(0 && "refcounting here is wrong if the key already exists");
boxed_locals->d[incref(new_elem.first)] = incref(new_elem.second);
}
} else {
for (const auto& p : *d) {
......
......@@ -478,7 +478,7 @@ public:
int numReceivedArgs() { return num_args + takes_varargs + takes_kwargs; }
BoxedCode* getCode();
BORROWED(BoxedCode*) getCode();
bool isGenerator() const {
if (source)
......@@ -944,12 +944,12 @@ struct FrameInfo {
Box* boxedLocals;
BoxedFrame* frame_obj;
BoxedClosure* passed_closure;
BORROWED(BoxedClosure*) passed_closure;
Box** vregs;
AST_stmt* stmt; // current statement
// This is either a module or a dict
Box* globals;
BORROWED(Box*) globals;
FrameInfo* back;
FunctionMetadata* md;
......
......@@ -304,7 +304,7 @@ bool exceptionAtLineCheck() {
void exceptionAtLine(LineInfo line_info, Box** traceback) {
if (exceptionAtLineCheck())
BoxedTraceback::here(line_info, traceback, getFrame((FrameInfo*)cur_thread_state.frame_info));
BoxedTraceback::here(line_info, traceback, autoDecref(getFrame((FrameInfo*)cur_thread_state.frame_info)));
}
void startReraise() {
......
......@@ -80,15 +80,17 @@ public:
auto f = static_cast<BoxedFrame*>(obj);
if (!f->_code)
f->_code = (Box*)f->frame_info->md->getCode();
return f->_code;
f->_code = incref((Box*)f->frame_info->md->getCode());
return incref(f->_code);
}
static Box* locals(Box* obj, void*) {
auto f = static_cast<BoxedFrame*>(obj);
if (f->hasExited())
return f->_locals;
return incref(f->_locals);
return f->frame_info->updateBoxedLocals();
}
......@@ -96,11 +98,15 @@ public:
auto f = static_cast<BoxedFrame*>(obj);
if (!f->_globals) {
f->_globals = f->frame_info->globals;
if (f->_globals && PyModule_Check(f->_globals))
f->_globals = f->_globals->getAttrWrapper();
Box* globals = f->frame_info->globals;
if (globals && PyModule_Check(globals))
f->_globals = globals->getAttrWrapper();
else {
f->_globals = incref(globals);
}
}
return f->_globals;
return incref(f->_globals);
}
static Box* back(Box* obj, void*) {
......@@ -108,11 +114,12 @@ public:
if (!f->_back) {
if (!f->frame_info->back)
f->_back = None;
f->_back = incref(None);
else
f->_back = BoxedFrame::boxFrame(f->frame_info->back);
}
return f->_back;
return incref(f->_back);
}
static Box* lineno(Box* obj, void*) {
......@@ -129,9 +136,11 @@ public:
if (hasExited())
return;
_back = back(this, NULL);
_code = code(this, NULL);
_globals = globals(this, NULL);
// Call the getters for their side-effects of caching the result:
autoDecref(back(this, NULL));
autoDecref(code(this, NULL));
autoDecref(globals(this, NULL));
assert(!_locals);
_locals = locals(this, NULL);
_stmt = frame_info->stmt;
......@@ -145,19 +154,28 @@ public:
if (fi->frame_obj == NULL)
fi->frame_obj = new BoxedFrame(fi);
assert(fi->frame_obj->cls == frame_cls);
return fi->frame_obj;
return incref(fi->frame_obj);
}
static void dealloc(Box* b) noexcept {
Py_FatalError("unimplemented");
BoxedFrame* f = static_cast<BoxedFrame*>(b);
//Py_DECREF(f->_back);
//Py_DECREF(f->_code);
//Py_DECREF(f->_globals);
//Py_DECREF(f->_locals);
_PyObject_GC_UNTRACK(f);
Py_DECREF(f->_back);
Py_DECREF(f->_code);
Py_DECREF(f->_globals);
Py_DECREF(f->_locals);
f->cls->tp_free(b);
}
static int traverse(Box* self, visitproc visit, void *arg) noexcept {
Py_FatalError("unimplemented");
BoxedFrame* o = static_cast<BoxedFrame*>(self);
Py_VISIT(o->_back);
Py_VISIT(o->_code);
Py_VISIT(o->_globals);
Py_VISIT(o->_locals);
return 0;
}
static int clear(Box* self) noexcept {
Py_FatalError("unimplemented");
......@@ -192,8 +210,11 @@ extern "C" void initFrame(FrameInfo* frame_info) {
extern "C" void deinitFrame(FrameInfo* frame_info) {
cur_thread_state.frame_info = frame_info->back;
BoxedFrame* frame = frame_info->frame_obj;
if (frame)
if (frame) {
frame->handleFrameExit();
Py_CLEAR(frame_info->frame_obj);
}
Py_CLEAR(frame_info->boxedLocals);
}
extern "C" int PyFrame_GetLineNumber(PyFrameObject* _f) noexcept {
......
......@@ -3470,9 +3470,11 @@ tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
void BoxedModule::dealloc(Box* b) noexcept {
BoxedModule* self = static_cast<BoxedModule*>(b);
BoxedModule::clear(b);
_PyObject_GC_UNTRACK(self);
b->cls->tp_free(b);
BoxedModule::clear(self);
b->cls->tp_free(self);
}
int BoxedModule::traverse(Box* _m, visitproc visit, void* arg) noexcept {
......
......@@ -865,6 +865,11 @@ struct BoxAndHash {
static unsigned getHashValue(BoxAndHash val) { return val.hash; }
};
};
// Similar to the incref(Box*) function:
inline BoxAndHash& incref(BoxAndHash& b) {
Py_INCREF(b.value);
return b;
}
class BoxedDict : public Box {
public:
......
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