From 862ba430c5bc1ba9e47644d2a75a6091842c53d0 Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Sat, 5 Jul 2014 01:02:53 -0700
Subject: [PATCH 01/11] Fix valgrind.h for Win64. _WIN32 is defined for 64-bit
 builds as well, so test for _WIN64 first.

---
 src/rt/valgrind/valgrind.h | 61 +++++++++++++++++++-------------------
 1 file changed, 31 insertions(+), 30 deletions(-)

diff --git a/src/rt/valgrind/valgrind.h b/src/rt/valgrind/valgrind.h
index 3c2098cd7bd76..af01dfd71a71c 100644
--- a/src/rt/valgrind/valgrind.h
+++ b/src/rt/valgrind/valgrind.h
@@ -21,16 +21,16 @@
    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
 
-   2. The origin of this software must not be misrepresented; you must 
-      not claim that you wrote the original software.  If you use this 
-      software in a product, an acknowledgment in the product 
+   2. The origin of this software must not be misrepresented; you must
+      not claim that you wrote the original software.  If you use this
+      software in a product, an acknowledgment in the product
       documentation would be appreciated but is not required.
 
    3. Altered source versions must be plainly marked as such, and must
       not be misrepresented as being the original software.
 
-   4. The name of the author may not be used to endorse or promote 
-      products derived from this software without specific prior written 
+   4. The name of the author may not be used to endorse or promote
+      products derived from this software without specific prior written
       permission.
 
    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
@@ -52,13 +52,13 @@
    the terms of the GNU General Public License, version 2.  See the
    COPYING file in the source distribution for details.
 
-   ---------------------------------------------------------------- 
+   ----------------------------------------------------------------
 */
 
 
 /* This file is for inclusion into client (your!) code.
 
-   You can use these macros to manipulate and query Valgrind's 
+   You can use these macros to manipulate and query Valgrind's
    execution inside your own programs.
 
    The resulting executables will still run without Valgrind, just a
@@ -126,11 +126,11 @@
 #  define PLAT_x86_darwin 1
 #elif defined(__APPLE__) && defined(__x86_64__)
 #  define PLAT_amd64_darwin 1
+#elif defined(__MINGW64__) || (defined(_WIN64) && defined(_M_X64))
+#  define PLAT_amd64_win64 1
 #elif defined(__MINGW32__) || defined(__CYGWIN32__) \
       || (defined(_WIN32) && defined(_M_IX86))
 #  define PLAT_x86_win32 1
-#elif defined(__MINGW64__) || (defined(_WIN64) && defined(_M_X64))
-#  define PLAT_amd64_win64 1
 #elif defined(__linux__) && defined(__i386__)
 #  define PLAT_x86_linux 1
 #elif defined(__linux__) && defined(__x86_64__)
@@ -214,8 +214,8 @@
    this is executed not under Valgrind.  Args are passed in a memory
    block, and so there's no intrinsic limit to the number that could
    be passed, but it's currently five.
-   
-   The macro args are: 
+
+   The macro args are:
       _zzq_rlval    result lvalue
       _zzq_default  default value (result returned when running on real CPU)
       _zzq_request  request code
@@ -242,7 +242,7 @@
     ||  (defined(PLAT_x86_win32) && defined(__GNUC__))
 
 typedef
-   struct { 
+   struct {
       unsigned int nraddr; /* where's the code? */
    }
    OrigFn;
@@ -306,7 +306,7 @@ typedef
 #if defined(PLAT_x86_win32) && !defined(__GNUC__)
 
 typedef
-   struct { 
+   struct {
       unsigned int nraddr; /* where's the code? */
    }
    OrigFn;
@@ -374,12 +374,13 @@ valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
 
 #endif /* PLAT_x86_win32 */
 
-/* ------------------------ amd64-{linux,darwin} --------------- */
+/* -------------------- amd64-{linux,darwin,win64} ------------- */
 
-#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
+#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin) \
+    || defined(PLAT_amd64_win64)
 
 typedef
-   struct { 
+   struct {
       unsigned long long int nraddr; /* where's the code? */
    }
    OrigFn;
@@ -443,7 +444,7 @@ typedef
 #if defined(PLAT_ppc32_linux)
 
 typedef
-   struct { 
+   struct {
       unsigned int nraddr; /* where's the code? */
    }
    OrigFn;
@@ -512,7 +513,7 @@ typedef
 #if defined(PLAT_ppc64_linux)
 
 typedef
-   struct { 
+   struct {
       unsigned long long int nraddr; /* where's the code? */
       unsigned long long int r2;  /* what tocptr do we need? */
    }
@@ -591,7 +592,7 @@ typedef
 #if defined(PLAT_arm_linux)
 
 typedef
-   struct { 
+   struct {
       unsigned int nraddr; /* where's the code? */
    }
    OrigFn;
@@ -736,7 +737,7 @@ typedef
 #if defined(PLAT_mips32_linux)
 
 typedef
-   struct { 
+   struct {
       unsigned int nraddr; /* where's the code? */
    }
    OrigFn;
@@ -750,7 +751,7 @@ typedef
                      "srl $0, $0, 29\n\t"       \
                      "srl $0, $0, 3\n\t"        \
                      "srl $0, $0, 19\n\t"
-                    
+
 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                                \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
@@ -1999,7 +2000,7 @@ typedef
 #define VALGRIND_RESTORE_STACK             \
       "mr 1,28\n\t"
 
-/* These CALL_FN_ macros assume that on ppc32-linux, 
+/* These CALL_FN_ macros assume that on ppc32-linux,
    sizeof(unsigned long) == 4. */
 
 #define CALL_FN_W_v(lval, orig)                                   \
@@ -3509,7 +3510,7 @@ typedef
 #define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
                            "f0","f1","f2","f3","f4","f5","f6","f7"
 
-/* Nb: Although r11 is modified in the asm snippets below (inside 
+/* Nb: Although r11 is modified in the asm snippets below (inside
    VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
    two reasons:
    (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not
@@ -3959,7 +3960,7 @@ typedef
 #endif /* PLAT_s390x_linux */
 
 /* ------------------------- mips32-linux ----------------------- */
- 
+
 #if defined(PLAT_mips32_linux)
 
 /* These regs are trashed by the hidden call. */
@@ -4935,7 +4936,7 @@ typedef
 #define VG_IS_TOOL_USERREQ(a, b, v) \
    (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
 
-/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! 
+/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
    This enum comprises an ABI exported by Valgrind to programs
    which use client requests.  DO NOT CHANGE THE ORDER OF THESE
    ENTRIES, NOR DELETE ANY -- add new ones at the end. */
@@ -5073,7 +5074,7 @@ VALGRIND_PRINTF(const char *format, ...)
    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                               VG_USERREQ__PRINTF_VALIST_BY_REF,
                               (unsigned long)format,
-                              (unsigned long)&vargs, 
+                              (unsigned long)&vargs,
                               0, 0, 0);
 #endif
    va_end(vargs);
@@ -5111,7 +5112,7 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                               VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
                               (unsigned long)format,
-                              (unsigned long)&vargs, 
+                              (unsigned long)&vargs,
                               0, 0, 0);
 #endif
    va_end(vargs);
@@ -5122,7 +5123,7 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
 
 /* These requests allow control to move from the simulated CPU to the
    real CPU, calling an arbitary function.
-   
+
    Note that the current ThreadId is inserted as the first argument.
    So this call:
 
@@ -5208,7 +5209,7 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
    - It marks the block as being addressable and undefined (if 'is_zeroed' is
      not set), or addressable and defined (if 'is_zeroed' is set).  This
      controls how accesses to the block by the program are handled.
-   
+
    'addr' is the start of the usable block (ie. after any
    redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
    can apply redzones -- these are blocks of padding at the start and end of
@@ -5216,7 +5217,7 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
    Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
    zeroed (or filled with another predictable value), as is the case for
    calloc().
-   
+
    VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
    heap block -- that will be used by the client program -- is allocated.
    It's best to put it at the outermost level of the allocator if possible;

From bf420e58c2f88c8f37f83aaf947e7abba1cd7f79 Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Sat, 5 Jul 2014 00:42:58 -0700
Subject: [PATCH 02/11] 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.

---
 src/libgreen/context.rs | 40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/src/libgreen/context.rs b/src/libgreen/context.rs
index 8c60f3d9fe1dc..45f41181bf8c7 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")]

From bf76e0023114fb47cc8fc766dc2f3d5db8c696a2 Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Sat, 5 Jul 2014 00:47:09 -0700
Subject: [PATCH 03/11] libnative should not mess with stack limits in the TIB.
  Only libgreen has a legitimate need to set them.

---
 src/libgreen/context.rs | 4 ++--
 src/librustrt/stack.rs  | 7 ++++++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/libgreen/context.rs b/src/libgreen/context.rs
index 45f41181bf8c7..d681e53af42d5 100644
--- a/src/libgreen/context.rs
+++ b/src/libgreen/context.rs
@@ -105,11 +105,11 @@ impl Context {
             // invalid for the current task. Lucky for us `rust_swap_registers`
             // is a C function so we don't have to worry about that!
             match in_context.stack_bounds {
-                Some((lo, hi)) => stack::record_stack_bounds(lo, hi),
+                Some((lo, hi)) => stack::record_stack_bounds_green(lo, hi),
                 // If we're going back to one of the original contexts or
                 // something that's possibly not a "normal task", then reset
                 // the stack limit to 0 to make morestack never fail
-                None => stack::record_stack_bounds(0, uint::MAX),
+                None => stack::record_stack_bounds_green(0, uint::MAX),
             }
             rust_swap_registers(out_regs, in_regs)
         }
diff --git a/src/librustrt/stack.rs b/src/librustrt/stack.rs
index 6544c020e0949..a79f453cf1ecb 100644
--- a/src/librustrt/stack.rs
+++ b/src/librustrt/stack.rs
@@ -125,7 +125,7 @@ extern fn stack_exhausted() {
 }
 
 #[inline(always)]
-pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) {
+pub unsafe fn record_stack_bounds_green(stack_lo: uint, stack_hi: uint) {
     // When the old runtime had segmented stacks, it used a calculation that was
     // "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic
     // symbol resolution, llvm function calls, etc. In theory this red zone
@@ -154,6 +154,11 @@ pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) {
     }
 }
 
+#[inline(always)]
+pub unsafe fn record_stack_bounds(stack_lo: uint, _stack_hi: uint) {
+    record_sp_limit(stack_lo + RED_ZONE);
+}
+
 /// Records the current limit of the stack as specified by `end`.
 ///
 /// This is stored in an OS-dependent location, likely inside of the thread

From ad2f67f1c3c5549d4f95dc566133ea648eb4c44c Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Sat, 5 Jul 2014 00:52:32 -0700
Subject: [PATCH 04/11] Use mingw64 target spelling.

---
 src/etc/get-snapshot.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/etc/get-snapshot.py b/src/etc/get-snapshot.py
index ec87c321f56f9..c5acb69df8d73 100755
--- a/src/etc/get-snapshot.py
+++ b/src/etc/get-snapshot.py
@@ -53,7 +53,7 @@ def unpack_snapshot(triple, dl_path):
   dl_path = sys.argv[2]
 else:
   # There are no 64-bit Windows snapshots yet, so we'll use 32-bit ones instead, for now
-  snap_triple = triple if triple != "x86_64-w64-mingw32" else "i686-pc-mingw32"
+  snap_triple = triple if triple != "x86_64-w64-mingw32" else "i686-w64-mingw32"
   snap = determine_curr_snapshot(snap_triple)
   dl = os.path.join(download_dir_base, snap)
   url = download_url_base + "/" + snap

From 9bdaf0b5da1334f9a7101c36f11807dab5e11c81 Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Sat, 5 Jul 2014 00:53:46 -0700
Subject: [PATCH 05/11] Use gcc for cross-build linking, not g++.

---
 mk/platform.mk | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mk/platform.mk b/mk/platform.mk
index 29643ea25f707..b1128bc40cc5c 100644
--- a/mk/platform.mk
+++ b/mk/platform.mk
@@ -377,7 +377,7 @@ RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabi :=
 # mipsel-linux configuration
 CC_mipsel-linux=mipsel-linux-gcc
 CXX_mipsel-linux=mipsel-linux-g++
-CPP_mipsel-linux=mipsel-linux-gcc 
+CPP_mipsel-linux=mipsel-linux-gcc
 AR_mipsel-linux=mipsel-linux-ar
 CFG_LIB_NAME_mipsel-linux=lib$(1).so
 CFG_STATIC_LIB_NAME_mipsel-linux=lib$(1).a
@@ -641,7 +641,7 @@ define CFG_MAKE_TOOLCHAIN
 	CXX_$(1)=$(CROSS_PREFIX_$(1))$(CXX_$(1))
 	CPP_$(1)=$(CROSS_PREFIX_$(1))$(CPP_$(1))
 	AR_$(1)=$(CROSS_PREFIX_$(1))$(AR_$(1))
-	RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(CXX_$(1))) \
+	RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(CC_$(1))) \
 	    -C ar=$$(call FIND_COMPILER,$$(AR_$(1))) $(RUSTC_CROSS_FLAGS_$(1))
 
 	RUSTC_FLAGS_$(1)=$$(RUSTC_CROSS_FLAGS_$(1)) $(RUSTC_FLAGS_$(1))

From 081991e7e1d4181a22687331b0f504765370835d Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Mon, 28 Jul 2014 13:35:34 -0700
Subject: [PATCH 06/11] Fix crash in OsRng when compiling with -O.

---
 src/libstd/rand/os.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 60e2c4c894919..ffe8e539ffba1 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -136,10 +136,11 @@ mod imp {
     use rand::Rng;
     use result::{Ok, Err};
     use rt::stack;
-    use self::libc::{c_ulong, DWORD, BYTE, LPCSTR, BOOL};
+    use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
+    use self::libc::types::os::arch::extra::{LONG_PTR};
     use slice::MutableVector;
 
-    type HCRYPTPROV = c_ulong;
+    type HCRYPTPROV = LONG_PTR;
 
     /// A random number generator that retrieves randomness straight from
     /// the operating system. Platform sources:

From a12b23521fd5cc826a787a45cfa6630857a8939e Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Fri, 1 Aug 2014 02:23:05 -0700
Subject: [PATCH 07/11] Update LLVM

---
 src/llvm                             | 2 +-
 src/rustllvm/RustWrapper.cpp         | 4 ++--
 src/rustllvm/llvm-auto-clean-trigger | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/llvm b/src/llvm
index 0d999e5b315b6..90a314162053a 160000
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 0d999e5b315b6ff78fcea772466d985ce53fd8dc
+Subproject commit 90a314162053a0c51a50a1c603c9203bef241e0d
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 8a3e06aabc697..8051235da20aa 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -282,7 +282,7 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType(
     LLVMValueRef ParameterTypes) {
     return wrap(Builder->createSubroutineType(
         unwrapDI<DIFile>(File),
-        unwrapDI<DIArray>(ParameterTypes)));
+        unwrapDI<DITypeArray>(ParameterTypes)));
 }
 
 extern "C" LLVMValueRef LLVMDIBuilderCreateFunction(
@@ -634,7 +634,7 @@ extern "C" void LLVMDICompositeTypeSetTypeArray(
     LLVMValueRef CompositeType,
     LLVMValueRef TypeArray)
 {
-    unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
+    unwrapDI<DICompositeType>(CompositeType).setArrays(unwrapDI<DIArray>(TypeArray));
 }
 
 extern "C" char *LLVMTypeToString(LLVMTypeRef Type) {
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
index afba5a4dfd8c2..bf488ca1527c1 100644
--- a/src/rustllvm/llvm-auto-clean-trigger
+++ b/src/rustllvm/llvm-auto-clean-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2014-07-29
+2014-08-24

From 5a24ee8a9ef1bb3bf250ce39902cf8dfca1a4dea Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Thu, 10 Apr 2014 10:48:38 -0700
Subject: [PATCH 08/11] Implement unwinding for Win64. The original trick used
 to trigger unwinds would not work with GCC's implementation of SEH, so I had
 to invent a new one: rust_try now consists of two routines: the outer one,
 whose handler triggers unwinds, and the inner one, that stops unwinds by
 having a landing pad that swallows exceptions and passes them on to the outer
 routine via a normal return.

---
 src/librustrt/libunwind.rs |   2 +-
 src/librustrt/unwind.rs    | 145 ++++++++++++++++++++++++++++++-------
 src/rt/rust_try.ll         |  34 ++++++---
 3 files changed, 146 insertions(+), 35 deletions(-)

diff --git a/src/librustrt/libunwind.rs b/src/librustrt/libunwind.rs
index 789723af1b133..db6308c10dcf2 100644
--- a/src/librustrt/libunwind.rs
+++ b/src/librustrt/libunwind.rs
@@ -60,7 +60,7 @@ pub type _Unwind_Word = libc::uintptr_t;
 pub static unwinder_private_data_size: uint = 5;
 
 #[cfg(target_arch = "x86_64")]
-pub static unwinder_private_data_size: uint = 2;
+pub static unwinder_private_data_size: uint = 6;
 
 #[cfg(target_arch = "arm", not(target_os = "ios"))]
 pub static unwinder_private_data_size: uint = 20;
diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs
index 52b02479f7fc7..9c62936ef9a49 100644
--- a/src/librustrt/unwind.rs
+++ b/src/librustrt/unwind.rs
@@ -227,7 +227,7 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
 //   This is achieved by overriding the return value in search phase to always
 //   say "catch!".
 
-#[cfg(not(target_arch = "arm"), not(test))]
+#[cfg(not(target_arch = "arm"), not(windows, target_arch = "x86_64"), not(test))]
 #[doc(hidden)]
 #[allow(visible_private_types)]
 pub mod eabi {
@@ -244,7 +244,8 @@ pub mod eabi {
     }
 
     #[lang="eh_personality"]
-    extern fn eh_personality(
+    #[no_mangle] // referenced from rust_try.ll
+    extern fn rust_eh_personality(
         version: c_int,
         actions: uw::_Unwind_Action,
         exception_class: uw::_Unwind_Exception_Class,
@@ -260,21 +261,19 @@ pub mod eabi {
 
     #[no_mangle] // referenced from rust_try.ll
     pub extern "C" fn rust_eh_personality_catch(
-        version: c_int,
+        _version: c_int,
         actions: uw::_Unwind_Action,
-        exception_class: uw::_Unwind_Exception_Class,
-        ue_header: *mut uw::_Unwind_Exception,
-        context: *mut uw::_Unwind_Context
+        _exception_class: uw::_Unwind_Exception_Class,
+        _ue_header: *mut uw::_Unwind_Exception,
+        _context: *mut uw::_Unwind_Context
     ) -> uw::_Unwind_Reason_Code
     {
+
         if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
             uw::_URC_HANDLER_FOUND // catch!
         }
         else { // cleanup phase
-            unsafe {
-                __gcc_personality_v0(version, actions, exception_class, ue_header,
-                                     context)
-            }
+            uw::_URC_INSTALL_CONTEXT
         }
     }
 }
@@ -299,7 +298,7 @@ pub mod eabi {
     }
 
     #[lang="eh_personality"]
-    #[no_mangle] // so we can reference it by name from middle/trans/base.rs
+    #[no_mangle] // referenced from rust_try.ll
     pub extern "C" fn rust_eh_personality(
         version: c_int,
         actions: uw::_Unwind_Action,
@@ -316,21 +315,18 @@ pub mod eabi {
 
     #[no_mangle] // referenced from rust_try.ll
     pub extern "C" fn rust_eh_personality_catch(
-        version: c_int,
+        _version: c_int,
         actions: uw::_Unwind_Action,
-        exception_class: uw::_Unwind_Exception_Class,
-        ue_header: *mut uw::_Unwind_Exception,
-        context: *mut uw::_Unwind_Context
+        _exception_class: uw::_Unwind_Exception_Class,
+        _ue_header: *mut uw::_Unwind_Exception,
+        _context: *mut uw::_Unwind_Context
     ) -> uw::_Unwind_Reason_Code
     {
         if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
             uw::_URC_HANDLER_FOUND // catch!
         }
         else { // cleanup phase
-            unsafe {
-                __gcc_personality_sj0(version, actions, exception_class, ue_header,
-                                      context)
-            }
+            uw::_URC_INSTALL_CONTEXT
         }
     }
 }
@@ -338,7 +334,7 @@ pub mod eabi {
 
 // ARM EHABI uses a slightly different personality routine signature,
 // but otherwise works the same.
-#[cfg(target_arch = "arm", not(test), not(target_os = "ios"))]
+#[cfg(target_arch = "arm", not(target_os = "ios", not(test)))]
 #[allow(visible_private_types)]
 pub mod eabi {
     use uw = libunwind;
@@ -352,7 +348,8 @@ pub mod eabi {
     }
 
     #[lang="eh_personality"]
-    extern "C" fn eh_personality(
+    #[no_mangle] // referenced from rust_try.ll
+    extern "C" fn rust_eh_personality(
         state: uw::_Unwind_State,
         ue_header: *mut uw::_Unwind_Exception,
         context: *mut uw::_Unwind_Context
@@ -366,8 +363,8 @@ pub mod eabi {
     #[no_mangle] // referenced from rust_try.ll
     pub extern "C" fn rust_eh_personality_catch(
         state: uw::_Unwind_State,
-        ue_header: *mut uw::_Unwind_Exception,
-        context: *mut uw::_Unwind_Context
+        _ue_header: *mut uw::_Unwind_Exception,
+        _context: *mut uw::_Unwind_Context
     ) -> uw::_Unwind_Reason_Code
     {
         if (state as c_int & uw::_US_ACTION_MASK as c_int)
@@ -375,10 +372,108 @@ pub mod eabi {
             uw::_URC_HANDLER_FOUND // catch!
         }
         else { // cleanup phase
-            unsafe {
-                __gcc_personality_v0(state, ue_header, context)
+            uw::_URC_INSTALL_CONTEXT
+        }
+    }
+}
+
+// Win64 SEH (see http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx)
+//
+// This looks a bit convoluted because rather than implementing a native SEH handler,
+// GCC reuses the same personality routine as for the other architectures by wrapping it
+// with an "API translator" layer (_GCC_specific_handler).
+
+#[cfg(windows, target_arch = "x86_64", not(test))]
+#[allow(visible_private_types)]
+#[allow(non_camel_case_types)]
+#[allow(unused_variable)]
+#[allow(uppercase_variables)]
+pub mod eabi {
+    use uw = libunwind;
+    use libc::{c_void, c_int};
+
+    struct EXCEPTION_RECORD;
+    struct CONTEXT;
+    struct DISPATCHER_CONTEXT;
+
+    #[repr(C)]
+    enum EXCEPTION_DISPOSITION {
+        ExceptionContinueExecution,
+        ExceptionContinueSearch,
+        ExceptionNestedException,
+        ExceptionCollidedUnwind
+    }
+
+    type _Unwind_Personality_Fn =
+        extern "C" fn(
+            version: c_int,
+            actions: uw::_Unwind_Action,
+            exception_class: uw::_Unwind_Exception_Class,
+            ue_header: *mut uw::_Unwind_Exception,
+            context: *mut uw::_Unwind_Context
+        ) -> uw::_Unwind_Reason_Code;
+
+    extern "C" {
+        fn __gcc_personality_seh0(
+            exceptionRecord: *mut EXCEPTION_RECORD,
+            establisherFrame: *mut c_void,
+            contextRecord: *mut CONTEXT,
+            dispatcherContext: *mut DISPATCHER_CONTEXT
+        ) -> EXCEPTION_DISPOSITION;
+
+        fn _GCC_specific_handler(
+            exceptionRecord: *mut EXCEPTION_RECORD,
+            establisherFrame: *mut c_void,
+            contextRecord: *mut CONTEXT,
+            dispatcherContext: *mut DISPATCHER_CONTEXT,
+            personality: _Unwind_Personality_Fn
+        ) -> EXCEPTION_DISPOSITION;
+    }
+
+    #[lang="eh_personality"]
+    #[no_mangle] // referenced from rust_try.ll
+    extern "C" fn rust_eh_personality(
+        exceptionRecord: *mut EXCEPTION_RECORD,
+        establisherFrame: *mut c_void,
+        contextRecord: *mut CONTEXT,
+        dispatcherContext: *mut DISPATCHER_CONTEXT
+    ) -> EXCEPTION_DISPOSITION
+    {
+        unsafe {
+            __gcc_personality_seh0(exceptionRecord, establisherFrame,
+                                   contextRecord, dispatcherContext)
+        }
+    }
+
+    #[no_mangle] // referenced from rust_try.ll
+    pub extern "C" fn rust_eh_personality_catch(
+        exceptionRecord: *mut EXCEPTION_RECORD,
+        establisherFrame: *mut c_void,
+        contextRecord: *mut CONTEXT,
+        dispatcherContext: *mut DISPATCHER_CONTEXT
+    ) -> EXCEPTION_DISPOSITION
+    {
+        extern "C" fn inner(
+                _version: c_int,
+                actions: uw::_Unwind_Action,
+                _exception_class: uw::_Unwind_Exception_Class,
+                _ue_header: *mut uw::_Unwind_Exception,
+                _context: *mut uw::_Unwind_Context
+            ) -> uw::_Unwind_Reason_Code
+        {
+            if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
+                uw::_URC_HANDLER_FOUND // catch!
+            }
+            else { // cleanup phase
+                uw::_URC_INSTALL_CONTEXT
             }
         }
+
+        unsafe {
+            _GCC_specific_handler(exceptionRecord, establisherFrame,
+                                  contextRecord, dispatcherContext,
+                                  inner)
+        }
     }
 }
 
diff --git a/src/rt/rust_try.ll b/src/rt/rust_try.ll
index c912aa789bf6b..08bf5e3dface4 100644
--- a/src/rt/rust_try.ll
+++ b/src/rt/rust_try.ll
@@ -11,24 +11,40 @@
 ; Rust's try-catch
 ; When f(...) returns normally, the return value is null.
 ; When f(...) throws, the return value is a pointer to the caught exception object.
-; See also: libstd/rt/unwind.rs
+; See also: librustrt/unwind.rs
 
 define i8* @rust_try(void (i8*,i8*)* %f, i8* %fptr, i8* %env) {
 
-	invoke void %f(i8* %fptr, i8* %env)
-		to label %normal
-		unwind label %catch
+    %1 = invoke i8* @rust_try_inner(void (i8*,i8*)* %f, i8* %fptr, i8* %env)
+        to label %normal
+        unwind label %catch
 
 normal:
-	ret i8* null
+    ret i8* %1
 
 catch:
-	%1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @rust_eh_personality_catch to i8*)
-			catch i8* null ; catch everything
+    landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @rust_eh_personality_catch to i8*)
+        catch i8* null
+    ; execution will never reach here because rust_try_inner's landing pad does not resume unwinds
+    ret i8* null
+}
+
+define internal i8* @rust_try_inner(void (i8*,i8*)* %f, i8* %fptr, i8* %env) {
+
+    invoke void %f(i8* %fptr, i8* %env)
+        to label %normal
+        unwind label %catch
 
-	; extract and return pointer to the exception object
+normal:
+    ret i8* null
+
+catch:
+    %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @rust_eh_personality to i8*)
+        catch i8* null
+    ; extract and return pointer to the exception object
     %2 = extractvalue { i8*, i32 } %1, 0
-	ret i8* %2
+    ret i8* %2
 }
 
+declare i32 @rust_eh_personality(...)
 declare i32 @rust_eh_personality_catch(...)

From cb55279f2378c8f3e8528c8c4c8a0f67d6955cb1 Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Fri, 1 Aug 2014 01:51:08 -0700
Subject: [PATCH 09/11] Fix tests.

---
 src/test/run-pass/intrinsic-alignment.rs | 9 +++++++++
 src/test/run-pass/rec-align-u64.rs       | 6 ++++++
 2 files changed, 15 insertions(+)

diff --git a/src/test/run-pass/intrinsic-alignment.rs b/src/test/run-pass/intrinsic-alignment.rs
index 197b92ba63526..ad9f8459eb79b 100644
--- a/src/test/run-pass/intrinsic-alignment.rs
+++ b/src/test/run-pass/intrinsic-alignment.rs
@@ -51,6 +51,15 @@ mod m {
             assert_eq!(::rusti::min_align_of::<u64>(), 8u);
         }
     }
+
+    #[main]
+    #[cfg(target_arch = "x86_64")]
+    pub fn main() {
+        unsafe {
+            assert_eq!(::rusti::pref_align_of::<u64>(), 8u);
+            assert_eq!(::rusti::min_align_of::<u64>(), 8u);
+        }
+    }
 }
 
 #[cfg(target_os = "android")]
diff --git a/src/test/run-pass/rec-align-u64.rs b/src/test/run-pass/rec-align-u64.rs
index ada012fc2f501..88295208672b7 100644
--- a/src/test/run-pass/rec-align-u64.rs
+++ b/src/test/run-pass/rec-align-u64.rs
@@ -61,6 +61,12 @@ mod m {
         pub fn align() -> uint { 8u }
         pub fn size() -> uint { 16u }
     }
+
+    #[cfg(target_arch = "x86_64")]
+    pub mod m {
+        pub fn align() -> uint { 8u }
+        pub fn size() -> uint { 16u }
+    }
 }
 
 #[cfg(target_os = "android")]

From cd2003ffd8dd976342f9e8fc1429ae93d6780e81 Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Tue, 5 Aug 2014 19:07:38 -0700
Subject: [PATCH 10/11] Added clarification regarding rust_try_inner.

---
 src/librustrt/unwind.rs              | 19 +++++++++++++------
 src/rt/rust_try.ll                   |  3 ++-
 src/rustllvm/llvm-auto-clean-trigger |  2 +-
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs
index 9c62936ef9a49..f0967edc82061 100644
--- a/src/librustrt/unwind.rs
+++ b/src/librustrt/unwind.rs
@@ -220,12 +220,19 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
 //
 // This is pretty close to Rust's exception handling approach, except that Rust
 // does have a single "catch-all" handler at the bottom of each task's stack.
-// So we have two versions:
+// So we have two versions of the personality routine:
 // - rust_eh_personality, used by all cleanup landing pads, which never catches,
 //   so the behavior of __gcc_personality_v0 is perfectly adequate there, and
 // - rust_eh_personality_catch, used only by rust_try(), which always catches.
-//   This is achieved by overriding the return value in search phase to always
-//   say "catch!".
+//
+// Note, however, that for implementation simplicity, rust_eh_personality_catch
+// lacks code to install a landing pad, so in order to obtain exception object
+// pointer (which it needs to return upstream), rust_try() employs another trick:
+// it calls into the nested rust_try_inner(), whose landing pad does not resume
+// unwinds.  Instead, it extracts the exception pointer and performs a "normal"
+// return.
+//
+// See also: rt/rust_try.ll
 
 #[cfg(not(target_arch = "arm"), not(windows, target_arch = "x86_64"), not(test))]
 #[doc(hidden)]
@@ -334,7 +341,8 @@ pub mod eabi {
 
 // ARM EHABI uses a slightly different personality routine signature,
 // but otherwise works the same.
-#[cfg(target_arch = "arm", not(target_os = "ios", not(test)))]
+#[cfg(target_arch = "arm", not(target_os = "ios"), not(test))]
+#[doc(hidden)]
 #[allow(visible_private_types)]
 pub mod eabi {
     use uw = libunwind;
@@ -384,10 +392,9 @@ pub mod eabi {
 // with an "API translator" layer (_GCC_specific_handler).
 
 #[cfg(windows, target_arch = "x86_64", not(test))]
+#[doc(hidden)]
 #[allow(visible_private_types)]
 #[allow(non_camel_case_types)]
-#[allow(unused_variable)]
-#[allow(uppercase_variables)]
 pub mod eabi {
     use uw = libunwind;
     use libc::{c_void, c_int};
diff --git a/src/rt/rust_try.ll b/src/rt/rust_try.ll
index 08bf5e3dface4..33d2d31a2e0c1 100644
--- a/src/rt/rust_try.ll
+++ b/src/rt/rust_try.ll
@@ -11,6 +11,7 @@
 ; Rust's try-catch
 ; When f(...) returns normally, the return value is null.
 ; When f(...) throws, the return value is a pointer to the caught exception object.
+
 ; See also: librustrt/unwind.rs
 
 define i8* @rust_try(void (i8*,i8*)* %f, i8* %fptr, i8* %env) {
@@ -25,7 +26,7 @@ normal:
 catch:
     landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @rust_eh_personality_catch to i8*)
         catch i8* null
-    ; execution will never reach here because rust_try_inner's landing pad does not resume unwinds
+    ; rust_try_inner's landing pad does not resume unwinds, so execution will never reach here
     ret i8* null
 }
 
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
index bf488ca1527c1..dd1c444119bde 100644
--- a/src/rustllvm/llvm-auto-clean-trigger
+++ b/src/rustllvm/llvm-auto-clean-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2014-08-24
+2014-08-05

From 881bfb1a180a1b545daa9da1539ec4c8ebda7ed1 Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Tue, 5 Aug 2014 20:53:42 -0700
Subject: [PATCH 11/11] Renamed `record_stack_bounds` for clarity. For a good
 measure, implemented target_record_stack_bounds for 32-bit Windows as well.

---
 src/libgreen/context.rs |  4 ++--
 src/libnative/lib.rs    |  2 +-
 src/libnative/task.rs   |  2 +-
 src/librustrt/stack.rs  | 37 ++++++++++++++++++++++++-------------
 src/librustrt/thread.rs |  2 +-
 5 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/src/libgreen/context.rs b/src/libgreen/context.rs
index d681e53af42d5..b63758cdcc5e7 100644
--- a/src/libgreen/context.rs
+++ b/src/libgreen/context.rs
@@ -105,11 +105,11 @@ impl Context {
             // invalid for the current task. Lucky for us `rust_swap_registers`
             // is a C function so we don't have to worry about that!
             match in_context.stack_bounds {
-                Some((lo, hi)) => stack::record_stack_bounds_green(lo, hi),
+                Some((lo, hi)) => stack::record_rust_managed_stack_bounds(lo, hi),
                 // If we're going back to one of the original contexts or
                 // something that's possibly not a "normal task", then reset
                 // the stack limit to 0 to make morestack never fail
-                None => stack::record_stack_bounds_green(0, uint::MAX),
+                None => stack::record_rust_managed_stack_bounds(0, uint::MAX),
             }
             rust_swap_registers(out_regs, in_regs)
         }
diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs
index d358aa6b6453e..c7b89b6cb9153 100644
--- a/src/libnative/lib.rs
+++ b/src/libnative/lib.rs
@@ -137,7 +137,7 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
     task.name = Some(str::Slice("<main>"));
     drop(task.run(|| {
         unsafe {
-            rt::stack::record_stack_bounds(my_stack_bottom, my_stack_top);
+            rt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
         }
         exit_code = Some(run(main.take_unwrap()));
     }).destroy());
diff --git a/src/libnative/task.rs b/src/libnative/task.rs
index c72d6c24a7c16..55806caaf1352 100644
--- a/src/libnative/task.rs
+++ b/src/libnative/task.rs
@@ -84,7 +84,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
         let addr = &something_around_the_top_of_the_stack as *const int;
         let my_stack = addr as uint;
         unsafe {
-            stack::record_stack_bounds(my_stack - stack + 1024, my_stack);
+            stack::record_os_managed_stack_bounds(my_stack - stack + 1024, my_stack);
         }
         let mut ops = ops;
         ops.stack_bounds = (my_stack - stack + 1024, my_stack);
diff --git a/src/librustrt/stack.rs b/src/librustrt/stack.rs
index a79f453cf1ecb..c941107d7e81a 100644
--- a/src/librustrt/stack.rs
+++ b/src/librustrt/stack.rs
@@ -124,8 +124,23 @@ extern fn stack_exhausted() {
     }
 }
 
+// Windows maintains a record of upper and lower stack bounds in the Thread Information
+// Block (TIB), and some syscalls do check that addresses which are supposed to be in
+// the stack, indeed lie between these two values.
+// (See https://github.com/rust-lang/rust/issues/3445#issuecomment-26114839)
+//
+// When using Rust-managed stacks (libgreen), we must maintain these values accordingly.
+// For OS-managed stacks (libnative), we let the OS manage them for us.
+//
+// On all other platforms both variants behave identically.
+
+#[inline(always)]
+pub unsafe fn record_os_managed_stack_bounds(stack_lo: uint, _stack_hi: uint) {
+    record_sp_limit(stack_lo + RED_ZONE);
+}
+
 #[inline(always)]
-pub unsafe fn record_stack_bounds_green(stack_lo: uint, stack_hi: uint) {
+pub unsafe fn record_rust_managed_stack_bounds(stack_lo: uint, stack_hi: uint) {
     // When the old runtime had segmented stacks, it used a calculation that was
     // "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic
     // symbol resolution, llvm function calls, etc. In theory this red zone
@@ -138,27 +153,23 @@ pub unsafe fn record_stack_bounds_green(stack_lo: uint, stack_hi: uint) {
 
     return target_record_stack_bounds(stack_lo, stack_hi);
 
-    #[cfg(not(windows))] #[cfg(not(target_arch = "x86_64"))] #[inline(always)]
+    #[cfg(not(windows))] #[inline(always)]
     unsafe fn target_record_stack_bounds(_stack_lo: uint, _stack_hi: uint) {}
+
+    #[cfg(windows, target_arch = "x86")] #[inline(always)]
+    unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
+        // stack range is at TIB: %fs:0x04 (top) and %fs:0x08 (bottom)
+        asm!("mov $0, %fs:0x04" :: "r"(stack_hi) :: "volatile");
+        asm!("mov $0, %fs:0x08" :: "r"(stack_lo) :: "volatile");
+    }
     #[cfg(windows, target_arch = "x86_64")] #[inline(always)]
     unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
-        // Windows compiles C functions which may check the stack bounds. This
-        // means that if we want to perform valid FFI on windows, then we need
-        // to ensure that the stack bounds are what they truly are for this
-        // task. More info can be found at:
-        //   https://github.com/rust-lang/rust/issues/3445#issuecomment-26114839
-        //
         // stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
         asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");
         asm!("mov $0, %gs:0x10" :: "r"(stack_lo) :: "volatile");
     }
 }
 
-#[inline(always)]
-pub unsafe fn record_stack_bounds(stack_lo: uint, _stack_hi: uint) {
-    record_sp_limit(stack_lo + RED_ZONE);
-}
-
 /// Records the current limit of the stack as specified by `end`.
 ///
 /// This is stored in an OS-dependent location, likely inside of the thread
diff --git a/src/librustrt/thread.rs b/src/librustrt/thread.rs
index 7bc991cf72f3a..43364466dbe39 100644
--- a/src/librustrt/thread.rs
+++ b/src/librustrt/thread.rs
@@ -44,7 +44,7 @@ static DEFAULT_STACK_SIZE: uint = 1024 * 1024;
 #[no_split_stack]
 extern fn thread_start(main: *mut libc::c_void) -> imp::rust_thread_return {
     unsafe {
-        stack::record_stack_bounds(0, uint::MAX);
+        stack::record_os_managed_stack_bounds(0, uint::MAX);
         let f: Box<proc()> = mem::transmute(main);
         (*f)();
         mem::transmute(0 as imp::rust_thread_return)