"Fossies" - the Fresh Open Source Software Archive

Member "AutoHotkey_L-1.1.33.09/source/lib_pcre/pcre/sljit/sljitUtils.c" (8 May 2021, 7146 Bytes) of package /windows/misc/AutoHotkey_L-1.1.33.09.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sljitUtils.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  *    Stack-less Just-In-Time compiler
    3  *
    4  *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without modification, are
    7  * permitted provided that the following conditions are met:
    8  *
    9  *   1. Redistributions of source code must retain the above copyright notice, this list of
   10  *      conditions and the following disclaimer.
   11  *
   12  *   2. Redistributions in binary form must reproduce the above copyright notice, this list
   13  *      of conditions and the following disclaimer in the documentation and/or other materials
   14  *      provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
   17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
   19  * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
   21  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
   22  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   24  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 /* ------------------------------------------------------------------------ */
   28 /*  Locks                                                                   */
   29 /* ------------------------------------------------------------------------ */
   30 
   31 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
   32 
   33 #ifdef _WIN32
   34 
   35 #include "windows.h"
   36 
   37 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
   38 
   39 static HANDLE allocator_mutex = 0;
   40 
   41 static SLJIT_INLINE void allocator_grab_lock(void)
   42 {
   43     /* No idea what to do if an error occures. Static mutexes should never fail... */
   44     if (!allocator_mutex)
   45         allocator_mutex = CreateMutex(NULL, TRUE, NULL);
   46     else
   47         WaitForSingleObject(allocator_mutex, INFINITE);
   48 }
   49 
   50 static SLJIT_INLINE void allocator_release_lock(void)
   51 {
   52     ReleaseMutex(allocator_mutex);
   53 }
   54 
   55 #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
   56 
   57 #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
   58 
   59 static HANDLE global_mutex = 0;
   60 
   61 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
   62 {
   63     /* No idea what to do if an error occures. Static mutexes should never fail... */
   64     if (!global_mutex)
   65         global_mutex = CreateMutex(NULL, TRUE, NULL);
   66     else
   67         WaitForSingleObject(global_mutex, INFINITE);
   68 }
   69 
   70 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
   71 {
   72     ReleaseMutex(global_mutex);
   73 }
   74 
   75 #endif /* SLJIT_UTIL_GLOBAL_LOCK */
   76 
   77 #else /* _WIN32 */
   78 
   79 #include "pthread.h"
   80 
   81 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
   82 
   83 static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
   84 
   85 static SLJIT_INLINE void allocator_grab_lock(void)
   86 {
   87     pthread_mutex_lock(&allocator_mutex);
   88 }
   89 
   90 static SLJIT_INLINE void allocator_release_lock(void)
   91 {
   92     pthread_mutex_unlock(&allocator_mutex);
   93 }
   94 
   95 #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
   96 
   97 #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
   98 
   99 static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
  100 
  101 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
  102 {
  103     pthread_mutex_lock(&global_mutex);
  104 }
  105 
  106 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
  107 {
  108     pthread_mutex_unlock(&global_mutex);
  109 }
  110 
  111 #endif /* SLJIT_UTIL_GLOBAL_LOCK */
  112 
  113 #endif /* _WIN32 */
  114 
  115 /* ------------------------------------------------------------------------ */
  116 /*  Stack                                                                   */
  117 /* ------------------------------------------------------------------------ */
  118 
  119 #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
  120 
  121 #ifdef _WIN32
  122 #include "windows.h"
  123 #else
  124 #include <sys/mman.h>
  125 #include <unistd.h>
  126 #endif
  127 
  128 /* Planning to make it even more clever in the future. */
  129 static sljit_w sljit_page_align = 0;
  130 
  131 SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit)
  132 {
  133     struct sljit_stack *stack;
  134     union {
  135         void *ptr;
  136         sljit_uw uw;
  137     } base;
  138 #ifdef _WIN32
  139     SYSTEM_INFO si;
  140 #endif
  141 
  142     if (limit > max_limit || limit < 1)
  143         return NULL;
  144 
  145 #ifdef _WIN32
  146     if (!sljit_page_align) {
  147         GetSystemInfo(&si);
  148         sljit_page_align = si.dwPageSize - 1;
  149     }
  150 #else
  151     if (!sljit_page_align) {
  152         sljit_page_align = sysconf(_SC_PAGESIZE);
  153         /* Should never happen. */
  154         if (sljit_page_align < 0)
  155             sljit_page_align = 4096;
  156         sljit_page_align--;
  157     }
  158 #endif
  159 
  160     /* Align limit and max_limit. */
  161     max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
  162 
  163     stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack));
  164     if (!stack)
  165         return NULL;
  166 
  167 #ifdef _WIN32
  168     base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE);
  169     if (!base.ptr) {
  170         SLJIT_FREE(stack);
  171         return NULL;
  172     }
  173     stack->base = base.uw;
  174     stack->limit = stack->base;
  175     stack->max_limit = stack->base + max_limit;
  176     if (sljit_stack_resize(stack, stack->base + limit)) {
  177         sljit_free_stack(stack);
  178         return NULL;
  179     }
  180 #else
  181     base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
  182     if (base.ptr == MAP_FAILED) {
  183         SLJIT_FREE(stack);
  184         return NULL;
  185     }
  186     stack->base = base.uw;
  187     stack->limit = stack->base + limit;
  188     stack->max_limit = stack->base + max_limit;
  189 #endif
  190     stack->top = stack->base;
  191     return stack;
  192 }
  193 
  194 #undef PAGE_ALIGN
  195 
  196 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack)
  197 {
  198 #ifdef _WIN32
  199     VirtualFree((void*)stack->base, 0, MEM_RELEASE);
  200 #else
  201     munmap((void*)stack->base, stack->max_limit - stack->base);
  202 #endif
  203     SLJIT_FREE(stack);
  204 }
  205 
  206 SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
  207 {
  208     sljit_uw aligned_old_limit;
  209     sljit_uw aligned_new_limit;
  210 
  211     if ((new_limit > stack->max_limit) || (new_limit < stack->base))
  212         return -1;
  213 #ifdef _WIN32
  214     aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
  215     aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
  216     if (aligned_new_limit != aligned_old_limit) {
  217         if (aligned_new_limit > aligned_old_limit) {
  218             if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE))
  219                 return -1;
  220         }
  221         else {
  222             if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT))
  223                 return -1;
  224         }
  225     }
  226     stack->limit = new_limit;
  227     return 0;
  228 #else
  229     if (new_limit >= stack->limit) {
  230         stack->limit = new_limit;
  231         return 0;
  232     }
  233     aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
  234     aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
  235     if (aligned_new_limit < aligned_old_limit)
  236         madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED);
  237     stack->limit = new_limit;
  238     return 0;
  239 #endif
  240 }
  241 
  242 #endif /* SLJIT_UTIL_STACK */
  243 
  244 #endif