"Fossies" - the Fresh Open Source Software Archive

Member "pcre-8.42/sljit/sljitUtils.c" (10 Jan 2018, 9435 Bytes) of package /linux/misc/pcre-8.42.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.41_vs_8.42.

    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/mman.h>
  158 /* For detecting the page size. */
  159 #include <unistd.h>
  160 
  161 #ifndef MAP_ANON
  162 
  163 #include <fcntl.h>
  164 
  165 /* Some old systems does not have MAP_ANON. */
  166 static sljit_s32 dev_zero = -1;
  167 
  168 #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
  169 
  170 static SLJIT_INLINE sljit_s32 open_dev_zero(void)
  171 {
  172     dev_zero = open("/dev/zero", O_RDWR);
  173     return dev_zero < 0;
  174 }
  175 
  176 #else /* SLJIT_SINGLE_THREADED */
  177 
  178 #include <pthread.h>
  179 
  180 static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
  181 
  182 static SLJIT_INLINE sljit_s32 open_dev_zero(void)
  183 {
  184     pthread_mutex_lock(&dev_zero_mutex);
  185     /* The dev_zero might be initialized by another thread during the waiting. */
  186     if (dev_zero < 0) {
  187         dev_zero = open("/dev/zero", O_RDWR);
  188     }
  189     pthread_mutex_unlock(&dev_zero_mutex);
  190     return dev_zero < 0;
  191 }
  192 
  193 #endif /* SLJIT_SINGLE_THREADED */
  194 
  195 #endif
  196 
  197 #endif
  198 
  199 #endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */
  200 
  201 #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
  202 
  203 /* Planning to make it even more clever in the future. */
  204 static sljit_sw sljit_page_align = 0;
  205 
  206 SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
  207 {
  208     struct sljit_stack *stack;
  209     void *ptr;
  210 #ifdef _WIN32
  211     SYSTEM_INFO si;
  212 #endif
  213 
  214     SLJIT_UNUSED_ARG(allocator_data);
  215     if (start_size > max_size || start_size < 1)
  216         return NULL;
  217 
  218 #ifdef _WIN32
  219     if (!sljit_page_align) {
  220         GetSystemInfo(&si);
  221         sljit_page_align = si.dwPageSize - 1;
  222     }
  223 #else
  224     if (!sljit_page_align) {
  225         sljit_page_align = sysconf(_SC_PAGESIZE);
  226         /* Should never happen. */
  227         if (sljit_page_align < 0)
  228             sljit_page_align = 4096;
  229         sljit_page_align--;
  230     }
  231 #endif
  232 
  233     stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
  234     if (!stack)
  235         return NULL;
  236 
  237     /* Align max_size. */
  238     max_size = (max_size + sljit_page_align) & ~sljit_page_align;
  239 
  240 #ifdef _WIN32
  241     ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
  242     if (!ptr) {
  243         SLJIT_FREE(stack, allocator_data);
  244         return NULL;
  245     }
  246 
  247     stack->min_start = (sljit_u8 *)ptr;
  248     stack->end = stack->min_start + max_size;
  249     stack->start = stack->end;
  250 
  251     if (sljit_stack_resize(stack, stack->end - start_size) == NULL) {
  252         sljit_free_stack(stack, allocator_data);
  253         return NULL;
  254     }
  255 #else
  256 #ifdef MAP_ANON
  257     ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
  258 #else
  259     if (dev_zero < 0) {
  260         if (open_dev_zero()) {
  261             SLJIT_FREE(stack, allocator_data);
  262             return NULL;
  263         }
  264     }
  265     ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
  266 #endif
  267     if (ptr == MAP_FAILED) {
  268         SLJIT_FREE(stack, allocator_data);
  269         return NULL;
  270     }
  271     stack->min_start = (sljit_u8 *)ptr;
  272     stack->end = stack->min_start + max_size;
  273     stack->start = stack->end - start_size;
  274 #endif
  275     stack->top = stack->end;
  276     return stack;
  277 }
  278 
  279 #undef PAGE_ALIGN
  280 
  281 SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
  282 {
  283     SLJIT_UNUSED_ARG(allocator_data);
  284 #ifdef _WIN32
  285     VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
  286 #else
  287     munmap((void*)stack->min_start, stack->end - stack->min_start);
  288 #endif
  289     SLJIT_FREE(stack, allocator_data);
  290 }
  291 
  292 SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
  293 {
  294     sljit_uw aligned_old_start;
  295     sljit_uw aligned_new_start;
  296 
  297     if ((new_start < stack->min_start) || (new_start >= stack->end))
  298         return NULL;
  299 
  300 #ifdef _WIN32
  301     aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
  302     aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
  303     if (aligned_new_start != aligned_old_start) {
  304         if (aligned_new_start < aligned_old_start) {
  305             if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
  306                 return NULL;
  307         }
  308         else {
  309             if (!VirtualFree((void*)aligned_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))
  310                 return NULL;
  311         }
  312     }
  313 #else
  314     if (stack->start < new_start) {
  315         aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
  316         aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
  317         /* If madvise is available, we release the unnecessary space. */
  318 #if defined(MADV_DONTNEED)
  319         if (aligned_new_start > aligned_old_start)
  320             madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED);
  321 #elif defined(POSIX_MADV_DONTNEED)
  322         if (aligned_new_start > aligned_old_start)
  323             posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
  324 #endif
  325     }
  326 #endif
  327     stack->start = new_start;
  328     return new_start;
  329 }
  330 
  331 #endif /* SLJIT_UTIL_STACK */
  332 
  333 #endif