(Experimental) Add Brooks pointers.
This feature is disabled by default.
Verified that the Brooks pointers are installed correctly by using the
CMS/SS collectors.
Change-Id: Ia9be9814ab6e29169ac85edc4792ce8c81d552a9
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index df8104d..478cc36 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -92,6 +92,38 @@
Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
}
+inline Object* Object::GetBrooksPointer() {
+#ifdef USE_BROOKS_POINTER
+ DCHECK(kUseBrooksPointer);
+ return GetFieldObject<Object, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Object, x_brooks_ptr_), false);
+#else
+ LOG(FATAL) << "Unreachable";
+ return nullptr;
+#endif
+}
+
+inline void Object::SetBrooksPointer(Object* brooks_pointer) {
+#ifdef USE_BROOKS_POINTER
+ DCHECK(kUseBrooksPointer);
+ // We don't mark the card as this occurs as part of object allocation. Not all objects have
+ // backing cards, such as large objects.
+ SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
+ OFFSET_OF_OBJECT_MEMBER(Object, x_brooks_ptr_), brooks_pointer, false);
+#else
+ LOG(FATAL) << "Unreachable";
+#endif
+}
+
+inline void Object::AssertSelfBrooksPointer() const {
+#ifdef USE_BROOKS_POINTER
+ DCHECK(kUseBrooksPointer);
+ Object* obj = const_cast<Object*>(this);
+ DCHECK_EQ(obj, obj->GetBrooksPointer());
+#else
+ LOG(FATAL) << "Unreachable";
+#endif
+}
+
template<VerifyObjectFlags kVerifyFlags>
inline bool Object::VerifierInstanceOf(Class* klass) {
DCHECK(klass != NULL);
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 7487dd2..ded4e0a 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -76,6 +76,10 @@
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
void SetClass(Class* new_klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ Object* GetBrooksPointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetBrooksPointer(Object* brooks_pointer) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void AssertSelfBrooksPointer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// The verifier treats all interfaces as java.lang.Object and relies on runtime checks in
// invoke-interface to detect incompatible interface types.
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -260,6 +264,14 @@
// Monitor and hash code information.
uint32_t monitor_;
+#ifdef USE_BROOKS_POINTER
+ // Note names use a 'x' prefix and the x_brooks_ptr_ is of type int
+ // instead of Object to go with the alphabetical/by-type field order
+ // on the Java side.
+ uint32_t x_brooks_ptr_; // For the Brooks pointer.
+ uint32_t x_padding_; // For 8-byte alignment. TODO: get rid of this.
+#endif
+
friend class art::ImageWriter;
friend class art::Monitor;
friend struct art::ObjectOffsets; // for verifying offset information