Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-alloc.c view on Meta::CPAN
}
/*@
* @deftypefun void _jit_free_exec (void *@var{ptr}, unsigned int @var{size})
* Free a block of memory that was previously allocated by
* @code{_jit_malloc_exec}. The @var{size} must be identical to the
* original allocated size, as some systems need to know this information
* to be able to free the block.
* @end deftypefun
@*/
void
_jit_free_exec(void *ptr, unsigned int size)
{
if(ptr)
{
#if defined(JIT_WIN32_PLATFORM)
VirtualFree(ptr, 0, MEM_RELEASE);
#elif defined(JIT_USE_MMAP)
munmap(ptr, size);
#else
free(ptr);
#endif
}
}
/*@
* @deftypefun void _jit_flush_exec (void *@var{ptr}, unsigned int @var{size})
* Flush the contents of the block at @var{ptr} from the CPU's
* data and instruction caches. This must be used after the code is
* written to an executable code segment, but before the code is
* executed, to prepare it for execution.
* @end deftypefun
@*/
void
_jit_flush_exec(void *ptr, unsigned int size)
{
#define ROUND_BEG_PTR(p) \
((void *)((((jit_nuint)(p)) / CLSIZE) * CLSIZE))
#define ROUND_END_PTR(p,s) \
((void *)(((((jit_nuint)(p)) + (s) + CLSIZE - 1)/CLSIZE)*CLSIZE))
#if defined(__GNUC__)
#if defined(PPC)
#define CLSIZE 4
/* Flush the CPU cache on PPC platforms */
register unsigned char *p;
register unsigned char *end;
/* Flush the data out of the data cache */
p = ROUND_BEG_PTR (ptr);
end = ROUND_END_PTR (p, size);
while (p < end)
{
__asm__ __volatile__ ("dcbst 0,%0" :: "r"(p));
p += CLSIZE;
}
__asm__ __volatile__ ("sync");
/* Invalidate the cache lines in the instruction cache */
p = ROUND_BEG_PTR (ptr);
while (p < end)
{
__asm__ __volatile__ ("icbi 0,%0; isync" :: "r"(p));
p += CLSIZE;
}
__asm__ __volatile__ ("isync");
#elif defined(__sparc)
#define CLSIZE 4
/* Flush the CPU cache on sparc platforms */
register unsigned char *p = ROUND_BEG_PTR (ptr);
register unsigned char *end = ROUND_END_PTR (p, size);
__asm__ __volatile__ ("stbar");
while (p < end)
{
__asm__ __volatile__ ("flush %0" :: "r"(p));
p += CLSIZE;
}
__asm__ __volatile__ ("nop; nop; nop; nop; nop");
#elif (defined(__arm__) || defined(__arm)) && defined(linux)
/* ARM Linux has a "cacheflush" system call */
/* R0 = start of range, R1 = end of range, R3 = flags */
/* flags = 0 indicates data cache, flags = 1 indicates both caches */
__asm __volatile ("mov r0, %0\n"
"mov r1, %1\n"
"mov r2, %2\n"
"swi 0x9f0002 @ sys_cacheflush"
: /* no outputs */
: "r" (ptr),
"r" (((int)ptr) + (int)size),
"r" (0)
: "r0", "r1", "r3" );
#elif (defined(__ia64) || defined(__ia64__)) && defined(linux)
#define CLSIZE 32
register unsigned char *p = ROUND_BEG_PTR (ptr);
register unsigned char *end = ROUND_END_PTR (p, size);
while(p < end)
{
asm volatile("fc %0" :: "r"(p));
p += CLSIZE;
}
asm volatile(";;sync.i;;srlz.i;;");
#endif
#endif /* __GNUC__ */
}
( run in 1.085 second using v1.01-cache-2.11-cpan-119454b85a5 )