Commit 7df079cb authored by Kevin Modzelewski's avatar Kevin Modzelewski

Pass frame-state through to make reraising faster

Instead of relying on stack unwinding to find it.
parent 1b9d802e
...@@ -1128,7 +1128,7 @@ Value ASTInterpreter::visit_raise(AST_Raise* node) { ...@@ -1128,7 +1128,7 @@ Value ASTInterpreter::visit_raise(AST_Raise* node) {
finishJITing(); finishJITing();
} }
raise0(); ASTInterpreterJitInterface::raise0Helper(this);
} }
Value arg0 = node->arg0 ? visit_expr(node->arg0) : getNone(); Value arg0 = node->arg0 ? visit_expr(node->arg0) : getNone();
...@@ -1678,6 +1678,11 @@ Box* ASTInterpreterJitInterface::uncacheExcInfoHelper(void* _interpreter) { ...@@ -1678,6 +1678,11 @@ Box* ASTInterpreterJitInterface::uncacheExcInfoHelper(void* _interpreter) {
return None; return None;
} }
void ASTInterpreterJitInterface::raise0Helper(void* _interpreter) {
ASTInterpreter* interpreter = (ASTInterpreter*)_interpreter;
raise0(&interpreter->getFrameInfo()->exc);
}
const void* interpreter_instr_addr = (void*)&executeInnerAndSetupFrame; const void* interpreter_instr_addr = (void*)&executeInnerAndSetupFrame;
// small wrapper around executeInner because we can not directly call the member function from asm. // small wrapper around executeInner because we can not directly call the member function from asm.
......
...@@ -48,6 +48,7 @@ struct ASTInterpreterJitInterface { ...@@ -48,6 +48,7 @@ struct ASTInterpreterJitInterface {
static Box* setExcInfoHelper(void* interp, Box* type, Box* value, Box* traceback); static Box* setExcInfoHelper(void* interp, Box* type, Box* value, Box* traceback);
static void setLocalClosureHelper(void* interp, long vreg, InternedString id, Box* v); static void setLocalClosureHelper(void* interp, long vreg, InternedString id, Box* v);
static Box* uncacheExcInfoHelper(void* interp); static Box* uncacheExcInfoHelper(void* interp);
static void raise0Helper(void* interp) __attribute__((noreturn));
}; };
class RewriterVar; class RewriterVar;
......
...@@ -478,7 +478,7 @@ void JitFragmentWriter::emitPrint(RewriterVar* dest, RewriterVar* var, bool nl) ...@@ -478,7 +478,7 @@ void JitFragmentWriter::emitPrint(RewriterVar* dest, RewriterVar* var, bool nl)
} }
void JitFragmentWriter::emitRaise0() { void JitFragmentWriter::emitRaise0() {
call(false, (void*)raise0); call(false, (void*)ASTInterpreterJitInterface::raise0Helper, getInterp());
} }
void JitFragmentWriter::emitRaise3(RewriterVar* arg0, RewriterVar* arg1, RewriterVar* arg2) { void JitFragmentWriter::emitRaise3(RewriterVar* arg0, RewriterVar* arg1, RewriterVar* arg2) {
......
...@@ -2327,13 +2327,14 @@ private: ...@@ -2327,13 +2327,14 @@ private:
assert(!node->arg1); assert(!node->arg1);
assert(!node->arg2); assert(!node->arg2);
llvm::Value* exc_info = emitter.getBuilder()->CreateConstInBoundsGEP2_32(irstate->getFrameInfoVar(), 0, 0);
if (target_exception_style == CAPI) { if (target_exception_style == CAPI) {
emitter.createCall(unw_info, g.funcs.raise0_capi, std::vector<llvm::Value*>(), CAPI); emitter.createCall(unw_info, g.funcs.raise0_capi, exc_info, CAPI);
emitter.checkAndPropagateCapiException(unw_info, getNullPtr(g.llvm_value_type_ptr), emitter.checkAndPropagateCapiException(unw_info, getNullPtr(g.llvm_value_type_ptr),
getNullPtr(g.llvm_value_type_ptr)); getNullPtr(g.llvm_value_type_ptr));
emitter.getBuilder()->CreateUnreachable(); emitter.getBuilder()->CreateUnreachable();
} else { } else {
emitter.createCall(unw_info, g.funcs.raise0, std::vector<llvm::Value*>()); emitter.createCall(unw_info, g.funcs.raise0, exc_info);
emitter.getBuilder()->CreateUnreachable(); emitter.getBuilder()->CreateUnreachable();
} }
......
...@@ -777,6 +777,15 @@ ExcInfo* getFrameExcInfo() { ...@@ -777,6 +777,15 @@ ExcInfo* getFrameExcInfo() {
return cur_exc; return cur_exc;
} }
void updateFrameExcInfoIfNeeded(ExcInfo* latest) {
if (latest->type)
return;
ExcInfo* updated = getFrameExcInfo();
assert(updated == latest);
return;
}
CLFunction* getTopPythonFunction() { CLFunction* getTopPythonFunction() {
auto rtn = getTopPythonFrame(); auto rtn = getTopPythonFrame();
if (!rtn) if (!rtn)
......
...@@ -106,6 +106,10 @@ PythonFrameIterator getPythonFrame(int depth); ...@@ -106,6 +106,10 @@ PythonFrameIterator getPythonFrame(int depth);
// Fetches a writeable pointer to the frame-local excinfo object, // Fetches a writeable pointer to the frame-local excinfo object,
// calculating it if necessary (from previous frames). // calculating it if necessary (from previous frames).
ExcInfo* getFrameExcInfo(); ExcInfo* getFrameExcInfo();
// A similar function, but that takes a pointer to the most-recent ExcInfo.
// This is faster in the case that the frame-level excinfo is already up-to-date,
// but just as slow if it's not.
void updateFrameExcInfoIfNeeded(ExcInfo* latest);
struct FrameStackState { struct FrameStackState {
// This includes all # variables (but not the ! ones). // This includes all # variables (but not the ! ones).
......
...@@ -135,33 +135,34 @@ ExcInfo excInfoForRaise(Box* type, Box* value, Box* tb) { ...@@ -135,33 +135,34 @@ ExcInfo excInfoForRaise(Box* type, Box* value, Box* tb) {
return ExcInfo(type, value, tb); return ExcInfo(type, value, tb);
} }
extern "C" void raise0() { extern "C" void raise0(ExcInfo* frame_exc_info) {
ExcInfo* exc_info = getFrameExcInfo(); updateFrameExcInfoIfNeeded(frame_exc_info);
assert(exc_info->type); assert(frame_exc_info->type);
// TODO need to clean up when we call normalize, do_raise, etc // TODO need to clean up when we call normalize, do_raise, etc
if (exc_info->type == None) if (frame_exc_info->type == None)
raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not NoneType"); raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not NoneType");
startReraise(); startReraise();
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
throw * exc_info; throw * frame_exc_info;
} }
extern "C" void raise0_capi() noexcept { extern "C" void raise0_capi(ExcInfo* frame_exc_info) noexcept {
ExcInfo exc_info = *getFrameExcInfo(); updateFrameExcInfoIfNeeded(frame_exc_info);
assert(exc_info.type); assert(frame_exc_info->type);
// TODO need to clean up when we call normalize, do_raise, etc // TODO need to clean up when we call normalize, do_raise, etc
if (exc_info.type == None) { if (frame_exc_info->type == None) {
exc_info.type = TypeError; frame_exc_info->type = TypeError;
exc_info.value = boxString("exceptions must be old-style classes or derived from BaseException, not NoneType"); frame_exc_info->value
exc_info.traceback = None; = boxString("exceptions must be old-style classes or derived from BaseException, not NoneType");
PyErr_NormalizeException(&exc_info.type, &exc_info.value, &exc_info.traceback); frame_exc_info->traceback = None;
PyErr_NormalizeException(&frame_exc_info->type, &frame_exc_info->value, &frame_exc_info->traceback);
} }
startReraise(); startReraise();
PyErr_Restore(exc_info.type, exc_info.value, exc_info.traceback); PyErr_Restore(frame_exc_info->type, frame_exc_info->value, frame_exc_info->traceback);
} }
extern "C" void raise3(Box* arg0, Box* arg1, Box* arg2) { extern "C" void raise3(Box* arg0, Box* arg1, Box* arg2) {
......
...@@ -33,8 +33,8 @@ class BoxedTuple; ...@@ -33,8 +33,8 @@ class BoxedTuple;
// user-level raise functions that implement python-level semantics // user-level raise functions that implement python-level semantics
ExcInfo excInfoForRaise(Box*, Box*, Box*); ExcInfo excInfoForRaise(Box*, Box*, Box*);
extern "C" void raise0() __attribute__((__noreturn__)); extern "C" void raise0(ExcInfo* frame_exc_info) __attribute__((__noreturn__));
extern "C" void raise0_capi() noexcept; extern "C" void raise0_capi(ExcInfo* frame_exc_info) noexcept;
extern "C" void raise3(Box*, Box*, Box*) __attribute__((__noreturn__)); extern "C" void raise3(Box*, Box*, Box*) __attribute__((__noreturn__));
extern "C" void raise3_capi(Box*, Box*, Box*) noexcept; extern "C" void raise3_capi(Box*, Box*, Box*) noexcept;
void raiseExc(Box* exc_obj) __attribute__((__noreturn__)); void raiseExc(Box* exc_obj) __attribute__((__noreturn__));
......
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