Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mu-impl-fast
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
40
Issues
40
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
mu
mu-impl-fast
Commits
eb300764
Commit
eb300764
authored
Jan 18, 2017
by
qinsoon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[wip] exception should work fine. but it doenst run when running with
other tests
parent
a0cafb0d
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
65 additions
and
12 deletions
+65
-12
build.rs
build.rs
+2
-2
src/runtime/exception_x64.rs
src/runtime/exception_x64.rs
+44
-9
src/runtime/swap_stack_x64_sysv.S
src/runtime/swap_stack_x64_sysv.S
+18
-1
src/runtime/thread.rs
src/runtime/thread.rs
+1
-0
No files found.
build.rs
View file @
eb300764
...
@@ -5,7 +5,7 @@ extern crate gcc;
...
@@ -5,7 +5,7 @@ extern crate gcc;
fn
main
()
{
fn
main
()
{
gcc
::
compile_library
(
"libruntime.a"
,
&
[
"src/runtime/runtime_x64_sysv.c"
]);
gcc
::
compile_library
(
"libruntime.a"
,
&
[
"src/runtime/runtime_x64_sysv.c"
]);
gcc
::
Config
::
new
()
.flag
(
"-O3"
)
gcc
::
Config
::
new
()
.flag
(
"-O3"
)
.flag
(
"-c"
)
.file
(
"src/runtime/swap_stack_x64_sysv.S"
)
.file
(
"src/runtime/swap_stack_x64_sysv.S"
)
.compile
(
"libswap_stack.a"
);
.compile
(
"libswap_stack.a"
);
}
}
...
@@ -15,7 +15,7 @@ fn main() {
...
@@ -15,7 +15,7 @@ fn main() {
fn
main
()
{
fn
main
()
{
gcc
::
compile_library
(
"libruntime.a"
,
&
[
"src/runtime/runtime_x64_sysv.c"
]);
gcc
::
compile_library
(
"libruntime.a"
,
&
[
"src/runtime/runtime_x64_sysv.c"
]);
gcc
::
Config
::
new
()
.flag
(
"-O3"
)
gcc
::
Config
::
new
()
.flag
(
"-O3"
)
.flag
(
"-c"
)
.file
(
"src/runtime/swap_stack_x64_sysv.S"
)
.file
(
"src/runtime/swap_stack_x64_sysv.S"
)
.compile
(
"libswap_stack.a"
);
.compile
(
"libswap_stack.a"
);
}
}
src/runtime/exception_x64.rs
View file @
eb300764
...
@@ -11,22 +11,48 @@ use std::sync::RwLockReadGuard;
...
@@ -11,22 +11,48 @@ use std::sync::RwLockReadGuard;
use
std
::
collections
::
HashMap
;
use
std
::
collections
::
HashMap
;
use
std
::
fmt
;
use
std
::
fmt
;
// muentry_throw_exception in swap_stack_x64_sysV.S
// is like a special calling convention to throw_exception_internal
// in order to save all the callee saved registers at a known location
// normal calling convention:
// ---code--- ---stack---
// push caller saved caller saved
// call return addr
// -> (in callee) push rbp old rbp
// mov rsp -> rbp callee saved
// push callee saved
// this function's calling convention
// ---code--- ---stack---
// push caller saved caller saved
// call return addr
// -> (in asm) push callee saved all callee saved <- 2nd arg
// (in rust) push rbp (by rust) old rbp
// mov rsp -> rbp (by rust) callee saved
// push callee saved
// we do not want to make any assumptionon where rust saves rbp or callee saved
// so we save them by ourselves in assembly, and pass a pointer as 2nd argument
#[no_mangle]
#[no_mangle]
#[allow(unreachable_code)]
#[allow(unreachable_code)]
pub
extern
fn
muentry_throw_exception
(
exception_obj
:
Address
)
{
// last_frame_callee_saved: a pointer passed from assembly, values of 6 callee_saved
// registers are layed out as rbx, rbp, r12-r15 (from low address to high address)
// and return address is put after 6 callee saved regsiters
pub
extern
fn
throw_exception_internal
(
exception_obj
:
Address
,
last_frame_callee_saved
:
Address
)
{
trace!
(
"throwing exception: {}"
,
exception_obj
);
trace!
(
"throwing exception: {}"
,
exception_obj
);
trace!
(
"callee saved registers of last frame is saved at {}"
,
last_frame_callee_saved
);
inspect_nearby_address
(
last_frame_callee_saved
,
8
);
let
mut
cur_thread
=
thread
::
MuThread
::
current_mut
();
let
mut
cur_thread
=
thread
::
MuThread
::
current_mut
();
// set exception object
// set exception object
cur_thread
.exception_obj
=
exception_obj
;
cur_thread
.exception_obj
=
exception_obj
;
let
cf_lock
=
cur_thread
.vm
.compiled_funcs
()
.read
()
.unwrap
();
let
cf_lock
=
cur_thread
.vm
.compiled_funcs
()
.read
()
.unwrap
();
// rbp of current frame (mu_throw_exception(), Rust frame)
let
rust_frame_return_addr
=
unsafe
{
last_frame_callee_saved
.plus
(
POINTER_SIZE
*
x86_64
::
CALLEE_SAVED_GPRs
.len
())
.load
::
<
Address
>
()};
let
rust_frame_rbp
=
unsafe
{
thread
::
get_current_frame_rbp
()};
trace!
(
"current frame RBP: 0x{:x}"
,
rust_frame_rbp
);
inspect_nearby_address
(
rust_frame_rbp
,
5
);
let
rust_frame_return_addr
=
unsafe
{
rust_frame_rbp
.plus
(
POINTER_SIZE
)
.load
::
<
Address
>
()};
trace!
(
"return address : 0x{:x} - throw instruction"
,
rust_frame_return_addr
);
trace!
(
"return address : 0x{:x} - throw instruction"
,
rust_frame_return_addr
);
// the return address is within throwing frame
// the return address is within throwing frame
...
@@ -36,7 +62,9 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
...
@@ -36,7 +62,9 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
// skip to previous frame
// skip to previous frame
// this is the frame that throws the exception
// this is the frame that throws the exception
let
rbp
=
unsafe
{
rust_frame_rbp
.load
::
<
Address
>
()};
let
previous_frame_rbp_loc
=
last_frame_callee_saved
.plus
(
POINTER_SIZE
);
let
rbp
=
unsafe
{
previous_frame_rbp_loc
.load
::
<
Address
>
()};
trace!
(
"rbp of previous frame is {} (last_frame_callee_saved {} + 8)"
,
rbp
,
last_frame_callee_saved
);
// set cursor to throwing frame
// set cursor to throwing frame
let
mut
cursor
=
FrameCursor
{
let
mut
cursor
=
FrameCursor
{
...
@@ -44,7 +72,14 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
...
@@ -44,7 +72,14 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
return_addr
:
unsafe
{
rbp
.plus
(
POINTER_SIZE
)
.load
::
<
Address
>
()},
return_addr
:
unsafe
{
rbp
.plus
(
POINTER_SIZE
)
.load
::
<
Address
>
()},
func_id
:
throw_func
,
func_id
:
throw_func
,
func_ver_id
:
throw_fv
,
func_ver_id
:
throw_fv
,
callee_saved_locs
:
HashMap
::
new
()
callee_saved_locs
:
hashmap!
{
x86_64
::
RBX
.id
()
=>
last_frame_callee_saved
,
x86_64
::
RBP
.id
()
=>
previous_frame_rbp_loc
,
x86_64
::
R12
.id
()
=>
last_frame_callee_saved
.plus
(
POINTER_SIZE
*
2
),
x86_64
::
R13
.id
()
=>
last_frame_callee_saved
.plus
(
POINTER_SIZE
*
3
),
x86_64
::
R14
.id
()
=>
last_frame_callee_saved
.plus
(
POINTER_SIZE
*
4
),
x86_64
::
R15
.id
()
=>
last_frame_callee_saved
.plus
(
POINTER_SIZE
*
5
),
}
};
};
trace!
(
"cursor at first Mu frame: {}"
,
cursor
);
trace!
(
"cursor at first Mu frame: {}"
,
cursor
);
...
...
src/runtime/swap_stack_x64_sysv.S
View file @
eb300764
...
@@ -70,8 +70,25 @@ begin_func get_current_frame_rbp
...
@@ -70,8 +70,25 @@ begin_func get_current_frame_rbp
ret
ret
end_func
get_current_frame_rbp
end_func
get_current_frame_rbp
#
muentry_throw_exception
(
obj
:
Address
)
#
%
rdi
begin_func
muentry_throw_exception
#
save
all
callee
-
saved
pushq
%
r15
pushq
%
r14
pushq
%
r13
pushq
%
r12
pushq
%
rbp
pushq
%
rbx
#
%
rsp
points
to
%
rbx
,
pass
this
as
2
nd
argument
movq
%
rsp
,
%
rsi
jmp
CNAME
(
throw_exception_internal
)
#
won
't return
#
_exception_restore
(
dest
:
Address
,
callee_saved
:
*
const
Word
,
rsp
:
Address
)
->
!
#
_exception_restore
(
dest
:
Address
,
callee_saved
:
*
const
Word
,
rsp
:
Address
)
->
!
#
%
rdi
%
rsi
%
rdx
#
%
rdi
%
rsi
%
rdx
#
callee_saved
:
[
rbx
,
rbp
,
r12
,
r13
,
r14
,
r15
]
#
callee_saved
:
[
rbx
,
rbp
,
r12
,
r13
,
r14
,
r15
]
begin_func
exception_restore
begin_func
exception_restore
movq
0
(%
rsi
),
%
rbx
movq
0
(%
rsi
),
%
rbx
...
...
src/runtime/thread.rs
View file @
eb300764
...
@@ -300,6 +300,7 @@ impl MuThread {
...
@@ -300,6 +300,7 @@ impl MuThread {
if
!
unsafe
{
muentry_get_thread_local
()}
.is_zero
()
{
if
!
unsafe
{
muentry_get_thread_local
()}
.is_zero
()
{
warn!
(
"current thread has a thread local (has a muthread to it)"
);
warn!
(
"current thread has a thread local (has a muthread to it)"
);
panic!
(
"should not have muthread here"
);
return
false
;
return
false
;
}
}
...
...
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