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;