Change well-known `DdmServer` methods to `ArtMethod*`.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing --interpreter
Test: run-libjdwp-tests.sh --mode=device --variant=X32 --debug
Change-Id: I31c61424a81037a20d4a6bceb081915da067d87f
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index 6499bac..0057bf9 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -48,6 +48,158 @@
 
 namespace art {
 
+namespace detail {
+
+template <> struct ShortyTraits<'V'> {
+  using Type = void;
+  static Type Get(const JValue& value ATTRIBUTE_UNUSED) {}
+  // `kVRegCount` and `Set()` are not defined.
+};
+
+template <> struct ShortyTraits<'Z'> {
+  // We're using `uint8_t` for `boolean`, see `JValue`.
+  using Type = uint8_t;
+  static Type Get(const JValue& value) { return value.GetZ(); }
+  static constexpr size_t kVRegCount = 1u;
+  static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'B'> {
+  using Type = int8_t;
+  static Type Get(const JValue& value) { return value.GetB(); }
+  static constexpr size_t kVRegCount = 1u;
+  static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'C'> {
+  using Type = uint16_t;
+  static Type Get(const JValue& value) { return value.GetC(); }
+  static constexpr size_t kVRegCount = 1u;
+  static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'S'> {
+  using Type = int16_t;
+  static Type Get(const JValue& value) { return value.GetS(); }
+  static constexpr size_t kVRegCount = 1u;
+  static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'I'> {
+  using Type = int32_t;
+  static Type Get(const JValue& value) { return value.GetI(); }
+  static constexpr size_t kVRegCount = 1u;
+  static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'J'> {
+  using Type = int64_t;
+  static Type Get(const JValue& value) { return value.GetJ(); }
+  static constexpr size_t kVRegCount = 2u;
+  static void Set(uint32_t* args, Type value) {
+    // Little-endian representation.
+    args[0] = static_cast<uint32_t>(value);
+    args[1] = static_cast<uint32_t>(static_cast<uint64_t>(value) >> 32);
+  }
+};
+
+template <> struct ShortyTraits<'F'> {
+  using Type = float;
+  static Type Get(const JValue& value) { return value.GetF(); }
+  static constexpr size_t kVRegCount = 1u;
+  static void Set(uint32_t* args, Type value) { args[0] = bit_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'D'> {
+  using Type = double;
+  static Type Get(const JValue& value) { return value.GetD(); }
+  static constexpr size_t kVRegCount = 2u;
+  static void Set(uint32_t* args, Type value) {
+    // Little-endian representation.
+    uint64_t v = bit_cast<uint64_t>(value);
+    args[0] = static_cast<uint32_t>(v);
+    args[1] = static_cast<uint32_t>(v >> 32);
+  }
+};
+
+template <> struct ShortyTraits<'L'> {
+  using Type = ObjPtr<mirror::Object>;
+  static Type Get(const JValue& value) REQUIRES_SHARED(Locks::mutator_lock_) {
+      return value.GetL();
+  }
+  static constexpr size_t kVRegCount = 1u;
+  static void Set(uint32_t* args, Type value) REQUIRES_SHARED(Locks::mutator_lock_) {
+    args[0] = StackReference<mirror::Object>::FromMirrorPtr(value.Ptr()).AsVRegValue();
+  }
+};
+
+template <char... Shorty>
+constexpr auto MaterializeShorty() {
+  constexpr size_t kSize = std::size({Shorty...}) + 1u;
+  return std::array<char, kSize>{Shorty..., '\0'};
+}
+
+template <char... ArgType>
+constexpr size_t NumberOfVRegs() {
+  constexpr size_t kArgVRegCount[] = {
+    ShortyTraits<ArgType>::kVRegCount...
+  };
+  size_t sum = 0u;
+  for (size_t count : kArgVRegCount) {
+    sum += count;
+  }
+  return sum;
+}
+
+template <char... ArgType>
+inline ALWAYS_INLINE void FillVRegs(uint32_t* vregs ATTRIBUTE_UNUSED,
+                                    typename ShortyTraits<ArgType>::Type... args ATTRIBUTE_UNUSED)
+    REQUIRES_SHARED(Locks::mutator_lock_) {}
+
+template <char FirstArgType, char... ArgType>
+inline ALWAYS_INLINE void FillVRegs(uint32_t* vregs,
+                                    typename ShortyTraits<FirstArgType>::Type first_arg,
+                                    typename ShortyTraits<ArgType>::Type... args)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  ShortyTraits<FirstArgType>::Set(vregs, first_arg);
+  FillVRegs<ArgType...>(vregs + ShortyTraits<FirstArgType>::kVRegCount, args...);
+}
+
+template <char... ArgType>
+inline ALWAYS_INLINE auto MaterializeVRegs(typename ShortyTraits<ArgType>::Type... args)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  constexpr size_t kNumVRegs = NumberOfVRegs<ArgType...>();
+  std::array<uint32_t, kNumVRegs> vregs;
+  FillVRegs<ArgType...>(vregs.data(), args...);
+  return vregs;
+}
+
+}  // namespace detail
+
+template <char ReturnType, char... ArgType>
+inline typename detail::ShortyTraits<ReturnType>::Type
+ArtMethod::InvokeStatic(Thread* self, typename detail::ShortyTraits<ArgType>::Type... args) {
+  DCHECK(IsStatic());
+  JValue result;
+  constexpr auto shorty = detail::MaterializeShorty<ReturnType, ArgType...>();
+  auto vregs = detail::MaterializeVRegs<ArgType...>(args...);
+  Invoke(self, vregs.data(), sizeof(vregs), &result, shorty.data());
+  return detail::ShortyTraits<ReturnType>::Get(result);
+}
+
+template <char ReturnType, char... ArgType>
+typename detail::ShortyTraits<ReturnType>::Type
+ArtMethod::InvokeInstance(Thread* self,
+                          ObjPtr<mirror::Object> receiver,
+                          typename detail::ShortyTraits<ArgType>::Type... args) {
+  DCHECK(!IsStatic());
+  JValue result;
+  constexpr auto shorty = detail::MaterializeShorty<ReturnType, ArgType...>();
+  auto vregs = detail::MaterializeVRegs<'L', ArgType...>(receiver, args...);
+  Invoke(self, vregs.data(), sizeof(vregs), &result, shorty.data());
+  return detail::ShortyTraits<ReturnType>::Get(result);
+}
+
 template <ReadBarrierOption kReadBarrierOption>
 inline ObjPtr<mirror::Class> ArtMethod::GetDeclaringClassUnchecked() {
   GcRootSource gc_root_source(this);
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 8347577..f7f900f 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -68,6 +68,20 @@
 class String;
 }  // namespace mirror
 
+namespace detail {
+template <char Type> struct ShortyTraits;
+template <> struct ShortyTraits<'V'>;
+template <> struct ShortyTraits<'Z'>;
+template <> struct ShortyTraits<'B'>;
+template <> struct ShortyTraits<'C'>;
+template <> struct ShortyTraits<'S'>;
+template <> struct ShortyTraits<'I'>;
+template <> struct ShortyTraits<'J'>;
+template <> struct ShortyTraits<'F'>;
+template <> struct ShortyTraits<'D'>;
+template <> struct ShortyTraits<'L'>;
+}  // namespace detail
+
 class ArtMethod final {
  public:
   // Should the class state be checked on sensitive operations?
@@ -644,6 +658,18 @@
   void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  template <char ReturnType, char... ArgType>
+  typename detail::ShortyTraits<ReturnType>::Type
+  InvokeStatic(Thread* self, typename detail::ShortyTraits<ArgType>::Type... args)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
+  template <char ReturnType, char... ArgType>
+  typename detail::ShortyTraits<ReturnType>::Type
+  InvokeInstance(Thread* self,
+                 ObjPtr<mirror::Object> receiver,
+                 typename detail::ShortyTraits<ArgType>::Type... args)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
   const void* GetEntryPointFromQuickCompiledCode() const {
     return GetEntryPointFromQuickCompiledCodePtrSize(kRuntimePointerSize);
   }
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 12ed605..77de012 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1141,6 +1141,9 @@
       WellKnownClasses::java_lang_Integer_valueOf,
       WellKnownClasses::java_lang_Long_valueOf,
       WellKnownClasses::java_lang_Short_valueOf,
+      // We're suppressing exceptions from `DdmServer` and we do not want to repeatedly
+      // suppress class initialization error (say, due to OOM), so initialize it early.
+      WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_dispatch,
   };
   for (ArtMethod* method : static_methods_of_classes_to_initialize) {
     EnsureRootInitialized(this, self, method->GetDeclaringClass());
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 3781522..3dda8f9 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -187,33 +187,29 @@
                          const ArrayRef<const jbyte>& data,
                          /*out*/uint32_t* out_type,
                          /*out*/std::vector<uint8_t>* out_data) {
-  ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(data.size()));
-  if (dataArray.get() == nullptr) {
+  ScopedObjectAccess soa(env);
+  StackHandleScope<1u> hs(soa.Self());
+  Handle<mirror::ByteArray> data_array =
+      hs.NewHandle(mirror::ByteArray::Alloc(soa.Self(), data.size()));
+  if (data_array == nullptr) {
     LOG(WARNING) << "byte[] allocation failed: " << data.size();
     env->ExceptionClear();
     return false;
   }
-  env->SetByteArrayRegion(dataArray.get(),
-                          0,
-                          data.size(),
-                          reinterpret_cast<const jbyte*>(data.data()));
+  memcpy(data_array->GetData(), data.data(), data.size());
   // Call "private static Chunk dispatch(int type, byte[] data, int offset, int length)".
-  ScopedLocalRef<jobject> chunk(
-      env,
-      env->CallStaticObjectMethod(
-          WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer,
-          WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_dispatch,
-          type, dataArray.get(), 0, data.size()));
-  if (env->ExceptionCheck()) {
-    Thread* self = Thread::Current();
-    ScopedObjectAccess soa(self);
+  ArtMethod* dispatch = WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_dispatch;
+  DCHECK(dispatch->GetDeclaringClass()->IsInitialized());
+  ObjPtr<mirror::Object> chunk = dispatch->InvokeStatic<'L', 'I', 'L', 'I', 'I'>(
+      soa.Self(), type, data_array.Get(), 0, static_cast<jint>(data.size()));
+  if (soa.Self()->IsExceptionPending()) {
     LOG(INFO) << StringPrintf("Exception thrown by dispatcher for 0x%08x", type) << std::endl
-              << self->GetException()->Dump();
-    self->ClearException();
+              << soa.Self()->GetException()->Dump();
+    soa.Self()->ClearException();
     return false;
   }
 
-  if (chunk.get() == nullptr) {
+  if (chunk == nullptr) {
     return false;
   }
 
@@ -229,39 +225,33 @@
    *
    * So we're pretty much stuck with copying data around multiple times.
    */
-  ScopedLocalRef<jbyteArray> replyData(env, nullptr);
-  jint offset;
-  jint length;
-  {
-    ScopedObjectAccess soa(env);
-    ObjPtr<mirror::Object> raw_chunk = soa.Decode<mirror::Object>(chunk.get());
-    replyData.reset(soa.AddLocalReference<jbyteArray>(
-        WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_data->GetObject(raw_chunk)));
-    offset = WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_offset->GetInt(raw_chunk);
-    length = WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_length->GetInt(raw_chunk);
-    *out_type = WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_type->GetInt(raw_chunk);
-  }
+  ObjPtr<mirror::ByteArray> reply_data = ObjPtr<mirror::ByteArray>::DownCast(
+      WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_data->GetObject(chunk));
+  jint offset = WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_offset->GetInt(chunk);
+  jint length = WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_length->GetInt(chunk);
+  *out_type = WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_type->GetInt(chunk);
 
   VLOG(jdwp) << StringPrintf("DDM reply: type=0x%08x data=%p offset=%d length=%d",
                              type,
-                             replyData.get(),
+                             reply_data.Ptr(),
                              offset,
                              length);
-  out_data->resize(length);
-  env->GetByteArrayRegion(replyData.get(),
-                          offset,
-                          length,
-                          reinterpret_cast<jbyte*>(out_data->data()));
 
-  if (env->ExceptionCheck()) {
-    Thread* self = Thread::Current();
-    ScopedObjectAccess soa(self);
-    LOG(INFO) << StringPrintf("Exception thrown when reading response data from dispatcher 0x%08x",
-                              type) << std::endl << self->GetException()->Dump();
-    self->ClearException();
+  if (reply_data == nullptr) {
+    LOG(INFO) << "Null reply data";
     return false;
   }
 
+  jint reply_length = reply_data->GetLength();
+  if (offset < 0 || offset > reply_length || length < 0 || length > reply_length - offset) {
+    LOG(INFO) << "Invalid reply data range: offset=" << offset << ", length=" << length
+              << " reply_length=" << reply_length;
+    return false;
+  }
+
+  out_data->resize(length);
+  memcpy(out_data->data(), reply_data->GetData() + offset, length);
+
   return true;
 }
 
@@ -274,12 +264,14 @@
     /* try anyway? */
   }
 
+  // TODO: Can we really get here while not `Runnable`? If not, we do not need the `soa`.
+  ScopedObjectAccessUnchecked soa(self);
   JNIEnv* env = self->GetJniEnv();
   jint event = connect ? 1 /*DdmServer.CONNECTED*/ : 2 /*DdmServer.DISCONNECTED*/;
-  env->CallStaticVoidMethod(WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer,
-                            WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_broadcast,
-                            event);
-  if (env->ExceptionCheck()) {
+  ArtMethod* broadcast = WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_broadcast;
+  DCHECK(broadcast->GetDeclaringClass()->IsInitialized());
+  broadcast->InvokeStatic<'V', 'I'>(self, event);
+  if (self->IsExceptionPending()) {
     LOG(ERROR) << "DdmServer.broadcast " << event << " failed";
     env->ExceptionDescribe();
     env->ExceptionClear();
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 26f1802..781ee1a 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -88,8 +88,6 @@
 jclass WellKnownClasses::libcore_reflect_AnnotationFactory;
 jclass WellKnownClasses::libcore_reflect_AnnotationMember;
 jclass WellKnownClasses::libcore_util_EmptyArray;
-jclass WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk;
-jclass WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer;
 
 jmethodID WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath;
 jmethodID WellKnownClasses::dalvik_system_VMRuntime_runFinalization;
@@ -131,8 +129,8 @@
 jmethodID WellKnownClasses::java_util_function_Consumer_accept;
 jmethodID WellKnownClasses::libcore_reflect_AnnotationFactory_createAnnotation;
 jmethodID WellKnownClasses::libcore_reflect_AnnotationMember_init;
-jmethodID WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_broadcast;
-jmethodID WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_dispatch;
+ArtMethod* WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_broadcast;
+ArtMethod* WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_dispatch;
 
 ArtField* WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList;
 ArtField* WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;
@@ -258,7 +256,9 @@
     klass->DumpClass(os, mirror::Class::kDumpClassFullDetail);
     LOG(FATAL) << "Couldn't find " << (is_static ? "static" : "instance") << " method \""
                << name << "\" with signature \"" << signature << "\": " << os.str();
+    UNREACHABLE();
   }
+  DCHECK(method->GetDeclaringClass() == klass);
   return method;
 }
 
@@ -413,8 +413,6 @@
   libcore_reflect_AnnotationFactory = CacheClass(env, "libcore/reflect/AnnotationFactory");
   libcore_reflect_AnnotationMember = CacheClass(env, "libcore/reflect/AnnotationMember");
   libcore_util_EmptyArray = CacheClass(env, "libcore/util/EmptyArray");
-  org_apache_harmony_dalvik_ddmc_Chunk = CacheClass(env, "org/apache/harmony/dalvik/ddmc/Chunk");
-  org_apache_harmony_dalvik_ddmc_DdmServer = CacheClass(env, "org/apache/harmony/dalvik/ddmc/DdmServer");
 
   InitFieldsAndMethodsOnly(env);
 }
@@ -475,12 +473,14 @@
   java_util_function_Consumer_accept = CacheMethod(env, java_util_function_Consumer, false, "accept", "(Ljava/lang/Object;)V");
   libcore_reflect_AnnotationFactory_createAnnotation = CacheMethod(env, libcore_reflect_AnnotationFactory, true, "createAnnotation", "(Ljava/lang/Class;[Llibcore/reflect/AnnotationMember;)Ljava/lang/annotation/Annotation;");
   libcore_reflect_AnnotationMember_init = CacheMethod(env, libcore_reflect_AnnotationMember, false, "<init>", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V");
-  org_apache_harmony_dalvik_ddmc_DdmServer_broadcast = CacheMethod(env, org_apache_harmony_dalvik_ddmc_DdmServer, true, "broadcast", "(I)V");
-  org_apache_harmony_dalvik_ddmc_DdmServer_dispatch = CacheMethod(env, org_apache_harmony_dalvik_ddmc_DdmServer, true, "dispatch", "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;");
 
-  StackHandleScope<1u> hs(self);
+  StackHandleScope<3u> hs(self);
   Handle<mirror::Class> j_i_fd =
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/io/FileDescriptor;"));
+  Handle<mirror::Class> o_a_h_d_c =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Lorg/apache/harmony/dalvik/ddmc/Chunk;"));
+  Handle<mirror::Class> o_a_h_d_d_ds =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Lorg/apache/harmony/dalvik/ddmc/DdmServer;"));
 
   ScopedAssertNoThreadSuspension sants(__FUNCTION__);
   PointerSize pointer_size = class_linker->GetImagePointerSize();
@@ -492,6 +492,15 @@
   java_lang_Float_floatToRawIntBits =
       CacheMethod(j_l_Float, /*is_static=*/ true, "floatToRawIntBits", "(F)I", pointer_size);
 
+  org_apache_harmony_dalvik_ddmc_DdmServer_broadcast =
+      CacheMethod(o_a_h_d_d_ds.Get(), /*is_static=*/ true, "broadcast", "(I)V", pointer_size);
+  org_apache_harmony_dalvik_ddmc_DdmServer_dispatch =
+      CacheMethod(o_a_h_d_d_ds.Get(),
+                  /*is_static=*/ true,
+                  "dispatch",
+                  "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;",
+                  pointer_size);
+
   ObjPtr<mirror::Class> d_s_bdcl = soa.Decode<mirror::Class>(dalvik_system_BaseDexClassLoader);
   dalvik_system_BaseDexClassLoader_pathList = CacheField(
       d_s_bdcl, /*is_static=*/ false, "pathList", "Ldalvik/system/DexPathList;");
@@ -585,15 +594,14 @@
   libcore_util_EmptyArray_STACK_TRACE_ELEMENT = CacheField(
       l_u_ea, /*is_static=*/ true, "STACK_TRACE_ELEMENT", "[Ljava/lang/StackTraceElement;");
 
-  ObjPtr<mirror::Class> o_a_h_d_c = soa.Decode<mirror::Class>(org_apache_harmony_dalvik_ddmc_Chunk);
   org_apache_harmony_dalvik_ddmc_Chunk_data =
-      CacheField(o_a_h_d_c, /*is_static=*/ false, "data", "[B");
+      CacheField(o_a_h_d_c.Get(), /*is_static=*/ false, "data", "[B");
   org_apache_harmony_dalvik_ddmc_Chunk_length =
-      CacheField(o_a_h_d_c, /*is_static=*/ false, "length", "I");
+      CacheField(o_a_h_d_c.Get(), /*is_static=*/ false, "length", "I");
   org_apache_harmony_dalvik_ddmc_Chunk_offset =
-      CacheField(o_a_h_d_c, /*is_static=*/ false, "offset", "I");
+      CacheField(o_a_h_d_c.Get(), /*is_static=*/ false, "offset", "I");
   org_apache_harmony_dalvik_ddmc_Chunk_type =
-      CacheField(o_a_h_d_c, /*is_static=*/ false, "type", "I");
+      CacheField(o_a_h_d_c.Get(), /*is_static=*/ false, "type", "I");
 }
 
 void WellKnownClasses::LateInit(JNIEnv* env) {
@@ -668,8 +676,6 @@
   libcore_reflect_AnnotationFactory = nullptr;
   libcore_reflect_AnnotationMember = nullptr;
   libcore_util_EmptyArray = nullptr;
-  org_apache_harmony_dalvik_ddmc_Chunk = nullptr;
-  org_apache_harmony_dalvik_ddmc_DdmServer = nullptr;
 
   dalvik_system_BaseDexClassLoader_getLdLibraryPath = nullptr;
   dalvik_system_VMRuntime_runFinalization = nullptr;
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index 2373e56..a585147 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -100,8 +100,6 @@
   static jclass libcore_reflect_AnnotationFactory;
   static jclass libcore_reflect_AnnotationMember;
   static jclass libcore_util_EmptyArray;
-  static jclass org_apache_harmony_dalvik_ddmc_Chunk;
-  static jclass org_apache_harmony_dalvik_ddmc_DdmServer;
 
   static jmethodID dalvik_system_BaseDexClassLoader_getLdLibraryPath;
   static jmethodID dalvik_system_VMRuntime_runFinalization;
@@ -143,8 +141,8 @@
   static jmethodID java_util_function_Consumer_accept;
   static jmethodID libcore_reflect_AnnotationFactory_createAnnotation;
   static jmethodID libcore_reflect_AnnotationMember_init;
-  static jmethodID org_apache_harmony_dalvik_ddmc_DdmServer_broadcast;
-  static jmethodID org_apache_harmony_dalvik_ddmc_DdmServer_dispatch;
+  static ArtMethod* org_apache_harmony_dalvik_ddmc_DdmServer_broadcast;
+  static ArtMethod* org_apache_harmony_dalvik_ddmc_DdmServer_dispatch;
 
   static ArtField* dalvik_system_BaseDexClassLoader_pathList;
   static ArtField* dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;