Fix 003-omnibus-opcodes flaky failures with GSS GC.

Fix a moving GC bug in Class::SetStatus().

Bug: 19828874

Change-Id: I6bef49a7ce964e8a7e316f282aaf1b8544efe76d
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 0fb5c4a..67872d7 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -282,7 +282,7 @@
   CHECK(java_lang_Object.Get() != nullptr);
   // backfill Object as the super class of Class.
   java_lang_Class->SetSuperClass(java_lang_Object.Get());
-  java_lang_Object->SetStatus(mirror::Class::kStatusLoaded, self);
+  mirror::Class::SetStatus(java_lang_Object, mirror::Class::kStatusLoaded, self);
 
   // Object[] next to hold class roots.
   Handle<mirror::Class> object_array_class(hs.NewHandle(
@@ -311,14 +311,14 @@
       AllocClass(self, java_lang_Class.Get(), mirror::String::ClassSize())));
   mirror::String::SetClass(java_lang_String.Get());
   java_lang_String->SetObjectSize(mirror::String::InstanceSize());
-  java_lang_String->SetStatus(mirror::Class::kStatusResolved, self);
+  mirror::Class::SetStatus(java_lang_String, mirror::Class::kStatusResolved, self);
 
   // Setup Reference.
   Handle<mirror::Class> java_lang_ref_Reference(hs.NewHandle(
       AllocClass(self, java_lang_Class.Get(), mirror::Reference::ClassSize())));
   mirror::Reference::SetClass(java_lang_ref_Reference.Get());
   java_lang_ref_Reference->SetObjectSize(mirror::Reference::InstanceSize());
-  java_lang_ref_Reference->SetStatus(mirror::Class::kStatusResolved, self);
+  mirror::Class::SetStatus(java_lang_ref_Reference, mirror::Class::kStatusResolved, self);
 
   // Create storage for root classes, save away our work so far (requires descriptors).
   class_roots_ = GcRoot<mirror::ObjectArray<mirror::Class> >(
@@ -360,7 +360,7 @@
       AllocClass(self, java_lang_Class.Get(), mirror::DexCache::ClassSize())));
   SetClassRoot(kJavaLangDexCache, java_lang_DexCache.Get());
   java_lang_DexCache->SetObjectSize(mirror::DexCache::InstanceSize());
-  java_lang_DexCache->SetStatus(mirror::Class::kStatusResolved, self);
+  mirror::Class::SetStatus(java_lang_DexCache, mirror::Class::kStatusResolved, self);
 
   // Constructor, Field, Method, and AbstractMethod are necessary so
   // that FindClass can link members.
@@ -369,7 +369,7 @@
   CHECK(java_lang_reflect_ArtField.Get() != nullptr);
   java_lang_reflect_ArtField->SetObjectSize(mirror::ArtField::InstanceSize());
   SetClassRoot(kJavaLangReflectArtField, java_lang_reflect_ArtField.Get());
-  java_lang_reflect_ArtField->SetStatus(mirror::Class::kStatusResolved, self);
+  mirror::Class::SetStatus(java_lang_reflect_ArtField, mirror::Class::kStatusResolved, self);
   mirror::ArtField::SetClass(java_lang_reflect_ArtField.Get());
 
   Handle<mirror::Class> java_lang_reflect_ArtMethod(hs.NewHandle(
@@ -378,7 +378,7 @@
   size_t pointer_size = GetInstructionSetPointerSize(Runtime::Current()->GetInstructionSet());
   java_lang_reflect_ArtMethod->SetObjectSize(mirror::ArtMethod::InstanceSize(pointer_size));
   SetClassRoot(kJavaLangReflectArtMethod, java_lang_reflect_ArtMethod.Get());
-  java_lang_reflect_ArtMethod->SetStatus(mirror::Class::kStatusResolved, self);
+  mirror::Class::SetStatus(java_lang_reflect_ArtMethod, mirror::Class::kStatusResolved, self);
   mirror::ArtMethod::SetClass(java_lang_reflect_ArtMethod.Get());
 
   // Set up array classes for string, field, method
@@ -434,18 +434,18 @@
   }
 
   // Object, String and DexCache need to be rerun through FindSystemClass to finish init
-  java_lang_Object->SetStatus(mirror::Class::kStatusNotReady, self);
+  mirror::Class::SetStatus(java_lang_Object, mirror::Class::kStatusNotReady, self);
   mirror::Class* Object_class = FindSystemClass(self, "Ljava/lang/Object;");
   CHECK_EQ(java_lang_Object.Get(), Object_class);
   CHECK_EQ(java_lang_Object->GetObjectSize(), mirror::Object::InstanceSize());
-  java_lang_String->SetStatus(mirror::Class::kStatusNotReady, self);
+  mirror::Class::SetStatus(java_lang_String, mirror::Class::kStatusNotReady, self);
   mirror::Class* String_class = FindSystemClass(self, "Ljava/lang/String;");
   std::ostringstream os1, os2;
   java_lang_String->DumpClass(os1, mirror::Class::kDumpClassFullDetail);
   String_class->DumpClass(os2, mirror::Class::kDumpClassFullDetail);
   CHECK_EQ(java_lang_String.Get(), String_class) << os1.str() << "\n\n" << os2.str();
   CHECK_EQ(java_lang_String->GetObjectSize(), mirror::String::InstanceSize());
-  java_lang_DexCache->SetStatus(mirror::Class::kStatusNotReady, self);
+  mirror::Class::SetStatus(java_lang_DexCache, mirror::Class::kStatusNotReady, self);
   mirror::Class* DexCache_class = FindSystemClass(self, "Ljava/lang/DexCache;");
   CHECK_EQ(java_lang_String.Get(), String_class);
   CHECK_EQ(java_lang_DexCache.Get(), DexCache_class);
@@ -505,11 +505,11 @@
   mirror::Class* Class_class = FindSystemClass(self, "Ljava/lang/Class;");
   CHECK_EQ(java_lang_Class.Get(), Class_class);
 
-  java_lang_reflect_ArtMethod->SetStatus(mirror::Class::kStatusNotReady, self);
+  mirror::Class::SetStatus(java_lang_reflect_ArtMethod, mirror::Class::kStatusNotReady, self);
   mirror::Class* Art_method_class = FindSystemClass(self, "Ljava/lang/reflect/ArtMethod;");
   CHECK_EQ(java_lang_reflect_ArtMethod.Get(), Art_method_class);
 
-  java_lang_reflect_ArtField->SetStatus(mirror::Class::kStatusNotReady, self);
+  mirror::Class::SetStatus(java_lang_reflect_ArtField, mirror::Class::kStatusNotReady, self);
   mirror::Class* Art_field_class = FindSystemClass(self, "Ljava/lang/reflect/ArtField;");
   CHECK_EQ(java_lang_reflect_ArtField.Get(), Art_field_class);
 
@@ -533,7 +533,7 @@
 
   // java.lang.ref classes need to be specially flagged, but otherwise are normal classes
   // finish initializing Reference class
-  java_lang_ref_Reference->SetStatus(mirror::Class::kStatusNotReady, self);
+  mirror::Class::SetStatus(java_lang_ref_Reference, mirror::Class::kStatusNotReady, self);
   mirror::Class* Reference_class = FindSystemClass(self, "Ljava/lang/ref/Reference;");
   CHECK_EQ(java_lang_ref_Reference.Get(), Reference_class);
   CHECK_EQ(java_lang_ref_Reference->GetObjectSize(), mirror::Reference::InstanceSize());
@@ -1213,7 +1213,7 @@
     // Check for circular dependencies between classes.
     if (!h_class->IsResolved() && h_class->GetClinitThreadId() == self->GetTid()) {
       ThrowClassCircularityError(h_class.Get());
-      h_class->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(h_class, mirror::Class::kStatusError, self);
       return nullptr;
     }
     // Wait for the pending initialization to complete.
@@ -1489,7 +1489,7 @@
     // An exception occured during load, set status to erroneous while holding klass' lock in case
     // notification is necessary.
     if (!klass->IsErroneous()) {
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
     }
     return nullptr;
   }
@@ -1508,7 +1508,7 @@
   if (!LoadSuperAndInterfaces(klass, dex_file)) {
     // Loading failed.
     if (!klass->IsErroneous()) {
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
     }
     return nullptr;
   }
@@ -1522,7 +1522,7 @@
   if (!LinkClass(self, descriptor, klass, interfaces, &new_class)) {
     // Linking failed.
     if (!klass->IsErroneous()) {
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
     }
     return nullptr;
   }
@@ -1894,7 +1894,7 @@
   klass->SetAccessFlags(access_flags);
   klass->SetClassLoader(class_loader);
   DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
-  klass->SetStatus(mirror::Class::kStatusIdx, nullptr);
+  mirror::Class::SetStatus(klass, mirror::Class::kStatusIdx, nullptr);
 
   klass->SetDexClassDefIndex(dex_file.GetIndexForClassDef(dex_class_def));
   klass->SetDexTypeIndex(dex_class_def.class_idx_);
@@ -2223,14 +2223,14 @@
   StackHandleScope<1> hs(self);
   Handle<mirror::Class> h_class(hs.NewHandle(primitive_class));
   ObjectLock<mirror::Class> lock(self, h_class);
-  primitive_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
-  primitive_class->SetPrimitiveType(type);
-  primitive_class->SetStatus(mirror::Class::kStatusInitialized, self);
+  h_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
+  h_class->SetPrimitiveType(type);
+  mirror::Class::SetStatus(h_class, mirror::Class::kStatusInitialized, self);
   const char* descriptor = Primitive::Descriptor(type);
-  mirror::Class* existing = InsertClass(descriptor, primitive_class,
+  mirror::Class* existing = InsertClass(descriptor, h_class.Get(),
                                         ComputeModifiedUtf8Hash(descriptor));
   CHECK(existing == nullptr) << "InitPrimitiveClass(" << type << ") failed";
-  return primitive_class;
+  return h_class.Get();
 }
 
 // Create an array class (i.e. the class object for the array, not the
@@ -2336,13 +2336,13 @@
   new_class->SetVTable(java_lang_Object->GetVTable());
   new_class->SetPrimitiveType(Primitive::kPrimNot);
   new_class->SetClassLoader(component_type->GetClassLoader());
-  new_class->SetStatus(mirror::Class::kStatusLoaded, self);
+  mirror::Class::SetStatus(new_class, mirror::Class::kStatusLoaded, self);
   {
     StackHandleScope<mirror::Class::kImtSize> hs2(self,
                                                   Runtime::Current()->GetImtUnimplementedMethod());
     new_class->PopulateEmbeddedImtAndVTable(&hs2);
   }
-  new_class->SetStatus(mirror::Class::kStatusInitialized, self);
+  mirror::Class::SetStatus(new_class, mirror::Class::kStatusInitialized, self);
   // don't need to set new_class->SetObjectSize(..)
   // because Object::SizeOf delegates to Array::SizeOf
 
@@ -2672,17 +2672,17 @@
   }
 
   if (klass->GetStatus() == mirror::Class::kStatusResolved) {
-    klass->SetStatus(mirror::Class::kStatusVerifying, self);
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusVerifying, self);
   } else {
     CHECK_EQ(klass->GetStatus(), mirror::Class::kStatusRetryVerificationAtRuntime)
         << PrettyClass(klass.Get());
     CHECK(!Runtime::Current()->IsAotCompiler());
-    klass->SetStatus(mirror::Class::kStatusVerifyingAtRuntime, self);
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusVerifyingAtRuntime, self);
   }
 
   // Skip verification if disabled.
   if (!Runtime::Current()->IsVerificationEnabled()) {
-    klass->SetStatus(mirror::Class::kStatusVerified, self);
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
     EnsurePreverifiedMethods(klass);
     return;
   }
@@ -2715,7 +2715,7 @@
       if (Runtime::Current()->IsAotCompiler()) {
         Runtime::Current()->GetCompilerCallbacks()->ClassRejected(ref);
       }
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
       return;
     }
   }
@@ -2730,7 +2730,7 @@
         << klass->GetDexCache()->GetLocation()->ToModifiedUtf8();
     ThrowVerifyError(klass.Get(), "Rejecting class %s because it failed compile-time verification",
                      PrettyDescriptor(klass.Get()).c_str());
-    klass->SetStatus(mirror::Class::kStatusError, self);
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
     return;
   }
   verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure;
@@ -2753,10 +2753,10 @@
       // Even though there were no verifier failures we need to respect whether the super-class
       // was verified or requiring runtime reverification.
       if (super.Get() == nullptr || super->IsVerified()) {
-        klass->SetStatus(mirror::Class::kStatusVerified, self);
+        mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
       } else {
         CHECK_EQ(super->GetStatus(), mirror::Class::kStatusRetryVerificationAtRuntime);
-        klass->SetStatus(mirror::Class::kStatusRetryVerificationAtRuntime, self);
+        mirror::Class::SetStatus(klass, mirror::Class::kStatusRetryVerificationAtRuntime, self);
         // Pretend a soft failure occured so that we don't consider the class verified below.
         verifier_failure = verifier::MethodVerifier::kSoftFailure;
       }
@@ -2766,9 +2766,9 @@
       // failures at runtime will be handled by slow paths in the generated
       // code. Set status accordingly.
       if (Runtime::Current()->IsAotCompiler()) {
-        klass->SetStatus(mirror::Class::kStatusRetryVerificationAtRuntime, self);
+        mirror::Class::SetStatus(klass, mirror::Class::kStatusRetryVerificationAtRuntime, self);
       } else {
-        klass->SetStatus(mirror::Class::kStatusVerified, self);
+        mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
         // As this is a fake verified status, make sure the methods are _not_ marked preverified
         // later.
         klass->SetPreverified();
@@ -2780,7 +2780,7 @@
         << " because: " << error_msg;
     self->AssertNoPendingException();
     ThrowVerifyError(klass.Get(), "%s", error_msg.c_str());
-    klass->SetStatus(mirror::Class::kStatusError, self);
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
   }
   if (preverified || verifier_failure == verifier::MethodVerifier::kNoFailure) {
     // Class is verified so we don't need to do any access check on its methods.
@@ -2947,7 +2947,7 @@
   klass->SetName(soa.Decode<mirror::String*>(name));
   mirror::Class* proxy_class = GetClassRoot(kJavaLangReflectProxy);
   klass->SetDexCache(proxy_class->GetDexCache());
-  klass->SetStatus(mirror::Class::kStatusIdx, self);
+  mirror::Class::SetStatus(klass, mirror::Class::kStatusIdx, self);
 
   // Instance fields are inherited, but we add a couple of static fields...
   {
@@ -3022,7 +3022,7 @@
   }
 
   klass->SetSuperClass(proxy_class);  // The super class is java.lang.reflect.Proxy
-  klass->SetStatus(mirror::Class::kStatusLoaded, self);  // Now effectively in the loaded state.
+  mirror::Class::SetStatus(klass, mirror::Class::kStatusLoaded, self);  // Now effectively in the loaded state.
   self->AssertNoPendingException();
 
   std::string descriptor(GetDescriptorForProxy(klass.Get()));
@@ -3034,7 +3034,7 @@
     Handle<mirror::ObjectArray<mirror::Class> > h_interfaces(
         hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces)));
     if (!LinkClass(self, descriptor.c_str(), klass, h_interfaces, &new_class)) {
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
       return nullptr;
     }
   }
@@ -3053,7 +3053,7 @@
   {
     // Lock on klass is released. Lock new class object.
     ObjectLock<mirror::Class> initialization_lock(self, klass);
-    klass->SetStatus(mirror::Class::kStatusInitialized, self);
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusInitialized, self);
   }
 
   // sanity checks
@@ -3310,7 +3310,7 @@
     }
 
     if (!ValidateSuperClassDescriptors(klass)) {
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
       return false;
     }
     self->AllowThreadSuspension();
@@ -3320,7 +3320,7 @@
     // From here out other threads may observe that we're initializing and so changes of state
     // require the a notification.
     klass->SetClinitThreadId(self->GetTid());
-    klass->SetStatus(mirror::Class::kStatusInitializing, self);
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusInitializing, self);
 
     t0 = NanoTime();
   }
@@ -3345,7 +3345,7 @@
             << (self->GetException() != nullptr ? self->GetException()->Dump() : "");
         ObjectLock<mirror::Class> lock(self, klass);
         // Initialization failed because the super-class is erroneous.
-        klass->SetStatus(mirror::Class::kStatusError, self);
+        mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
         return false;
       }
     }
@@ -3410,7 +3410,7 @@
 
     if (self->IsExceptionPending()) {
       WrapExceptionInInitializer(klass);
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
       success = false;
     } else if (Runtime::Current()->IsTransactionAborted()) {
       // The exception thrown when the transaction aborted has been caught and cleared
@@ -3418,7 +3418,7 @@
       VLOG(compiler) << "Return from class initializer of " << PrettyDescriptor(klass.Get())
                      << " without exception while transaction was aborted: re-throw it now.";
       Runtime::Current()->ThrowInternalErrorForAbortedTransaction(self);
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
       success = false;
     } else {
       RuntimeStats* global_stats = Runtime::Current()->GetStats();
@@ -3428,7 +3428,7 @@
       global_stats->class_init_time_ns += (t1 - t0);
       thread_stats->class_init_time_ns += (t1 - t0);
       // Set the class as initialized except if failed to initialize static fields.
-      klass->SetStatus(mirror::Class::kStatusInitialized, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusInitialized, self);
       if (VLOG_IS_ON(class_linker)) {
         std::string temp;
         LOG(INFO) << "Initialized class " << klass->GetDescriptor(&temp) << " from " <<
@@ -3454,7 +3454,7 @@
     // we were not using WaitIgnoringInterrupts), bail out.
     if (self->IsExceptionPending()) {
       WrapExceptionInInitializer(klass);
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
       return false;
     }
     // Spurious wakeup? Go back to waiting.
@@ -3688,7 +3688,7 @@
 
     // This will notify waiters on klass that saw the not yet resolved
     // class in the class_table_ during EnsureResolved.
-    klass->SetStatus(mirror::Class::kStatusResolved, self);
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusResolved, self);
     *new_class = klass.Get();
   } else {
     CHECK(!klass->IsResolved());
@@ -3696,7 +3696,7 @@
     *new_class = klass->CopyOf(self, class_size, &imt_handle_scope);
     if (UNLIKELY(*new_class == nullptr)) {
       CHECK(self->IsExceptionPending());  // Expect an OOME.
-      klass->SetStatus(mirror::Class::kStatusError, self);
+      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
       return false;
     }
 
@@ -3713,12 +3713,12 @@
 
     // This will notify waiters on temp class that saw the not yet resolved class in the
     // class_table_ during EnsureResolved.
-    klass->SetStatus(mirror::Class::kStatusRetired, self);
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusRetired, self);
 
     CHECK_EQ(new_class_h->GetStatus(), mirror::Class::kStatusResolving);
     // This will notify waiters on new_class that saw the not yet resolved
     // class in the class_table_ during EnsureResolved.
-    new_class_h->SetStatus(mirror::Class::kStatusResolved, self);
+    mirror::Class::SetStatus(new_class_h, mirror::Class::kStatusResolved, self);
   }
   return true;
 }
@@ -3933,7 +3933,7 @@
     }
   }
   // Mark the class as loaded.
-  klass->SetStatus(mirror::Class::kStatusLoaded, nullptr);
+  mirror::Class::SetStatus(klass, mirror::Class::kStatusLoaded, nullptr);
   return true;
 }