From: Aleksey Demakov Date: Sat, 11 Feb 2012 09:12:39 +0000 (+0300) Subject: A little bit more jit-cache cleanup X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=e332897e9b53e3796185f21df6b9e1c0a73fe996;p=francis%2Flibjit.git A little bit more jit-cache cleanup --- diff --git a/ChangeLog b/ChangeLog index 264d3b0..4a3be53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2012-02-11 Aleksey Demakov + + * 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 * jit/jit-rules.h (struct jit_gencode): add offset_encoder field diff --git a/jit/jit-cache.c b/jit/jit-cache.c index b9a1eb2..afda4f8 100644 --- a/jit/jit-cache.c +++ b/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. diff --git a/jit/jit-cache.h b/jit/jit-cache.h index 2c1c849..3cfa557 100644 --- a/jit/jit-cache.h +++ b/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 }; diff --git a/jit/jit-compile.c b/jit/jit-compile.c index dfc0ffe..3a4d3b2 100644 --- a/jit/jit-compile.c +++ b/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)); diff --git a/jit/jit-rules-interp.c b/jit/jit-rules-interp.c index 0aebe23..33d5679 100644 --- a/jit/jit-rules-interp.c +++ b/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. */