Browse Source

Remove jit_malloc_exec() and friends from public API.

cache-refactoring
Aleksey Demakov 12 years ago
parent
commit
ca560895bb
  1. 11
      ChangeLog
  2. 4
      doc/Makefile.am
  3. 1
      doc/libjit.texi
  4. 5
      include/jit/jit-util.h
  5. 124
      jit/jit-alloc.c
  6. 6
      jit/jit-apply-arm.c
  7. 2
      jit/jit-apply.c
  8. 10
      jit/jit-cache.c
  9. 2
      jit/jit-compile.c
  10. 16
      jit/jit-elf-read.c
  11. 4
      jit/jit-function.c
  12. 4
      jit/jit-internal.h
  13. 72
      jit/jit-util.c
  14. 8
      jit/jit-vmem.c

11
ChangeLog

@ -1,8 +1,13 @@
2012-10-12 Aleksey Demakov <ademakov@gmail.com> 2012-10-12 Aleksey Demakov <ademakov@gmail.com>
* jit/jit-memory.h: remove file. * include/jit/jit-util.h, jit/jit-alloc.c (jit_malloc_exec)
* jit/jit-memory.c: rename to jit/jit-util.c. (jit_free_exec, jit_flush_exec, jit_exec_page_size): remove functions
* jit/jit-string.c: append to jit/jit-util.c. from public API.
* jit/jit-internal.h, jit/jit-alloc.c (_jit_malloc_exec)
(_jit_free_exec, _jit_flush_exec): make these functions internal.
* jit/jit-util.c: new file, move here all public util functions from
jit/jit-alloc.c, jit/jit-memory.c, jit/jit-string.c.
2012-10-08 Aleksey Demakov <ademakov@gmail.com> 2012-10-08 Aleksey Demakov <ademakov@gmail.com>

4
doc/Makefile.am

@ -5,7 +5,6 @@ EXTRA_DIST = $(man_MANS) $(EXTRA_SCRIPTS)
info_TEXINFOS = libjit.texi info_TEXINFOS = libjit.texi
libjit_TEXINFOS = \ libjit_TEXINFOS = \
$(srcdir)/libjitext-alloc.texi \
$(srcdir)/libjitext-apply.texi \ $(srcdir)/libjitext-apply.texi \
$(srcdir)/libjitext-block.texi \ $(srcdir)/libjitext-block.texi \
$(srcdir)/libjitext-context.texi \ $(srcdir)/libjitext-context.texi \
@ -30,9 +29,6 @@ libjit_TEXINFOS = \
$(srcdir)/libjitext-plus-function.texi \ $(srcdir)/libjitext-plus-function.texi \
$(srcdir)/libjitext-plus-value.texi $(srcdir)/libjitext-plus-value.texi
$(srcdir)/libjitext-alloc.texi: $(top_srcdir)/jit/jit-alloc.c
$(SHELL) $(srcdir)/extract-docs.sh $< >$@
$(srcdir)/libjitext-apply.texi: $(top_srcdir)/jit/jit-apply.c $(srcdir)/libjitext-apply.texi: $(top_srcdir)/jit/jit-apply.c
$(SHELL) $(srcdir)/extract-docs.sh $< >$@ $(SHELL) $(srcdir)/extract-docs.sh $< >$@

1
doc/libjit.texi

@ -1057,7 +1057,6 @@ field with a @code{pointer to procedure/function} type.
The @code{libjit} library provides a number of utility routines The @code{libjit} library provides a number of utility routines
that it itself uses internally, but which may also be useful to front ends. that it itself uses internally, but which may also be useful to front ends.
@include libjitext-alloc.texi
@include libjitext-util.texi @include libjitext-util.texi
@include libjitext-meta.texi @include libjitext-meta.texi
@include libjitext-apply.texi @include libjitext-apply.texi

5
include/jit/jit-util.h

@ -34,10 +34,7 @@ void *jit_malloc(unsigned int size) JIT_NOTHROW;
void *jit_calloc(unsigned int num, unsigned int size) JIT_NOTHROW; void *jit_calloc(unsigned int num, unsigned int size) JIT_NOTHROW;
void *jit_realloc(void *ptr, unsigned int size) JIT_NOTHROW; void *jit_realloc(void *ptr, unsigned int size) JIT_NOTHROW;
void jit_free(void *ptr) JIT_NOTHROW; void jit_free(void *ptr) JIT_NOTHROW;
void *jit_malloc_exec(unsigned int size) JIT_NOTHROW;
void jit_free_exec(void *ptr, unsigned int size) JIT_NOTHROW;
void jit_flush_exec(void *ptr, unsigned int size) JIT_NOTHROW;
unsigned int jit_exec_page_size(void) JIT_NOTHROW;
#define jit_new(type) ((type *)jit_malloc(sizeof(type))) #define jit_new(type) ((type *)jit_malloc(sizeof(type)))
#define jit_cnew(type) ((type *)jit_calloc(1, sizeof(type))) #define jit_cnew(type) ((type *)jit_calloc(1, sizeof(type)))

124
jit/jit-alloc.c

@ -57,91 +57,22 @@
#endif #endif
#endif #endif
/*@
* @section Memory allocation
*
* The @code{libjit} library provides an interface to the traditional
* system @code{malloc} routines. All heap allocation in @code{libjit}
* goes through these functions. If you need to perform some other kind
* of memory allocation, you can replace these functions with your
* own versions.
@*/
/*@
* @deftypefun {void *} jit_malloc (unsigned int @var{size})
* Allocate @var{size} bytes of memory from the heap.
* @end deftypefun
*
* @deftypefun {type *} jit_new (@var{type})
* Allocate @code{sizeof(@var{type})} bytes of memory from the heap and
* cast the return pointer to @code{@var{type} *}. This is a macro that
* wraps up the underlying @code{jit_malloc} function and is less
* error-prone when allocating structures.
* @end deftypefun
@*/
void *jit_malloc(unsigned int size)
{
return malloc(size);
}
/*@ /*@
* @deftypefun {void *} jit_calloc (unsigned int @var{num}, unsigned int @var{size}) * @deftypefun {void *} _jit_malloc_exec (unsigned int @var{size})
* Allocate @code{@var{num} * @var{size}} bytes of memory from the heap and clear
* them to zero.
* @end deftypefun
*
* @deftypefun {type *} jit_cnew (@var{type})
* Allocate @code{sizeof(@var{type})} bytes of memory from the heap and
* cast the return pointer to @code{@var{type} *}. The memory is cleared
* to zero.
* @end deftypefun
@*/
void *jit_calloc(unsigned int num, unsigned int size)
{
return calloc(num, size);
}
/*@
* @deftypefun {void *} jit_realloc (void *@var{ptr}, unsigned int @var{size})
* Re-allocate the memory at @var{ptr} to be @var{size} bytes in size.
* The memory block at @var{ptr} must have been allocated by a previous
* call to @code{jit_malloc}, @code{jit_calloc}, or @code{jit_realloc}.
* @end deftypefun
@*/
void *jit_realloc(void *ptr, unsigned int size)
{
return realloc(ptr, size);
}
/*@
* @deftypefun void jit_free (void *@var{ptr})
* Free the memory at @var{ptr}. It is safe to pass a NULL pointer.
* @end deftypefun
@*/
void jit_free(void *ptr)
{
if(ptr)
{
free(ptr);
}
}
/*@
* @deftypefun {void *} jit_malloc_exec (unsigned int @var{size})
* Allocate a block of memory that is read/write/executable. Such blocks * Allocate a block of memory that is read/write/executable. Such blocks
* are used to store JIT'ed code, function closures, and other trampolines. * are used to store JIT'ed code, function closures, and other trampolines.
* The size should be a multiple of @code{jit_exec_page_size()}. * The size should be a multiple of @code{jit_vmem_page_size()}.
* *
* This will usually be identical to @code{jit_malloc}. However, * This will usually be identical to @code{jit_malloc}. However,
* some systems may need special handling to create executable code * some systems may need special handling to create executable code
* segments, so this function must be used instead. * segments, so this function must be used instead.
* *
* You must never mix regular and executable segment allocation. That is, * You must never mix regular and executable segment allocation. That is,
* do not use @code{jit_free} to free the result of @code{jit_malloc_exec}. * do not use @code{jit_free} to free the result of @code{_jit_malloc_exec}.
* @end deftypefun * @end deftypefun
@*/ @*/
void *jit_malloc_exec(unsigned int size) void *
_jit_malloc_exec(unsigned int size)
{ {
#if defined(JIT_WIN32_PLATFORM) #if defined(JIT_WIN32_PLATFORM)
return VirtualAlloc(NULL, size, return VirtualAlloc(NULL, size,
@ -162,14 +93,15 @@ void *jit_malloc_exec(unsigned int size)
} }
/*@ /*@
* @deftypefun void jit_free_exec (void *@var{ptr}, unsigned int @var{size}) * @deftypefun void _jit_free_exec (void *@var{ptr}, unsigned int @var{size})
* Free a block of memory that was previously allocated by * Free a block of memory that was previously allocated by
* @code{jit_malloc_exec}. The @var{size} must be identical to the * @code{_jit_malloc_exec}. The @var{size} must be identical to the
* original allocated size, as some systems need to know this information * original allocated size, as some systems need to know this information
* to be able to free the block. * to be able to free the block.
* @end deftypefun * @end deftypefun
@*/ @*/
void jit_free_exec(void *ptr, unsigned int size) void
_jit_free_exec(void *ptr, unsigned int size)
{ {
if(ptr) if(ptr)
{ {
@ -184,14 +116,15 @@ void jit_free_exec(void *ptr, unsigned int size)
} }
/*@ /*@
* @deftypefun void jit_flush_exec (void *@var{ptr}, unsigned int @var{size}) * @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 * 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 * data and instruction caches. This must be used after the code is
* written to an executable code segment, but before the code is * written to an executable code segment, but before the code is
* executed, to prepare it for execution. * executed, to prepare it for execution.
* @end deftypefun * @end deftypefun
@*/ @*/
void jit_flush_exec(void *ptr, unsigned int size) void
_jit_flush_exec(void *ptr, unsigned int size)
{ {
#define ROUND_BEG_PTR(p) \ #define ROUND_BEG_PTR(p) \
@ -269,36 +202,3 @@ void jit_flush_exec(void *ptr, unsigned int size)
#endif #endif
#endif /* __GNUC__ */ #endif /* __GNUC__ */
} }
/*@
* @deftypefun {unsigned int} jit_exec_page_size (void)
* Get the page allocation size for the system. This is the preferred
* unit when making calls to @code{jit_malloc_exec}. It is not
* required that you supply a multiple of this size when allocating,
* but it can lead to better performance on some systems.
* @end deftypefun
@*/
unsigned int jit_exec_page_size(void)
{
#ifndef JIT_WIN32_PLATFORM
/* Get the page size using a Unix-like sequence */
#ifdef HAVE_GETPAGESIZE
return (unsigned long)getpagesize();
#else
#ifdef NBPG
return NBPG;
#else
#ifdef PAGE_SIZE
return PAGE_SIZE;
#else
return 4096;
#endif
#endif
#endif
#else
/* Get the page size from a Windows-specific API */
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
return (unsigned long)(sysInfo.dwPageSize);
#endif
}

6
jit/jit-apply-arm.c

@ -91,7 +91,7 @@ void *_jit_create_redirector(unsigned char *buf, void *func,
arm_mov_reg_reg(inst, ARM_PC, ARM_R12); arm_mov_reg_reg(inst, ARM_PC, ARM_R12);
/* Flush the cache lines that we just wrote */ /* Flush the cache lines that we just wrote */
jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf); _jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf);
/* Return the aligned start of the buffer as the entry point */ /* Return the aligned start of the buffer as the entry point */
return (void *)buf; return (void *)buf;
@ -118,7 +118,7 @@ void *_jit_create_indirector(unsigned char *buf, void **entry)
arm_mov_reg_reg(inst, ARM_PC, ARM_WORK); arm_mov_reg_reg(inst, ARM_PC, ARM_WORK);
/* Flush the cache lines that we just wrote */ /* Flush the cache lines that we just wrote */
jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf); _jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf);
return start; return start;
} }
@ -137,7 +137,7 @@ void _jit_pad_buffer(unsigned char *buf, int len)
} }
/* Flush the cache lines that we just wrote */ /* Flush the cache lines that we just wrote */
jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf); _jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf);
} }
#endif /* arm */ #endif /* arm */

2
jit/jit-apply.c

@ -906,7 +906,7 @@ jit_closure_create(jit_context_t context, jit_type_t signature, jit_closure_func
closure->user_data = user_data; closure->user_data = user_data;
/* Perform a cache flush on the closure's code */ /* Perform a cache flush on the closure's code */
jit_flush_exec(closure->buf, sizeof(closure->buf)); _jit_flush_exec(closure->buf, sizeof(closure->buf));
/* Unlock the cache, as we are finished with it */ /* Unlock the cache, as we are finished with it */
jit_mutex_unlock(&context->cache_lock); jit_mutex_unlock(&context->cache_lock);

10
jit/jit-cache.c

@ -146,7 +146,7 @@ AllocCachePage(jit_cache_t cache, int factor)
} }
/* Try to allocate a physical page */ /* Try to allocate a physical page */
ptr = (unsigned char *) jit_malloc_exec((unsigned int) cache->pageSize * factor); ptr = (unsigned char *) _jit_malloc_exec((unsigned int) cache->pageSize * factor);
if(!ptr) if(!ptr)
{ {
goto failAlloc; goto failAlloc;
@ -176,7 +176,7 @@ AllocCachePage(jit_cache_t cache, int factor)
sizeof(struct jit_cache_page) * num); sizeof(struct jit_cache_page) * num);
if(!list) if(!list)
{ {
jit_free_exec(ptr, cache->pageSize * factor); _jit_free_exec(ptr, cache->pageSize * factor);
failAlloc: failAlloc:
cache->free_start = 0; cache->free_start = 0;
cache->free_end = 0; cache->free_end = 0;
@ -380,7 +380,7 @@ _jit_cache_create(jit_context_t context)
} }
/* determine the default cache page size */ /* determine the default cache page size */
exec_page_size = jit_exec_page_size(); exec_page_size = jit_vmem_page_size();
if(cache_page_size <= 0) if(cache_page_size <= 0)
{ {
cache_page_size = JIT_CACHE_PAGE_SIZE; cache_page_size = JIT_CACHE_PAGE_SIZE;
@ -446,7 +446,7 @@ _jit_cache_destroy(jit_cache_t cache)
/* Free all of the cache pages */ /* Free all of the cache pages */
for(page = 0; page < cache->numPages; ++page) for(page = 0; page < cache->numPages; ++page)
{ {
jit_free_exec(cache->pages[page].page, _jit_free_exec(cache->pages[page].page,
cache->pageSize * cache->pages[page].factor); cache->pageSize * cache->pages[page].factor);
} }
if(cache->pages) if(cache->pages)
@ -476,7 +476,7 @@ _jit_cache_extend(jit_cache_t cache, int count)
if((cache->free_start == ((unsigned char *)p->page)) if((cache->free_start == ((unsigned char *)p->page))
&& (cache->free_end == (cache->free_start + cache->pageSize * p->factor))) && (cache->free_end == (cache->free_start + cache->pageSize * p->factor)))
{ {
jit_free_exec(p->page, cache->pageSize * p->factor); _jit_free_exec(p->page, cache->pageSize * p->factor);
--(cache->numPages); --(cache->numPages);
if(cache->pagesLeft >= 0) if(cache->pagesLeft >= 0)

2
jit/jit-compile.c

@ -523,7 +523,7 @@ cache_flush(_jit_compile_t *state)
#ifndef JIT_BACKEND_INTERP #ifndef JIT_BACKEND_INTERP
/* On success perform a CPU cache flush, to make the code executable */ /* On success perform a CPU cache flush, to make the code executable */
jit_flush_exec(state->code_start, _jit_flush_exec(state->code_start,
(unsigned int)(state->code_end - state->code_start)); (unsigned int)(state->code_end - state->code_start));
#endif #endif

16
jit/jit-elf-read.c

@ -299,7 +299,7 @@ static int map_program(jit_readelf_t readelf, int fd)
int zero_fd, prot; int zero_fd, prot;
/* Round the total memory and file sizes up to the CPU page size */ /* Round the total memory and file sizes up to the CPU page size */
page_size = (Elf_Off)(jit_exec_page_size()); page_size = (Elf_Off)(jit_vmem_page_size());
end = memory_size; end = memory_size;
if((end % page_size) != 0) if((end % page_size) != 0)
{ {
@ -416,7 +416,7 @@ failed_mmap:
/* If we haven't mapped the file yet, then fall back to "malloc" */ /* If we haven't mapped the file yet, then fall back to "malloc" */
if(!base_address) if(!base_address)
{ {
base_address = jit_malloc_exec(memory_size); base_address = _jit_malloc_exec(memory_size);
if(!base_address) if(!base_address)
{ {
return 0; return 0;
@ -433,7 +433,7 @@ failed_mmap:
read(fd, segment_address, (size_t)(phdr->p_filesz)) read(fd, segment_address, (size_t)(phdr->p_filesz))
!= (int)(size_t)(phdr->p_filesz)) != (int)(size_t)(phdr->p_filesz))
{ {
jit_free_exec(base_address, memory_size); _jit_free_exec(base_address, memory_size);
return 0; return 0;
} }
} }
@ -458,19 +458,19 @@ static void *map_section(int fd, Elf_Off offset, Elf_Xword file_size,
{ {
memory_size = file_size; memory_size = file_size;
} }
address = jit_malloc_exec(memory_size); address = _jit_malloc_exec(memory_size);
if(!address) if(!address)
{ {
return 0; return 0;
} }
if(lseek(fd, (off_t)offset, 0) != (off_t)offset) if(lseek(fd, (off_t)offset, 0) != (off_t)offset)
{ {
jit_free_exec(address, memory_size); _jit_free_exec(address, memory_size);
return 0; return 0;
} }
if(read(fd, address, (size_t)file_size) != (int)(size_t)file_size) if(read(fd, address, (size_t)file_size) != (int)(size_t)file_size)
{ {
jit_free_exec(address, memory_size); _jit_free_exec(address, memory_size);
return 0; return 0;
} }
return address; return address;
@ -488,7 +488,7 @@ static void unmap_section(void *address, Elf_Xword file_size,
} }
if((flags & JIT_ELF_IS_MALLOCED) != 0) if((flags & JIT_ELF_IS_MALLOCED) != 0)
{ {
jit_free_exec(address, (unsigned int)memory_size); _jit_free_exec(address, (unsigned int)memory_size);
} }
} }
@ -1105,7 +1105,7 @@ void jit_readelf_close(jit_readelf_t readelf)
else else
#endif #endif
{ {
jit_free_exec(readelf->map_address, readelf->map_size); _jit_free_exec(readelf->map_address, readelf->map_size);
} }
for(index = 0; index < readelf->ehdr.e_shnum; ++index) for(index = 0; index < readelf->ehdr.e_shnum; ++index)
{ {

4
jit/jit-function.c

@ -103,11 +103,11 @@ jit_function_create(jit_context_t context, jit_type_t signature)
func->entry_point = _jit_create_redirector func->entry_point = _jit_create_redirector
(func->redirector, (void *) context->on_demand_driver, (func->redirector, (void *) context->on_demand_driver,
func, jit_type_get_abi(signature)); func, jit_type_get_abi(signature));
jit_flush_exec(func->redirector, jit_redirector_size); _jit_flush_exec(func->redirector, jit_redirector_size);
#endif #endif
#if !defined(JIT_BACKEND_INTERP) && defined(jit_indirector_size) #if !defined(JIT_BACKEND_INTERP) && defined(jit_indirector_size)
_jit_create_indirector(func->indirector, (void**) &(func->entry_point)); _jit_create_indirector(func->indirector, (void**) &(func->entry_point));
jit_flush_exec(func->indirector, jit_indirector_size); _jit_flush_exec(func->indirector, jit_indirector_size);
#endif #endif
/* Add the function to the context list */ /* Add the function to the context list */

4
jit/jit-internal.h

@ -81,6 +81,10 @@ extern "C" {
*/ */
#include "jit-varint.h" #include "jit-varint.h"
void *_jit_malloc_exec(unsigned int size);
void _jit_free_exec(void *ptr, unsigned int size);
void _jit_flush_exec(void *ptr, unsigned int size);
/* /*
* The following is some macro magic that attempts to detect * The following is some macro magic that attempts to detect
* the best alignment to use on the target platform. The final * the best alignment to use on the target platform. The final

72
jit/jit-util.c

@ -24,6 +24,9 @@
#include "jit-config.h" #include "jit-config.h"
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#if defined(HAVE_STRING_H) #if defined(HAVE_STRING_H)
# include <string.h> # include <string.h>
#elif defined(HAVE_STRINGS_H) #elif defined(HAVE_STRINGS_H)
@ -48,6 +51,75 @@
#undef jit_memcmp #undef jit_memcmp
#undef jit_memchr #undef jit_memchr
/*@
* @section Memory allocation
*
* The @code{libjit} library provides an interface to the traditional
* system @code{malloc} routines. All heap allocation in @code{libjit}
* goes through these functions. If you need to perform some other kind
* of memory allocation, you can replace these functions with your
* own versions.
@*/
/*@
* @deftypefun {void *} jit_malloc (unsigned int @var{size})
* Allocate @var{size} bytes of memory from the heap.
* @end deftypefun
*
* @deftypefun {type *} jit_new (@var{type})
* Allocate @code{sizeof(@var{type})} bytes of memory from the heap and
* cast the return pointer to @code{@var{type} *}. This is a macro that
* wraps up the underlying @code{jit_malloc} function and is less
* error-prone when allocating structures.
* @end deftypefun
@*/
void *jit_malloc(unsigned int size)
{
return malloc(size);
}
/*@
* @deftypefun {void *} jit_calloc (unsigned int @var{num}, unsigned int @var{size})
* Allocate @code{@var{num} * @var{size}} bytes of memory from the heap and clear
* them to zero.
* @end deftypefun
*
* @deftypefun {type *} jit_cnew (@var{type})
* Allocate @code{sizeof(@var{type})} bytes of memory from the heap and
* cast the return pointer to @code{@var{type} *}. The memory is cleared
* to zero.
* @end deftypefun
@*/
void *jit_calloc(unsigned int num, unsigned int size)
{
return calloc(num, size);
}
/*@
* @deftypefun {void *} jit_realloc (void *@var{ptr}, unsigned int @var{size})
* Re-allocate the memory at @var{ptr} to be @var{size} bytes in size.
* The memory block at @var{ptr} must have been allocated by a previous
* call to @code{jit_malloc}, @code{jit_calloc}, or @code{jit_realloc}.
* @end deftypefun
@*/
void *jit_realloc(void *ptr, unsigned int size)
{
return realloc(ptr, size);
}
/*@
* @deftypefun void jit_free (void *@var{ptr})
* Free the memory at @var{ptr}. It is safe to pass a NULL pointer.
* @end deftypefun
@*/
void jit_free(void *ptr)
{
if(ptr)
{
free(ptr);
}
}
/*@ /*@
* @section Memory set, copy, compare, etc * @section Memory set, copy, compare, etc
* @cindex Memory operations * @cindex Memory operations

8
jit/jit-vmem.c

@ -108,6 +108,14 @@ jit_vmem_init(void)
#endif #endif
} }
/*@
* @deftypefun {unsigned int} jit_vmem_page_size (void)
* Get the page allocation size for the system. This is the preferred
* unit when making calls to @code{_jit_malloc_exec}. It is not
* required that you supply a multiple of this size when allocating,
* but it can lead to better performance on some systems.
* @end deftypefun
@*/
jit_uint jit_uint
jit_vmem_page_size(void) jit_vmem_page_size(void)
{ {

Loading…
Cancel
Save