Revert "Revert "Fix an outstanding compaction bug in interpreter.""

Fixed the generic trampoline to not use ToJObject when unnecessary.

Bug: 15167269

This reverts commit 3bdb873122964da7937eb070cbcf2ef638a8e459.

Change-Id: I0525d0e0f3afb753c770e1572070a0fa22b02271
diff --git a/runtime/handle.h b/runtime/handle.h
index 3127864..b70f651 100644
--- a/runtime/handle.h
+++ b/runtime/handle.h
@@ -53,29 +53,48 @@
     reference_->Assign(reference);
     return old;
   }
-  jobject ToJObject() const ALWAYS_INLINE {
+  jobject ToJObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+    if (UNLIKELY(reference_->AsMirrorPtr() == nullptr)) {
+      // Special case so that we work with NullHandles.
+      return nullptr;
+    }
     return reinterpret_cast<jobject>(reference_);
   }
 
- private:
+ protected:
   StackReference<T>* reference_;
 
   template<typename S>
   explicit Handle(StackReference<S>* reference)
       : reference_(reinterpret_cast<StackReference<T>*>(reference)) {
   }
-
   template<typename S>
   explicit Handle(const Handle<S>& handle)
       : reference_(reinterpret_cast<StackReference<T>*>(handle.reference_)) {
   }
 
+  StackReference<T>* GetReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+    return reference_;
+  }
+
+ private:
+  friend class BuildGenericJniFrameVisitor;
   template<class S> friend class Handle;
   friend class HandleScope;
   template<class S> friend class HandleWrapper;
   template<size_t kNumReferences> friend class StackHandleScope;
 };
 
+template<class T>
+class NullHandle : public Handle<T> {
+ public:
+  NullHandle() : Handle<T>(&null_ref_) {
+  }
+
+ private:
+  StackReference<T> null_ref_;
+};
+
 }  // namespace art
 
 #endif  // ART_RUNTIME_HANDLE_H_