From: Rhys Weatherley Date: Sat, 8 May 2004 00:42:18 +0000 (+0000) Subject: Add "_jit_cache_get_end_method", to allow the end of a method's code X-Git-Tag: r.0.0.2~28 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=048a004a871707dc764a8c477b08a793b4f48a9d;p=francis%2Flibjit.git Add "_jit_cache_get_end_method", to allow the end of a method's code to be located without explicit marking. --- diff --git a/ChangeLog b/ChangeLog index 91968f3..20a02ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,10 @@ +2004-05-08 Rhys Weatherley + + * jit/jit-cache.c, jit/jit-cache.h, jit/jit-dump.c, jit/jit-interp.h, + jit/jit-rules-interp.c: add "_jit_cache_get_end_method", to allow + the end of a method's code to be located without explicit marking. + 2004-05-07 Rhys Weatherley * dpas/dpas-function.c, dpas/dpas-internal.h, dpas/dpas-main.c, diff --git a/jit/jit-cache.c b/jit/jit-cache.c index e27debc..251ccaa 100644 --- a/jit/jit-cache.c +++ b/jit/jit-cache.c @@ -976,6 +976,149 @@ void *_jit_cache_get_method(jit_cache_t cache, void *pc, void **cookie) return 0; } +/* + * Add a parent pointer to a list. Returns null if out of memory. + */ +static int add_parent(jit_cache_method_t *parent_buf, + jit_cache_method_t **parents, + int *num_parents, int *max_parents, + jit_cache_method_t node) +{ + jit_cache_method_t *new_list; + if(*num_parents >= *max_parents) + { + if(*parents == parent_buf) + { + new_list = (jit_cache_method_t *)jit_malloc + ((*max_parents * 2) * sizeof(jit_cache_method_t)); + if(new_list) + { + jit_memcpy(new_list, *parents, + (*num_parents) * sizeof(jit_cache_method_t)); + } + } + else + { + new_list = (jit_cache_method_t *)jit_realloc + (*parents, (*max_parents * 2) * sizeof(jit_cache_method_t)); + } + if(!new_list) + { + return 0; + } + *parents = new_list; + *max_parents *= 2; + } + (*parents)[*num_parents] = node; + ++(*num_parents); + return 1; +} + +void *_jit_cache_get_end_method(jit_cache_t cache, void *pc) +{ + jit_cache_method_t parent_buf[16]; + jit_cache_method_t *parents = parent_buf; + int num_parents = 0; + int max_parents = 16; + jit_cache_method_t node = cache->head.right; + jit_cache_method_t last; + jit_cache_method_t parent; + void *method; + while(node != &(cache->nil)) + { + if(((unsigned char *)pc) < node->start) + { + if(!add_parent(parent_buf, &parents, &num_parents, + &max_parents, node)) + { + break; + } + node = GetLeft(node); + } + else if(((unsigned char *)pc) >= node->end) + { + if(!add_parent(parent_buf, &parents, &num_parents, + &max_parents, node)) + { + break; + } + node = GetRight(node); + } + else + { + /* This is the node that contains the starting position. + We now need to do an inorder traversal from this point + to find the last node that mentions this method */ + method = node->method; + last = node; + do + { + if(GetRight(node) != &(cache->nil)) + { + /* Move down the left-most sub-tree of the right */ + if(!add_parent(parent_buf, &parents, &num_parents, + &max_parents, node)) + { + goto failed; + } + node = GetRight(node); + while(GetLeft(node) != &(cache->nil)) + { + if(!add_parent(parent_buf, &parents, &num_parents, + &max_parents, node)) + { + goto failed; + } + node = GetLeft(node); + } + } + else + { + /* Find a parent or other ancestor that contains this + node within its left sub-tree */ + for(;;) + { + if(num_parents == 0) + { + node = 0; + break; + } + parent = parents[--num_parents]; + if(GetLeft(parent) == node) + { + /* We are on our parent's left, so next is parent */ + node = parent; + break; + } + node = parent; + } + if(!node) + { + /* We reached the root of the tree */ + break; + } + } + if(node->method == method) + { + last = node; + } + } + while(node->method == method); + if(parents != parent_buf) + { + jit_free(parents); + } + return last->end; + } + } +failed: + if(parents != parent_buf) + { + jit_free(parents); + } + return 0; +} + /* * Count the number of methods in a sub-tree. */ diff --git a/jit/jit-cache.h b/jit/jit-cache.h index 03b339b..25cf305 100644 --- a/jit/jit-cache.h +++ b/jit/jit-cache.h @@ -129,6 +129,12 @@ void _jit_cache_set_cookie(jit_cache_posn *posn, void *cookie); */ void *_jit_cache_get_method(jit_cache_t cache, void *pc, void **cookie); +/* + * Get the end of a method with a particular starting PC. + * Returns NULL if the PC could not be located. + */ +void *_jit_cache_get_end_method(jit_cache_t cache, void *pc); + /* * Get a list of all method that are presently in the cache. * The list is terminated by a NULL, and must be free'd with diff --git a/jit/jit-dump.c b/jit/jit-dump.c index 914e9b8..85cad4c 100644 --- a/jit/jit-dump.c +++ b/jit/jit-dump.c @@ -496,18 +496,14 @@ extern jit_opcode_info_t const _jit_interp_opcodes[JIT_OP_NUM_INTERP_OPCODES]; /* * Dump the interpreted bytecode representation of a function. */ -static void dump_interp_code(FILE *stream, void **pc) +static void dump_interp_code(FILE *stream, void **pc, void **end) { int opcode; const jit_opcode_info_t *info; - for(;;) + while(pc < end) { /* Fetch the next opcode */ opcode = (int)(jit_nint)(*pc); - if(opcode == JIT_OP_END_MARKER) - { - break; - } /* Dump the address of the opcode */ fprintf(stream, "\t%08lX: ", (long)(jit_nint)pc); @@ -546,31 +542,50 @@ static void dump_interp_code(FILE *stream, void **pc) case JIT_OPCODE_CONST_LONG: { - /* TODO */ + jit_ulong value; + jit_memcpy(&value, pc, sizeof(jit_ulong)); + pc += (sizeof(jit_ulong) + sizeof(void *) - 1) & + ~(sizeof(void *) - 1); + fprintf(stream, " 0x%lX%08lX", + (long)((value >> 32) & jit_max_uint), + (long)(value & jit_max_uint)); } break; case JIT_OPCODE_CONST_FLOAT32: { - /* TODO */ + jit_float32 value; + jit_memcpy(&value, pc, sizeof(jit_float32)); + pc += (sizeof(jit_float32) + sizeof(void *) - 1) & + ~(sizeof(void *) - 1); + fprintf(stream, " %g", (double)value); } break; case JIT_OPCODE_CONST_FLOAT64: { - /* TODO */ + jit_float64 value; + jit_memcpy(&value, pc, sizeof(jit_float64)); + pc += (sizeof(jit_float64) + sizeof(void *) - 1) & + ~(sizeof(void *) - 1); + fprintf(stream, " %g", (double)value); } break; case JIT_OPCODE_CONST_NFLOAT: { - /* TODO */ + jit_nfloat value; + jit_memcpy(&value, pc, sizeof(jit_nfloat)); + pc += (sizeof(jit_nfloat) + sizeof(void *) - 1) & + ~(sizeof(void *) - 1); + fprintf(stream, " %g", (double)value); } break; case JIT_OPCODE_CALL_INDIRECT_ARGS: { - /* TODO */ + fprintf(stream, " %ld", (long)(jit_nint)(pc[1])); + pc += 2; } break; @@ -738,6 +753,8 @@ void jit_dump_function(FILE *stream, jit_function_t func, const char *name) } else if(func->is_compiled) { + void *end = _jit_cache_get_end_method + (func->context->cache, func->entry_point); #if defined(JIT_BACKEND_INTERP) /* Dump the interpreter's bytecode representation */ jit_function_interp_t interp; @@ -746,7 +763,7 @@ void jit_dump_function(FILE *stream, jit_function_t func, const char *name) (long)(jit_nint)interp, (long)(jit_nint)func, (int)(interp->args_size), (int)(interp->frame_size), (int)(interp->working_area)); - dump_interp_code(stream, (void **)(interp + 1)); + dump_interp_code(stream, (void **)(interp + 1), (void **)end); #else /* TODO: use objdump to dump native code */ #endif diff --git a/jit/jit-interp.h b/jit/jit-interp.h index dc40134..7a12506 100644 --- a/jit/jit-interp.h +++ b/jit/jit-interp.h @@ -189,7 +189,7 @@ public: #define JIT_OP_CALL_FINALLY (JIT_OP_NUM_OPCODES + 0x0038) /* - * Marker opcode for the end of a function. + * Marker opcode for the end of the interpreter-specific opcodes. */ #define JIT_OP_END_MARKER (JIT_OP_NUM_OPCODES + 0x0039) diff --git a/jit/jit-rules-interp.c b/jit/jit-rules-interp.c index 2d80cb5..7479933 100644 --- a/jit/jit-rules-interp.c +++ b/jit/jit-rules-interp.c @@ -621,7 +621,7 @@ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf) @*/ void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func) { - jit_cache_opcode(&(gen->posn), JIT_OP_END_MARKER); + /* The interpreter doesn't use epilogs */ } /*@