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
02e46a45
Commit
02e46a45
authored
Aug 17, 2016
by
Marius Wachtler
Committed by
GitHub
Aug 17, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1330 from undingen/fix_eh_handling
EH: correctly deregister EH frames and cleanup the code
parents
af9934e1
d4b8c35c
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
71 additions
and
50 deletions
+71
-50
libunwind_patches/0003-use-a-sorted-array-for-registered-objects-and-do-a-b.patch
...se-a-sorted-array-for-registered-objects-and-do-a-b.patch
+1
-1
src/codegen/baseline_jit.cpp
src/codegen/baseline_jit.cpp
+4
-11
src/codegen/baseline_jit.h
src/codegen/baseline_jit.h
+1
-0
src/codegen/memmgr.cpp
src/codegen/memmgr.cpp
+0
-10
src/codegen/memmgr.h
src/codegen/memmgr.h
+0
-2
src/codegen/unwinding.cpp
src/codegen/unwinding.cpp
+37
-1
src/codegen/unwinding.h
src/codegen/unwinding.h
+18
-1
src/runtime/ics.cpp
src/runtime/ics.cpp
+8
-24
src/runtime/ics.h
src/runtime/ics.h
+2
-0
No files found.
libunwind_patches/0003-use-a-sorted-array-for-registered-objects-and-do-a-b.patch
View file @
02e46a45
...
@@ -89,7 +89,7 @@ index e784317..fedba3e 100644
...
@@ -89,7 +89,7 @@ index e784317..fedba3e 100644
+ int i;
+ int i;
+ for (i = 0; i < _U_dyn_info_list_size; i ++) {
+ for (i = 0; i < _U_dyn_info_list_size; i ++) {
+ if (di == _U_dyn_info_list[i] && i < _U_dyn_info_list_size - 1) {
+ if (di == _U_dyn_info_list[i] && i < _U_dyn_info_list_size - 1) {
+ memmove(
_U_dyn_info_list[i],
_U_dyn_info_list[i+1],
+ memmove(
&_U_dyn_info_list[i], &
_U_dyn_info_list[i+1],
+ sizeof(unw_dyn_info_t*) * (_U_dyn_info_list_size - i - 1));
+ sizeof(unw_dyn_info_t*) * (_U_dyn_info_list_size - i - 1));
+ break;
+ break;
+ }
+ }
...
...
src/codegen/baseline_jit.cpp
View file @
02e46a45
...
@@ -104,19 +104,12 @@ JitCodeBlock::JitCodeBlock(llvm::StringRef name)
...
@@ -104,19 +104,12 @@ JitCodeBlock::JitCodeBlock(llvm::StringRef name)
entry_offset
=
a
.
bytesWritten
();
entry_offset
=
a
.
bytesWritten
();
// generate the eh frame...
// generate the eh frame...
const
int
size
=
sizeof
(
eh_info
);
const
int
eh_frame_
size
=
sizeof
(
eh_info
);
void
*
eh_frame_addr
=
memory
.
get
();
void
*
eh_frame_addr
=
memory
.
get
();
memcpy
(
eh_frame_addr
,
eh_info
,
size
);
memcpy
(
eh_frame_addr
,
eh_info
,
eh_frame_
size
);
int32_t
*
offset_ptr
=
(
int32_t
*
)((
uint8_t
*
)
eh_frame_addr
+
0x20
);
register_eh_info
.
updateAndRegisterFrameFromTemplate
((
uint64_t
)
code
,
code_size
,
(
uint64_t
)
eh_frame_addr
,
int32_t
*
size_ptr
=
(
int32_t
*
)((
uint8_t
*
)
eh_frame_addr
+
0x24
);
eh_frame_size
);
int64_t
offset
=
(
int8_t
*
)
code
-
(
int8_t
*
)
offset_ptr
;
assert
(
offset
>=
INT_MIN
&&
offset
<=
INT_MAX
);
*
offset_ptr
=
offset
;
*
size_ptr
=
code_size
;
registerDynamicEhFrame
((
uint64_t
)
code
,
code_size
,
(
uint64_t
)
eh_frame_addr
,
size
-
4
);
registerEHFrames
((
uint8_t
*
)
eh_frame_addr
,
(
uint64_t
)
eh_frame_addr
,
size
);
static
int
num_block
=
0
;
static
int
num_block
=
0
;
auto
unique_name
=
(
"bjit_"
+
name
+
"_"
+
llvm
::
Twine
(
num_block
++
)).
str
();
auto
unique_name
=
(
"bjit_"
+
name
+
"_"
+
llvm
::
Twine
(
num_block
++
)).
str
();
...
...
src/codegen/baseline_jit.h
View file @
02e46a45
...
@@ -177,6 +177,7 @@ private:
...
@@ -177,6 +177,7 @@ private:
// this contains all the decref infos the bjit generated inside the memory block,
// this contains all the decref infos the bjit generated inside the memory block,
// this allows us to deregister them when we release the code
// this allows us to deregister them when we release the code
std
::
vector
<
DecrefInfo
>
decref_infos
;
std
::
vector
<
DecrefInfo
>
decref_infos
;
RegisterEHFrame
register_eh_info
;
public:
public:
JitCodeBlock
(
llvm
::
StringRef
name
);
JitCodeBlock
(
llvm
::
StringRef
name
);
...
...
src/codegen/memmgr.cpp
View file @
02e46a45
...
@@ -241,14 +241,4 @@ PystonMemoryManager::~PystonMemoryManager() {
...
@@ -241,14 +241,4 @@ PystonMemoryManager::~PystonMemoryManager() {
std
::
unique_ptr
<
llvm
::
RTDyldMemoryManager
>
createMemoryManager
()
{
std
::
unique_ptr
<
llvm
::
RTDyldMemoryManager
>
createMemoryManager
()
{
return
std
::
unique_ptr
<
llvm
::
RTDyldMemoryManager
>
(
new
PystonMemoryManager
());
return
std
::
unique_ptr
<
llvm
::
RTDyldMemoryManager
>
(
new
PystonMemoryManager
());
}
}
// These functions exist as instance methods of the RTDyldMemoryManager class,
// but it's tricky to access them since the class has pure-virtual methods.
void
registerEHFrames
(
uint8_t
*
addr
,
uint64_t
load_addr
,
size_t
size
)
{
PystonMemoryManager
().
registerEHFrames
(
addr
,
load_addr
,
size
);
}
void
deregisterEHFrames
(
uint8_t
*
addr
,
uint64_t
load_addr
,
size_t
size
)
{
PystonMemoryManager
().
deregisterEHFrames
(
addr
,
load_addr
,
size
);
}
}
}
src/codegen/memmgr.h
View file @
02e46a45
...
@@ -26,8 +26,6 @@ class RTDyldMemoryManager;
...
@@ -26,8 +26,6 @@ class RTDyldMemoryManager;
namespace
pyston
{
namespace
pyston
{
std
::
unique_ptr
<
llvm
::
RTDyldMemoryManager
>
createMemoryManager
();
std
::
unique_ptr
<
llvm
::
RTDyldMemoryManager
>
createMemoryManager
();
void
registerEHFrames
(
uint8_t
*
addr
,
uint64_t
load_addr
,
size_t
size
);
void
deregisterEHFrames
(
uint8_t
*
addr
,
uint64_t
load_addr
,
size_t
size
);
}
}
#endif
#endif
src/codegen/unwinding.cpp
View file @
02e46a45
...
@@ -94,7 +94,7 @@ void parseEhFrame(uint64_t start_addr, uint64_t size, uint64_t func_addr, uint64
...
@@ -94,7 +94,7 @@ void parseEhFrame(uint64_t start_addr, uint64_t size, uint64_t func_addr, uint64
*
out_len
=
nentries
;
*
out_len
=
nentries
;
}
}
void
registerDynamicEhFrame
(
uint64_t
code_addr
,
size_t
code_size
,
uint64_t
eh_frame_addr
,
size_t
eh_frame_size
)
{
void
*
registerDynamicEhFrame
(
uint64_t
code_addr
,
size_t
code_size
,
uint64_t
eh_frame_addr
,
size_t
eh_frame_size
)
{
unw_dyn_info_t
*
dyn_info
=
new
unw_dyn_info_t
();
unw_dyn_info_t
*
dyn_info
=
new
unw_dyn_info_t
();
dyn_info
->
start_ip
=
code_addr
;
dyn_info
->
start_ip
=
code_addr
;
dyn_info
->
end_ip
=
code_addr
+
code_size
;
dyn_info
->
end_ip
=
code_addr
+
code_size
;
...
@@ -116,6 +116,42 @@ void registerDynamicEhFrame(uint64_t code_addr, size_t code_size, uint64_t eh_fr
...
@@ -116,6 +116,42 @@ void registerDynamicEhFrame(uint64_t code_addr, size_t code_size, uint64_t eh_fr
// as opposed to the binary search it can do within a dyn_info.
// as opposed to the binary search it can do within a dyn_info.
// If we're registering a lot of dyn_info's, it might make sense to coalesce them into a single
// If we're registering a lot of dyn_info's, it might make sense to coalesce them into a single
// dyn_info that contains a binary search table.
// dyn_info that contains a binary search table.
return
dyn_info
;
}
void
deregisterDynamicEhFrame
(
void
*
_dyn_info
)
{
auto
dyn_info
=
(
unw_dyn_info_t
*
)
_dyn_info
;
_U_dyn_cancel
(
dyn_info
);
delete
(
uw_table_entry
*
)
dyn_info
->
u
.
rti
.
table_data
;
delete
dyn_info
;
}
void
RegisterEHFrame
::
updateAndRegisterFrameFromTemplate
(
uint64_t
code_addr
,
size_t
code_size
,
uint64_t
eh_frame_addr
,
size_t
eh_frame_size
)
{
assert
(
eh_frame_size
>
0x24
);
int32_t
*
offset_ptr
=
(
int32_t
*
)((
uint8_t
*
)
eh_frame_addr
+
0x20
);
int32_t
*
size_ptr
=
(
int32_t
*
)((
uint8_t
*
)
eh_frame_addr
+
0x24
);
int64_t
offset
=
(
int8_t
*
)
code_addr
-
(
int8_t
*
)
offset_ptr
;
assert
(
offset
>=
INT_MIN
&&
offset
<=
INT_MAX
);
*
offset_ptr
=
offset
;
*
size_ptr
=
code_size
;
// (EH_FRAME_SIZE - 4) to omit the 4-byte null terminator, otherwise we trip an assert in parseEhFrame.
// TODO: can we omit the terminator in general?
registerFrame
(
code_addr
,
code_size
,
eh_frame_addr
,
eh_frame_size
-
4
);
}
void
RegisterEHFrame
::
registerFrame
(
uint64_t
code_addr
,
size_t
code_size
,
uint64_t
eh_frame_addr
,
size_t
eh_frame_size
)
{
assert
(
!
dyn_info
);
dyn_info
=
registerDynamicEhFrame
(
code_addr
,
code_size
,
eh_frame_addr
,
eh_frame_size
);
}
void
RegisterEHFrame
::
deregisterFrame
()
{
if
(
dyn_info
)
{
deregisterDynamicEhFrame
(
dyn_info
);
dyn_info
=
NULL
;
}
}
}
struct
compare_cf
{
struct
compare_cf
{
...
...
src/codegen/unwinding.h
View file @
02e46a45
...
@@ -30,7 +30,24 @@ class BoxedDict;
...
@@ -30,7 +30,24 @@ class BoxedDict;
class
BoxedModule
;
class
BoxedModule
;
struct
FrameInfo
;
struct
FrameInfo
;
void
registerDynamicEhFrame
(
uint64_t
code_addr
,
size_t
code_size
,
uint64_t
eh_frame_addr
,
size_t
eh_frame_size
);
class
RegisterEHFrame
{
private:
void
*
dyn_info
;
public:
RegisterEHFrame
()
:
dyn_info
(
NULL
)
{}
~
RegisterEHFrame
()
{
deregisterFrame
();
}
// updates the EH info at eh_frame_addr to reference the passed code addr and code size and registers it
void
updateAndRegisterFrameFromTemplate
(
uint64_t
code_addr
,
size_t
code_size
,
uint64_t
eh_frame_addr
,
size_t
eh_frame_size
);
void
registerFrame
(
uint64_t
code_addr
,
size_t
code_size
,
uint64_t
eh_frame_addr
,
size_t
eh_frame_size
);
void
deregisterFrame
();
};
void
*
registerDynamicEhFrame
(
uint64_t
code_addr
,
size_t
code_size
,
uint64_t
eh_frame_addr
,
size_t
eh_frame_size
);
void
deregisterDynamicEhFrame
(
void
*
dyn_info
);
uint64_t
getCXXUnwindSymbolAddress
(
llvm
::
StringRef
sym
);
uint64_t
getCXXUnwindSymbolAddress
(
llvm
::
StringRef
sym
);
// use this instead of std::uncaught_exception.
// use this instead of std::uncaught_exception.
...
...
src/runtime/ics.cpp
View file @
02e46a45
...
@@ -22,7 +22,6 @@
...
@@ -22,7 +22,6 @@
#include "codegen/memmgr.h"
#include "codegen/memmgr.h"
#include "codegen/patchpoints.h"
#include "codegen/patchpoints.h"
#include "codegen/stackmaps.h"
#include "codegen/stackmaps.h"
#include "codegen/unwinding.h" // registerDynamicEhFrame
#include "core/common.h"
#include "core/common.h"
#include "core/options.h"
#include "core/options.h"
#include "core/stats.h"
#include "core/stats.h"
...
@@ -161,23 +160,6 @@ static constexpr int _eh_frame_template_fp_size = sizeof(_eh_frame_template_fp)
...
@@ -161,23 +160,6 @@ static constexpr int _eh_frame_template_fp_size = sizeof(_eh_frame_template_fp)
static_assert
(
sizeof
(
""
)
==
1
,
"strings are null-terminated"
);
static_assert
(
sizeof
(
""
)
==
1
,
"strings are null-terminated"
);
static
void
writeTrivialEhFrame
(
void
*
eh_frame_addr
,
void
*
func_addr
,
uint64_t
func_size
,
bool
omit_frame_pointer
)
{
if
(
omit_frame_pointer
)
memcpy
(
eh_frame_addr
,
_eh_frame_template_ofp
,
_eh_frame_template_ofp_size
);
else
memcpy
(
eh_frame_addr
,
_eh_frame_template_fp
,
_eh_frame_template_fp_size
);
int32_t
*
offset_ptr
=
(
int32_t
*
)((
uint8_t
*
)
eh_frame_addr
+
0x20
);
int32_t
*
size_ptr
=
(
int32_t
*
)((
uint8_t
*
)
eh_frame_addr
+
0x24
);
int64_t
offset
=
(
int8_t
*
)
func_addr
-
(
int8_t
*
)
offset_ptr
;
RELEASE_ASSERT
(
offset
>=
INT_MIN
&&
offset
<=
INT_MAX
,
""
);
*
offset_ptr
=
offset
;
assert
(
func_size
<=
UINT_MAX
);
*
size_ptr
=
func_size
;
}
#if RUNTIMEICS_OMIT_FRAME_PTR
#if RUNTIMEICS_OMIT_FRAME_PTR
// If you change this, you *must* update the value in _eh_frame_template
// If you change this, you *must* update the value in _eh_frame_template
// (set the -9'th byte to this value plus 8)
// (set the -9'th byte to this value plus 8)
...
@@ -309,11 +291,13 @@ RuntimeIC::RuntimeIC(void* func_addr, int total_size) {
...
@@ -309,11 +291,13 @@ RuntimeIC::RuntimeIC(void* func_addr, int total_size) {
assert
(
!
epilogue_assem
.
hasFailed
());
assert
(
!
epilogue_assem
.
hasFailed
());
assert
(
epilogue_assem
.
isExactlyFull
());
assert
(
epilogue_assem
.
isExactlyFull
());
writeTrivialEhFrame
(
eh_frame_addr
,
addr
,
total_code_size
,
RUNTIMEICS_OMIT_FRAME_PTR
);
// (EH_FRAME_SIZE - 4) to omit the 4-byte null terminator, otherwise we trip an assert in parseEhFrame.
if
(
RUNTIMEICS_OMIT_FRAME_PTR
)
// TODO: can we omit the terminator in general?
memcpy
(
eh_frame_addr
,
_eh_frame_template_ofp
,
_eh_frame_template_ofp_size
);
registerDynamicEhFrame
((
uint64_t
)
addr
,
total_code_size
,
(
uint64_t
)
eh_frame_addr
,
EH_FRAME_SIZE
-
4
);
else
registerEHFrames
((
uint8_t
*
)
eh_frame_addr
,
(
uint64_t
)
eh_frame_addr
,
EH_FRAME_SIZE
);
memcpy
(
eh_frame_addr
,
_eh_frame_template_fp
,
_eh_frame_template_fp_size
);
register_eh_frame
.
updateAndRegisterFrameFromTemplate
((
uint64_t
)
addr
,
total_code_size
,
(
uint64_t
)
eh_frame_addr
,
EH_FRAME_SIZE
);
}
else
{
}
else
{
addr
=
func_addr
;
addr
=
func_addr
;
}
}
...
@@ -321,8 +305,8 @@ RuntimeIC::RuntimeIC(void* func_addr, int total_size) {
...
@@ -321,8 +305,8 @@ RuntimeIC::RuntimeIC(void* func_addr, int total_size) {
RuntimeIC
::~
RuntimeIC
()
{
RuntimeIC
::~
RuntimeIC
()
{
if
(
ENABLE_RUNTIME_ICS
)
{
if
(
ENABLE_RUNTIME_ICS
)
{
register_eh_frame
.
deregisterFrame
();
uint8_t
*
eh_frame_addr
=
(
uint8_t
*
)
addr
-
EH_FRAME_SIZE
;
uint8_t
*
eh_frame_addr
=
(
uint8_t
*
)
addr
-
EH_FRAME_SIZE
;
deregisterEHFrames
(
eh_frame_addr
,
(
uint64_t
)
eh_frame_addr
,
EH_FRAME_SIZE
);
memory_manager_512b
.
dealloc
(
eh_frame_addr
);
memory_manager_512b
.
dealloc
(
eh_frame_addr
);
}
else
{
}
else
{
}
}
...
...
src/runtime/ics.h
View file @
02e46a45
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#ifndef PYSTON_RUNTIME_ICS_H
#ifndef PYSTON_RUNTIME_ICS_H
#define PYSTON_RUNTIME_ICS_H
#define PYSTON_RUNTIME_ICS_H
#include "codegen/unwinding.h" // RegisterEHFrame
#include "core/common.h"
#include "core/common.h"
#include "runtime/objmodel.h"
#include "runtime/objmodel.h"
...
@@ -26,6 +27,7 @@ class RuntimeIC {
...
@@ -26,6 +27,7 @@ class RuntimeIC {
private:
private:
void
*
addr
;
// points to function start not the start of the allocated memory block.
void
*
addr
;
// points to function start not the start of the allocated memory block.
RegisterEHFrame
register_eh_frame
;
std
::
unique_ptr
<
ICInfo
>
icinfo
;
std
::
unique_ptr
<
ICInfo
>
icinfo
;
RuntimeIC
(
const
RuntimeIC
&
)
=
delete
;
RuntimeIC
(
const
RuntimeIC
&
)
=
delete
;
...
...
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