Skip to content

Commit 1f39198

Browse files
committed
Trying to count live blocks and live lines
1 parent bd3305f commit 1f39198

File tree

3 files changed

+65
-23
lines changed

3 files changed

+65
-23
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static_assertions = "1.1.0"
5050
strum = "0.25"
5151
strum_macros = "0.25"
5252
sysinfo = "0.29"
53+
chrono = "*"
5354

5455
[dev-dependencies]
5556
paste = "1.0.8"

src/memory_manager.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -557,13 +557,13 @@ pub fn live_bytes_in_last_gc<VM: VMBinding>(mmtk: &MMTK<VM>) -> usize {
557557
mmtk.state.live_bytes_in_last_gc.load(Ordering::SeqCst)
558558
}
559559

560-
/// Return the percentage of fragmentation of the immixspace (e.g. 42.98 percent). To do that we count the size of every live object
560+
/// Return the percentage of occupation of the immixspace (e.g. 42.98 percent). To do that we count the size of every live object
561561
/// in the immixspace. Since MMTk accounts for memory in pages, we return the ratio between this number and
562562
/// the number of used bytes (according to the used pages by the immixspace).
563563
/// The value returned by this method is only updated when we finish tracing in a GC. A recommended timing
564564
/// to call this method is at the end of a GC (e.g. when the runtime is about to resume threads).
565565
#[cfg(feature = "count_live_bytes_immixspace")]
566-
pub fn fragmentation_rate_in_immixspace<VM: VMBinding>(mmtk: &MMTK<VM>) -> f64 {
566+
pub fn occupation_rate_in_immixspace<VM: VMBinding>(mmtk: &MMTK<VM>) -> f64 {
567567
use crate::policy::immix::ImmixSpace;
568568
use crate::policy::space::Space;
569569
let mut rate = None;
@@ -575,7 +575,7 @@ pub fn fragmentation_rate_in_immixspace<VM: VMBinding>(mmtk: &MMTK<VM>) -> f64 {
575575
"There are multiple Immix spaces in the plan."
576576
);
577577
// Get the stats here from ImmixSpace
578-
rate = Some(immix.get_fragmentation_rate());
578+
rate = Some(immix.get_occupation_rate());
579579
}
580580
});
581581
rate.expect("No Immix space in the plan.") as f64 / 100.0

src/policy/immix/immixspace.rs

+61-20
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub struct ImmixSpace<VM: VMBinding> {
5858
#[cfg(feature = "count_live_bytes_immixspace")]
5959
live_bytes_in_immixspace: AtomicUsize,
6060
#[cfg(feature = "count_live_bytes_immixspace")]
61-
fragmentation_rate: AtomicUsize,
61+
occupation_rate: AtomicUsize,
6262
}
6363

6464
/// Some arguments for Immix Space.
@@ -328,7 +328,7 @@ impl<VM: VMBinding> ImmixSpace<VM> {
328328
#[cfg(feature = "count_live_bytes_immixspace")]
329329
live_bytes_in_immixspace: AtomicUsize::new(0),
330330
#[cfg(feature = "count_live_bytes_immixspace")]
331-
fragmentation_rate: AtomicUsize::new(0),
331+
occupation_rate: AtomicUsize::new(0),
332332
}
333333
}
334334

@@ -483,25 +483,66 @@ impl<VM: VMBinding> ImmixSpace<VM> {
483483

484484
// calculate the fragmentation rate
485485
#[cfg(feature = "count_live_bytes_immixspace")]
486-
{
487-
trace!("Live bytes in immixspace = {}", self.get_live_bytes());
488-
trace!("Reserved pages in immixspace = {}", self.reserved_pages());
489-
490-
trace!(
491-
"Reserved bytes in immixspace = {}",
492-
self.reserved_pages() << LOG_BYTES_IN_PAGE
493-
);
494-
let f_rate: f64 =
495-
self.get_live_bytes() as f64 / (self.reserved_pages() << LOG_BYTES_IN_PAGE) as f64;
486+
self.dump_memory_stats();
496487

497-
let f_rate_usize: usize = (f_rate * 10000.0) as usize;
488+
did_defrag
489+
}
498490

499-
debug_assert!((0.0..=1.0).contains(&f_rate));
491+
fn dump_memory_stats(&mut self) {
492+
#[derive(Default)]
493+
struct Dist {
494+
live_blocks: usize,
495+
live_lines: usize,
496+
}
497+
let mut dist = Dist::default();
498+
for chunk in self.chunk_map.all_chunks() {
499+
if !self.address_in_space(chunk.start()) {
500+
continue;
501+
}
500502

501-
self.set_fragmentation_rate(f_rate_usize);
503+
for block in chunk
504+
.iter_region::<Block>()
505+
.filter(|b| b.get_state() != BlockState::Unallocated)
506+
{
507+
dist.live_blocks += 1;
508+
for _line in block
509+
.lines()
510+
.filter(|l| l.is_marked(self.line_mark_state.load(Ordering::Acquire)))
511+
{
512+
dist.live_lines = 1;
513+
}
514+
}
502515
}
503516

504-
did_defrag
517+
println!(
518+
"{} immixspace",
519+
chrono::offset::Local::now().format("%Y-%m-%d %H:%M:%S")
520+
);
521+
println!("Live bytes = {}", self.get_live_bytes());
522+
println!("Reserved pages = {}", self.reserved_pages());
523+
println!(
524+
"Reserved pages (bytes) = {}",
525+
self.reserved_pages() << LOG_BYTES_IN_PAGE
526+
);
527+
println!("Live blocks = {}", dist.live_blocks);
528+
println!(
529+
"Live blocks (bytes) = {}",
530+
dist.live_blocks << Block::LOG_BYTES
531+
);
532+
println!("Live lines = {}", dist.live_lines);
533+
println!(
534+
"Live lines (bytes) = {}",
535+
dist.live_lines << Line::LOG_BYTES
536+
);
537+
538+
let o_rate: f64 =
539+
self.get_live_bytes() as f64 / (self.reserved_pages() << LOG_BYTES_IN_PAGE) as f64;
540+
541+
let o_rate_usize: usize = (o_rate * 10000.0) as usize;
542+
543+
debug_assert!((0.0..=1.0).contains(&o_rate));
544+
545+
self.set_occupation_rate(o_rate_usize);
505546
}
506547

507548
/// Generate chunk sweep tasks
@@ -862,13 +903,13 @@ impl<VM: VMBinding> ImmixSpace<VM> {
862903
}
863904

864905
#[cfg(feature = "count_live_bytes_immixspace")]
865-
pub fn get_fragmentation_rate(&self) -> usize {
866-
self.fragmentation_rate.load(Ordering::SeqCst)
906+
pub fn get_occupation_rate(&self) -> usize {
907+
self.occupation_rate.load(Ordering::SeqCst)
867908
}
868909

869910
#[cfg(feature = "count_live_bytes_immixspace")]
870-
pub fn set_fragmentation_rate(&self, size: usize) {
871-
self.fragmentation_rate.store(size, Ordering::SeqCst);
911+
pub fn set_occupation_rate(&self, size: usize) {
912+
self.occupation_rate.store(size, Ordering::SeqCst);
872913
}
873914
}
874915

0 commit comments

Comments
 (0)