[Vm-dev] [commit] r2454 - Maintain 16-byte stack alignment in win32 SSE2 regime on Alien callbacks.

commits at squeakvm.org commits at squeakvm.org
Tue Jul 12 17:34:46 UTC 2011


Author: eliot
Date: 2011-07-12 10:34:46 -0700 (Tue, 12 Jul 2011)
New Revision: 2454

Modified:
   trunk/platforms/Cross/plugins/IA32ABI/ia32abicc.c
Log:
Maintain 16-byte stack alignment in win32 SSE2 regime on Alien callbacks.


Modified: trunk/platforms/Cross/plugins/IA32ABI/ia32abicc.c
===================================================================
--- trunk/platforms/Cross/plugins/IA32ABI/ia32abicc.c	2011-07-11 20:55:34 UTC (rev 2453)
+++ trunk/platforms/Cross/plugins/IA32ABI/ia32abicc.c	2011-07-12 17:34:46 UTC (rev 2454)
@@ -30,6 +30,7 @@
 #include <stdio.h> /* for fprintf(stderr,...) */
 
 #include "vmCallback.h"
+#include "sqAssert.h"
 #include "sqMemoryAccess.h"
 #include "sqVirtualMachine.h"
 #include "ia32abi.h"
@@ -64,6 +65,12 @@
 # define STACK_ALIGN_BYTES 16
 #elif __linux__ && __i386__
 # define STACK_ALIGN_BYTES 16
+#elif defined(WIN32) && __SSE2__
+/* using sse2 instructions requires 16-byte stack alignment but on win32 there's
+ * no guarantee that libraries preserve alignment so compensate on callback.
+ */
+# define STACK_ALIGN_HACK
+# define STACK_ALIGN_BYTES 16
 #endif
 
 #if !defined(setsp)
@@ -165,7 +172,8 @@
  * requirement on platforms using SSE2 such as Mac OS X, and harmless elsewhere.
  *
  * This function's roles are to use setjmp/longjmp to save the call point
- * and return to it, and to return any of the various values from the callback.
+ * and return to it, to correct C stack pointer alignment if necessary (see
+ * STACK_ALIGN_HACK), and to return any of the various values from the callback.
  *
  * Looking forward to support for x86-64, which typically has 6 register
  * arguments, the function would take 8 arguments, the 6 register args as
@@ -185,6 +193,23 @@
 		return -1;
 	}
 
+#if defined(STACK_ALIGN_HACK)
+  { void *sp = getsp();
+    int offset = (unsigned long)sp & (STACK_ALIGN_BYTES - 1);
+	if (offset) {
+#if _MSC_VER
+		_asm sub esp, dword ptr offset;
+#elif __GNUC__
+		asm("sub %0,%%esp" : : "m"(offset));
+#else
+# error need to subtract offset from esp
+#endif
+		sp = getsp();
+		assert(!((unsigned long)sp & (STACK_ALIGN_BYTES - 1)));
+	}
+  }
+#endif
+
 	if (!(returnType = setjmp(vmcc.trampoline))) {
 		previousCallbackContext = getRMCC();
 		setRMCC(&vmcc);



More information about the Vm-dev mailing list