#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
&& !(defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
#define SLJIT_ALLOCATOR_LOCK …
#define SLJIT_ALLOCATOR_UNLOCK …
#elif !(defined _WIN32)
#include <pthread.h>
static pthread_mutex_t allocator_lock = …;
#define SLJIT_ALLOCATOR_LOCK() …
#define SLJIT_ALLOCATOR_UNLOCK() …
#else
static HANDLE allocator_lock;
static SLJIT_INLINE void allocator_grab_lock(void)
{
HANDLE lock;
if (SLJIT_UNLIKELY(!InterlockedCompareExchangePointer(&allocator_lock, NULL, NULL))) {
lock = CreateMutex(NULL, FALSE, NULL);
if (InterlockedCompareExchangePointer(&allocator_lock, lock, NULL))
CloseHandle(lock);
}
WaitForSingleObject(allocator_lock, INFINITE);
}
#define SLJIT_ALLOCATOR_LOCK …
#define SLJIT_ALLOCATOR_UNLOCK …
#endif
#endif
#if ((defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
&& !(defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)) \
|| ((defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
&& !((defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) \
|| (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)))
#ifndef _WIN32
#include <sys/types.h>
#include <sys/mman.h>
#ifndef MAP_ANON
#ifdef MAP_ANONYMOUS
#define MAP_ANON …
#endif
#endif
#ifndef MAP_ANON
#include <fcntl.h>
#ifdef O_CLOEXEC
#define SLJIT_CLOEXEC …
#else
#define SLJIT_CLOEXEC …
#endif
static int dev_zero = -1;
#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
static SLJIT_INLINE int open_dev_zero(void)
{
dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
return dev_zero < 0;
}
#else
#include <pthread.h>
static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
static SLJIT_INLINE int open_dev_zero(void)
{
pthread_mutex_lock(&dev_zero_mutex);
if (SLJIT_UNLIKELY(dev_zero < 0))
dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
pthread_mutex_unlock(&dev_zero_mutex);
return dev_zero < 0;
}
#endif
#undef SLJIT_CLOEXEC
#endif
#endif
#endif
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
|| (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
#ifdef _WIN32
static SLJIT_INLINE sljit_uw get_page_alignment(void) {
SYSTEM_INFO si;
static sljit_uw sljit_page_align = 0;
if (!sljit_page_align) {
GetSystemInfo(&si);
sljit_page_align = (sljit_uw)si.dwPageSize - 1;
}
return sljit_page_align;
}
#else
#include <unistd.h>
static SLJIT_INLINE sljit_uw get_page_alignment(void) { … }
#endif
#endif
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
#if (defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
{
struct sljit_stack *stack;
void *ptr;
SLJIT_UNUSED_ARG(allocator_data);
if (start_size > max_size || start_size < 1)
return NULL;
stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
if (stack == NULL)
return NULL;
ptr = SLJIT_MALLOC(max_size, allocator_data);
if (ptr == NULL) {
SLJIT_FREE(stack, allocator_data);
return NULL;
}
stack->min_start = (sljit_u8 *)ptr;
stack->end = stack->min_start + max_size;
stack->start = stack->end - start_size;
stack->top = stack->end;
return stack;
}
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
{
SLJIT_UNUSED_ARG(allocator_data);
SLJIT_FREE((void*)stack->min_start, allocator_data);
SLJIT_FREE(stack, allocator_data);
}
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
{
if ((new_start < stack->min_start) || (new_start >= stack->end))
return NULL;
stack->start = new_start;
return new_start;
}
#else
#ifdef _WIN32
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
{
SLJIT_UNUSED_ARG(allocator_data);
VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
SLJIT_FREE(stack, allocator_data);
}
#else
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
{ … }
#endif
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
{ … }
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
{ … }
#endif
#endif