Use accessor methods for Object fields.

Ensure that Object fields are modified via accessors so that it's easy
to insert barriers (make all fields within Objects private). Add validity
checks to Field and Method accessors to ensure they are accessed when a
Class is in a suitable state. Add validity checks to all Object
accessors to check heap isn't corrupted. Remove hacked in strings from Field
and Method; make type fields used the dex cache that is lazily initialized.
Clean up various other TODOs and lint issues.

Change-Id: Iac0afc515c01f5419874d9cdcdb9a7b45443e3fb
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index a34f180..6f894e3 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -2,6 +2,8 @@
 
 #include "class_linker.h"
 
+#include <string>
+
 #include "UniquePtr.h"
 #include "common_test.h"
 #include "dex_cache.h"
@@ -35,14 +37,13 @@
     EXPECT_TRUE(primitive->GetSuperClass() == NULL);
     EXPECT_FALSE(primitive->HasSuperClass());
     EXPECT_TRUE(primitive->GetClassLoader() == NULL);
-    EXPECT_TRUE(primitive->GetComponentType() == NULL);
     EXPECT_TRUE(primitive->GetStatus() == Class::kStatusInitialized);
     EXPECT_FALSE(primitive->IsErroneous());
     EXPECT_TRUE(primitive->IsVerified());
     EXPECT_TRUE(primitive->IsLinked());
     EXPECT_FALSE(primitive->IsArrayInstance());
     EXPECT_FALSE(primitive->IsArrayClass());
-    EXPECT_EQ(0, primitive->array_rank_);
+    EXPECT_EQ(0, primitive->GetArrayRank());
     EXPECT_FALSE(primitive->IsInterface());
     EXPECT_TRUE(primitive->IsPublic());
     EXPECT_TRUE(primitive->IsFinal());
@@ -60,7 +61,7 @@
                         const StringPiece& component_type,
                         const ClassLoader* class_loader) {
     Class* array = class_linker_->FindClass(array_descriptor, class_loader);
-    EXPECT_EQ(array_rank, array->array_rank_);
+    EXPECT_EQ(array_rank, array->GetArrayRank());
     EXPECT_TRUE(array->GetComponentType()->GetDescriptor()->Equals(component_type));
     EXPECT_EQ(class_loader, array->GetClassLoader());
     AssertArrayClass(array_descriptor, array);
@@ -83,7 +84,7 @@
     EXPECT_TRUE(array->IsLinked());
     EXPECT_FALSE(array->IsArrayInstance());
     EXPECT_TRUE(array->IsArrayClass());
-    EXPECT_LE(1, array->array_rank_);
+    EXPECT_LE(1, array->GetArrayRank());
     EXPECT_FALSE(array->IsInterface());
     EXPECT_EQ(array->GetComponentType()->IsPublic(), array->IsPublic());
     EXPECT_TRUE(array->IsFinal());
@@ -101,49 +102,49 @@
     EXPECT_TRUE(method->GetName() != NULL);
     EXPECT_TRUE(method->GetSignature() != NULL);
 
-    EXPECT_TRUE(method->dex_cache_strings_ != NULL);
-    EXPECT_TRUE(method->dex_cache_resolved_types_ != NULL);
-    EXPECT_TRUE(method->dex_cache_resolved_methods_ != NULL);
-    EXPECT_TRUE(method->dex_cache_resolved_fields_ != NULL);
-    EXPECT_TRUE(method->dex_cache_code_and_direct_methods_ != NULL);
-    EXPECT_TRUE(method->dex_cache_initialized_static_storage_ != NULL);
-    EXPECT_EQ(method->declaring_class_->dex_cache_->GetStrings(),
-              method->dex_cache_strings_);
-    EXPECT_EQ(method->declaring_class_->dex_cache_->GetResolvedTypes(),
-              method->dex_cache_resolved_types_);
-    EXPECT_EQ(method->declaring_class_->dex_cache_->GetResolvedMethods(),
-              method->dex_cache_resolved_methods_);
-    EXPECT_EQ(method->declaring_class_->dex_cache_->GetResolvedFields(),
-              method->dex_cache_resolved_fields_);
-    EXPECT_EQ(method->declaring_class_->dex_cache_->GetCodeAndDirectMethods(),
-              method->dex_cache_code_and_direct_methods_);
-    EXPECT_EQ(method->declaring_class_->dex_cache_->GetInitializedStaticStorage(),
-              method->dex_cache_initialized_static_storage_);
+    EXPECT_TRUE(method->GetDexCacheStrings() != NULL);
+    EXPECT_TRUE(method->GetDexCacheResolvedTypes() != NULL);
+    EXPECT_TRUE(method->GetDexCacheResolvedMethods() != NULL);
+    EXPECT_TRUE(method->GetDexCacheResolvedFields() != NULL);
+    EXPECT_TRUE(method->GetDexCacheCodeAndDirectMethods() != NULL);
+    EXPECT_TRUE(method->GetDexCacheInitializedStaticStorage() != NULL);
+    EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetStrings(),
+              method->GetDexCacheStrings());
+    EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetResolvedTypes(),
+              method->GetDexCacheResolvedTypes());
+    EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetResolvedMethods(),
+              method->GetDexCacheResolvedMethods());
+    EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetResolvedFields(),
+              method->GetDexCacheResolvedFields());
+    EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetCodeAndDirectMethods(),
+              method->GetDexCacheCodeAndDirectMethods());
+    EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetInitializedStaticStorage(),
+              method->GetDexCacheInitializedStaticStorage());
   }
 
   void AssertField(Class* klass, Field* field) {
     EXPECT_TRUE(field != NULL);
     EXPECT_EQ(klass, field->GetDeclaringClass());
     EXPECT_TRUE(field->GetName() != NULL);
-    EXPECT_TRUE(field->GetDescriptor() != NULL);
+    EXPECT_TRUE(field->GetType() != NULL);
   }
 
   void AssertClass(const StringPiece& descriptor, Class* klass) {
     EXPECT_TRUE(klass->GetDescriptor()->Equals(descriptor));
-    if (klass->descriptor_->Equals(String::AllocFromModifiedUtf8("Ljava/lang/Object;"))) {
+    if (klass->GetDescriptor()->Equals(String::AllocFromModifiedUtf8("Ljava/lang/Object;"))) {
       EXPECT_FALSE(klass->HasSuperClass());
     } else {
       EXPECT_TRUE(klass->HasSuperClass());
       EXPECT_TRUE(klass->GetSuperClass() != NULL);
     }
     EXPECT_TRUE(klass->GetDexCache() != NULL);
-    EXPECT_TRUE(klass->GetComponentType() == NULL);
-    EXPECT_TRUE(klass->GetComponentType() == NULL);
     EXPECT_EQ(Class::kStatusResolved, klass->GetStatus());
     EXPECT_FALSE(klass->IsErroneous());
     EXPECT_FALSE(klass->IsVerified());
     EXPECT_TRUE(klass->IsLinked());
     EXPECT_TRUE(klass->IsLoaded());
+    EXPECT_FALSE(klass->IsArrayClass());
+    EXPECT_EQ(0, klass->GetArrayRank());
     EXPECT_TRUE(klass->IsInSamePackage(klass));
     EXPECT_TRUE(Class::IsInSamePackage(klass->GetDescriptor(), klass->GetDescriptor()));
     if (klass->IsInterface()) {
@@ -206,15 +207,13 @@
     EXPECT_GE(klass->NumInstanceFields(), klass->NumReferenceInstanceFields());
     for (size_t i = 0; i < klass->NumReferenceInstanceFields(); i++) {
       Field* field = klass->GetInstanceField(i);
-      Class* field_type = class_linker_->FindClass(field->GetDescriptor(),
-                                                   klass->GetClassLoader());
+      Class* field_type = field->GetType();
       ASSERT_TRUE(field_type != NULL);
-      EXPECT_FALSE(field_type->IsPrimitive());
+      ASSERT_TRUE(!field_type->IsPrimitive());
     }
     for (size_t i = klass->NumReferenceInstanceFields(); i < klass->NumInstanceFields(); i++) {
       Field* field = klass->GetInstanceField(i);
-      Class* field_type = class_linker_->FindClass(field->GetDescriptor(),
-                                                   klass->GetClassLoader());
+      Class* field_type = field->GetType();
       ASSERT_TRUE(field_type != NULL);
       EXPECT_TRUE(field_type->IsPrimitive());
     }
@@ -310,13 +309,12 @@
   EXPECT_TRUE(JavaLangObject->GetSuperClass() == NULL);
   EXPECT_FALSE(JavaLangObject->HasSuperClass());
   EXPECT_TRUE(JavaLangObject->GetClassLoader() == NULL);
-  EXPECT_TRUE(JavaLangObject->GetComponentType() == NULL);
   EXPECT_FALSE(JavaLangObject->IsErroneous());
   EXPECT_FALSE(JavaLangObject->IsVerified());
   EXPECT_TRUE(JavaLangObject->IsLinked());
   EXPECT_FALSE(JavaLangObject->IsArrayInstance());
   EXPECT_FALSE(JavaLangObject->IsArrayClass());
-  EXPECT_EQ(0, JavaLangObject->array_rank_);
+  EXPECT_EQ(0, JavaLangObject->GetArrayRank());
   EXPECT_FALSE(JavaLangObject->IsInterface());
   EXPECT_TRUE(JavaLangObject->IsPublic());
   EXPECT_FALSE(JavaLangObject->IsFinal());
@@ -340,14 +338,13 @@
   EXPECT_TRUE(MyClass->GetSuperClass() == JavaLangObject);
   EXPECT_TRUE(MyClass->HasSuperClass());
   EXPECT_EQ(class_loader, MyClass->GetClassLoader());
-  EXPECT_TRUE(MyClass->GetComponentType() == NULL);
   EXPECT_TRUE(MyClass->GetStatus() == Class::kStatusResolved);
   EXPECT_FALSE(MyClass->IsErroneous());
   EXPECT_FALSE(MyClass->IsVerified());
   EXPECT_TRUE(MyClass->IsLinked());
   EXPECT_FALSE(MyClass->IsArrayInstance());
   EXPECT_FALSE(MyClass->IsArrayClass());
-  EXPECT_EQ(0, JavaLangObject->array_rank_);
+  EXPECT_EQ(0, JavaLangObject->GetArrayRank());
   EXPECT_FALSE(MyClass->IsInterface());
   EXPECT_FALSE(MyClass->IsPublic());
   EXPECT_FALSE(MyClass->IsFinal());
@@ -394,6 +391,13 @@
   EXPECT_TRUE(throwable->GetInstanceField(3)->GetName()->Equals("stackTrace"));
   EXPECT_TRUE(throwable->GetInstanceField(4)->GetName()->Equals("suppressedExceptions"));
 
+  Class* stack_trace_element = class_linker_->FindSystemClass( "Ljava/lang/StackTraceElement;");
+  ASSERT_EQ(4U, stack_trace_element->NumInstanceFields());
+  EXPECT_TRUE(stack_trace_element->GetInstanceField(0)->GetName()->Equals("declaringClass"));
+  EXPECT_TRUE(stack_trace_element->GetInstanceField(1)->GetName()->Equals("fileName"));
+  EXPECT_TRUE(stack_trace_element->GetInstanceField(2)->GetName()->Equals("methodName"));
+  EXPECT_TRUE(stack_trace_element->GetInstanceField(3)->GetName()->Equals("lineNumber"));
+
   Class* accessible_object = class_linker_->FindSystemClass("Ljava/lang/reflect/AccessibleObject;");
   ASSERT_EQ(1U, accessible_object->NumInstanceFields());
   EXPECT_TRUE(accessible_object->GetInstanceField(0)->GetName()->Equals("flag"));
@@ -438,7 +442,8 @@
   Class* array_class = class_linker_->FindSystemClass("[Ljava/lang/String;");
   ObjectArray<String>* array = ObjectArray<String>::Alloc(array_class, 0);
   uint32_t array_offset = reinterpret_cast<uint32_t>(array);
-  uint32_t data_offset = reinterpret_cast<uint32_t>(array->GetData());
+  uint32_t data_offset =
+      array_offset + ObjectArray<String>::DataOffset().Uint32Value();
   EXPECT_EQ(16U, data_offset - array_offset);
 }
 
@@ -471,54 +476,54 @@
 
   EXPECT_EQ(10U, statics->NumStaticFields());
 
-  Field* s0 = statics->FindStaticField("s0", "Z");
-  EXPECT_TRUE(s0->GetClass()->descriptor_->Equals("Ljava/lang/reflect/Field;"));
-  EXPECT_EQ('Z', s0->GetType());
+  Field* s0 = statics->FindStaticField("s0", class_linker_->FindClass("Z", class_loader));
+  EXPECT_TRUE(s0->GetClass()->GetDescriptor()->Equals("Ljava/lang/reflect/Field;"));
+  EXPECT_TRUE(s0->GetType()->IsPrimitiveBoolean());
   // EXPECT_EQ(true, s0->GetBoolean(NULL)); // TODO: needs clinit to be run?
   s0->SetBoolean(NULL, false);
 
-  Field* s1 = statics->FindStaticField("s1", "B");
-  EXPECT_EQ('B', s1->GetType());
+  Field* s1 = statics->FindStaticField("s1", class_linker_->FindClass("B", class_loader));
+  EXPECT_TRUE(s1->GetType()->IsPrimitiveByte());
   // EXPECT_EQ(5, s1->GetByte(NULL));  // TODO: needs clinit to be run?
   s1->SetByte(NULL, 6);
 
-  Field* s2 = statics->FindStaticField("s2", "C");
-  EXPECT_EQ('C', s2->GetType());
+  Field* s2 = statics->FindStaticField("s2", class_linker_->FindClass("C", class_loader));
+  EXPECT_TRUE(s2->GetType()->IsPrimitiveChar());
   // EXPECT_EQ('a', s2->GetChar(NULL));  // TODO: needs clinit to be run?
   s2->SetChar(NULL, 'b');
 
-  Field* s3 = statics->FindStaticField("s3", "S");
-  EXPECT_EQ('S', s3->GetType());
+  Field* s3 = statics->FindStaticField("s3", class_linker_->FindClass("S", class_loader));
+  EXPECT_TRUE(s3->GetType()->IsPrimitiveShort());
   // EXPECT_EQ(65000, s3->GetShort(NULL));  // TODO: needs clinit to be run?
   s3->SetShort(NULL, 65001);
 
-  Field* s4 = statics->FindStaticField("s4", "I");
-  EXPECT_EQ('I', s4->GetType());
+  Field* s4 = statics->FindStaticField("s4", class_linker_->FindClass("I", class_loader));
+  EXPECT_TRUE(s4->GetType()->IsPrimitiveInt());
   // EXPECT_EQ(2000000000, s4->GetInt(NULL));  // TODO: needs clinit to be run?
   s4->SetInt(NULL, 2000000001);
 
-  Field* s5 = statics->FindStaticField("s5", "J");
-  EXPECT_EQ('J', s5->GetType());
+  Field* s5 = statics->FindStaticField("s5", class_linker_->FindClass("J", class_loader));
+  EXPECT_TRUE(s5->GetType()->IsPrimitiveLong());
   // EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong(NULL));  // TODO: needs clinit to be run?
   s5->SetLong(NULL, 0x34567890abcdef12LL);
 
-  Field* s6 = statics->FindStaticField("s6", "F");
-  EXPECT_EQ('F', s6->GetType());
+  Field* s6 = statics->FindStaticField("s6", class_linker_->FindClass("F", class_loader));
+  EXPECT_TRUE(s6->GetType()->IsPrimitiveFloat());
   // EXPECT_EQ(0.5, s6->GetFloat(NULL));  // TODO: needs clinit to be run?
   s6->SetFloat(NULL, 0.75);
 
-  Field* s7 = statics->FindStaticField("s7", "D");
-  EXPECT_EQ('D', s7->GetType());
+  Field* s7 = statics->FindStaticField("s7", class_linker_->FindClass("D", class_loader));
+  EXPECT_TRUE(s7->GetType()->IsPrimitiveDouble());
   // EXPECT_EQ(16777217, s7->GetDouble(NULL));  // TODO: needs clinit to be run?
   s7->SetDouble(NULL, 16777219);
 
-  Field* s8 = statics->FindStaticField("s8", "Ljava/lang/Object;");
-  EXPECT_EQ('L', s8->GetType());
+  Field* s8 = statics->FindStaticField("s8", class_linker_->FindClass("Ljava/lang/Object;", class_loader));
+  EXPECT_FALSE(s8->GetType()->IsPrimitive());
   // EXPECT_TRUE(s8->GetObject(NULL)->AsString()->Equals("android"));  // TODO: needs clinit to be run?
   s8->SetObject(NULL, String::AllocFromModifiedUtf8("robot"));
 
-  Field* s9 = statics->FindStaticField("s9", "[Ljava/lang/Object;");
-  EXPECT_EQ('[', s9->GetType());
+  Field* s9 = statics->FindStaticField("s9", class_linker_->FindClass("[Ljava/lang/Object;", class_loader));
+  EXPECT_TRUE(s9->GetType()->IsArrayClass());
   // EXPECT_EQ(NULL, s9->GetObject(NULL));  // TODO: needs clinit to be run?
   s9->SetObject(NULL, NULL);