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
8e6d1230
Commit
8e6d1230
authored
Sep 29, 2016
by
qinsoon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[wip] keep implementing exception
parent
f9e3d65e
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
131 additions
and
33 deletions
+131
-33
src/compiler/backend/arch/x86_64/inst_sel.rs
src/compiler/backend/arch/x86_64/inst_sel.rs
+1
-1
src/compiler/frame.rs
src/compiler/frame.rs
+8
-15
src/runtime/exception.rs
src/runtime/exception.rs
+0
-12
src/runtime/exception_x64.rs
src/runtime/exception_x64.rs
+98
-0
src/runtime/mod.rs
src/runtime/mod.rs
+3
-0
src/runtime/swap_stack_x64_macos.s
src/runtime/swap_stack_x64_macos.s
+6
-0
src/runtime/thread.rs
src/runtime/thread.rs
+6
-3
src/utils/src/address.rs
src/utils/src/address.rs
+9
-2
No files found.
src/compiler/backend/arch/x86_64/inst_sel.rs
View file @
8e6d1230
...
...
@@ -1104,7 +1104,7 @@ impl CompilerPass for InstructionSelection {
fn
start_function
(
&
mut
self
,
vm
:
&
VM
,
func_ver
:
&
mut
MuFunctionVersion
)
{
debug!
(
"{}"
,
self
.name
());
self
.current_frame
=
Some
(
Frame
::
new
());
self
.current_frame
=
Some
(
Frame
::
new
(
func_ver
.id
()
));
self
.current_func_start
=
Some
({
let
funcs
=
vm
.funcs
()
.read
()
.unwrap
();
let
func
=
funcs
.get
(
&
func_ver
.func_id
)
.unwrap
()
.read
()
.unwrap
();
...
...
src/compiler/frame.rs
View file @
8e6d1230
...
...
@@ -6,8 +6,6 @@ use std::collections::HashMap;
use
utils
::
POINTER_SIZE
;
use
vm
::
VM
;
type
SlotID
=
usize
;
// | previous frame ...
// |---------------
// | return address
...
...
@@ -21,16 +19,16 @@ use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
#[derive(RustcEncodable,
RustcDecodable)]
pub
struct
Frame
{
cur_slot_id
:
Slot
ID
,
func_ver_id
:
Mu
ID
,
cur_offset
:
isize
,
// offset to rbp
allocated
:
HashMap
<
Slot
ID
,
FrameSlot
>
,
pub
allocated
:
HashMap
<
Mu
ID
,
FrameSlot
>
,
}
impl
Frame
{
pub
fn
new
()
->
Frame
{
pub
fn
new
(
func_ver_id
:
MuID
)
->
Frame
{
Frame
{
cur_slot_id
:
0
,
func_ver_id
:
func_ver_id
,
cur_offset
:
-
(
POINTER_SIZE
as
isize
*
1
),
// reserve for old RBP
allocated
:
HashMap
::
new
()
}
...
...
@@ -47,28 +45,23 @@ impl Frame {
}
fn
alloc_slot
(
&
mut
self
,
val
:
&
P
<
Value
>
,
vm
:
&
VM
)
->
&
FrameSlot
{
let
id
=
self
.cur_slot_id
;
let
id
=
val
.id
()
;
let
ret
=
FrameSlot
{
id
:
id
,
offset
:
self
.cur_offset
,
value
:
val
.clone
()
};
self
.cur_slot_id
+=
1
;
self
.cur_offset
-=
vm
.get_type_size
(
val
.ty
.id
())
as
isize
;
self
.allocated
.insert
(
id
,
ret
);
self
.allocated
.get
(
&
id
)
.unwrap
()
}
}
#[derive(RustcEncodable,
RustcDecodable)]
struct
FrameSlot
{
id
:
SlotID
,
offset
:
isize
,
value
:
P
<
Value
>
pub
struct
FrameSlot
{
pub
offset
:
isize
,
pub
value
:
P
<
Value
>
}
impl
FrameSlot
{
...
...
src/runtime/exception.rs
deleted
100644 → 0
View file @
f9e3d65e
use
utils
::
Address
;
use
runtime
::
thread
;
#[no_mangle]
#[cfg(target_arch
=
"x86_64"
)]
pub
extern
fn
mu_throw_exception
(
exception_obj
:
Address
)
{
trace!
(
"throwing exception: {}"
,
exception_obj
);
thread
::
MuThread
::
current_mut
()
.exception_obj
=
exception_obj
;
}
\ No newline at end of file
src/runtime/exception_x64.rs
0 → 100644
View file @
8e6d1230
use
ast
::
ir
::
*
;
use
compiler
::
machine_code
::
CompiledFunction
;
use
compiler
::
frame
::
*
;
use
compiler
::
backend
::
x86_64
;
use
utils
::
Address
;
use
utils
::
POINTER_SIZE
;
use
runtime
::
thread
;
use
std
::
sync
::
RwLock
;
use
std
::
sync
::
RwLockReadGuard
;
use
std
::
collections
::
HashMap
;
#[no_mangle]
pub
extern
fn
mu_throw_exception
(
exception_obj
:
Address
)
{
trace!
(
"throwing exception: {}"
,
exception_obj
);
let
mut
cur_thread
=
thread
::
MuThread
::
current_mut
();
// set exception object
cur_thread
.exception_obj
=
exception_obj
;
let
cf_lock
=
cur_thread
.vm
.compiled_funcs
()
.read
()
.unwrap
();
// rbp of current frame (mu_throw_exception(), Rust frame)
let
rust_frame_rbp
=
unsafe
{
thread
::
get_current_frame_rbp
()};
let
rust_frame_return_addr
=
unsafe
{
rust_frame_rbp
.plus
(
POINTER_SIZE
)
.load
::
<
Address
>
()};
// the return address is within throwing frame
let
throw_frame_callsite
=
rust_frame_return_addr
;
let
throw_func_id
=
find_func_for_address
(
&
cf_lock
,
throw_frame_callsite
);
// skip to previous frame
// this is the frame that throws the exception
let
rbp
=
unsafe
{
rust_frame_rbp
.load
::
<
Address
>
()};
// set cursor to throwing frame
let
mut
cursor
=
FrameCursor
{
rbp
:
rbp
,
return_addr
:
unsafe
{
rbp
.plus
(
POINTER_SIZE
)
.load
::
<
Address
>
()},
func_id
:
throw_func_id
,
callee_saved_locs
:
HashMap
::
new
()
};
loop
{
// get return address (the slot above RBP slot)
// let return_addr = unsafe {rbp.plus(POINTER_SIZE).load::<Address>()};
// check if return_addr is valid
// FIXME: should use a sentinel value here
if
cursor
.return_addr
.is_zero
()
{
panic!
(
"cannot find exception catch block, throws by {}"
,
throw_func_id
);
}
let
rwlock_cf
=
match
cf_lock
.get
(
&
cursor
.func_id
)
{
Some
(
ret
)
=>
ret
,
None
=>
panic!
(
"cannot find compiled func with func_id {}, possibly didnt find the right frame for return address"
,
cursor
.func_id
)
};
let
rwlock_cf
=
rwlock_cf
.read
()
.unwrap
();
let
ref
frame
=
rwlock_cf
.frame
;
// update callee saved register location
for
reg
in
x86_64
::
CALLEE_SAVED_GPRs
.iter
()
{
let
reg_id
=
reg
.id
();
if
frame
.allocated
.contains_key
(
&
reg_id
)
{
let
offset_from_rbp
=
frame
.allocated
.get
(
&
reg_id
)
.unwrap
()
.offset
;
let
reg_restore_addr
=
cursor
.rbp
.offset
(
offset_from_rbp
);
cursor
.callee_saved_locs
.insert
(
reg_id
,
reg_restore_addr
);
}
}
cursor
.to_previous_frame
(
&
cf_lock
);
// find exception block (if available)
}
}
struct
FrameCursor
{
rbp
:
Address
,
return_addr
:
Address
,
func_id
:
MuID
,
callee_saved_locs
:
HashMap
<
MuID
,
Address
>
}
impl
FrameCursor
{
fn
to_previous_frame
(
&
mut
self
,
cf
:
&
RwLockReadGuard
<
HashMap
<
MuID
,
RwLock
<
CompiledFunction
>>>
)
{
let
previous_rbp
=
unsafe
{
self
.rbp.load
::
<
Address
>
()};
let
previous_return_addr
=
unsafe
{
previous_rbp
.plus
(
POINTER_SIZE
)
.load
::
<
Address
>
()};
let
previous_func_id
=
find_func_for_address
(
cf
,
self
.return_addr
);
self
.rbp
=
previous_rbp
;
self
.return_addr
=
previous_return_addr
;
self
.func_id
=
previous_func_id
;
}
}
fn
find_func_for_address
(
cf
:
&
RwLockReadGuard
<
HashMap
<
MuID
,
RwLock
<
CompiledFunction
>>>
,
pc_addr
:
Address
)
->
MuID
{
unimplemented!
()
}
\ No newline at end of file
src/runtime/mod.rs
View file @
8e6d1230
...
...
@@ -16,6 +16,9 @@ use std::sync::Arc;
pub
extern
crate
gc
as
mm
;
pub
mod
thread
;
pub
mod
entrypoints
;
#[cfg(target_arch
=
"x86_64"
)]
#[path
=
"exception_x64.rs"
]
pub
mod
exception
;
// consider using libloading crate instead of the raw c functions for dynalic libraries
...
...
src/runtime/swap_stack_x64_macos.s
View file @
8e6d1230
...
...
@@ -61,3 +61,9 @@ _swap_back_to_native_stack:
popq
%
rbp
ret
#
_get_current_frame_rbp
()
->
Address
.
globl
_get_current_frame_rbp
_get_current_frame_rbp
:
movq
%
rbp
,
%
rax
ret
src/runtime/thread.rs
View file @
8e6d1230
...
...
@@ -207,13 +207,13 @@ pub enum MuStackState {
pub
struct
MuThread
{
pub
hdr
:
MuEntityHeader
,
allocator
:
mm
::
Mutator
,
stack
:
Option
<
Box
<
MuStack
>>
,
pub
stack
:
Option
<
Box
<
MuStack
>>
,
native_sp_loc
:
Address
,
user_tls
:
Option
<
Address
>
,
vm
:
Arc
<
VM
>
,
exception_obj
:
Address
pub
vm
:
Arc
<
VM
>
,
pub
exception_obj
:
Address
}
// this depends on the layout of MuThread
...
...
@@ -245,6 +245,7 @@ extern "C" {
extern
"C"
{
fn
swap_to_mu_stack
(
new_sp
:
Address
,
entry
:
Address
,
old_sp_loc
:
Address
);
fn
swap_back_to_native_stack
(
sp_loc
:
Address
);
pub
fn
get_current_frame_rbp
()
->
Address
;
}
impl
MuThread
{
...
...
@@ -260,12 +261,14 @@ impl MuThread {
}
}
#[inline(always)]
pub
fn
current
()
->
&
'static
MuThread
{
unsafe
{
get_thread_local
()
.to_ptr
::
<
MuThread
>
()
.as_ref
()
.unwrap
()
}
}
#[inline(always)]
pub
fn
current_mut
()
->
&
'static
mut
MuThread
{
unsafe
{
get_thread_local
()
.to_ptr_mut
::
<
MuThread
>
()
.as_mut
()
.unwrap
()
...
...
src/utils/src/address.rs
View file @
8e6d1230
#![allow(dead_code)]
use
std
::
cmp
;
use
std
::
fmt
;
use
std
::
mem
;
...
...
@@ -11,13 +13,18 @@ impl Address {
pub
fn
plus
(
&
self
,
bytes
:
usize
)
->
Self
{
Address
(
self
.
0
+
bytes
)
}
#[allow(dead_code)]
#[inline(always)]
pub
fn
sub
(
&
self
,
bytes
:
usize
)
->
Self
{
Address
(
self
.
0
-
bytes
)
}
#[inline(always)]
pub
fn
offset
<
T
>
(
&
self
,
offset
:
isize
)
->
Self
{
pub
fn
offset
(
&
self
,
offset
:
isize
)
->
Self
{
debug_assert!
((
self
.
0
as
isize
)
<
0
);
Address
((
self
.
0
as
isize
+
offset
)
as
usize
)
}
#[inline(always)]
pub
fn
shift
<
T
>
(
&
self
,
offset
:
isize
)
->
Self
{
debug_assert!
((
self
.
0
as
isize
)
<
0
);
Address
((
self
.
0
as
isize
+
mem
::
size_of
::
<
T
>
()
as
isize
*
offset
)
as
usize
)
}
#[inline(always)]
...
...
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