Commit aa322f25 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Rewriter paths refcount correctly now

not sure about the code they emit though, since right now it's too large.
parent 34f922be
...@@ -770,7 +770,7 @@ Box* JitFragmentWriter::createListHelper(uint64_t num, Box** data) { ...@@ -770,7 +770,7 @@ Box* JitFragmentWriter::createListHelper(uint64_t num, Box** data) {
BoxedList* list = (BoxedList*)createList(); BoxedList* list = (BoxedList*)createList();
list->ensure(num); list->ensure(num);
for (uint64_t i = 0; i < num; ++i) { for (uint64_t i = 0; i < num; ++i) {
listAppendInternal(list, data[i]); listAppendInternalStolen(list, data[i]);
} }
return list; return list;
} }
......
...@@ -217,7 +217,7 @@ public: ...@@ -217,7 +217,7 @@ public:
const llvm::ArrayRef<RewriterVar*> args, std::vector<BoxedString*>* keyword_names); const llvm::ArrayRef<RewriterVar*> args, std::vector<BoxedString*>* keyword_names);
RewriterVar* emitCompare(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type); RewriterVar* emitCompare(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitCreateDict(const llvm::ArrayRef<RewriterVar*> keys, const llvm::ArrayRef<RewriterVar*> values); RewriterVar* emitCreateDict(const llvm::ArrayRef<RewriterVar*> keys, const llvm::ArrayRef<RewriterVar*> values);
RewriterVar* emitCreateList(const llvm::ArrayRef<RewriterVar*> values); RewriterVar* emitCreateList(const llvm::ArrayRef<STOLEN(RewriterVar*)> values);
RewriterVar* emitCreateSet(const llvm::ArrayRef<RewriterVar*> values); RewriterVar* emitCreateSet(const llvm::ArrayRef<RewriterVar*> values);
RewriterVar* emitCreateSlice(RewriterVar* start, RewriterVar* stop, RewriterVar* step); RewriterVar* emitCreateSlice(RewriterVar* start, RewriterVar* stop, RewriterVar* step);
RewriterVar* emitCreateTuple(const llvm::ArrayRef<RewriterVar*> values); RewriterVar* emitCreateTuple(const llvm::ArrayRef<RewriterVar*> values);
......
...@@ -1431,7 +1431,7 @@ template <class T, class R> void findNodes(const R& roots, std::vector<T*>& outp ...@@ -1431,7 +1431,7 @@ template <class T, class R> void findNodes(const R& roots, std::vector<T*>& outp
void makeModuleInteractive(AST_Module* m); void makeModuleInteractive(AST_Module* m);
llvm::StringRef getOpSymbol(int op_type); llvm::StringRef getOpSymbol(int op_type);
BoxedString* getOpName(int op_type); BORROWED(BoxedString*) getOpName(int op_type);
int getReverseCmpOp(int op_type, bool& success); int getReverseCmpOp(int op_type, bool& success);
BoxedString* getReverseOpName(int op_type); BoxedString* getReverseOpName(int op_type);
BoxedString* getInplaceOpName(int op_type); BoxedString* getInplaceOpName(int op_type);
......
...@@ -57,7 +57,7 @@ int SPECULATION_THRESHOLD = 100; ...@@ -57,7 +57,7 @@ int SPECULATION_THRESHOLD = 100;
int MAX_OBJECT_CACHE_ENTRIES = 500; int MAX_OBJECT_CACHE_ENTRIES = 500;
static bool _GLOBAL_ENABLE = 1; static bool _GLOBAL_ENABLE = 1;
bool ENABLE_ICS = 0 && _GLOBAL_ENABLE; bool ENABLE_ICS = 1 && _GLOBAL_ENABLE;
bool ENABLE_ICGENERICS = 1 && ENABLE_ICS; bool ENABLE_ICGENERICS = 1 && ENABLE_ICS;
bool ENABLE_ICGETITEMS = 1 && ENABLE_ICS; bool ENABLE_ICGETITEMS = 1 && ENABLE_ICS;
bool ENABLE_ICSETITEMS = 1 && ENABLE_ICS; bool ENABLE_ICSETITEMS = 1 && ENABLE_ICS;
......
...@@ -1376,6 +1376,8 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box ...@@ -1376,6 +1376,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_self->incref();
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;
} }
...@@ -3179,15 +3181,18 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3179,15 +3181,18 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
if (unlikely(rewrite_args && rewrite_args->rewriter->aggressiveness() < 50)) { if (unlikely(rewrite_args && rewrite_args->rewriter->aggressiveness() < 50)) {
class Helper { class Helper {
public: public:
static Box* call(Box* val, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, void** extra_args) { static Box* call(STOLEN(Box*) val, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3,
void** extra_args) {
if (!val) { if (!val) {
assert(S == CAPI); assert(S == CAPI);
return NULL; return NULL;
} }
Box** args = (Box**)extra_args[0]; Box** args = (Box**)extra_args[0];
const std::vector<BoxedString*>* keyword_names = (const std::vector<BoxedString*>*)extra_args[1]; const std::vector<BoxedString*>* keyword_names = (const std::vector<BoxedString*>*)extra_args[1];
return runtimeCallInternal<S, NOT_REWRITABLE>(val, NULL, argspec, arg1, arg2, arg3, args, Box* rtn
keyword_names); = runtimeCallInternal<S, NOT_REWRITABLE>(val, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
Py_DECREF(val);
return rtn;
} }
}; };
...@@ -3212,9 +3217,13 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3212,9 +3217,13 @@ 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)
r_bind_obj->decref();
void* _args[2] = { args, const_cast<std::vector<BoxedString*>*>(keyword_names) }; void* _args[2] = { args, const_cast<std::vector<BoxedString*>*>(keyword_names) };
return Helper::call(val, argspec, arg1, arg2, arg3, _args); Box* rtn = Helper::call(val, argspec, arg1, arg2, arg3, _args);
Py_XDECREF(bind_obj);
return rtn;
} }
Box* r; Box* r;
...@@ -3229,6 +3238,11 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3229,6 +3238,11 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
} }
Py_XDECREF(bind_obj); Py_XDECREF(bind_obj);
Py_DECREF(val); Py_DECREF(val);
if (rewrite_args) {
if (r_bind_obj)
r_bind_obj->decref();
r_val->decref();
}
return r; return r;
} }
...@@ -3505,8 +3519,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3505,8 +3519,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
rewrite_args = NULL; rewrite_args = NULL;
} }
assert(!rewrite_args && "check refcounting");
/* /*
* Procedure: * Procedure:
* - First match up positional arguments; any extra go to varargs. error if too many. * - First match up positional arguments; any extra go to varargs. error if too many.
...@@ -3541,9 +3553,26 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3541,9 +3553,26 @@ 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;
} }
assert(!rewrite_args && "check refcounting");
if (rewrite_args)
raise(SIGTRAP);
// Fast path: if it's a simple-enough call, we don't have to do anything special. On a simple // Fast path: if it's a simple-enough call, we don't have to do anything special. On a simple
// django-admin test this covers something like 93% of all calls to callFunc. // django-admin test this covers something like 93% of all calls to callFunc.
if (argspec.num_keywords == 0 && argspec.has_starargs == paramspec.takes_varargs && !argspec.has_kwargs if (argspec.num_keywords == 0 && argspec.has_starargs == paramspec.takes_varargs && !argspec.has_kwargs
...@@ -4102,6 +4131,11 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -4102,6 +4131,11 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
for (int i = 0; i < num_output_args - 3; i++) { for (int i = 0; i < num_output_args - 3; i++) {
Py_XDECREF(oargs[i]); Py_XDECREF(oargs[i]);
} }
if (rewrite_args) {
for (int i = 0; i < num_output_args; i++) {
getArg(i, rewrite_args)->xdecref();
}
}
return res; return res;
} }
...@@ -4653,6 +4687,7 @@ Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteAr ...@@ -4653,6 +4687,7 @@ Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteAr
Box* irtn = NULL; Box* irtn = NULL;
if (inplace) { if (inplace) {
// XXX I think we need to make sure that we keep these strings alive?
DecrefHandle<BoxedString> iop_name(getInplaceOpName(op_type)); DecrefHandle<BoxedString> iop_name(getInplaceOpName(op_type));
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);
...@@ -6335,7 +6370,6 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) { ...@@ -6335,7 +6370,6 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) {
if (globals->cls == module_cls) { if (globals->cls == module_cls) {
BoxedModule* m = static_cast<BoxedModule*>(globals); BoxedModule* m = static_cast<BoxedModule*>(globals);
if (rewriter.get()) { if (rewriter.get()) {
assert(0 && "check refcounting");
RewriterVar* r_mod = rewriter->getArg(0); RewriterVar* r_mod = rewriter->getArg(0);
// Guard on it being a module rather than a dict // Guard on it being a module rather than a dict
...@@ -6351,9 +6385,13 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) { ...@@ -6351,9 +6385,13 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) {
rewrite_args.assertReturnConvention(r ? ReturnConvention::HAS_RETURN : ReturnConvention::NO_RETURN); rewrite_args.assertReturnConvention(r ? ReturnConvention::HAS_RETURN : ReturnConvention::NO_RETURN);
} }
if (r) { if (r) {
if (rewriter.get()) if (rewriter.get()) {
rewriter->commitReturning(rewrite_args.getReturn(ReturnConvention::HAS_RETURN)); RewriterVar* r_rtn = rewrite_args.getReturn(ReturnConvention::HAS_RETURN);
r_rtn->incref();
rewriter->commitReturning(r_rtn);
}
Py_INCREF(r);
return r; return r;
} }
} else { } else {
......
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