Add Handle/HandleScope and delete SirtRef.

Delete SirtRef and replaced it with Handle. Handles are value types
which wrap around StackReference*.

Renamed StackIndirectReferenceTable to HandleScope.

Added a scoped handle wrapper which wraps around an Object** and
restores it in its destructor.

Renamed Handle::get -> Get.

Bug: 8473721

Change-Id: Idbfebd4f35af629f0f43931b7c5184b334822c7a
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index 6a2bfb5..d9bc105 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -371,13 +371,14 @@
   ScopedObjectAccess soa(self);
   // garbage is created during ClassLinker::Init
 
-  SirtRef<mirror::String> obj(soa.Self(),
-                              mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!"));
+  StackHandleScope<2> hs(soa.Self());
+  Handle<mirror::String> obj(
+      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!")));
   LockWord lock = obj->GetLockWord(false);
   LockWord::LockState old_state = lock.GetState();
   EXPECT_EQ(LockWord::LockState::kUnlocked, old_state);
 
-  Invoke3(reinterpret_cast<size_t>(obj.get()), 0U, 0U,
+  Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U,
           reinterpret_cast<uintptr_t>(&art_quick_lock_object), self);
 
   LockWord lock_after = obj->GetLockWord(false);
@@ -386,7 +387,7 @@
   EXPECT_EQ(lock_after.ThinLockCount(), 0U);  // Thin lock starts count at zero
 
   for (size_t i = 1; i < kThinLockLoops; ++i) {
-    Invoke3(reinterpret_cast<size_t>(obj.get()), 0U, 0U,
+    Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U,
               reinterpret_cast<uintptr_t>(&art_quick_lock_object), self);
 
     // Check we're at lock count i
@@ -398,12 +399,12 @@
   }
 
   // Force a fat lock by running identity hashcode to fill up lock word.
-  SirtRef<mirror::Object> obj2(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(),
-                                                                                 "hello, world!"));
+  Handle<mirror::String> obj2(hs.NewHandle(
+      mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!")));
 
   obj2->IdentityHashCode();
 
-  Invoke3(reinterpret_cast<size_t>(obj2.get()), 0U, 0U,
+  Invoke3(reinterpret_cast<size_t>(obj2.Get()), 0U, 0U,
           reinterpret_cast<uintptr_t>(&art_quick_lock_object), self);
 
   LockWord lock_after2 = obj2->GetLockWord(false);
@@ -447,16 +448,16 @@
   // Create an object
   ScopedObjectAccess soa(self);
   // garbage is created during ClassLinker::Init
-
-  SirtRef<mirror::String> obj(soa.Self(),
-                              mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!"));
+  static constexpr size_t kNumberOfLocks = 10;  // Number of objects = lock
+  StackHandleScope<kNumberOfLocks + 1> hs(self);
+  Handle<mirror::String> obj(
+      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!")));
   LockWord lock = obj->GetLockWord(false);
   LockWord::LockState old_state = lock.GetState();
   EXPECT_EQ(LockWord::LockState::kUnlocked, old_state);
 
-  test->Invoke3(reinterpret_cast<size_t>(obj.get()), 0U, 0U,
+  test->Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U,
                 reinterpret_cast<uintptr_t>(&art_quick_unlock_object), self);
-
   // This should be an illegal monitor state.
   EXPECT_TRUE(self->IsExceptionPending());
   self->ClearException();
@@ -465,14 +466,14 @@
   LockWord::LockState new_state = lock_after.GetState();
   EXPECT_EQ(LockWord::LockState::kUnlocked, new_state);
 
-  test->Invoke3(reinterpret_cast<size_t>(obj.get()), 0U, 0U,
+  test->Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U,
                 reinterpret_cast<uintptr_t>(&art_quick_lock_object), self);
 
   LockWord lock_after2 = obj->GetLockWord(false);
   LockWord::LockState new_state2 = lock_after2.GetState();
   EXPECT_EQ(LockWord::LockState::kThinLocked, new_state2);
 
-  test->Invoke3(reinterpret_cast<size_t>(obj.get()), 0U, 0U,
+  test->Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U,
                 reinterpret_cast<uintptr_t>(&art_quick_unlock_object), self);
 
   LockWord lock_after3 = obj->GetLockWord(false);
@@ -485,20 +486,18 @@
 
   RandGen r(0x1234);
 
-  constexpr size_t kNumberOfLocks = 10;  // Number of objects = lock
   constexpr size_t kIterations = 10000;  // Number of iterations
   constexpr size_t kMoveToFat = 1000;     // Chance of 1:kMoveFat to make a lock fat.
 
   size_t counts[kNumberOfLocks];
   bool fat[kNumberOfLocks];  // Whether a lock should be thin or fat.
-  SirtRef<mirror::String>* objects[kNumberOfLocks];
+  Handle<mirror::String> objects[kNumberOfLocks];
 
   // Initialize = allocate.
   for (size_t i = 0; i < kNumberOfLocks; ++i) {
     counts[i] = 0;
     fat[i] = false;
-    objects[i] = new SirtRef<mirror::String>(soa.Self(),
-                                             mirror::String::AllocFromModifiedUtf8(soa.Self(), ""));
+    objects[i] = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), ""));
   }
 
   for (size_t i = 0; i < kIterations; ++i) {
@@ -508,9 +507,9 @@
     // Make lock fat?
     if (!fat[index] && (r.next() % kMoveToFat == 0)) {
       fat[index] = true;
-      objects[index]->get()->IdentityHashCode();
+      objects[index]->IdentityHashCode();
 
-      LockWord lock_iter = objects[index]->get()->GetLockWord(false);
+      LockWord lock_iter = objects[index]->GetLockWord(false);
       LockWord::LockState iter_state = lock_iter.GetState();
       if (counts[index] == 0) {
         EXPECT_EQ(LockWord::LockState::kHashCode, iter_state);
@@ -529,11 +528,11 @@
       }
 
       if (lock) {
-        test-> Invoke3(reinterpret_cast<size_t>(objects[index]->get()), 0U, 0U,
+        test->Invoke3(reinterpret_cast<size_t>(objects[index].Get()), 0U, 0U,
                        reinterpret_cast<uintptr_t>(&art_quick_lock_object), self);
         counts[index]++;
       } else {
-        test->Invoke3(reinterpret_cast<size_t>(objects[index]->get()), 0U, 0U,
+        test->Invoke3(reinterpret_cast<size_t>(objects[index].Get()), 0U, 0U,
                       reinterpret_cast<uintptr_t>(&art_quick_unlock_object), self);
         counts[index]--;
       }
@@ -541,12 +540,12 @@
       EXPECT_FALSE(self->IsExceptionPending());
 
       // Check the new state.
-      LockWord lock_iter = objects[index]->get()->GetLockWord(true);
+      LockWord lock_iter = objects[index]->GetLockWord(true);
       LockWord::LockState iter_state = lock_iter.GetState();
       if (fat[index]) {
         // Abuse MonitorInfo.
         EXPECT_EQ(LockWord::LockState::kFatLocked, iter_state) << index;
-        MonitorInfo info(objects[index]->get());
+        MonitorInfo info(objects[index].Get());
         EXPECT_EQ(counts[index], info.entry_count_) << index;
       } else {
         if (counts[index] > 0) {
@@ -560,23 +559,20 @@
   }
 
   // Unlock the remaining count times and then check it's unlocked. Then deallocate.
-  // Go reverse order to correctly handle SirtRefs.
+  // Go reverse order to correctly handle Handles.
   for (size_t i = 0; i < kNumberOfLocks; ++i) {
     size_t index = kNumberOfLocks - 1 - i;
     size_t count = counts[index];
     while (count > 0) {
-      test->Invoke3(reinterpret_cast<size_t>(objects[index]->get()), 0U, 0U,
+      test->Invoke3(reinterpret_cast<size_t>(objects[index].Get()), 0U, 0U,
                     reinterpret_cast<uintptr_t>(&art_quick_unlock_object), self);
-
       count--;
     }
 
-    LockWord lock_after4 = objects[index]->get()->GetLockWord(false);
+    LockWord lock_after4 = objects[index]->GetLockWord(false);
     LockWord::LockState new_state4 = lock_after4.GetState();
     EXPECT_TRUE(LockWord::LockState::kUnlocked == new_state4
                 || LockWord::LockState::kFatLocked == new_state4);
-
-    delete objects[index];
   }
 
   // Test done.
@@ -602,31 +598,32 @@
   ScopedObjectAccess soa(self);
   // garbage is created during ClassLinker::Init
 
-  SirtRef<mirror::Class> c(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
-                                                                          "[Ljava/lang/Object;"));
-  SirtRef<mirror::Class> c2(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
-                                                                            "[Ljava/lang/String;"));
+  StackHandleScope<2> hs(soa.Self());
+  Handle<mirror::Class> c(
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
+  Handle<mirror::Class> c2(
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;")));
 
   EXPECT_FALSE(self->IsExceptionPending());
 
-  Invoke3(reinterpret_cast<size_t>(c.get()), reinterpret_cast<size_t>(c.get()), 0U,
+  Invoke3(reinterpret_cast<size_t>(c.Get()), reinterpret_cast<size_t>(c.Get()), 0U,
           reinterpret_cast<uintptr_t>(&art_quick_check_cast), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
 
-  Invoke3(reinterpret_cast<size_t>(c2.get()), reinterpret_cast<size_t>(c2.get()), 0U,
+  Invoke3(reinterpret_cast<size_t>(c2.Get()), reinterpret_cast<size_t>(c2.Get()), 0U,
           reinterpret_cast<uintptr_t>(&art_quick_check_cast), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
 
-  Invoke3(reinterpret_cast<size_t>(c.get()), reinterpret_cast<size_t>(c2.get()), 0U,
+  Invoke3(reinterpret_cast<size_t>(c.Get()), reinterpret_cast<size_t>(c2.Get()), 0U,
           reinterpret_cast<uintptr_t>(&art_quick_check_cast), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
 
   // TODO: Make the following work. But that would require correct managed frames.
 
-  Invoke3(reinterpret_cast<size_t>(c2.get()), reinterpret_cast<size_t>(c.get()), 0U,
+  Invoke3(reinterpret_cast<size_t>(c2.Get()), reinterpret_cast<size_t>(c.Get()), 0U,
           reinterpret_cast<uintptr_t>(&art_quick_check_cast), self);
 
   EXPECT_TRUE(self->IsExceptionPending());
@@ -654,23 +651,22 @@
   ScopedObjectAccess soa(self);
   // garbage is created during ClassLinker::Init
 
-  SirtRef<mirror::Class> c(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
-                                                                            "Ljava/lang/Object;"));
-  SirtRef<mirror::Class> c2(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
-                                                                            "Ljava/lang/String;"));
-  SirtRef<mirror::Class> ca(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
-                                                                            "[Ljava/lang/String;"));
+  StackHandleScope<5> hs(soa.Self());
+  Handle<mirror::Class> c(
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
+  Handle<mirror::Class> ca(
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;")));
 
   // Build a string array of size 1
-  SirtRef<mirror::ObjectArray<mirror::Object> > array(soa.Self(),
-            mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), ca.get(), 10));
+  Handle<mirror::ObjectArray<mirror::Object>> array(
+      hs.NewHandle(mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), ca.Get(), 10)));
 
   // Build a string -> should be assignable
-  SirtRef<mirror::Object> str_obj(soa.Self(),
-                                  mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!"));
+  Handle<mirror::String> str_obj(
+      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!")));
 
   // Build a generic object -> should fail assigning
-  SirtRef<mirror::Object> obj_obj(soa.Self(), c->AllocObject(soa.Self()));
+  Handle<mirror::Object> obj_obj(hs.NewHandle(c->AllocObject(soa.Self())));
 
   // Play with it...
 
@@ -679,51 +675,51 @@
 
   EXPECT_FALSE(self->IsExceptionPending());
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 0U, reinterpret_cast<size_t>(str_obj.get()),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 0U, reinterpret_cast<size_t>(str_obj.Get()),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
-  EXPECT_EQ(str_obj.get(), array->Get(0));
+  EXPECT_EQ(str_obj.Get(), array->Get(0));
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 1U, reinterpret_cast<size_t>(str_obj.get()),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 1U, reinterpret_cast<size_t>(str_obj.Get()),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
-  EXPECT_EQ(str_obj.get(), array->Get(1));
+  EXPECT_EQ(str_obj.Get(), array->Get(1));
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 2U, reinterpret_cast<size_t>(str_obj.get()),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 2U, reinterpret_cast<size_t>(str_obj.Get()),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
-  EXPECT_EQ(str_obj.get(), array->Get(2));
+  EXPECT_EQ(str_obj.Get(), array->Get(2));
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 3U, reinterpret_cast<size_t>(str_obj.get()),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 3U, reinterpret_cast<size_t>(str_obj.Get()),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
-  EXPECT_EQ(str_obj.get(), array->Get(3));
+  EXPECT_EQ(str_obj.Get(), array->Get(3));
 
   // 1.2) Assign null to array[0..3]
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 0U, reinterpret_cast<size_t>(nullptr),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 0U, reinterpret_cast<size_t>(nullptr),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
   EXPECT_EQ(nullptr, array->Get(0));
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 1U, reinterpret_cast<size_t>(nullptr),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 1U, reinterpret_cast<size_t>(nullptr),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
   EXPECT_EQ(nullptr, array->Get(1));
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 2U, reinterpret_cast<size_t>(nullptr),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 2U, reinterpret_cast<size_t>(nullptr),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
   EXPECT_EQ(nullptr, array->Get(2));
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 3U, reinterpret_cast<size_t>(nullptr),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 3U, reinterpret_cast<size_t>(nullptr),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_FALSE(self->IsExceptionPending());
@@ -735,7 +731,7 @@
   // 2.1) Array = null
   // TODO: Throwing NPE needs actual DEX code
 
-//  Invoke3(reinterpret_cast<size_t>(nullptr), 0U, reinterpret_cast<size_t>(str_obj.get()),
+//  Invoke3(reinterpret_cast<size_t>(nullptr), 0U, reinterpret_cast<size_t>(str_obj.Get()),
 //          reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 //
 //  EXPECT_TRUE(self->IsExceptionPending());
@@ -743,8 +739,8 @@
 
   // 2.2) Index < 0
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), static_cast<size_t>(-1),
-          reinterpret_cast<size_t>(str_obj.get()),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), static_cast<size_t>(-1),
+          reinterpret_cast<size_t>(str_obj.Get()),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_TRUE(self->IsExceptionPending());
@@ -752,7 +748,7 @@
 
   // 2.3) Index > 0
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 10U, reinterpret_cast<size_t>(str_obj.get()),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 10U, reinterpret_cast<size_t>(str_obj.Get()),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_TRUE(self->IsExceptionPending());
@@ -760,7 +756,7 @@
 
   // 3) Failure cases (obj into str[])
 
-  Invoke3(reinterpret_cast<size_t>(array.get()), 0U, reinterpret_cast<size_t>(obj_obj.get()),
+  Invoke3(reinterpret_cast<size_t>(array.Get()), 0U, reinterpret_cast<size_t>(obj_obj.Get()),
           reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
 
   EXPECT_TRUE(self->IsExceptionPending());
@@ -785,8 +781,9 @@
   ScopedObjectAccess soa(self);
   // garbage is created during ClassLinker::Init
 
-  SirtRef<mirror::Class> c(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
-                                                                      "Ljava/lang/Object;"));
+  StackHandleScope<2> hs(soa.Self());
+  Handle<mirror::Class> c(
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
 
   // Play with it...
 
@@ -802,35 +799,35 @@
     EXPECT_FALSE(self->IsExceptionPending());
     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
     mirror::Object* obj = reinterpret_cast<mirror::Object*>(result);
-    EXPECT_EQ(c.get(), obj->GetClass());
+    EXPECT_EQ(c.Get(), obj->GetClass());
     VerifyObject(obj);
   }
 
   {
     // We can use nullptr in the second argument as we do not need a method here (not used in
     // resolved/initialized cases)
-    size_t result = Invoke3(reinterpret_cast<size_t>(c.get()), reinterpret_cast<size_t>(nullptr), 0U,
+    size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), reinterpret_cast<size_t>(nullptr), 0U,
                             reinterpret_cast<uintptr_t>(GetTlsPtr(self)->quick_entrypoints.pAllocObjectResolved),
                             self);
 
     EXPECT_FALSE(self->IsExceptionPending());
     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
     mirror::Object* obj = reinterpret_cast<mirror::Object*>(result);
-    EXPECT_EQ(c.get(), obj->GetClass());
+    EXPECT_EQ(c.Get(), obj->GetClass());
     VerifyObject(obj);
   }
 
   {
     // We can use nullptr in the second argument as we do not need a method here (not used in
     // resolved/initialized cases)
-    size_t result = Invoke3(reinterpret_cast<size_t>(c.get()), reinterpret_cast<size_t>(nullptr), 0U,
+    size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), reinterpret_cast<size_t>(nullptr), 0U,
                             reinterpret_cast<uintptr_t>(GetTlsPtr(self)->quick_entrypoints.pAllocObjectInitialized),
                             self);
 
     EXPECT_FALSE(self->IsExceptionPending());
     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
     mirror::Object* obj = reinterpret_cast<mirror::Object*>(result);
-    EXPECT_EQ(c.get(), obj->GetClass());
+    EXPECT_EQ(c.Get(), obj->GetClass());
     VerifyObject(obj);
   }
 
@@ -841,19 +838,21 @@
     Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
 
     // Array helps to fill memory faster.
-    SirtRef<mirror::Class> ca(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
-                                                                         "[Ljava/lang/Object;"));
-    std::vector<SirtRef<mirror::Object>*> sirt_refs;
+    Handle<mirror::Class> ca(
+        hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
+
+    // Use arbitrary large amount for now.
+    static const size_t kMaxHandles = 1000000;
+    UniquePtr<StackHandleScope<kMaxHandles> > hsp(new StackHandleScope<kMaxHandles>(self));
+
+    std::vector<Handle<mirror::Object>> handles;
     // Start allocating with 128K
     size_t length = 128 * KB / 4;
     while (length > 10) {
-      SirtRef<mirror::Object>* ref = new SirtRef<mirror::Object>(soa.Self(),
-                                              mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(),
-                                                                                         ca.get(),
-                                                                                         length/4));
-      if (self->IsExceptionPending() || ref->get() == nullptr) {
+      Handle<mirror::Object> h(hsp->NewHandle<mirror::Object>(
+          mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), ca.Get(), length / 4)));
+      if (self->IsExceptionPending() || h.Get() == nullptr) {
         self->ClearException();
-        delete ref;
 
         // Try a smaller length
         length = length / 8;
@@ -863,38 +862,26 @@
           length = mem / 8;
         }
       } else {
-        sirt_refs.push_back(ref);
+        handles.push_back(h);
       }
     }
-    LOG(INFO) << "Used " << sirt_refs.size() << " arrays to fill space.";
+    LOG(INFO) << "Used " << handles.size() << " arrays to fill space.";
 
     // Allocate simple objects till it fails.
     while (!self->IsExceptionPending()) {
-      SirtRef<mirror::Object>* ref = new SirtRef<mirror::Object>(soa.Self(),
-                                                                 c->AllocObject(soa.Self()));
-      if (!self->IsExceptionPending() && ref->get() != nullptr) {
-        sirt_refs.push_back(ref);
-      } else {
-        delete ref;
+      Handle<mirror::Object> h = hsp->NewHandle(c->AllocObject(soa.Self()));
+      if (!self->IsExceptionPending() && h.Get() != nullptr) {
+        handles.push_back(h);
       }
     }
     self->ClearException();
 
-    size_t result = Invoke3(reinterpret_cast<size_t>(c.get()), reinterpret_cast<size_t>(nullptr), 0U,
+    size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), reinterpret_cast<size_t>(nullptr), 0U,
                             reinterpret_cast<uintptr_t>(GetTlsPtr(self)->quick_entrypoints.pAllocObjectInitialized),
                             self);
-
     EXPECT_TRUE(self->IsExceptionPending());
     self->ClearException();
     EXPECT_EQ(reinterpret_cast<size_t>(nullptr), result);
-
-    // Release all the allocated objects.
-    // Need to go backward to release SirtRef in the right order.
-    auto it = sirt_refs.rbegin();
-    auto end = sirt_refs.rend();
-    for (; it != end; ++it) {
-      delete *it;
-    }
   }
 
   // Tests done.
@@ -916,12 +903,13 @@
   ScopedObjectAccess soa(self);
   // garbage is created during ClassLinker::Init
 
-  SirtRef<mirror::Class> c(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
-                                                                        "[Ljava/lang/Object;"));
+  StackHandleScope<2> hs(self);
+  Handle<mirror::Class> c(
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
 
   // Needed to have a linked method.
-  SirtRef<mirror::Class> c_obj(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
-                                                                          "Ljava/lang/Object;"));
+  Handle<mirror::Class> c_obj(
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
 
   // Play with it...
 
@@ -941,7 +929,7 @@
     EXPECT_FALSE(self->IsExceptionPending());
     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
     mirror::Array* obj = reinterpret_cast<mirror::Array*>(result);
-    EXPECT_EQ(c.get(), obj->GetClass());
+    EXPECT_EQ(c.Get(), obj->GetClass());
     VerifyObject(obj);
     EXPECT_EQ(obj->GetLength(), 10);
   }
@@ -949,16 +937,15 @@
   {
     // We can use nullptr in the second argument as we do not need a method here (not used in
     // resolved/initialized cases)
-    size_t result = Invoke3(reinterpret_cast<size_t>(c.get()), reinterpret_cast<size_t>(nullptr), 10U,
+    size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), reinterpret_cast<size_t>(nullptr), 10U,
                             reinterpret_cast<uintptr_t>(GetTlsPtr(self)->quick_entrypoints.pAllocArrayResolved),
                             self);
-
     EXPECT_FALSE(self->IsExceptionPending()) << PrettyTypeOf(self->GetException(nullptr));
     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
     mirror::Object* obj = reinterpret_cast<mirror::Object*>(result);
     EXPECT_TRUE(obj->IsArrayInstance());
     EXPECT_TRUE(obj->IsObjectArray());
-    EXPECT_EQ(c.get(), obj->GetClass());
+    EXPECT_EQ(c.Get(), obj->GetClass());
     VerifyObject(obj);
     mirror::Array* array = reinterpret_cast<mirror::Array*>(result);
     EXPECT_EQ(array->GetLength(), 10);
@@ -968,7 +955,7 @@
 
   // Out-of-memory.
   {
-    size_t result = Invoke3(reinterpret_cast<size_t>(c.get()), reinterpret_cast<size_t>(nullptr),
+    size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), reinterpret_cast<size_t>(nullptr),
                             GB,  // that should fail...
                             reinterpret_cast<uintptr_t>(GetTlsPtr(self)->quick_entrypoints.pAllocArrayResolved),
                             self);
@@ -1005,32 +992,31 @@
   // Use array so we can index into it and use a matrix for expected results
   // Setup: The first half is standard. The second half uses a non-zero offset.
   // TODO: Shared backing arrays.
-  constexpr size_t base_string_count = 7;
-  const char* c[base_string_count] = { "", "", "a", "aa", "ab", "aac", "aac" , };
+  static constexpr size_t kBaseStringCount  = 7;
+  const char* c[kBaseStringCount] = { "", "", "a", "aa", "ab", "aac", "aac" , };
 
-  constexpr size_t string_count = 2 * base_string_count;
+  static constexpr size_t kStringCount = 2 * kBaseStringCount;
 
-  SirtRef<mirror::String>* s[string_count];
+  StackHandleScope<kStringCount> hs(self);
+  Handle<mirror::String> s[kStringCount];
 
-  for (size_t i = 0; i < base_string_count; ++i) {
-    s[i] = new SirtRef<mirror::String>(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(),
-                                                                                         c[i]));
+  for (size_t i = 0; i < kBaseStringCount; ++i) {
+    s[i] = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), c[i]));
   }
 
   RandGen r(0x1234);
 
-  for (size_t i = base_string_count; i < string_count; ++i) {
-    s[i] = new SirtRef<mirror::String>(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(),
-                                                                         c[i - base_string_count]));
-    int32_t length = s[i]->get()->GetLength();
+  for (size_t i = kBaseStringCount; i < kStringCount; ++i) {
+    s[i] = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), c[i - kBaseStringCount]));
+    int32_t length = s[i]->GetLength();
     if (length > 1) {
       // Set a random offset and length.
       int32_t new_offset = 1 + (r.next() % (length - 1));
       int32_t rest = length - new_offset - 1;
       int32_t new_length = 1 + (rest > 0 ? r.next() % rest : 0);
 
-      s[i]->get()->SetField32<false>(mirror::String::CountOffset(), new_length);
-      s[i]->get()->SetField32<false>(mirror::String::OffsetOffset(), new_offset);
+      s[i]->SetField32<false>(mirror::String::CountOffset(), new_length);
+      s[i]->SetField32<false>(mirror::String::OffsetOffset(), new_offset);
     }
   }
 
@@ -1039,20 +1025,20 @@
   // Matrix of expectations. First component is first parameter. Note we only check against the
   // sign, not the value. As we are testing random offsets, we need to compute this and need to
   // rely on String::CompareTo being correct.
-  int32_t expected[string_count][string_count];
-  for (size_t x = 0; x < string_count; ++x) {
-    for (size_t y = 0; y < string_count; ++y) {
-      expected[x][y] = s[x]->get()->CompareTo(s[y]->get());
+  int32_t expected[kStringCount][kStringCount];
+  for (size_t x = 0; x < kStringCount; ++x) {
+    for (size_t y = 0; y < kStringCount; ++y) {
+      expected[x][y] = s[x]->CompareTo(s[y].Get());
     }
   }
 
   // Play with it...
 
-  for (size_t x = 0; x < string_count; ++x) {
-    for (size_t y = 0; y < string_count; ++y) {
+  for (size_t x = 0; x < kStringCount; ++x) {
+    for (size_t y = 0; y < kStringCount; ++y) {
       // Test string_compareto x y
-      size_t result = Invoke3(reinterpret_cast<size_t>(s[x]->get()),
-                              reinterpret_cast<size_t>(s[y]->get()), 0U,
+      size_t result = Invoke3(reinterpret_cast<size_t>(s[x].Get()),
+                              reinterpret_cast<size_t>(s[y].Get()), 0U,
                               reinterpret_cast<uintptr_t>(&art_quick_string_compareto), self);
 
       EXPECT_FALSE(self->IsExceptionPending());
@@ -1090,7 +1076,7 @@
 extern "C" void art_quick_get32_static(void);
 #endif
 
-static void GetSet32Static(SirtRef<mirror::Object>* obj, SirtRef<mirror::ArtField>* f, Thread* self,
+static void GetSet32Static(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self,
                            mirror::ArtMethod* referrer, StubTest* test)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
@@ -1126,7 +1112,7 @@
 extern "C" void art_quick_get32_instance(void);
 #endif
 
-static void GetSet32Instance(SirtRef<mirror::Object>* obj, SirtRef<mirror::ArtField>* f,
+static void GetSet32Instance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
                              Thread* self, mirror::ArtMethod* referrer, StubTest* test)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
@@ -1135,20 +1121,20 @@
 
   for (size_t i = 0; i < num_values; ++i) {
     test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
-                              reinterpret_cast<size_t>(obj->get()),
+                              reinterpret_cast<size_t>(obj->Get()),
                               static_cast<size_t>(values[i]),
                               reinterpret_cast<uintptr_t>(&art_quick_set32_instance),
                               self,
                               referrer);
 
-    int32_t res = f->get()->GetInt(obj->get());
+    int32_t res = f->Get()->GetInt(obj->Get());
     EXPECT_EQ(res, static_cast<int32_t>(values[i])) << "Iteration " << i;
 
     res++;
-    f->get()->SetInt<false>(obj->get(), res);
+    f->Get()->SetInt<false>(obj->Get(), res);
 
     size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
-                                            reinterpret_cast<size_t>(obj->get()),
+                                            reinterpret_cast<size_t>(obj->Get()),
                                             0U,
                                             reinterpret_cast<uintptr_t>(&art_quick_get32_instance),
                                             self,
@@ -1187,7 +1173,7 @@
 }
 #endif
 
-static void GetSetObjStatic(SirtRef<mirror::Object>* obj, SirtRef<mirror::ArtField>* f, Thread* self,
+static void GetSetObjStatic(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self,
                             mirror::ArtMethod* referrer, StubTest* test)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
@@ -1210,7 +1196,7 @@
 extern "C" void art_quick_set_obj_instance(void);
 extern "C" void art_quick_get_obj_instance(void);
 
-static void set_and_check_instance(SirtRef<mirror::ArtField>* f, mirror::Object* trg,
+static void set_and_check_instance(Handle<mirror::ArtField>* f, mirror::Object* trg,
                                    mirror::Object* val, Thread* self, mirror::ArtMethod* referrer,
                                    StubTest* test)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -1230,21 +1216,21 @@
 
   EXPECT_EQ(res, reinterpret_cast<size_t>(val)) << "Value " << val;
 
-  EXPECT_EQ(val, f->get()->GetObj(trg));
+  EXPECT_EQ(val, f->Get()->GetObj(trg));
 }
 #endif
 
-static void GetSetObjInstance(SirtRef<mirror::Object>* obj, SirtRef<mirror::ArtField>* f,
+static void GetSetObjInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
                               Thread* self, mirror::ArtMethod* referrer, StubTest* test)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
-  set_and_check_instance(f, obj->get(), nullptr, self, referrer, test);
+  set_and_check_instance(f, obj->Get(), nullptr, self, referrer, test);
 
   // Allocate a string object for simplicity.
   mirror::String* str = mirror::String::AllocFromModifiedUtf8(self, "Test");
-  set_and_check_instance(f, obj->get(), str, self, referrer, test);
+  set_and_check_instance(f, obj->Get(), str, self, referrer, test);
 
-  set_and_check_instance(f, obj->get(), nullptr, self, referrer, test);
+  set_and_check_instance(f, obj->Get(), nullptr, self, referrer, test);
 #else
   LOG(INFO) << "Skipping setObjinstance as I don't know how to do that on " << kRuntimeISA;
   // Force-print to std::cout so it's also outside the logcat.
@@ -1260,7 +1246,7 @@
 extern "C" void art_quick_get64_static(void);
 #endif
 
-static void GetSet64Static(SirtRef<mirror::Object>* obj, SirtRef<mirror::ArtField>* f, Thread* self,
+static void GetSet64Static(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self,
                            mirror::ArtMethod* referrer, StubTest* test)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
 #if defined(__x86_64__) || defined(__aarch64__)
@@ -1295,7 +1281,7 @@
 extern "C" void art_quick_get64_instance(void);
 #endif
 
-static void GetSet64Instance(SirtRef<mirror::Object>* obj, SirtRef<mirror::ArtField>* f,
+static void GetSet64Instance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
                              Thread* self, mirror::ArtMethod* referrer, StubTest* test)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
 #if defined(__x86_64__) || defined(__aarch64__)
@@ -1304,20 +1290,20 @@
 
   for (size_t i = 0; i < num_values; ++i) {
     test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
-                              reinterpret_cast<size_t>(obj->get()),
+                              reinterpret_cast<size_t>(obj->Get()),
                               static_cast<size_t>(values[i]),
                               reinterpret_cast<uintptr_t>(&art_quick_set64_instance),
                               self,
                               referrer);
 
-    int64_t res = f->get()->GetLong(obj->get());
+    int64_t res = f->Get()->GetLong(obj->Get());
     EXPECT_EQ(res, static_cast<int64_t>(values[i])) << "Iteration " << i;
 
     res++;
-    f->get()->SetLong<false>(obj->get(), res);
+    f->Get()->SetLong<false>(obj->Get(), res);
 
     size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
-                                            reinterpret_cast<size_t>(obj->get()),
+                                            reinterpret_cast<size_t>(obj->Get()),
                                             0U,
                                             reinterpret_cast<uintptr_t>(&art_quick_get64_instance),
                                             self,
@@ -1341,41 +1327,41 @@
   CHECK(o != NULL);
 
   ScopedObjectAccess soa(self);
-  SirtRef<mirror::Object> obj(self, soa.Decode<mirror::Object*>(o));
-
-  SirtRef<mirror::Class> c(self, obj->GetClass());
-
+  StackHandleScope<5> hs(self);
+  Handle<mirror::Object> obj(hs.NewHandle(soa.Decode<mirror::Object*>(o)));
+  Handle<mirror::Class> c(hs.NewHandle(obj->GetClass()));
   // Need a method as a referrer
-  SirtRef<mirror::ArtMethod> m(self, c->GetDirectMethod(0));
+  Handle<mirror::ArtMethod> m(hs.NewHandle(c->GetDirectMethod(0)));
 
   // Play with it...
 
   // Static fields.
   {
-    SirtRef<mirror::ObjectArray<mirror::ArtField>> fields(self, c.get()->GetSFields());
+    Handle<mirror::ObjectArray<mirror::ArtField>> fields(hs.NewHandle(c.Get()->GetSFields()));
     int32_t num_fields = fields->GetLength();
     for (int32_t i = 0; i < num_fields; ++i) {
-      SirtRef<mirror::ArtField> f(self, fields->Get(i));
+      StackHandleScope<1> hs(self);
+      Handle<mirror::ArtField> f(hs.NewHandle(fields->Get(i)));
 
-      FieldHelper fh(f.get());
+      FieldHelper fh(f.Get());
       Primitive::Type type = fh.GetTypeAsPrimitiveType();
       switch (type) {
         case Primitive::Type::kPrimInt:
           if (test_type == type) {
-            GetSet32Static(&obj, &f, self, m.get(), test);
+            GetSet32Static(&obj, &f, self, m.Get(), test);
           }
           break;
 
         case Primitive::Type::kPrimLong:
           if (test_type == type) {
-            GetSet64Static(&obj, &f, self, m.get(), test);
+            GetSet64Static(&obj, &f, self, m.Get(), test);
           }
           break;
 
         case Primitive::Type::kPrimNot:
           // Don't try array.
           if (test_type == type && fh.GetTypeDescriptor()[0] != '[') {
-            GetSetObjStatic(&obj, &f, self, m.get(), test);
+            GetSetObjStatic(&obj, &f, self, m.Get(), test);
           }
           break;
 
@@ -1387,30 +1373,31 @@
 
   // Instance fields.
   {
-    SirtRef<mirror::ObjectArray<mirror::ArtField>> fields(self, c.get()->GetIFields());
+    Handle<mirror::ObjectArray<mirror::ArtField>> fields(hs.NewHandle(c.Get()->GetIFields()));
     int32_t num_fields = fields->GetLength();
     for (int32_t i = 0; i < num_fields; ++i) {
-      SirtRef<mirror::ArtField> f(self, fields->Get(i));
+      StackHandleScope<1> hs(self);
+      Handle<mirror::ArtField> f(hs.NewHandle(fields->Get(i)));
 
-      FieldHelper fh(f.get());
+      FieldHelper fh(f.Get());
       Primitive::Type type = fh.GetTypeAsPrimitiveType();
       switch (type) {
         case Primitive::Type::kPrimInt:
           if (test_type == type) {
-            GetSet32Instance(&obj, &f, self, m.get(), test);
+            GetSet32Instance(&obj, &f, self, m.Get(), test);
           }
           break;
 
         case Primitive::Type::kPrimLong:
           if (test_type == type) {
-            GetSet64Instance(&obj, &f, self, m.get(), test);
+            GetSet64Instance(&obj, &f, self, m.Get(), test);
           }
           break;
 
         case Primitive::Type::kPrimNot:
           // Don't try array.
           if (test_type == type && fh.GetTypeDescriptor()[0] != '[') {
-            GetSetObjInstance(&obj, &f, self, m.get(), test);
+            GetSetObjInstance(&obj, &f, self, m.Get(), test);
           }
           break;