Simplify instance reference offsets.

Don't encode Object's class. Use trailing rather than leading zeroes to give
offset position.

Change-Id: I1ae74e7a01f63696429644adf81cdf6ee58832fe
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 3fcb188..6df7204 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -278,14 +278,15 @@
 }
 
 void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
-  if (new_reference_offsets != CLASS_WALK_SUPER) {
+  if (kIsDebugBuild && (new_reference_offsets != kClassWalkSuper)) {
     // Sanity check that the number of bits set in the reference offset bitmap
     // agrees with the number of references
-    size_t count = 0;
+    uint32_t count = 0;
     for (Class* c = this; c != nullptr; c = c->GetSuperClass()) {
       count += c->NumReferenceInstanceFieldsDuringLinking();
     }
-    CHECK_EQ((size_t)POPCOUNT(new_reference_offsets), count);
+    // +1 for the Class in Object.
+    CHECK_EQ(static_cast<uint32_t>(POPCOUNT(new_reference_offsets)) + 1, count);
   }
   // Not called within a transaction.
   SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 0acf695..2d49121 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -28,40 +28,6 @@
 #include "primitive.h"
 #include "read_barrier_option.h"
 
-/*
- * A magic value for refOffsets. Ignore the bits and walk the super
- * chain when this is the value.
- * [This is an unlikely "natural" value, since it would be 30 non-ref instance
- * fields followed by 2 ref instance fields.]
- */
-#define CLASS_WALK_SUPER 3U
-#define CLASS_BITS_PER_WORD (sizeof(uint32_t) * 8)
-#define CLASS_OFFSET_ALIGNMENT 4
-#define CLASS_HIGH_BIT (1U << (CLASS_BITS_PER_WORD - 1))
-/*
- * Given an offset, return the bit number which would encode that offset.
- * Local use only.
- */
-#define _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) \
-    ((unsigned int)(byteOffset) / \
-     CLASS_OFFSET_ALIGNMENT)
-/*
- * Is the given offset too large to be encoded?
- */
-#define CLASS_CAN_ENCODE_OFFSET(byteOffset) \
-    (_CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) < CLASS_BITS_PER_WORD)
-/*
- * Return a single bit, encoding the offset.
- * Undefined if the offset is too large, as defined above.
- */
-#define CLASS_BIT_FROM_OFFSET(byteOffset) \
-    (CLASS_HIGH_BIT >> _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset))
-/*
- * Return an offset, given a bit number as returned from CLZ.
- */
-#define CLASS_OFFSET_FROM_CLZ(rshift) \
-    MemberOffset((static_cast<int>(rshift) * CLASS_OFFSET_ALIGNMENT))
-
 namespace art {
 
 struct ClassOffsets;
@@ -81,6 +47,12 @@
 // C++ mirror of java.lang.Class
 class MANAGED Class FINAL : public Object {
  public:
+  // A magic value for reference_instance_offsets_. Ignore the bits and walk the super chain when
+  // this is the value.
+  // [This is an unlikely "natural" value, since it would be 30 non-ref instance fields followed by
+  // 2 ref instance fields.]
+  static constexpr uint32_t kClassWalkSuper = 0xC0000000;
+
   // Interface method table size. Increasing this value reduces the chance of two interface methods
   // colliding in the interface method table but increases the size of classes that implement
   // (non-marker) interfaces.
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 166ea9c..4d5f621 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -888,18 +888,18 @@
 
 template<bool kVisitClass, bool kIsStatic, typename Visitor>
 inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) {
-  if (!kIsStatic && LIKELY(ref_offsets != CLASS_WALK_SUPER)) {
-    if (!kVisitClass) {
-      // Mask out the class from the reference offsets.
-      ref_offsets ^= kWordHighBitMask;
+  if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) {
+    // Instance fields and not the slow-path.
+    if (kVisitClass) {
+      visitor(this, ClassOffset(), kIsStatic);
     }
-    DCHECK_EQ(ClassOffset().Uint32Value(), 0U);
-    // Found a reference offset bitmap. Visit the specified offsets.
+    uint32_t field_offset = mirror::kObjectHeaderSize;
     while (ref_offsets != 0) {
-      size_t right_shift = CLZ(ref_offsets);
-      MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
-      visitor(this, field_offset, kIsStatic);
-      ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
+      if ((ref_offsets & 1) != 0) {
+        visitor(this, MemberOffset(field_offset), kIsStatic);
+      }
+      ref_offsets >>= 1;
+      field_offset += sizeof(mirror::HeapReference<mirror::Object>);
     }
   } else {
     // There is no reference offset bitmap. In the non-static case, walk up the class
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index b68aef9..4ed96fc 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -17,6 +17,7 @@
 #ifndef ART_RUNTIME_MIRROR_OBJECT_H_
 #define ART_RUNTIME_MIRROR_OBJECT_H_
 
+#include "globals.h"
 #include "object_reference.h"
 #include "offsets.h"
 #include "verify_object.h"
@@ -60,6 +61,9 @@
 // Checks that we don't do field assignments which violate the typing system.
 static constexpr bool kCheckFieldAssignments = false;
 
+// Size of Object.
+static constexpr uint32_t kObjectHeaderSize = kUseBrooksReadBarrier ? 16 : 8;
+
 // C++ mirror of java.lang.Object
 class MANAGED LOCKABLE Object {
  public:
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 7fa664d..1aeba74 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -76,7 +76,8 @@
 
 // Keep constants in sync.
 TEST_F(ObjectTest, Constants) {
-  EXPECT_EQ(kObjectReferenceSize, sizeof(mirror::HeapReference<mirror::Object>));
+  EXPECT_EQ(kObjectReferenceSize, sizeof(HeapReference<Object>));
+  EXPECT_EQ(kObjectHeaderSize, sizeof(Object));
 }
 
 // Keep the assembly code constats in sync.