Fixed ArtMethod::GetQuickFrameInfo() for proxy methods
If we call ArtMethod::GetQuickFrameInfo() on a proxy constructor when
instrumentation stubs are installed, the entry point returned by
Instrumentation::GetQuickCodeFor() would be a artQuickProxyInvokeHandler,
and not a regular quick oat code pointer. This patch adds special handling
for proxy constructors to always compute frame info from the regular quick
code entry point. (These entry points are never updated by instrumentation
for proxy methods.)
Change-Id: I8e51f5622b6d327037d5c968b07505b2bf4ac737
Signed-off-by: Daniel Mihalyi <daniel.mihalyi@mattakis.com>
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index 5c72e55..aa10a17 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -442,13 +442,27 @@
return QuickMethodFrameInfo(kStackAlignment, 0u, 0u);
}
Runtime* runtime = Runtime::Current();
- // For Proxy method we exclude direct method (there is only one direct method - constructor).
- // Direct method is cloned from original java.lang.reflect.Proxy class together with code
- // and as a result it is executed as usual quick compiled method without any stubs.
- // So the frame info should be returned as it is a quick method not a stub.
- if (UNLIKELY(IsAbstract()) || UNLIKELY(IsProxyMethod() && !IsDirect())) {
+
+ if (UNLIKELY(IsAbstract())) {
return runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs);
}
+
+ // For Proxy method we add special handling for the direct method case (there is only one
+ // direct method - constructor). Direct method is cloned from original
+ // java.lang.reflect.Proxy class together with code and as a result it is executed as usual
+ // quick compiled method without any stubs. So the frame info should be returned as it is a
+ // quick method not a stub. However, if instrumentation stubs are installed, the
+ // instrumentation->GetQuickCodeFor() returns the artQuickProxyInvokeHandler instead of an
+ // oat code pointer, thus we have to add a special case here.
+ if (UNLIKELY(IsProxyMethod())) {
+ if (IsDirect()) {
+ CHECK(IsConstructor());
+ return GetQuickFrameInfo(EntryPointToCodePointer(GetEntryPointFromQuickCompiledCode()));
+ } else {
+ return runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs);
+ }
+ }
+
if (UNLIKELY(IsRuntimeMethod())) {
return runtime->GetRuntimeMethodFrameInfo(this);
}