Commit 37b5d25f authored by Kevin Modzelewski's avatar Kevin Modzelewski

xxx wip

parent 43344454
...@@ -270,6 +270,8 @@ void Rewriter::assertArgsInPlace() { ...@@ -270,6 +270,8 @@ void Rewriter::assertArgsInPlace() {
void RewriterVar::addGuard(uint64_t val) { void RewriterVar::addGuard(uint64_t val) {
STAT_TIMER(t0, "us_timer_rewriter", 10); STAT_TIMER(t0, "us_timer_rewriter", 10);
assert(this->reftype == RefType::UNKNOWN || this->vrefcount > 0);
if (isConstant()) { if (isConstant()) {
RELEASE_ASSERT(constant_value == val, "added guard which is always false"); RELEASE_ASSERT(constant_value == val, "added guard which is always false");
return; return;
...@@ -323,6 +325,8 @@ void Rewriter::_addGuard(RewriterVar* var, RewriterVar* val_constant) { ...@@ -323,6 +325,8 @@ void Rewriter::_addGuard(RewriterVar* var, RewriterVar* val_constant) {
void RewriterVar::addGuardNotEq(uint64_t val) { void RewriterVar::addGuardNotEq(uint64_t val) {
STAT_TIMER(t0, "us_timer_rewriter", 10); STAT_TIMER(t0, "us_timer_rewriter", 10);
assert(this->reftype == RefType::UNKNOWN || this->vrefcount > 0);
RewriterVar* val_var = rewriter->loadConst(val); RewriterVar* val_var = rewriter->loadConst(val);
rewriter->addAction([=]() { rewriter->_addGuardNotEq(this, val_var); }, { this, val_var }, ActionType::GUARD); rewriter->addAction([=]() { rewriter->_addGuardNotEq(this, val_var); }, { this, val_var }, ActionType::GUARD);
} }
...@@ -354,6 +358,8 @@ void Rewriter::_addGuardNotEq(RewriterVar* var, RewriterVar* val_constant) { ...@@ -354,6 +358,8 @@ void Rewriter::_addGuardNotEq(RewriterVar* var, RewriterVar* val_constant) {
void RewriterVar::addAttrGuard(int offset, uint64_t val, bool negate) { void RewriterVar::addAttrGuard(int offset, uint64_t val, bool negate) {
STAT_TIMER(t0, "us_timer_rewriter", 10); STAT_TIMER(t0, "us_timer_rewriter", 10);
assert(this->reftype == RefType::UNKNOWN || this->vrefcount > 0);
if (!attr_guards.insert(std::make_tuple(offset, val, negate)).second) if (!attr_guards.insert(std::make_tuple(offset, val, negate)).second)
return; // duplicate guard detected return; // duplicate guard detected
...@@ -405,6 +411,8 @@ void Rewriter::_addAttrGuard(RewriterVar* var, int offset, RewriterVar* val_cons ...@@ -405,6 +411,8 @@ void Rewriter::_addAttrGuard(RewriterVar* var, int offset, RewriterVar* val_cons
RewriterVar* RewriterVar::getAttr(int offset, Location dest, assembler::MovType type) { RewriterVar* RewriterVar::getAttr(int offset, Location dest, assembler::MovType type) {
STAT_TIMER(t0, "us_timer_rewriter", 10); STAT_TIMER(t0, "us_timer_rewriter", 10);
assert(this->reftype == RefType::UNKNOWN || this->vrefcount > 0);
RewriterVar* result = rewriter->createNewVar(); RewriterVar* result = rewriter->createNewVar();
rewriter->addAction([=]() { rewriter->_getAttr(result, this, offset, dest, type); }, { this }, ActionType::NORMAL); rewriter->addAction([=]() { rewriter->_getAttr(result, this, offset, dest, type); }, { this }, ActionType::NORMAL);
return result; return result;
...@@ -434,6 +442,8 @@ void Rewriter::_getAttr(RewriterVar* result, RewriterVar* ptr, int offset, Locat ...@@ -434,6 +442,8 @@ void Rewriter::_getAttr(RewriterVar* result, RewriterVar* ptr, int offset, Locat
RewriterVar* RewriterVar::getAttrDouble(int offset, Location dest) { RewriterVar* RewriterVar::getAttrDouble(int offset, Location dest) {
STAT_TIMER(t0, "us_timer_rewriter", 10); STAT_TIMER(t0, "us_timer_rewriter", 10);
assert(this->reftype == RefType::UNKNOWN || this->vrefcount > 0);
RewriterVar* result = rewriter->createNewVar(); RewriterVar* result = rewriter->createNewVar();
rewriter->addAction([=]() { rewriter->_getAttrDouble(result, this, offset, dest); }, { this }, ActionType::NORMAL); rewriter->addAction([=]() { rewriter->_getAttrDouble(result, this, offset, dest); }, { this }, ActionType::NORMAL);
return result; return result;
...@@ -456,6 +466,8 @@ void Rewriter::_getAttrDouble(RewriterVar* result, RewriterVar* ptr, int offset, ...@@ -456,6 +466,8 @@ void Rewriter::_getAttrDouble(RewriterVar* result, RewriterVar* ptr, int offset,
RewriterVar* RewriterVar::getAttrFloat(int offset, Location dest) { RewriterVar* RewriterVar::getAttrFloat(int offset, Location dest) {
STAT_TIMER(t0, "us_timer_rewriter", 10); STAT_TIMER(t0, "us_timer_rewriter", 10);
assert(this->reftype == RefType::UNKNOWN || this->vrefcount > 0);
RewriterVar* result = rewriter->createNewVar(); RewriterVar* result = rewriter->createNewVar();
rewriter->addAction([=]() { rewriter->_getAttrFloat(result, this, offset, dest); }, { this }, ActionType::NORMAL); rewriter->addAction([=]() { rewriter->_getAttrFloat(result, this, offset, dest); }, { this }, ActionType::NORMAL);
return result; return result;
...@@ -637,6 +649,9 @@ void Rewriter::_toBool(RewriterVar* result, RewriterVar* var, Location dest) { ...@@ -637,6 +649,9 @@ void Rewriter::_toBool(RewriterVar* result, RewriterVar* var, Location dest) {
void RewriterVar::setAttr(int offset, RewriterVar* val) { void RewriterVar::setAttr(int offset, RewriterVar* val) {
STAT_TIMER(t0, "us_timer_rewriter", 10); STAT_TIMER(t0, "us_timer_rewriter", 10);
for (auto a : {this, val})
assert(a->reftype == RefType::UNKNOWN || a->vrefcount > 0);
rewriter->addAction([=]() { rewriter->_setAttr(this, offset, val); }, { this, val }, ActionType::MUTATION); rewriter->addAction([=]() { rewriter->_setAttr(this, offset, val); }, { this, val }, ActionType::MUTATION);
} }
...@@ -673,6 +688,8 @@ void RewriterVar::dump() { ...@@ -673,6 +688,8 @@ void RewriterVar::dump() {
printf("RewriterVar at %p: %ld locations:\n", this, locations.size()); printf("RewriterVar at %p: %ld locations:\n", this, locations.size());
for (Location l : locations) for (Location l : locations)
l.dump(); l.dump();
if (is_constant)
printf("Constant value: 0x%lx\n", this->constant_value);
} }
assembler::Immediate RewriterVar::tryGetAsImmediate(bool* is_immediate) { assembler::Immediate RewriterVar::tryGetAsImmediate(bool* is_immediate) {
...@@ -908,6 +925,9 @@ static const Location caller_save_registers[]{ ...@@ -908,6 +925,9 @@ static const Location caller_save_registers[]{
RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, const RewriterVar::SmallVector& args, RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, const RewriterVar::SmallVector& args,
const RewriterVar::SmallVector& args_xmm) { const RewriterVar::SmallVector& args_xmm) {
for (auto a : args)
assert(a->reftype == RefType::UNKNOWN || a->vrefcount > 0);
RewriterVar* result = createNewVar(); RewriterVar* result = createNewVar();
RewriterVar::SmallVector uses; RewriterVar::SmallVector uses;
for (RewriterVar* v : args) { for (RewriterVar* v : args) {
...@@ -1255,6 +1275,10 @@ void Rewriter::commit() { ...@@ -1255,6 +1275,10 @@ void Rewriter::commit() {
} }
} }
for (RewriterVar& var : vars) {
assert(var.vrefcount == 0);
}
assertConsistent(); assertConsistent();
// Emit assembly for each action, and set done_guarding when // Emit assembly for each action, and set done_guarding when
...@@ -1481,6 +1505,8 @@ bool Rewriter::finishAssembly(int continue_offset) { ...@@ -1481,6 +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);
addAction([=]() { addAction([=]() {
assembler->comment("commitReturning"); assembler->comment("commitReturning");
var->getInReg(getReturnDestination(), true /* allow_constant_in_reg */); var->getInReg(getReturnDestination(), true /* allow_constant_in_reg */);
......
...@@ -200,6 +200,12 @@ class Rewriter; ...@@ -200,6 +200,12 @@ class Rewriter;
class RewriterVar; class RewriterVar;
class RewriterAction; class RewriterAction;
enum class RefType {
UNKNOWN,
OWNED,
BORROWED,
};
// This might make more sense as an inner class of Rewriter, but // This might make more sense as an inner class of Rewriter, but
// you can't forward-declare that :/ // you can't forward-declare that :/
class RewriterVar { class RewriterVar {
...@@ -216,9 +222,53 @@ public: ...@@ -216,9 +222,53 @@ public:
void setAttr(int offset, RewriterVar* other); void setAttr(int offset, RewriterVar* other);
RewriterVar* cmp(AST_TYPE::AST_TYPE cmp_type, RewriterVar* other, Location loc = Location::any()); RewriterVar* cmp(AST_TYPE::AST_TYPE cmp_type, RewriterVar* other, Location loc = Location::any());
RewriterVar* toBool(Location loc = Location::any()); RewriterVar* toBool(Location loc = Location::any());
void incref();
void decref(); RewriterVar* setType(RefType type) {
void xdecref(); assert(this->reftype == RefType::UNKNOWN);
assert(type != RefType::UNKNOWN);
this->reftype = type;
this->vrefcount = 1;
return this;
}
RewriterVar* asBorrowed() {
if (this->reftype == RefType::UNKNOWN)
return setType(RefType::BORROWED);
assert(this->reftype == RefType::BORROWED);
return this->incvref();
}
RewriterVar* incvref() {
assert(reftype == RefType::OWNED || reftype == RefType::BORROWED);
assert(vrefcount > 0 || (reftype == RefType::BORROWED && vrefcount >= 0));
vrefcount++;
return this;
}
RewriterVar* decvref() {
assert(reftype == RefType::OWNED || reftype == RefType::BORROWED);
assert(vrefcount > 0);
vrefcount--;
if (reftype == RefType::OWNED && vrefcount == 0)
decref();
return this;
}
RewriterVar* materializeVref() {
assert(reftype == RefType::OWNED || reftype == RefType::BORROWED);
assert(vrefcount > 0);
vrefcount--;
if (reftype == RefType::OWNED && vrefcount == 0) {
// handoff, do nothing
} else {
incref();
}
return this;
}
template <typename Src, typename Dst> inline RewriterVar* getAttrCast(int offset, Location loc = Location::any()); template <typename Src, typename Dst> inline RewriterVar* getAttrCast(int offset, Location loc = Location::any());
...@@ -230,6 +280,10 @@ private: ...@@ -230,6 +280,10 @@ private:
llvm::SmallVector<Location, 4> locations; llvm::SmallVector<Location, 4> locations;
bool isInLocation(Location l); bool isInLocation(Location l);
void incref();
void decref();
void xdecref();
// uses is a vector of the indices into the Rewriter::actions vector // uses is a vector of the indices into the Rewriter::actions vector
// indicated the actions that use this variable. // indicated the actions that use this variable.
// During the assembly-emitting phase, next_use is used to keep track of the next // During the assembly-emitting phase, next_use is used to keep track of the next
...@@ -250,6 +304,9 @@ private: ...@@ -250,6 +304,9 @@ private:
bool is_arg; bool is_arg;
bool is_constant; bool is_constant;
RefType reftype = RefType::UNKNOWN;
int vrefcount;
uint64_t constant_value; uint64_t constant_value;
Location arg_loc; Location arg_loc;
std::pair<int /*offset*/, int /*size*/> scratch_allocation; std::pair<int /*offset*/, int /*size*/> scratch_allocation;
...@@ -275,10 +332,21 @@ private: ...@@ -275,10 +332,21 @@ private:
RewriterVar& operator=(const RewriterVar&) = delete; RewriterVar& operator=(const RewriterVar&) = delete;
public: public:
RewriterVar(Rewriter* rewriter) : rewriter(rewriter), next_use(0), is_arg(false), is_constant(false) { RewriterVar(Rewriter* rewriter)
: rewriter(rewriter),
next_use(0),
is_arg(false),
is_constant(false),
vrefcount(0) {
assert(rewriter); assert(rewriter);
} }
// XXX: for testing, reset these on deallocation so that we will see the next time they get set.
~RewriterVar() {
reftype = (RefType)-1;
vrefcount = -11;
}
Rewriter* getRewriter() { return rewriter; } Rewriter* getRewriter() { return rewriter; }
friend class Rewriter; friend class Rewriter;
......
...@@ -417,7 +417,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -417,7 +417,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
if (v.o) { if (v.o) {
Py_XDECREF(v.o); Py_XDECREF(v.o);
if (v.var) if (v.var)
v.var->decref(); v.var->decvref();
} }
v = interpreter.visit_stmt(s); v = interpreter.visit_stmt(s);
} }
...@@ -467,7 +467,7 @@ void ASTInterpreter::doStore(AST_Name* node, STOLEN(Value) value) { ...@@ -467,7 +467,7 @@ void ASTInterpreter::doStore(AST_Name* node, STOLEN(Value) value) {
setGlobal(globals, name.getBox(), value.o); setGlobal(globals, name.getBox(), value.o);
Py_DECREF(value.o); Py_DECREF(value.o);
if (jit) if (jit)
value.var->decref(); value.var->decvref();
} else if (vst == ScopeInfo::VarScopeType::NAME) { } else if (vst == ScopeInfo::VarScopeType::NAME) {
assert(0 && "check refcounting"); assert(0 && "check refcounting");
if (jit) if (jit)
...@@ -554,8 +554,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) { ...@@ -554,8 +554,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) {
Value ASTInterpreter::getNone() { Value ASTInterpreter::getNone() {
RewriterVar* v = NULL; RewriterVar* v = NULL;
if (jit) { if (jit) {
v = jit->imm(None); v = jit->imm(None)->setType(RefType::BORROWED);
v->incref();
} }
return Value(incref(None), v); return Value(incref(None), v);
} }
...@@ -575,8 +574,8 @@ Value ASTInterpreter::visit_binop(AST_BinOp* node) { ...@@ -575,8 +574,8 @@ Value ASTInterpreter::visit_binop(AST_BinOp* node) {
Py_DECREF(left.o); Py_DECREF(left.o);
Py_DECREF(right.o); Py_DECREF(right.o);
if (jit) { if (jit) {
left.var->decref(); left.var->decvref();
right.var->decref(); right.var->decvref();
} }
return r; return r;
} }
...@@ -863,8 +862,8 @@ Value ASTInterpreter::visit_augBinOp(AST_AugBinOp* node) { ...@@ -863,8 +862,8 @@ Value ASTInterpreter::visit_augBinOp(AST_AugBinOp* node) {
Py_DECREF(right.o); Py_DECREF(right.o);
if (jit) { if (jit) {
left.var->decref(); left.var->decvref();
right.var->decref(); right.var->decvref();
} }
return r; return r;
} }
...@@ -877,7 +876,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -877,7 +876,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
v = Value(getPystonIter(val.o), jit ? jit->emitGetPystonIter(val) : NULL); v = Value(getPystonIter(val.o), jit ? jit->emitGetPystonIter(val) : NULL);
Py_DECREF(val.o); Py_DECREF(val.o);
if (jit) if (jit)
val.var->decref(); val.var->decvref();
} else if (node->opcode == AST_LangPrimitive::IMPORT_FROM) { } else if (node->opcode == AST_LangPrimitive::IMPORT_FROM) {
assert(node->args.size() == 2); assert(node->args.size() == 2);
assert(node->args[0]->type == AST_TYPE::Name); assert(node->args[0]->type == AST_TYPE::Name);
...@@ -938,7 +937,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -938,7 +937,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
v = Value(boxBool(nonzero(obj.o)), jit ? jit->emitNonzero(obj) : NULL); v = Value(boxBool(nonzero(obj.o)), jit ? jit->emitNonzero(obj) : NULL);
Py_DECREF(obj.o); Py_DECREF(obj.o);
if (jit) if (jit)
obj.var->decref(); obj.var->decvref();
} else if (node->opcode == AST_LangPrimitive::SET_EXC_INFO) { } else if (node->opcode == AST_LangPrimitive::SET_EXC_INFO) {
assert(node->args.size() == 3); assert(node->args.size() == 3);
...@@ -965,7 +964,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -965,7 +964,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
v = Value(boxBool(hasnext(obj.o)), jit ? jit->emitHasnext(obj) : NULL); v = Value(boxBool(hasnext(obj.o)), jit ? jit->emitHasnext(obj) : NULL);
Py_DECREF(obj.o); Py_DECREF(obj.o);
if (jit) if (jit)
obj.var->decref(); obj.var->decvref();
} else if (node->opcode == AST_LangPrimitive::PRINT_EXPR) { } else if (node->opcode == AST_LangPrimitive::PRINT_EXPR) {
abortJITing(); abortJITing();
Value obj = visit_expr(node->args[0]); Value obj = visit_expr(node->args[0]);
...@@ -1144,8 +1143,8 @@ Value ASTInterpreter::visit_makeFunction(AST_MakeFunction* mkfn) { ...@@ -1144,8 +1143,8 @@ Value ASTInterpreter::visit_makeFunction(AST_MakeFunction* mkfn) {
if (jit) { if (jit) {
auto prev_func_var = func.var; auto prev_func_var = func.var;
func.var = jit->emitRuntimeCall(NULL, decorators[i], ArgPassSpec(1), { func }, NULL); func.var = jit->emitRuntimeCall(NULL, decorators[i], ArgPassSpec(1), { func }, NULL);
decorators[i].var->decref(); decorators[i].var->decvref();
prev_func_var->decref(); prev_func_var->decvref();
} }
} }
return func; return func;
...@@ -1322,8 +1321,8 @@ Value ASTInterpreter::visit_print(AST_Print* node) { ...@@ -1322,8 +1321,8 @@ Value ASTInterpreter::visit_print(AST_Print* node) {
if (jit) { if (jit) {
if (node->dest) if (node->dest)
dest.var->decref(); dest.var->decvref();
var.var->decref(); var.var->decvref();
} }
return Value(); return Value();
...@@ -1350,8 +1349,8 @@ Value ASTInterpreter::visit_compare(AST_Compare* node) { ...@@ -1350,8 +1349,8 @@ Value ASTInterpreter::visit_compare(AST_Compare* node) {
Py_DECREF(left.o); Py_DECREF(left.o);
Py_DECREF(right.o); Py_DECREF(right.o);
if (jit) { if (jit) {
left.var->decref(); left.var->decvref();
right.var->decref(); right.var->decvref();
} }
return r; return r;
} }
...@@ -1487,9 +1486,9 @@ Value ASTInterpreter::visit_call(AST_Call* node) { ...@@ -1487,9 +1486,9 @@ Value ASTInterpreter::visit_call(AST_Call* node) {
Py_DECREF(e); Py_DECREF(e);
if (jit) { if (jit) {
func.var->decref(); func.var->decvref();
for (auto e : args_vars) for (auto e : args_vars)
e->decref(); e->decvref();
} }
return v; return v;
...@@ -1515,8 +1514,7 @@ Value ASTInterpreter::visit_num(AST_Num* node) { ...@@ -1515,8 +1514,7 @@ Value ASTInterpreter::visit_num(AST_Num* node) {
Py_INCREF(o); Py_INCREF(o);
RewriterVar* v = NULL; RewriterVar* v = NULL;
if (jit) { if (jit) {
v = jit->imm(o); v = jit->imm(o)->setType(RefType::BORROWED);
v->incref();
} }
return Value(o, v); return Value(o, v);
} }
......
...@@ -168,7 +168,7 @@ RewriterVar* JitFragmentWriter::emitAugbinop(AST_expr* node, RewriterVar* lhs, R ...@@ -168,7 +168,7 @@ RewriterVar* JitFragmentWriter::emitAugbinop(AST_expr* node, RewriterVar* lhs, R
RewriterVar* JitFragmentWriter::emitBinop(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type) { RewriterVar* JitFragmentWriter::emitBinop(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type) {
/// XXX increase this too much for testing /// XXX increase this too much for testing
return emitPPCall((void*)binop, { lhs, rhs, imm(op_type) }, 2, 640, node); return emitPPCall((void*)binop, { lhs, rhs, imm(op_type) }, 2, 640, node)->setType(RefType::OWNED);
} }
RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags, RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags,
...@@ -266,8 +266,7 @@ RewriterVar* JitFragmentWriter::emitCreateTuple(const llvm::ArrayRef<RewriterVar ...@@ -266,8 +266,7 @@ RewriterVar* JitFragmentWriter::emitCreateTuple(const llvm::ArrayRef<RewriterVar
auto num = values.size(); auto num = values.size();
RewriterVar* r; RewriterVar* r;
if (num == 0) { if (num == 0) {
r = imm(EmptyTuple); r = imm(EmptyTuple)->setType(RefType::BORROWED);
r->incref();
} else if (num == 1) } else if (num == 1)
r = call(false, (void*)BoxedTuple::create1, values[0]); r = call(false, (void*)BoxedTuple::create1, values[0]);
else if (num == 2) else if (num == 2)
...@@ -278,7 +277,7 @@ RewriterVar* JitFragmentWriter::emitCreateTuple(const llvm::ArrayRef<RewriterVar ...@@ -278,7 +277,7 @@ RewriterVar* JitFragmentWriter::emitCreateTuple(const llvm::ArrayRef<RewriterVar
r = call(false, (void*)createTupleHelper, imm(num), allocArgs(values)); r = call(false, (void*)createTupleHelper, imm(num), allocArgs(values));
for (auto v : values) for (auto v : values)
v->decref(); v->decvref();
return r; return r;
} }
...@@ -304,8 +303,7 @@ RewriterVar* JitFragmentWriter::emitGetBlockLocal(InternedString s, int vreg) { ...@@ -304,8 +303,7 @@ RewriterVar* JitFragmentWriter::emitGetBlockLocal(InternedString s, int vreg) {
auto it = local_syms.find(s); auto it = local_syms.find(s);
if (it == local_syms.end()) if (it == local_syms.end())
return emitGetLocal(s, vreg); return emitGetLocal(s, vreg);
// TODO xincref? it->second->incvref();
it->second->incref();
return it->second; return it->second;
} }
...@@ -325,11 +323,14 @@ RewriterVar* JitFragmentWriter::emitGetClsAttr(RewriterVar* obj, BoxedString* s) ...@@ -325,11 +323,14 @@ RewriterVar* JitFragmentWriter::emitGetClsAttr(RewriterVar* obj, BoxedString* s)
RewriterVar* JitFragmentWriter::emitGetGlobal(Box* global, BoxedString* s) { RewriterVar* JitFragmentWriter::emitGetGlobal(Box* global, BoxedString* s) {
if (s->s() == "None") { if (s->s() == "None") {
RewriterVar* r = imm(None); RewriterVar* r = imm(None)->setType(RefType::BORROWED);
r->incref();
return r; return r;
} }
return emitPPCall((void*)getGlobal, { imm(global), imm(s) }, 2, 512);
RewriterVar* args[] = { NULL, NULL };
args[0] = imm(global)->asBorrowed()->decvref();
args[1] = imm(s)->asBorrowed()->decvref();
return emitPPCall((void*)getGlobal, args, 2, 512)->setType(RefType::OWNED);
} }
RewriterVar* JitFragmentWriter::emitGetItem(AST_expr* node, RewriterVar* value, RewriterVar* slice) { RewriterVar* JitFragmentWriter::emitGetItem(AST_expr* node, RewriterVar* value, RewriterVar* slice) {
...@@ -338,7 +339,7 @@ RewriterVar* JitFragmentWriter::emitGetItem(AST_expr* node, RewriterVar* value, ...@@ -338,7 +339,7 @@ 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);
RewriterVar* val_var = vregs_array->getAttr(vreg * 8); 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;
} }
...@@ -405,7 +406,7 @@ RewriterVar* JitFragmentWriter::emitRuntimeCall(AST_expr* node, RewriterVar* obj ...@@ -405,7 +406,7 @@ RewriterVar* JitFragmentWriter::emitRuntimeCall(AST_expr* node, RewriterVar* obj
if (keyword_names) if (keyword_names)
call_args.push_back(imm(keyword_names)); call_args.push_back(imm(keyword_names));
return emitPPCall((void*)runtimeCall, call_args, 2, 640, node, type_recorder); return emitPPCall((void*)runtimeCall, call_args, 2, 640, node, type_recorder)->setType(RefType::OWNED);
#else #else
RewriterVar* argspec_var = imm(argspec.asInt()); RewriterVar* argspec_var = imm(argspec.asInt());
RewriterVar* keyword_names_var = keyword_names ? imm(keyword_names) : nullptr; RewriterVar* keyword_names_var = keyword_names ? imm(keyword_names) : nullptr;
...@@ -476,7 +477,7 @@ void JitFragmentWriter::emitExec(RewriterVar* code, RewriterVar* globals, Rewrit ...@@ -476,7 +477,7 @@ void JitFragmentWriter::emitExec(RewriterVar* code, RewriterVar* globals, Rewrit
void JitFragmentWriter::emitJump(CFGBlock* b) { void JitFragmentWriter::emitJump(CFGBlock* b) {
for (auto v : local_syms) { for (auto v : local_syms) {
if (v.second) if (v.second)
v.second->decref(); // xdecref? v.second->decvref(); // xdecref?
} }
RewriterVar* next = imm(b); RewriterVar* next = imm(b);
...@@ -508,9 +509,11 @@ void JitFragmentWriter::emitRaise3(RewriterVar* arg0, RewriterVar* arg1, Rewrite ...@@ -508,9 +509,11 @@ void JitFragmentWriter::emitRaise3(RewriterVar* arg0, RewriterVar* arg1, Rewrite
void JitFragmentWriter::emitReturn(RewriterVar* v) { void JitFragmentWriter::emitReturn(RewriterVar* v) {
for (auto v : local_syms) { for (auto v : local_syms) {
if (v.second) if (v.second)
v.second->decref(); v.second->decvref();
} }
v->materializeVref();
addAction([=]() { _emitReturn(v); }, { v }, ActionType::NORMAL); addAction([=]() { _emitReturn(v); }, { v }, ActionType::NORMAL);
} }
...@@ -523,7 +526,7 @@ void JitFragmentWriter::emitSetBlockLocal(InternedString s, RewriterVar* v) { ...@@ -523,7 +526,7 @@ void JitFragmentWriter::emitSetBlockLocal(InternedString s, RewriterVar* v) {
local_syms[s] = v; local_syms[s] = v;
if (prev) { if (prev) {
// TODO: xdecref? // TODO: xdecref?
prev->decref(); prev->decvref();
} }
} }
...@@ -559,10 +562,10 @@ void JitFragmentWriter::emitSetLocal(InternedString s, int vreg, bool set_closur ...@@ -559,10 +562,10 @@ void JitFragmentWriter::emitSetLocal(InternedString s, int vreg, bool set_closur
#endif #endif
v); v);
} else { } else {
RewriterVar* prev = vregs_array->getAttr(8 * vreg); RewriterVar* prev = vregs_array->getAttr(8 * vreg)->setType(RefType::OWNED);
vregs_array->setAttr(8 * vreg, v); vregs_array->setAttr(8 * vreg, v);
// 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.
prev->decref(); prev->decvref();
//prev->xdecref(); //prev->xdecref();
} }
} }
......
...@@ -874,8 +874,8 @@ template <Rewritable rewritable> Box* Box::getattr(BoxedString* attr, GetattrRew ...@@ -874,8 +874,8 @@ template <Rewritable rewritable> Box* Box::getattr(BoxedString* attr, GetattrRew
} else { } else {
RewriterVar* r_attrs RewriterVar* r_attrs
= rewrite_args->obj->getAttr(cls->attrs_offset + offsetof(HCAttrs, attr_list), Location::any()); = rewrite_args->obj->getAttr(cls->attrs_offset + offsetof(HCAttrs, attr_list), Location::any());
RewriterVar* r_rtn RewriterVar* r_rtn = r_attrs->getAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs),
= r_attrs->getAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs), Location::any()); Location::any())->setType(RefType::BORROWED);
rewrite_args->setReturn(r_rtn, ReturnConvention::HAS_RETURN); rewrite_args->setReturn(r_rtn, ReturnConvention::HAS_RETURN);
} }
} }
...@@ -1019,8 +1019,10 @@ void Box::setattr(BoxedString* attr, Box* val, SetattrRewriteArgs* rewrite_args) ...@@ -1019,8 +1019,10 @@ void Box::setattr(BoxedString* attr, Box* val, SetattrRewriteArgs* rewrite_args)
RewriterVar* r_hattrs RewriterVar* r_hattrs
= rewrite_args->obj->getAttr(cls->attrs_offset + offsetof(HCAttrs, attr_list), Location::any()); = rewrite_args->obj->getAttr(cls->attrs_offset + offsetof(HCAttrs, attr_list), Location::any());
r_hattrs->getAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs))->decref(); r_hattrs->getAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs))
rewrite_args->attrval->incref(); ->setType(RefType::OWNED)
->decvref();
rewrite_args->attrval->materializeVref();
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);
...@@ -1038,6 +1040,7 @@ void Box::setattr(BoxedString* attr, Box* val, SetattrRewriteArgs* rewrite_args) ...@@ -1038,6 +1040,7 @@ void Box::setattr(BoxedString* attr, Box* val, SetattrRewriteArgs* rewrite_args)
// make sure we don't need to rearrange the attributes // make sure we don't need to rearrange the attributes
assert(new_hcls->getStrAttrOffsets().lookup(attr) == hcls->attributeArraySize()); assert(new_hcls->getStrAttrOffsets().lookup(attr) == hcls->attributeArraySize());
assert(!rewrite_args && "check rewriter refcounting");
this->appendNewHCAttr(val, rewrite_args); this->appendNewHCAttr(val, rewrite_args);
attrs->hcls = new_hcls; attrs->hcls = new_hcls;
...@@ -1278,8 +1281,12 @@ template <Rewritable rewritable> Box* typeLookup(BoxedClass* cls, BoxedString* a ...@@ -1278,8 +1281,12 @@ template <Rewritable rewritable> Box* typeLookup(BoxedClass* cls, BoxedString* a
obj_saved->addAttrGuard(offsetof(BoxedClass, tp_version_tag), (intptr_t)cls->tp_version_tag); obj_saved->addAttrGuard(offsetof(BoxedClass, tp_version_tag), (intptr_t)cls->tp_version_tag);
if (!val) if (!val)
rewrite_args->setReturn(NULL, ReturnConvention::NO_RETURN); rewrite_args->setReturn(NULL, ReturnConvention::NO_RETURN);
else else {
rewrite_args->setReturn(rewrite_args->rewriter->loadConst((int64_t)val), ReturnConvention::HAS_RETURN); // typeLookup is special since it doesn't even return a vref
rewrite_args->setReturn(
rewrite_args->rewriter->loadConst((int64_t)val)->setType(RefType::BORROWED),
ReturnConvention::HAS_RETURN);
}
} }
return val; return val;
} }
...@@ -1376,8 +1383,8 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box ...@@ -1376,8 +1383,8 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
} else { } else {
*bind_obj_out = incref(im_self); *bind_obj_out = incref(im_self);
if (rewrite_args) { if (rewrite_args) {
r_im_func->incref(); r_im_func->incvref();
r_im_self->incref(); r_im_self->incvref();
rewrite_args->setReturn(r_im_func, ReturnConvention::HAS_RETURN); rewrite_args->setReturn(r_im_func, ReturnConvention::HAS_RETURN);
*r_bind_obj_out = r_im_self; *r_bind_obj_out = r_im_self;
} }
...@@ -2585,6 +2592,10 @@ extern "C" void setattr(Box* obj, BoxedString* attr, Box* attr_val) { ...@@ -2585,6 +2592,10 @@ extern "C" void setattr(Box* obj, BoxedString* attr, Box* attr_val) {
assert(!obj->cls->tp_setattr); assert(!obj->cls->tp_setattr);
if (rewriter.get()) { if (rewriter.get()) {
rewriter->getArg(0)->setType(RefType::BORROWED);
rewriter->getArg(1)->setType(RefType::BORROWED);
rewriter->getArg(2)->setType(RefType::BORROWED);
auto r_cls = rewriter->getArg(0)->getAttr(offsetof(Box, cls)); auto r_cls = rewriter->getArg(0)->getAttr(offsetof(Box, cls));
// rewriter->trap(); // rewriter->trap();
r_cls->addAttrGuard(offsetof(BoxedClass, tp_setattr), 0); r_cls->addAttrGuard(offsetof(BoxedClass, tp_setattr), 0);
...@@ -3218,7 +3229,7 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3218,7 +3229,7 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
auto r_rtn = rewrite_args->rewriter->call(true, (void*)Helper::call, arg_vec); auto r_rtn = rewrite_args->rewriter->call(true, (void*)Helper::call, arg_vec);
rewrite_args->setReturn(r_rtn, S == CXX ? ReturnConvention::HAS_RETURN : ReturnConvention::CAPI_RETURN); rewrite_args->setReturn(r_rtn, S == CXX ? ReturnConvention::HAS_RETURN : ReturnConvention::CAPI_RETURN);
if (r_bind_obj) if (r_bind_obj)
r_bind_obj->decref(); r_bind_obj->decvref();
void* _args[2] = { args, const_cast<std::vector<BoxedString*>*>(keyword_names) }; void* _args[2] = { args, const_cast<std::vector<BoxedString*>*>(keyword_names) };
Box* rtn = Helper::call(val, argspec, arg1, arg2, arg3, _args); Box* rtn = Helper::call(val, argspec, arg1, arg2, arg3, _args);
...@@ -3240,8 +3251,8 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3240,8 +3251,8 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
Py_DECREF(val); Py_DECREF(val);
if (rewrite_args) { if (rewrite_args) {
if (r_bind_obj) if (r_bind_obj)
r_bind_obj->decref(); r_bind_obj->decvref();
r_val->decref(); r_val->decvref();
} }
return r; return r;
} }
...@@ -3553,19 +3564,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3553,19 +3564,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
Py_INCREF(oargs[i]); Py_INCREF(oargs[i]);
} }
} }
if (rewrite_args) {
if (num_output_args >= 1)
rewrite_args->arg1->incref();
if (num_output_args >= 2)
rewrite_args->arg2->incref();
if (num_output_args >= 3)
rewrite_args->arg3->incref();
if (num_output_args >= 3) {
for (int i = 0; i < num_output_args - 3; i++) {
rewrite_args->args->getAttr(i * sizeof(Box*))->incref();
}
}
}
return; return;
} }
...@@ -4132,8 +4130,9 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -4132,8 +4130,9 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
Py_DECREF(oargs[i]); Py_DECREF(oargs[i]);
} }
if (rewrite_args) { if (rewrite_args) {
RELEASE_ASSERT(num_output_args <= 3, "figure out vrefs for arg array");
for (int i = 0; i < num_output_args; i++) { for (int i = 0; i < num_output_args; i++) {
getArg(i, rewrite_args)->decref(); getArg(i, rewrite_args)->decvref();
} }
} }
...@@ -4323,7 +4322,7 @@ Box* callCLFunc(FunctionMetadata* md, CallRewriteArgs* rewrite_args, int num_out ...@@ -4323,7 +4322,7 @@ Box* callCLFunc(FunctionMetadata* md, CallRewriteArgs* rewrite_args, int num_out
if (num_output_args >= 4) if (num_output_args >= 4)
arg_vec.push_back(rewrite_args->args); arg_vec.push_back(rewrite_args->args);
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, func_ptr, arg_vec); rewrite_args->out_rtn = rewrite_args->rewriter->call(true, func_ptr, arg_vec)->setType(RefType::OWNED);
if (S == CXX && chosen_cf->exception_style == CAPI) if (S == CXX && chosen_cf->exception_style == CAPI)
rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn); rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
...@@ -4730,6 +4729,8 @@ Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteAr ...@@ -4730,6 +4729,8 @@ Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteAr
if (rewrite_args) { if (rewrite_args) {
CallattrRewriteArgs srewrite_args(rewrite_args->rewriter, rewrite_args->lhs, rewrite_args->destination); CallattrRewriteArgs srewrite_args(rewrite_args->rewriter, rewrite_args->lhs, rewrite_args->destination);
srewrite_args.arg1 = rewrite_args->rhs; srewrite_args.arg1 = rewrite_args->rhs;
rewrite_args->lhs->incvref();
rewrite_args->rhs->incvref();
lrtn = callattrInternal1<CXX, REWRITABLE>(lhs, op_name, CLASS_ONLY, &srewrite_args, ArgPassSpec(1), rhs); lrtn = callattrInternal1<CXX, REWRITABLE>(lhs, op_name, CLASS_ONLY, &srewrite_args, ArgPassSpec(1), rhs);
if (!srewrite_args.isSuccessful()) { if (!srewrite_args.isSuccessful()) {
...@@ -4753,6 +4754,8 @@ Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteAr ...@@ -4753,6 +4754,8 @@ Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteAr
if (lrtn) { if (lrtn) {
if (lrtn != NotImplemented) { if (lrtn != NotImplemented) {
if (rewrite_args) { if (rewrite_args) {
rewrite_args->lhs->decvref();
rewrite_args->rhs->decvref();
assert(rewrite_args->out_rtn); assert(rewrite_args->out_rtn);
rewrite_args->out_success = true; rewrite_args->out_success = true;
} }
...@@ -4835,14 +4838,17 @@ extern "C" Box* binop(Box* lhs, Box* rhs, int op_type) { ...@@ -4835,14 +4838,17 @@ extern "C" Box* binop(Box* lhs, Box* rhs, int op_type) {
Box* rtn; Box* rtn;
if (rewriter.get()) { if (rewriter.get()) {
// rewriter->trap(); // rewriter->trap();
BinopRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0), rewriter->getArg(1), BinopRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0)->setType(RefType::BORROWED),
rewriter->getArg(1)->setType(RefType::BORROWED),
rewriter->getReturnDestination()); rewriter->getReturnDestination());
rtn = binopInternal<REWRITABLE>(lhs, rhs, op_type, false, &rewrite_args); rtn = binopInternal<REWRITABLE>(lhs, rhs, op_type, false, &rewrite_args);
assert(rtn); assert(rtn);
if (!rewrite_args.out_success) { if (!rewrite_args.out_success) {
rewriter.reset(NULL); rewriter.reset(NULL);
} else } else {
rewrite_args.out_rtn->materializeVref();
rewriter->commitReturning(rewrite_args.out_rtn); rewriter->commitReturning(rewrite_args.out_rtn);
}
} else { } else {
rtn = binopInternal<NOT_REWRITABLE>(lhs, rhs, op_type, false, NULL); rtn = binopInternal<NOT_REWRITABLE>(lhs, rhs, op_type, false, NULL);
} }
...@@ -6387,7 +6393,7 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) { ...@@ -6387,7 +6393,7 @@ 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->incref(); 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