Browse Source

A little bit more jit-cache cleanup

cache-refactoring
Aleksey Demakov 13 years ago
parent
commit
e332897e9b
  1. 13
      ChangeLog
  2. 65
      jit/jit-cache.c
  3. 89
      jit/jit-cache.h
  4. 62
      jit/jit-compile.c
  5. 10
      jit/jit-rules-interp.c

13
ChangeLog

@ -1,3 +1,16 @@
2012-02-11 Aleksey Demakov <ademakov@gmail.com>
* jit/jit-cache.h, jit/jit-cache.c (_jit_cache_end_method): add
result argument that indicates if the code genration will need
to be restarted.
* jit/jit-cache.h, jit/jit-cache.c (jit_cache_mark_full): remove
macro and replace it with direct jit_cache_posn access where
appropriate.
* jit/jit-cache.h, jit/jit-cache.c (jit_cache_get_posn): likewise.
* jit/jit-cache.h, jit/jit-rules-interp.c (jit_cache_native): move
macro to where it only used.
* jit/jit-cache.h, jit/jit-cache.c: remove other unused stuff.
2012-01-21 Aleksey Demakov <ademakov@gmail.com>
* jit/jit-rules.h (struct jit_gencode): add offset_encoder field

65
jit/jit-cache.c

@ -454,10 +454,10 @@ int _jit_cache_is_full(jit_cache_t cache, jit_cache_posn *posn)
void
_jit_cache_check_space(jit_cache_posn *posn, int space)
{
if(!jit_cache_check_for_n(posn, space))
if((posn->ptr + space) >= posn->limit)
{
/* No space left on the current cache page. */
jit_cache_mark_full(posn);
posn->ptr = posn->limit;
jit_exception_builtin(JIT_RESULT_CACHE_FULL);
}
}
@ -526,12 +526,19 @@ int _jit_cache_start_method(jit_cache_t cache,
return JIT_CACHE_OK;
}
int _jit_cache_end_method(jit_cache_posn *posn)
int
_jit_cache_end_method(jit_cache_posn *posn, int result)
{
jit_cache_t cache = posn->cache;
jit_cache_method_t method;
jit_cache_method_t next;
if (result != JIT_CACHE_OK)
{
/* mark cache page full */
posn->ptr = posn->limit;
}
/* Determine if we ran out of space while writing the method */
if(posn->ptr >= posn->limit)
{
@ -637,44 +644,6 @@ void *_jit_cache_alloc_no_method
return (void *)ptr;
}
void _jit_cache_align(jit_cache_posn *posn, int align, int diff, int nop)
{
jit_nuint current;
jit_nuint next;
/* Determine the location of the next alignment boundary */
if(align <= 1)
{
align = 1;
}
current = (jit_nuint)(posn->ptr);
next = (current + ((jit_nuint)align) - 1) &
~(((jit_nuint)align) - 1);
if(current == next || (next - current) >= (jit_nuint)diff)
{
return;
}
/* Detect overflow of the free memory region */
if(next > ((jit_nuint)(posn->limit)))
{
posn->ptr = posn->limit;
return;
}
#ifndef jit_should_pad
/* Fill from "current" to "next" with nop bytes */
while(current < next)
{
*((posn->ptr)++) = (unsigned char)nop;
++current;
}
#else
/* Use CPU-specific padding, because it may be more efficient */
_jit_pad_buffer((unsigned char *)current, (int)(next - current));
#endif
}
jit_function_t
_jit_cache_get_method(jit_cache_t cache, void *pc)
{
@ -741,20 +710,6 @@ returns one of three result codes:
for allocation. In this case a restart
won't help.
To write code to the method, use the following:
jit_cache_byte(&posn, value);
jit_cache_word16(&posn, value);
jit_cache_word32(&posn, value);
jit_cache_native(&posn, value);
jit_cache_word64(&posn, value);
These macros write the value to cache and then update the current
position. If the macros detect the end of the avaialable space,
they will flag overflow, but otherwise do nothing (overflow is
flagged when posn->ptr == posn->limit). The current position
in the method can be obtained using "jit_cache_get_posn".
Some CPU optimization guides recommend that labels should be aligned.
This can be achieved using _jit_cache_align.

89
jit/jit-cache.h

@ -101,7 +101,7 @@ int _jit_cache_start_method(jit_cache_t cache,
/*
* End output of a method. Returns zero if a restart.
*/
int _jit_cache_end_method(jit_cache_posn *posn);
int _jit_cache_end_method(jit_cache_posn *posn, int result);
/*
* Allocate "size" bytes of storage in the method cache's
@ -118,14 +118,6 @@ void *_jit_cache_alloc(jit_cache_posn *posn, unsigned long size);
void *_jit_cache_alloc_no_method
(jit_cache_t cache, unsigned long size, unsigned long align);
/*
* Align the method code on a particular boundary if the
* difference between the current position and the aligned
* boundary is less than "diff". The "nop" value is used
* to pad unused bytes.
*/
void _jit_cache_align(jit_cache_posn *posn, int align, int diff, int nop);
/*
* Find the method that is associated with a particular
* program counter. Returns NULL if the PC is not associated
@ -133,85 +125,6 @@ void _jit_cache_align(jit_cache_posn *posn, int align, int diff, int nop);
*/
jit_function_t _jit_cache_get_method(jit_cache_t cache, void *pc);
/*
* Convert a return address into a program counter value
* that can be used with "_jit_cache_get_method". Normally
* return addresses point to the next instruction after
* an instruction that falls within a method region. This
* macro corrects for the "off by 1" address.
*/
#define jit_cache_return_to_pc(addr) \
((void *)(((unsigned char *)(addr)) - 1))
/*
* Output a single byte to the current method.
*/
#define jit_cache_byte(posn,value) \
do { \
if((posn)->ptr < (posn)->limit) \
{ \
*(((posn)->ptr)++) = (unsigned char)(value); \
} \
} while (0)
/*
* Output a 16-bit word to the current method.
*/
#define jit_cache_word16(posn,value) \
do { \
_jit_cache_check_space((posn), 2); \
*((jit_ushort *)((posn)->ptr)) = (jit_ushort)(value); \
(posn)->ptr += 2; \
} while (0)
/*
* Output a 32-bit word to the current method.
*/
#define jit_cache_word32(posn,value) \
do { \
_jit_cache_check_space((posn), 4); \
*((jit_uint *)((posn)->ptr)) = (jit_uint)(value); \
(posn)->ptr += 4; \
} while (0)
/*
* Output a native word to the current method.
*/
#define jit_cache_native(posn,value) \
do { \
_jit_cache_check_space((posn), sizeof(jit_nuint)); \
*((jit_nuint *)((posn)->ptr)) = (jit_nuint)(value); \
(posn)->ptr += sizeof(jit_nuint); \
} while (0)
/*
* Output a 64-bit word to the current method.
*/
#define jit_cache_word64(posn,value) \
do { \
_jit_cache_check_space((posn), 8); \
*((jit_ulong *)((posn)->ptr)) = (jit_ulong)(value); \
(posn)->ptr += 8; \
} while (0)
/*
* Get the output position within the current method.
*/
#define jit_cache_get_posn(posn) ((posn)->ptr)
/*
* Determine if there is sufficient space for N bytes in the current method.
*/
#define jit_cache_check_for_n(posn,n) \
(((posn)->ptr + (n)) <= (posn)->limit)
/*
* Mark the cache as full.
*/
#define jit_cache_mark_full(posn) \
do { \
(posn)->ptr = (posn)->limit; \
} while (0)
#ifdef __cplusplus
};

62
jit/jit-compile.c

@ -158,8 +158,7 @@ jit_optimize(jit_function_t func)
void
mark_offset(jit_gencode_t gen, jit_function_t func, unsigned long offset)
{
unsigned char *ptr = jit_cache_get_posn(&gen->posn);
unsigned long native_offset = ptr - func->start;
unsigned long native_offset = gen->posn.ptr - func->start;
if(!_jit_varint_encode_uint(&gen->offset_encoder, (jit_uint) offset))
{
jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
@ -452,6 +451,54 @@ cache_alloc(_jit_compile_t *state)
state->cache_started = 1;
}
#if NOT_USED
/*
* Align the method code on a particular boundary if the
* difference between the current position and the aligned
* boundary is less than "diff". The "nop" value is used
* to pad unused bytes.
*/
static void
cache_align(jit_cache_posn *posn, int align, int diff, int nop)
{
jit_nuint current;
jit_nuint next;
/* Determine the location of the next alignment boundary */
if(align <= 1)
{
align = 1;
}
current = (jit_nuint)(posn->ptr);
next = (current + ((jit_nuint)align) - 1) &
~(((jit_nuint)align) - 1);
if(current == next || (next - current) >= (jit_nuint)diff)
{
return;
}
/* Detect overflow of the free memory region */
if(next > ((jit_nuint)(posn->limit)))
{
posn->ptr = posn->limit;
return;
}
#ifndef jit_should_pad
/* Fill from "current" to "next" with nop bytes */
while(current < next)
{
*((posn->ptr)++) = (unsigned char)nop;
++current;
}
#else
/* Use CPU-specific padding, because it may be more efficient */
_jit_pad_buffer((unsigned char *)current, (int)(next - current));
#endif
}
#endif
/*
* End function output to the cache.
*/
@ -465,7 +512,7 @@ cache_flush(_jit_compile_t *state)
state->cache_started = 0;
/* End the function's output process */
result = _jit_cache_end_method(&state->gen.posn);
result = _jit_cache_end_method(&state->gen.posn, JIT_CACHE_OK);
if(result != JIT_CACHE_OK)
{
if(result == JIT_CACHE_RESTART)
@ -508,13 +555,8 @@ cache_abort(_jit_compile_t *state)
{
state->cache_started = 0;
/* Make sure that the _jit_cache_end_method() call below will
release the currently held cache space rather than make it
allocated permanently */
jit_cache_mark_full(&state->gen.posn);
/* Actually release the cache space */
_jit_cache_end_method(&state->gen.posn);
/* Release the cache space */
_jit_cache_end_method(&state->gen.posn, JIT_CACHE_RESTART);
/* Free encoded bytecode offset data */
_jit_varint_free_data(_jit_varint_get_data(&state->gen.offset_encoder));

10
jit/jit-rules-interp.c

@ -184,6 +184,16 @@ generation is complete.
@*/
/*
* Output a native word to the current method.
*/
#define jit_cache_native(posn,value) \
do { \
_jit_cache_check_space((posn), sizeof(jit_nuint)); \
*((jit_nuint *)((posn)->ptr)) = (jit_nuint)(value); \
(posn)->ptr += sizeof(jit_nuint); \
} while (0)
/*
* Write an interpreter opcode to the cache.
*/

Loading…
Cancel
Save