"Fossies" - the Fresh Open Source Software Archive

Member "pcre-8.44/sljit/sljitUtils.c" (19 Nov 2019, 9541 Bytes) of package /linux/misc/pcre-8.44.tar.bz2:


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 and the latest Fossies "Diffs" side-by-side code changes report: 8.43_vs_8.44.

    1 /*
    2  *    Stack-less Just-In-Time compiler
    3  *
    4  *    Copyright 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 #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
   34 
   35 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
   36 
   37 static SLJIT_INLINE void allocator_grab_lock(void)
   38 {
   39     /* Always successful. */
   40 }
   41 
   42 static SLJIT_INLINE void allocator_release_lock(void)
   43 {
   44     /* Always successful. */
   45 }
   46 
   47 #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
   48 
   49 #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
   50 
   51 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
   52 {
   53     /* Always successful. */
   54 }
   55 
   56 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
   57 {
   58     /* Always successful. */
   59 }
   60 
   61 #endif /* SLJIT_UTIL_GLOBAL_LOCK */
   62 
   63 #elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */
   64 
   65 #include "windows.h"
   66 
   67 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
   68 
   69 static HANDLE allocator_mutex = 0;
   70 
   71 static SLJIT_INLINE void allocator_grab_lock(void)
   72 {
   73     /* No idea what to do if an error occures. Static mutexes should never fail... */
   74     if (!allocator_mutex)
   75         allocator_mutex = CreateMutex(NULL, TRUE, NULL);
   76     else
   77         WaitForSingleObject(allocator_mutex, INFINITE);
   78 }
   79 
   80 static SLJIT_INLINE void allocator_release_lock(void)
   81 {
   82     ReleaseMutex(allocator_mutex);
   83 }
   84 
   85 #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
   86 
   87 #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
   88 
   89 static HANDLE global_mutex = 0;
   90 
   91 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
   92 {
   93     /* No idea what to do if an error occures. Static mutexes should never fail... */
   94     if (!global_mutex)
   95         global_mutex = CreateMutex(NULL, TRUE, NULL);
   96     else
   97         WaitForSingleObject(global_mutex, INFINITE);
   98 }
   99 
  100 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
  101 {
  102     ReleaseMutex(global_mutex);
  103 }
  104 
  105 #endif /* SLJIT_UTIL_GLOBAL_LOCK */
  106 
  107 #else /* _WIN32 */
  108 
  109 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
  110 
  111 #include <pthread.h>
  112 
  113 static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
  114 
  115 static SLJIT_INLINE void allocator_grab_lock(void)
  116 {
  117     pthread_mutex_lock(&allocator_mutex);
  118 }
  119 
  120 static SLJIT_INLINE void allocator_release_lock(void)
  121 {
  122     pthread_mutex_unlock(&allocator_mutex);
  123 }
  124 
  125 #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
  126 
  127 #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
  128 
  129 #include <pthread.h>
  130 
  131 static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
  132 
  133 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
  134 {
  135     pthread_mutex_lock(&global_mutex);
  136 }
  137 
  138 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
  139 {
  140     pthread_mutex_unlock(&global_mutex);
  141 }
  142 
  143 #endif /* SLJIT_UTIL_GLOBAL_LOCK */
  144 
  145 #endif /* _WIN32 */
  146 
  147 /* ------------------------------------------------------------------------ */
  148 /*  Stack                                                                   */
  149 /* ------------------------------------------------------------------------ */
  150 
  151 #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
  152 
  153 #ifdef _WIN32
  154 #include "windows.h"
  155 #else
  156 /* Provides mmap function. */
  157 #include <sys/types.h>
  158 #include <sys/mman.h>
  159 #ifndef MAP_ANON
  160 #ifdef MAP_ANONYMOUS
  161 #define MAP_ANON MAP_ANONYMOUS
  162 #endif
  163 #endif
  164 /* For detecting the page size. */
  165 #include <unistd.h>
  166 
  167 #ifndef MAP_ANON
  168 
  169 #include <fcntl.h>
  170 
  171 /* Some old systems does not have MAP_ANON. */
  172 static sljit_s32 dev_zero = -1;
  173 
  174 #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
  175 
  176 static SLJIT_INLINE sljit_s32 open_dev_zero(void)
  177 {
  178     dev_zero = open("/dev/zero", O_RDWR);
  179     return dev_zero < 0;
  180 }
  181 
  182 #else /* SLJIT_SINGLE_THREADED */
  183 
  184 #include <pthread.h>
  185 
  186 static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
  187 
  188 static SLJIT_INLINE sljit_s32 open_dev_zero(void)
  189 {
  190     pthread_mutex_lock(&dev_zero_mutex);
  191     /* The dev_zero might be initialized by another thread during the waiting. */
  192     if (dev_zero < 0) {
  193         dev_zero = open("/dev/zero", O_RDWR);
  194     }
  195     pthread_mutex_unlock(&dev_zero_mutex);
  196     return dev_zero < 0;
  197 }
  198 
  199 #endif /* SLJIT_SINGLE_THREADED */
  200 
  201 #endif
  202 
  203 #endif
  204 
  205 #endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */
  206 
  207 #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
  208 
  209 /* Planning to make it even more clever in the future. */
  210 static sljit_sw sljit_page_align = 0;
  211 
  212 SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
  213 {
  214     struct sljit_stack *stack;
  215     void *ptr;
  216 #ifdef _WIN32
  217     SYSTEM_INFO si;
  218 #endif
  219 
  220     SLJIT_UNUSED_ARG(allocator_data);
  221     if (start_size > max_size || start_size < 1)
  222         return NULL;
  223 
  224 #ifdef _WIN32
  225     if (!sljit_page_align) {
  226         GetSystemInfo(&si);
  227         sljit_page_align = si.dwPageSize - 1;
  228     }
  229 #else
  230     if (!sljit_page_align) {
  231         sljit_page_align = sysconf(_SC_PAGESIZE);
  232         /* Should never happen. */
  233         if (sljit_page_align < 0)
  234             sljit_page_align = 4096;
  235         sljit_page_align--;
  236     }
  237 #endif
  238 
  239     stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
  240     if (!stack)
  241         return NULL;
  242 
  243     /* Align max_size. */
  244     max_size = (max_size + sljit_page_align) & ~sljit_page_align;
  245 
  246 #ifdef _WIN32
  247     ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
  248     if (!ptr) {
  249         SLJIT_FREE(stack, allocator_data);
  250         return NULL;
  251     }
  252 
  253     stack->min_start = (sljit_u8 *)ptr;
  254     stack->end = stack->min_start + max_size;
  255     stack->start = stack->end;
  256 
  257     if (sljit_stack_resize(stack, stack->end - start_size) == NULL) {
  258         sljit_free_stack(stack, allocator_data);
  259         return NULL;
  260     }
  261 #else
  262 #ifdef MAP_ANON
  263     ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
  264 #else
  265     if (dev_zero < 0) {
  266         if (open_dev_zero()) {
  267             SLJIT_FREE(stack, allocator_data);
  268             return NULL;
  269         }
  270     }
  271     ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
  272 #endif
  273     if (ptr == MAP_FAILED) {
  274         SLJIT_FREE(stack, allocator_data);
  275         return NULL;
  276     }
  277     stack->min_start = (sljit_u8 *)ptr;
  278     stack->end = stack->min_start + max_size;
  279     stack->start = stack->end - start_size;
  280 #endif
  281     stack->top = stack->end;
  282     return stack;
  283 }
  284 
  285 #undef PAGE_ALIGN
  286 
  287 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
  288 {
  289     SLJIT_UNUSED_ARG(allocator_data);
  290 #ifdef _WIN32
  291     VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
  292 #else
  293     munmap((void*)stack->min_start, stack->end - stack->min_start);
  294 #endif
  295     SLJIT_FREE(stack, allocator_data);
  296 }
  297 
  298 SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
  299 {
  300     sljit_uw aligned_old_start;
  301     sljit_uw aligned_new_start;
  302 
  303     if ((new_start < stack->min_start) || (new_start >= stack->end))
  304         return NULL;
  305 
  306 #ifdef _WIN32
  307     aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
  308     aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
  309     if (aligned_new_start != aligned_old_start) {
  310         if (aligned_new_start < aligned_old_start) {
  311             if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
  312                 return NULL;
  313         }
  314         else {
  315             if (!VirtualFree((void*)aligned_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))
  316                 return NULL;
  317         }
  318     }
  319 #else
  320     if (stack->start < new_start) {
  321         aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
  322         aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
  323         /* If madvise is available, we release the unnecessary space. */
  324 #if defined(MADV_DONTNEED)
  325         if (aligned_new_start > aligned_old_start)
  326             madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED);
  327 #elif defined(POSIX_MADV_DONTNEED)
  328         if (aligned_new_start > aligned_old_start)
  329             posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
  330 #endif
  331     }
  332 #endif
  333     stack->start = new_start;
  334     return new_start;
  335 }
  336 
  337 #endif /* SLJIT_UTIL_STACK */
  338 
  339 #endif