Commit 14ee9479 authored by Chris Toshok's avatar Chris Toshok

end the unwind session by setting the is_active flag to false. if the unwind...

end the unwind session by setting the is_active flag to false.  if the unwind session isn't active we don't mark through the ExcInfo, so exceptions/tracebacks should get gc'ed properly.
parent cc16b91a
...@@ -477,22 +477,31 @@ bool frameIsPythonFrame(unw_word_t ip, unw_word_t bp, unw_cursor_t* cursor, Pyth ...@@ -477,22 +477,31 @@ bool frameIsPythonFrame(unw_word_t ip, unw_word_t bp, unw_cursor_t* cursor, Pyth
class UnwindSession : public Box { class UnwindSession : public Box {
ExcInfo exc_info; ExcInfo exc_info;
bool skip; bool skip;
bool is_active;
public: public:
DEFAULT_CLASS_SIMPLE(unwind_session_cls); DEFAULT_CLASS_SIMPLE(unwind_session_cls);
UnwindSession() : exc_info(NULL, NULL, NULL), skip(false) {} UnwindSession() : exc_info(NULL, NULL, NULL), skip(false), is_active(false) {}
ExcInfo* getExcInfoStorage() { return &exc_info; } ExcInfo* getExcInfoStorage() { return &exc_info; }
bool shouldSkipFrame() const { return skip; } bool shouldSkipFrame() const { return skip; }
void setShouldSkipNextFrame(bool skip) { this->skip = skip; } void setShouldSkipNextFrame(bool skip) { this->skip = skip; }
bool isActive() const { return is_active; }
void clear() { void begin() {
RELEASE_ASSERT(!is_active, "");
exc_info = ExcInfo(NULL, NULL, NULL); exc_info = ExcInfo(NULL, NULL, NULL);
skip = false; skip = false;
is_active = true;
}
void end() {
RELEASE_ASSERT(is_active, "");
is_active = false;
} }
void addTraceback(const LineInfo& line_info) { void addTraceback(const LineInfo& line_info) {
RELEASE_ASSERT(is_active, "");
if (skip) { if (skip) {
skip = false; skip = false;
return; return;
...@@ -505,8 +514,13 @@ public: ...@@ -505,8 +514,13 @@ public:
} }
static void gcHandler(GCVisitor* v, Box* _o) { static void gcHandler(GCVisitor* v, Box* _o) {
// assert(_o->cls == unwind_session_cls) assert(_o->cls == unwind_session_cls);
UnwindSession* o = static_cast<UnwindSession*>(_o); UnwindSession* o = static_cast<UnwindSession*>(_o);
if (!o->is_active)
return;
v->visitIf(o->exc_info.type); v->visitIf(o->exc_info.type);
v->visitIf(o->exc_info.value); v->visitIf(o->exc_info.value);
v->visitIf(o->exc_info.traceback); v->visitIf(o->exc_info.traceback);
...@@ -519,8 +533,7 @@ UnwindSession* beginUnwind() { ...@@ -519,8 +533,7 @@ UnwindSession* beginUnwind() {
cur_unwind = new UnwindSession(); cur_unwind = new UnwindSession();
pyston::gc::registerPermanentRoot(cur_unwind); pyston::gc::registerPermanentRoot(cur_unwind);
} }
// if we can figure out a way to make endUnwind in cxx_uwind.cpp work, we can remove this. cur_unwind->begin();
cur_unwind->clear();
return cur_unwind; return cur_unwind;
} }
...@@ -531,7 +544,7 @@ UnwindSession* getUnwind() { ...@@ -531,7 +544,7 @@ UnwindSession* getUnwind() {
void endUnwind(UnwindSession* unwind) { void endUnwind(UnwindSession* unwind) {
RELEASE_ASSERT(unwind && unwind == cur_unwind, ""); RELEASE_ASSERT(unwind && unwind == cur_unwind, "");
cur_unwind->clear(); unwind->end();
} }
void* getExceptionStorage(UnwindSession* unwind) { void* getExceptionStorage(UnwindSession* unwind) {
RELEASE_ASSERT(unwind && unwind == cur_unwind, ""); RELEASE_ASSERT(unwind && unwind == cur_unwind, "");
...@@ -587,7 +600,10 @@ void unwindingThroughFrame(UnwindSession* unwind_session, unw_cursor_t* cursor) ...@@ -587,7 +600,10 @@ void unwindingThroughFrame(UnwindSession* unwind_session, unw_cursor_t* cursor)
// C++11 range loops, for example). // C++11 range loops, for example).
// Return true from the handler to stop iteration at that frame. // Return true from the handler to stop iteration at that frame.
template <typename Func> void unwindPythonStack(Func func) { template <typename Func> void unwindPythonStack(Func func) {
UnwindSession* unwind_state = (UnwindSession*)beginUnwind(); UnwindSession* unwind_session = new UnwindSession();
unwind_session->begin();
unw_context_t ctx; unw_context_t ctx;
unw_cursor_t cursor; unw_cursor_t cursor;
unw_getcontext(&ctx); unw_getcontext(&ctx);
...@@ -607,11 +623,11 @@ template <typename Func> void unwindPythonStack(Func func) { ...@@ -607,11 +623,11 @@ template <typename Func> void unwindPythonStack(Func func) {
PythonFrameIteratorImpl frame_iter; PythonFrameIteratorImpl frame_iter;
if (frameIsPythonFrame(ip, bp, &cursor, &frame_iter)) { if (frameIsPythonFrame(ip, bp, &cursor, &frame_iter)) {
if (!unwind_state->shouldSkipFrame()) if (!unwind_session->shouldSkipFrame())
stop_unwinding = func(&frame_iter); stop_unwinding = func(&frame_iter);
// frame_iter->cf->entry_descriptor will be non-null for OSR frames. // frame_iter->cf->entry_descriptor will be non-null for OSR frames.
unwind_state->setShouldSkipNextFrame((bool)frame_iter.cf->entry_descriptor); unwind_session->setShouldSkipNextFrame((bool)frame_iter.cf->entry_descriptor);
} }
if (stop_unwinding) if (stop_unwinding)
...@@ -636,7 +652,7 @@ template <typename Func> void unwindPythonStack(Func func) { ...@@ -636,7 +652,7 @@ template <typename Func> void unwindPythonStack(Func func) {
// keep unwinding // keep unwinding
} }
endUnwind(unwind_state); unwind_session->end();
} }
static std::unique_ptr<PythonFrameIteratorImpl> getTopPythonFrame() { static std::unique_ptr<PythonFrameIteratorImpl> getTopPythonFrame() {
......
...@@ -556,8 +556,7 @@ static inline void unwind_loop(ExcInfo* exc_data) { ...@@ -556,8 +556,7 @@ static inline void unwind_loop(ExcInfo* exc_data) {
int64_t switch_value = determine_action(&info, &entry); int64_t switch_value = determine_action(&info, &entry);
if (switch_value != CLEANUP_ACTION) { if (switch_value != CLEANUP_ACTION) {
// printf ("cleanup action == %ld, should end unwind session\n", switch_value); endUnwind(unwind_token);
// endUnwind(unwind_token);
} }
resume(&cursor, entry.landing_pad, switch_value, exc_data); resume(&cursor, entry.landing_pad, switch_value, exc_data);
} }
......
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