about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Chugunov <vadimcn@gmail.com>2014-07-05 00:42:58 -0700
committerVadim Chugunov <vadimcn@gmail.com>2014-08-04 17:43:47 -0700
commitbf420e58c2f88c8f37f83aaf947e7abba1cd7f79 (patch)
tree9fd15b4d8c3981d6aa9fe61ffcc23c9aa5199def
parent862ba430c5bc1ba9e47644d2a75a6091842c53d0 (diff)
downloadrust-bf420e58c2f88c8f37f83aaf947e7abba1cd7f79.tar.gz
rust-bf420e58c2f88c8f37f83aaf947e7abba1cd7f79.zip
Ensure that Registers struct is 16-byte aligned on x86_64.
This is important when building with --disable-jemalloc: unlike jemalloc,  msvcrt does not align on 16 bytes unless asked to.
-rw-r--r--src/libgreen/context.rs40
1 files changed, 29 insertions, 11 deletions
diff --git a/src/libgreen/context.rs b/src/libgreen/context.rs
index 8c60f3d9fe1..45f41181bf8 100644
--- a/src/libgreen/context.rs
+++ b/src/libgreen/context.rs
@@ -13,6 +13,8 @@ use std::uint;
 use std::mem::transmute;
 use std::rt::stack;
 use std::raw;
+#[cfg(target_arch = "x86_64")]
+use std::simd;
 
 // FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
 // SSE regs.  It would be marginally better not to do this. In C++ we
@@ -186,14 +188,30 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
 // windows requires saving more registers (both general and XMM), so the windows
 // register context must be larger.
 #[cfg(windows, target_arch = "x86_64")]
-type Registers = [uint, ..34];
+struct Registers {
+    gpr:[uint, ..14],
+    _xmm:[simd::u32x4, ..10]
+}
 #[cfg(not(windows), target_arch = "x86_64")]
-type Registers = [uint, ..22];
+struct Registers {
+    gpr:[uint, ..10],
+    _xmm:[simd::u32x4, ..6]
+}
 
 #[cfg(windows, target_arch = "x86_64")]
-fn new_regs() -> Box<Registers> { box() ([0, .. 34]) }
+fn new_regs() -> Box<Registers> {
+    box() Registers {
+        gpr:[0,..14],
+        _xmm:[simd::u32x4(0,0,0,0),..10]
+    }
+}
 #[cfg(not(windows), target_arch = "x86_64")]
-fn new_regs() -> Box<Registers> { box() ([0, .. 22]) }
+fn new_regs() -> Box<Registers> {
+    box() Registers {
+        gpr:[0,..10],
+        _xmm:[simd::u32x4(0,0,0,0),..6]
+    }
+}
 
 #[cfg(target_arch = "x86_64")]
 fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
@@ -222,20 +240,20 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
 
     // These registers are frobbed by rust_bootstrap_green_task into the right
     // location so we can invoke the "real init function", `fptr`.
-    regs[RUSTRT_R12] = arg as uint;
-    regs[RUSTRT_R13] = procedure.code as uint;
-    regs[RUSTRT_R14] = procedure.env as uint;
-    regs[RUSTRT_R15] = fptr as uint;
+    regs.gpr[RUSTRT_R12] = arg as uint;
+    regs.gpr[RUSTRT_R13] = procedure.code as uint;
+    regs.gpr[RUSTRT_R14] = procedure.env as uint;
+    regs.gpr[RUSTRT_R15] = fptr as uint;
 
     // These registers are picked up by the regular context switch paths. These
     // will put us in "mostly the right context" except for frobbing all the
     // arguments to the right place. We have the small trampoline code inside of
     // rust_bootstrap_green_task to do that.
-    regs[RUSTRT_RSP] = sp as uint;
-    regs[RUSTRT_IP] = rust_bootstrap_green_task as uint;
+    regs.gpr[RUSTRT_RSP] = sp as uint;
+    regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as uint;
 
     // Last base pointer on the stack should be 0
-    regs[RUSTRT_RBP] = 0;
+    regs.gpr[RUSTRT_RBP] = 0;
 }
 
 #[cfg(target_arch = "arm")]