Make PopSirt inlinable, pass self to SirtRef.

Change-Id: Ieb91526b1cb1f8644ceb3c5b99649f658f43bbc1
diff --git a/src/class_linker.cc b/src/class_linker.cc
index fdcbf20..448ad6a 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -47,6 +47,7 @@
 #endif
 #include "ScopedLocalRef.h"
 #include "scoped_thread_state_change.h"
+#include "sirt_ref.h"
 #include "space.h"
 #include "space_bitmap.h"
 #include "stack_indirect_reference_table.h"
@@ -232,42 +233,43 @@
   CHECK(!init_done_);
 
   // java_lang_Class comes first, it's needed for AllocClass
+  Thread* self = Thread::Current();
   Heap* heap = Runtime::Current()->GetHeap();
-  SirtRef<Class> java_lang_Class(down_cast<Class*>(heap->AllocObject(NULL, sizeof(ClassClass))));
+  SirtRef<Class> java_lang_Class(self, down_cast<Class*>(heap->AllocObject(NULL, sizeof(ClassClass))));
   CHECK(java_lang_Class.get() != NULL);
   java_lang_Class->SetClass(java_lang_Class.get());
   java_lang_Class->SetClassSize(sizeof(ClassClass));
   // AllocClass(Class*) can now be used
 
   // Class[] is used for reflection support.
-  SirtRef<Class> class_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> class_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
   class_array_class->SetComponentType(java_lang_Class.get());
 
   // java_lang_Object comes next so that object_array_class can be created.
-  SirtRef<Class> java_lang_Object(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> java_lang_Object(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
   CHECK(java_lang_Object.get() != NULL);
   // backfill Object as the super class of Class.
   java_lang_Class->SetSuperClass(java_lang_Object.get());
   java_lang_Object->SetStatus(Class::kStatusLoaded);
 
   // Object[] next to hold class roots.
-  SirtRef<Class> object_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> object_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
   object_array_class->SetComponentType(java_lang_Object.get());
 
   // Object[][] needed for iftables.
-  SirtRef<Class> object_array_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> object_array_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
   object_array_array_class->SetComponentType(object_array_class.get());
 
   // Setup the char class to be used for char[].
-  SirtRef<Class> char_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> char_class(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
 
   // Setup the char[] class to be used for String.
-  SirtRef<Class> char_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> char_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
   char_array_class->SetComponentType(char_class.get());
   CharArray::SetArrayClass(char_array_class.get());
 
   // Setup String.
-  SirtRef<Class> java_lang_String(AllocClass(java_lang_Class.get(), sizeof(StringClass)));
+  SirtRef<Class> java_lang_String(self, AllocClass(java_lang_Class.get(), sizeof(StringClass)));
   String::SetClass(java_lang_String.get());
   java_lang_String->SetObjectSize(sizeof(String));
   java_lang_String->SetStatus(Class::kStatusResolved);
@@ -297,7 +299,7 @@
   array_iftable_ = AllocIfTable(2);
 
   // Create int array type for AllocDexCache (done in AppendToBootClassPath).
-  SirtRef<Class> int_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> int_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
   int_array_class->SetComponentType(GetClassRoot(kPrimitiveInt));
   IntArray::SetArrayClass(int_array_class.get());
   SetClassRoot(kIntArrayClass, int_array_class.get());
@@ -305,33 +307,33 @@
   // now that these are registered, we can use AllocClass() and AllocObjectArray
 
   // Setup DexCache. This can not be done later since AppendToBootClassPath calls AllocDexCache.
-  SirtRef<Class> java_lang_DexCache(AllocClass(java_lang_Class.get(), sizeof(DexCacheClass)));
+  SirtRef<Class> java_lang_DexCache(self, AllocClass(java_lang_Class.get(), sizeof(DexCacheClass)));
   SetClassRoot(kJavaLangDexCache, java_lang_DexCache.get());
   java_lang_DexCache->SetObjectSize(sizeof(DexCacheClass));
   java_lang_DexCache->SetStatus(Class::kStatusResolved);
 
   // Constructor, Field, Method, and AbstractMethod are necessary so that FindClass can link members.
-  SirtRef<Class> java_lang_reflect_Constructor(AllocClass(java_lang_Class.get(),
+  SirtRef<Class> java_lang_reflect_Constructor(self, AllocClass(java_lang_Class.get(),
                                                           sizeof(MethodClass)));
   CHECK(java_lang_reflect_Constructor.get() != NULL);
   java_lang_reflect_Constructor->SetObjectSize(sizeof(Constructor));
   SetClassRoot(kJavaLangReflectConstructor, java_lang_reflect_Constructor.get());
   java_lang_reflect_Constructor->SetStatus(Class::kStatusResolved);
 
-  SirtRef<Class> java_lang_reflect_Field(AllocClass(java_lang_Class.get(), sizeof(FieldClass)));
+  SirtRef<Class> java_lang_reflect_Field(self, AllocClass(java_lang_Class.get(), sizeof(FieldClass)));
   CHECK(java_lang_reflect_Field.get() != NULL);
   java_lang_reflect_Field->SetObjectSize(sizeof(Field));
   SetClassRoot(kJavaLangReflectField, java_lang_reflect_Field.get());
   java_lang_reflect_Field->SetStatus(Class::kStatusResolved);
   Field::SetClass(java_lang_reflect_Field.get());
 
-  SirtRef<Class> java_lang_reflect_Method(AllocClass(java_lang_Class.get(), sizeof(MethodClass)));
+  SirtRef<Class> java_lang_reflect_Method(self, AllocClass(java_lang_Class.get(), sizeof(MethodClass)));
   CHECK(java_lang_reflect_Method.get() != NULL);
   java_lang_reflect_Method->SetObjectSize(sizeof(Method));
   SetClassRoot(kJavaLangReflectMethod, java_lang_reflect_Method.get());
   java_lang_reflect_Method->SetStatus(Class::kStatusResolved);
 
-  SirtRef<Class> java_lang_reflect_AbstractMethod(AllocClass(java_lang_Class.get(),
+  SirtRef<Class> java_lang_reflect_AbstractMethod(self, AllocClass(java_lang_Class.get(),
                                                              sizeof(MethodClass)));
   CHECK(java_lang_reflect_AbstractMethod.get() != NULL);
   java_lang_reflect_AbstractMethod->SetObjectSize(sizeof(AbstractMethod));
@@ -340,15 +342,15 @@
   AbstractMethod::SetClasses(java_lang_reflect_Constructor.get(), java_lang_reflect_Method.get());
 
   // Set up array classes for string, field, method
-  SirtRef<Class> object_array_string(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> object_array_string(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
   object_array_string->SetComponentType(java_lang_String.get());
   SetClassRoot(kJavaLangStringArrayClass, object_array_string.get());
 
-  SirtRef<Class> object_array_field(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> object_array_field(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
   object_array_field->SetComponentType(java_lang_reflect_Field.get());
   SetClassRoot(kJavaLangReflectFieldArrayClass, object_array_field.get());
 
-  SirtRef<Class> object_array_abstract_method(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  SirtRef<Class> object_array_abstract_method(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
   object_array_abstract_method->SetComponentType(java_lang_reflect_AbstractMethod.get());
   SetClassRoot(kJavaLangReflectAbstractMethodArrayClass, object_array_abstract_method.get());
 
@@ -960,8 +962,9 @@
 
   CHECK_EQ(oat_file->GetOatHeader().GetDexFileCount(),
            static_cast<uint32_t>(dex_caches->GetLength()));
+  Thread* self = Thread::Current();
   for (int i = 0; i < dex_caches->GetLength(); i++) {
-    SirtRef<DexCache> dex_cache(dex_caches->Get(i));
+    SirtRef<DexCache> dex_cache(self, dex_caches->Get(i));
     const std::string& dex_file_location(dex_cache->GetLocation()->ToModifiedUtf8());
     const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file_location);
     const DexFile* dex_file = oat_dex_file->OpenDexFile();
@@ -1110,32 +1113,35 @@
 DexCache* ClassLinker::AllocDexCache(const DexFile& dex_file) {
   Heap* heap = Runtime::Current()->GetHeap();
   Class* dex_cache_class = GetClassRoot(kJavaLangDexCache);
+  Thread* self = Thread::Current();
   SirtRef<DexCache> dex_cache(
+      self,
       down_cast<DexCache*>(heap->AllocObject(dex_cache_class, dex_cache_class->GetObjectSize())));
   if (dex_cache.get() == NULL) {
     return NULL;
   }
-  SirtRef<String> location(intern_table_->InternStrong(dex_file.GetLocation().c_str()));
+  SirtRef<String> location(self, intern_table_->InternStrong(dex_file.GetLocation().c_str()));
   if (location.get() == NULL) {
     return NULL;
   }
-  SirtRef<ObjectArray<String> > strings(AllocStringArray(dex_file.NumStringIds()));
+  SirtRef<ObjectArray<String> > strings(self, AllocStringArray(dex_file.NumStringIds()));
   if (strings.get() == NULL) {
     return NULL;
   }
-  SirtRef<ObjectArray<Class> > types(AllocClassArray(dex_file.NumTypeIds()));
+  SirtRef<ObjectArray<Class> > types(self, AllocClassArray(dex_file.NumTypeIds()));
   if (types.get() == NULL) {
     return NULL;
   }
-  SirtRef<ObjectArray<AbstractMethod> > methods(AllocMethodArray(dex_file.NumMethodIds()));
+  SirtRef<ObjectArray<AbstractMethod> > methods(self, AllocMethodArray(dex_file.NumMethodIds()));
   if (methods.get() == NULL) {
     return NULL;
   }
-  SirtRef<ObjectArray<Field> > fields(AllocFieldArray(dex_file.NumFieldIds()));
+  SirtRef<ObjectArray<Field> > fields(self, AllocFieldArray(dex_file.NumFieldIds()));
   if (fields.get() == NULL) {
     return NULL;
   }
-  SirtRef<ObjectArray<StaticStorageBase> > initialized_static_storage(AllocObjectArray<StaticStorageBase>(dex_file.NumTypeIds()));
+  SirtRef<ObjectArray<StaticStorageBase> >
+      initialized_static_storage(self, AllocObjectArray<StaticStorageBase>(dex_file.NumTypeIds()));
   if (initialized_static_storage.get() == NULL) {
     return NULL;
   }
@@ -1152,8 +1158,9 @@
 
 InterfaceEntry* ClassLinker::AllocInterfaceEntry(Class* interface) {
   DCHECK(interface->IsInterface());
-  SirtRef<ObjectArray<Object> > array(AllocObjectArray<Object>(InterfaceEntry::LengthAsArray()));
-  SirtRef<InterfaceEntry> interface_entry(down_cast<InterfaceEntry*>(array.get()));
+  Thread* self = Thread::Current();
+  SirtRef<ObjectArray<Object> > array(self, AllocObjectArray<Object>(InterfaceEntry::LengthAsArray()));
+  SirtRef<InterfaceEntry> interface_entry(self, down_cast<InterfaceEntry*>(array.get()));
   interface_entry->SetInterface(interface);
   return interface_entry.get();
 }
@@ -1161,7 +1168,8 @@
 Class* ClassLinker::AllocClass(Class* java_lang_Class, size_t class_size) {
   DCHECK_GE(class_size, sizeof(Class));
   Heap* heap = Runtime::Current()->GetHeap();
-  SirtRef<Class> klass(heap->AllocObject(java_lang_Class, class_size)->AsClass());
+  SirtRef<Class> klass(Thread::Current(),
+                       heap->AllocObject(java_lang_Class, class_size)->AsClass());
   klass->SetPrimitiveType(Primitive::kPrimNot);  // default to not being primitive
   klass->SetClassSize(class_size);
   return klass.get();
@@ -1195,7 +1203,7 @@
   // Wait for the class if it has not already been linked.
   Thread* self = Thread::Current();
   if (!klass->IsResolved() && !klass->IsErroneous()) {
-    ObjectLock lock(klass);
+    ObjectLock lock(self, klass);
     // Check for circular dependencies between classes.
     if (!klass->IsResolved() && klass->GetClinitThreadId() == self->GetTid()) {
       self->ThrowNewException("Ljava/lang/ClassCircularityError;",
@@ -1311,7 +1319,8 @@
                                 ClassLoader* class_loader,
                                 const DexFile& dex_file,
                                 const DexFile::ClassDef& dex_class_def) {
-  SirtRef<Class> klass(NULL);
+  Thread* self = Thread::Current();
+  SirtRef<Class> klass(self, NULL);
   // Load the class from the dex file.
   if (!init_done_) {
     // finish up init of hand crafted class_roots_
@@ -1340,15 +1349,14 @@
   klass->SetDexCache(FindDexCache(dex_file));
   LoadClass(dex_file, dex_class_def, klass, class_loader);
   // Check for a pending exception during load
-  Thread* self = Thread::Current();
   if (self->IsExceptionPending()) {
     klass->SetStatus(Class::kStatusError);
     return NULL;
   }
-  ObjectLock lock(klass.get());
+  ObjectLock lock(self, klass.get());
   klass->SetClinitThreadId(self->GetTid());
   // Add the newly loaded class to the loaded classes table.
-  SirtRef<Class> existing(InsertClass(descriptor, klass.get(), false));
+  SirtRef<Class> existing(self, InsertClass(descriptor, klass.get(), false));
   if (existing.get() != NULL) {
     // We failed to insert because we raced with another thread.
     return EnsureResolved(existing.get());
@@ -1586,13 +1594,14 @@
   if (it.NumInstanceFields() != 0) {
     klass->SetIFields(AllocObjectArray<Field>(it.NumInstanceFields()));
   }
+  Thread* self = Thread::Current();
   for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) {
-    SirtRef<Field> sfield(AllocField());
+    SirtRef<Field> sfield(self, AllocField());
     klass->SetStaticField(i, sfield.get());
     LoadField(dex_file, it, klass, sfield);
   }
   for (size_t i = 0; it.HasNextInstanceField(); i++, it.Next()) {
-    SirtRef<Field> ifield(AllocField());
+    SirtRef<Field> ifield(self, AllocField());
     klass->SetInstanceField(i, ifield.get());
     LoadField(dex_file, it, klass, ifield);
   }
@@ -1613,7 +1622,7 @@
   }
   size_t class_def_method_index = 0;
   for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) {
-    SirtRef<AbstractMethod> method(LoadMethod(dex_file, it, klass));
+    SirtRef<AbstractMethod> method(self, LoadMethod(dex_file, it, klass));
     klass->SetDirectMethod(i, method.get());
     if (oat_class.get() != NULL) {
       LinkCode(method, oat_class.get(), class_def_method_index);
@@ -1622,7 +1631,7 @@
     class_def_method_index++;
   }
   for (size_t i = 0; it.HasNextVirtualMethod(); i++, it.Next()) {
-    SirtRef<AbstractMethod> method(LoadMethod(dex_file, it, klass));
+    SirtRef<AbstractMethod> method(self, LoadMethod(dex_file, it, klass));
     klass->SetVirtualMethod(i, method.get());
     DCHECK_EQ(class_def_method_index, it.NumDirectMethods() + i);
     if (oat_class.get() != NULL) {
@@ -1704,7 +1713,7 @@
 }
 
 void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) {
-  SirtRef<DexCache> dex_cache(AllocDexCache(dex_file));
+  SirtRef<DexCache> dex_cache(Thread::Current(), AllocDexCache(dex_file));
   AppendToBootClassPath(dex_file, dex_cache);
 }
 
@@ -1738,8 +1747,9 @@
 }
 
 void ClassLinker::RegisterDexFile(const DexFile& dex_file) {
+  Thread* self = Thread::Current();
   {
-    MutexLock mu(dex_lock_);
+    MutexLock mu(self, dex_lock_);
     if (IsDexFileRegisteredLocked(dex_file)) {
       return;
     }
@@ -1747,9 +1757,9 @@
   // Don't alloc while holding the lock, since allocation may need to
   // suspend all threads and another thread may need the dex_lock_ to
   // get to a suspend point.
-  SirtRef<DexCache> dex_cache(AllocDexCache(dex_file));
+  SirtRef<DexCache> dex_cache(self, AllocDexCache(dex_file));
   {
-    MutexLock mu(dex_lock_);
+    MutexLock mu(self, dex_lock_);
     if (IsDexFileRegisteredLocked(dex_file)) {
       return;
     }
@@ -1793,7 +1803,8 @@
 
 Class* ClassLinker::InitializePrimitiveClass(Class* primitive_class, Primitive::Type type) {
   CHECK(primitive_class != NULL);
-  ObjectLock lock(primitive_class);  // Must hold lock on object when initializing.
+  // Must hold lock on object when initializing.
+  ObjectLock lock(Thread::Current(), primitive_class);
   primitive_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
   primitive_class->SetPrimitiveType(type);
   primitive_class->SetStatus(Class::kStatusInitialized);
@@ -1857,8 +1868,8 @@
   //
   // Array classes are simple enough that we don't need to do a full
   // link step.
-
-  SirtRef<Class> new_class(NULL);
+  Thread* self = Thread::Current();
+  SirtRef<Class> new_class(self, NULL);
   if (!init_done_) {
     // Classes that were hand created, ie not by FindSystemClass
     if (descriptor == "[Ljava/lang/Class;") {
@@ -1886,7 +1897,7 @@
     }
     new_class->SetComponentType(component_type);
   }
-  ObjectLock lock(new_class.get());  // Must hold lock on object when initializing.
+  ObjectLock lock(self, new_class.get());  // Must hold lock on object when initializing.
   DCHECK(new_class->GetComponentType() != NULL);
   Class* java_lang_Object = GetClassRoot(kJavaLangObject);
   new_class->SetSuperClass(java_lang_Object);
@@ -2074,7 +2085,8 @@
 
 void ClassLinker::VerifyClass(Class* klass) {
   // TODO: assert that the monitor on the Class is held
-  ObjectLock lock(klass);
+  Thread* self = Thread::Current();
+  ObjectLock lock(self, klass);
 
   // Don't attempt to re-verify if already sufficiently verified.
   if (klass->IsVerified() ||
@@ -2102,7 +2114,7 @@
   std::string error_msg;
   if (super != NULL) {
     // Acquire lock to prevent races on verifying the super class.
-    ObjectLock lock(super);
+    ObjectLock lock(self, super);
 
     if (!super->IsVerified() && !super->IsErroneous()) {
       Runtime::Current()->GetClassLinker()->VerifyClass(super);
@@ -2113,8 +2125,7 @@
       error_msg += " that attempts to sub-class erroneous class ";
       error_msg += PrettyDescriptor(super);
       LOG(ERROR) << error_msg  << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8();
-      Thread* self = Thread::Current();
-      SirtRef<Throwable> cause(self->GetException());
+      SirtRef<Throwable> cause(self, self->GetException());
       if (cause.get() != NULL) {
         self->ClearException();
       }
@@ -2151,7 +2162,7 @@
           << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8()
           << " because: " << error_msg;
     }
-    Thread::Current()->AssertNoPendingException();
+    self->AssertNoPendingException();
     // Make sure all classes referenced by catch blocks are resolved.
     ResolveClassExceptionHandlerTypes(dex_file, klass);
     if (verifier_failure == verifier::MethodVerifier::kNoFailure) {
@@ -2171,7 +2182,6 @@
     LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(klass)
         << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8()
         << " because: " << error_msg;
-    Thread* self = Thread::Current();
     self->AssertNoPendingException();
     self->ThrowNewException("Ljava/lang/VerifyError;", error_msg.c_str());
     klass->SetStatus(Class::kStatusError);
@@ -2284,7 +2294,8 @@
 Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interfaces,
                                      ClassLoader* loader, ObjectArray<AbstractMethod>* methods,
                                      ObjectArray<ObjectArray<Class> >* throws) {
-  SirtRef<Class> klass(AllocClass(GetClassRoot(kJavaLangClass), sizeof(SynthesizedProxyClass)));
+  Thread* self = Thread::Current();
+  SirtRef<Class> klass(self, AllocClass(GetClassRoot(kJavaLangClass), sizeof(SynthesizedProxyClass)));
   CHECK(klass.get() != NULL);
   DCHECK(klass->GetClass() != NULL);
   klass->SetObjectSize(sizeof(Proxy));
@@ -2303,13 +2314,13 @@
   klass->SetSFields(AllocObjectArray<Field>(2));
   // 1. Create a static field 'interfaces' that holds the _declared_ interfaces implemented by
   // our proxy, so Class.getInterfaces doesn't return the flattened set.
-  SirtRef<Field> interfaces_sfield(AllocField());
+  SirtRef<Field> interfaces_sfield(self, AllocField());
   klass->SetStaticField(0, interfaces_sfield.get());
   interfaces_sfield->SetDexFieldIndex(0);
   interfaces_sfield->SetDeclaringClass(klass.get());
   interfaces_sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
   // 2. Create a static field 'throws' that holds exceptions thrown by our methods.
-  SirtRef<Field> throws_sfield(AllocField());
+  SirtRef<Field> throws_sfield(self, AllocField());
   klass->SetStaticField(1, throws_sfield.get());
   throws_sfield->SetDexFieldIndex(1);
   throws_sfield->SetDeclaringClass(klass.get());
@@ -2323,7 +2334,7 @@
   size_t num_virtual_methods = methods->GetLength();
   klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(num_virtual_methods));
   for (size_t i = 0; i < num_virtual_methods; ++i) {
-    SirtRef<AbstractMethod> prototype(methods->Get(i));
+    SirtRef<AbstractMethod> prototype(self, methods->Get(i));
     klass->SetVirtualMethod(i, CreateProxyMethod(klass, prototype));
   }
 
@@ -2337,7 +2348,7 @@
     return NULL;
   }
   {
-    ObjectLock lock(klass.get());  // Must hold lock on object when initializing.
+    ObjectLock lock(self, klass.get());  // Must hold lock on object when initializing.
     interfaces_sfield->SetObject(NULL, interfaces);
     throws_sfield->SetObject(NULL, throws);
     klass->SetStatus(Class::kStatusInitialized);
@@ -2348,7 +2359,7 @@
     CHECK(klass->GetIFields() == NULL);
     CheckProxyConstructor(klass->GetDirectMethod(0));
     for (size_t i = 0; i < num_virtual_methods; ++i) {
-      SirtRef<AbstractMethod> prototype(methods->Get(i));
+      SirtRef<AbstractMethod> prototype(self, methods->Get(i));
       CheckProxyMethod(klass->GetVirtualMethod(i), prototype);
     }
 
@@ -2483,7 +2494,7 @@
   AbstractMethod* clinit = NULL;
   {
     // see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol
-    ObjectLock lock(klass);
+    ObjectLock lock(self, klass);
 
     if (klass->GetStatus() == Class::kStatusInitialized) {
       return true;
@@ -2555,7 +2566,7 @@
       CHECK(klass->IsErroneous());
     }
     // Signal to any waiting threads that saw this class as initializing.
-    ObjectLock lock(klass);
+    ObjectLock lock(self, klass);
     lock.NotifyAll();
     return false;
   }
@@ -2572,7 +2583,7 @@
 
   bool success = true;
   {
-    ObjectLock lock(klass);
+    ObjectLock lock(self, klass);
 
     if (self->IsExceptionPending()) {
       WrapExceptionInInitializer();
@@ -2739,7 +2750,8 @@
     Class* super_class = klass->GetSuperClass();
     if (!super_class->IsInitialized()) {
       CHECK(!super_class->IsInterface());
-      ObjectLock lock(klass);  // Must hold lock on object when initializing and setting status.
+      // Must hold lock on object when initializing and setting status.
+      ObjectLock lock(Thread::Current(), klass);
       bool super_initialized = InitializeClass(super_class, can_run_clinit, can_init_fields);
       // TODO: check for a pending exception
       if (!super_initialized) {
@@ -2961,12 +2973,14 @@
 }
 
 bool ClassLinker::LinkVirtualMethods(SirtRef<Class>& klass) {
+  Thread* self = Thread::Current();
   if (klass->HasSuperClass()) {
     uint32_t max_count = klass->NumVirtualMethods() + klass->GetSuperClass()->GetVTable()->GetLength();
     size_t actual_count = klass->GetSuperClass()->GetVTable()->GetLength();
     CHECK_LE(actual_count, max_count);
     // TODO: do not assign to the vtable field until it is fully constructed.
-    SirtRef<ObjectArray<AbstractMethod> > vtable(klass->GetSuperClass()->GetVTable()->CopyOf(max_count));
+    SirtRef<ObjectArray<AbstractMethod> >
+        vtable(self, klass->GetSuperClass()->GetVTable()->CopyOf(max_count));
     // See if any of our virtual methods override the superclass.
     MethodHelper local_mh(NULL, this);
     MethodHelper super_mh(NULL, this);
@@ -3019,7 +3033,8 @@
       ThrowClassFormatError("Too many methods: %d", num_virtual_methods);
       return false;
     }
-    SirtRef<ObjectArray<AbstractMethod> > vtable(AllocObjectArray<AbstractMethod>(num_virtual_methods));
+    SirtRef<ObjectArray<AbstractMethod> >
+        vtable(self, AllocObjectArray<AbstractMethod>(num_virtual_methods));
     for (size_t i = 0; i < num_virtual_methods; ++i) {
       AbstractMethod* virtual_method = klass->GetVirtualMethodDuringLinking(i);
       vtable->Set(i, virtual_method);
@@ -3051,7 +3066,8 @@
     // DCHECK(klass->GetIfTable() == NULL);
     return true;
   }
-  SirtRef<ObjectArray<InterfaceEntry> > iftable(AllocIfTable(ifcount));
+  Thread* self = Thread::Current();
+  SirtRef<ObjectArray<InterfaceEntry> > iftable(self, AllocIfTable(ifcount));
   if (super_ifcount != 0) {
     ObjectArray<InterfaceEntry>* super_iftable = klass->GetSuperClass()->GetIfTable();
     for (size_t i = 0; i < super_ifcount; i++) {
@@ -3066,7 +3082,6 @@
     DCHECK(interface != NULL);
     if (!interface->IsInterface()) {
       ClassHelper ih(interface);
-      Thread* self = Thread::Current();
       self->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
           "Class %s implements non-interface class %s",
           PrettyDescriptor(klass.get()).c_str(),
@@ -3150,7 +3165,7 @@
         }
       }
       if (k < 0) {
-        SirtRef<AbstractMethod> miranda_method(NULL);
+        SirtRef<AbstractMethod> miranda_method(self, NULL);
         for (size_t mir = 0; mir < miranda_list.size(); mir++) {
           AbstractMethod* mir_method = miranda_list[mir];
           vtable_mh.ChangeMethod(mir_method);
@@ -3175,7 +3190,7 @@
                              ? AllocObjectArray<AbstractMethod>(new_method_count)
                              : klass->GetVirtualMethods()->CopyOf(new_method_count));
 
-    SirtRef<ObjectArray<AbstractMethod> > vtable(klass->GetVTableDuringLinking());
+    SirtRef<ObjectArray<AbstractMethod> > vtable(self, klass->GetVTableDuringLinking());
     CHECK(vtable.get() != NULL);
     int old_vtable_count = vtable->GetLength();
     int new_vtable_count = old_vtable_count + miranda_list.size();