about summary refs log tree commit diff
path: root/src/liballoc_system
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2018-04-04 18:43:28 +0200
committerSimon Sapin <simon.sapin@exyr.org>2018-04-12 22:53:14 +0200
commitc033f1ff5f29ecac41dee668e373c9fc870f2d43 (patch)
treeae3664c9a4cd8e67dbc8016cc3df83b7770134b7 /src/liballoc_system
parent747cc749430d66bd2fca8e81fd8a1c994e36dcf1 (diff)
downloadrust-c033f1ff5f29ecac41dee668e373c9fc870f2d43.tar.gz
rust-c033f1ff5f29ecac41dee668e373c9fc870f2d43.zip
Move platform-specific OOM handling to functions
Diffstat (limited to 'src/liballoc_system')
-rw-r--r--src/liballoc_system/lib.rs131
1 files changed, 58 insertions, 73 deletions
diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs
index 6ffbd029281..8cb5c5d5be9 100644
--- a/src/liballoc_system/lib.rs
+++ b/src/liballoc_system/lib.rs
@@ -224,40 +224,7 @@ mod platform {
         alloc_methods_based_on_global_alloc!();
 
         fn oom(&mut self) -> ! {
-            use core::fmt::{self, Write};
-
-            // Print a message to stderr before aborting to assist with
-            // debugging. It is critical that this code does not allocate any
-            // memory since we are in an OOM situation. Any errors are ignored
-            // while printing since there's nothing we can do about them and we
-            // are about to exit anyways.
-            drop(writeln!(Stderr, "fatal runtime error: {}", AllocErr));
-            unsafe {
-                ::core::intrinsics::abort();
-            }
-
-            struct Stderr;
-
-            impl Write for Stderr {
-                #[cfg(target_os = "cloudabi")]
-                fn write_str(&mut self, _: &str) -> fmt::Result {
-                    // CloudABI does not have any reserved file descriptor
-                    // numbers. We should not attempt to write to file
-                    // descriptor #2, as it may be associated with any kind of
-                    // resource.
-                    Ok(())
-                }
-
-                #[cfg(not(target_os = "cloudabi"))]
-                fn write_str(&mut self, s: &str) -> fmt::Result {
-                    unsafe {
-                        libc::write(libc::STDERR_FILENO,
-                                    s.as_ptr() as *const libc::c_void,
-                                    s.len());
-                    }
-                    Ok(())
-                }
-            }
+            ::oom()
         }
     }
 
@@ -301,8 +268,6 @@ mod platform {
 #[cfg(windows)]
 #[allow(bad_style)]
 mod platform {
-    use core::ptr;
-
     use MIN_ALIGN;
     use System;
     use core::alloc::{GlobalAlloc, Alloc, Void, AllocErr, Layout, CannotReallocInPlace};
@@ -312,10 +277,6 @@ mod platform {
     type SIZE_T = usize;
     type DWORD = u32;
     type BOOL = i32;
-    type LPDWORD = *mut DWORD;
-    type LPOVERLAPPED = *mut u8;
-
-    const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
 
     extern "system" {
         fn GetProcessHeap() -> HANDLE;
@@ -323,20 +284,12 @@ mod platform {
         fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
         fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
         fn GetLastError() -> DWORD;
-        fn WriteFile(hFile: HANDLE,
-                     lpBuffer: LPVOID,
-                     nNumberOfBytesToWrite: DWORD,
-                     lpNumberOfBytesWritten: LPDWORD,
-                     lpOverlapped: LPOVERLAPPED)
-                     -> BOOL;
-        fn GetStdHandle(which: DWORD) -> HANDLE;
     }
 
     #[repr(C)]
     struct Header(*mut u8);
 
     const HEAP_ZERO_MEMORY: DWORD = 0x00000008;
-    const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010;
 
     unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
         &mut *(ptr as *mut Header).offset(-1)
@@ -438,31 +391,7 @@ mod platform {
         }
 
         fn oom(&mut self) -> ! {
-            use core::fmt::{self, Write};
-
-            // Same as with unix we ignore all errors here
-            drop(writeln!(Stderr, "fatal runtime error: {}", AllocErr));
-            unsafe {
-                ::core::intrinsics::abort();
-            }
-
-            struct Stderr;
-
-            impl Write for Stderr {
-                fn write_str(&mut self, s: &str) -> fmt::Result {
-                    unsafe {
-                        // WriteFile silently fails if it is passed an invalid
-                        // handle, so there is no need to check the result of
-                        // GetStdHandle.
-                        WriteFile(GetStdHandle(STD_ERROR_HANDLE),
-                                  s.as_ptr() as LPVOID,
-                                  s.len() as DWORD,
-                                  ptr::null_mut(),
-                                  ptr::null_mut());
-                    }
-                    Ok(())
-                }
-            }
+            ::oom()
         }
     }
 }
@@ -522,3 +451,59 @@ mod platform {
         alloc_methods_based_on_global_alloc!();
     }
 }
+
+fn oom() -> ! {
+    write_to_stderr("fatal runtime error: memory allocation failed");
+    unsafe {
+        ::core::intrinsics::abort();
+    }
+}
+
+#[cfg(any(unix, target_os = "redox"))]
+fn write_to_stderr(s: &str) {
+    extern crate libc;
+
+    unsafe {
+        libc::write(libc::STDERR_FILENO,
+                    s.as_ptr() as *const libc::c_void,
+                    s.len());
+    }
+}
+
+#[cfg(windows)]
+fn write_to_stderr(s: &str) {
+    use core::ptr;
+
+    type LPVOID = *mut u8;
+    type HANDLE = LPVOID;
+    type DWORD = u32;
+    type BOOL = i32;
+    type LPDWORD = *mut DWORD;
+    type LPOVERLAPPED = *mut u8;
+
+    const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
+
+    extern "system" {
+        fn WriteFile(hFile: HANDLE,
+                     lpBuffer: LPVOID,
+                     nNumberOfBytesToWrite: DWORD,
+                     lpNumberOfBytesWritten: LPDWORD,
+                     lpOverlapped: LPOVERLAPPED)
+                     -> BOOL;
+        fn GetStdHandle(which: DWORD) -> HANDLE;
+    }
+
+    unsafe {
+        // WriteFile silently fails if it is passed an invalid
+        // handle, so there is no need to check the result of
+        // GetStdHandle.
+        WriteFile(GetStdHandle(STD_ERROR_HANDLE),
+                  s.as_ptr() as LPVOID,
+                  s.len() as DWORD,
+                  ptr::null_mut(),
+                  ptr::null_mut());
+    }
+}
+
+#[cfg(not(any(windows, unix, target_os = "redox")))]
+fn write_to_stderr(_: &str) {}