Commit 206b8a24 authored by Kevin Modzelewski's avatar Kevin Modzelewski

fix materializeRef -> stealRef

parent 46af909b
...@@ -1505,7 +1505,8 @@ bool Rewriter::finishAssembly(int continue_offset) { ...@@ -1505,7 +1505,8 @@ bool Rewriter::finishAssembly(int continue_offset) {
void Rewriter::commitReturning(RewriterVar* var) { void Rewriter::commitReturning(RewriterVar* var) {
STAT_TIMER(t0, "us_timer_rewriter", 10); STAT_TIMER(t0, "us_timer_rewriter", 10);
assert(var->vrefcount == 0); assert(var->vrefcount == 1);
var->stealRef();
addAction([=]() { addAction([=]() {
assembler->comment("commitReturning"); assembler->comment("commitReturning");
...@@ -1513,6 +1514,8 @@ void Rewriter::commitReturning(RewriterVar* var) { ...@@ -1513,6 +1514,8 @@ void Rewriter::commitReturning(RewriterVar* var) {
var->bumpUse(); var->bumpUse();
}, { var }, ActionType::NORMAL); }, { var }, ActionType::NORMAL);
var->decvref();
commit(); commit();
} }
......
...@@ -270,19 +270,36 @@ public: ...@@ -270,19 +270,36 @@ public:
return this; return this;
} }
RewriterVar* materializeVref() { // Steal a ref (not a vref) from this object.
// If there aren't any owned refs available, one will be created.
// Doesn't change the vrefcount, but the vref that stealRef acts on
// becomes a borrowed vref. One can not use this RewriterVar after stealRef
// except for the operation that will actually steal the ref.
// If that is necessary, an extra vref should be taken out beforehand.
//
// Typical usage should look like:
// var->stealRef();
// functionThatStealsRef(var);
// var->decvref();
//
// If you need to use var after functionThatStealsRef, the whole snippet
// needs to be surrounded in an incvref/decvref.
//
// TODO: I still think I can find a better API for this. Maybe something like
// var->materializeRefFor([&](){ functionThatStealsRef(var); });
//
RewriterVar* stealRef() {
assert(reftype == RefType::OWNED || reftype == RefType::BORROWED); assert(reftype == RefType::OWNED || reftype == RefType::BORROWED);
assert(vrefcount > 0); assert(vrefcount > 0);
vrefcount--;
if (reftype == RefType::OWNED && vrefcount == 0) { if (reftype == RefType::OWNED && vrefcount == 1) {
// handoff, do nothing; // handoff, do nothing;
// we skip this incref because we skipped the decref in decvref (by touching vrefcount manually) reftype = RefType::BORROWED;
} else { } else {
incref(); incref();
} }
if (vrefcount == 0) { if (vrefcount == 1) {
// See the comment in decvref. // See the comment in decvref.
// This is similar, except that we want there to be exactly one more use of this variable: // This is similar, except that we want there to be exactly one more use of this variable:
// whatever consumes the vref. We want that to happen after the materializeVref call. // whatever consumes the vref. We want that to happen after the materializeVref call.
......
...@@ -339,6 +339,8 @@ RewriterVar* JitFragmentWriter::emitGetItem(AST_expr* node, RewriterVar* value, ...@@ -339,6 +339,8 @@ RewriterVar* JitFragmentWriter::emitGetItem(AST_expr* node, RewriterVar* value,
RewriterVar* JitFragmentWriter::emitGetLocal(InternedString s, int vreg) { RewriterVar* JitFragmentWriter::emitGetLocal(InternedString s, int vreg) {
assert(vreg >= 0); assert(vreg >= 0);
// TODO Can we use BORROWED here? Not sure if there are cases when we can't rely on borrowing the ref
// from the vregs array. Safer like this.
RewriterVar* val_var = vregs_array->getAttr(vreg * 8)->setType(RefType::OWNED); RewriterVar* val_var = vregs_array->getAttr(vreg * 8)->setType(RefType::OWNED);
addAction([=]() { _emitGetLocal(val_var, s.c_str()); }, { val_var }, ActionType::NORMAL); addAction([=]() { _emitGetLocal(val_var, s.c_str()); }, { val_var }, ActionType::NORMAL);
return val_var; return val_var;
...@@ -512,9 +514,9 @@ void JitFragmentWriter::emitReturn(RewriterVar* v) { ...@@ -512,9 +514,9 @@ void JitFragmentWriter::emitReturn(RewriterVar* v) {
v.second->decvref(); v.second->decvref();
} }
v->materializeVref(); v->stealRef();
addAction([=]() { _emitReturn(v); }, { v }, ActionType::NORMAL); addAction([=]() { _emitReturn(v); }, { v }, ActionType::NORMAL);
v->decvref();
} }
void JitFragmentWriter::emitSetAttr(AST_expr* node, RewriterVar* obj, BoxedString* s, RewriterVar* attr) { void JitFragmentWriter::emitSetAttr(AST_expr* node, RewriterVar* obj, BoxedString* s, RewriterVar* attr) {
...@@ -563,9 +565,12 @@ void JitFragmentWriter::emitSetLocal(InternedString s, int vreg, bool set_closur ...@@ -563,9 +565,12 @@ void JitFragmentWriter::emitSetLocal(InternedString s, int vreg, bool set_closur
v); v);
} else { } else {
RewriterVar* prev = vregs_array->getAttr(8 * vreg)->setType(RefType::OWNED); RewriterVar* prev = vregs_array->getAttr(8 * vreg)->setType(RefType::OWNED);
v->materializeVref(); v->stealRef();
vregs_array->setAttr(8 * vreg, v); vregs_array->setAttr(8 * vreg, v);
v->decvref();
// XXX: this either needs to be an xdecref or we should check liveness analysis. // XXX: this either needs to be an xdecref or we should check liveness analysis.
// keeping it like this for some performance testing but we need to fix this (will segfault
// on non-osr entries to the bjit)
prev->decvref(); prev->decvref();
//prev->xdecvref(); //prev->xdecvref();
} }
......
...@@ -1022,9 +1022,10 @@ void Box::setattr(BoxedString* attr, Box* val, SetattrRewriteArgs* rewrite_args) ...@@ -1022,9 +1022,10 @@ void Box::setattr(BoxedString* attr, Box* val, SetattrRewriteArgs* rewrite_args)
r_hattrs->getAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs)) r_hattrs->getAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs))
->setType(RefType::OWNED) ->setType(RefType::OWNED)
->decvref(); ->decvref();
rewrite_args->attrval->materializeVref(); rewrite_args->attrval->stealRef();
r_hattrs->setAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs), r_hattrs->setAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs),
rewrite_args->attrval); rewrite_args->attrval);
rewrite_args->attrval->decvref();
rewrite_args->out_success = true; rewrite_args->out_success = true;
} }
...@@ -4859,7 +4860,6 @@ extern "C" Box* binop(Box* lhs, Box* rhs, int op_type) { ...@@ -4859,7 +4860,6 @@ extern "C" Box* binop(Box* lhs, Box* rhs, int op_type) {
} else { } else {
rewriter->getArg(0)->decvref(); rewriter->getArg(0)->decvref();
rewriter->getArg(1)->decvref(); rewriter->getArg(1)->decvref();
rewrite_args.out_rtn->materializeVref();
rewriter->commitReturning(rewrite_args.out_rtn); rewriter->commitReturning(rewrite_args.out_rtn);
} }
} else { } else {
...@@ -6406,7 +6406,6 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) { ...@@ -6406,7 +6406,6 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) {
if (r) { if (r) {
if (rewriter.get()) { if (rewriter.get()) {
RewriterVar* r_rtn = rewrite_args.getReturn(ReturnConvention::HAS_RETURN); RewriterVar* r_rtn = rewrite_args.getReturn(ReturnConvention::HAS_RETURN);
r_rtn->materializeVref();
rewriter->commitReturning(r_rtn); rewriter->commitReturning(r_rtn);
} }
......
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