# Patch created by krokas
# Date: Mon Aug 14 21:21:17 MSD 2006
# Repository: libjit
# Comments:
# 
#### End of Preamble ####

#### Patch data follows ####
Index: include/jit/jit-common.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/include/jit/jit-common.h,v
retrieving revision 1.2
diff -c -r1.2 jit-common.h
*** include/jit/jit-common.h	6 Oct 2004 05:43:15 -0000	1.2
--- include/jit/jit-common.h	14 Aug 2006 17:20:59 -0000
***************
*** 38,43 ****
--- 38,48 ----
  typedef struct _jit_function *jit_function_t;
  
  /*
+  * Opaque structure that represents a memory stack.
+  */
+ typedef struct _jit_mem_stack *jit_mem_stack_t;
+ 
+ /*
   * Opaque type that represents the compiled form of a function.
   */
  typedef void *jit_function_compiled_t;
Index: include/jit/jit-util.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/include/jit/jit-util.h,v
retrieving revision 1.5
diff -c -r1.5 jit-util.h
*** include/jit/jit-util.h	8 May 2004 01:36:42 -0000	1.5
--- include/jit/jit-util.h	14 Aug 2006 17:21:00 -0000
***************
*** 34,43 ****
  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)))
  
--- 34,50 ----
  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(jit_mem_stack_t stack, 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;
+ void jit_page_init(void) JIT_NOTHROW;
+ void *jit_page_alloc(unsigned long size) JIT_NOTHROW;
+ void jit_page_free(void *ptr, unsigned long size) JIT_NOTHROW;
+ void jit_mem_stack_init(jit_mem_stack_t stack, unsigned long maxSize) JIT_NOTHROW;
+ void jit_mem_stack_destroy(jit_mem_stack_t stack) JIT_NOTHROW;
+ void *jit_mem_stack_alloc_item(jit_mem_stack_t stack, unsigned int size) JIT_NOTHROW;
+ 
  #define	jit_new(type)		((type *)jit_malloc(sizeof(type)))
  #define	jit_cnew(type)		((type *)jit_calloc(1, sizeof(type)))
  
Index: jit/jit-alloc.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-alloc.c,v
retrieving revision 1.4
diff -c -r1.4 jit-alloc.c
*** jit/jit-alloc.c	7 Jun 2004 22:07:11 -0000	1.4
--- jit/jit-alloc.c	14 Aug 2006 17:21:02 -0000
***************
*** 41,46 ****
--- 41,56 ----
  	#include <io.h>
  #endif
  
+ #include "jit-rules.h"
+ 
+ /*
+  * Determine if we should use the system's malloc heap.
+  */
+ #if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \
+     !(defined(HAVE_MMAP) && defined(HAVE_MUNMAP))
+     #define JIT_USE_MALLOC_FOR_PAGES
+ #endif
+ 
  /*@
   * @section Memory allocation
   *
***************
*** 111,132 ****
  }
  
  /*@
!  * @deftypefun {void *} jit_malloc_exec ({unsigned int} 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()}.
   *
   * 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}.
   * @end deftypefun
  @*/
! void *jit_malloc_exec(unsigned int size)
  {
  	return malloc(size);
  }
  
  /*@
--- 121,149 ----
  }
  
  /*@
!  * @deftypefun {void *} jit_malloc_exec ({jit_mem_stack_t} stack, {unsigned int} 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()}.
   *
   * 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. For instance,
!  * on Alpha GNU/Linux and Fedora Code x86 we need to use mmap instead
!  * of malloc.
   *
   * 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}.
+  * @code{stack} is a memory stack available to execute native code within.
   * @end deftypefun
  @*/
! void *jit_malloc_exec(jit_mem_stack_t stack, unsigned int size)
  {
+ #ifndef JIT_USE_MALLOC_FOR_PAGES
+ 	return jit_mem_stack_alloc_item(stack, size);
+ #else
  	return malloc(size);
+ #endif
  }
  
  /*@
***************
*** 141,147 ****
--- 158,168 ----
  {
  	if(ptr)
  	{
+ #ifndef JIT_USE_MALLOC_FOR_PAGES
+ 		jit_page_free(ptr, size);
+ #else
  		free(ptr);
+ #endif
  	}
  }
  
***************
*** 264,266 ****
--- 285,516 ----
  	return (unsigned long)(sysInfo.dwPageSize);
  #endif
  }
+ 
+ #define _jit_call_once(func)	\
+ 			    do { \
+ 				    static int __once = 0; \
+ 				    if(!__once) \
+ 				    { \
+ 					    __once = 1; \
+ 					    (*(func))(); \
+ 				    } \
+ 				} while(0)
+ 
+ 
+ /*
+  * Make sure that "MAP_ANON" is correctly defined, because it
+  * may not exist on some variants of Unix.
+  */
+ #ifndef MAP_ANON
+     #ifndef MAP_ANONYMOUS
+         #define MAP_ANON        0
+     #else
+         #define MAP_ANON        MAP_ANONYMOUS
+     #endif
+ #endif
+ 
+ /*
+  * Control variables for page allocation.
+  */
+ static int zero_fd = -1;
+ 
+ /*@
+  * @deftypefun void jit_page_init (void)
+  * Initialize the page allocation subsystem.  Only called once.
+  * @end deftypefun
+ @*/
+ void jit_page_init(void)
+ {
+ 	void *addr;
+ 	zero_fd = open("/dev/zero", O_RDWR, 0);
+ 	if(zero_fd != -1)
+ 	{
+ 		/* Set the descriptor to "no-inherit" */
+ 		fcntl(zero_fd, F_SETFD, 1);
+ 
+ 		/* Try to allocate a page, which should tell us if "/dev/zero"
+ 		   is actually live and working on this platform */
+ 		addr = mmap((void *)0, jit_exec_page_size(),
+ 				    PROT_READ | PROT_WRITE | PROT_EXEC,
+ 				    MAP_SHARED | MAP_ANON, zero_fd, 0);
+ 		if(addr == (void *)(-1))
+ 		{
+ 			close(zero_fd);
+ 			zero_fd = -1;
+ 		}
+ 		else
+ 		{
+ 			munmap(addr, jit_exec_page_size());
+ 		}
+ 	}
+ }
+ 
+ /*@
+  * @deftypefun {void *} jit_page_alloc ({unsigned long} size)
+  * Allocate a page of native memory which is read/write/executable.
+  * @end deftypefun
+ @*/
+ void *jit_page_alloc(unsigned long size)
+ {
+ 	/* Initialize the page allocation routines */
+ 	_jit_call_once(jit_page_init);
+ 
+ 	/* Determine if we can should mmap or calloc */
+ 	if(zero_fd != -1)
+ 	{
+ 		void *addr = mmap((void *)0, size,
+ 						  PROT_READ | PROT_WRITE | PROT_EXEC,
+ 						  MAP_SHARED | MAP_ANON, zero_fd, 0);
+ 		if(addr == (void *)(-1))
+ 		{
+ 			/* The allocation failed */
+ 			return 0;
+ 		}
+ 		else
+ 		{
+ 			return addr;
+ 		}
+ 	}
+ 	else
+ 	{
+ 		return jit_malloc(size);
+ 	}
+ }
+ 
+ /*@
+  * @deftypefun void jit_page_free ({void *} ptr, {unsigned long} size)
+  * Free all native memory at @code{ptr} that has been allocated 
+  * with @code{jit_page_alloc}.
+  * @end deftypefun
+ @*/
+ void jit_page_free(void *ptr, unsigned long size)
+ {
+ 	if(zero_fd != -1)
+ 	{
+ 		munmap(ptr, size);
+ 	}
+ 	else
+ 	{
+ 		jit_free(ptr);
+ 	}
+ }
+ 
+ /*
+  * Tuning parameters.
+  */
+ #ifndef	JIT_MEMSTACK_BLOCK_SIZE
+ #define	JIT_MEMSTACK_BLOCK_SIZE			262144
+ #endif
+ #ifndef	JIT_MEMSTACK_MAX_OBJECT_SIZE
+ #define	JIT_MEMSTACK_MAX_OBJECT_SIZE		65536
+ #endif
+ 
+ /*@
+  * @deftypefun void jit_mem_stack_init ({jit_mem_stack_t} stack, {unsigned long} maxSize)
+  * Initialize @code{stack} with @code{maxSize} bytes.
+  * @end deftypefun
+ @*/
+ void jit_mem_stack_init(jit_mem_stack_t stack, unsigned long maxSize)
+ {
+ 	stack->size = JIT_MEMSTACK_BLOCK_SIZE & ~(jit_exec_page_size() - 1);
+ 	stack->posn = stack->size;
+ 	stack->blocks = 0;
+ 	stack->currSize = 0;
+ 	stack->maxSize = maxSize;
+ 	stack->extras = 0;
+ }
+ 
+ /*@
+  * @deftypefun void jit_mem_stack_destroy ({jit_mem_stack_t} stack, {unsigned long} maxSize)
+  * Destroy all memory associated with @code{stack}.
+  * @end deftypefun
+ @*/
+ void jit_mem_stack_destroy(jit_mem_stack_t stack)
+ {
+ 	void *block, *next;
+ 	block = stack->blocks;
+ 	unsigned int size;
+ 	while(block != 0)
+ 	{
+ 		next = *((void **)block);
+ 		jit_page_free(block, stack->size);
+ 		block = next;
+ 	}
+ 	block = stack->extras;
+ 	while(block != 0)
+ 	{
+ 		next = ((void **)block)[0];
+ 		size = ((void **)block)[1];
+ 		jit_page_free(block, size);
+ 		block = next;
+ 	}
+ 	stack->posn = stack->size;
+ 	stack->blocks = 0;
+ 	stack->currSize = 0;
+ 	stack->extras = 0;
+ }
+ 
+ /*@
+  * @deftypefun {void *} jit_mem_stack_alloc_item ({jit_mem_stack_t} stack, {unsigned int} size)
+  * Allocate an item in @code{stack} of @code{size} bytes.
+  * @end deftypefun
+ @*/
+ void *jit_mem_stack_alloc_item(jit_mem_stack_t stack, unsigned int size)
+ {
+ 	void *ptr;
+ 
+ 	/* Round up the size to the nearest alignment boundary */
+ 	size = (size + JIT_FUNCTION_ALIGNMENT - 1) & ~(JIT_FUNCTION_ALIGNMENT - 1);
+ 	/* If the size is greater than the maximum object size,
+ 	   then put the data into a separate malloc'ed block */
+ 	if(size > JIT_MEMSTACK_MAX_OBJECT_SIZE)
+ 	{
+ 		if(stack->maxSize && (stack->currSize + size + 64) > stack->maxSize)
+ 		{
+ 			/* We've reached the built-in limit for the stack */
+ 			printf("jit_mem_stack_alloc_item: We've reached the built-in limit for the stack\n");
+ 			jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
+ 			return 0;
+ 		}
+ 		ptr = jit_page_alloc(size + JIT_FUNCTION_ALIGNMENT);
+ 		if(!ptr)
+ 		{
+ 			/* The system itself is out of memory */
+ 			jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
+ 			return 0;
+ 		}
+ 		stack->currSize += size + 64;
+ 		((void **)ptr)[0] = stack->extras;
+ 		((void **)ptr)[1] = size + JIT_FUNCTION_ALIGNMENT;
+ 		stack->extras = ptr;
+ 		return (void *)(((unsigned char *)ptr) + JIT_FUNCTION_ALIGNMENT);
+ 	}
+ 
+ 	/* Do we need to allocate a new block? */
+ 	if((stack->posn + size) > stack->size)
+ 	{
+ 		if(stack->maxSize && stack->currSize >= stack->maxSize)
+ 		{
+ 			/* We've reached the built-in limit for the stack */
+ 			printf("We've reached the built-in limit for the stack\n");
+ 			jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
+ 			return 0;
+ 		}
+ 		ptr = jit_page_alloc(stack->size);
+ 		if(!ptr)
+ 		{
+ 			/* The system itself is out of memory */
+ 			jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
+ 			return 0;
+ 		}
+ 		*((void **)ptr) = stack->blocks;
+ 		stack->blocks = ptr;
+ 		stack->posn = JIT_FUNCTION_ALIGNMENT;
+ 		stack->currSize += stack->size;
+ 	}
+ 
+ 	/* Allocate the item */
+ 	ptr = (void *)(((unsigned char *)(stack->blocks)) + stack->posn);
+ 	stack->posn += size;
+ 	return ptr;
+ }
Index: jit/jit-cache.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-cache.c,v
retrieving revision 1.4
diff -c -r1.4 jit-cache.c
*** jit/jit-cache.c	24 Dec 2005 06:55:13 -0000	1.4
--- jit/jit-cache.c	14 Aug 2006 17:21:04 -0000
***************
*** 66,72 ****
  	jit_cache_debug_t  debug;		/* Debug information for method */
  	jit_cache_method_t left;		/* Left sub-tree and red/black bit */
  	jit_cache_method_t right;		/* Right sub-tree */
- 
  };
  
  /*
--- 66,71 ----
***************
*** 91,97 ****
  	int				  debugLen;		/* Length of temporary debug data */
  	jit_cache_debug_t firstDebug;	/* First debug block for method */
  	jit_cache_debug_t lastDebug;	/* Last debug block for method */
! 
  };
  
  /*
--- 90,96 ----
  	int				  debugLen;		/* Length of temporary debug data */
  	jit_cache_debug_t firstDebug;	/* First debug block for method */
  	jit_cache_debug_t lastDebug;	/* Last debug block for method */
! 	jit_context_t			  context; /* Build context that is associated with this cache */
  };
  
  /*
***************
*** 291,297 ****
  	}
  
  	/* Try to allocate a physical page */
! 	ptr = jit_malloc_exec((unsigned int)(cache->pageSize));
  	if(!ptr)
  	{
  		goto failAlloc;
--- 290,296 ----
  	}
  
  	/* Try to allocate a physical page */
! 	ptr = jit_malloc_exec(cache->context->jit_exec_mem_stack, (unsigned int)(cache->pageSize));
  	if(!ptr)
  	{
  		goto failAlloc;
***************
*** 567,573 ****
  	}
  }
  
! jit_cache_t _jit_cache_create(long limit, long cache_page_size)
  {
  	jit_cache_t cache;
  	unsigned long size;
--- 566,572 ----
  	}
  }
  
! jit_cache_t _jit_cache_create(jit_context_t context, long limit, long cache_page_size)
  {
  	jit_cache_t cache;
  	unsigned long size;
***************
*** 627,633 ****
  	cache->debugLen = 0;
  	cache->firstDebug = 0;
  	cache->lastDebug = 0;
! 
  	/* Allocate the initial cache page */
  	AllocCachePage(cache);
  	if(cache->outOfMemory)
--- 626,632 ----
  	cache->debugLen = 0;
  	cache->firstDebug = 0;
  	cache->lastDebug = 0;
! 	cache->context = context;
  	/* Allocate the initial cache page */
  	AllocCachePage(cache);
  	if(cache->outOfMemory)
Index: jit/jit-cache.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-cache.h,v
retrieving revision 1.3
diff -c -r1.3 jit-cache.h
*** jit/jit-cache.h	24 Dec 2005 06:55:13 -0000	1.3
--- jit/jit-cache.h	14 Aug 2006 17:21:05 -0000
***************
*** 46,53 ****
   * If "limit" is non-zero, then it specifies the maximum
   * size of the cache in bytes.  If "cache_page_size" is
   * non-zero, then it indicates the size of each cache page.
   */
! jit_cache_t _jit_cache_create(long limit, long cache_page_size);
  
  /*
   * Destroy a method cache.
--- 46,54 ----
   * If "limit" is non-zero, then it specifies the maximum
   * size of the cache in bytes.  If "cache_page_size" is
   * non-zero, then it indicates the size of each cache page.
+  * We associate with the cache a built context.
   */
! jit_cache_t _jit_cache_create(jit_context_t context, long limit, long cache_page_size);
  
  /*
   * Destroy a method cache.
Index: jit/jit-context.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-context.c,v
retrieving revision 1.5
diff -c -r1.5 jit-context.c
*** jit/jit-context.c	6 Oct 2004 05:43:15 -0000	1.5
--- jit/jit-context.c	14 Aug 2006 17:21:07 -0000
***************
*** 75,81 ****
  
  	/* Make sure that the JIT is initialized */
  	jit_init();
! 
  	/* Allocate memory for the context */
  	context = jit_cnew(struct _jit_context);
  	if(!context)
--- 75,81 ----
  
  	/* Make sure that the JIT is initialized */
  	jit_init();
! 	
  	/* Allocate memory for the context */
  	context = jit_cnew(struct _jit_context);
  	if(!context)
***************
*** 83,88 ****
--- 83,92 ----
  		return 0;
  	}
  
+ 	context->jit_exec_mem_stack = jit_cnew(struct _jit_mem_stack);
+ 	/* Initialize memory stack for code */	
+ 	jit_mem_stack_init(context->jit_exec_mem_stack, JIT_EXEC_MEMORY_SIZE);
+ 
  	/* Initialize the context and return it */
  	jit_mutex_create(&(context->builder_lock));
  	jit_mutex_create(&(context->cache_lock));
***************
*** 118,123 ****
--- 122,129 ----
  		jit_free(context->registered_symbols);
  		jit_mutex_destroy(&(context->cache_lock));
  		jit_mutex_destroy(&(context->builder_lock));
+ 		jit_mem_stack_destroy(context->jit_exec_mem_stack);
+ 		jit_free(context->jit_exec_mem_stack);
  		jit_free(context);
  	}
  }
***************
*** 263,269 ****
  	if(!(context->cache))
  	{
  		context->cache = _jit_cache_create
! 			((long)jit_context_get_meta_numeric
  				(context, JIT_OPTION_CACHE_LIMIT),
  			 (long)jit_context_get_meta_numeric
  				(context, JIT_OPTION_CACHE_PAGE_SIZE));
--- 269,276 ----
  	if(!(context->cache))
  	{
  		context->cache = _jit_cache_create
! 			(context,
! 			(long)jit_context_get_meta_numeric
  				(context, JIT_OPTION_CACHE_LIMIT),
  			 (long)jit_context_get_meta_numeric
  				(context, JIT_OPTION_CACHE_PAGE_SIZE));
Index: jit/jit-elf-read.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-elf-read.c,v
retrieving revision 1.3
diff -c -r1.3 jit-elf-read.c
*** jit/jit-elf-read.c	1 Jun 2004 06:46:46 -0000	1.3
--- jit/jit-elf-read.c	14 Aug 2006 17:21:09 -0000
***************
*** 416,422 ****
  	/* If we haven't mapped the file yet, then fall back to "malloc" */
  	if(!base_address)
  	{
! 		base_address = jit_malloc_exec(memory_size);
  		if(!base_address)
  		{
  			return 0;
--- 416,422 ----
  	/* If we haven't mapped the file yet, then fall back to "malloc" */
  	if(!base_address)
  	{
! 		base_address = jit_malloc(memory_size);
  		if(!base_address)
  		{
  			return 0;
***************
*** 433,439 ****
  	               read(fd, segment_address, (size_t)(phdr->p_filesz))
  				   		!= (int)(size_t)(phdr->p_filesz))
  				{
! 					jit_free_exec(base_address, memory_size);
  					return 0;
  				}
  			}
--- 433,439 ----
  	               read(fd, segment_address, (size_t)(phdr->p_filesz))
  				   		!= (int)(size_t)(phdr->p_filesz))
  				{
! 					jit_free(base_address);
  					return 0;
  				}
  			}
***************
*** 458,476 ****
  	{
  		memory_size = file_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);
  		return 0;
  	}
  	if(read(fd, address, (size_t)file_size) != (int)(size_t)file_size)
  	{
! 		jit_free_exec(address, memory_size);
  		return 0;
  	}
  	return address;
--- 458,476 ----
  	{
  		memory_size = file_size;
  	}
! 	address = jit_malloc(memory_size);
  	if(!address)
  	{
  		return 0;
  	}
  	if(lseek(fd, (off_t)offset, 0) != (off_t)offset)
  	{
! 		jit_free(address);
  		return 0;
  	}
  	if(read(fd, address, (size_t)file_size) != (int)(size_t)file_size)
  	{
! 		jit_free(address);
  		return 0;
  	}
  	return address;
***************
*** 488,494 ****
  	}
  	if((flags & JIT_ELF_IS_MALLOCED) != 0)
  	{
! 		jit_free_exec(address, (unsigned int)memory_size);
  	}
  }
  
--- 488,494 ----
  	}
  	if((flags & JIT_ELF_IS_MALLOCED) != 0)
  	{
! 		jit_free(address);
  	}
  }
  
***************
*** 1105,1111 ****
  	else
  #endif
  	{
! 		jit_free_exec(readelf->map_address, readelf->map_size);
  	}
  	for(index = 0; index < readelf->ehdr.e_shnum; ++index)
  	{
--- 1105,1111 ----
  	else
  #endif
  	{
! 		jit_free(readelf->map_address);
  	}
  	for(index = 0; index < readelf->ehdr.e_shnum; ++index)
  	{
Index: jit/jit-function.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-function.c,v
retrieving revision 1.20
diff -c -r1.20 jit-function.c
*** jit/jit-function.c	3 Jun 2006 13:39:53 -0000	1.20
--- jit/jit-function.c	14 Aug 2006 17:21:10 -0000
***************
*** 46,54 ****
  jit_function_t jit_function_create(jit_context_t context, jit_type_t signature)
  {
  	jit_function_t func;
- 
  	/* Allocate memory for the function and clear it */
  	func = jit_cnew(struct _jit_function);
  	if(!func)
  	{
  		return 0;
--- 46,61 ----
  jit_function_t jit_function_create(jit_context_t context, jit_type_t signature)
  {
  	jit_function_t func;
  	/* Allocate memory for the function and clear it */
  	func = jit_cnew(struct _jit_function);
+ 	
+ 	/* Allocate memory for the redirector and indirector */
+ #if defined(jit_redirector_size)
+ 	func->redirector = jit_malloc_exec(context->jit_exec_mem_stack, jit_redirector_size);
+ #endif
+ #if defined(jit_indirector_size)
+ 	func->indirector = jit_malloc_exec(context->jit_exec_mem_stack, jit_indirector_size);
+ #endif
  	if(!func)
  	{
  		return 0;
***************
*** 203,208 ****
--- 210,221 ----
  	}
  	_jit_function_free_builder(func);
  	jit_meta_destroy(&(func->meta));
+ 	#if defined(jit_redirector_size)
+ 	jit_free_exec(func->redirector, jit_redirector_size);
+ 	#endif
+ 	#if defined(jit_indirector_size)
+ 	jit_free_exec(func->indirector, jit_indirector_size);
+ 	#endif
  	jit_free(func);
  }
  
Index: jit/jit-internal.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-internal.h,v
retrieving revision 1.23
diff -c -r1.23 jit-internal.h
*** jit/jit-internal.h	14 Apr 2006 14:44:29 -0000	1.23
--- jit/jit-internal.h	14 Aug 2006 17:21:12 -0000
***************
*** 22,28 ****
  #define	_JIT_INTERNAL_H
  
  #include <jit/jit.h>
! 
  #ifdef	__cplusplus
  extern	"C" {
  #endif
--- 22,28 ----
  #define	_JIT_INTERNAL_H
  
  #include <jit/jit.h>
! #include <sys/mman.h>
  #ifdef	__cplusplus
  extern	"C" {
  #endif
***************
*** 401,413 ****
  #ifdef jit_redirector_size
  	/* Buffer that contains the redirector for this function.
  	   Redirectors are used to support on-demand compilation */
! 	unsigned char		redirector[jit_redirector_size];
  #endif
  #ifdef jit_indirector_size
  	/* Buffer that contains the indirector for this function.
  	   The indirector is used to jump either to the function
  	   redirector or the compiled function itself. */
! 	unsigned char		indirector[jit_indirector_size];
  #endif
  };
  
--- 401,413 ----
  #ifdef jit_redirector_size
  	/* Buffer that contains the redirector for this function.
  	   Redirectors are used to support on-demand compilation */
! 	unsigned char		*redirector;
  #endif
  #ifdef jit_indirector_size
  	/* Buffer that contains the indirector for this function.
  	   The indirector is used to jump either to the function
  	   redirector or the compiled function itself. */
! 	unsigned char		*indirector;
  #endif
  };
  
***************
*** 447,452 ****
--- 447,471 ----
  	char	name[1];
  };
  
+ #define JIT_EXEC_MEMORY_SIZE	16777216
+ 
+ /*
+  * Structure of a memory stack allocation context.
+  * This should be treated as opaque.  A memory stack
+  * differs from a memory pool in that it allocates
+  * any size of structure from the same set of blocks,
+  * and data can only be freed by freeing the stack.
+  */
+ struct _jit_mem_stack
+ {
+ 	unsigned		posn;			/* Position within the current block */
+ 	unsigned		size;			/* Size of individual blocks */
+ 	void		   *blocks;			/* List of blocks in the stack */
+ 	unsigned long	currSize;		/* Current size of the stack */
+ 	unsigned long	maxSize;		/* Maximum size of the stack */
+ 	void           *extras;			/* List of extra alloc'ed blocks */
+ };
+ 
  /*
   * Internal structure of a context.
   */
***************
*** 468,473 ****
--- 487,495 ----
  	/* The context's function code cache */
  	struct jit_cache   *cache;
  
+ 	/* Stack of memory that can be used for execution */
+ 	jit_mem_stack_t			jit_exec_mem_stack;
+ 
  	/* ELF binaries that have been loaded into this context */
  	jit_readelf_t		elf_binaries;
  
***************
*** 478,483 ****
--- 500,506 ----
  	/* Debugger support */
  	jit_debugger_hook_func debug_hook;
  	jit_debugger_t		debugger;
+ 	
  };
  
  /*
#### End of Patch data ####
