Commit a44f1c81 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Some light profiling to inform capi vs cxx exceptions

parent 9f5eb123
......@@ -332,6 +332,7 @@ Box* ASTInterpreter::execJITedBlock(CFGBlock* b) {
throw e;
auto source = getCL()->source.get();
stmt->cxx_exception_count++;
exceptionCaughtInInterpreter(LineInfo(stmt->lineno, stmt->col_offset, source->fn, source->getName()), &e);
next_block = ((AST_Invoke*)stmt)->exc_dest;
......@@ -764,6 +765,7 @@ Value ASTInterpreter::visit_invoke(AST_Invoke* node) {
abortJITing();
auto source = getCL()->source.get();
node->cxx_exception_count++;
exceptionCaughtInInterpreter(LineInfo(node->lineno, node->col_offset, source->fn, source->getName()), &e);
next_block = node->exc_dest;
......
......@@ -107,13 +107,23 @@ ExceptionStyle IRGenState::getLandingpadStyle(AST_Invoke* invoke) {
r = CXX; // default
assert(invoke->stmt->cxx_exception_count == 0); // could be ok but would be unexpected
// First, check if we think it makes sense:
bool should = (invoke->cxx_exception_count >= 10 || invoke->stmt->type == AST_TYPE::Raise);
if (!should)
return r;
// Second, check if we are able to do it:
// (not all code paths support capi exceptions yet)
if (invoke->stmt->type == AST_TYPE::Raise) {
AST_Raise* raise_stmt = ast_cast<AST_Raise>(invoke->stmt);
// Currently can't do a re-raise with a capi exception:
if (raise_stmt->arg0 && !raise_stmt->arg2) {
if (raise_stmt->arg0 && !raise_stmt->arg2)
r = CAPI;
return r;
}
else
r = CXX;
return r;
}
AST_expr* expr = NULL;
......@@ -127,21 +137,18 @@ ExceptionStyle IRGenState::getLandingpadStyle(AST_Invoke* invoke) {
if (!expr)
return r;
if (0 && expr->type == AST_TYPE::Call) {
AST_Call* call = ast_cast<AST_Call>(expr);
if (call->func->type != AST_TYPE::Attribute && call->func->type != AST_TYPE::ClsAttribute) {
r = CAPI;
// printf("Doing a capi exception to %d\n", invoke->exc_dest->idx);
}
if (expr->type == AST_TYPE::Call) {
r = CAPI;
return r;
}
if (expr->type == AST_TYPE::Attribute || expr->type == AST_TYPE::Subscript) {
r = CAPI;
// printf("Doing a capi exception to %d\n", invoke->exc_dest->idx);
return r;
}
// Some expression type we haven't added yet -- might be worth looking into.
r = CXX;
return r;
}
......@@ -488,8 +495,7 @@ public:
llvm::BasicBlock* exc_dest;
bool exc_caught;
if (unw_info.hasHandler()) {
assert(unw_info.capi_exc_dest);
if (unw_info.capi_exc_dest) {
exc_dest = unw_info.capi_exc_dest;
exc_caught = true;
} else {
......@@ -508,7 +514,13 @@ public:
embedRelocatablePtr(irstate->getSourceInfo(), g.i8_ptr));
if (!exc_caught) {
getBuilder()->CreateCall(g.funcs.reraiseJitCapiExc);
if (unw_info.cxx_exc_dest) {
// TODO: I'm not sure this gets the tracebacks quite right. this is only for testing though:
assert(FORCE_LLVM_CAPI && "this shouldn't happen in non-FORCE mode");
createCall(unw_info, g.funcs.reraiseJitCapiExc);
} else {
getBuilder()->CreateCall(g.funcs.reraiseJitCapiExc);
}
getBuilder()->CreateUnreachable();
}
......@@ -2429,8 +2441,11 @@ private:
if (landingpad_style == CXX)
doStmt(invoke->stmt, UnwindInfo(node, NULL, entry_blocks[invoke->exc_dest]));
else
else {
// print_ast(invoke);
// printf(" (%d exceptions)\n", invoke->cxx_exception_count);
doStmt(invoke->stmt, UnwindInfo(node, entry_blocks[invoke->exc_dest], NULL));
}
assert(state == RUNNING || state == DEAD);
if (state == RUNNING) {
......
......@@ -536,6 +536,8 @@ public:
exc_info.reraise = false;
return;
}
// TODO: shouldn't fetch this multiple times?
frame_iter.getCurrentStatement()->cxx_exception_count++;
auto line_info = lineInfoForFrame(&frame_iter);
BoxedTraceback::here(line_info, &exc_info.traceback);
}
......
......@@ -182,6 +182,8 @@ class AST_stmt : public AST {
public:
virtual void accept_stmt(StmtVisitor* v) = 0;
int cxx_exception_count = 0;
AST_stmt(AST_TYPE::AST_TYPE type) : AST(type) {}
};
......
......@@ -3488,8 +3488,6 @@ template <ExceptionStyle S>
static Box* callChosenCF(CompiledFunction* chosen_cf, BoxedClosure* closure, BoxedGenerator* generator, Box* oarg1,
Box* oarg2, Box* oarg3, Box** oargs) noexcept(S == CAPI) {
if (S != chosen_cf->exception_style) {
static StatCounter sc("num_runtimecall_exc_mismatches");
sc.log();
if (S == CAPI) {
try {
return callChosenCF<CXX>(chosen_cf, closure, generator, oarg1, oarg2, oarg3, oargs);
......@@ -3606,6 +3604,21 @@ Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_arg
rewrite_args->out_success = true;
}
if (chosen_cf->exception_style != S) {
static StatCounter sc("num_runtimecall_exc_mismatches");
sc.log();
if (rewrite_args) {
static StatCounter sc2("num_runtimecall_exc_mismatches_rewriteable");
sc2.log();
#if 0
StatCounter sc3("num_runtime_call_exc_mismatches_rewriteable."
+ g.func_addr_registry.getFuncNameAtAddress(chosen_cf->code, true, NULL));
sc3.log();
#endif
}
}
Box* r;
// we duplicate the call to callChosenCf here so we can
// distinguish lexically between calls that target jitted python
......
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