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();
}
예제 #2
0
//
// Helper function for field access
//
jfieldID _KNI_field_lookup_helper(jclass classHandle, const char* name,
                                  const char* signature, bool is_static) {
  UsingFastOops fast_oops;
  JavaClassObj::Fast mirror = kni_read_handle(classHandle);
  InstanceClass::Fast ic = mirror().java_class();
  InstanceClass::Fast holder(ic.obj());

  GUARANTEE(ic.is_instance_class(), "sanity check");

  SETUP_ERROR_CHECKER_ARG;
  Symbol::Fast n = SymbolTable::check_symbol_for(name _KNI_CHECK_0);
  Symbol::Fast s = TypeSymbol::parse((char*)signature _KNI_CHECK_0);

  Field field(&holder, &n, &s);

#ifndef PRODUCT
  // If you're hit by this GUARANTEE, make sure you have use
  // the DontRenameNonPublicFields option in the -romconfig file for
  // this class.
  //GUARANTEE(!field.is_valid(), "Field was renamed by Romizer.");

  if (!field.is_valid()) {
    tty->print_cr("WARNING: invalid KNI field access: %s", name);
  }
#endif

  // No exception check (OutOfMemoryError) done, field lookup will
  // fail and NULL be returned below anyway.
  if (!field.is_valid() || (field.is_static() != is_static) ||
      // We do not support field IDs in super classes:
      (field.is_static() && !holder().equals(&ic))) {
    return (jfieldID)0;
  } else {
    return (jfieldID)((jint)field.offset());
  }
}
예제 #3
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);
}
예제 #4
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();
}
void ReferenceTypeImpl::static_field_getter_setter(PacketInputStream *in, 
                         PacketOutputStream *out,
                         bool is_setter)
{
  UsingFastOops fast_oops;

  InstanceClass::Fast clazz = in->read_class_ref(); 
  jint num = in->read_int();
  int i;

#ifdef AZZERT
  if (TraceDebugger) {
    tty->print_cr("Static %s: class=0x%lx, count=%ld",
                  (is_setter ? "Set" : "Get"), 
                  clazz.obj(), num);
  }
#endif

  // Prevent compiler warnings
  clazz = clazz;

  // Create a buffered output stream so we can asynchronously send an error
  // Calculate the size based on half of the items being 'longs'
  if (!is_setter) { 
    out->write_int(num);
  }

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

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

    if (field_clazz.is_null()) {
      out->send_error(JDWP_Error_INVALID_FIELDID);
      return;
    }
    fields = field_clazz().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(&field_clazz, field_id * Field::NUMBER_OF_SLOTS);
    if (!field.is_static() || (is_setter && field.is_final())) { 
      out->send_error(JDWP_Error_INVALID_FIELDID);
      return;
    }

    type_tag = (field.type() < T_OBJECT ) 
      ? JavaDebugger::get_tag_from_type(field.type())
      : JDWP_Tag_OBJECT;
    Oop::Fast p;
#if ENABLE_ISOLATES
    // Statics don't live at the end of the JavaClassDesc, we need to
    // find the correct task mirror for this task
    {
      SETUP_ERROR_CHECKER_ARG;
      TaskGCContext tmp(in->transport()->task_id());
      TaskMirror::Fast tm = field_clazz().task_mirror_no_check();
      if (!TaskMirrorDesc::is_initialized_mirror((TaskMirrorDesc*)tm.obj())) {
        GUARANTEE(field_clazz().is_interface(),
                  "Non-interface class not initialized");
        if (field_clazz().is_interface()) {
          SAVE_CURRENT_EXCEPTION;
          // If an interface contains only non-object data then
          // it will not get initialized since javac will only
          // create a reference to the interface class if you
          // are accessing some static object like a static array
          // We need to at least initialized the statics
          tm = task_barrier(Thread::current(), field_clazz.obj() JVM_NO_CHECK);
          if (tm.is_null()) {
            // oome
            RESTORE_CURRENT_EXCEPTION;
            out->send_error(JDWP_Error_OUT_OF_MEMORY);
            return;
          }
          RESTORE_CURRENT_EXCEPTION;
        }
      }
      p = tm();
    }
#else
    p = field_clazz();
#endif
    if (is_setter) {
      ObjectReferenceImpl::read_value_to_address(in, &p,
                                                 field.offset(),
                                                 type_tag, true);
    } else { 
      ObjectReferenceImpl::write_value_from_address(out, &p,
                                                    field.offset(),
                                                    type_tag, true, true);
    }
#ifdef AZZERT
    if (TraceDebugger) { 
      tty->print("    ");     
      JavaDebugger::print_class(&field_clazz);
      tty->print(".");  
      JavaDebugger::print_field(&field);
      tty->print(": ");
      ObjectReferenceImpl::print_value_from_address(&p, 
                                                    field.offset(),
                                                    type_tag);
      tty->print_cr("");
    }
#endif
  }
  out->send_packet();
}