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>
info_TEXINFOS = libjit.texi
libjit_TEXINFOS = \
- $(srcdir)/libjitext-alloc.texi \
$(srcdir)/libjitext-apply.texi \
$(srcdir)/libjitext-block.texi \
$(srcdir)/libjitext-context.texi \
$(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 $< >$@
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
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)))
#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,
}
/*@
- * @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)
{
}
/*@
- * @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) \
#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
-}
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;
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;
}
}
/* 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 */
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);
}
/* 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;
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;
}
/* 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;
/* Free all of the cache pages */
for(page = 0; page < cache->numPages; ++page)
{
- jit_free_exec(cache->pages[page].page,
- cache->pageSize * cache->pages[page].factor);
+ _jit_free_exec(cache->pages[page].page,
+ cache->pageSize * cache->pages[page].factor);
}
if(cache->pages)
{
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)
#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
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)
{
/* 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;
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;
}
}
{
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;
}
if((flags & JIT_ELF_IS_MALLOCED) != 0)
{
- jit_free_exec(address, (unsigned int)memory_size);
+ _jit_free_exec(address, (unsigned int)memory_size);
}
}
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)
{
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 */
*/
#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
#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)
#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
#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)
{