File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pcre / sljit / sljitUtils.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:19:18 2012 UTC (11 years, 8 months ago) by misho
Branches: pcre, MAIN
CVS tags: v8_31, HEAD
pcre

    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: #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_CALL sljit_grab_lock(void)
   52: {
   53: 	/* Always successful. */
   54: }
   55: 
   56: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL 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_CALL 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_CALL sljit_release_lock(void)
  101: {
  102: 	ReleaseMutex(global_mutex);
  103: }
  104: 
  105: #endif /* SLJIT_UTIL_GLOBAL_LOCK */
  106: 
  107: #else /* _WIN32 */
  108: 
  109: #include "pthread.h"
  110: 
  111: #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
  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: static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
  130: 
  131: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
  132: {
  133: 	pthread_mutex_lock(&global_mutex);
  134: }
  135: 
  136: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
  137: {
  138: 	pthread_mutex_unlock(&global_mutex);
  139: }
  140: 
  141: #endif /* SLJIT_UTIL_GLOBAL_LOCK */
  142: 
  143: #endif /* _WIN32 */
  144: 
  145: /* ------------------------------------------------------------------------ */
  146: /*  Stack                                                                   */
  147: /* ------------------------------------------------------------------------ */
  148: 
  149: #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
  150: 
  151: #ifdef _WIN32
  152: #include "windows.h"
  153: #else
  154: #include <sys/mman.h>
  155: #include <unistd.h>
  156: #endif
  157: 
  158: /* Planning to make it even more clever in the future. */
  159: static sljit_w sljit_page_align = 0;
  160: 
  161: SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit)
  162: {
  163: 	struct sljit_stack *stack;
  164: 	union {
  165: 		void *ptr;
  166: 		sljit_uw uw;
  167: 	} base;
  168: #ifdef _WIN32
  169: 	SYSTEM_INFO si;
  170: #endif
  171: 
  172: 	if (limit > max_limit || limit < 1)
  173: 		return NULL;
  174: 
  175: #ifdef _WIN32
  176: 	if (!sljit_page_align) {
  177: 		GetSystemInfo(&si);
  178: 		sljit_page_align = si.dwPageSize - 1;
  179: 	}
  180: #else
  181: 	if (!sljit_page_align) {
  182: 		sljit_page_align = sysconf(_SC_PAGESIZE);
  183: 		/* Should never happen. */
  184: 		if (sljit_page_align < 0)
  185: 			sljit_page_align = 4096;
  186: 		sljit_page_align--;
  187: 	}
  188: #endif
  189: 
  190: 	/* Align limit and max_limit. */
  191: 	max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
  192: 
  193: 	stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack));
  194: 	if (!stack)
  195: 		return NULL;
  196: 
  197: #ifdef _WIN32
  198: 	base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE);
  199: 	if (!base.ptr) {
  200: 		SLJIT_FREE(stack);
  201: 		return NULL;
  202: 	}
  203: 	stack->base = base.uw;
  204: 	stack->limit = stack->base;
  205: 	stack->max_limit = stack->base + max_limit;
  206: 	if (sljit_stack_resize(stack, stack->base + limit)) {
  207: 		sljit_free_stack(stack);
  208: 		return NULL;
  209: 	}
  210: #else
  211: 	base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
  212: 	if (base.ptr == MAP_FAILED) {
  213: 		SLJIT_FREE(stack);
  214: 		return NULL;
  215: 	}
  216: 	stack->base = base.uw;
  217: 	stack->limit = stack->base + limit;
  218: 	stack->max_limit = stack->base + max_limit;
  219: #endif
  220: 	stack->top = stack->base;
  221: 	return stack;
  222: }
  223: 
  224: #undef PAGE_ALIGN
  225: 
  226: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack)
  227: {
  228: #ifdef _WIN32
  229: 	VirtualFree((void*)stack->base, 0, MEM_RELEASE);
  230: #else
  231: 	munmap((void*)stack->base, stack->max_limit - stack->base);
  232: #endif
  233: 	SLJIT_FREE(stack);
  234: }
  235: 
  236: SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
  237: {
  238: 	sljit_uw aligned_old_limit;
  239: 	sljit_uw aligned_new_limit;
  240: 
  241: 	if ((new_limit > stack->max_limit) || (new_limit < stack->base))
  242: 		return -1;
  243: #ifdef _WIN32
  244: 	aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
  245: 	aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
  246: 	if (aligned_new_limit != aligned_old_limit) {
  247: 		if (aligned_new_limit > aligned_old_limit) {
  248: 			if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE))
  249: 				return -1;
  250: 		}
  251: 		else {
  252: 			if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT))
  253: 				return -1;
  254: 		}
  255: 	}
  256: 	stack->limit = new_limit;
  257: 	return 0;
  258: #else
  259: 	if (new_limit >= stack->limit) {
  260: 		stack->limit = new_limit;
  261: 		return 0;
  262: 	}
  263: 	aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
  264: 	aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
  265: 	if (aligned_new_limit < aligned_old_limit)
  266: 		posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED);
  267: 	stack->limit = new_limit;
  268: 	return 0;
  269: #endif
  270: }
  271: 
  272: #endif /* SLJIT_UTIL_STACK */
  273: 
  274: #endif

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