Add Handle::GetFromGdb function
When using a debugger it is normally quite difficult to examine
mirror objects being held by Handles due to the inlining of the
various accessor functions. This adds a new 'GetFromGdb' function that
is emitted normally to allow one to decode the handle from gdb. This
function is defined for every Handle type using a macro.
Test: Manual debugging
Change-Id: I7cb95468b1a14438df4dccdf84b48e2af5ec71b9
diff --git a/runtime/Android.bp b/runtime/Android.bp
index a4e9984..e8bfa34 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -120,6 +120,7 @@
"gc/space/zygote_space.cc",
"gc/task_processor.cc",
"gc/verification.cc",
+ "handle.cc",
"hidden_api.cc",
"hprof/hprof.cc",
"image.cc",
diff --git a/runtime/class_root.h b/runtime/class_root.h
index 1ff4845..835ec90 100644
--- a/runtime/class_root.h
+++ b/runtime/class_root.h
@@ -52,37 +52,50 @@
class VarHandle;
} // namespace mirror
-#define CLASS_ROOT_LIST(M) \
- M(kJavaLangClass, "Ljava/lang/Class;", mirror::Class) \
- M(kJavaLangObject, "Ljava/lang/Object;", mirror::Object) \
- M(kClassArrayClass, "[Ljava/lang/Class;", mirror::ObjectArray<mirror::Class>) \
- M(kObjectArrayClass, "[Ljava/lang/Object;", mirror::ObjectArray<mirror::Object>) \
- M(kJavaLangString, "Ljava/lang/String;", mirror::String) \
- M(kJavaLangDexCache, "Ljava/lang/DexCache;", mirror::DexCache) \
- M(kJavaLangRefReference, "Ljava/lang/ref/Reference;", mirror::Reference) \
- M(kJavaLangReflectConstructor, "Ljava/lang/reflect/Constructor;", mirror::Constructor) \
- M(kJavaLangReflectField, "Ljava/lang/reflect/Field;", mirror::Field) \
- M(kJavaLangReflectMethod, "Ljava/lang/reflect/Method;", mirror::Method) \
- M(kJavaLangReflectProxy, "Ljava/lang/reflect/Proxy;", mirror::Proxy) \
- M(kJavaLangStringArrayClass, "[Ljava/lang/String;", mirror::ObjectArray<mirror::String>) \
- M(kJavaLangReflectConstructorArrayClass, "[Ljava/lang/reflect/Constructor;", mirror::ObjectArray<mirror::Constructor>) \
- M(kJavaLangReflectFieldArrayClass, "[Ljava/lang/reflect/Field;", mirror::ObjectArray<mirror::Field>) \
- M(kJavaLangReflectMethodArrayClass, "[Ljava/lang/reflect/Method;", mirror::ObjectArray<mirror::Method>) \
- M(kJavaLangInvokeCallSite, "Ljava/lang/invoke/CallSite;", mirror::CallSite) \
- M(kJavaLangInvokeMethodHandle, "Ljava/lang/invoke/MethodHandle;", mirror::MethodHandle) \
- M(kJavaLangInvokeMethodHandleImpl, "Ljava/lang/invoke/MethodHandleImpl;", mirror::MethodHandleImpl) \
- M(kJavaLangInvokeMethodHandlesLookup, "Ljava/lang/invoke/MethodHandles$Lookup;", mirror::MethodHandlesLookup) \
- M(kJavaLangInvokeMethodType, "Ljava/lang/invoke/MethodType;", mirror::MethodType) \
- M(kJavaLangInvokeVarHandle, "Ljava/lang/invoke/VarHandle;", mirror::VarHandle) \
- M(kJavaLangInvokeFieldVarHandle, "Ljava/lang/invoke/FieldVarHandle;", mirror::FieldVarHandle) \
- M(kJavaLangInvokeArrayElementVarHandle, "Ljava/lang/invoke/ArrayElementVarHandle;", mirror::ArrayElementVarHandle) \
- M(kJavaLangInvokeByteArrayViewVarHandle, "Ljava/lang/invoke/ByteArrayViewVarHandle;", mirror::ByteArrayViewVarHandle) \
- M(kJavaLangInvokeByteBufferViewVarHandle, "Ljava/lang/invoke/ByteBufferViewVarHandle;", mirror::ByteBufferViewVarHandle) \
- M(kJavaLangClassLoader, "Ljava/lang/ClassLoader;", mirror::ClassLoader) \
- M(kJavaLangThrowable, "Ljava/lang/Throwable;", mirror::Throwable) \
+#define CLASS_MIRROR_ROOT_LIST(M) \
+ M(kJavaLangClass, "Ljava/lang/Class;", mirror::Class) \
+ M(kJavaLangObject, "Ljava/lang/Object;", mirror::Object) \
+ M(kClassArrayClass, "[Ljava/lang/Class;", mirror::ObjectArray<mirror::Class>) \
+ M(kObjectArrayClass, "[Ljava/lang/Object;", mirror::ObjectArray<mirror::Object>) \
+ M(kJavaLangString, "Ljava/lang/String;", mirror::String) \
+ M(kJavaLangDexCache, "Ljava/lang/DexCache;", mirror::DexCache) \
+ M(kJavaLangRefReference, "Ljava/lang/ref/Reference;", mirror::Reference) \
+ M(kJavaLangReflectConstructor, "Ljava/lang/reflect/Constructor;", mirror::Constructor) \
+ M(kJavaLangReflectField, "Ljava/lang/reflect/Field;", mirror::Field) \
+ M(kJavaLangReflectMethod, "Ljava/lang/reflect/Method;", mirror::Method) \
+ M(kJavaLangReflectProxy, "Ljava/lang/reflect/Proxy;", mirror::Proxy) \
+ M(kJavaLangStringArrayClass, "[Ljava/lang/String;", mirror::ObjectArray<mirror::String>) \
+ M(kJavaLangReflectConstructorArrayClass, "[Ljava/lang/reflect/Constructor;", mirror::ObjectArray<mirror::Constructor>) \
+ M(kJavaLangReflectFieldArrayClass, "[Ljava/lang/reflect/Field;", mirror::ObjectArray<mirror::Field>) \
+ M(kJavaLangReflectMethodArrayClass, "[Ljava/lang/reflect/Method;", mirror::ObjectArray<mirror::Method>) \
+ M(kJavaLangInvokeCallSite, "Ljava/lang/invoke/CallSite;", mirror::CallSite) \
+ M(kJavaLangInvokeMethodHandle, "Ljava/lang/invoke/MethodHandle;", mirror::MethodHandle) \
+ M(kJavaLangInvokeMethodHandleImpl, "Ljava/lang/invoke/MethodHandleImpl;", mirror::MethodHandleImpl) \
+ M(kJavaLangInvokeMethodHandlesLookup, "Ljava/lang/invoke/MethodHandles$Lookup;", mirror::MethodHandlesLookup) \
+ M(kJavaLangInvokeMethodType, "Ljava/lang/invoke/MethodType;", mirror::MethodType) \
+ M(kJavaLangInvokeVarHandle, "Ljava/lang/invoke/VarHandle;", mirror::VarHandle) \
+ M(kJavaLangInvokeFieldVarHandle, "Ljava/lang/invoke/FieldVarHandle;", mirror::FieldVarHandle) \
+ M(kJavaLangInvokeArrayElementVarHandle, "Ljava/lang/invoke/ArrayElementVarHandle;", mirror::ArrayElementVarHandle) \
+ M(kJavaLangInvokeByteArrayViewVarHandle, "Ljava/lang/invoke/ByteArrayViewVarHandle;", mirror::ByteArrayViewVarHandle) \
+ M(kJavaLangInvokeByteBufferViewVarHandle, "Ljava/lang/invoke/ByteBufferViewVarHandle;", mirror::ByteBufferViewVarHandle) \
+ M(kJavaLangClassLoader, "Ljava/lang/ClassLoader;", mirror::ClassLoader) \
+ M(kJavaLangThrowable, "Ljava/lang/Throwable;", mirror::Throwable) \
+ M(kJavaLangStackTraceElement, "Ljava/lang/StackTraceElement;", mirror::StackTraceElement) \
+ M(kDalvikSystemEmulatedStackFrame, "Ldalvik/system/EmulatedStackFrame;", mirror::EmulatedStackFrame) \
+ M(kBooleanArrayClass, "[Z", mirror::PrimitiveArray<uint8_t>) \
+ M(kByteArrayClass, "[B", mirror::PrimitiveArray<int8_t>) \
+ M(kCharArrayClass, "[C", mirror::PrimitiveArray<uint16_t>) \
+ M(kDoubleArrayClass, "[D", mirror::PrimitiveArray<double>) \
+ M(kFloatArrayClass, "[F", mirror::PrimitiveArray<float>) \
+ M(kIntArrayClass, "[I", mirror::PrimitiveArray<int32_t>) \
+ M(kLongArrayClass, "[J", mirror::PrimitiveArray<int64_t>) \
+ M(kShortArrayClass, "[S", mirror::PrimitiveArray<int16_t>) \
+ M(kJavaLangStackTraceElementArrayClass, "[Ljava/lang/StackTraceElement;", mirror::ObjectArray<mirror::StackTraceElement>) \
+ M(kJavaLangClassLoaderArrayClass, "[Ljava/lang/ClassLoader;", mirror::ObjectArray<mirror::ClassLoader>) \
+ M(kDalvikSystemClassExt, "Ldalvik/system/ClassExt;", mirror::ClassExt)
+
+#define CLASS_NO_MIRROR_ROOT_LIST(M) \
M(kJavaLangClassNotFoundException, "Ljava/lang/ClassNotFoundException;", detail::NoMirrorType<detail::ClassNotFoundExceptionTag>) \
- M(kJavaLangStackTraceElement, "Ljava/lang/StackTraceElement;", mirror::StackTraceElement) \
- M(kDalvikSystemEmulatedStackFrame, "Ldalvik/system/EmulatedStackFrame;", mirror::EmulatedStackFrame) \
M(kPrimitiveBoolean, "Z", detail::NoMirrorType<uint8_t>) \
M(kPrimitiveByte, "B", detail::NoMirrorType<int8_t>) \
M(kPrimitiveChar, "C", detail::NoMirrorType<uint16_t>) \
@@ -91,18 +104,11 @@
M(kPrimitiveInt, "I", detail::NoMirrorType<int32_t>) \
M(kPrimitiveLong, "J", detail::NoMirrorType<int64_t>) \
M(kPrimitiveShort, "S", detail::NoMirrorType<int16_t>) \
- M(kPrimitiveVoid, "V", detail::NoMirrorType<void>) \
- M(kBooleanArrayClass, "[Z", mirror::PrimitiveArray<uint8_t>) \
- M(kByteArrayClass, "[B", mirror::PrimitiveArray<int8_t>) \
- M(kCharArrayClass, "[C", mirror::PrimitiveArray<uint16_t>) \
- M(kDoubleArrayClass, "[D", mirror::PrimitiveArray<double>) \
- M(kFloatArrayClass, "[F", mirror::PrimitiveArray<float>) \
- M(kIntArrayClass, "[I", mirror::PrimitiveArray<int32_t>) \
- M(kLongArrayClass, "[J", mirror::PrimitiveArray<int64_t>) \
- M(kShortArrayClass, "[S", mirror::PrimitiveArray<int16_t>) \
- M(kJavaLangStackTraceElementArrayClass, "[Ljava/lang/StackTraceElement;", mirror::ObjectArray<mirror::StackTraceElement>) \
- M(kJavaLangClassLoaderArrayClass, "[Ljava/lang/ClassLoader;", mirror::ObjectArray<mirror::ClassLoader>) \
- M(kDalvikSystemClassExt, "Ldalvik/system/ClassExt;", mirror::ClassExt)
+ M(kPrimitiveVoid, "V", detail::NoMirrorType<void>)
+
+#define CLASS_ROOT_LIST(M) \
+ CLASS_MIRROR_ROOT_LIST(M) \
+ CLASS_NO_MIRROR_ROOT_LIST(M)
// Well known mirror::Class roots accessed via ClassLinker::GetClassRoots().
enum class ClassRoot : uint32_t {
diff --git a/runtime/handle.cc b/runtime/handle.cc
new file mode 100644
index 0000000..0028dee
--- /dev/null
+++ b/runtime/handle.cc
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "handle.h"
+
+#include "mirror/object.h"
+#include "mirror/accessible_object.h"
+#include "mirror/array.h"
+#include "mirror/call_site.h"
+#include "mirror/class.h"
+#include "mirror/class_ext.h"
+#include "mirror/dex_cache.h"
+#include "mirror/emulated_stack_frame.h"
+#include "mirror/executable.h"
+#include "mirror/field.h"
+#include "mirror/iftable.h"
+#include "mirror/method_handle_impl.h"
+#include "mirror/method_handles_lookup.h"
+#include "mirror/method_type.h"
+#include "mirror/method.h"
+#include "mirror/proxy.h"
+#include "mirror/reference.h"
+#include "mirror/stack_trace_element.h"
+#include "mirror/string.h"
+#include "mirror/throwable.h"
+#include "mirror/var_handle.h"
+
+#include "class_root.h"
+
+namespace art {
+
+#define MAKE_OBJECT_FOR_GDB(ROOT, NAME, MIRROR) \
+ template <> MIRROR* Handle<MIRROR>::GetFromGdb() { \
+ return Get(); \
+ } \
+ template <> mirror::Object* Handle<MIRROR>::ObjectFromGdb() { \
+ return static_cast<mirror::Object*>(Get()); \
+ }
+
+CLASS_MIRROR_ROOT_LIST(MAKE_OBJECT_FOR_GDB)
+
+#undef MAKE_OBJECT_FOR_GDB
+
+} // namespace art
diff --git a/runtime/handle.h b/runtime/handle.h
index 6de4e88..779345d 100644
--- a/runtime/handle.h
+++ b/runtime/handle.h
@@ -117,6 +117,9 @@
return IsNull();
}
+ mirror::Object* ObjectFromGdb() REQUIRES_SHARED(Locks::mutator_lock_);
+ T* GetFromGdb() REQUIRES_SHARED(Locks::mutator_lock_);
+
protected:
template<typename S>
explicit Handle(StackReference<S>* reference)