Commit 9789073f authored by Kevin Modzelewski's avatar Kevin Modzelewski

Have the llvm tier be able to throw capi exceptions

(Not enabled yet)
parent 2f7d52be
...@@ -743,12 +743,19 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) { ...@@ -743,12 +743,19 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_jitted_code"); UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_jitted_code");
CompiledFunction* partial_func = compilePartialFuncInternal(&exit); CompiledFunction* partial_func = compilePartialFuncInternal(&exit);
auto arg_tuple = getTupleFromArgsArray(&arg_array[0], arg_array.size()); auto arg_tuple = getTupleFromArgsArray(&arg_array[0], arg_array.size());
Box* r = partial_func->call(std::get<0>(arg_tuple), std::get<1>(arg_tuple), std::get<2>(arg_tuple), Box* r = partial_func->call(std::get<0>(arg_tuple), std::get<1>(arg_tuple), std::get<2>(arg_tuple),
std::get<3>(arg_tuple)); std::get<3>(arg_tuple));
assert(r); if (partial_func->exception_style == CXX) {
return r; assert(r);
return r;
} else {
if (!r)
throwCAPIException();
return r;
}
} }
Value ASTInterpreter::visit_invoke(AST_Invoke* node) { Value ASTInterpreter::visit_invoke(AST_Invoke* node) {
...@@ -1725,14 +1732,24 @@ Box* astInterpretFunction(CLFunction* clfunc, int nargs, Box* closure, Box* gene ...@@ -1725,14 +1732,24 @@ Box* astInterpretFunction(CLFunction* clfunc, int nargs, Box* closure, Box* gene
clfunc->dependent_interp_callsites.invalidateAll(); clfunc->dependent_interp_callsites.invalidateAll();
UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_jitted_code"); UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_jitted_code");
Box* r;
if (closure && generator) if (closure && generator)
return optimized->closure_generator_call((BoxedClosure*)closure, (BoxedGenerator*)generator, arg1, arg2, r = optimized->closure_generator_call((BoxedClosure*)closure, (BoxedGenerator*)generator, arg1, arg2, arg3,
arg3, args); args);
else if (closure) else if (closure)
return optimized->closure_call((BoxedClosure*)closure, arg1, arg2, arg3, args); r = optimized->closure_call((BoxedClosure*)closure, arg1, arg2, arg3, args);
else if (generator) else if (generator)
return optimized->generator_call((BoxedGenerator*)generator, arg1, arg2, arg3, args); r = optimized->generator_call((BoxedGenerator*)generator, arg1, arg2, arg3, args);
return optimized->call(arg1, arg2, arg3, args); else
r = optimized->call(arg1, arg2, arg3, args);
if (optimized->exception_style == CXX)
return r;
else {
if (!r)
throwCAPIException();
return r;
}
} }
Box** vregs = NULL; Box** vregs = NULL;
......
...@@ -1610,15 +1610,13 @@ public: ...@@ -1610,15 +1610,13 @@ public:
"%d", info.unw_info.current_stmt->lineno); "%d", info.unw_info.current_stmt->lineno);
CompiledFunction* cf = NULL; CompiledFunction* cf = NULL;
CompiledFunction* best_exception_mismatch = NULL;
bool found = false; bool found = false;
// TODO have to find the right version.. similar to resolveclfunc? // TODO have to find the right version.. similar to resolveclfunc?
for (int i = 0; i < cl->versions.size(); i++) { for (int i = 0; i < cl->versions.size(); i++) {
cf = cl->versions[i]; cf = cl->versions[i];
assert(cf->spec->arg_types.size() == cl->numReceivedArgs()); assert(cf->spec->arg_types.size() == cl->numReceivedArgs());
if (cf->exception_style != exception_style)
continue;
bool fits = true; bool fits = true;
for (int j = 0; j < args.size(); j++) { for (int j = 0; j < args.size(); j++) {
if (!args[j]->canConvertTo(cf->spec->arg_types[j + 1])) { if (!args[j]->canConvertTo(cf->spec->arg_types[j + 1])) {
...@@ -1629,14 +1627,22 @@ public: ...@@ -1629,14 +1627,22 @@ public:
if (!fits) if (!fits)
continue; continue;
if (cf->exception_style != exception_style) {
if (!best_exception_mismatch)
best_exception_mismatch = cf;
continue;
}
found = true; found = true;
break; break;
} }
if (!found && exception_style == CAPI) { if (!found) {
std::string name = g.func_addr_registry.getFuncNameAtAddress(cl->versions[0]->code, true); assert(best_exception_mismatch);
RELEASE_ASSERT(0, "Please define a capi variant for %s", name.c_str()); cf = best_exception_mismatch;
found = true;
} }
RELEASE_ASSERT(found, ""); RELEASE_ASSERT(found, "");
RELEASE_ASSERT(cf->code, ""); RELEASE_ASSERT(cf->code, "");
...@@ -1708,7 +1714,6 @@ public: ...@@ -1708,7 +1714,6 @@ public:
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr, CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr,
CallattrFlags flags, const std::vector<CompilerVariable*>& args, CallattrFlags flags, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override { const std::vector<BoxedString*>* keyword_names) override {
// XXX investigate
ExceptionStyle exception_style = info.preferredExceptionStyle(); ExceptionStyle exception_style = info.preferredExceptionStyle();
ConcreteCompilerVariable* called_constant = tryCallattrConstant( ConcreteCompilerVariable* called_constant = tryCallattrConstant(
......
...@@ -967,7 +967,7 @@ static std::string getUniqueFunctionName(std::string nameprefix, EffortLevel eff ...@@ -967,7 +967,7 @@ static std::string getUniqueFunctionName(std::string nameprefix, EffortLevel eff
CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* param_names, CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* param_names,
const OSREntryDescriptor* entry_descriptor, EffortLevel effort, const OSREntryDescriptor* entry_descriptor, EffortLevel effort,
FunctionSpecialization* spec, std::string nameprefix) { ExceptionStyle exception_style, FunctionSpecialization* spec, std::string nameprefix) {
Timer _t("in doCompile"); Timer _t("in doCompile");
Timer _t2; Timer _t2;
long irgen_us = 0; long irgen_us = 0;
...@@ -1030,8 +1030,7 @@ CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* ...@@ -1030,8 +1030,7 @@ CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames*
} }
} }
CompiledFunction* cf = new CompiledFunction(NULL, spec, NULL, effort, exception_style, entry_descriptor);
CompiledFunction* cf = new CompiledFunction(NULL, spec, NULL, effort, ExceptionStyle::CXX, entry_descriptor);
// Make sure that the instruction memory keeps the module object alive. // Make sure that the instruction memory keeps the module object alive.
// TODO: implement this for real // TODO: implement this for real
......
...@@ -113,7 +113,7 @@ bool isIsDefinedName(llvm::StringRef name); ...@@ -113,7 +113,7 @@ bool isIsDefinedName(llvm::StringRef name);
CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* param_names, CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* param_names,
const OSREntryDescriptor* entry_descriptor, EffortLevel effort, const OSREntryDescriptor* entry_descriptor, EffortLevel effort,
FunctionSpecialization* spec, std::string nameprefix); ExceptionStyle exception_style, FunctionSpecialization* spec, std::string nameprefix);
// A common pattern is to branch based off whether a variable is defined but only if it is // A common pattern is to branch based off whether a variable is defined but only if it is
// potentially-undefined. If it is potentially-undefined, we have to generate control-flow // potentially-undefined. If it is potentially-undefined, we have to generate control-flow
......
...@@ -197,6 +197,10 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E ...@@ -197,6 +197,10 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
ASSERT(f->versions.size() < 20, "%s %ld", name.c_str(), f->versions.size()); ASSERT(f->versions.size() < 20, "%s %ld", name.c_str(), f->versions.size());
ExceptionStyle exception_style = CXX;
if (FORCE_LLVM_CAPI_THROWS)
exception_style = CAPI;
if (VERBOSITY("irgen") >= 1) { if (VERBOSITY("irgen") >= 1) {
std::string s; std::string s;
llvm::raw_string_ostream ss(s); llvm::raw_string_ostream ss(s);
...@@ -223,7 +227,8 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E ...@@ -223,7 +227,8 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
ss << "\033[" << colors[(int)effort] << ";1mDoing OSR-entry partial compile of " << source->fn << ":" ss << "\033[" << colors[(int)effort] << ";1mDoing OSR-entry partial compile of " << source->fn << ":"
<< name << ", starting with backedge to block " << entry_descriptor->backedge->target->idx; << name << ", starting with backedge to block " << entry_descriptor->backedge->target->idx;
} }
ss << " at effort level " << (int)effort << '\n'; ss << " at effort level " << (int)effort << " with exception style "
<< (exception_style == CXX ? "C++" : "CAPI") << '\n';
if (entry_descriptor && VERBOSITY("irgen") >= 2) { if (entry_descriptor && VERBOSITY("irgen") >= 2) {
for (const auto& p : entry_descriptor->args) { for (const auto& p : entry_descriptor->args) {
...@@ -241,8 +246,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E ...@@ -241,8 +246,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
} }
CompiledFunction* cf = doCompile(f, source, &f->param_names, entry_descriptor, effort, exception_style, spec, name);
CompiledFunction* cf = doCompile(f, source, &f->param_names, entry_descriptor, effort, spec, name);
compileIR(cf, effort); compileIR(cf, effort);
f->addVersion(cf); f->addVersion(cf);
...@@ -822,7 +826,9 @@ extern "C" CompiledFunction* reoptCompiledFuncInternal(CompiledFunction* cf) { ...@@ -822,7 +826,9 @@ extern "C" CompiledFunction* reoptCompiledFuncInternal(CompiledFunction* cf) {
extern "C" char* reoptCompiledFunc(CompiledFunction* cf) { extern "C" char* reoptCompiledFunc(CompiledFunction* cf) {
return (char*)reoptCompiledFuncInternal(cf)->code; CompiledFunction* new_cf = reoptCompiledFuncInternal(cf);
assert(new_cf->exception_style == cf->exception_style);
return (char*)new_cf->code;
} }
CLFunction* createRTFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, CLFunction* createRTFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs,
......
...@@ -95,7 +95,7 @@ llvm::Value* IRGenState::getScratchSpace(int min_bytes) { ...@@ -95,7 +95,7 @@ llvm::Value* IRGenState::getScratchSpace(int min_bytes) {
} }
ExceptionStyle UnwindInfo::preferredExceptionStyle() const { ExceptionStyle UnwindInfo::preferredExceptionStyle() const {
if (FORCE_LLVM_CAPI) if (FORCE_LLVM_CAPI_CALLS)
return CAPI; return CAPI;
// TODO: I think this makes more sense as a relative percentage rather // TODO: I think this makes more sense as a relative percentage rather
...@@ -253,11 +253,21 @@ private: ...@@ -253,11 +253,21 @@ 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) {
if (unw_info.hasHandler() && target_exception_style == CXX) { if (target_exception_style == CXX && (unw_info.hasHandler() || irstate->getExceptionStyle() == CAPI)) {
// Create the invoke: // Create the invoke:
llvm::BasicBlock* normal_dest llvm::BasicBlock* normal_dest
= llvm::BasicBlock::Create(g.context, curblock->getName(), irstate->getLLVMFunction()); = llvm::BasicBlock::Create(g.context, curblock->getName(), irstate->getLLVMFunction());
llvm::BasicBlock* exc_dest = irgenerator->getCXXExcDest(unw_info.exc_dest);
llvm::BasicBlock* final_exc_dest;
if (unw_info.hasHandler()) {
final_exc_dest = unw_info.exc_dest;
} else {
assert(irstate->getExceptionStyle() == CAPI && "shoudn't have bothered creating an invoke");
final_exc_dest = NULL; // signal to reraise as a capi exception
}
llvm::BasicBlock* exc_dest = irgenerator->getCXXExcDest(final_exc_dest);
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);
...@@ -526,9 +536,9 @@ private: ...@@ -526,9 +536,9 @@ private:
llvm::SmallVector<ExceptionState, 2> incoming_exc_state; llvm::SmallVector<ExceptionState, 2> incoming_exc_state;
// These are the values that are outgoing of an invoke block: // These are the values that are outgoing of an invoke block:
llvm::SmallVector<ExceptionState, 2> outgoing_exc_state; llvm::SmallVector<ExceptionState, 2> outgoing_exc_state;
llvm::BasicBlock* cxx_exc_dest = NULL, * cxx_exc_final_dest = NULL; llvm::DenseMap<llvm::BasicBlock*, llvm::BasicBlock*> cxx_exc_dests;
llvm::BasicBlock* capi_exc_dest = NULL, * capi_exc_final_dest = NULL; llvm::DenseMap<llvm::BasicBlock*, llvm::BasicBlock*> capi_exc_dests;
AST_stmt* capi_current_stmt = NULL; llvm::DenseMap<llvm::BasicBlock*, AST_stmt*> capi_current_statements;
enum State { enum State {
RUNNING, // normal RUNNING, // normal
...@@ -2777,20 +2787,22 @@ public: ...@@ -2777,20 +2787,22 @@ public:
emitter.createCall(UnwindInfo(next_statement, NULL), g.funcs.allowGLReadPreemption); emitter.createCall(UnwindInfo(next_statement, NULL), g.funcs.allowGLReadPreemption);
} }
// Create a (or reuse an existing) block that will catch a CAPI exception, and then forward
// it to the "final_dest" block. ie final_dest is a block corresponding to the IR level
// LANDINGPAD, and this function will createa helper block that fetches the exception.
// As a special-case, a NULL value for final_dest means that this helper block should
// instead propagate the exception out of the function.
llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* final_dest, AST_stmt* current_stmt) { llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* final_dest, AST_stmt* current_stmt) {
llvm::BasicBlock*& capi_exc_dest = capi_exc_dests[final_dest];
if (capi_exc_dest) { if (capi_exc_dest) {
// We should only have one "final_dest"; we could support having multiple but assert(capi_current_statements[final_dest] == current_stmt);
// for now it should be an invariante:
assert(capi_exc_final_dest == final_dest);
assert(capi_current_stmt == current_stmt);
return capi_exc_dest; return capi_exc_dest;
} }
llvm::BasicBlock* orig_block = curblock; llvm::BasicBlock* orig_block = curblock;
capi_exc_dest = llvm::BasicBlock::Create(g.context, "", irstate->getLLVMFunction()); capi_exc_dest = llvm::BasicBlock::Create(g.context, "", irstate->getLLVMFunction());
capi_exc_final_dest = final_dest; capi_current_statements[final_dest] = current_stmt;
capi_current_stmt = current_stmt;
emitter.setCurrentBasicBlock(capi_exc_dest); emitter.setCurrentBasicBlock(capi_exc_dest);
emitter.getBuilder()->CreateCall2(g.funcs.capiExcCaughtInJit, emitter.getBuilder()->CreateCall2(g.funcs.capiExcCaughtInJit,
...@@ -2798,9 +2810,15 @@ public: ...@@ -2798,9 +2810,15 @@ public:
embedRelocatablePtr(irstate->getSourceInfo(), g.i8_ptr)); embedRelocatablePtr(irstate->getSourceInfo(), g.i8_ptr));
if (!final_dest) { if (!final_dest) {
emitter.getBuilder()->CreateCall(g.funcs.reraiseJitCapiExc); // Propagate the exception out of the function:
emitter.getBuilder()->CreateUnreachable(); if (irstate->getExceptionStyle() == CXX) {
emitter.getBuilder()->CreateCall(g.funcs.reraiseJitCapiExc);
emitter.getBuilder()->CreateUnreachable();
} else {
emitter.getBuilder()->CreateRet(getNullPtr(g.llvm_value_type_ptr));
}
} else { } else {
// Catch the exception and forward to final_dest:
llvm::Value* exc_type_ptr llvm::Value* exc_type_ptr
= new llvm::AllocaInst(g.llvm_value_type_ptr, getConstantInt(1, g.i64), "exc_type", = new llvm::AllocaInst(g.llvm_value_type_ptr, getConstantInt(1, g.i64), "exc_type",
irstate->getLLVMFunction()->getEntryBlock().getFirstInsertionPt()); irstate->getLLVMFunction()->getEntryBlock().getFirstInsertionPt());
...@@ -2832,17 +2850,13 @@ public: ...@@ -2832,17 +2850,13 @@ public:
} }
llvm::BasicBlock* getCXXExcDest(llvm::BasicBlock* final_dest) { llvm::BasicBlock* getCXXExcDest(llvm::BasicBlock* final_dest) {
if (cxx_exc_dest) { llvm::BasicBlock*& cxx_exc_dest = cxx_exc_dests[final_dest];
// We should only have one "final_dest"; we could support having multiple but if (cxx_exc_dest)
// for now it should be an invariante:
assert(cxx_exc_final_dest == final_dest);
return cxx_exc_dest; return cxx_exc_dest;
}
llvm::BasicBlock* orig_block = curblock; llvm::BasicBlock* orig_block = curblock;
cxx_exc_dest = llvm::BasicBlock::Create(g.context, "", irstate->getLLVMFunction()); cxx_exc_dest = llvm::BasicBlock::Create(g.context, "", irstate->getLLVMFunction());
cxx_exc_final_dest = final_dest;
emitter.getBuilder()->SetInsertPoint(cxx_exc_dest); emitter.getBuilder()->SetInsertPoint(cxx_exc_dest);
...@@ -2872,11 +2886,22 @@ public: ...@@ -2872,11 +2886,22 @@ public:
llvm::Value* exc_traceback llvm::Value* exc_traceback
= builder->CreateLoad(builder->CreateConstInBoundsGEP2_32(excinfo_pointer_casted, 0, 2)); = builder->CreateLoad(builder->CreateConstInBoundsGEP2_32(excinfo_pointer_casted, 0, 2));
addOutgoingExceptionState(ExceptionState(cxx_exc_dest, new ConcreteCompilerVariable(UNKNOWN, exc_type, true), if (final_dest) {
new ConcreteCompilerVariable(UNKNOWN, exc_value, true), // Catch the exception and forward to final_dest:
new ConcreteCompilerVariable(UNKNOWN, exc_traceback, true))); addOutgoingExceptionState(ExceptionState(cxx_exc_dest,
new ConcreteCompilerVariable(UNKNOWN, exc_type, true),
new ConcreteCompilerVariable(UNKNOWN, exc_value, true),
new ConcreteCompilerVariable(UNKNOWN, exc_traceback, true)));
builder->CreateBr(final_dest); builder->CreateBr(final_dest);
} else {
// Propagate the exception out of the function.
// We shouldn't be hitting this case if the current function is CXX-style; then we should have
// just not created an Invoke and let the exception machinery propagate it for us.
assert(irstate->getExceptionStyle() == CAPI);
builder->CreateCall3(g.funcs.PyErr_Restore, exc_type, exc_value, exc_traceback);
builder->CreateRet(getNullPtr(g.llvm_value_type_ptr));
}
emitter.setCurrentBasicBlock(orig_block); emitter.setCurrentBasicBlock(orig_block);
......
...@@ -80,6 +80,8 @@ public: ...@@ -80,6 +80,8 @@ public:
CompiledFunction* getCurFunction() { return cf; } CompiledFunction* getCurFunction() { return cf; }
CLFunction* getCL() { return clfunc; } CLFunction* getCL() { return clfunc; }
ExceptionStyle getExceptionStyle() { return cf->exception_style; }
llvm::Function* getLLVMFunction() { return cf->func; } llvm::Function* getLLVMFunction() { return cf->func; }
EffortLevel getEffortLevel() { return cf->effort; } EffortLevel getEffortLevel() { return cf->effort; }
......
...@@ -311,6 +311,7 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -311,6 +311,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(raise3_capi); GET(raise3_capi);
GET(PyErr_Fetch); GET(PyErr_Fetch);
GET(PyErr_NormalizeException); GET(PyErr_NormalizeException);
GET(PyErr_Restore);
GET(capiExcCaughtInJit); GET(capiExcCaughtInJit);
GET(reraiseJitCapiExc); GET(reraiseJitCapiExc);
GET(deopt); GET(deopt);
......
...@@ -51,7 +51,7 @@ struct GlobalFuncs { ...@@ -51,7 +51,7 @@ struct GlobalFuncs {
llvm::Value* __cxa_end_catch; llvm::Value* __cxa_end_catch;
llvm::Value* raise0, *raise3, *raise3_capi; llvm::Value* raise0, *raise3, *raise3_capi;
llvm::Value* PyErr_Fetch, *PyErr_NormalizeException, *capiExcCaughtInJit, *reraiseJitCapiExc; llvm::Value* PyErr_Fetch, *PyErr_NormalizeException, *PyErr_Restore, *capiExcCaughtInJit, *reraiseJitCapiExc;
llvm::Value* deopt; llvm::Value* deopt;
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;
......
...@@ -45,8 +45,10 @@ bool USE_REGALLOC_BASIC = true; ...@@ -45,8 +45,10 @@ bool USE_REGALLOC_BASIC = true;
bool PAUSE_AT_ABORT = false; bool PAUSE_AT_ABORT = false;
bool ENABLE_TRACEBACKS = true; bool ENABLE_TRACEBACKS = true;
// Forces the llvm jit to use capi exceptions whenever it can, as opposed to whenever it thinks // Forces the llvm jit to use capi exceptions whenever it can, as opposed to whenever it thinks
// it is faster: // it is faster. The CALLS version is for calls that the llvm jit will make, and the THROWS version
bool FORCE_LLVM_CAPI = false; // is for the exceptions it will throw.
bool FORCE_LLVM_CAPI_CALLS = false;
bool FORCE_LLVM_CAPI_THROWS = false;
int OSR_THRESHOLD_INTERPRETER = 25; int OSR_THRESHOLD_INTERPRETER = 25;
int REOPT_THRESHOLD_INTERPRETER = 25; int REOPT_THRESHOLD_INTERPRETER = 25;
......
...@@ -39,7 +39,7 @@ extern int MAX_OBJECT_CACHE_ENTRIES; ...@@ -39,7 +39,7 @@ extern int MAX_OBJECT_CACHE_ENTRIES;
extern bool SHOW_DISASM, FORCE_INTERPRETER, FORCE_OPTIMIZE, PROFILE, DUMPJIT, TRAP, USE_STRIPPED_STDLIB, extern bool SHOW_DISASM, FORCE_INTERPRETER, FORCE_OPTIMIZE, PROFILE, DUMPJIT, TRAP, USE_STRIPPED_STDLIB,
CONTINUE_AFTER_FATAL, ENABLE_INTERPRETER, ENABLE_BASELINEJIT, ENABLE_PYPA_PARSER, USE_REGALLOC_BASIC, CONTINUE_AFTER_FATAL, ENABLE_INTERPRETER, ENABLE_BASELINEJIT, ENABLE_PYPA_PARSER, USE_REGALLOC_BASIC,
PAUSE_AT_ABORT, ENABLE_TRACEBACKS, ASSEMBLY_LOGGING, FORCE_LLVM_CAPI; PAUSE_AT_ABORT, ENABLE_TRACEBACKS, ASSEMBLY_LOGGING, FORCE_LLVM_CAPI_CALLS, FORCE_LLVM_CAPI_THROWS;
extern bool ENABLE_ICS, ENABLE_ICGENERICS, ENABLE_ICGETITEMS, ENABLE_ICSETITEMS, ENABLE_ICDELITEMS, ENABLE_ICBINEXPS, extern bool ENABLE_ICS, ENABLE_ICGENERICS, ENABLE_ICGETITEMS, ENABLE_ICSETITEMS, ENABLE_ICDELITEMS, ENABLE_ICBINEXPS,
ENABLE_ICNONZEROS, ENABLE_ICCALLSITES, ENABLE_ICSETATTRS, ENABLE_ICGETATTRS, ENALBE_ICDELATTRS, ENABLE_ICGETGLOBALS, ENABLE_ICNONZEROS, ENABLE_ICCALLSITES, ENABLE_ICSETATTRS, ENABLE_ICGETATTRS, ENALBE_ICDELATTRS, ENABLE_ICGETGLOBALS,
......
...@@ -129,6 +129,7 @@ void force() { ...@@ -129,6 +129,7 @@ void force() {
FORCE(raise3_capi); FORCE(raise3_capi);
FORCE(PyErr_Fetch); FORCE(PyErr_Fetch);
FORCE(PyErr_NormalizeException); FORCE(PyErr_NormalizeException);
FORCE(PyErr_Restore);
FORCE(capiExcCaughtInJit); FORCE(capiExcCaughtInJit);
FORCE(reraiseJitCapiExc); FORCE(reraiseJitCapiExc);
FORCE(deopt); FORCE(deopt);
......
...@@ -262,6 +262,10 @@ extern "C" void dumpEx(void* p, int levels) { ...@@ -262,6 +262,10 @@ extern "C" void dumpEx(void* p, int levels) {
printf("Has %ld function versions\n", cl->versions.size()); printf("Has %ld function versions\n", cl->versions.size());
for (CompiledFunction* cf : cl->versions) { for (CompiledFunction* cf : cl->versions) {
bool got_name; bool got_name;
if (cf->exception_style == CXX)
printf("CXX style: ");
else
printf("CAPI style: ");
std::string name = g.func_addr_registry.getFuncNameAtAddress(cf->code, true, &got_name); std::string name = g.func_addr_registry.getFuncNameAtAddress(cf->code, true, &got_name);
if (got_name) if (got_name)
printf("%s\n", name.c_str()); printf("%s\n", name.c_str());
......
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