Commit f834dfdc authored by Kevin Modzelewski's avatar Kevin Modzelewski

Try to reduce cxx-exception-fixup overhead

I think this is the main source of our jit-time regression.
parent dceb1e9e
...@@ -373,20 +373,25 @@ void addCXXFixup(llvm::Instruction* inst, const llvm::SmallVector<llvm::Tracking ...@@ -373,20 +373,25 @@ void addCXXFixup(llvm::Instruction* inst, const llvm::SmallVector<llvm::Tracking
call->replaceAllUsesWith(new_invoke); call->replaceAllUsesWith(new_invoke);
call->eraseFromParent(); call->eraseFromParent();
llvm::Value* exc_type, *exc_value, *exc_traceback;
std::tie(exc_type, exc_value, exc_traceback) = createLandingpad(fixup_block);
llvm::IRBuilder<true> builder(fixup_block); llvm::IRBuilder<true> builder(fixup_block);
llvm::SmallVector<llvm::Value*, 4> decref_args; static llvm::Function* _personality_func = g.stdlib_module->getFunction("__gxx_personality_v0");
decref_args.push_back(getConstantInt(to_decref.size(), g.i32)); assert(_personality_func);
decref_args.append(to_decref.begin(), to_decref.end()); llvm::Value* personality_func
builder.CreateCall(g.funcs.xdecrefAll, decref_args); = g.cur_module->getOrInsertFunction(_personality_func->getName(), _personality_func->getFunctionType());
assert(personality_func);
auto rethrow = builder.CreateCall3(g.funcs.rawReraise, exc_type, exc_value, exc_traceback); static llvm::Type* lp_type = llvm::StructType::create(std::vector<llvm::Type*>{ g.i8_ptr, g.i64 });
assert(lp_type);
llvm::LandingPadInst* landing_pad = builder.CreateLandingPad(lp_type, personality_func, 1);
landing_pad->addClause(getNullPtr(g.i8_ptr));
llvm::SmallVector<llvm::Value*, 4> call_args;
llvm::Value* cxaexc_pointer = builder.CreateExtractValue(landing_pad, { 0 });
call_args.push_back(cxaexc_pointer);
call_args.push_back(getConstantInt(to_decref.size(), g.i32));
call_args.append(to_decref.begin(), to_decref.end());
builder.CreateCall(g.funcs.xdecrefAndRethrow, call_args);
builder.CreateUnreachable(); builder.CreateUnreachable();
// new_invoke->getParent()->getParent()->dump();
} }
// TODO: this should be cleaned up and moved to src/core/ // TODO: this should be cleaned up and moved to src/core/
......
...@@ -324,7 +324,7 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -324,7 +324,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(reraiseCapiExcAsCxx); GET(reraiseCapiExcAsCxx);
GET(deopt); GET(deopt);
GET(checkRefs); GET(checkRefs);
GET(xdecrefAll); GET(xdecrefAndRethrow);
GET(div_float_float); GET(div_float_float);
GET(floordiv_float_float); GET(floordiv_float_float);
......
...@@ -55,7 +55,7 @@ struct GlobalFuncs { ...@@ -55,7 +55,7 @@ struct GlobalFuncs {
llvm::Value* raise0, *raise0_capi, *raise3, *raise3_capi, *rawReraise; llvm::Value* raise0, *raise0_capi, *raise3, *raise3_capi, *rawReraise;
llvm::Value* PyErr_Fetch, *PyErr_NormalizeException, *PyErr_Restore, *caughtCapiException, *reraiseCapiExcAsCxx; llvm::Value* PyErr_Fetch, *PyErr_NormalizeException, *PyErr_Restore, *caughtCapiException, *reraiseCapiExcAsCxx;
llvm::Value* deopt; llvm::Value* deopt;
llvm::Value* checkRefs, *xdecrefAll; llvm::Value* checkRefs, *xdecrefAndRethrow;
llvm::Value* div_float_float, *floordiv_float_float, *mod_float_float, *pow_float_float; llvm::Value* div_float_float, *floordiv_float_float, *mod_float_float, *pow_float_float;
......
...@@ -140,7 +140,7 @@ void force() { ...@@ -140,7 +140,7 @@ void force() {
FORCE(reraiseCapiExcAsCxx); FORCE(reraiseCapiExcAsCxx);
FORCE(deopt); FORCE(deopt);
FORCE(checkRefs); FORCE(checkRefs);
FORCE(xdecrefAll); FORCE(xdecrefAndRethrow);
FORCE(div_i64_i64); FORCE(div_i64_i64);
FORCE(mod_i64_i64); FORCE(mod_i64_i64);
......
...@@ -118,7 +118,10 @@ static inline Box* callattrInternal3(Box* obj, BoxedString* attr, LookupScope sc ...@@ -118,7 +118,10 @@ static inline Box* callattrInternal3(Box* obj, BoxedString* attr, LookupScope sc
return callattrInternal<S, rewritable>(obj, attr, scope, rewrite_args, argspec, arg1, arg2, arg3, NULL, NULL); return callattrInternal<S, rewritable>(obj, attr, scope, rewrite_args, argspec, arg1, arg2, arg3, NULL, NULL);
} }
extern "C" void xdecrefAll(int num, ...) { extern "C" void* __cxa_begin_catch(void*);
extern "C" void xdecrefAndRethrow(void* cxa_ptr, int num, ...) {
ExcInfo e = *(ExcInfo*)__cxa_begin_catch(cxa_ptr);
va_list va; va_list va;
va_start(va, num); va_start(va, num);
...@@ -128,6 +131,8 @@ extern "C" void xdecrefAll(int num, ...) { ...@@ -128,6 +131,8 @@ extern "C" void xdecrefAll(int num, ...) {
} }
va_end(va); va_end(va);
rawReraise(e.type, e.value, e.traceback);
} }
extern "C" Box* deopt(AST_expr* expr, Box* value) { extern "C" Box* deopt(AST_expr* expr, Box* value) {
......
...@@ -231,6 +231,6 @@ extern "C" void boxedLocalsDel(Box* boxedLocals, BoxedString* attr); ...@@ -231,6 +231,6 @@ extern "C" void boxedLocalsDel(Box* boxedLocals, BoxedString* attr);
extern "C" void checkRefs(Box* b); // asserts that b has >= 0 refs extern "C" void checkRefs(Box* b); // asserts that b has >= 0 refs
extern "C" Box* assertAlive(Box* b); // asserts that b has > 0 refs, and returns b extern "C" Box* assertAlive(Box* b); // asserts that b has > 0 refs, and returns b
extern "C" void xdecrefAll(int num, ...); extern "C" void xdecrefAndRethrow(void* cxa_ptr, int num_decref, ...);
} }
#endif #endif
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