mmtk/policy/immix/
line.rs1use std::ops::Range;
2
3use super::block::Block;
4use crate::util::linear_scan::{Region, RegionIterator};
5use crate::util::metadata::side_metadata::SideMetadataSpec;
6use crate::{
7 util::{Address, ObjectReference},
8 vm::*,
9};
10
11#[repr(transparent)]
13#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Eq)]
14pub struct Line(Address);
15
16impl Region for Line {
17 const LOG_BYTES: usize = 8;
18
19 #[allow(clippy::assertions_on_constants)] fn from_aligned_address(address: Address) -> Self {
21 debug_assert!(!super::BLOCK_ONLY);
22 debug_assert!(address.is_aligned_to(Self::BYTES));
23 Self(address)
24 }
25
26 fn start(&self) -> Address {
27 self.0
28 }
29}
30
31#[allow(clippy::assertions_on_constants)]
32impl Line {
33 pub const RESET_MARK_STATE: u8 = 1;
34 pub const MAX_MARK_STATE: u8 = 127;
35
36 pub const MARK_TABLE: SideMetadataSpec =
38 crate::util::metadata::side_metadata::spec_defs::IX_LINE_MARK;
39
40 pub fn block(&self) -> Block {
42 debug_assert!(!super::BLOCK_ONLY);
43 Block::from_unaligned_address(self.0)
44 }
45
46 pub fn get_index_within_block(&self) -> usize {
48 let addr = self.start();
49 addr.get_extent(Block::align(addr)) >> Line::LOG_BYTES
50 }
51
52 pub fn mark(&self, state: u8) {
54 debug_assert!(!super::BLOCK_ONLY);
55 unsafe {
56 Self::MARK_TABLE.store::<u8>(self.start(), state);
57 }
58 }
59
60 pub fn is_marked(&self, state: u8) -> bool {
62 debug_assert!(!super::BLOCK_ONLY);
63 unsafe { Self::MARK_TABLE.load::<u8>(self.start()) == state }
64 }
65
66 pub fn mark_lines_for_object<VM: VMBinding>(object: ObjectReference, state: u8) -> usize {
68 debug_assert!(!super::BLOCK_ONLY);
69 let start = object.to_object_start::<VM>();
70 let end = start + VM::VMObjectModel::get_current_size(object);
71 let start_line = Line::from_unaligned_address(start);
72 let mut end_line = Line::from_unaligned_address(end);
73 if !Line::is_aligned(end) {
74 end_line = end_line.next();
75 }
76 let mut marked_lines = 0;
77 let iter = RegionIterator::<Line>::new(start_line, end_line);
78 for line in iter {
79 if !line.is_marked(state) {
80 marked_lines += 1;
81 }
82 line.mark(state)
83 }
84 marked_lines
85 }
86
87 pub fn initialize_mark_table_as_marked<VM: VMBinding>(lines: Range<Line>) {
93 let meta = VM::VMObjectModel::LOCAL_MARK_BIT_SPEC.extract_side_spec();
94 let start = lines.start.start();
95 let limit = lines.end.start();
96 let size = limit - start;
97 meta.bset_metadata(start, size);
98 }
99
100 pub fn bulk_set_line_mark_states(line_mark_state: u8, lines: Range<Line>) {
102 for line in RegionIterator::<Line>::new(lines.start, lines.end) {
103 line.mark(line_mark_state);
104 }
105 }
106
107 pub fn eager_mark_lines<VM: VMBinding>(line_mark_state: u8, lines: Range<Line>) {
111 Self::bulk_set_line_mark_states(line_mark_state, lines.clone());
112 Self::initialize_mark_table_as_marked::<VM>(lines);
113 }
114}