FileDocCategorySizeDatePackage
DebuggerInvoke.javaAPI DocphoneME MR2 API (J2ME)8272Wed May 02 17:59:54 BST 2007com.sun.cldchi.jvm

DebuggerInvoke

public class DebuggerInvoke extends Object

Fields Summary
private static final int
T_BOOLEAN
private static final int
T_CHAR
private static final int
T_FLOAT
private static final int
T_DOUBLE
private static final int
T_BYTE
private static final int
T_SHORT
private static final int
T_INT
private static final int
T_LONG
private static final int
T_OBJECT
private static final int
T_ARRAY
private static final int
T_VOID
Constructors Summary
Methods Summary
private static voiddebuggerInvoke(java.lang.Object entry, java.lang.Object transport, int id, int options, int return_type, int is_obj_return)
This method is used to synchronously invoke a method on behalf of a debugger and then return the method return value back to the debugger. The reason for this sync method is the non-synchronous nature of EntryActivations in the VM. Picture this, some event happens in the VM, like a breakpoint, which gets sent to the debugger. The debugger decides to invoke a Method. The return packet to the debugger for that invoke can't be sent until the Method returns and we send the return value (or exception object!) back to the debugger. So, all threads are suspended in the VM, we have a Method in hand and the debugger has picked a thread to execute this Method. We create an entry activation for that Method with all the args passed in by debugger. Then we create another entry activattion for this method. This allows us to synchronously call the Method requested, catch any exceptions and then call back down into the VM to send the reply packet. The return code in the VM will strip off these method calls from the thread stack so the thread will be back in the state it was before we started this whole invoke thing. We use two different return call methods based on what type of caller was on the stack when we started the whole invoke process. This is because there are two entry points into the VM; shared_call_vm and shared_call_vm_oop. (Don't care about shared_call_vm_exception). We need to make sure that the original call into the VM returns properly including any return values (object or otherwise) stored on the stack or in the EntryFrame or ThreadDesc.

param
entry really an EntryActivation object from the VM
param
transport a Transport object from the VM
param
id debugger request id used to generate outgoing reply packet
param
options invoke options from debugger
param
return_type return type of Method being invoked
param
is_obj_return if original caller of VM was shared_call_vm_oop


                                                                                                                                                                                                                                                                                                                                                              

            
                                          
                                        
    
      try {
        Object ret_obj = null;
        switch (return_type) {
        case T_VOID:
            invokeV(entry);
            break;
        case  T_OBJECT: {
            Object[] ret = new Object[1];
            Object o = invokeL(entry);
            ret[0] = o;
            ret_obj = ret;
            break;
        }

        case T_BOOLEAN:
        case T_BYTE:
        case T_SHORT:
        case T_CHAR:
        case T_INT: {
            int[] ret = new int[1];
            switch (return_type) {
            case T_BOOLEAN:
                boolean b = invokeZ(entry);
                ret[0] = b ? 1 : 0;
                break;
            case T_BYTE:
                ret[0] = (int)invokeB(entry);
                break;
            case T_SHORT:
                ret[0] = (int)invokeS(entry);
                break;
            case T_CHAR:
                ret[0] = (int)invokeC(entry);
                break;
            case T_INT:
                ret[0] = invokeI(entry);
                break;
            }
            ret_obj = ret;
            break;
        }
        case T_LONG: {
            long[] ret = new long[1];
            ret[0] = invokeJ(entry);
            ret_obj = ret;
            break;
        }
        case T_DOUBLE: {
            double[] ret = new double[1];
            ret[0] = invokeD(entry);
            ret_obj = ret;
            break;
        }
        case T_FLOAT: {
            float[] ret = new float[1];
            ret[0] = invokeF(entry);
            ret_obj = ret;
            break;
        }
        }
        if (is_obj_return == 1) {
            debuggerInvokeReturnObj(ret_obj, null, transport, id, options,
                                    return_type);
        } else {
            debuggerInvokeReturn(ret_obj, null, transport, id, options,
                                 return_type);
        }
      } catch (Throwable t) {
          // we send the exception object to the debugger via the native call
          if (is_obj_return == 1) {
              debuggerInvokeReturnObj(null, t, transport, id, options,
                                      return_type);
          } else {
              debuggerInvokeReturn(null, t, transport, id, options,
                                   return_type);
          }
      }
    
private static native longdebuggerInvokeReturn(java.lang.Object ret, java.lang.Object exception, java.lang.Object transport, int id, int options, int return_type)
This method is used by the java debugger code to signal the synchronous end of a method invoke

private static native java.lang.ObjectdebuggerInvokeReturnObj(java.lang.Object ret, java.lang.Object exception, java.lang.Object transport, int id, int options, int return_type)
You might think "Oh, I could combine this two methods into one and pass an arg to distinguish them". Don't! This one returns Object so that it enters the VM via shared_call_vm_oop. When we strip the frames off the stack in ObjectReferenceImpl::invoke_return we need to make sure we return the original return value that was stored in the EntryFrame back to the original caller.

private static native byteinvokeB(java.lang.Object entry)

private static native charinvokeC(java.lang.Object entry)

private static native doubleinvokeD(java.lang.Object entry)

private static native floatinvokeF(java.lang.Object entry)

private static native intinvokeI(java.lang.Object entry)

private static native longinvokeJ(java.lang.Object entry)

private static native java.lang.ObjectinvokeL(java.lang.Object entry)

private static native shortinvokeS(java.lang.Object entry)

private static native voidinvokeV(java.lang.Object entry)

private static native booleaninvokeZ(java.lang.Object entry)