Fix for potential moving GC bugs around proxy class.
- Handlerize proxy_class which is live across multiple allocation
points in ClassLinker::CreateProxyClass().
- In ClassLinker::CreateProxyClass(), insert a proxy class into the
class table before creating ArtFields for it (and update it later in
LinkClass()) because the field roots (ArtField::declaring_class_)
won't be updated by GC unless the class is in the class table. If GC
happens before they are updated by FixupTemporaryDeclaringClass()
from LinkClass(), FixupTemporaryDeclaringClass() may not update the
field roots correctly because the old class may already be moved but
the fields roots may not. Reduce a window of time where the fields
roots could be stale.
- In ClassLinker::LinkClass(), directly wrap a new class in a handle
to avoid a window of time where new_class may be potentially stale.
- Print more diagnostic info about the holder of the field upon a mark
sweep invalid ref crash.
- Add an additional sanity check in Field::GetArtField().
(cherry pick commit 08d1b5f2296c0f51507b8b443f4e39dfc161572c)
Bug: 20557050
Change-Id: I9ad32d304922da96b7e1fad262d97de21cbac776
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 95c8aa0..947e152 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -49,6 +49,7 @@
} // namespace mirror
template<class T> class Handle;
+template<class T> class MutableHandle;
class InternTable;
template<class T> class ObjectLock;
class Runtime;
@@ -572,7 +573,7 @@
bool LinkClass(Thread* self, const char* descriptor, Handle<mirror::Class> klass,
Handle<mirror::ObjectArray<mirror::Class>> interfaces,
- mirror::Class** new_class)
+ MutableHandle<mirror::Class>* h_new_class_out)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool LinkSuperClass(Handle<mirror::Class> klass)
@@ -622,8 +623,7 @@
// Returns the boot image oat file.
const OatFile* GetBootOatFile() SHARED_LOCKS_REQUIRED(dex_lock_);
- mirror::ArtMethod* CreateProxyConstructor(Thread* self, Handle<mirror::Class> klass,
- mirror::Class* proxy_class)
+ mirror::ArtMethod* CreateProxyConstructor(Thread* self, Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::ArtMethod* CreateProxyMethod(Thread* self, Handle<mirror::Class> klass,
Handle<mirror::ArtMethod> prototype)