diff --git a/libjava/ChangeLog b/libjava/ChangeLog index a2357c3e747..bb1ca39f46d 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,11 @@ +2006-01-30 Keith Seitz + + * include/java-interp.h (insn_index): New declaration. + (num_insn_slots): New private variable. + (get_line_table): New declaration. + * interpret.cc (insn_index): New function. + (get_line_table): New function. + 2006-01-24 Archit Shah Tom Tromey diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h index 872fb10a32b..73ab2fe0ae6 100644 --- a/libjava/include/java-interp.h +++ b/libjava/include/java-interp.h @@ -145,6 +145,7 @@ class _Jv_InterpMethod : public _Jv_MethodBase _Jv_LineTableEntry *line_table; void *prepared; + int number_insn_slots; unsigned char* bytecode () { @@ -182,9 +183,24 @@ class _Jv_InterpMethod : public _Jv_MethodBase // number info is unavailable. int get_source_line(pc_t mpc); +#ifdef DIRECT_THREADED + // Convenience function for indexing bytecode PC/insn slots in + // line tables for JDWP + jlong insn_index (pc_t pc); +#endif + public: static void dump_object(jobject o); + /* Get the line table for this method. + * start is the lowest index in the method + * end is the highest index in the method + * line_numbers is an array to hold the list of source line numbers + * code_indices is an array to hold the corresponding list of code indices + */ + void get_line_table (jlong& start, jlong& end, jintArray& line_numbers, + jlongArray& code_indices); + #ifdef DIRECT_THREADED friend void _Jv_CompileMethod (_Jv_InterpMethod*); #endif diff --git a/libjava/interpret.cc b/libjava/interpret.cc index d6e8ccca023..87d357c94c2 100644 --- a/libjava/interpret.cc +++ b/libjava/interpret.cc @@ -330,6 +330,7 @@ _Jv_InterpMethod::compile (const void * const *insn_targets) if (! first_pass) { insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next); + number_insn_slots = next; next = 0; } @@ -3672,6 +3673,80 @@ _Jv_InterpMethod::ncode () return self->ncode; } +#ifdef DIRECT_THREADED +/* Find the index of the given insn in the array of insn slots + for this method. Returns -1 if not found. */ +jlong +_Jv_InterpMethod::insn_index (pc_t pc) +{ + jlong left = 0; + jlong right = number_insn_slots; + insn_slot* slots = reinterpret_cast (prepared); + + while (right >= 0) + { + jlong mid = (left + right) / 2; + if (&slots[mid] == pc) + return mid; + + if (pc < &slots[mid]) + right = mid - 1; + else + left = mid + 1; + } + + return -1; +} +#endif // DIRECT_THREADED + +void +_Jv_InterpMethod::get_line_table (jlong& start, jlong& end, + jintArray& line_numbers, + jlongArray& code_indices) +{ +#ifdef DIRECT_THREADED + /* For the DIRECT_THREADED case, if the method has not yet been + * compiled, the linetable will change to insn slots instead of + * bytecode PCs. It is probably easiest, in this case, to simply + * compile the method and guarantee that we are using insn + * slots. + */ + _Jv_CompileMethod (this); + + if (line_table_len > 0) + { + start = 0; + end = number_insn_slots; + line_numbers = JvNewIntArray (line_table_len); + code_indices = JvNewLongArray (line_table_len); + + jint* lines = elements (line_numbers); + jlong* indices = elements (code_indices); + for (int i = 0; i < line_table_len; ++i) + { + lines[i] = line_table[i].line; + indices[i] = insn_index (line_table[i].pc); + } + } +#else // !DIRECT_THREADED + if (line_table_len > 0) + { + start = 0; + end = code_length; + line_numbers = JvNewIntArray (line_table_len); + code_indices = JvNewLongArray (line_table_len); + + jint* lines = elements (line_numbers); + jlong* indices = elements (code_indices); + for (int i = 0; i < line_table_len; ++i) + { + lines[i] = line_table[i].line; + indices[i] = (jlong) line_table[i].bytecode_pc; + } + } +#endif // !DIRECT_THREADED +} + void * _Jv_JNIMethod::ncode () {