Fix and optimize verify object.

VerifyObject no longer resides in heap. You can now enable
VerifyObject for non-debug builds. VerifyStack is still slow, so it
is now guarded by its own flag.

Fixed the image writer to not use verification at places where
verification fails due to invalid reads.

Fixed RosAlloc to use SizeOf which doesn't call verify object.

Added a flag paremeter to some of the mirror getters / setters to
be able to selectively disable VerifyObject on certain calls.

Optimized the GC to not verify each object multiple times during
object scanning if verify object is enabled.

Added 3 verification options: verify reads, verify this, and verify
writes so that you can select how much verification you want for
mirror getters and setters.

Removed some useless DCHECKs which would slow debug builds without
providing any benefits.

TODO: RosAlloc verification doesn't currently work with verify
objects.

Bug: 12934910
Bug: 12879358

Change-Id: Ic61033104dfc334543f89b0fc0ad8cd4f4015d69
diff --git a/runtime/gc/space/space_test.cc b/runtime/gc/space/space_test.cc
index 6d07a60..0b9f7ad 100644
--- a/runtime/gc/space/space_test.cc
+++ b/runtime/gc/space/space_test.cc
@@ -38,18 +38,20 @@
     Runtime::Current()->GetHeap()->RevokeAllThreadLocalBuffers();
     Runtime::Current()->GetHeap()->AddSpace(space);
   }
-  void InstallClass(mirror::Object* o, size_t size) NO_THREAD_SAFETY_ANALYSIS {
+  void InstallClass(SirtRef<mirror::Object>& o, size_t size)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     // Note the minimum size, which is the size of a zero-length byte array.
     EXPECT_GE(size, SizeOfZeroLengthByteArray());
-    SirtRef<mirror::ClassLoader> null_loader(Thread::Current(), NULL);
-    mirror::Class* byte_array_class = Runtime::Current()->GetClassLinker()->FindClass("[B", null_loader);
-    EXPECT_TRUE(byte_array_class != NULL);
+    SirtRef<mirror::ClassLoader> null_loader(Thread::Current(), nullptr);
+    mirror::Class* byte_array_class = Runtime::Current()->GetClassLinker()->FindClass("[B",
+                                                                                      null_loader);
+    EXPECT_TRUE(byte_array_class != nullptr);
     o->SetClass(byte_array_class);
-    mirror::Array* arr = o->AsArray();
+    mirror::Array* arr = o->AsArray<kVerifyNone>();
     size_t header_size = SizeOfZeroLengthByteArray();
     int32_t length = size - header_size;
     arr->SetLength(length);
-    EXPECT_EQ(arr->SizeOf(), size);
+    EXPECT_EQ(arr->SizeOf<kVerifyNone>(), size);
   }
 
   static size_t SizeOfZeroLengthByteArray() {
@@ -86,38 +88,38 @@
 void SpaceTest::InitTestBody(CreateSpaceFn create_space) {
   {
     // Init < max == growth
-    UniquePtr<Space> space(create_space("test", 16 * MB, 32 * MB, 32 * MB, NULL));
-    EXPECT_TRUE(space.get() != NULL);
+    UniquePtr<Space> space(create_space("test", 16 * MB, 32 * MB, 32 * MB, nullptr));
+    EXPECT_TRUE(space.get() != nullptr);
   }
   {
     // Init == max == growth
-    UniquePtr<Space> space(create_space("test", 16 * MB, 16 * MB, 16 * MB, NULL));
-    EXPECT_TRUE(space.get() != NULL);
+    UniquePtr<Space> space(create_space("test", 16 * MB, 16 * MB, 16 * MB, nullptr));
+    EXPECT_TRUE(space.get() != nullptr);
   }
   {
     // Init > max == growth
-    UniquePtr<Space> space(create_space("test", 32 * MB, 16 * MB, 16 * MB, NULL));
-    EXPECT_TRUE(space.get() == NULL);
+    UniquePtr<Space> space(create_space("test", 32 * MB, 16 * MB, 16 * MB, nullptr));
+    EXPECT_TRUE(space.get() == nullptr);
   }
   {
     // Growth == init < max
-    UniquePtr<Space> space(create_space("test", 16 * MB, 16 * MB, 32 * MB, NULL));
-    EXPECT_TRUE(space.get() != NULL);
+    UniquePtr<Space> space(create_space("test", 16 * MB, 16 * MB, 32 * MB, nullptr));
+    EXPECT_TRUE(space.get() != nullptr);
   }
   {
     // Growth < init < max
-    UniquePtr<Space> space(create_space("test", 16 * MB, 8 * MB, 32 * MB, NULL));
-    EXPECT_TRUE(space.get() == NULL);
+    UniquePtr<Space> space(create_space("test", 16 * MB, 8 * MB, 32 * MB, nullptr));
+    EXPECT_TRUE(space.get() == nullptr);
   }
   {
     // Init < growth < max
-    UniquePtr<Space> space(create_space("test", 8 * MB, 16 * MB, 32 * MB, NULL));
-    EXPECT_TRUE(space.get() != NULL);
+    UniquePtr<Space> space(create_space("test", 8 * MB, 16 * MB, 32 * MB, nullptr));
+    EXPECT_TRUE(space.get() != nullptr);
   }
   {
     // Init < max < growth
-    UniquePtr<Space> space(create_space("test", 8 * MB, 32 * MB, 16 * MB, NULL));
-    EXPECT_TRUE(space.get() == NULL);
+    UniquePtr<Space> space(create_space("test", 8 * MB, 32 * MB, 16 * MB, nullptr));
+    EXPECT_TRUE(space.get() == nullptr);
   }
 }
 
@@ -134,52 +136,52 @@
 // the GC works with the ZygoteSpace.
 void SpaceTest::ZygoteSpaceTestBody(CreateSpaceFn create_space) {
   size_t dummy = 0;
-  MallocSpace* space(create_space("test", 4 * MB, 16 * MB, 16 * MB, NULL));
-  ASSERT_TRUE(space != NULL);
+  MallocSpace* space(create_space("test", 4 * MB, 16 * MB, 16 * MB, nullptr));
+  ASSERT_TRUE(space != nullptr);
 
   // Make space findable to the heap, will also delete space when runtime is cleaned up
   AddSpace(space);
   Thread* self = Thread::Current();
+  ScopedObjectAccess soa(self);
 
   // Succeeds, fits without adjusting the footprint limit.
-  mirror::Object* ptr1 = space->Alloc(self, 1 * MB, &dummy);
-  EXPECT_TRUE(ptr1 != NULL);
+  SirtRef<mirror::Object> ptr1(self, space->Alloc(self, 1 * MB, &dummy));
+  EXPECT_TRUE(ptr1.get() != nullptr);
   InstallClass(ptr1, 1 * MB);
 
   // Fails, requires a higher footprint limit.
   mirror::Object* ptr2 = space->Alloc(self, 8 * MB, &dummy);
-  EXPECT_TRUE(ptr2 == NULL);
+  EXPECT_TRUE(ptr2 == nullptr);
 
   // Succeeds, adjusts the footprint.
   size_t ptr3_bytes_allocated;
-  mirror::Object* ptr3 = space->AllocWithGrowth(self, 8 * MB, &ptr3_bytes_allocated);
-  EXPECT_TRUE(ptr3 != NULL);
+  SirtRef<mirror::Object> ptr3(self, space->AllocWithGrowth(self, 8 * MB, &ptr3_bytes_allocated));
+  EXPECT_TRUE(ptr3.get() != nullptr);
   EXPECT_LE(8U * MB, ptr3_bytes_allocated);
   InstallClass(ptr3, 8 * MB);
 
   // Fails, requires a higher footprint limit.
   mirror::Object* ptr4 = space->Alloc(self, 8 * MB, &dummy);
-  EXPECT_TRUE(ptr4 == NULL);
+  EXPECT_TRUE(ptr4 == nullptr);
 
   // Also fails, requires a higher allowed footprint.
   mirror::Object* ptr5 = space->AllocWithGrowth(self, 8 * MB, &dummy);
-  EXPECT_TRUE(ptr5 == NULL);
+  EXPECT_TRUE(ptr5 == nullptr);
 
   // Release some memory.
-  ScopedObjectAccess soa(self);
-  size_t free3 = space->AllocationSize(ptr3);
+  size_t free3 = space->AllocationSize(ptr3.get());
   EXPECT_EQ(free3, ptr3_bytes_allocated);
-  EXPECT_EQ(free3, space->Free(self, ptr3));
+  EXPECT_EQ(free3, space->Free(self, ptr3.reset(nullptr)));
   EXPECT_LE(8U * MB, free3);
 
   // Succeeds, now that memory has been freed.
-  mirror::Object* ptr6 = space->AllocWithGrowth(self, 9 * MB, &dummy);
-  EXPECT_TRUE(ptr6 != NULL);
+  SirtRef<mirror::Object> ptr6(self, space->AllocWithGrowth(self, 9 * MB, &dummy));
+  EXPECT_TRUE(ptr6.get() != nullptr);
   InstallClass(ptr6, 9 * MB);
 
   // Final clean up.
-  size_t free1 = space->AllocationSize(ptr1);
-  space->Free(self, ptr1);
+  size_t free1 = space->AllocationSize(ptr1.get());
+  space->Free(self, ptr1.reset(nullptr));
   EXPECT_LE(1U * MB, free1);
 
   // Make sure that the zygote space isn't directly at the start of the space.
@@ -199,23 +201,23 @@
   AddSpace(space);
 
   // Succeeds, fits without adjusting the footprint limit.
-  ptr1 = space->Alloc(self, 1 * MB, &dummy);
-  EXPECT_TRUE(ptr1 != NULL);
+  ptr1.reset(space->Alloc(self, 1 * MB, &dummy));
+  EXPECT_TRUE(ptr1.get() != nullptr);
   InstallClass(ptr1, 1 * MB);
 
   // Fails, requires a higher footprint limit.
   ptr2 = space->Alloc(self, 8 * MB, &dummy);
-  EXPECT_TRUE(ptr2 == NULL);
+  EXPECT_TRUE(ptr2 == nullptr);
 
   // Succeeds, adjusts the footprint.
-  ptr3 = space->AllocWithGrowth(self, 2 * MB, &dummy);
-  EXPECT_TRUE(ptr3 != NULL);
+  ptr3.reset(space->AllocWithGrowth(self, 2 * MB, &dummy));
+  EXPECT_TRUE(ptr3.get() != nullptr);
   InstallClass(ptr3, 2 * MB);
-  space->Free(self, ptr3);
+  space->Free(self, ptr3.reset(nullptr));
 
   // Final clean up.
-  free1 = space->AllocationSize(ptr1);
-  space->Free(self, ptr1);
+  free1 = space->AllocationSize(ptr1.get());
+  space->Free(self, ptr1.reset(nullptr));
   EXPECT_LE(1U * MB, free1);
 }
 
@@ -229,52 +231,52 @@
 
 void SpaceTest::AllocAndFreeTestBody(CreateSpaceFn create_space) {
   size_t dummy = 0;
-  MallocSpace* space(create_space("test", 4 * MB, 16 * MB, 16 * MB, NULL));
-  ASSERT_TRUE(space != NULL);
+  MallocSpace* space(create_space("test", 4 * MB, 16 * MB, 16 * MB, nullptr));
+  ASSERT_TRUE(space != nullptr);
   Thread* self = Thread::Current();
+  ScopedObjectAccess soa(self);
 
   // Make space findable to the heap, will also delete space when runtime is cleaned up
   AddSpace(space);
 
   // Succeeds, fits without adjusting the footprint limit.
-  mirror::Object* ptr1 = space->Alloc(self, 1 * MB, &dummy);
-  EXPECT_TRUE(ptr1 != NULL);
+  SirtRef<mirror::Object> ptr1(self, space->Alloc(self, 1 * MB, &dummy));
+  EXPECT_TRUE(ptr1.get() != nullptr);
   InstallClass(ptr1, 1 * MB);
 
   // Fails, requires a higher footprint limit.
   mirror::Object* ptr2 = space->Alloc(self, 8 * MB, &dummy);
-  EXPECT_TRUE(ptr2 == NULL);
+  EXPECT_TRUE(ptr2 == nullptr);
 
   // Succeeds, adjusts the footprint.
   size_t ptr3_bytes_allocated;
-  mirror::Object* ptr3 = space->AllocWithGrowth(self, 8 * MB, &ptr3_bytes_allocated);
-  EXPECT_TRUE(ptr3 != NULL);
+  SirtRef<mirror::Object> ptr3(self, space->AllocWithGrowth(self, 8 * MB, &ptr3_bytes_allocated));
+  EXPECT_TRUE(ptr3.get() != nullptr);
   EXPECT_LE(8U * MB, ptr3_bytes_allocated);
   InstallClass(ptr3, 8 * MB);
 
   // Fails, requires a higher footprint limit.
   mirror::Object* ptr4 = space->Alloc(self, 8 * MB, &dummy);
-  EXPECT_TRUE(ptr4 == NULL);
+  EXPECT_TRUE(ptr4 == nullptr);
 
   // Also fails, requires a higher allowed footprint.
   mirror::Object* ptr5 = space->AllocWithGrowth(self, 8 * MB, &dummy);
-  EXPECT_TRUE(ptr5 == NULL);
+  EXPECT_TRUE(ptr5 == nullptr);
 
   // Release some memory.
-  ScopedObjectAccess soa(self);
-  size_t free3 = space->AllocationSize(ptr3);
+  size_t free3 = space->AllocationSize(ptr3.get());
   EXPECT_EQ(free3, ptr3_bytes_allocated);
-  space->Free(self, ptr3);
+  space->Free(self, ptr3.reset(nullptr));
   EXPECT_LE(8U * MB, free3);
 
   // Succeeds, now that memory has been freed.
-  mirror::Object* ptr6 = space->AllocWithGrowth(self, 9 * MB, &dummy);
-  EXPECT_TRUE(ptr6 != NULL);
+  SirtRef<mirror::Object> ptr6(self, space->AllocWithGrowth(self, 9 * MB, &dummy));
+  EXPECT_TRUE(ptr6.get() != nullptr);
   InstallClass(ptr6, 9 * MB);
 
   // Final clean up.
-  size_t free1 = space->AllocationSize(ptr1);
-  space->Free(self, ptr1);
+  size_t free1 = space->AllocationSize(ptr1.get());
+  space->Free(self, ptr1.reset(nullptr));
   EXPECT_LE(1U * MB, free1);
 }
 
@@ -288,11 +290,11 @@
 TEST_F(SpaceTest, LargeObjectTest) {
   size_t rand_seed = 0;
   for (size_t i = 0; i < 2; ++i) {
-    LargeObjectSpace* los = NULL;
+    LargeObjectSpace* los = nullptr;
     if (i == 0) {
       los = space::LargeObjectMapSpace::Create("large object space");
     } else {
-      los = space::FreeListSpace::Create("large object space", NULL, 128 * MB);
+      los = space::FreeListSpace::Create("large object space", nullptr, 128 * MB);
     }
 
     static const size_t num_allocations = 64;
@@ -304,7 +306,7 @@
         size_t request_size = test_rand(&rand_seed) % max_allocation_size;
         size_t allocation_size = 0;
         mirror::Object* obj = los->Alloc(Thread::Current(), request_size, &allocation_size);
-        ASSERT_TRUE(obj != NULL);
+        ASSERT_TRUE(obj != nullptr);
         ASSERT_EQ(allocation_size, los->AllocationSize(obj));
         ASSERT_GE(allocation_size, request_size);
         // Fill in our magic value.
@@ -337,7 +339,7 @@
     size_t bytes_allocated = 0;
     // Checks that the coalescing works.
     mirror::Object* obj = los->Alloc(Thread::Current(), 100 * MB, &bytes_allocated);
-    EXPECT_TRUE(obj != NULL);
+    EXPECT_TRUE(obj != nullptr);
     los->Free(Thread::Current(), obj);
 
     EXPECT_EQ(0U, los->GetBytesAllocated());
@@ -347,12 +349,13 @@
 }
 
 void SpaceTest::AllocAndFreeListTestBody(CreateSpaceFn create_space) {
-  MallocSpace* space(create_space("test", 4 * MB, 16 * MB, 16 * MB, NULL));
-  ASSERT_TRUE(space != NULL);
+  MallocSpace* space(create_space("test", 4 * MB, 16 * MB, 16 * MB, nullptr));
+  ASSERT_TRUE(space != nullptr);
 
   // Make space findable to the heap, will also delete space when runtime is cleaned up
   AddSpace(space);
   Thread* self = Thread::Current();
+  ScopedObjectAccess soa(self);
 
   // Succeeds, fits without adjusting the max allowed footprint.
   mirror::Object* lots_of_objects[1024];
@@ -361,17 +364,16 @@
     size_t size_of_zero_length_byte_array = SizeOfZeroLengthByteArray();
     lots_of_objects[i] = space->Alloc(self, size_of_zero_length_byte_array, &allocation_size);
     EXPECT_TRUE(lots_of_objects[i] != nullptr);
-    InstallClass(lots_of_objects[i], size_of_zero_length_byte_array);
+    SirtRef<mirror::Object> obj(self, lots_of_objects[i]);
+    InstallClass(obj, size_of_zero_length_byte_array);
+    lots_of_objects[i] = obj.get();
     EXPECT_EQ(allocation_size, space->AllocationSize(lots_of_objects[i]));
   }
 
-  // Release memory and check pointers are NULL.
-  {
-    ScopedObjectAccess soa(self);
-    space->FreeList(self, arraysize(lots_of_objects), lots_of_objects);
-    for (size_t i = 0; i < arraysize(lots_of_objects); i++) {
-      EXPECT_TRUE(lots_of_objects[i] == nullptr);
-    }
+  // Release memory and check pointers are nullptr.
+  space->FreeList(self, arraysize(lots_of_objects), lots_of_objects);
+  for (size_t i = 0; i < arraysize(lots_of_objects); i++) {
+    EXPECT_TRUE(lots_of_objects[i] == nullptr);
   }
 
   // Succeeds, fits by adjusting the max allowed footprint.
@@ -379,17 +381,17 @@
     size_t allocation_size = 0;
     lots_of_objects[i] = space->AllocWithGrowth(self, 1024, &allocation_size);
     EXPECT_TRUE(lots_of_objects[i] != nullptr);
-    InstallClass(lots_of_objects[i], 1024);
+    SirtRef<mirror::Object> obj(self, lots_of_objects[i]);
+    InstallClass(obj, 1024);
+    lots_of_objects[i] = obj.get();
     EXPECT_EQ(allocation_size, space->AllocationSize(lots_of_objects[i]));
   }
 
-  // Release memory and check pointers are NULL
-  {
-    ScopedObjectAccess soa(self);
-    space->FreeList(self, arraysize(lots_of_objects), lots_of_objects);
-    for (size_t i = 0; i < arraysize(lots_of_objects); i++) {
-      EXPECT_TRUE(lots_of_objects[i] == nullptr);
-    }
+  // Release memory and check pointers are nullptr
+  // TODO: This isn't compaction safe, fix.
+  space->FreeList(self, arraysize(lots_of_objects), lots_of_objects);
+  for (size_t i = 0; i < arraysize(lots_of_objects); i++) {
+    EXPECT_TRUE(lots_of_objects[i] == nullptr);
   }
 }
 
@@ -430,6 +432,7 @@
   size_t last_object = 0;  // last object for which allocation succeeded
   size_t amount_allocated = 0;  // amount of space allocated
   Thread* self = Thread::Current();
+  ScopedObjectAccess soa(self);
   size_t rand_seed = 123456789;
   for (size_t i = 0; i < max_objects; i++) {
     size_t alloc_fails = 0;  // number of failed allocations
@@ -446,19 +449,19 @@
           alloc_size = size_of_zero_length_byte_array;
         }
       }
-      mirror::Object* object;
+      SirtRef<mirror::Object> object(self, nullptr);
       size_t bytes_allocated = 0;
       if (round <= 1) {
-        object = space->Alloc(self, alloc_size, &bytes_allocated);
+        object.reset(space->Alloc(self, alloc_size, &bytes_allocated));
       } else {
-        object = space->AllocWithGrowth(self, alloc_size, &bytes_allocated);
+        object.reset(space->AllocWithGrowth(self, alloc_size, &bytes_allocated));
       }
       footprint = space->GetFootprint();
       EXPECT_GE(space->Size(), footprint);  // invariant
-      if (object != NULL) {  // allocation succeeded
+      if (object.get() != nullptr) {  // allocation succeeded
         InstallClass(object, alloc_size);
-        lots_of_objects.get()[i] = object;
-        size_t allocation_size = space->AllocationSize(object);
+        lots_of_objects[i] = object.get();
+        size_t allocation_size = space->AllocationSize(object.get());
         EXPECT_EQ(bytes_allocated, allocation_size);
         if (object_size > 0) {
           EXPECT_GE(allocation_size, static_cast<size_t>(object_size));
@@ -489,8 +492,11 @@
   // Release storage in a semi-adhoc manner
   size_t free_increment = 96;
   while (true) {
-    // Give the space a haircut
-    space->Trim();
+    {
+      ScopedThreadStateChange tsc(self, kNative);
+      // Give the space a haircut.
+      space->Trim();
+    }
 
     // Bounds sanity
     footprint = space->GetFootprint();
@@ -504,30 +510,28 @@
       break;
     }
 
-    {
-      // Free some objects
-      ScopedObjectAccess soa(self);
-      for (size_t i = 0; i < last_object; i += free_increment) {
-        mirror::Object* object = lots_of_objects.get()[i];
-        if (object == NULL) {
-          continue;
-        }
-        size_t allocation_size = space->AllocationSize(object);
-        if (object_size > 0) {
-          EXPECT_GE(allocation_size, static_cast<size_t>(object_size));
-        } else {
-          EXPECT_GE(allocation_size, 8u);
-        }
-        space->Free(self, object);
-        lots_of_objects.get()[i] = NULL;
-        amount_allocated -= allocation_size;
-        footprint = space->GetFootprint();
-        EXPECT_GE(space->Size(), footprint);  // invariant
+    // Free some objects
+    for (size_t i = 0; i < last_object; i += free_increment) {
+      mirror::Object* object = lots_of_objects.get()[i];
+      if (object == nullptr) {
+        continue;
       }
-
-      free_increment >>= 1;
+      size_t allocation_size = space->AllocationSize(object);
+      if (object_size > 0) {
+        EXPECT_GE(allocation_size, static_cast<size_t>(object_size));
+      } else {
+        EXPECT_GE(allocation_size, 8u);
+      }
+      space->Free(self, object);
+      lots_of_objects.get()[i] = nullptr;
+      amount_allocated -= allocation_size;
+      footprint = space->GetFootprint();
+      EXPECT_GE(space->Size(), footprint);  // invariant
     }
+
+    free_increment >>= 1;
   }
+
   // The space has become empty here before allocating a large object
   // below. For RosAlloc, revoke thread-local runs, which are kept
   // even when empty for a performance reason, so that they won't
@@ -537,15 +541,15 @@
   space->RevokeAllThreadLocalBuffers();
 
   // All memory was released, try a large allocation to check freed memory is being coalesced
-  mirror::Object* large_object;
+  SirtRef<mirror::Object> large_object(self, nullptr);
   size_t three_quarters_space = (growth_limit / 2) + (growth_limit / 4);
   size_t bytes_allocated = 0;
   if (round <= 1) {
-    large_object = space->Alloc(self, three_quarters_space, &bytes_allocated);
+    large_object.reset(space->Alloc(self, three_quarters_space, &bytes_allocated));
   } else {
-    large_object = space->AllocWithGrowth(self, three_quarters_space, &bytes_allocated);
+    large_object.reset(space->AllocWithGrowth(self, three_quarters_space, &bytes_allocated));
   }
-  EXPECT_TRUE(large_object != NULL);
+  EXPECT_TRUE(large_object.get() != nullptr);
   InstallClass(large_object, three_quarters_space);
 
   // Sanity check footprint
@@ -555,10 +559,8 @@
   EXPECT_LE(space->Size(), growth_limit);
 
   // Clean up
-  {
-    ScopedObjectAccess soa(self);
-    space->Free(self, large_object);
-  }
+  space->Free(self, large_object.reset(nullptr));
+
   // Sanity check footprint
   footprint = space->GetFootprint();
   EXPECT_LE(footprint, growth_limit);
@@ -574,8 +576,8 @@
   size_t initial_size = 4 * MB;
   size_t growth_limit = 8 * MB;
   size_t capacity = 16 * MB;
-  MallocSpace* space(create_space("test", initial_size, growth_limit, capacity, NULL));
-  ASSERT_TRUE(space != NULL);
+  MallocSpace* space(create_space("test", initial_size, growth_limit, capacity, nullptr));
+  ASSERT_TRUE(space != nullptr);
 
   // Basic sanity
   EXPECT_EQ(space->Capacity(), growth_limit);