Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
cc16b91a
Commit
cc16b91a
authored
Jun 12, 2015
by
Chris Toshok
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rename a few things. use the UnwindSession type in unwinding.h, but leave it opaque.
parent
20d98b25
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
88 additions
and
80 deletions
+88
-80
src/codegen/unwinding.cpp
src/codegen/unwinding.cpp
+75
-71
src/codegen/unwinding.h
src/codegen/unwinding.h
+10
-5
src/runtime/cxx_unwind.cpp
src/runtime/cxx_unwind.cpp
+3
-4
No files found.
src/codegen/unwinding.cpp
View file @
cc16b91a
...
...
@@ -297,11 +297,6 @@ public:
intptr_t
regs
[
16
];
uint16_t
regs_valid
;
// PythonFrameIteratorImpl(const PythonFrameIteratorImpl&) = delete;
// void operator=(const PythonFrameIteratorImpl&) = delete;
// PythonFrameIteratorImpl(const PythonFrameIteratorImpl&&) = delete;
// void operator=(const PythonFrameIteratorImpl&&) = delete;
PythonFrameIteratorImpl
()
:
regs_valid
(
0
)
{}
PythonFrameIteratorImpl
(
PythonFrameId
::
FrameType
type
,
uint64_t
ip
,
uint64_t
bp
,
CompiledFunction
*
cf
)
...
...
@@ -445,7 +440,7 @@ static inline unw_word_t get_cursor_bp(unw_cursor_t* cursor) {
return
get_cursor_reg
(
cursor
,
UNW_TDEP_BP
);
}
bool
unwindProcess
Frame
(
unw_word_t
ip
,
unw_word_t
bp
,
unw_cursor_t
*
cursor
,
PythonFrameIteratorImpl
*
info
)
{
bool
frameIsPython
Frame
(
unw_word_t
ip
,
unw_word_t
bp
,
unw_cursor_t
*
cursor
,
PythonFrameIteratorImpl
*
info
)
{
CompiledFunction
*
cf
=
getCFForAddress
(
ip
);
bool
jitted
=
cf
!=
NULL
;
if
(
!
cf
)
{
...
...
@@ -498,6 +493,10 @@ public:
}
void
addTraceback
(
const
LineInfo
&
line_info
)
{
if
(
skip
)
{
skip
=
false
;
return
;
}
if
(
exc_info
.
reraise
)
{
exc_info
.
reraise
=
false
;
return
;
...
...
@@ -513,6 +512,75 @@ public:
v
->
visitIf
(
o
->
exc_info
.
traceback
);
}
};
static
__thread
UnwindSession
*
cur_unwind
;
UnwindSession
*
beginUnwind
()
{
if
(
!
cur_unwind
)
{
cur_unwind
=
new
UnwindSession
();
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
->
clear
();
return
cur_unwind
;
}
UnwindSession
*
getUnwind
()
{
RELEASE_ASSERT
(
cur_unwind
,
""
);
return
cur_unwind
;
}
void
endUnwind
(
UnwindSession
*
unwind
)
{
RELEASE_ASSERT
(
unwind
&&
unwind
==
cur_unwind
,
""
);
cur_unwind
->
clear
();
}
void
*
getExceptionStorage
(
UnwindSession
*
unwind
)
{
RELEASE_ASSERT
(
unwind
&&
unwind
==
cur_unwind
,
""
);
UnwindSession
*
state
=
static_cast
<
UnwindSession
*>
(
unwind
);
return
state
->
getExcInfoStorage
();
}
static
const
LineInfo
lineInfoForFrame
(
PythonFrameIteratorImpl
*
frame_it
)
{
AST_stmt
*
current_stmt
=
frame_it
->
getCurrentStatement
();
auto
*
cf
=
frame_it
->
getCF
();
assert
(
cf
);
auto
source
=
cf
->
clfunc
->
source
.
get
();
return
LineInfo
(
current_stmt
->
lineno
,
current_stmt
->
col_offset
,
source
->
fn
,
source
->
getName
());
}
void
exceptionCaughtInInterpreter
(
LineInfo
line_info
,
ExcInfo
*
exc_info
)
{
// basically the same as UnwindSession::addTraceback, but needs to
// be callable after an UnwindSession has ended. The interpreter
// will call this from catch blocks if it needs to ensure that a
// line is added. Right now this only happens in
// ASTInterpreter::visit_invoke.
// It's basically the same except for one thing: we don't have to
// worry about the 'skip' (osr) state that UnwindSession handles
// here, because the only way we could have gotten into the ast
// interpreter is if the exception wasn't caught, and if there was
// the osr frame for the one the interpreter is running, it would
// have already caught it.
if
(
exc_info
->
reraise
)
{
exc_info
->
reraise
=
false
;
return
;
}
BoxedTraceback
::
Here
(
line_info
,
reinterpret_cast
<
BoxedTraceback
**>
(
&
exc_info
->
traceback
));
}
void
unwindingThroughFrame
(
UnwindSession
*
unwind_session
,
unw_cursor_t
*
cursor
)
{
unw_word_t
ip
=
get_cursor_ip
(
cursor
);
unw_word_t
bp
=
get_cursor_bp
(
cursor
);
PythonFrameIteratorImpl
frame_iter
;
if
(
frameIsPythonFrame
(
ip
,
bp
,
cursor
,
&
frame_iter
))
{
unwind_session
->
addTraceback
(
lineInfoForFrame
(
&
frame_iter
));
// frame_iter->cf->entry_descriptor will be non-null for OSR frames.
unwind_session
->
setShouldSkipNextFrame
((
bool
)
frame_iter
.
cf
->
entry_descriptor
);
}
}
// While I'm not a huge fan of the callback-passing style, libunwind cursors are only valid for
// the stack frame that they were created in, so we need to use this approach (as opposed to
...
...
@@ -538,7 +606,7 @@ template <typename Func> void unwindPythonStack(Func func) {
bool
stop_unwinding
=
false
;
PythonFrameIteratorImpl
frame_iter
;
if
(
unwindProcess
Frame
(
ip
,
bp
,
&
cursor
,
&
frame_iter
))
{
if
(
frameIsPython
Frame
(
ip
,
bp
,
&
cursor
,
&
frame_iter
))
{
if
(
!
unwind_state
->
shouldSkipFrame
())
stop_unwinding
=
func
(
&
frame_iter
);
...
...
@@ -581,70 +649,6 @@ static std::unique_ptr<PythonFrameIteratorImpl> getTopPythonFrame() {
return
rtn
;
}
static
const
LineInfo
lineInfoForFrame
(
PythonFrameIteratorImpl
*
frame_it
)
{
AST_stmt
*
current_stmt
=
frame_it
->
getCurrentStatement
();
auto
*
cf
=
frame_it
->
getCF
();
assert
(
cf
);
auto
source
=
cf
->
clfunc
->
source
.
get
();
return
LineInfo
(
current_stmt
->
lineno
,
current_stmt
->
col_offset
,
source
->
fn
,
source
->
getName
());
}
void
exceptionCaughtInInterpreter
(
LineInfo
line_info
,
ExcInfo
*
exc_info
)
{
if
(
exc_info
->
reraise
)
{
exc_info
->
reraise
=
false
;
return
;
}
BoxedTraceback
::
Here
(
line_info
,
reinterpret_cast
<
BoxedTraceback
**>
(
&
exc_info
->
traceback
));
}
static
__thread
UnwindSession
*
cur_unwind
;
void
*
beginUnwind
()
{
if
(
!
cur_unwind
)
{
cur_unwind
=
new
UnwindSession
();
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
->
clear
();
return
cur_unwind
;
}
void
*
getUnwind
()
{
RELEASE_ASSERT
(
cur_unwind
,
""
);
return
cur_unwind
;
}
void
endUnwind
(
void
*
unwind
)
{
RELEASE_ASSERT
(
unwind
&&
unwind
==
cur_unwind
,
""
);
cur_unwind
->
clear
();
}
void
*
getExceptionFerry
(
void
*
unwind
)
{
RELEASE_ASSERT
(
unwind
&&
unwind
==
cur_unwind
,
""
);
UnwindSession
*
state
=
static_cast
<
UnwindSession
*>
(
unwind
);
return
state
->
getExcInfoStorage
();
}
void
maybeTracebackHere
(
void
*
unw_cursor
,
void
*
unwind_token
)
{
unw_cursor_t
*
cursor
=
(
unw_cursor_t
*
)
unw_cursor
;
UnwindSession
*
state
=
(
UnwindSession
*
)
unwind_token
;
unw_word_t
ip
=
get_cursor_ip
(
cursor
);
unw_word_t
bp
=
get_cursor_bp
(
cursor
);
PythonFrameIteratorImpl
frame_iter
;
if
(
unwindProcessFrame
(
ip
,
bp
,
cursor
,
&
frame_iter
))
{
if
(
!
state
->
shouldSkipFrame
())
{
state
->
addTraceback
(
lineInfoForFrame
(
&
frame_iter
));
}
// frame_iter->cf->entry_descriptor will be non-null for OSR frames.
state
->
setShouldSkipNextFrame
((
bool
)
frame_iter
.
cf
->
entry_descriptor
);
}
}
// To produce a traceback, we:
//
// 1. Use libunwind to produce a cursor into our stack.
...
...
src/codegen/unwinding.h
View file @
cc16b91a
...
...
@@ -19,6 +19,10 @@
#include "codegen/codegen.h"
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#undef UNW_LOCAL_ONLY
namespace
pyston
{
class
Box
;
...
...
@@ -37,13 +41,14 @@ CompiledFunction* getCFForAddress(uint64_t addr);
BoxedTraceback
*
getTraceback
();
void
*
beginUnwind
();
void
*
getUnwind
();
void
endUnwind
(
void
*
unwind_token
);
void
*
getExceptionFerry
(
void
*
unwind_token
);
class
UnwindSession
;
UnwindSession
*
beginUnwind
();
UnwindSession
*
getUnwind
();
void
endUnwind
(
UnwindSession
*
unwind_session
);
void
*
getExceptionStorage
(
UnwindSession
*
unwind_session
);
void
unwindingThroughFrame
(
UnwindSession
*
unwind_session
,
unw_cursor_t
*
cursor
);
void
exceptionCaughtInInterpreter
(
LineInfo
line_info
,
ExcInfo
*
exc_info
);
void
maybeTracebackHere
(
void
*
unw_cursor
,
void
*
unwind_token
);
struct
ExecutionPoint
{
CompiledFunction
*
cf
;
...
...
src/runtime/cxx_unwind.cpp
View file @
cc16b91a
...
...
@@ -25,7 +25,6 @@
#include "codegen/unwinding.h" // getCFForAddress
#include "core/ast.h"
#include "core/stats.h" // StatCounter
#include "core/threading.h" // for getExceptionFerry
#include "core/types.h" // for ExcInfo
#include "core/util.h" // Timer
#include "runtime/generator.h" // generatorEntry
...
...
@@ -493,7 +492,7 @@ static inline void unwind_loop(ExcInfo* exc_data) {
unw_getcontext
(
&
uc
);
unw_init_local
(
&
cursor
,
&
uc
);
void
*
unwind_token
=
getUnwind
();
auto
unwind_token
=
getUnwind
();
while
(
unw_step
(
&
cursor
)
>
0
)
{
unw_proc_info_t
pip
;
...
...
@@ -508,7 +507,7 @@ static inline void unwind_loop(ExcInfo* exc_data) {
print_frame
(
&
cursor
,
&
pip
);
}
maybeTracebackHere
(
&
cursor
,
unwind_token
);
unwindingThroughFrame
(
unwind_token
,
&
cursor
);
// Skip frames without handlers
if
(
pip
.
handler
==
0
)
{
...
...
@@ -637,7 +636,7 @@ extern "C" void* __cxa_allocate_exception(size_t size) noexcept {
// our exception info in curexc_*, and then unset these in __cxa_end_catch, then we'll wipe our exception info
// during unwinding!
return
pyston
::
getException
Ferry
(
pyston
::
getUnwind
());
return
pyston
::
getException
Storage
(
pyston
::
getUnwind
());
}
// Takes the value that resume() sent us in RAX, and returns a pointer to the exception object actually thrown. In our
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment