Roughly in the order of priority:
The goal is to get a very basic debugger which handles breakpoints correctly and supports dumping local variables, all of which have been spilled into memory working on all the platforms we're planning to support.
During the construction of the primitive graph, the data nodes will be
annotated with a pointer to the LocalVariableEntry. Since it
is important to keep the compilation time down, it is necessary to
quickly get to a LocalVariableEntry at a given slot
index. Since the JVM specification doesn't state an order in which
these entries appear in the table, we'll keep the local variables in
the increasing order with respect to the slot index, so that a binary
search of the table will get us to the right entry in O(log(n)) time.
A hardware specific breakpoint/trap instruction will be inserted into the native code. A platform specific trap handler gets executed and the trap handler sends a JVMDI_Event of type JVMDI_EVENT_BREAKPOINT. And then waits till the debugger tells it to continue execution using a user defined event.
An auxillary data structure pc2bci maps the current PC to a byte
code index. Each local variable entry in the LocalVariableTable
will be annotated with a list of mappings from byte code ranges to
it's address in register or memory.
So querying the value of a local variable will involve the following steps:
pc2bci using the current
PC.
LocalVariableEntry up in LocalVariableTable
by name.
The debugger will run as a separate NSPR thread and wait for events coming in from the primitive debugger interface (PDI) as detailed in the Javasoft document.
Since all the necessary infrastructure is not in place, for testing purposes, an external driver program will be used that sends socket based messages to the debugger thread.
Further if the VM has been invoked with the -debug option, the VM
sends a breakpoint event to itself at the main routine, in order to
give the (possibly) remote debugger an opportunity to connect to the
VM. (Is this really necessary ?)