Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mu-impl-fast
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
40
Issues
40
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
mu
mu-impl-fast
Commits
71aefd55
Commit
71aefd55
authored
Nov 28, 2017
by
qinsoon
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into gc-rewrite
parents
211e3976
0f303eca
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
99 additions
and
34 deletions
+99
-34
ci.sh
ci.sh
+6
-6
asm_backend.rs
src/compiler/backend/arch/aarch64/asm_backend.rs
+13
-6
asm_backend.rs
src/compiler/backend/arch/x86_64/asm_backend.rs
+10
-4
coloring.rs
src/compiler/backend/reg_alloc/graph_coloring/coloring.rs
+38
-7
liveness.rs
src/compiler/backend/reg_alloc/graph_coloring/liveness.rs
+16
-3
mod.rs
src/runtime/mod.rs
+7
-2
vm.rs
src/vm/vm.rs
+9
-6
No files found.
ci.sh
View file @
71aefd55
...
...
@@ -13,15 +13,12 @@
# limitations under the License.
set
-e
if
[
-z
"
$MU_ZEBU
"
]
then
export
MU_ZEBU
=
$PWD
fi
export
MU_ZEBU
=
$(
dirname
$0
)
export
MU_LOG_LEVEL
=
none
export
RUST_TEST_THREADS
=
1
export
RUST_BACKTRACE
=
0
export
PYTHONPATH
=
"
$MU_ZEBU
/tests/test_jit/mu-client-pypy/:
$MU_ZEBU
/tests/test_jit/RPySOM/src"
export
LD_LIBRARY_PATH
=
"
$MU_ZEBU
/t
ests/test_jit/:
$MU_ZEBU
/tests/test_jit
:
$LD_LIBRARY_PATH
"
export
LD_LIBRARY_PATH
=
"
$MU_ZEBU
/t
arget/
$ZEBU_BUILD
:
$MU_ZEBU
/tests/test_jit/:
$MU_ZEBU
/tests/test_jit/emit/
:
$LD_LIBRARY_PATH
"
export
ZEBU_BUILD
=
release
rm
-rf
$MU_ZEBU
/emit
...
...
@@ -56,4 +53,7 @@ else
git
-C
./RPySOM submodule update
fi
shopt
-s
extglob
pytest ./test_!
(
pypy
)
.py
-v
--color
=
yes
2>&1 |
tee
$MU_ZEBU
/pytest_out.txt
pytest ./test_!
(
pypy
)
.py
-v
--color
=
yes
2>&1 |
tee
$MU_ZEBU
/pytest_jit_out.txt
cd
$MU_ZEBU
/tests/test_muc
pytest ./test_
*
.py
-v
--color
=
yes
2>&1 |
tee
$MU_ZEBU
/pytest_muc_out.txt
src/compiler/backend/arch/aarch64/asm_backend.rs
View file @
71aefd55
...
...
@@ -3638,7 +3638,8 @@ use std::collections::HashMap;
pub
fn
emit_context_with_reloc
(
vm
:
&
VM
,
symbols
:
HashMap
<
Address
,
MuName
>
,
fields
:
HashMap
<
Address
,
MuName
>
fields
:
HashMap
<
Address
,
MuName
>
,
primordial_threadlocal
:
Option
<
Address
>
)
{
use
std
::
path
;
use
std
::
io
::
prelude
::
*
;
...
...
@@ -3664,23 +3665,24 @@ pub fn emit_context_with_reloc(
// data
writeln!
(
file
,
".data"
)
.unwrap
();
// persist heap - we traverse the heap from globals
{
let
primordial_threadlocal
=
{
use
runtime
::
mm
;
// persist globals
let
global_locs_lock
=
vm
.global_locations
()
.read
()
.unwrap
();
let
global_lock
=
vm
.globals
()
.read
()
.unwrap
();
// a map from address to ID
let
global_addr_id_map
=
{
let
mut
map
:
LinkedHashMap
<
Address
,
MuID
>
=
LinkedHashMap
::
new
();
for
(
id
,
global_loc
)
in
global_locs_lock
.iter
()
{
map
.insert
(
global_loc
.to_address
(),
*
id
);
}
map
};
//
get address of all globals so we can traverse heap from them
//
dump heap from globals
let
global_addrs
:
Vec
<
Address
>
=
global_locs_lock
.values
()
.map
(|
x
|
x
.to_address
())
.collect
();
debug!
(
"going to dump these globals: {:?}"
,
global_addrs
);
...
...
@@ -3789,6 +3791,11 @@ pub fn emit_context_with_reloc(
offset
+=
POINTER_SIZE
;
}
}
primordial_threadlocal
.map
(|
a
|
relocatable_refs
.get
(
&
a
)
.unwrap
()
.clone
())
};
{
let
mut
lock
=
vm
.primordial_threadlocal
.write
()
.unwrap
();
*
lock
=
primordial_threadlocal
;
}
// serialize vm
...
...
@@ -3830,7 +3837,7 @@ fn write_obj_header(f: &mut File, obj: &ObjectEncode) {
}
pub
fn
emit_context
(
vm
:
&
VM
)
{
emit_context_with_reloc
(
vm
,
hashmap!
{},
hashmap!
{});
emit_context_with_reloc
(
vm
,
hashmap!
{},
hashmap!
{}
,
None
);
}
fn
write_data_bytes
(
f
:
&
mut
File
,
from
:
Address
,
to
:
Address
)
{
...
...
src/compiler/backend/arch/x86_64/asm_backend.rs
View file @
71aefd55
...
...
@@ -4161,7 +4161,8 @@ use std::collections::HashMap;
pub
fn
emit_context_with_reloc
(
vm
:
&
VM
,
symbols
:
HashMap
<
Address
,
MuName
>
,
fields
:
HashMap
<
Address
,
MuName
>
fields
:
HashMap
<
Address
,
MuName
>
,
primordial_threadlocal
:
Option
<
Address
>
)
{
// creates emit directy, and file
debug!
(
"---Emit VM Context---"
);
...
...
@@ -4188,7 +4189,7 @@ pub fn emit_context_with_reloc(
file
.write
(
"
\t
.data
\n
"
.as_bytes
())
.unwrap
();
// persist heap - we traverse the heap from globals
{
let
primordial_threadlocal
=
{
use
runtime
::
mm
;
let
global_locs_lock
=
vm
.global_locations
()
.read
()
.unwrap
();
...
...
@@ -4314,8 +4315,13 @@ pub fn emit_context_with_reloc(
offset
+=
POINTER_SIZE
;
}
}
}
primordial_threadlocal
.map
(|
a
|
relocatable_refs
.get
(
&
a
)
.unwrap
()
.clone
())
};
{
let
mut
lock
=
vm
.primordial_threadlocal
.write
()
.unwrap
();
*
lock
=
primordial_threadlocal
;
}
// serialize vm, and put it to boot image
// currently using rustc_serialize to persist vm as json string.
// Deserializing from this is extremely slow, we need to fix this. See Issue #41
...
...
@@ -4346,7 +4352,7 @@ pub fn emit_context_with_reloc(
/// emit vm context for current session,
/// without consideration about relocation symbols/fields from the client
pub
fn
emit_context
(
vm
:
&
VM
)
{
emit_context_with_reloc
(
vm
,
hashmap!
{},
hashmap!
{});
emit_context_with_reloc
(
vm
,
hashmap!
{},
hashmap!
{}
,
None
);
}
/// writes header for a dumped object
...
...
src/compiler/backend/reg_alloc/graph_coloring/coloring.rs
View file @
71aefd55
...
...
@@ -454,6 +454,43 @@ impl<'a> GraphColoring<'a> {
}
else
{
trace!
(
"Coalescing disabled..."
);
}
trace!
(
"Build freeze cost for each node..."
);
// we try to avoid freeze a node that is involved in many moves
for
n
in
self
.ig
.nodes
()
{
// freeze_cost(n) = SUM ((spill_cost(src) + spill_cost(dst)) for m (mov src->dst)
// in movelist[n])
let
closure
=
{
let
mut
ret
=
LinkedHashSet
::
new
();
let
mut
worklist
=
LinkedHashSet
::
new
();
worklist
.insert
(
n
);
while
!
worklist
.is_empty
()
{
let
n
=
worklist
.pop_front
()
.unwrap
();
for
m
in
self
.get_movelist
(
n
)
.iter
()
{
if
!
ret
.contains
(
&
m
.from
)
{
ret
.insert
(
m
.from
);
worklist
.insert
(
m
.from
);
}
if
!
ret
.contains
(
&
m
.to
)
{
ret
.insert
(
m
.to
);
worklist
.insert
(
m
.to
);
}
}
}
ret
};
let
mut
freeze_cost
=
0f32
;
for
related_node
in
closure
.iter
()
{
freeze_cost
+=
self
.ig
.get_spill_cost
(
*
related_node
);
}
self
.ig
.set_freeze_cost
(
n
,
freeze_cost
);
trace!
(
" {} closure: {:?}"
,
n
,
closure
);
trace!
(
" freeze cost = {}"
,
freeze_cost
);
}
}
fn
make_work_list
(
&
mut
self
)
{
...
...
@@ -836,13 +873,7 @@ impl<'a> GraphColoring<'a> {
let
mut
candidate
=
None
;
let
mut
candidate_cost
=
f32
::
MAX
;
for
&
n
in
self
.worklist_freeze
.iter
()
{
// freeze_cost(n) = SUM ((spill_cost(src) + spill_cost(dst)) for m (mov src->dst)
// in movelist[n])
let
mut
freeze_cost
=
0f32
;
for
m
in
self
.get_movelist
(
n
)
.iter
()
{
freeze_cost
+=
self
.ig
.get_spill_cost
(
m
.from
);
freeze_cost
+=
self
.ig
.get_spill_cost
(
m
.to
);
}
let
freeze_cost
=
self
.ig
.get_freeze_cost
(
n
);
if
freeze_cost
<
candidate_cost
{
candidate
=
Some
(
n
);
...
...
src/compiler/backend/reg_alloc/graph_coloring/liveness.rs
View file @
71aefd55
...
...
@@ -39,7 +39,9 @@ pub struct Node {
/// temp register group (which machine register class we should assign)
group
:
backend
::
RegGroup
,
/// cost to spill this temp
spill_cost
:
f32
spill_cost
:
f32
,
/// cost to freeze this temp
freeze_cost
:
f32
}
impl
fmt
::
Debug
for
Node
{
...
...
@@ -143,7 +145,8 @@ impl InterferenceGraph {
temp
:
reg_id
,
color
:
None
,
group
:
backend
::
RegGroup
::
get_from_ty
(
entry
.ty
()),
spill_cost
:
0.0f32
spill_cost
:
0.0f32
,
freeze_cost
:
0f32
};
self
.nodes
.insert
(
reg_id
,
node
);
...
...
@@ -162,7 +165,7 @@ impl InterferenceGraph {
fn
spillcost_heuristic
(
ty
:
NodeType
,
loop_depth
:
usize
)
->
f32
{
const
DEF_WEIGHT
:
f32
=
1f32
;
const
USE_WEIGHT
:
f32
=
1f32
;
const
COPY_WEIGHT
:
f32
=
0.5
f32
;
const
COPY_WEIGHT
:
f32
=
2
f32
;
let
loop_depth
=
loop_depth
as
i32
;
...
...
@@ -284,6 +287,16 @@ impl InterferenceGraph {
self
.nodes
.get
(
&
reg
)
.unwrap
()
.spill_cost
}
/// sets the freeze cost of a node
pub
fn
set_freeze_cost
(
&
mut
self
,
reg
:
MuID
,
cost
:
f32
)
{
self
.nodes
.get_mut
(
&
reg
)
.unwrap
()
.freeze_cost
=
cost
;
}
/// gets the freeze cost of a node
pub
fn
get_freeze_cost
(
&
self
,
reg
:
MuID
)
->
f32
{
self
.nodes
.get
(
&
reg
)
.unwrap
()
.freeze_cost
}
/// are two nodes the same node?
fn
is_same_node
(
&
self
,
reg1
:
MuID
,
reg2
:
MuID
)
->
bool
{
reg1
==
reg2
...
...
src/runtime/mod.rs
View file @
71aefd55
...
...
@@ -313,8 +313,13 @@ pub extern "C" fn mu_main(
args
};
// FIXME: currently assumes no user defined thread local - See Issue #48
thread
::
MuThread
::
new_thread_normal
(
stack
,
unsafe
{
Address
::
zero
()
},
args
,
vm
.clone
());
let
threadlocal
=
vm
.primordial_threadlocal
.read
()
.unwrap
()
.as_ref
()
.map
(|
name
|
resolve_symbol
(
Arc
::
new
(
name
.clone
())))
.unwrap_or
(
unsafe
{
Address
::
zero
()
});
thread
::
MuThread
::
new_thread_normal
(
stack
,
threadlocal
,
args
,
vm
.clone
());
loop
{
let
thread
=
vm
.pop_join_handle
();
...
...
src/vm/vm.rs
View file @
71aefd55
...
...
@@ -123,6 +123,7 @@ pub struct VM {
/// a map from callsite address to CompiledCallsite
compiled_callsite_table
:
RwLock
<
HashMap
<
Address
,
CompiledCallsite
>>
,
// 896
pub
primordial_threadlocal
:
RwLock
<
Option
<
String
>>
,
/// Nnmber of callsites in the callsite tables
callsite_count
:
AtomicUsize
,
...
...
@@ -172,6 +173,7 @@ unsafe impl rodal::Dump for VM {
RwLock
::
new
(
rodal
::
EmptyHashMap
::
<
Address
,
CompiledCallsite
>
::
new
());
dumper
.dump_object_here
(
&
compiled_callsite_table
);
dumper
.dump_object
(
&
self
.primordial_threadlocal
);
dumper
.dump_object
(
&
self
.callsite_count
);
dumper
.dump_padding
(
&
self
.pending_joins
);
...
...
@@ -248,6 +250,7 @@ impl<'a> VM {
gc_id_map
:
RwLock
::
new
(
HashMap
::
new
()),
aot_pending_funcref_store
:
RwLock
::
new
(
HashMap
::
new
()),
compiled_callsite_table
:
RwLock
::
new
(
HashMap
::
new
()),
primordial_threadlocal
:
RwLock
::
new
(
None
),
callsite_count
:
ATOMIC_USIZE_INIT
,
pending_joins
:
Mutex
::
new
(
LinkedList
::
new
())
};
...
...
@@ -1178,11 +1181,6 @@ impl<'a> VM {
whitelist_funcs
};
if
primordial_threadlocal
.is_some
()
{
// we are going to need to persist this threadlocal
unimplemented!
()
}
let
has_primordial_func
=
primordial_func
.is_some
();
let
has_primordial_stack
=
primordial_stack
.is_some
();
...
...
@@ -1235,7 +1233,12 @@ impl<'a> VM {
};
// emit context (persist vm, etc)
backend
::
emit_context_with_reloc
(
self
,
symbols
,
fields
);
backend
::
emit_context_with_reloc
(
self
,
symbols
,
fields
,
primordial_threadlocal
.map
(|
x
|
x
.v
.as_ref
()
.
1
)
);
// link
self
.link_boot_image
(
whitelist_funcs
,
extra_sources_to_link
,
output_file
);
...
...
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