1f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* 2f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * Stack-less Just-In-Time compiler 3f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 4f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 6f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * Redistribution and use in source and binary forms, with or without modification, are 7f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * permitted provided that the following conditions are met: 8f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 9f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 1. Redistributions of source code must retain the above copyright notice, this list of 10f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * conditions and the following disclaimer. 11f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 12f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * of conditions and the following disclaimer in the documentation and/or other materials 14f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * provided with the distribution. 15f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 16f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich */ 26f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 27f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* ------------------------------------------------------------------------ */ 28f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Locks */ 29f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* ------------------------------------------------------------------------ */ 30f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 31f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) 32f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 33f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) 34f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 35f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) 36f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 37f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE void allocator_grab_lock(void) 38f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 39f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Always successful. */ 40f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 41f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 42f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE void allocator_release_lock(void) 43f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 44f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Always successful. */ 45f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 46f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 47f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ 48f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 49f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) 50f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 51f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) 52f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 53f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Always successful. */ 54f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 55f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 56f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) 57f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 58f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Always successful. */ 59f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 60f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 61f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* SLJIT_UTIL_GLOBAL_LOCK */ 62f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 63f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */ 64f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 65f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include "windows.h" 66f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 67f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) 68f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 69f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic HANDLE allocator_mutex = 0; 70f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 71f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE void allocator_grab_lock(void) 72f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 73f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* No idea what to do if an error occures. Static mutexes should never fail... */ 74f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!allocator_mutex) 75f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich allocator_mutex = CreateMutex(NULL, TRUE, NULL); 76f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 77f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich WaitForSingleObject(allocator_mutex, INFINITE); 78f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 79f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 80f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE void allocator_release_lock(void) 81f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 82f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ReleaseMutex(allocator_mutex); 83f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 84f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 85f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ 86f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 87f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) 88f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 89f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic HANDLE global_mutex = 0; 90f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 91f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) 92f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 93f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* No idea what to do if an error occures. Static mutexes should never fail... */ 94f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!global_mutex) 95f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich global_mutex = CreateMutex(NULL, TRUE, NULL); 96f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 97f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich WaitForSingleObject(global_mutex, INFINITE); 98f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 99f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 100f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) 101f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 102f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ReleaseMutex(global_mutex); 103f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 104f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 105f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* SLJIT_UTIL_GLOBAL_LOCK */ 106f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 107f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else /* _WIN32 */ 108f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 109f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) 110f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 111f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <pthread.h> 112f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 113f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER; 114f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 115f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE void allocator_grab_lock(void) 116f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 117f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich pthread_mutex_lock(&allocator_mutex); 118f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 119f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 120f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE void allocator_release_lock(void) 121f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 122f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich pthread_mutex_unlock(&allocator_mutex); 123f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 124f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 125f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ 126f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 127f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) 128f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 129f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <pthread.h> 130f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 131f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; 132f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 133f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) 134f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 135f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich pthread_mutex_lock(&global_mutex); 136f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 137f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 138f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) 139f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 140f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich pthread_mutex_unlock(&global_mutex); 141f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 142f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 143f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* SLJIT_UTIL_GLOBAL_LOCK */ 144f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 145f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* _WIN32 */ 146f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 147f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* ------------------------------------------------------------------------ */ 148f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Stack */ 149f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* ------------------------------------------------------------------------ */ 150f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 151f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) 152f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 153f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef _WIN32 154f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include "windows.h" 155f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else 156f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Provides mmap function. */ 157f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <sys/mman.h> 158f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* For detecting the page size. */ 159f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <unistd.h> 160f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 161f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifndef MAP_ANON 162f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 163f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <fcntl.h> 164f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 165f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Some old systems does not have MAP_ANON. */ 166f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic sljit_si dev_zero = -1; 167f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 168f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) 169f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 170f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE sljit_si open_dev_zero(void) 171f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 172f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dev_zero = open("/dev/zero", O_RDWR); 173f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return dev_zero < 0; 174f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 175f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 176f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else /* SLJIT_SINGLE_THREADED */ 177f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 178f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <pthread.h> 179f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 180f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER; 181f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 182f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE sljit_si open_dev_zero(void) 183f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 184f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich pthread_mutex_lock(&dev_zero_mutex); 185f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dev_zero = open("/dev/zero", O_RDWR); 186f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich pthread_mutex_unlock(&dev_zero_mutex); 187f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return dev_zero < 0; 188f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 189f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 190f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* SLJIT_SINGLE_THREADED */ 191f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 192f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 193f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 194f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 195f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 196f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */ 197f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 198f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) 199f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 200f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Planning to make it even more clever in the future. */ 201f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic sljit_sw sljit_page_align = 0; 202f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2038366e8beecf85b8e61b5c1a1369666db7a292eaeElliott HughesSLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data) 204f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 205f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_stack *stack; 206f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich union { 207f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich void *ptr; 208f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_uw uw; 209f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } base; 210f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef _WIN32 211f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SYSTEM_INFO si; 212f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 213f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2148366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes SLJIT_UNUSED_ARG(allocator_data); 215f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (limit > max_limit || limit < 1) 216f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return NULL; 217f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 218f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef _WIN32 219f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!sljit_page_align) { 220f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich GetSystemInfo(&si); 221f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_page_align = si.dwPageSize - 1; 222f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 223f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else 224f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!sljit_page_align) { 225f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_page_align = sysconf(_SC_PAGESIZE); 226f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Should never happen. */ 227f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (sljit_page_align < 0) 228f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_page_align = 4096; 229f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_page_align--; 230f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 231f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 232f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 233f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Align limit and max_limit. */ 234f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich max_limit = (max_limit + sljit_page_align) & ~sljit_page_align; 235f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2368366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data); 237f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!stack) 238f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return NULL; 239f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 240f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef _WIN32 241f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich base.ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE); 242f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!base.ptr) { 2438366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes SLJIT_FREE(stack, allocator_data); 244f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return NULL; 245f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 246f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->base = base.uw; 247f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->limit = stack->base; 248f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->max_limit = stack->base + max_limit; 249f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (sljit_stack_resize(stack, stack->base + limit)) { 2508366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes sljit_free_stack(stack, allocator_data); 251f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return NULL; 252f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 253f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else 254f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef MAP_ANON 255f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); 256f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else 257f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dev_zero < 0) { 258f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (open_dev_zero()) { 2598366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes SLJIT_FREE(stack, allocator_data); 260f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return NULL; 261f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 262f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 263f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0); 264f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 265f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (base.ptr == MAP_FAILED) { 2668366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes SLJIT_FREE(stack, allocator_data); 267f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return NULL; 268f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 269f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->base = base.uw; 270f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->limit = stack->base + limit; 271f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->max_limit = stack->base + max_limit; 272f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 273f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->top = stack->base; 274f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return stack; 275f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 276f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 277f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#undef PAGE_ALIGN 278f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2798366e8beecf85b8e61b5c1a1369666db7a292eaeElliott HughesSLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack, void *allocator_data) 280f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 2818366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes SLJIT_UNUSED_ARG(allocator_data); 282f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef _WIN32 283f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich VirtualFree((void*)stack->base, 0, MEM_RELEASE); 284f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else 285f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich munmap((void*)stack->base, stack->max_limit - stack->base); 286f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 2878366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes SLJIT_FREE(stack, allocator_data); 288f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 289f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 290f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit) 291f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 292f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_uw aligned_old_limit; 293f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_uw aligned_new_limit; 294f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 295f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((new_limit > stack->max_limit) || (new_limit < stack->base)) 296f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return -1; 297f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef _WIN32 298f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; 299f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; 300f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (aligned_new_limit != aligned_old_limit) { 301f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (aligned_new_limit > aligned_old_limit) { 302f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE)) 303f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return -1; 304f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 305f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 306f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT)) 307f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return -1; 308f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 309f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 310f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->limit = new_limit; 311f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 312f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else 313f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (new_limit >= stack->limit) { 314f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->limit = new_limit; 315f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 316f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 317f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; 318f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; 319f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* If madvise is available, we release the unnecessary space. */ 320f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined(MADV_DONTNEED) 321f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (aligned_new_limit < aligned_old_limit) 322f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED); 323f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#elif defined(POSIX_MADV_DONTNEED) 324f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (aligned_new_limit < aligned_old_limit) 325f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED); 326f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 327f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich stack->limit = new_limit; 328f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 329f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 330f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 331f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 332f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* SLJIT_UTIL_STACK */ 333f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 334f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 335