pvmfw: Use tinyvec::ArrayVec in MemoryTracker

Instead of a DIY implementation, make use of the crate-provided struct.

Test: atest MicrodroidTestApp
Change-Id: I19418245f990a4be2300890767a1004e21b48ee7
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index 455b214..b78e077 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -17,6 +17,7 @@
         "liblibfdt",
         "liblog_rust_nostd",
         "libpvmfw_embedded_key",
+        "libtinyvec_nostd",
         "libvmbase",
     ],
     static_libs: [
diff --git a/pvmfw/src/memory.rs b/pvmfw/src/memory.rs
index 0f1892d..ca0b886 100644
--- a/pvmfw/src/memory.rs
+++ b/pvmfw/src/memory.rs
@@ -19,22 +19,22 @@
 use core::cmp::max;
 use core::cmp::min;
 use core::fmt;
-use core::mem;
-use core::mem::MaybeUninit;
 use core::num::NonZeroUsize;
 use core::ops::Range;
 use core::result;
 use log::error;
+use tinyvec::ArrayVec;
 
 type MemoryRange = Range<usize>;
 
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, Default)]
 enum MemoryType {
+    #[default]
     ReadOnly,
     ReadWrite,
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, Default)]
 struct MemoryRegion {
     range: MemoryRange,
     mem_type: MemoryType,
@@ -62,9 +62,7 @@
 
 /// Tracks non-overlapping slices of main memory.
 pub struct MemoryTracker {
-    // TODO: Use tinyvec::ArrayVec
-    count: usize,
-    regions: [MaybeUninit<MemoryRegion>; MemoryTracker::CAPACITY],
+    regions: ArrayVec<[MemoryRegion; MemoryTracker::CAPACITY]>,
     total: MemoryRange,
     page_table: mmu::PageTable,
 }
@@ -113,13 +111,7 @@
 
     /// Create a new instance from an active page table, covering the maximum RAM size.
     pub fn new(page_table: mmu::PageTable) -> Self {
-        Self {
-            total: Self::BASE..Self::MAX_ADDR,
-            count: 0,
-            page_table,
-            // SAFETY - MaybeUninit items (of regions) do not require initialization.
-            regions: unsafe { MaybeUninit::uninit().assume_init() },
-        }
+        Self { total: Self::BASE..Self::MAX_ADDR, page_table, regions: ArrayVec::new() }
     }
 
     /// Resize the total RAM size.
@@ -132,7 +124,7 @@
         if self.total.end < range.end {
             return Err(MemoryTrackerError::SizeTooLarge);
         }
-        if !self.regions().iter().all(|r| r.is_within(range)) {
+        if !self.regions.iter().all(|r| r.is_within(range)) {
             return Err(MemoryTrackerError::SizeTooSmall);
         }
 
@@ -168,31 +160,24 @@
         self.alloc_range_mut(&(base..(base + size.get())))
     }
 
-    fn regions(&self) -> &[MemoryRegion] {
-        // SAFETY - The first self.count regions have been properly initialized.
-        unsafe { mem::transmute::<_, &[MemoryRegion]>(&self.regions[..self.count]) }
-    }
-
     fn add(&mut self, region: MemoryRegion) -> Result<MemoryRange> {
         if !region.is_within(&self.total) {
             return Err(MemoryTrackerError::OutOfRange);
         }
-        if self.regions().iter().any(|r| r.overlaps(region.as_ref())) {
+        if self.regions.iter().any(|r| r.overlaps(region.as_ref())) {
             return Err(MemoryTrackerError::Overlaps);
         }
-        if self.regions.len() == self.count {
+        if self.regions.try_push(region).is_some() {
             return Err(MemoryTrackerError::Full);
         }
 
-        let region = self.regions[self.count].write(region);
-        self.count += 1;
-        Ok(region.as_ref().clone())
+        Ok(self.regions.last().unwrap().as_ref().clone())
     }
 }
 
 impl Drop for MemoryTracker {
     fn drop(&mut self) {
-        for region in self.regions().iter() {
+        for region in self.regions.iter() {
             match region.mem_type {
                 MemoryType::ReadWrite => {
                     // TODO: Use page table's dirty bit to only flush pages that were touched.