Skip to content

Commit 927f3ac

Browse files
authored
Merge pull request #464 from Freax13/enhancement/inline-step-functions
miscellaneous improvements
2 parents b62d1d9 + a0f6b62 commit 927f3ac

File tree

3 files changed

+66
-16
lines changed

3 files changed

+66
-16
lines changed

src/addr.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,15 @@ impl VirtAddr {
177177
where
178178
U: Into<u64>,
179179
{
180-
VirtAddr::new_truncate(align_down(self.0, align.into()))
180+
self.align_down_u64(align.into())
181+
}
182+
183+
/// Aligns the virtual address downwards to the given alignment.
184+
///
185+
/// See the `align_down` function for more information.
186+
#[inline]
187+
pub(crate) const fn align_down_u64(self, align: u64) -> Self {
188+
VirtAddr::new_truncate(align_down(self.0, align))
181189
}
182190

183191
/// Checks whether the virtual address has the demanded alignment.
@@ -186,7 +194,13 @@ impl VirtAddr {
186194
where
187195
U: Into<u64>,
188196
{
189-
self.align_down(align) == self
197+
self.is_aligned_u64(align.into())
198+
}
199+
200+
/// Checks whether the virtual address has the demanded alignment.
201+
#[inline]
202+
pub(crate) const fn is_aligned_u64(self, align: u64) -> bool {
203+
self.align_down_u64(align).as_u64() == self.as_u64()
190204
}
191205

192206
/// Returns the 12-bit page offset of this virtual address.
@@ -236,6 +250,7 @@ impl VirtAddr {
236250
}
237251

238252
// FIXME: Move this into the `Step` impl, once `Step` is stabilized.
253+
#[inline]
239254
pub(crate) fn forward_checked_impl(start: Self, count: usize) -> Option<Self> {
240255
let offset = u64::try_from(count).ok()?;
241256
if offset > ADDRESS_SPACE_SIZE {
@@ -343,14 +358,17 @@ impl Sub<VirtAddr> for VirtAddr {
343358

344359
#[cfg(feature = "step_trait")]
345360
impl Step for VirtAddr {
361+
#[inline]
346362
fn steps_between(start: &Self, end: &Self) -> Option<usize> {
347363
Self::steps_between_impl(start, end)
348364
}
349365

366+
#[inline]
350367
fn forward_checked(start: Self, count: usize) -> Option<Self> {
351368
Self::forward_checked_impl(start, count)
352369
}
353370

371+
#[inline]
354372
fn backward_checked(start: Self, count: usize) -> Option<Self> {
355373
let offset = u64::try_from(count).ok()?;
356374
if offset > ADDRESS_SPACE_SIZE {

src/structures/paging/page.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ impl<S: PageSize> Page<S> {
7777
///
7878
/// Returns an error if the address is not correctly aligned (i.e. is not a valid page start).
7979
#[inline]
80+
#[rustversion::attr(since(1.61), const)]
8081
pub fn from_start_address(address: VirtAddr) -> Result<Self, AddressNotAligned> {
81-
if !address.is_aligned(S::SIZE) {
82+
if !address.is_aligned_u64(S::SIZE) {
8283
return Err(AddressNotAligned);
8384
}
8485
Ok(Page::containing_address(address))
@@ -100,9 +101,10 @@ impl<S: PageSize> Page<S> {
100101

101102
/// Returns the page that contains the given virtual address.
102103
#[inline]
104+
#[rustversion::attr(since(1.61), const)]
103105
pub fn containing_address(address: VirtAddr) -> Self {
104106
Page {
105-
start_address: address.align_down(S::SIZE),
107+
start_address: address.align_down_u64(S::SIZE),
106108
size: PhantomData,
107109
}
108110
}
@@ -185,47 +187,50 @@ impl<S: NotGiantPageSize> Page<S> {
185187
impl Page<Size1GiB> {
186188
/// Returns the 1GiB memory page with the specified page table indices.
187189
#[inline]
190+
#[rustversion::attr(since(1.61), const)]
188191
pub fn from_page_table_indices_1gib(
189192
p4_index: PageTableIndex,
190193
p3_index: PageTableIndex,
191194
) -> Self {
192195
let mut addr = 0;
193-
addr |= u64::from(p4_index) << 39;
194-
addr |= u64::from(p3_index) << 30;
196+
addr |= p4_index.into_u64() << 39;
197+
addr |= p3_index.into_u64() << 30;
195198
Page::containing_address(VirtAddr::new_truncate(addr))
196199
}
197200
}
198201

199202
impl Page<Size2MiB> {
200203
/// Returns the 2MiB memory page with the specified page table indices.
201204
#[inline]
205+
#[rustversion::attr(since(1.61), const)]
202206
pub fn from_page_table_indices_2mib(
203207
p4_index: PageTableIndex,
204208
p3_index: PageTableIndex,
205209
p2_index: PageTableIndex,
206210
) -> Self {
207211
let mut addr = 0;
208-
addr |= u64::from(p4_index) << 39;
209-
addr |= u64::from(p3_index) << 30;
210-
addr |= u64::from(p2_index) << 21;
212+
addr |= p4_index.into_u64() << 39;
213+
addr |= p3_index.into_u64() << 30;
214+
addr |= p2_index.into_u64() << 21;
211215
Page::containing_address(VirtAddr::new_truncate(addr))
212216
}
213217
}
214218

215219
impl Page<Size4KiB> {
216220
/// Returns the 4KiB memory page with the specified page table indices.
217221
#[inline]
222+
#[rustversion::attr(since(1.61), const)]
218223
pub fn from_page_table_indices(
219224
p4_index: PageTableIndex,
220225
p3_index: PageTableIndex,
221226
p2_index: PageTableIndex,
222227
p1_index: PageTableIndex,
223228
) -> Self {
224229
let mut addr = 0;
225-
addr |= u64::from(p4_index) << 39;
226-
addr |= u64::from(p3_index) << 30;
227-
addr |= u64::from(p2_index) << 21;
228-
addr |= u64::from(p1_index) << 12;
230+
addr |= p4_index.into_u64() << 39;
231+
addr |= p3_index.into_u64() << 30;
232+
addr |= p2_index.into_u64() << 21;
233+
addr |= p1_index.into_u64() << 12;
229234
Page::containing_address(VirtAddr::new_truncate(addr))
230235
}
231236

src/structures/paging/page_table.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Abstractions for page tables and page table entries.
22
33
use core::fmt;
4+
#[cfg(feature = "step_trait")]
5+
use core::iter::Step;
46
use core::ops::{Index, IndexMut};
57

68
use super::{PageSize, PhysFrame, Size4KiB};
@@ -296,8 +298,8 @@ pub struct PageTableIndex(u16);
296298
impl PageTableIndex {
297299
/// Creates a new index from the given `u16`. Panics if the given value is >=512.
298300
#[inline]
299-
pub fn new(index: u16) -> Self {
300-
assert!(usize::from(index) < ENTRY_COUNT);
301+
pub const fn new(index: u16) -> Self {
302+
assert!((index as usize) < ENTRY_COUNT);
301303
Self(index)
302304
}
303305

@@ -306,6 +308,11 @@ impl PageTableIndex {
306308
pub const fn new_truncate(index: u16) -> Self {
307309
Self(index % ENTRY_COUNT as u16)
308310
}
311+
312+
#[inline]
313+
pub(crate) const fn into_u64(self) -> u64 {
314+
self.0 as u64
315+
}
309316
}
310317

311318
impl From<PageTableIndex> for u16 {
@@ -325,7 +332,7 @@ impl From<PageTableIndex> for u32 {
325332
impl From<PageTableIndex> for u64 {
326333
#[inline]
327334
fn from(index: PageTableIndex) -> Self {
328-
u64::from(index.0)
335+
index.into_u64()
329336
}
330337
}
331338

@@ -336,6 +343,26 @@ impl From<PageTableIndex> for usize {
336343
}
337344
}
338345

346+
#[cfg(feature = "step_trait")]
347+
impl Step for PageTableIndex {
348+
#[inline]
349+
fn steps_between(start: &Self, end: &Self) -> Option<usize> {
350+
end.0.checked_sub(start.0).map(usize::from)
351+
}
352+
353+
#[inline]
354+
fn forward_checked(start: Self, count: usize) -> Option<Self> {
355+
let idx = usize::from(start).checked_add(count)?;
356+
(idx < ENTRY_COUNT).then(|| Self::new(idx as u16))
357+
}
358+
359+
#[inline]
360+
fn backward_checked(start: Self, count: usize) -> Option<Self> {
361+
let idx = usize::from(start).checked_sub(count)?;
362+
Some(Self::new(idx as u16))
363+
}
364+
}
365+
339366
/// A 12-bit offset into a 4KiB Page.
340367
///
341368
/// This type is returned by the `VirtAddr::page_offset` method.

0 commit comments

Comments
 (0)