Commit 12e5d956 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Things are pretty hacky, but basic refcounting seems to be working ok

parent 3404d138
...@@ -271,6 +271,9 @@ llvm::Value* IRGenState::getGlobalsIfCustom() { ...@@ -271,6 +271,9 @@ llvm::Value* IRGenState::getGlobalsIfCustom() {
return getGlobals(); return getGlobals();
} }
// XXX This is pretty hacky, but I think I can get rid of it once I merge in Marius's new frame introspection work
#define NO_CXX_INTERCEPTION ((llvm::BasicBlock*)-1)
class IREmitterImpl : public IREmitter { class IREmitterImpl : public IREmitter {
private: private:
IRGenState* irstate; IRGenState* irstate;
...@@ -280,10 +283,14 @@ private: ...@@ -280,10 +283,14 @@ private:
llvm::CallSite emitCall(const UnwindInfo& unw_info, llvm::Value* callee, const std::vector<llvm::Value*>& args, llvm::CallSite emitCall(const UnwindInfo& unw_info, llvm::Value* callee, const std::vector<llvm::Value*>& args,
ExceptionStyle target_exception_style) { ExceptionStyle target_exception_style) {
bool needs_refcounting_fixup = true; bool needs_cxx_interception;
bool needs_cxx_interception if (unw_info.exc_dest == NO_CXX_INTERCEPTION) {
= (target_exception_style == CXX needs_cxx_interception = false;
&& (needs_refcounting_fixup || unw_info.hasHandler() || irstate->getExceptionStyle() == CAPI)); } else {
bool needs_refcounting_fixup = true;
needs_cxx_interception = (target_exception_style == CXX && (needs_refcounting_fixup || unw_info.hasHandler()
|| irstate->getExceptionStyle() == CAPI));
}
if (needs_cxx_interception) { if (needs_cxx_interception) {
// Create the invoke: // Create the invoke:
...@@ -297,7 +304,7 @@ private: ...@@ -297,7 +304,7 @@ private:
final_exc_dest = NULL; // signal to reraise as a capi exception final_exc_dest = NULL; // signal to reraise as a capi exception
} }
llvm::BasicBlock* exc_dest = irgenerator->getCXXExcDest(final_exc_dest); llvm::BasicBlock* exc_dest = irgenerator->getCXXExcDest(unw_info);
normal_dest->moveAfter(curblock); normal_dest->moveAfter(curblock);
llvm::InvokeInst* rtn = getBuilder()->CreateInvoke(callee, normal_dest, exc_dest, args); llvm::InvokeInst* rtn = getBuilder()->CreateInvoke(callee, normal_dest, exc_dest, args);
...@@ -410,7 +417,7 @@ public: ...@@ -410,7 +417,7 @@ public:
return llvm::BasicBlock::Create(g.context, name, irstate->getLLVMFunction()); return llvm::BasicBlock::Create(g.context, name, irstate->getLLVMFunction());
} }
llvm::Value* createCall(const UnwindInfo& unw_info, llvm::Value* callee, const std::vector<llvm::Value*>& args, llvm::Instruction* createCall(const UnwindInfo& unw_info, llvm::Value* callee, const std::vector<llvm::Value*>& args,
ExceptionStyle target_exception_style = CXX) override { ExceptionStyle target_exception_style = CXX) override {
#ifndef NDEBUG #ifndef NDEBUG
// Copied the argument-type-checking from CallInst::init, since the patchpoint arguments don't // Copied the argument-type-checking from CallInst::init, since the patchpoint arguments don't
...@@ -440,9 +447,9 @@ public: ...@@ -440,9 +447,9 @@ public:
if (rtn_type == cs->getType()) { if (rtn_type == cs->getType()) {
return cs.getInstruction(); return cs.getInstruction();
} else if (rtn_type == g.i1) { } else if (rtn_type == g.i1) {
return getBuilder()->CreateTrunc(cs.getInstruction(), rtn_type); return llvm::cast<llvm::Instruction>(getBuilder()->CreateTrunc(cs.getInstruction(), rtn_type));
} else if (llvm::isa<llvm::PointerType>(rtn_type)) { } else if (llvm::isa<llvm::PointerType>(rtn_type)) {
return getBuilder()->CreateIntToPtr(cs.getInstruction(), rtn_type); return llvm::cast<llvm::Instruction>(getBuilder()->CreateIntToPtr(cs.getInstruction(), rtn_type));
} else { } else {
cs.getInstruction()->getType()->dump(); cs.getInstruction()->getType()->dump();
rtn_type->dump(); rtn_type->dump();
...@@ -453,27 +460,27 @@ public: ...@@ -453,27 +460,27 @@ public:
} }
} }
llvm::Value* createCall(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Instruction* createCall(const UnwindInfo& unw_info, llvm::Value* callee,
ExceptionStyle target_exception_style = CXX) override { ExceptionStyle target_exception_style = CXX) override {
return createCall(unw_info, callee, std::vector<llvm::Value*>(), target_exception_style); return createCall(unw_info, callee, std::vector<llvm::Value*>(), target_exception_style);
} }
llvm::Value* createCall(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1, llvm::Instruction* createCall(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1,
ExceptionStyle target_exception_style = CXX) override { ExceptionStyle target_exception_style = CXX) override {
return createCall(unw_info, callee, std::vector<llvm::Value*>({ arg1 }), target_exception_style); return createCall(unw_info, callee, std::vector<llvm::Value*>({ arg1 }), target_exception_style);
} }
llvm::Value* createCall2(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2, llvm::Instruction* createCall2(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2,
ExceptionStyle target_exception_style = CXX) override { ExceptionStyle target_exception_style = CXX) override {
return createCall(unw_info, callee, { arg1, arg2 }, target_exception_style); return createCall(unw_info, callee, { arg1, arg2 }, target_exception_style);
} }
llvm::Value* createCall3(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2, llvm::Instruction* createCall3(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2,
llvm::Value* arg3, ExceptionStyle target_exception_style = CXX) override { llvm::Value* arg3, ExceptionStyle target_exception_style = CXX) override {
return createCall(unw_info, callee, { arg1, arg2, arg3 }, target_exception_style); return createCall(unw_info, callee, { arg1, arg2, arg3 }, target_exception_style);
} }
llvm::Value* createIC(const ICSetupInfo* pp, void* func_addr, const std::vector<llvm::Value*>& args, llvm::Instruction* createIC(const ICSetupInfo* pp, void* func_addr, const std::vector<llvm::Value*>& args,
const UnwindInfo& unw_info, ExceptionStyle target_exception_style = CXX) override { const UnwindInfo& unw_info, ExceptionStyle target_exception_style = CXX) override {
std::vector<llvm::Value*> stackmap_args; std::vector<llvm::Value*> stackmap_args;
...@@ -2756,11 +2763,18 @@ public: ...@@ -2756,11 +2763,18 @@ public:
return capi_exc_dest; return capi_exc_dest;
} }
llvm::BasicBlock* getCXXExcDest(llvm::BasicBlock* final_dest) override { llvm::BasicBlock* getCXXExcDest(const UnwindInfo& unw_info) override {
//llvm::BasicBlock*& cxx_exc_dest = cxx_exc_dests[final_dest]; //llvm::BasicBlock*& cxx_exc_dest = cxx_exc_dests[final_dest];
//if (cxx_exc_dest) //if (cxx_exc_dest)
//return cxx_exc_dest; //return cxx_exc_dest;
llvm::BasicBlock* final_dest;
if (unw_info.hasHandler()) {
final_dest = unw_info.exc_dest;
} else {
final_dest = NULL;
}
llvm::BasicBlock* orig_block = curblock; llvm::BasicBlock* orig_block = curblock;
llvm::BasicBlock* cxx_exc_dest = llvm::BasicBlock::Create(g.context, "", irstate->getLLVMFunction()); llvm::BasicBlock* cxx_exc_dest = llvm::BasicBlock::Create(g.context, "", irstate->getLLVMFunction());
...@@ -2812,7 +2826,8 @@ public: ...@@ -2812,7 +2826,8 @@ public:
irstate->getRefcounts()->refConsumed(exc_traceback, call_inst); irstate->getRefcounts()->refConsumed(exc_traceback, call_inst);
builder->CreateRet(getNullPtr(g.llvm_value_type_ptr)); builder->CreateRet(getNullPtr(g.llvm_value_type_ptr));
} else { } else {
auto call_inst = emitter.getBuilder()->CreateCall3(g.funcs.rawThrow, exc_type, exc_value, exc_traceback); auto call_inst = emitter.createCall3(UnwindInfo(unw_info.current_stmt, NO_CXX_INTERCEPTION),
g.funcs.rawThrow, exc_type, exc_value, exc_traceback);
irstate->getRefcounts()->refConsumed(exc_type, call_inst); irstate->getRefcounts()->refConsumed(exc_type, call_inst);
irstate->getRefcounts()->refConsumed(exc_value, call_inst); irstate->getRefcounts()->refConsumed(exc_value, call_inst);
irstate->getRefcounts()->refConsumed(exc_traceback, call_inst); irstate->getRefcounts()->refConsumed(exc_traceback, call_inst);
......
...@@ -41,6 +41,7 @@ struct PatchpointInfo; ...@@ -41,6 +41,7 @@ struct PatchpointInfo;
class ScopeInfo; class ScopeInfo;
class TypeAnalysis; class TypeAnalysis;
class RefcountTracker; class RefcountTracker;
class UnwindInfo;
typedef std::unordered_map<InternedString, CompilerVariable*> SymbolTable; typedef std::unordered_map<InternedString, CompilerVariable*> SymbolTable;
typedef std::map<InternedString, CompilerVariable*> SortedSymbolTable; typedef std::map<InternedString, CompilerVariable*> SortedSymbolTable;
...@@ -163,7 +164,7 @@ public: ...@@ -163,7 +164,7 @@ public:
std::vector<llvm::Value*>& stackmap_args) = 0; std::vector<llvm::Value*>& stackmap_args) = 0;
virtual void addOutgoingExceptionState(ExceptionState exception_state) = 0; virtual void addOutgoingExceptionState(ExceptionState exception_state) = 0;
virtual void setIncomingExceptionState(llvm::SmallVector<ExceptionState, 2> exc_state) = 0; virtual void setIncomingExceptionState(llvm::SmallVector<ExceptionState, 2> exc_state) = 0;
virtual llvm::BasicBlock* getCXXExcDest(llvm::BasicBlock* final_dest) = 0; virtual llvm::BasicBlock* getCXXExcDest(const UnwindInfo&) = 0;
virtual llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* from_block, llvm::BasicBlock* final_dest, virtual llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* from_block, llvm::BasicBlock* final_dest,
AST_stmt* current_stmt) = 0; AST_stmt* current_stmt) = 0;
virtual CFGBlock* getCFGBlock() = 0; virtual CFGBlock* getCFGBlock() = 0;
......
...@@ -342,9 +342,17 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -342,9 +342,17 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
num_consumed = it->second; num_consumed = it->second;
if (num_times_as_op[op] > num_consumed) { if (num_times_as_op[op] > num_consumed) {
if (rt->vars[op].reftype == RefType::BORROWED) { if (rt->vars[op].reftype == RefType::OWNED) {
} else { if (state.refs[op] == 0) {
assert(state.refs.count(op) && "handle this case (last reference of an owned var)"); if (llvm::InvokeInst* invoke = llvm::dyn_cast<llvm::InvokeInst>(&I)) {
addDecrefs(op, 1, findIncrefPt(invoke->getNormalDest()));
addDecrefs(op, 1, findIncrefPt(invoke->getUnwindDest()));
} else {
assert(&I != I.getParent()->getTerminator());
addDecrefs(op, 1, I.getNextNode());
}
state.refs[op] = 1;
}
} }
} }
......
...@@ -276,6 +276,7 @@ extern "C" void reraiseCapiExcAsCxx() { ...@@ -276,6 +276,7 @@ extern "C" void reraiseCapiExcAsCxx() {
} }
extern "C" void rawThrow(Box* type, Box* value, Box* tb) { extern "C" void rawThrow(Box* type, Box* value, Box* tb) {
startReraise();
throw ExcInfo(type, value, tb); throw ExcInfo(type, value, tb);
} }
......
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