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