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>
* jit/jit-memory.h: remove file.
* jit/jit-memory.c: rename to jit/jit-util.c.
* jit/jit-string.c: append to jit/jit-util.c.
* include/jit/jit-util.h, jit/jit-alloc.c (jit_malloc_exec)
(jit_free_exec, jit_flush_exec, jit_exec_page_size): remove functions
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>

4
doc/Makefile.am

@ -5,7 +5,6 @@ EXTRA_DIST = $(man_MANS) $(EXTRA_SCRIPTS)
info_TEXINFOS = libjit.texi
libjit_TEXINFOS = \
$(srcdir)/libjitext-alloc.texi \
$(srcdir)/libjitext-apply.texi \
$(srcdir)/libjitext-block.texi \
$(srcdir)/libjitext-context.texi \
@ -30,9 +29,6 @@ libjit_TEXINFOS = \
$(srcdir)/libjitext-plus-function.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
$(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
that it itself uses internally, but which may also be useful to front ends.
@include libjitext-alloc.texi
@include libjitext-util.texi
@include libjitext-meta.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_realloc(void *ptr, unsigned int size) 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_cnew(type) ((type *)jit_calloc(1, sizeof(type)))

124
jit/jit-alloc.c

@ -57,91 +57,22 @@
#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})
* 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})
* @deftypefun {void *} _jit_malloc_exec (unsigned int @var{size})
* Allocate a block of memory that is read/write/executable. Such blocks
* 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,
* some systems may need special handling to create executable code
* segments, so this function must be used instead.
*
* 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
@*/
void *jit_malloc_exec(unsigned int size)
void *
_jit_malloc_exec(unsigned int size)
{
#if defined(JIT_WIN32_PLATFORM)
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
* @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
* to be able to free the block.
* @end deftypefun
@*/
void jit_free_exec(void *ptr, unsigned int size)
void
_jit_free_exec(void *ptr, unsigned int size)
{
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
* 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)
void
_jit_flush_exec(void *ptr, unsigned int size)
{
#define ROUND_BEG_PTR(p) \
@ -269,36 +202,3 @@ void jit_flush_exec(void *ptr, unsigned int size)
#endif
#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);
/* 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 (void *)buf;
@ -118,7 +118,7 @@ void *_jit_create_indirector(unsigned char *buf, void **entry)
arm_mov_reg_reg(inst, ARM_PC, ARM_WORK);
/* 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;
}
@ -137,7 +137,7 @@ void _jit_pad_buffer(unsigned char *buf, int len)
}
/* 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 */

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;
/* 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 */
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 */
ptr = (unsigned char *) jit_malloc_exec((unsigned int) cache->pageSize * factor);
ptr = (unsigned char *) _jit_malloc_exec((unsigned int) cache->pageSize * factor);
if(!ptr)
{
goto failAlloc;
@ -176,7 +176,7 @@ AllocCachePage(jit_cache_t cache, int factor)
sizeof(struct jit_cache_page) * num);
if(!list)
{
jit_free_exec(ptr, cache->pageSize * factor);
_jit_free_exec(ptr, cache->pageSize * factor);
failAlloc:
cache->free_start = 0;
cache->free_end = 0;
@ -380,7 +380,7 @@ _jit_cache_create(jit_context_t context)
}
/* 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)
{
cache_page_size = JIT_CACHE_PAGE_SIZE;
@ -446,7 +446,7 @@ _jit_cache_destroy(jit_cache_t cache)
/* Free all of the cache pages */
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);
}
if(cache->pages)
@ -476,7 +476,7 @@ _jit_cache_extend(jit_cache_t cache, int count)
if((cache->free_start == ((unsigned char *)p->page))
&& (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);
if(cache->pagesLeft >= 0)

2
jit/jit-compile.c

@ -523,7 +523,7 @@ cache_flush(_jit_compile_t *state)
#ifndef JIT_BACKEND_INTERP
/* 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));
#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;
/* 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;
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(!base_address)
{
base_address = jit_malloc_exec(memory_size);
base_address = _jit_malloc_exec(memory_size);
if(!base_address)
{
return 0;
@ -433,7 +433,7 @@ failed_mmap:
read(fd, segment_address, (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;
}
}
@ -458,19 +458,19 @@ static void *map_section(int fd, Elf_Off offset, Elf_Xword file_size,
{
memory_size = file_size;
}
address = jit_malloc_exec(memory_size);
address = _jit_malloc_exec(memory_size);
if(!address)
{
return 0;
}
if(lseek(fd, (off_t)offset, 0) != (off_t)offset)
{
jit_free_exec(address, memory_size);
_jit_free_exec(address, memory_size);
return 0;
}
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 address;
@ -488,7 +488,7 @@ static void unmap_section(void *address, Elf_Xword file_size,
}
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
#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)
{

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->redirector, (void *) context->on_demand_driver,
func, jit_type_get_abi(signature));
jit_flush_exec(func->redirector, jit_redirector_size);
_jit_flush_exec(func->redirector, jit_redirector_size);
#endif
#if !defined(JIT_BACKEND_INTERP) && defined(jit_indirector_size)
_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
/* Add the function to the context list */

4
jit/jit-internal.h

@ -81,6 +81,10 @@ extern "C" {
*/
#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 best alignment to use on the target platform. The final

72
jit/jit-util.c

@ -24,6 +24,9 @@
#include "jit-config.h"
#include <stdio.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#if defined(HAVE_STRING_H)
# include <string.h>
#elif defined(HAVE_STRINGS_H)
@ -48,6 +51,75 @@
#undef jit_memcmp
#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
* @cindex Memory operations

8
jit/jit-vmem.c

@ -108,6 +108,14 @@ jit_vmem_init(void)
#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_vmem_page_size(void)
{

Loading…
Cancel
Save