about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2023-09-20 07:54:27 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2023-09-28 17:58:54 +1000
commit55a1a5223a0930df1cf98c0ea759d15700da9e5d (patch)
treeda480202b13a0cb7dbbb452c583138876dec9c02 /compiler
parent25407bc0bb2fd4aa2c1a37c81a72084160d097fd (diff)
downloadrust-55a1a5223a0930df1cf98c0ea759d15700da9e5d.tar.gz
rust-55a1a5223a0930df1cf98c0ea759d15700da9e5d.zip
Reduce `grow_and_alloc_raw` to a single call site.
The current structure is clumsy, calling `alloc_raw_without_grow` in one
function, and then if that fails, calling another function that calls
`alloc_raw_without_grow` again.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_arena/src/lib.rs24
1 files changed, 12 insertions, 12 deletions
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index fae147e98b1..73ce5fed93d 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -412,6 +412,8 @@ impl Default for DroplessArena {
 }
 
 impl DroplessArena {
+    #[inline(never)]
+    #[cold]
     fn grow(&self, layout: Layout) {
         // Add some padding so we can align `self.end` while
         // still fitting in a `layout` allocation.
@@ -451,13 +453,6 @@ impl DroplessArena {
         }
     }
 
-    #[inline(never)]
-    #[cold]
-    fn grow_and_alloc_raw(&self, layout: Layout) -> *mut u8 {
-        self.grow(layout);
-        self.alloc_raw_without_grow(layout).unwrap()
-    }
-
     /// Allocates a byte slice with specified layout from the current memory
     /// chunk. Returns `None` if there is no free space left to satisfy the
     /// request.
@@ -488,12 +483,17 @@ impl DroplessArena {
     #[inline]
     pub fn alloc_raw(&self, layout: Layout) -> *mut u8 {
         assert!(layout.size() != 0);
-        if let Some(a) = self.alloc_raw_without_grow(layout) {
-            return a;
+
+        // This loop executes once or twice: if allocation fails the first
+        // time, the `grow` ensures it will succeed the second time.
+        loop {
+            if let Some(a) = self.alloc_raw_without_grow(layout) {
+                return a;
+            }
+            // No free space left. Allocate a new chunk to satisfy the request.
+            // On failure the grow will panic or abort.
+            self.grow(layout);
         }
-        // No free space left. Allocate a new chunk to satisfy the request.
-        // On failure the grow will panic or abort.
-        self.grow_and_alloc_raw(layout)
     }
 
     #[inline]