示例#1
0
boolean debug_event(int event, Object *exception, const Thread *thread, const MethodRecord *method, byte *pc, int frame)
{
  // Inform the debug thread (if any) that there has been a debug event.
  // return false if no debug thread is waiting.
  switch(debugEventOptions[event])
  {
    case DBG_EVENT_DISABLE:
      return false;
    case DBG_EVENT_IGNORE:
      return true;
    default:
      break;
  }
  // Check that we have a debugger attached and that it is ready to go...
  if (!debug || get_monitor_count((&(debug->_super.sync))) != 0 ||
      debugThread->state != CONDVAR_WAITING || (Debug *)debugThread->waitingOn != debug)
    return false;
  // Setup the state
  debug->typ = event;
  debug->exception = ptr2ref(exception);
  debug->thread = ptr2ref(thread);
  debug->pc = (pc ? pc - get_binary_base() : 0);
  debug->method = (method ? method - get_method_table(get_class_record(0)) : 0);
  debug->frame = frame;
  // Suspend all threads (except current)
  suspend_thread(null);
  // Make sure current thread is also suspended
  suspend_thread(currentThread);
  //  Allow the debug thread to run
  resume_thread(debugThread);
  monitor_notify_unchecked(&debug->_super, 1);
  return true;
}
示例#2
0
文件: language.c 项目: h-sun/miss
/**
 * Create a compact form of the specified  call stack.
 * One int per frame containing
 * the method number and current offset. If the ignore parameter is non null
 * then frames that have a matching this field will not be included in the
 * trace. This allow the frames for the creation of an exception object to
 * be ignored.
 */
Object *
create_stack_trace(Thread *thread, Object *ignore)
{
  int frameCnt = thread->stackFrameIndex;
  Object *stackArray;
  JINT *data;
  int i;
  StackFrame *topFrame = ((StackFrame *)array_start(thread->stackFrameArray)) + frameCnt;
  StackFrame *stackFrame = topFrame;
  MethodRecord *methodBase = get_method_table(get_class_record(0));
  byte *pcBase = get_binary_base() + 2;

  // Ignore frames if required.
  if (ignore)
  {
    while ((STACKWORD)ignore == *(stackFrame->localsBase))
    {
      stackFrame--;
      frameCnt--;
    }
  }
  // Try and allocate the space for the trace.
  stackArray = new_single_array(AI, frameCnt);
  if (stackArray == JNULL) return JNULL;
  if (thread == currentThread)
    topFrame->pc = getPc();
  // adjust top most pc to allow for return address hack
  topFrame->pc += 2;
  // Fill in the trace.
  data = jint_array(stackArray);
  for(i = 0; i < frameCnt; i++)
  {
    data[i] = ((stackFrame->methodRecord - methodBase) << 16) | (stackFrame->pc - pcBase - stackFrame->methodRecord->codeOffset);
    stackFrame--;
  }
  // restore correct pc
  topFrame->pc -= 2;
  return stackArray;
}
示例#3
0
/**
 * @return false iff all threads are dead.
 */
void throw_exception (Object *exception)
{
  Thread *auxThread;
  
  #ifdef VERIFY
  assert (exception != null, EXCEPTIONS0);
  #endif // VERIFY

#if DEBUG_EXCEPTIONS
  printf("Throw exception\n");
#endif
  if (currentThread == null)
  {
    // No threads have started probably
    return;
  }
  else if (exception == interruptedException)
  {
    // Throwing an interrupted exception clears the flag
    currentThread->interruptState = INTERRUPT_CLEARED;
  }
  
  #ifdef VERIFY
  assert (currentThread->state > DEAD, EXCEPTIONS1);
  #endif // VERIFY
  
  gExceptionPc = pc;
  gExcepMethodRec = null;

  #if 0
  trace (-1, get_class_index(exception), 3);
  #endif

 LABEL_PROPAGATE:
  tempStackFrame = current_stackframe();
  tempMethodRecord = tempStackFrame->methodRecord;

  if (gExcepMethodRec == null)
    gExcepMethodRec = tempMethodRecord;
  gExceptionRecord = (ExceptionRecord *) (get_binary_base() + tempMethodRecord->exceptionTable);
  tempCurrentOffset = ptr2word(pc) - ptr2word(get_binary_base() + tempMethodRecord->codeOffset);

  #if 0
  trace (-1, tempCurrentOffset, 5);
  #endif

  gNumExceptionHandlers = tempMethodRecord->numExceptionHandlers;
#if DEBUG_EXCEPTIONS
  printf("Num exception handlers=%d\n",gNumExceptionHandlers);
#endif
  while (gNumExceptionHandlers--)
  {
    if (gExceptionRecord->start <= tempCurrentOffset /* off by one? < ? */
        && tempCurrentOffset <= gExceptionRecord->end)
    {
      // Check if exception class applies
      if (instance_of (exception, gExceptionRecord->classIndex))
      {
        // Clear operand stack
        init_sp (tempStackFrame, tempMethodRecord);
        // Push the exception object
        push_ref (ptr2word (exception));
        // Jump to handler:
        pc = get_binary_base() + tempMethodRecord->codeOffset + 
             gExceptionRecord->handler;
#if DEBUG_EXCEPTIONS
  printf("Found exception handler\n");
#endif
        return;
      }
    }
    gExceptionRecord++;
  }
  // No good handlers in current stack frame - go up.
  auxThread = currentThread;
  do_return (0);
  // Note: return takes care of synchronized methods.
  if (auxThread->state == DEAD)
  {
#if DEBUG_EXCEPTIONS
  printf("Thread is dead\n");
#endif
    if (get_class_index(exception) != JAVA_LANG_THREADDEATH)
    {
#if DEBUG_EXCEPTIONS
  printf("Handle uncaught exception\n");
#endif

      handle_uncaught_exception (exception, auxThread,
  			         gExcepMethodRec, tempMethodRecord,
			         gExceptionPc);
    }
    return;
  }
  goto LABEL_PROPAGATE; 


}
示例#4
0
文件: language.c 项目: h-sun/miss
/**
 * Exceute the static initializer if required. Note that the ret address used
 * here is set such that the current instruction will be re-started when the
 * initialization completes.
 * @return An indication of how the VM should proceed
 */
int dispatch_static_initializer (ClassRecord *aRec, byte *retAddr)
{
  int state = get_init_state(aRec);
  ClassRecord *init = aRec;
  ClassRecord *super = get_class_record(init->parentClass);
  MethodRecord *method;
  // Are we needed?
  if (state & C_INITIALIZED) return EXEC_CONTINUE;
  // We need to initialize all of the super classes first. So we find the
  // highest one that has not been initialized and deal with that. This code
  // will then be called again and we will init the next highest and so on
  // until all of the classes in the chain are done.
  for(;;)
  {
    // find first super class that has not been initialized
    while (init != super && (get_init_state(super) & C_INITIALIZED) == 0)
    {
      init = super;
      super = get_class_record(init->parentClass);
    }
    // Do we have an initilizer if so we have found our class
    if (has_clinit (init)) break;
    // no initializer so mark as now initialized
    set_init_state (init, C_INITIALIZED);
    // If we are at the start of the list we are done
    if (init == aRec) return EXEC_CONTINUE;
    // Otherwise go do it all again
    init = aRec;
  }
  state = get_init_state(init);
  // are we already initializing ?
  if (state & C_INITIALIZING)
  {
    // Is it this thread that is doing the init?
    if (get_sync(init)->threadId == currentThread->threadId)
      return EXEC_CONTINUE;
    // No so we must retry the current instruction
    curPc = retAddr;
    sleep_thread(1);
    schedule_request(REQUEST_SWITCH_THREAD);
    return EXEC_RETRY;
  }
  #if DEBUG_METHODS
  printf ("dispatch_static_initializer: has clinit: %d, %d\n",
          (int) aRec, (int) retAddr);
  #endif
  // Static initializer is always the first method
  method = get_method_table(init);
  if ((byte *)method == get_binary_base() || method->signatureId != _6clinit_7_4_5V)
  {
    throw_new_exception (JAVA_LANG_NOSUCHMETHODERROR);
    return EXEC_EXCEPTION;
  }

  // Can we run it?
  if (!dispatch_special (method, retAddr))
    return EXEC_RETRY;
  // Mark for next time
  set_init_state(init, C_INITIALIZING);
  // and claim the monitor
  current_stackframe()->monitor = (Object *)init;
  enter_monitor (currentThread, (Object *)init);
  return EXEC_RUN;
}