Annotation of embedaddon/pcre/sljit/sljitUtils.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *    Stack-less Just-In-Time compiler
                      3:  *
                      4:  *    Copyright 2009-2010 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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>