xref: /aosp_15_r20/external/pcre/src/sljit/sljitUtils.c (revision 22dc650d8ae982c6770746019a6f94af92b0f024)
1*22dc650dSSadaf Ebrahimi /*
2*22dc650dSSadaf Ebrahimi  *    Stack-less Just-In-Time compiler
3*22dc650dSSadaf Ebrahimi  *
4*22dc650dSSadaf Ebrahimi  *    Copyright Zoltan Herczeg ([email protected]). All rights reserved.
5*22dc650dSSadaf Ebrahimi  *
6*22dc650dSSadaf Ebrahimi  * Redistribution and use in source and binary forms, with or without modification, are
7*22dc650dSSadaf Ebrahimi  * permitted provided that the following conditions are met:
8*22dc650dSSadaf Ebrahimi  *
9*22dc650dSSadaf Ebrahimi  *   1. Redistributions of source code must retain the above copyright notice, this list of
10*22dc650dSSadaf Ebrahimi  *      conditions and the following disclaimer.
11*22dc650dSSadaf Ebrahimi  *
12*22dc650dSSadaf Ebrahimi  *   2. Redistributions in binary form must reproduce the above copyright notice, this list
13*22dc650dSSadaf Ebrahimi  *      of conditions and the following disclaimer in the documentation and/or other materials
14*22dc650dSSadaf Ebrahimi  *      provided with the distribution.
15*22dc650dSSadaf Ebrahimi  *
16*22dc650dSSadaf Ebrahimi  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17*22dc650dSSadaf Ebrahimi  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*22dc650dSSadaf Ebrahimi  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19*22dc650dSSadaf Ebrahimi  * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20*22dc650dSSadaf Ebrahimi  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21*22dc650dSSadaf Ebrahimi  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22*22dc650dSSadaf Ebrahimi  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23*22dc650dSSadaf Ebrahimi  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24*22dc650dSSadaf Ebrahimi  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*22dc650dSSadaf Ebrahimi  */
26*22dc650dSSadaf Ebrahimi 
27*22dc650dSSadaf Ebrahimi /* ------------------------------------------------------------------------ */
28*22dc650dSSadaf Ebrahimi /*  Locks                                                                   */
29*22dc650dSSadaf Ebrahimi /* ------------------------------------------------------------------------ */
30*22dc650dSSadaf Ebrahimi 
31*22dc650dSSadaf Ebrahimi /* Executable Allocator */
32*22dc650dSSadaf Ebrahimi 
33*22dc650dSSadaf Ebrahimi #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
34*22dc650dSSadaf Ebrahimi 	&& !(defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
35*22dc650dSSadaf Ebrahimi #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
36*22dc650dSSadaf Ebrahimi #define SLJIT_ALLOCATOR_LOCK()
37*22dc650dSSadaf Ebrahimi #define SLJIT_ALLOCATOR_UNLOCK()
38*22dc650dSSadaf Ebrahimi #elif !(defined _WIN32)
39*22dc650dSSadaf Ebrahimi #include <pthread.h>
40*22dc650dSSadaf Ebrahimi 
41*22dc650dSSadaf Ebrahimi static pthread_mutex_t allocator_lock = PTHREAD_MUTEX_INITIALIZER;
42*22dc650dSSadaf Ebrahimi 
43*22dc650dSSadaf Ebrahimi #define SLJIT_ALLOCATOR_LOCK() pthread_mutex_lock(&allocator_lock)
44*22dc650dSSadaf Ebrahimi #define SLJIT_ALLOCATOR_UNLOCK() pthread_mutex_unlock(&allocator_lock)
45*22dc650dSSadaf Ebrahimi #else /* windows */
46*22dc650dSSadaf Ebrahimi static HANDLE allocator_lock;
47*22dc650dSSadaf Ebrahimi 
allocator_grab_lock(void)48*22dc650dSSadaf Ebrahimi static SLJIT_INLINE void allocator_grab_lock(void)
49*22dc650dSSadaf Ebrahimi {
50*22dc650dSSadaf Ebrahimi 	HANDLE lock;
51*22dc650dSSadaf Ebrahimi 	if (SLJIT_UNLIKELY(!InterlockedCompareExchangePointer(&allocator_lock, NULL, NULL))) {
52*22dc650dSSadaf Ebrahimi 		lock = CreateMutex(NULL, FALSE, NULL);
53*22dc650dSSadaf Ebrahimi 		if (InterlockedCompareExchangePointer(&allocator_lock, lock, NULL))
54*22dc650dSSadaf Ebrahimi 			CloseHandle(lock);
55*22dc650dSSadaf Ebrahimi 	}
56*22dc650dSSadaf Ebrahimi 	WaitForSingleObject(allocator_lock, INFINITE);
57*22dc650dSSadaf Ebrahimi }
58*22dc650dSSadaf Ebrahimi 
59*22dc650dSSadaf Ebrahimi #define SLJIT_ALLOCATOR_LOCK() allocator_grab_lock()
60*22dc650dSSadaf Ebrahimi #define SLJIT_ALLOCATOR_UNLOCK() ReleaseMutex(allocator_lock)
61*22dc650dSSadaf Ebrahimi #endif /* thread implementation */
62*22dc650dSSadaf Ebrahimi #endif /* SLJIT_EXECUTABLE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */
63*22dc650dSSadaf Ebrahimi 
64*22dc650dSSadaf Ebrahimi /* ------------------------------------------------------------------------ */
65*22dc650dSSadaf Ebrahimi /*  Stack                                                                   */
66*22dc650dSSadaf Ebrahimi /* ------------------------------------------------------------------------ */
67*22dc650dSSadaf Ebrahimi 
68*22dc650dSSadaf Ebrahimi #if ((defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
69*22dc650dSSadaf Ebrahimi 	&& !(defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)) \
70*22dc650dSSadaf Ebrahimi 	|| ((defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
71*22dc650dSSadaf Ebrahimi 	&& !((defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) \
72*22dc650dSSadaf Ebrahimi 	|| (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)))
73*22dc650dSSadaf Ebrahimi 
74*22dc650dSSadaf Ebrahimi #ifndef _WIN32
75*22dc650dSSadaf Ebrahimi /* Provides mmap function. */
76*22dc650dSSadaf Ebrahimi #include <sys/types.h>
77*22dc650dSSadaf Ebrahimi #include <sys/mman.h>
78*22dc650dSSadaf Ebrahimi 
79*22dc650dSSadaf Ebrahimi #ifndef MAP_ANON
80*22dc650dSSadaf Ebrahimi #ifdef MAP_ANONYMOUS
81*22dc650dSSadaf Ebrahimi #define MAP_ANON MAP_ANONYMOUS
82*22dc650dSSadaf Ebrahimi #endif /* MAP_ANONYMOUS */
83*22dc650dSSadaf Ebrahimi #endif /* !MAP_ANON */
84*22dc650dSSadaf Ebrahimi 
85*22dc650dSSadaf Ebrahimi #ifndef MAP_ANON
86*22dc650dSSadaf Ebrahimi 
87*22dc650dSSadaf Ebrahimi #include <fcntl.h>
88*22dc650dSSadaf Ebrahimi 
89*22dc650dSSadaf Ebrahimi #ifdef O_CLOEXEC
90*22dc650dSSadaf Ebrahimi #define SLJIT_CLOEXEC	O_CLOEXEC
91*22dc650dSSadaf Ebrahimi #else /* !O_CLOEXEC */
92*22dc650dSSadaf Ebrahimi #define SLJIT_CLOEXEC	0
93*22dc650dSSadaf Ebrahimi #endif /* O_CLOEXEC */
94*22dc650dSSadaf Ebrahimi 
95*22dc650dSSadaf Ebrahimi /* Some old systems do not have MAP_ANON. */
96*22dc650dSSadaf Ebrahimi static int dev_zero = -1;
97*22dc650dSSadaf Ebrahimi 
98*22dc650dSSadaf Ebrahimi #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
99*22dc650dSSadaf Ebrahimi 
open_dev_zero(void)100*22dc650dSSadaf Ebrahimi static SLJIT_INLINE int open_dev_zero(void)
101*22dc650dSSadaf Ebrahimi {
102*22dc650dSSadaf Ebrahimi 	dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
103*22dc650dSSadaf Ebrahimi 
104*22dc650dSSadaf Ebrahimi 	return dev_zero < 0;
105*22dc650dSSadaf Ebrahimi }
106*22dc650dSSadaf Ebrahimi 
107*22dc650dSSadaf Ebrahimi #else /* !SLJIT_SINGLE_THREADED */
108*22dc650dSSadaf Ebrahimi 
109*22dc650dSSadaf Ebrahimi #include <pthread.h>
110*22dc650dSSadaf Ebrahimi 
111*22dc650dSSadaf Ebrahimi static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
112*22dc650dSSadaf Ebrahimi 
open_dev_zero(void)113*22dc650dSSadaf Ebrahimi static SLJIT_INLINE int open_dev_zero(void)
114*22dc650dSSadaf Ebrahimi {
115*22dc650dSSadaf Ebrahimi 	pthread_mutex_lock(&dev_zero_mutex);
116*22dc650dSSadaf Ebrahimi 	if (SLJIT_UNLIKELY(dev_zero < 0))
117*22dc650dSSadaf Ebrahimi 		dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
118*22dc650dSSadaf Ebrahimi 
119*22dc650dSSadaf Ebrahimi 	pthread_mutex_unlock(&dev_zero_mutex);
120*22dc650dSSadaf Ebrahimi 	return dev_zero < 0;
121*22dc650dSSadaf Ebrahimi }
122*22dc650dSSadaf Ebrahimi 
123*22dc650dSSadaf Ebrahimi #endif /* SLJIT_SINGLE_THREADED */
124*22dc650dSSadaf Ebrahimi #undef SLJIT_CLOEXEC
125*22dc650dSSadaf Ebrahimi #endif /* !MAP_ANON */
126*22dc650dSSadaf Ebrahimi #endif /* !_WIN32 */
127*22dc650dSSadaf Ebrahimi #endif /* open_dev_zero */
128*22dc650dSSadaf Ebrahimi 
129*22dc650dSSadaf Ebrahimi #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
130*22dc650dSSadaf Ebrahimi 	|| (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
131*22dc650dSSadaf Ebrahimi 
132*22dc650dSSadaf Ebrahimi #ifdef _WIN32
133*22dc650dSSadaf Ebrahimi 
get_page_alignment(void)134*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_uw get_page_alignment(void) {
135*22dc650dSSadaf Ebrahimi 	SYSTEM_INFO si;
136*22dc650dSSadaf Ebrahimi 	static sljit_uw sljit_page_align = 0;
137*22dc650dSSadaf Ebrahimi 	if (!sljit_page_align) {
138*22dc650dSSadaf Ebrahimi 		GetSystemInfo(&si);
139*22dc650dSSadaf Ebrahimi 		sljit_page_align = (sljit_uw)si.dwPageSize - 1;
140*22dc650dSSadaf Ebrahimi 	}
141*22dc650dSSadaf Ebrahimi 	return sljit_page_align;
142*22dc650dSSadaf Ebrahimi }
143*22dc650dSSadaf Ebrahimi 
144*22dc650dSSadaf Ebrahimi #else
145*22dc650dSSadaf Ebrahimi 
146*22dc650dSSadaf Ebrahimi #include <unistd.h>
147*22dc650dSSadaf Ebrahimi 
get_page_alignment(void)148*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_uw get_page_alignment(void) {
149*22dc650dSSadaf Ebrahimi 	static sljit_uw sljit_page_align = 0;
150*22dc650dSSadaf Ebrahimi 
151*22dc650dSSadaf Ebrahimi 	sljit_sw align;
152*22dc650dSSadaf Ebrahimi 
153*22dc650dSSadaf Ebrahimi 	if (!sljit_page_align) {
154*22dc650dSSadaf Ebrahimi #ifdef _SC_PAGESIZE
155*22dc650dSSadaf Ebrahimi 		align = sysconf(_SC_PAGESIZE);
156*22dc650dSSadaf Ebrahimi #else
157*22dc650dSSadaf Ebrahimi 		align = getpagesize();
158*22dc650dSSadaf Ebrahimi #endif
159*22dc650dSSadaf Ebrahimi 		/* Should never happen. */
160*22dc650dSSadaf Ebrahimi 		if (align < 0)
161*22dc650dSSadaf Ebrahimi 			align = 4096;
162*22dc650dSSadaf Ebrahimi 		sljit_page_align = (sljit_uw)align - 1;
163*22dc650dSSadaf Ebrahimi 	}
164*22dc650dSSadaf Ebrahimi 	return sljit_page_align;
165*22dc650dSSadaf Ebrahimi }
166*22dc650dSSadaf Ebrahimi 
167*22dc650dSSadaf Ebrahimi #endif /* _WIN32 */
168*22dc650dSSadaf Ebrahimi 
169*22dc650dSSadaf Ebrahimi #endif /* get_page_alignment() */
170*22dc650dSSadaf Ebrahimi 
171*22dc650dSSadaf Ebrahimi #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
172*22dc650dSSadaf Ebrahimi 
173*22dc650dSSadaf Ebrahimi #if (defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)
174*22dc650dSSadaf Ebrahimi 
sljit_allocate_stack(sljit_uw start_size,sljit_uw max_size,void * allocator_data)175*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
176*22dc650dSSadaf Ebrahimi {
177*22dc650dSSadaf Ebrahimi 	struct sljit_stack *stack;
178*22dc650dSSadaf Ebrahimi 	void *ptr;
179*22dc650dSSadaf Ebrahimi 
180*22dc650dSSadaf Ebrahimi 	SLJIT_UNUSED_ARG(allocator_data);
181*22dc650dSSadaf Ebrahimi 
182*22dc650dSSadaf Ebrahimi 	if (start_size > max_size || start_size < 1)
183*22dc650dSSadaf Ebrahimi 		return NULL;
184*22dc650dSSadaf Ebrahimi 
185*22dc650dSSadaf Ebrahimi 	stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
186*22dc650dSSadaf Ebrahimi 	if (stack == NULL)
187*22dc650dSSadaf Ebrahimi 		return NULL;
188*22dc650dSSadaf Ebrahimi 
189*22dc650dSSadaf Ebrahimi 	ptr = SLJIT_MALLOC(max_size, allocator_data);
190*22dc650dSSadaf Ebrahimi 	if (ptr == NULL) {
191*22dc650dSSadaf Ebrahimi 		SLJIT_FREE(stack, allocator_data);
192*22dc650dSSadaf Ebrahimi 		return NULL;
193*22dc650dSSadaf Ebrahimi 	}
194*22dc650dSSadaf Ebrahimi 
195*22dc650dSSadaf Ebrahimi 	stack->min_start = (sljit_u8 *)ptr;
196*22dc650dSSadaf Ebrahimi  	stack->end = stack->min_start + max_size;
197*22dc650dSSadaf Ebrahimi  	stack->start = stack->end - start_size;
198*22dc650dSSadaf Ebrahimi 	stack->top = stack->end;
199*22dc650dSSadaf Ebrahimi 	return stack;
200*22dc650dSSadaf Ebrahimi }
201*22dc650dSSadaf Ebrahimi 
sljit_free_stack(struct sljit_stack * stack,void * allocator_data)202*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
203*22dc650dSSadaf Ebrahimi {
204*22dc650dSSadaf Ebrahimi 	SLJIT_UNUSED_ARG(allocator_data);
205*22dc650dSSadaf Ebrahimi 	SLJIT_FREE((void*)stack->min_start, allocator_data);
206*22dc650dSSadaf Ebrahimi 	SLJIT_FREE(stack, allocator_data);
207*22dc650dSSadaf Ebrahimi }
208*22dc650dSSadaf Ebrahimi 
sljit_stack_resize(struct sljit_stack * stack,sljit_u8 * new_start)209*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
210*22dc650dSSadaf Ebrahimi {
211*22dc650dSSadaf Ebrahimi 	if ((new_start < stack->min_start) || (new_start >= stack->end))
212*22dc650dSSadaf Ebrahimi 		return NULL;
213*22dc650dSSadaf Ebrahimi 	stack->start = new_start;
214*22dc650dSSadaf Ebrahimi 	return new_start;
215*22dc650dSSadaf Ebrahimi }
216*22dc650dSSadaf Ebrahimi 
217*22dc650dSSadaf Ebrahimi #else /* !SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */
218*22dc650dSSadaf Ebrahimi 
219*22dc650dSSadaf Ebrahimi #ifdef _WIN32
220*22dc650dSSadaf Ebrahimi 
sljit_free_stack(struct sljit_stack * stack,void * allocator_data)221*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
222*22dc650dSSadaf Ebrahimi {
223*22dc650dSSadaf Ebrahimi 	SLJIT_UNUSED_ARG(allocator_data);
224*22dc650dSSadaf Ebrahimi 	VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
225*22dc650dSSadaf Ebrahimi 	SLJIT_FREE(stack, allocator_data);
226*22dc650dSSadaf Ebrahimi }
227*22dc650dSSadaf Ebrahimi 
228*22dc650dSSadaf Ebrahimi #else /* !_WIN32 */
229*22dc650dSSadaf Ebrahimi 
sljit_free_stack(struct sljit_stack * stack,void * allocator_data)230*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
231*22dc650dSSadaf Ebrahimi {
232*22dc650dSSadaf Ebrahimi 	SLJIT_UNUSED_ARG(allocator_data);
233*22dc650dSSadaf Ebrahimi 	munmap((void*)stack->min_start, (size_t)(stack->end - stack->min_start));
234*22dc650dSSadaf Ebrahimi 	SLJIT_FREE(stack, allocator_data);
235*22dc650dSSadaf Ebrahimi }
236*22dc650dSSadaf Ebrahimi 
237*22dc650dSSadaf Ebrahimi #endif /* _WIN32 */
238*22dc650dSSadaf Ebrahimi 
sljit_allocate_stack(sljit_uw start_size,sljit_uw max_size,void * allocator_data)239*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
240*22dc650dSSadaf Ebrahimi {
241*22dc650dSSadaf Ebrahimi 	struct sljit_stack *stack;
242*22dc650dSSadaf Ebrahimi 	void *ptr;
243*22dc650dSSadaf Ebrahimi 	sljit_uw page_align;
244*22dc650dSSadaf Ebrahimi 
245*22dc650dSSadaf Ebrahimi 	SLJIT_UNUSED_ARG(allocator_data);
246*22dc650dSSadaf Ebrahimi 
247*22dc650dSSadaf Ebrahimi 	if (start_size > max_size || start_size < 1)
248*22dc650dSSadaf Ebrahimi 		return NULL;
249*22dc650dSSadaf Ebrahimi 
250*22dc650dSSadaf Ebrahimi 	stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
251*22dc650dSSadaf Ebrahimi 	if (stack == NULL)
252*22dc650dSSadaf Ebrahimi 		return NULL;
253*22dc650dSSadaf Ebrahimi 
254*22dc650dSSadaf Ebrahimi 	/* Align max_size. */
255*22dc650dSSadaf Ebrahimi 	page_align = get_page_alignment();
256*22dc650dSSadaf Ebrahimi 	max_size = (max_size + page_align) & ~page_align;
257*22dc650dSSadaf Ebrahimi 
258*22dc650dSSadaf Ebrahimi #ifdef _WIN32
259*22dc650dSSadaf Ebrahimi 	ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
260*22dc650dSSadaf Ebrahimi 	if (!ptr) {
261*22dc650dSSadaf Ebrahimi 		SLJIT_FREE(stack, allocator_data);
262*22dc650dSSadaf Ebrahimi 		return NULL;
263*22dc650dSSadaf Ebrahimi 	}
264*22dc650dSSadaf Ebrahimi 
265*22dc650dSSadaf Ebrahimi 	stack->min_start = (sljit_u8 *)ptr;
266*22dc650dSSadaf Ebrahimi 	stack->end = stack->min_start + max_size;
267*22dc650dSSadaf Ebrahimi 	stack->start = stack->end;
268*22dc650dSSadaf Ebrahimi 
269*22dc650dSSadaf Ebrahimi 	if (sljit_stack_resize(stack, stack->end - start_size) == NULL) {
270*22dc650dSSadaf Ebrahimi 		sljit_free_stack(stack, allocator_data);
271*22dc650dSSadaf Ebrahimi 		return NULL;
272*22dc650dSSadaf Ebrahimi 	}
273*22dc650dSSadaf Ebrahimi #else /* !_WIN32 */
274*22dc650dSSadaf Ebrahimi #ifdef MAP_ANON
275*22dc650dSSadaf Ebrahimi 	ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
276*22dc650dSSadaf Ebrahimi #else /* !MAP_ANON */
277*22dc650dSSadaf Ebrahimi 	if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) {
278*22dc650dSSadaf Ebrahimi 		SLJIT_FREE(stack, allocator_data);
279*22dc650dSSadaf Ebrahimi 		return NULL;
280*22dc650dSSadaf Ebrahimi 	}
281*22dc650dSSadaf Ebrahimi 	ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
282*22dc650dSSadaf Ebrahimi #endif /* MAP_ANON */
283*22dc650dSSadaf Ebrahimi 	if (ptr == MAP_FAILED) {
284*22dc650dSSadaf Ebrahimi 		SLJIT_FREE(stack, allocator_data);
285*22dc650dSSadaf Ebrahimi 		return NULL;
286*22dc650dSSadaf Ebrahimi 	}
287*22dc650dSSadaf Ebrahimi 	stack->min_start = (sljit_u8 *)ptr;
288*22dc650dSSadaf Ebrahimi 	stack->end = stack->min_start + max_size;
289*22dc650dSSadaf Ebrahimi 	stack->start = stack->end - start_size;
290*22dc650dSSadaf Ebrahimi #endif /* _WIN32 */
291*22dc650dSSadaf Ebrahimi 
292*22dc650dSSadaf Ebrahimi 	stack->top = stack->end;
293*22dc650dSSadaf Ebrahimi 	return stack;
294*22dc650dSSadaf Ebrahimi }
295*22dc650dSSadaf Ebrahimi 
sljit_stack_resize(struct sljit_stack * stack,sljit_u8 * new_start)296*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
297*22dc650dSSadaf Ebrahimi {
298*22dc650dSSadaf Ebrahimi #if defined _WIN32 || defined(POSIX_MADV_DONTNEED)
299*22dc650dSSadaf Ebrahimi 	sljit_uw aligned_old_start;
300*22dc650dSSadaf Ebrahimi 	sljit_uw aligned_new_start;
301*22dc650dSSadaf Ebrahimi 	sljit_uw page_align;
302*22dc650dSSadaf Ebrahimi #endif
303*22dc650dSSadaf Ebrahimi 
304*22dc650dSSadaf Ebrahimi 	if ((new_start < stack->min_start) || (new_start >= stack->end))
305*22dc650dSSadaf Ebrahimi 		return NULL;
306*22dc650dSSadaf Ebrahimi 
307*22dc650dSSadaf Ebrahimi #ifdef _WIN32
308*22dc650dSSadaf Ebrahimi 	page_align = get_page_alignment();
309*22dc650dSSadaf Ebrahimi 
310*22dc650dSSadaf Ebrahimi 	aligned_new_start = (sljit_uw)new_start & ~page_align;
311*22dc650dSSadaf Ebrahimi 	aligned_old_start = ((sljit_uw)stack->start) & ~page_align;
312*22dc650dSSadaf Ebrahimi 	if (aligned_new_start != aligned_old_start) {
313*22dc650dSSadaf Ebrahimi 		if (aligned_new_start < aligned_old_start) {
314*22dc650dSSadaf Ebrahimi 			if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
315*22dc650dSSadaf Ebrahimi 				return NULL;
316*22dc650dSSadaf Ebrahimi 		}
317*22dc650dSSadaf Ebrahimi 		else {
318*22dc650dSSadaf Ebrahimi 			if (!VirtualFree((void*)aligned_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))
319*22dc650dSSadaf Ebrahimi 				return NULL;
320*22dc650dSSadaf Ebrahimi 		}
321*22dc650dSSadaf Ebrahimi 	}
322*22dc650dSSadaf Ebrahimi #elif defined(POSIX_MADV_DONTNEED)
323*22dc650dSSadaf Ebrahimi 	if (stack->start < new_start) {
324*22dc650dSSadaf Ebrahimi 		page_align = get_page_alignment();
325*22dc650dSSadaf Ebrahimi 
326*22dc650dSSadaf Ebrahimi 		aligned_new_start = (sljit_uw)new_start & ~page_align;
327*22dc650dSSadaf Ebrahimi 		aligned_old_start = ((sljit_uw)stack->start) & ~page_align;
328*22dc650dSSadaf Ebrahimi 
329*22dc650dSSadaf Ebrahimi 		if (aligned_new_start > aligned_old_start) {
330*22dc650dSSadaf Ebrahimi 			posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
331*22dc650dSSadaf Ebrahimi #ifdef MADV_FREE
332*22dc650dSSadaf Ebrahimi 			madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE);
333*22dc650dSSadaf Ebrahimi #endif /* MADV_FREE */
334*22dc650dSSadaf Ebrahimi 		}
335*22dc650dSSadaf Ebrahimi 	}
336*22dc650dSSadaf Ebrahimi #endif /* _WIN32 */
337*22dc650dSSadaf Ebrahimi 
338*22dc650dSSadaf Ebrahimi 	stack->start = new_start;
339*22dc650dSSadaf Ebrahimi 	return new_start;
340*22dc650dSSadaf Ebrahimi }
341*22dc650dSSadaf Ebrahimi 
342*22dc650dSSadaf Ebrahimi #endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */
343*22dc650dSSadaf Ebrahimi 
344*22dc650dSSadaf Ebrahimi #endif /* SLJIT_UTIL_STACK */
345