]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Add instructions and function API's for supporting debug line
authorRhys Weatherley <rweather@southern-storm.com.au>
Mon, 4 Oct 2004 00:51:45 +0000 (00:51 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Mon, 4 Oct 2004 00:51:45 +0000 (00:51 +0000)
numbers and breakpoints.

14 files changed:
ChangeLog
include/jit/jit-function.h
include/jit/jit-insn.h
include/jit/jit-opcode.h
include/jit/jit-plus.h
jit/jit-function.c
jit/jit-insn.c
jit/jit-internal.h
jit/jit-interp.c
jit/jit-opcode.c
jit/jit-rules-arm.sel
jit/jit-rules-interp.c
jit/jit-rules-x86.sel
jitplus/jit-plus-function.cpp

index f83863e54955fe1bf2e55082c16843e20de266e3..53ce64971c732c1fcaa07667cb65da26e91a2d87 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,14 @@
 
+2004-10-04  Rhys Weatherley  <rweather@southern-storm.com.au>
+
+       * include/jit/jit-function.h, include/jit/jit-insn.h,
+       include/jit/jit-opcode.h, include/jit/jit-plus.h, jit/jit-function.c,
+       jit/jit-insn.c, jit/jit-internal.h, jit/jit-interp.c,
+       jit/jit-opcode.c, jit/jit-rules-interp.c, jit/jit-rules-arm.sel,
+       jit/jit-rules-x86.sel, jitplus/jit-plus-function.cpp:
+       add instructions and function API's for supporting debug line
+       numbers and breakpoints.
+
 2004-09-10  Rhys Weatherley  <rweather@southern-storm.com.au>
 
        * jit/jit-rules-x86.sel: pointer-relative loads and stores
index cd5e5d614378ebd40904dec67b51a698a249a603..c376d7f10939fb556776a47dab0ac00906f53501 100644 (file)
@@ -70,6 +70,8 @@ void jit_function_set_optimization_level
 unsigned int jit_function_get_optimization_level
        (jit_function_t func) JIT_NOTHROW;
 unsigned int jit_function_get_max_optimization_level(void) JIT_NOTHROW;
+void jit_function_enable_breakpoints(jit_function_t func, int flag) JIT_NOTHROW;
+int jit_function_breakpoints_enabled(jit_function_t func) JIT_NOTHROW;
 
 #ifdef __cplusplus
 };
index d974121c9bf3314b280e968a8950cf055a684e4e..299ee79f7c15236c04bb575acd9469436dd4b165 100644 (file)
@@ -304,9 +304,16 @@ jit_value_t jit_insn_alloca
        (jit_function_t func, jit_value_t size) JIT_NOTHROW;
 
 int jit_insn_move_blocks_to_end
-       (jit_function_t func, jit_label_t from_label, jit_label_t to_label);
+       (jit_function_t func, jit_label_t from_label, jit_label_t to_label)
+               JIT_NOTHROW;
 int jit_insn_move_blocks_to_start
-       (jit_function_t func, jit_label_t from_label, jit_label_t to_label);
+       (jit_function_t func, jit_label_t from_label, jit_label_t to_label)
+               JIT_NOTHROW;
+
+int jit_insn_mark_offset
+       (jit_function_t func, jit_int offset) JIT_NOTHROW;
+int jit_insn_mark_debug
+       (jit_function_t func, jit_nint data1, jit_nint data2) JIT_NOTHROW;
 
 void jit_insn_iter_init(jit_insn_iter_t *iter, jit_block_t block) JIT_NOTHROW;
 void jit_insn_iter_init_last
index b6f20d3c25fc92205bf808630913ba0ad7e68185..ec370a54b909b2e78b732c6ff58d6a9e515e0ce5 100644 (file)
@@ -511,10 +511,16 @@ extern    "C" {
  */
 #define        JIT_OP_ALLOCA                                           0x019F
 
+/*
+ * Debugging support.
+ */
+#define        JIT_OP_MARK_OFFSET                                      0x01A0
+#define        JIT_OP_MARK_DEBUG                                       0x01A1
+
 /*
  * The number of opcodes in the above list.
  */
-#define        JIT_OP_NUM_OPCODES                                      0x01A0
+#define        JIT_OP_NUM_OPCODES                                      0x01A2
 
 /*
  * Opcode information.
index 05bb29191f14dade4f17f04a285f529ec9789f57..6f118d57a302dcd2b9f10ce3ac8d2168e91af595 100644 (file)
@@ -350,6 +350,8 @@ public:
                (const jit_label& from_label, const jit_label& to_label);
        void insn_move_blocks_to_start
                (const jit_label& from_label, const jit_label& to_label);
+       void insn_mark_offset(jit_int offset);
+       void insn_mark_debug(jit_nint data1, jit_nint data2);
 
 private:
        jit_function_t func;
index 578622b985cfccd0c1c4c46d890c0b6c1afca1ef..6e7f3d32985c41018624c71f42d96652c4015b55 100644 (file)
@@ -518,6 +518,16 @@ static void compile_block(jit_gencode_t gen, jit_function_t func,
                        }
                        break;
 
+                       case JIT_OP_MARK_OFFSET:
+                       {
+                               /* Mark the current code position as corresponding
+                                  to a particular bytecode offset */
+                               _jit_cache_mark_bytecode
+                                       (&(gen->posn), (unsigned long)(long)
+                                                       jit_value_get_nint_constant(insn->value1));
+                       }
+                       break;
+
                        default:
                        {
                                /* Generate code for the instruction with the back end */
@@ -1278,3 +1288,45 @@ unsigned int jit_function_get_max_optimization_level(void)
        /* TODO - implement more than basic optimization */
        return 0;
 }
+
+/*@
+ * @deftypefun void jit_function_enable_breakpoints (jit_function_t func)
+ * Enable or disable all breakpoints in the specified function.  Breakpoints
+ * occur at locations marked by @code{jit_insn_mark_debug}.
+ *
+ * The @code{libjit} library provides a very simple breakpoint mechanism.
+ * Upon reaching each breakpoint in the function, the global debug hook
+ * is called.  It is up to the debug hook to decide whether to stop execution
+ * or to ignore the breakpoint.
+ *
+ * Typically, the debug hook will inspect a table to determine which
+ * breakpoints were actually selected by the user in a debugger's user
+ * interface.  The debug hook may even evaluate a complicated expression,
+ * taking the function, current thread, and the value of local variables
+ * into account, to make the decision.
+ * @end deftypefun
+@*/
+void jit_function_enable_breakpoints(jit_function_t func, int flag)
+{
+       if(func)
+       {
+               func->breakpoints_enabled = flag;
+       }
+}
+
+/*@
+ * @deftypefun int jit_function_breakpoints_enabled (jit_function_t func)
+ * Determine if breakpoints are enabled on the specified function.
+ * @end deftypefun
+@*/
+int jit_function_breakpoints_enabled(jit_function_t func)
+{
+       if(func)
+       {
+               return func->breakpoints_enabled;
+       }
+       else
+       {
+               return 0;
+       }
+}
index fb460c8f4733f49169337bf727247911f7f9403b..e334eef38bf8096f8049b9d7f63b31fae899afbe 100644 (file)
@@ -7675,6 +7675,48 @@ int jit_insn_move_blocks_to_start
        return 1;
 }
 
+/*@
+ * @deftypefun int jit_insn_mark_offset (jit_function_t func, jit_int offset)
+ * Mark the current position in @code{func} as corresponding to the
+ * specified bytecode @code{offset}.  This value will be returned
+ * by @code{jit_stack_trace_get_offset}, and is useful for associating
+ * code positions with source line numbers.
+ * @end deftypefun
+@*/
+int jit_insn_mark_offset(jit_function_t func, jit_int offset)
+{
+       if(!jit_insn_new_block(func))
+       {
+               return 0;
+       }
+       return create_unary_note(func, JIT_OP_MARK_OFFSET,
+                                                    jit_value_create_nint_constant
+                                                               (func, jit_type_int, offset));
+}
+
+/*@
+ * @deftypefun int jit_insn_mark_debug (jit_function_t func, jit_nint data1, jit_nint data2)
+ * Mark the current position in @code{func} as corresponding to a breakpoint
+ * location.  When a break occurs, the global debug hook is called with
+ * @code{func}, @code{data1}, and @code{data2} as arguments.  See the
+ * description for @code{jit_function_enable_breakpoints} for more
+ * information on breakpoint support.
+ * @end deftypefun
+@*/
+int jit_insn_mark_debug
+       (jit_function_t func, jit_nint data1, jit_nint data2)
+{
+       if(!jit_insn_new_block(func))
+       {
+               return 0;
+       }
+       return create_note(func, JIT_OP_MARK_DEBUG,
+                                      jit_value_create_nint_constant
+                                                       (func, jit_type_nint, data1),
+                                      jit_value_create_nint_constant
+                                                       (func, jit_type_nint, data2));
+}
+
 /*@
  * @deftypefun void jit_insn_iter_init ({jit_insn_iter_t *} iter, jit_block_t block)
  * Initialize an iterator to point to the first instruction in @code{block}.
index 4cb6ac54f1c4b2274f3aa519cc71157d9782da48..4afbe51df345e85e2cd07aae08e7b8bc71c3089a 100644 (file)
@@ -377,6 +377,7 @@ struct _jit_function
        int                                     has_try : 1;
        int                                     optimization_level : 8;
        int volatile            is_compiled;
+       int volatile            breakpoints_enabled;
 
        /* The entry point for the function's compiled code */
        void * volatile         entry_point;
index b92fb762f7f21e75cd1e7ac3c4e70b5bd0bcfa26..0de6402fe23a790585af934b52f32e6a40eb3766 100644 (file)
@@ -4456,6 +4456,18 @@ void _jit_run_function(jit_function_interp_t func, jit_item *args,
                }
                VMBREAK;
 
+               /******************************************************************
+                * Debugging support.
+                ******************************************************************/
+
+               VMCASE(JIT_OP_MARK_DEBUG):
+               {
+                       /* Process a breakpoint within the current function */
+                       /* TODO */
+                       VM_MODIFY_PC_AND_STACK(3, 0);
+               }
+               VMBREAK;
+
                /******************************************************************
                 * Opcodes that aren't used by the interpreter.  These are replaced
                 * by more specific instructions during function compilation.
@@ -4495,6 +4507,7 @@ void _jit_run_function(jit_function_interp_t func, jit_item *args,
                VMCASE(JIT_OP_ENTER_FINALLY):
                VMCASE(JIT_OP_ENTER_FILTER):
                VMCASE(JIT_OP_CALL_FILTER_RETURN):
+               VMCASE(JIT_OP_MARK_OFFSET):
                {
                        /* Shouldn't happen, but skip the instruction anyway */
                        VM_MODIFY_PC_AND_STACK(1, 0);
index ed60e5c7d2fb53d9905ef249536ce8b9e15af1a7..0d2a9924808cd3d1ac5abcdc54bcf76fb66191bd 100644 (file)
@@ -527,6 +527,12 @@ jit_opcode_info_t const jit_opcodes[JIT_OP_NUM_OPCODES] = {
         */
        {"alloca",                                              F_(PTR, PTR, EMPTY)},
 
+       /*
+        * Debugging support.
+        */
+       {"mark_offset",                                         F_(EMPTY, INT, EMPTY)},
+       {"mark_debug",                                          F_(EMPTY, PTR, PTR)},
+
 };
 
 #if defined(JIT_BACKEND_INTERP)
index 173033f8993136a49bb6089f70f287bd9b0c0c92..d41b761770bb6afb93cd9f4ff5535089cd638ba4 100644 (file)
@@ -1399,3 +1399,13 @@ JIT_OP_ADD_RELATIVE: unary
                        arm_alu_reg_imm(inst, ARM_ADD, $1, $1, insn->value2->address);
                }
        }
+
+/*
+ * Debugging support.
+ */
+
+JIT_OP_MARK_DEBUG: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
index 032054ee160b96ee71a0b6e0b8f133c82a564632..e8ceefca8c241f0f782e29c1312a55f37e5c5bb0 100644 (file)
@@ -1631,6 +1631,15 @@ void _jit_gen_insn(jit_gencode_t gen, jit_function_t func,
                }
                break;
 
+               case JIT_OP_MARK_DEBUG:
+               {
+                       /* Mark the current location as a potential breakpoint */
+                       jit_cache_opcode(&(gen->posn), insn->opcode);
+                       jit_cache_native(&(gen->posn), insn->value1->address);
+                       jit_cache_native(&(gen->posn), insn->value2->address);
+               }
+               break;
+
                default:
                {
                        /* Whatever opcodes are left are ordinary operators,
index 30aa4ccf75d5c4bff0118071c3eb73edc468ee0a..2d7f612586ddd8b25a6be1309cbe9721596399ea 100644 (file)
@@ -2800,3 +2800,13 @@ JIT_OP_ALLOCA: unary
                x86_mov_reg_reg(inst, $1, X86_ESP, 4);
                gen->stack_changed = 1;
        }
+
+/*
+ * Debugging support.
+ */
+
+JIT_OP_MARK_DEBUG: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
index 17237716e0f5eec0aab53709543c50b4c5d25d3c..df486a7be022ccd57ddb01317f7787b331fde928 100644 (file)
@@ -672,6 +672,8 @@ jit_value jit_function::get_struct_pointer()
  * @deftypemethodx jit_function jit_value jit_insn_alloca ({const jit_value&} size)
  * @deftypemethodx jit_function void insn_move_blocks_to_end ({const jit_label&} from_label, {const jit_label&} to_label)
  * @deftypemethodx jit_function void insn_move_blocks_to_start ({const jit_label&} from_label, {const jit_label&} to_label)
+ * @deftypemethodx jit_function void insn_mark_offset (jit_int offset)
+ * @deftypemethodx jit_function void insn_mark_debug (jit_nint data1, jit_nint data2)
  * Create instructions of various kinds.  @xref{Instructions}, for more
  * information on the individual instructions and their arguments.
  * @end deftypemethod
@@ -1426,6 +1428,22 @@ void jit_function::insn_move_blocks_to_start
        }
 }
 
+void jit_function::insn_mark_offset(jit_int offset)
+{
+       if(!jit_insn_mark_offset(func, offset))
+       {
+               out_of_memory();
+       }
+}
+
+void jit_function::insn_mark_debug(jit_nint data1, jit_nint data2)
+{
+       if(!jit_insn_mark_debug(func, data1, data2))
+       {
+               out_of_memory();
+       }
+}
+
 void jit_function::register_on_demand()
 {
        jit_function_set_on_demand_compiler(func, on_demand_compiler);