PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/pcre/pcre2lib/sljit - sljitUtils.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 32 47 68.1 %
Date: 2022-01-26 Functions: 5 7 71.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *    Stack-less Just-In-Time compiler
       3             :  *
       4             :  *    Copyright 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_FUNC sljit_grab_lock(void)
      52             : {
      53             :         /* Always successful. */
      54             : }
      55             : 
      56             : SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC 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_FUNC 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_FUNC sljit_release_lock(void)
     101             : {
     102             :         ReleaseMutex(global_mutex);
     103             : }
     104             : 
     105             : #endif /* SLJIT_UTIL_GLOBAL_LOCK */
     106             : 
     107             : #else /* _WIN32 */
     108             : 
     109             : #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
     110             : 
     111             : #include <pthread.h>
     112             : 
     113             : static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
     114             : 
     115      103310 : static SLJIT_INLINE void allocator_grab_lock(void)
     116             : {
     117      103310 :         pthread_mutex_lock(&allocator_mutex);
     118      103310 : }
     119             : 
     120      103310 : static SLJIT_INLINE void allocator_release_lock(void)
     121             : {
     122      103310 :         pthread_mutex_unlock(&allocator_mutex);
     123      103310 : }
     124             : 
     125             : #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
     126             : 
     127             : #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
     128             : 
     129             : #include <pthread.h>
     130             : 
     131             : static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
     132             : 
     133           0 : SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
     134             : {
     135           0 :         pthread_mutex_lock(&global_mutex);
     136           0 : }
     137             : 
     138           0 : SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
     139             : {
     140           0 :         pthread_mutex_unlock(&global_mutex);
     141           0 : }
     142             : 
     143             : #endif /* SLJIT_UTIL_GLOBAL_LOCK */
     144             : 
     145             : #endif /* _WIN32 */
     146             : 
     147             : /* ------------------------------------------------------------------------ */
     148             : /*  Stack                                                                   */
     149             : /* ------------------------------------------------------------------------ */
     150             : 
     151             : #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
     152             : 
     153             : #ifdef _WIN32
     154             : #include "windows.h"
     155             : #else
     156             : /* Provides mmap function. */
     157             : #include <sys/mman.h>
     158             : /* For detecting the page size. */
     159             : #include <unistd.h>
     160             : 
     161             : #ifndef MAP_ANON
     162             : 
     163             : #include <fcntl.h>
     164             : 
     165             : /* Some old systems does not have MAP_ANON. */
     166             : static sljit_s32 dev_zero = -1;
     167             : 
     168             : #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
     169             : 
     170             : static SLJIT_INLINE sljit_s32 open_dev_zero(void)
     171             : {
     172             :         dev_zero = open("/dev/zero", O_RDWR);
     173             :         return dev_zero < 0;
     174             : }
     175             : 
     176             : #else /* SLJIT_SINGLE_THREADED */
     177             : 
     178             : #include <pthread.h>
     179             : 
     180             : static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
     181             : 
     182             : static SLJIT_INLINE sljit_s32 open_dev_zero(void)
     183             : {
     184             :         pthread_mutex_lock(&dev_zero_mutex);
     185             :         /* The dev_zero might be initialized by another thread during the waiting. */
     186             :         if (dev_zero < 0) {
     187             :                 dev_zero = open("/dev/zero", O_RDWR);
     188             :         }
     189             :         pthread_mutex_unlock(&dev_zero_mutex);
     190             :         return dev_zero < 0;
     191             : }
     192             : 
     193             : #endif /* SLJIT_SINGLE_THREADED */
     194             : 
     195             : #endif
     196             : 
     197             : #endif
     198             : 
     199             : #endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */
     200             : 
     201             : #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
     202             : 
     203             : /* Planning to make it even more clever in the future. */
     204             : static sljit_sw sljit_page_align = 0;
     205             : 
     206       26000 : SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
     207             : {
     208             :         struct sljit_stack *stack;
     209             :         void *ptr;
     210             : #ifdef _WIN32
     211             :         SYSTEM_INFO si;
     212             : #endif
     213             : 
     214             :         SLJIT_UNUSED_ARG(allocator_data);
     215       26000 :         if (start_size > max_size || start_size < 1)
     216           0 :                 return NULL;
     217             : 
     218             : #ifdef _WIN32
     219             :         if (!sljit_page_align) {
     220             :                 GetSystemInfo(&si);
     221             :                 sljit_page_align = si.dwPageSize - 1;
     222             :         }
     223             : #else
     224       26000 :         if (!sljit_page_align) {
     225       25961 :                 sljit_page_align = sysconf(_SC_PAGESIZE);
     226             :                 /* Should never happen. */
     227       25961 :                 if (sljit_page_align < 0)
     228           0 :                         sljit_page_align = 4096;
     229       25961 :                 sljit_page_align--;
     230             :         }
     231             : #endif
     232             : 
     233       26000 :         stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
     234       26000 :         if (!stack)
     235           0 :                 return NULL;
     236             : 
     237             :         /* Align max_size. */
     238       26000 :         max_size = (max_size + sljit_page_align) & ~sljit_page_align;
     239             : 
     240             : #ifdef _WIN32
     241             :         ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
     242             :         if (!ptr) {
     243             :                 SLJIT_FREE(stack, allocator_data);
     244             :                 return NULL;
     245             :         }
     246             : 
     247             :         stack->min_start = (sljit_u8 *)ptr;
     248             :         stack->end = stack->min_start + max_size;
     249             :         stack->start = stack->end;
     250             : 
     251             :         if (sljit_stack_resize(stack, stack->end - start_size) == NULL) {
     252             :                 sljit_free_stack(stack, allocator_data);
     253             :                 return NULL;
     254             :         }
     255             : #else
     256             : #ifdef MAP_ANON
     257       26000 :         ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
     258             : #else
     259             :         if (dev_zero < 0) {
     260             :                 if (open_dev_zero()) {
     261             :                         SLJIT_FREE(stack, allocator_data);
     262             :                         return NULL;
     263             :                 }
     264             :         }
     265             :         ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
     266             : #endif
     267       26000 :         if (ptr == MAP_FAILED) {
     268           0 :                 SLJIT_FREE(stack, allocator_data);
     269           0 :                 return NULL;
     270             :         }
     271       26000 :         stack->min_start = (sljit_u8 *)ptr;
     272       26000 :         stack->end = stack->min_start + max_size;
     273       26000 :         stack->start = stack->end - start_size;
     274             : #endif
     275       26000 :         stack->top = stack->end;
     276       26000 :         return stack;
     277             : }
     278             : 
     279             : #undef PAGE_ALIGN
     280             : 
     281       26061 : SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
     282             : {
     283             :         SLJIT_UNUSED_ARG(allocator_data);
     284             : #ifdef _WIN32
     285             :         VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
     286             : #else
     287       26061 :         munmap((void*)stack->min_start, stack->end - stack->min_start);
     288             : #endif
     289       26061 :         SLJIT_FREE(stack, allocator_data);
     290       26061 : }
     291             : 
     292          36 : SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
     293             : {
     294             :         sljit_uw aligned_old_start;
     295             :         sljit_uw aligned_new_start;
     296             : 
     297          36 :         if ((new_start < stack->min_start) || (new_start >= stack->end))
     298           1 :                 return NULL;
     299             : 
     300             : #ifdef _WIN32
     301             :         aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
     302             :         aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
     303             :         if (aligned_new_start != aligned_old_start) {
     304             :                 if (aligned_new_start < aligned_old_start) {
     305             :                         if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
     306             :                                 return NULL;
     307             :                 }
     308             :                 else {
     309             :                         if (!VirtualFree((void*)aligned_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))
     310             :                                 return NULL;
     311             :                 }
     312             :         }
     313             : #else
     314          35 :         if (stack->start < new_start) {
     315           0 :                 aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
     316           0 :                 aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
     317             :                 /* If madvise is available, we release the unnecessary space. */
     318             : #if defined(MADV_DONTNEED)
     319           0 :                 if (aligned_new_start > aligned_old_start)
     320           0 :                         madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED);
     321             : #elif defined(POSIX_MADV_DONTNEED)
     322             :                 if (aligned_new_start > aligned_old_start)
     323             :                         posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
     324             : #endif
     325             :         }
     326             : #endif
     327          35 :         stack->start = new_start;
     328          35 :         return new_start;
     329             : }
     330             : 
     331             : #endif /* SLJIT_UTIL_STACK */
     332             : 
     333             : #endif

Generated by: LCOV version 1.10

Generated at Wed, 26 Jan 2022 17:13:56 +0000 (2 days ago)

Copyright © 2005-2022 The PHP Group
All rights reserved.