Annotation of embedaddon/pcre/sljit/sljitUtils.c, revision 1.1.1.3
1.1 misho 1: /*
2: * Stack-less Just-In-Time compiler
3: *
1.1.1.2 misho 4: * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
1.1 misho 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:
1.1.1.3 ! misho 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 */
1.1 misho 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)
1.1.1.3 ! misho 266: posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED);
1.1 misho 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>