[Pcre-svn] [1300] code/trunk/src/sljit: JIT compiler update.

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [1300] code/trunk/src/sljit: JIT compiler update.
Revision: 1300
          http://www.exim.org/viewvc/pcre2?view=rev&revision=1300
Author:   zherczeg
Date:     2021-02-12 07:45:12 +0000 (Fri, 12 Feb 2021)
Log Message:
-----------
JIT compiler update.


Modified Paths:
--------------
    code/trunk/src/sljit/sljitConfigInternal.h
    code/trunk/src/sljit/sljitExecAllocator.c
    code/trunk/src/sljit/sljitNativeS390X.c


Modified: code/trunk/src/sljit/sljitConfigInternal.h
===================================================================
--- code/trunk/src/sljit/sljitConfigInternal.h    2021-02-07 16:43:00 UTC (rev 1299)
+++ code/trunk/src/sljit/sljitConfigInternal.h    2021-02-12 07:45:12 UTC (rev 1300)
@@ -158,6 +158,8 @@
 #define SLJIT_CONFIG_MIPS_64 1
 #elif defined(__sparc__) || defined(__sparc)
 #define SLJIT_CONFIG_SPARC_32 1
+#elif defined(__s390x__)
+#define SLJIT_CONFIG_S390X 1
 #else
 /* Unsupported architecture */
 #define SLJIT_CONFIG_UNSUPPORTED 1


Modified: code/trunk/src/sljit/sljitExecAllocator.c
===================================================================
--- code/trunk/src/sljit/sljitExecAllocator.c    2021-02-07 16:43:00 UTC (rev 1299)
+++ code/trunk/src/sljit/sljitExecAllocator.c    2021-02-12 07:45:12 UTC (rev 1300)
@@ -79,6 +79,7 @@
 */


#ifdef _WIN32
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)

 static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
 {
@@ -91,66 +92,77 @@
     VirtualFree(chunk, 0, MEM_RELEASE);
 }


-#else
+#else /* POSIX */

-#ifdef __APPLE__
+#if defined(__APPLE__) && defined(MAP_JIT)
+/*
+ On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a
+ version where it's OK to have more than one JIT block or where MAP_JIT is
+ required.
+ On non-macOS systems, returns MAP_JIT if it is defined.
+*/
+#include <TargetConditionals.h>
+#if TARGET_OS_OSX
+#if defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86
#ifdef MAP_ANON
-/* Configures TARGET_OS_OSX when appropriate */
-#include <TargetConditionals.h>
-
-#if TARGET_OS_OSX && defined(MAP_JIT)
#include <sys/utsname.h>
-#endif /* TARGET_OS_OSX && MAP_JIT */
+#include <stdlib.h>

-#ifdef MAP_JIT
+#define SLJIT_MAP_JIT    (get_map_jit_flag())


-/*
-   On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a
-   version where it's OK to have more than one JIT block.
-   On non-macOS systems, returns MAP_JIT if it is defined.
-*/
 static SLJIT_INLINE int get_map_jit_flag()
 {
-#if TARGET_OS_OSX
-    sljit_sw page_size = get_page_alignment() + 1;
+    sljit_sw page_size;
     void *ptr;
+    struct utsname name;
     static int map_jit_flag = -1;


-    /*
-      The following code is thread safe because multiple initialization
-      sets map_jit_flag to the same value and the code has no side-effects.
-      Changing the kernel version witout system restart is (very) unlikely.
-    */
-    if (map_jit_flag == -1) {
-        struct utsname name;
-
+    if (map_jit_flag < 0) {
         map_jit_flag = 0;
         uname(&name);


-        /* Kernel version for 10.14.0 (Mojave) */
+        /* Kernel version for 10.14.0 (Mojave) or later */
         if (atoi(name.release) >= 18) {
+            page_size = get_page_alignment() + 1;
             /* Only use MAP_JIT if a hardened runtime is used */
+            ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC,
+                    MAP_PRIVATE | MAP_ANON, -1, 0);


-            ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
-
-            if (ptr == MAP_FAILED) {
+            if (ptr != MAP_FAILED)
+                munmap(ptr, page_size);
+            else
                 map_jit_flag = MAP_JIT;
-            } else {
-                munmap(ptr, page_size);
-            }
         }
     }
+    return map_jit_flag;
+}
+#endif /* MAP_ANON */
+#else /* !SLJIT_CONFIG_X86 */
+#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
+#error Unsupported architecture
+#endif /* SLJIT_CONFIG_ARM */
+#include <pthread.h>


-    return map_jit_flag;
+#define SLJIT_MAP_JIT    (MAP_JIT)
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
+                        apple_update_wx_flags(enable_exec)
+
+static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec)
+{
+    pthread_jit_write_protect_np(enable_exec);
+}
+#endif /* SLJIT_CONFIG_X86 */
 #else /* !TARGET_OS_OSX */
-    return MAP_JIT;
+#define SLJIT_MAP_JIT    (MAP_JIT)
 #endif /* TARGET_OS_OSX */
-}
+#endif /* __APPLE__ && MAP_JIT */
+#ifndef SLJIT_UPDATE_WX_FLAGS
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
+#endif /* !SLJIT_UPDATE_WX_FLAGS */
+#ifndef SLJIT_MAP_JIT
+#define SLJIT_MAP_JIT    (0)
+#endif /* !SLJIT_MAP_JIT */


-#endif /* MAP_JIT */
-#endif /* MAP_ANON */
-#endif /* __APPLE__ */
-
 static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
 {
     void *retval;
@@ -157,13 +169,8 @@
     const int prot = PROT_READ | PROT_WRITE | PROT_EXEC;


 #ifdef MAP_ANON
+    int flags = MAP_PRIVATE | MAP_ANON | SLJIT_MAP_JIT;


-    int flags = MAP_PRIVATE | MAP_ANON;
-
-#ifdef MAP_JIT
-    flags |= get_map_jit_flag();
-#endif
-
     retval = mmap(NULL, size, prot, flags, -1, 0);
 #else /* !MAP_ANON */
     if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))
@@ -173,14 +180,15 @@
 #endif /* MAP_ANON */


     if (retval == MAP_FAILED)
-        retval = NULL;
-    else {
-        if (mprotect(retval, size, prot) < 0) {
-            munmap(retval, size);
-            retval = NULL;
-        }
+        return NULL;
+
+    if (mprotect(retval, size, prot) < 0) {
+        munmap(retval, size);
+        return NULL;
     }


+    SLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0);
+
     return retval;
 }


@@ -189,7 +197,7 @@
     munmap(chunk, size);
 }


-#endif
+#endif /* windows */

 /* --------------------------------------------------------------------- */
 /*  Common functions                                                     */
@@ -261,6 +269,7 @@
     while (free_block) {
         if (free_block->size >= size) {
             chunk_size = free_block->size;
+            SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
             if (chunk_size > size + 64) {
                 /* We just cut a block from the end of the free block. */
                 chunk_size -= size;
@@ -326,6 +335,7 @@
     allocated_size -= header->size;


     /* Connecting free blocks together if possible. */
+    SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);


     /* If header->prev_size == 0, free_block will equal to header.
        In this case, free_block->header.size will be > 0. */
@@ -358,6 +368,7 @@
         }
     }


+    SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
     SLJIT_ALLOCATOR_UNLOCK();
 }


@@ -367,6 +378,7 @@
     struct free_block* next_free_block;


     SLJIT_ALLOCATOR_LOCK();
+    SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);


     free_block = free_blocks;
     while (free_block) {
@@ -381,5 +393,6 @@
     }


     SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
+    SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
     SLJIT_ALLOCATOR_UNLOCK();
 }


Modified: code/trunk/src/sljit/sljitNativeS390X.c
===================================================================
--- code/trunk/src/sljit/sljitNativeS390X.c    2021-02-07 16:43:00 UTC (rev 1299)
+++ code/trunk/src/sljit/sljitNativeS390X.c    2021-02-12 07:45:12 UTC (rev 1300)
@@ -42,7 +42,7 @@
 typedef sljit_uw sljit_ins;


/* Instruction tags (most significant halfword). */
-const sljit_ins sljit_ins_const = (sljit_ins)1 << 48;
+static const sljit_ins sljit_ins_const = (sljit_ins)1 << 48;

 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
     14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1
@@ -66,22 +66,22 @@
  * will be retired ASAP (TODO: carenas)
  */


-const sljit_gpr r0 = 0;    /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */
-const sljit_gpr r1 = 1;    /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */
-const sljit_gpr r2 = 2;    /* reg_map[1]: 1st argument */
-const sljit_gpr r3 = 3;    /* reg_map[2]: 2nd argument */
-const sljit_gpr r4 = 4;    /* reg_map[3]: 3rd argument */
-const sljit_gpr r5 = 5;    /* reg_map[4]: 4th argument */
-const sljit_gpr r6 = 6;    /* reg_map[5]: 5th argument; 1st saved register */
-const sljit_gpr r7 = 7;    /* reg_map[6] */
-const sljit_gpr r8 = 8;    /* reg_map[7] */
-const sljit_gpr r9 = 9;    /* reg_map[8] */
-const sljit_gpr r10 = 10;    /* reg_map[9] */
-const sljit_gpr r11 = 11;    /* reg_map[10] */
-const sljit_gpr r12 = 12;    /* reg_map[11]: GOT */
-const sljit_gpr r13 = 13;    /* reg_map[12]: Literal Pool pointer */
-const sljit_gpr r14 = 14;    /* reg_map[0]: return address and flag register */
-const sljit_gpr r15 = 15;    /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */
+static const sljit_gpr r0 = 0;        /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */
+static const sljit_gpr r1 = 1;        /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */
+static const sljit_gpr r2 = 2;        /* reg_map[1]: 1st argument */
+static const sljit_gpr r3 = 3;        /* reg_map[2]: 2nd argument */
+static const sljit_gpr r4 = 4;        /* reg_map[3]: 3rd argument */
+static const sljit_gpr r5 = 5;        /* reg_map[4]: 4th argument */
+static const sljit_gpr r6 = 6;        /* reg_map[5]: 5th argument; 1st saved register */
+static const sljit_gpr r7 = 7;        /* reg_map[6] */
+static const sljit_gpr r8 = 8;        /* reg_map[7] */
+static const sljit_gpr r9 = 9;        /* reg_map[8] */
+static const sljit_gpr r10 = 10;    /* reg_map[9] */
+static const sljit_gpr r11 = 11;    /* reg_map[10] */
+static const sljit_gpr r12 = 12;    /* reg_map[11]: GOT */
+static const sljit_gpr r13 = 13;    /* reg_map[12]: Literal Pool pointer */
+static const sljit_gpr r14 = 14;    /* reg_map[0]: return address and flag register */
+static const sljit_gpr r15 = 15;    /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */


 /* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */
 /* TODO(carenas): r12 might conflict in PIC code, reserve? */
@@ -100,8 +100,8 @@
 /* Link registers. The normal link register is r14, but since
    we use that for flags we need to use r0 instead to do fast
    calls so that flags are preserved. */
-const sljit_gpr link_r = 14;     /* r14 */
-const sljit_gpr fast_link_r = 0; /* r0 */
+static const sljit_gpr link_r = 14;     /* r14 */
+static const sljit_gpr fast_link_r = 0; /* r0 */


/* Flag register layout:

@@ -110,7 +110,7 @@
    |      ZERO     | 0 | 0 |  C C  |///////|
    +---------------+---+---+-------+-------+
 */
-const sljit_gpr flag_r = 14; /* r14 */
+static const sljit_gpr flag_r = 14; /* r14 */


 struct sljit_s390x_const {
     struct sljit_const const_; /* must be first */
@@ -1465,7 +1465,8 @@
     op = GET_OPCODE(op) | (op & SLJIT_I32_OP);
     switch (op) {
     case SLJIT_BREAKPOINT:
-        /* TODO(mundaym): insert real breakpoint? */
+        /* The following invalid instruction is emitted by gdb. */
+        return push_inst(compiler, 0x0001 /* 2-byte trap */);
     case SLJIT_NOP:
         return push_inst(compiler, 0x0700 /* 2-byte nop */);
     case SLJIT_LMUL_UW: