[Pcre-svn] [956] code/trunk/sljit: JIT compiler update: fix …

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [956] code/trunk/sljit: JIT compiler update: fix x86-64 alignemnt issue
Revision: 956
          http://vcs.pcre.org/viewvc?view=rev&revision=956
Author:   zherczeg
Date:     2012-04-04 06:35:52 +0100 (Wed, 04 Apr 2012)


Log Message:
-----------
JIT compiler update: fix x86-64 alignemnt issue

Modified Paths:
--------------
    code/trunk/sljit/sljitNativeX86_32.c
    code/trunk/sljit/sljitNativeX86_64.c
    code/trunk/sljit/sljitNativeX86_common.c


Modified: code/trunk/sljit/sljitNativeX86_32.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_32.c    2012-04-03 15:32:36 UTC (rev 955)
+++ code/trunk/sljit/sljitNativeX86_32.c    2012-04-04 05:35:52 UTC (rev 956)
@@ -149,14 +149,14 @@
 #ifdef _WIN32
     if (local_size > 1024) {
         FAIL_IF(emit_do_imm(compiler, 0xb8 + reg_map[SLJIT_TEMPORARY_REG1], local_size));
-        FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_touch_stack)));
+        FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
     }
 #endif


     compiler->local_size = local_size;
-    if (local_size > 0)
-        return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
-            SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);
+    SLJIT_ASSERT(local_size > 0);
+    return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
+        SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);


     return SLJIT_SUCCESS;
 }
@@ -199,9 +199,9 @@
     compiler->flags_saved = 0;
     FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));


-    if (compiler->local_size > 0)
-        FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
-                SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
+    SLJIT_ASSERT(compiler->local_size > 0);
+    FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
+        SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));


     size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)


Modified: code/trunk/sljit/sljitNativeX86_64.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_64.c    2012-04-03 15:32:36 UTC (rev 955)
+++ code/trunk/sljit/sljitNativeX86_64.c    2012-04-04 05:35:52 UTC (rev 956)
@@ -196,12 +196,11 @@
 #endif
     }


-    local_size = ((local_size + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
-#ifdef _WIN64
-    local_size += 4 * sizeof(sljit_w);
+    local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
     compiler->local_size = local_size;
+#ifdef _WIN64
     if (local_size > 1024) {
-        /* Allocate the stack for the function itself. */
+        /* Allocate stack for the callback, which grows the stack. */
         buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
         FAIL_IF(!buf);
         INC_SIZE(4);
@@ -218,36 +217,29 @@
             local_size -= 4 * sizeof(sljit_w);
         }
         FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size));
-        FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_touch_stack)));
+        FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
     }
-#else
-    local_size += sizeof(sljit_w);
-    compiler->local_size = local_size;
-    if (local_size > 0) {
 #endif
-        /* In case of Win64, local_size is always > 4 * sizeof(sljit_w) */
-        if (local_size <= 127) {
-            buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
-            FAIL_IF(!buf);
-            INC_SIZE(4);
-            *buf++ = REX_W;
-            *buf++ = 0x83;
-            *buf++ = 0xc0 | (5 << 3) | 4;
-            *buf++ = local_size;
-        }
-        else {
-            buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
-            FAIL_IF(!buf);
-            INC_SIZE(7);
-            *buf++ = REX_W;
-            *buf++ = 0x81;
-            *buf++ = 0xc0 | (5 << 3) | 4;
-            *(sljit_hw*)buf = local_size;
-            buf += sizeof(sljit_hw);
-        }
-#ifndef _WIN64
+    SLJIT_ASSERT(local_size > 0);
+    if (local_size <= 127) {
+        buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+        FAIL_IF(!buf);
+        INC_SIZE(4);
+        *buf++ = REX_W;
+        *buf++ = 0x83;
+        *buf++ = 0xc0 | (5 << 3) | 4;
+        *buf++ = local_size;
     }
-#endif
+    else {
+        buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
+        FAIL_IF(!buf);
+        INC_SIZE(7);
+        *buf++ = REX_W;
+        *buf++ = 0x81;
+        *buf++ = 0xc0 | (5 << 3) | 4;
+        *(sljit_hw*)buf = local_size;
+        buf += sizeof(sljit_hw);
+    }


     return SLJIT_SUCCESS;
 }
@@ -271,12 +263,7 @@
     if (temporaries >= 5)
         pushed_size += sizeof(sljit_w);
 #endif
-    compiler->local_size = ((local_size + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
-#ifdef _WIN64
-    compiler->local_size += 4 * sizeof(sljit_w);
-#else
-    compiler->local_size += sizeof(sljit_w);
-#endif
+    compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
 }


 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
@@ -291,26 +278,25 @@
     compiler->flags_saved = 0;
     FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));


-    if (compiler->local_size > 0) {
-        if (compiler->local_size <= 127) {
-            buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
-            FAIL_IF(!buf);
-            INC_SIZE(4);
-            *buf++ = REX_W;
-            *buf++ = 0x83;
-            *buf++ = 0xc0 | (0 << 3) | 4;
-            *buf = compiler->local_size;
-        }
-        else {
-            buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
-            FAIL_IF(!buf);
-            INC_SIZE(7);
-            *buf++ = REX_W;
-            *buf++ = 0x81;
-            *buf++ = 0xc0 | (0 << 3) | 4;
-            *(sljit_hw*)buf = compiler->local_size;
-        }
+    SLJIT_ASSERT(compiler->local_size > 0);
+    if (compiler->local_size <= 127) {
+        buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+        FAIL_IF(!buf);
+        INC_SIZE(4);
+        *buf++ = REX_W;
+        *buf++ = 0x83;
+        *buf++ = 0xc0 | (0 << 3) | 4;
+        *buf = compiler->local_size;
     }
+    else {
+        buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
+        FAIL_IF(!buf);
+        INC_SIZE(7);
+        *buf++ = REX_W;
+        *buf++ = 0x81;
+        *buf++ = 0xc0 | (0 << 3) | 4;
+        *(sljit_hw*)buf = compiler->local_size;
+    }


     size = 1 + compiler->saveds;
 #ifndef _WIN64


Modified: code/trunk/sljit/sljitNativeX86_common.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_common.c    2012-04-03 15:32:36 UTC (rev 955)
+++ code/trunk/sljit/sljitNativeX86_common.c    2012-04-04 05:35:52 UTC (rev 956)
@@ -457,11 +457,17 @@
 #ifdef _WIN32
 #include <malloc.h>


-static void SLJIT_CALL sljit_touch_stack(sljit_w local_size)
+static void SLJIT_CALL sljit_grow_stack(sljit_w local_size)
 {
-    /* Workaround for calling _chkstk. */
+    /* Workaround for calling the internal _chkstk() function on Windows.
+    This function touches all 4k pages belongs to the requested stack space,
+    which size is passed in local_size. This is necessary on Windows where
+    the stack can only grow in 4k steps. However, this function just burn
+    CPU cycles if the stack is large enough, but you don't know it in advance.
+    I think this is a bad design even if it has some reasons. */
     alloca(local_size);
 }
+
 #endif


#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)