Move static field storage to end of Class instance

Change-Id: I90061999c9eef9d900e4269508b983a61f48b264
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 6379113..92cf4de 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -65,14 +65,14 @@
   CHECK(!init_done_);
 
   // java_lang_Class comes first, its needed for AllocClass
-  Class* java_lang_Class = down_cast<Class*>(Heap::AllocObject(NULL, sizeof(Class)));
+  Class* java_lang_Class = down_cast<Class*>(Heap::AllocObject(NULL, sizeof(ClassClass)));
   CHECK(java_lang_Class != NULL);
-  java_lang_Class->object_size_ = sizeof(Class);
+  java_lang_Class->class_size_ = sizeof(ClassClass);
   java_lang_Class->klass_ = java_lang_Class;
   // AllocClass(Class*) can now be used
 
   // java_lang_Object comes next so that object_array_class can be created
-  Class* java_lang_Object = AllocClass(java_lang_Class);
+  Class* java_lang_Object = AllocClass(java_lang_Class, sizeof(Class));
   CHECK(java_lang_Object != NULL);
   // backfill Object as the super class of Class
   java_lang_Class->super_class_ = java_lang_Object;
@@ -80,17 +80,17 @@
   java_lang_Object->primitive_type_ = Class::kPrimNot;
 
   // object_array_class is for root_classes to provide the storage for these classes
-  Class* object_array_class = AllocClass(java_lang_Class);
+  Class* object_array_class = AllocClass(java_lang_Class, sizeof(Class));
   CHECK(object_array_class != NULL);
   object_array_class->component_type_ = java_lang_Object;
 
   // String and char[] are necessary so that FindClass can assign names to members
-  Class* java_lang_String = AllocClass(java_lang_Class);
+  Class* java_lang_String = AllocClass(java_lang_Class, sizeof(StringClass));
   CHECK(java_lang_String != NULL);
   CHECK_LT(java_lang_String->object_size_, sizeof(String));
   java_lang_String->object_size_ = sizeof(String);
   String::SetClass(java_lang_String);
-  Class* char_array_class = AllocClass(java_lang_Class);
+  Class* char_array_class = AllocClass(java_lang_Class, sizeof(Class));
   CHECK(char_array_class != NULL);
   CharArray::SetArrayClass(char_array_class);
   // Now String::Alloc* can be used
@@ -102,23 +102,13 @@
   java_lang_String->descriptor_ = String::AllocFromModifiedUtf8("Ljava/lang/String;");
   char_array_class->descriptor_ = String::AllocFromModifiedUtf8("[C");
 
-  // int[] and long[] are used for static field storage
-  Class* int_array_class = AllocClass(java_lang_Class);
-  CHECK(int_array_class != NULL);
-  int_array_class->descriptor_ = String::AllocFromModifiedUtf8("[I");
-  IntArray::SetArrayClass(int_array_class);
-  Class* long_array_class = AllocClass(java_lang_Class);
-  CHECK(long_array_class != NULL);
-  long_array_class->descriptor_ = String::AllocFromModifiedUtf8("[J");
-  LongArray::SetArrayClass(long_array_class);
-
   // Field and Method are necessary so that FindClass can link members
-  Class* java_lang_reflect_Field = AllocClass(java_lang_Class);
+  Class* java_lang_reflect_Field = AllocClass(java_lang_Class, sizeof(FieldClass));
   CHECK(java_lang_reflect_Field != NULL);
   java_lang_reflect_Field->descriptor_ = String::AllocFromModifiedUtf8("Ljava/lang/reflect/Field;");
   CHECK_LT(java_lang_reflect_Field->object_size_, sizeof(Field));
   java_lang_reflect_Field->object_size_ = sizeof(Field);
-  Class* java_lang_reflect_Method = AllocClass(java_lang_Class);
+  Class* java_lang_reflect_Method = AllocClass(java_lang_Class, sizeof(MethodClass));
   java_lang_reflect_Method->descriptor_ = String::AllocFromModifiedUtf8("Ljava/lang/reflect/Method;");
   CHECK(java_lang_reflect_Method != NULL);
   CHECK_LT(java_lang_reflect_Method->object_size_, sizeof(Method));
@@ -131,8 +121,6 @@
   SetClassRoot(kObjectArrayClass, object_array_class);
   SetClassRoot(kJavaLangString, java_lang_String);
   SetClassRoot(kCharArrayClass, char_array_class);
-  SetClassRoot(kIntArrayClass, int_array_class);
-  SetClassRoot(kLongArrayClass, long_array_class);
   SetClassRoot(kJavaLangReflectField, java_lang_reflect_Field);
   SetClassRoot(kJavaLangReflectMethod, java_lang_reflect_Method);
   // now that these are registered, we can use AllocClass() and AllocObjectArray
@@ -225,10 +213,6 @@
   // run char[], int[] and long[] through FindClass to complete initialization
   Class* found_char_array_class = FindSystemClass("[C");
   CHECK_EQ(char_array_class, found_char_array_class);
-  Class* found_int_array_class = FindSystemClass("[I");
-  CHECK_EQ(int_array_class, found_int_array_class);
-  Class* found_long_array_class = FindSystemClass("[J");
-  CHECK_EQ(long_array_class, found_long_array_class);
 
   // Initialize all the other primitive array types for PrimitiveArray::Alloc.
   // These are easy because everything we need has already been set up.
@@ -236,11 +220,15 @@
   SetClassRoot(kByteArrayClass, FindSystemClass("[B"));
   SetClassRoot(kDoubleArrayClass, FindSystemClass("[D"));
   SetClassRoot(kFloatArrayClass, FindSystemClass("[F"));
+  SetClassRoot(kIntArrayClass, FindSystemClass("[I"));
+  SetClassRoot(kLongArrayClass, FindSystemClass("[J"));
   SetClassRoot(kShortArrayClass, FindSystemClass("[S"));
   BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
   ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
   DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
   FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
+  IntArray::SetArrayClass(GetClassRoot(kIntArrayClass));
+  LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
   ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
 
   FinishInit();
@@ -343,7 +331,7 @@
   FinishInit();
 }
 
-void ClassLinker::InitCallback(Object *obj, void *arg) {
+void ClassLinker::InitCallback(Object* obj, void *arg) {
   DCHECK(obj != NULL);
   DCHECK(arg != NULL);
   InitCallbackState* state = reinterpret_cast<InitCallbackState*>(arg);
@@ -410,12 +398,15 @@
   return dex_cache;
 }
 
-Class* ClassLinker::AllocClass(Class* java_lang_Class) {
-  return java_lang_Class->NewInstance()->AsClass();
+Class* ClassLinker::AllocClass(Class* java_lang_Class, size_t class_size) {
+  DCHECK_GE(class_size, sizeof(Class));
+  Class* klass = Heap::AllocObject(java_lang_Class, class_size)->AsClass();
+  klass->class_size_ = class_size;
+  return klass;
 }
 
-Class* ClassLinker::AllocClass() {
-  return AllocClass(GetClassRoot(kJavaLangClass));
+Class* ClassLinker::AllocClass(size_t class_size) {
+  return AllocClass(GetClassRoot(kJavaLangClass), class_size);
 }
 
 Field* ClassLinker::AllocField() {
@@ -476,10 +467,10 @@
       } else if (descriptor == "Ljava/lang/reflect/Method;") {
         klass = GetClassRoot(kJavaLangReflectMethod);
       } else {
-        klass = AllocClass();
+        klass = AllocClass(SizeOfClass(dex_file, dex_class_def));
       }
     } else {
-      klass = AllocClass();
+      klass = AllocClass(SizeOfClass(dex_file, dex_class_def));
     }
     klass->dex_cache_ = dex_cache;
     LoadClass(dex_file, dex_class_def, klass, class_loader);
@@ -542,6 +533,53 @@
   return klass;
 }
 
+// Precomputes size that will be needed for Class, matching LinkStaticFields
+size_t ClassLinker::SizeOfClass(const DexFile& dex_file,
+                                const DexFile::ClassDef& dex_class_def) {
+  const byte* class_data = dex_file.GetClassData(dex_class_def);
+  DexFile::ClassDataHeader header = dex_file.ReadClassDataHeader(&class_data);
+  size_t num_static_fields = header.static_fields_size_;
+  size_t num_ref = 0;
+  size_t num_32 = 0;
+  size_t num_64 = 0;
+  if (num_static_fields != 0) {
+    uint32_t last_idx = 0;
+    for (size_t i = 0; i < num_static_fields; ++i) {
+      DexFile::Field dex_field;
+      dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx);
+      const DexFile::FieldId& field_id = dex_file.GetFieldId(dex_field.field_idx_);
+      const char* descriptor = dex_file.dexStringByTypeIdx(field_id.type_idx_);
+      char c = descriptor[0];
+      if (c == 'L' || c == '[') {
+        num_ref++;
+      } else if (c == 'J' || c == 'D') {
+        num_64++;
+      } else {
+        num_32++;
+      }
+    }
+  }
+
+  // start with generic class data
+  size_t size = sizeof(Class);
+  // follow with reference fields which must be contiguous at start
+  size += (num_ref * sizeof(uint32_t));
+  // if there are 64-bit fields to add, make sure they are aligned
+  if (num_64 != 0 && size != RoundUp(size, 8)) { // for 64-bit alignment
+    if (num_32 != 0) {
+      // use an available 32-bit field for padding
+      num_32--;
+    }
+    size += sizeof(uint32_t);  // either way, we are adding a word
+    DCHECK_EQ(size, RoundUp(size, 8));
+  }
+  // tack on any 64-bit fields now that alignment is assured
+  size += (num_64 * sizeof(uint64_t));
+  // tack on any remaining 32-bit fields
+  size += (num_32 * sizeof(uint32_t));
+  return size;
+}
+
 void ClassLinker::LoadClass(const DexFile& dex_file,
                             const DexFile::ClassDef& dex_class_def,
                             Class* klass,
@@ -750,7 +788,7 @@
 }
 
 Class* ClassLinker::CreatePrimitiveClass(const char* descriptor) {
-  Class* klass = AllocClass();
+  Class* klass = AllocClass(sizeof(Class));
   CHECK(klass != NULL);
   klass->super_class_ = NULL;
   klass->access_flags_ = kAccPublic | kAccFinal | kAccAbstract;
@@ -849,14 +887,10 @@
       new_class = GetClassRoot(kObjectArrayClass);
     } else if (descriptor == "[C") {
       new_class = GetClassRoot(kCharArrayClass);
-    } else if (descriptor == "[I") {
-      new_class = GetClassRoot(kIntArrayClass);
-    } else if (descriptor == "[J") {
-      new_class = GetClassRoot(kLongArrayClass);
     }
   }
   if (new_class == NULL) {
-    new_class = AllocClass();
+    new_class = AllocClass(sizeof(Class));
     if (new_class == NULL) {
       return NULL;
     }
@@ -1205,6 +1239,7 @@
     return;
   }
   DexCache* dex_cache = klass->GetDexCache();
+  // TODO: this seems like the wrong check. do we really want !IsPrimitive && !IsArray?
   if (dex_cache == NULL) {
     return;
   }
@@ -1224,37 +1259,37 @@
     DexFile::ValueType type = dex_file.ReadEncodedValue(&addr, &value);
     switch (type) {
       case DexFile::kByte:
-        field->SetByte(value.b);
+        field->SetByte(NULL, value.b);
         break;
       case DexFile::kShort:
-        field->SetShort(value.s);
+        field->SetShort(NULL, value.s);
         break;
       case DexFile::kChar:
-        field->SetChar(value.c);
+        field->SetChar(NULL, value.c);
         break;
       case DexFile::kInt:
-        field->SetInt(value.i);
+        field->SetInt(NULL, value.i);
         break;
       case DexFile::kLong:
-        field->SetLong(value.j);
+        field->SetLong(NULL, value.j);
         break;
       case DexFile::kFloat:
-        field->SetFloat(value.f);
+        field->SetFloat(NULL, value.f);
         break;
       case DexFile::kDouble:
-        field->SetDouble(value.d);
+        field->SetDouble(NULL, value.d);
         break;
       case DexFile::kString: {
         uint32_t string_idx = value.i;
         String* resolved = ResolveString(klass, string_idx, dex_file);
-        field->SetObject(resolved);
+        field->SetObject(NULL, resolved);
         break;
       }
       case DexFile::kBoolean:
-        field->SetBoolean(value.z);
+        field->SetBoolean(NULL, value.z);
         break;
       case DexFile::kNull:
-        field->SetObject(value.l);
+        field->SetObject(NULL, value.l);
         break;
       default:
         LOG(FATAL) << "Unknown type " << static_cast<int>(type);
@@ -1270,13 +1305,14 @@
   if (!LinkMethods(klass)) {
     return false;
   }
-  if (!LinkStaticFields(klass)) {
-    return false;
-  }
   if (!LinkInstanceFields(klass)) {
     return false;
   }
-  CreateReferenceOffsets(klass);
+  if (!LinkStaticFields(klass)) {
+    return false;
+  }
+  CreateReferenceInstanceOffsets(klass);
+  CreateReferenceStaticOffsets(klass);
   CHECK_EQ(Class::kStatusLoaded, klass->status_);
   klass->status_ = Class::kStatusResolved;
   return true;
@@ -1557,68 +1593,61 @@
   }
 }
 
-// Each static field will be stored in one of three arrays: static_references_,
-// static_32bit_primitives_, or static_64bit_primitives_. This assigns each
-// field a slot in its array and create the arrays.
-bool ClassLinker::LinkStaticFields(Class* klass) {
-  size_t next_reference_slot = 0;
-  size_t next_32bit_primitive_slot = 0;
-  size_t next_64bit_primitive_slot = 0;
-
-  for (size_t i = 0; i < klass->NumStaticFields(); i++) {
-    Field* field = klass->GetStaticField(i);
-    char type = field->GetType();
-    if (type == '[' || type == 'L') {
-      field->offset_ = next_reference_slot++;
-    } else if (type == 'J' || type == 'D') {
-      field->offset_ = next_64bit_primitive_slot++;
-    } else {
-      field->offset_ = next_32bit_primitive_slot++;
-    }
-  }
-
-  if (next_reference_slot > 0) {
-    Class* array_class = GetClassRoot(kObjectArrayClass);
-    klass->static_references_ = ObjectArray<Object>::Alloc(array_class, next_reference_slot);
-  }
-  if (next_32bit_primitive_slot > 0) {
-    klass->static_32bit_primitives_ = IntArray::Alloc(next_32bit_primitive_slot);
-  }
-  if (next_64bit_primitive_slot > 0) {
-    klass->static_64bit_primitives_ = LongArray::Alloc(next_64bit_primitive_slot);
-  }
-
-  return true;
-}
-
 bool ClassLinker::LinkInstanceFields(Class* klass) {
-  int field_offset;
+  CHECK(klass != NULL);
+  size_t field_offset;
   if (klass->GetSuperClass() != NULL) {
     field_offset = klass->GetSuperClass()->object_size_;
   } else {
     field_offset = OFFSETOF_MEMBER(DataObject, fields_);
   }
+  return LinkFields(field_offset,
+                    klass->num_reference_instance_fields_,
+                    klass->NumInstanceFields(),
+                    klass->ifields_,
+                    klass->object_size_);
+}
+
+bool ClassLinker::LinkStaticFields(Class* klass) {
+  CHECK(klass != NULL);
+  size_t allocated_class_size = klass->class_size_;
+  size_t field_offset = OFFSETOF_MEMBER(Class, fields_);
+  bool success = LinkFields(field_offset,
+                            klass->num_reference_static_fields_,
+                            klass->NumStaticFields(),
+                            klass->sfields_,
+                            klass->class_size_);
+  CHECK_EQ(allocated_class_size, klass->class_size_);
+  return success;
+}
+
+bool ClassLinker::LinkFields(size_t field_offset,
+                             size_t& num_reference_fields,
+                             size_t num_fields,
+                             ObjectArray<Field>* fields,
+                             size_t& size) {
+  CHECK((num_fields == 0) == (fields == NULL));
   // Move references to the front.
-  klass->num_reference_instance_fields_ = 0;
+  num_reference_fields = 0;
   size_t i = 0;
-  for ( ; i < klass->NumInstanceFields(); i++) {
-    Field* pField = klass->GetInstanceField(i);
+  for ( ; i < num_fields; i++) {
+    Field* pField = fields->Get(i);
     char c = pField->GetType();
     if (c != '[' && c != 'L') {
-      for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
-        Field* refField = klass->GetInstanceField(j);
+      for (size_t j = num_fields - 1; j > i; j--) {
+        Field* refField = fields->Get(j);
         char rc = refField->GetType();
         if (rc == '[' || rc == 'L') {
-          klass->SetInstanceField(i, refField);
-          klass->SetInstanceField(j, pField);
+          fields->Set(i, refField);
+          fields->Set(j, pField);
           pField = refField;
           c = rc;
-          klass->num_reference_instance_fields_++;
+          num_reference_fields++;
           break;
         }
       }
     } else {
-      klass->num_reference_instance_fields_++;
+      num_reference_fields++;
     }
     if (c != '[' && c != 'L') {
       break;
@@ -1630,8 +1659,8 @@
   // Now we want to pack all of the double-wide fields together.  If
   // we're not aligned, though, we want to shuffle one 32-bit field
   // into place.  If we can't find one, we'll have to pad it.
-  if (i != klass->NumInstanceFields() && (field_offset & 0x04) != 0) {
-    Field* pField = klass->GetInstanceField(i);
+  if (i != num_fields && (field_offset & 0x04) != 0) {
+    Field* pField = fields->Get(i);
     char c = pField->GetType();
 
     if (c != 'J' && c != 'D') {
@@ -1645,12 +1674,12 @@
       // Next field is 64-bit, so search for a 32-bit field we can
       // swap into it.
       bool found = false;
-      for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
-        Field* singleField = klass->GetInstanceField(j);
+      for (size_t j = num_fields - 1; j > i; j--) {
+        Field* singleField = fields->Get(j);
         char rc = singleField->GetType();
         if (rc != 'J' && rc != 'D') {
-          klass->SetInstanceField(i, singleField);
-          klass->SetInstanceField(j, pField);
+          fields->Set(i, singleField);
+          fields->Set(j, pField);
           pField = singleField;
           pField->SetOffset(field_offset);
           field_offset += sizeof(uint32_t);
@@ -1667,17 +1696,17 @@
 
   // Alignment is good, shuffle any double-wide fields forward, and
   // finish assigning field offsets to all fields.
-  DCHECK(i == klass->NumInstanceFields() || (field_offset & 0x04) == 0);
-  for ( ; i < klass->NumInstanceFields(); i++) {
-    Field* pField = klass->GetInstanceField(i);
+  DCHECK(i == num_fields || (field_offset & 0x04) == 0);
+  for ( ; i < num_fields; i++) {
+    Field* pField = fields->Get(i);
     char c = pField->GetType();
     if (c != 'D' && c != 'J') {
-      for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
-        Field* doubleField = klass->GetInstanceField(j);
+      for (size_t j = num_fields - 1; j > i; j--) {
+        Field* doubleField = fields->Get(j);
         char rc = doubleField->GetType();
         if (rc == 'D' || rc == 'J') {
-          klass->SetInstanceField(i, doubleField);
-          klass->SetInstanceField(j, pField);
+          fields->Set(i, doubleField);
+          fields->Set(j, pField);
           pField = doubleField;
           c = rc;
           break;
@@ -1689,16 +1718,17 @@
 
     pField->SetOffset(field_offset);
     field_offset += sizeof(uint32_t);
-    if (c == 'J' || c == 'D')
+    if (c == 'J' || c == 'D') {
       field_offset += sizeof(uint32_t);
+    }
   }
 
 #ifndef NDEBUG
   // Make sure that all reference fields appear before
   // non-reference fields, and all double-wide fields are aligned.
   bool seen_non_ref = false;
-  for (i = 0; i < klass->NumInstanceFields(); i++) {
-    Field *pField = klass->GetInstanceField(i);
+  for (i = 0; i < num_fields; i++) {
+    Field *pField = fields->Get(i);
     char c = pField->GetType();
 
     if (c == 'D' || c == 'J') {
@@ -1708,50 +1738,64 @@
     if (c != '[' && c != 'L') {
       if (!seen_non_ref) {
         seen_non_ref = true;
-        DCHECK_EQ(klass->NumReferenceInstanceFields(), i);
+        DCHECK_EQ(num_reference_fields, i);
       }
     } else {
       DCHECK(!seen_non_ref);
     }
   }
   if (!seen_non_ref) {
-    DCHECK_EQ(klass->NumInstanceFields(), klass->NumReferenceInstanceFields());
+    DCHECK_EQ(num_fields, num_reference_fields);
   }
 #endif
-  klass->object_size_ = field_offset;
+  size = field_offset;
   return true;
 }
 
 //  Set the bitmap of reference offsets, refOffsets, from the ifields
 //  list.
-void ClassLinker::CreateReferenceOffsets(Class* klass) {
-  uint32_t reference_offsets = 0;
+void ClassLinker::CreateReferenceInstanceOffsets(Class* klass) {
+  klass->reference_instance_offsets_ = 0;
   if (klass->HasSuperClass()) {
-    reference_offsets = klass->GetSuperClass()->GetReferenceOffsets();
-  }
-  // If our superclass overflowed, we don't stand a chance.
-  if (reference_offsets != CLASS_WALK_SUPER) {
-    // All of the fields that contain object references are guaranteed
-    // to be at the beginning of the ifields list.
-    for (size_t i = 0; i < klass->NumReferenceInstanceFields(); ++i) {
-      // Note that, per the comment on struct InstField, f->byteOffset
-      // is the offset from the beginning of obj, not the offset into
-      // obj->instanceData.
-      const Field* field = klass->GetInstanceField(i);
-      size_t byte_offset = field->GetOffset();
-      CHECK_GE(byte_offset, CLASS_SMALLEST_OFFSET);
-      CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
-      if (CLASS_CAN_ENCODE_OFFSET(byte_offset)) {
-        uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset);
-        CHECK_NE(new_bit, 0U);
-        reference_offsets |= new_bit;
-      } else {
-        reference_offsets = CLASS_WALK_SUPER;
-        break;
-      }
+    klass->reference_instance_offsets_ = klass->GetSuperClass()->GetReferenceInstanceOffsets();
+    // If our superclass overflowed, we don't stand a chance.
+    if (klass->reference_instance_offsets_ == CLASS_WALK_SUPER) {
+      return;
     }
   }
-  klass->SetReferenceOffsets(reference_offsets);
+  CreateReferenceOffsets(klass->reference_instance_offsets_,
+                         klass->NumReferenceInstanceFields(),
+                         klass->ifields_);
+}
+
+void ClassLinker::CreateReferenceStaticOffsets(Class* klass) {
+  klass->reference_static_offsets_ = 0;
+  CreateReferenceOffsets(klass->reference_static_offsets_,
+                         klass->NumReferenceStaticFields(),
+                         klass->sfields_);
+}
+
+void ClassLinker::CreateReferenceOffsets(uint32_t& reference_offsets,
+                                         size_t num_reference_fields,
+                                         const ObjectArray<Field>* fields) {
+  // All of the fields that contain object references are guaranteed
+  // to be at the beginning of the fields list.
+  for (size_t i = 0; i < num_reference_fields; ++i) {
+    // Note that byte_offset is the offset from the beginning of
+    // object, not the offset into instance data
+    const Field* field = fields->Get(i);
+    size_t byte_offset = field->GetOffset();
+    CHECK_GE(byte_offset, CLASS_SMALLEST_OFFSET);
+    CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
+    if (CLASS_CAN_ENCODE_OFFSET(byte_offset)) {
+      uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset);
+      CHECK_NE(new_bit, 0U);
+      reference_offsets |= new_bit;
+    } else {
+      reference_offsets = CLASS_WALK_SUPER;
+      break;
+    }
+  }
 }
 
 Class* ClassLinker::ResolveClass(const Class* referrer,