void ClassTypeImpl::class_type_super_class(PacketInputStream *in, 
                     PacketOutputStream *out)
{
  UsingFastOops fast_oops;

  InstanceClass::Fast clazz = in->read_class_ref();
  InstanceClass::Fast superclass;

  if (clazz.is_null() || clazz().is_interface()) { 
    out->write_int(0);
  } else {
#ifdef AZZERT
    if (TraceDebugger) {
      tty->print("Superclass of class: ");
      JavaDebugger::print_class(&clazz);
      tty->print_cr("");
    }
#endif
    superclass = clazz().super();
    if (superclass.is_null()) {
      out->write_int(0);
    } else {
#ifdef AZZERT
      if (TraceDebugger) {
        tty->print("SuperClass = ");
        JavaDebugger::print_class(&superclass);
        tty->print_cr(", id = 0x%x", JavaDebugger::get_object_id_by_ref_nocreate(&superclass));
      }
#endif
      out->write_class(&superclass);
    }
  }
  out->send_packet();
}
Exemplo n.º 2
0
void ObjectReferenceImpl::common_invoke_method(PacketInputStream *in,
                                                     PacketOutputStream *out,
                                                     bool is_static)
{
  UsingFastOops fastoops;

  SETUP_ERROR_CHECKER_ARG;
  Oop::Fast this_object;
  JavaClass::Fast this_klass;
  Thread::Fast invoke_thread;
  InstanceClass::Fast ic;
  Method::Fast m, sync_method;
  int arg_count;
  jbyte type_tag, modified_tag;
  EntryActivation::Fast entry, sync_entry;
  int arg_index = 0;
  int options;

#ifdef AZZERT
  if (TraceDebugger) {
    tty->print_cr("ObjectReferenceImpl: invoke %s method starting",
                  (is_static ? "static" : "instance"));
  }
#endif
  if (!is_static) {
    this_object = in->read_object();
    if (this_object.is_null()) {
      out->send_error(JDWP_Error_INVALID_OBJECT);
      return;
    }
    invoke_thread = in->read_thread_ref();
    ic = in->read_class_ref();
  } else {
    // Why couldn't they use the same order as static invoke?
    ic = in->read_class_ref();
    invoke_thread = in->read_thread_ref();
  }
  if (invoke_thread.is_null()) {
    out->send_error(JDWP_Error_INVALID_THREAD);
    return;
  }
  if ((invoke_thread().status() & THREAD_DBG_SUSPENDED_BY_EVENT) == 0) {
    if (TraceDebugger) {
      tty->print_cr("ObjectReferenceImpl: Thread not suspended by event");
    }
    out->send_error(JDWP_Error_THREAD_NOT_SUSPENDED);
    return;
  }
  if (ic.is_null()) {
    out->send_error(JDWP_Error_INVALID_CLASS);
    return;
  }
  m = JavaDebugger::get_method_by_id(&ic, in->read_long());

  if (m.is_null()) {
    out->send_error(JDWP_Error_INVALID_METHODID);
    return;
  }
#ifdef AZZERT
  if (TraceDebugger) {
      tty->print("ObjectReferenceImpl: invoke method ");
      m().print_value_on(tty);
      tty->cr();
      tty->print("   class ref ");
      ic().print_name_on(tty);
      tty->cr();
  }
#endif
  arg_count = in->read_int();
  arg_count += (!is_static ? 1 : 0);
  entry = Universe::new_entry_activation(&m, arg_count JVM_NO_CHECK);
  Signature::Fast sig = m().signature();
  SignatureStream ss(&sig, is_static);

  // If it's an instance method we need to push the 'this_object' rather
  // than one of the arguments sitting in the input stream.
  if (!is_static) {
    entry().obj_at_put(arg_index++, &this_object);
    ss.next();  // point at arg just past 'this'
  }

  for (;
       !ss.eos() && arg_index < arg_count && !ss.is_return_type();
       ss.next()) {
    type_tag = in->read_byte();
    modified_tag = type_tag;
    if (type_tag == JDWP_Tag_STRING ||
        type_tag == JDWP_Tag_THREAD ||
        type_tag == JDWP_Tag_CLASS_OBJECT) {
      modified_tag = JDWP_Tag_OBJECT;
    }
    if (JavaDebugger::get_tag_from_type(ss.type()) != modified_tag) {
      if (TraceDebugger) {
        tty->print_cr("ObjectReferenceImpl: invoke method: illegal arg, type %d, expected %d ", type_tag, ss.type());
      }
      out->send_error(JDWP_Error_ILLEGAL_ARGUMENT);
      return;
    } 
    switch(type_tag) {
    case JDWP_Tag_INT:
      entry().int_at_put(arg_index++, in->read_int());
      break;
    case JDWP_Tag_CHAR:
      entry().int_at_put(arg_index++, (int)in->read_char());
      break;
    case JDWP_Tag_SHORT:
      entry().int_at_put(arg_index++, (int)in->read_short());
      break;
    case JDWP_Tag_DOUBLE:
      entry().double_at_put(arg_index++, in->read_double());
      break;
    case JDWP_Tag_LONG:
      entry().long_at_put(arg_index++, in->read_long());
      break;
    case JDWP_Tag_BOOLEAN:
      entry().int_at_put(arg_index++, (int)in->read_boolean());
      break;
    case JDWP_Tag_OBJECT:
    case JDWP_Tag_ARRAY:
    case JDWP_Tag_STRING:
    case JDWP_Tag_THREAD:
    case JDWP_Tag_CLASS_OBJECT:
      {
        UsingFastOops fastoops2;
        Oop::Fast o = in->read_object();
        JavaClass::Fast o_klass = o().blueprint();
        JavaClass::Fast sig_klass = ss.type_klass();
        if (!sig_klass().is_subtype_of(&o_klass)) {
          out->send_error(JDWP_Error_ILLEGAL_ARGUMENT);
          return;
        }
        entry().obj_at_put(arg_index++, &o);
        break;
      }
    default:
#ifdef AZZERT
      tty->print_cr("Unknown argument type %d", type_tag);
      out->send_error(JDWP_Error_ILLEGAL_ARGUMENT);
      return;
#endif
      break;
    }
  }
  if (arg_index < arg_count || !ss.is_return_type()) {
    // if arg_index < arg_count we must have reached eos
    // if !return_type then the actual method has more args than the debugger
    // thinks
    out->send_error(JDWP_Error_ILLEGAL_ARGUMENT);
    return;
  }
  options = in->read_int();
  if (options & JDWP_InvokeOptions_INVOKE_SINGLE_THREADED) {
    ThreadReferenceImpl::resume_specific_thread(&invoke_thread, -1);
  } else {
    ThreadReferenceImpl::resume_all_threads(-1);
  }
  sync_method =
    Universe::dbg_class()->find_local_method(Symbols::debugger_sync_name(),
                               Symbols::obj_obj_int_int_int_int_void_signature());
  if (sync_method.is_null()) {
    out->send_error(JDWP_Error_ILLEGAL_ARGUMENT);
    return;
  }
#ifdef AZZERT
  Frame fr(&invoke_thread);
  GUARANTEE(fr.is_java_frame(), "Must have java frame before invoking method");
#endif
  address* stack_pointer = (address*)invoke_thread().stack_pointer();
  address ret_addr =
      stack_pointer[-1 * JavaStackDirection];
  int is_object_return = 0;
  if (ret_addr == (address)shared_call_vm_oop_return) {
    is_object_return = 1;
  }
  sync_entry = Universe::new_entry_activation(&sync_method, 6 JVM_NO_CHECK);
  sync_entry().obj_at_put(0, &entry);
  sync_entry().obj_at_put(1, in->transport());
  sync_entry().int_at_put(2, in->id());
  sync_entry().int_at_put(3, options);
  sync_entry().int_at_put(4, ss.type());
  sync_entry().int_at_put(5, is_object_return);
  invoke_thread().append_pending_entry(&sync_entry);
}
Exemplo n.º 3
0
void ObjectReferenceImpl::object_field_getter_setter(PacketInputStream *in, 
                         PacketOutputStream *out, 
                         bool is_setter)
{
  UsingFastOops fast_oops;
  int i;

  Oop::Fast object = in->read_object();
  jint num = in->read_int();
  if (object.is_null()) {
    out->send_error(JDWP_Error_INVALID_OBJECT);
    return;
  }

  // Create a buffered output stream so we can asynchronously send an error
  // Calculate the size based on half of the items being 'longs'
#ifdef AZZERT
  if (TraceDebugger) {
    tty->print_cr("Object %s, objectID=%ld, object=0x%lx, count=%ld",
                  (is_setter ? "Set" : "Get"), 
                  JavaDebugger::get_object_id_by_ref_nocreate(&object), 
                  object.obj(), num);
  }
#endif
  if (!is_setter) { 
    out->write_int(num);
  }

  for (i = 0; i < num; i++) {
    UsingFastOops fast_oops_2;

    InstanceClass::Fast fieldClazz = in->read_class_ref();
    TypeArray::Fast fields;  
    jint field_id = in->read_int();

    if (fieldClazz.is_null()) {
      out->send_error(JDWP_Error_INVALID_FIELDID);
      return;
    }
    fields = fieldClazz().fields();
    if (fields.is_null()) {
      out->send_error(JDWP_Error_INVALID_FIELDID);
      return;
    }
    if (field_id >=fields().length() / Field::NUMBER_OF_SLOTS) {
      out->send_error(JDWP_Error_INVALID_FIELDID);
      return;
    }
    Field field(&fieldClazz, field_id * Field::NUMBER_OF_SLOTS);
    char type_tag = (field.type() < T_OBJECT) 
      ? JavaDebugger::get_tag_from_type(field.type()) 
      : JDWP_Tag_OBJECT;
    if (is_setter) { 
      read_value_to_address(in, &object, field.offset(), type_tag, false);
    } else { 
      write_value_from_address(out, &object, field.offset(), type_tag, true, false);
    }
#ifdef AZZERT
    if (TraceDebugger) {
      //AccessFlags field_access_flags = field.access_flags();
      tty->print("    ");  
      JavaDebugger::print_class(&fieldClazz), 
        tty->print(".");
      JavaDebugger::print_field(&field);
      tty->print(": ");
      print_value_from_address(&object, field.offset(), type_tag);
      tty->print_cr("");
    }
#endif
  }
  out->send_packet();
}