Create templates for primitive types.

In preparation to move static fields into their own array
members off of class.

Change-Id: Ic524e12952af985d8ae16a05b5f4e50676a9c136
diff --git a/src/class_linker.cc b/src/class_linker.cc
index e1dcbf8..89c96b4 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -464,7 +464,7 @@
                             Field* dst) {
   const DexFile::FieldId& field_id = dex_file.GetFieldId(src.field_idx_);
   dst->klass_ = klass;
-  dst->java_name_ = ResolveString(klass, field_id.name_idx_, dex_file);
+  dst->name_ = ResolveString(klass, field_id.name_idx_, dex_file);
   dst->descriptor_.set(dex_file.dexStringByTypeIdx(field_id.type_idx_));
   dst->access_flags_ = src.access_flags_;
 }
@@ -475,7 +475,7 @@
                              Method* dst) {
   const DexFile::MethodId& method_id = dex_file.GetMethodId(src.method_idx_);
   dst->klass_ = klass;
-  dst->java_name_ = ResolveString(klass, method_id.name_idx_, dex_file);
+  dst->name_ = ResolveString(klass, method_id.name_idx_, dex_file);
   {
     int32_t utf16_length;
     scoped_ptr<char> utf8(dex_file.CreateMethodDescriptor(method_id.proto_idx_,
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 5951c0b..5e48921 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -143,11 +143,13 @@
     for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
       InstanceField* field = klass->GetInstanceField(i);
       EXPECT_TRUE(field != NULL);
+      EXPECT_FALSE(field->IsStatic());
     }
 
     for (size_t i = 0; i < klass->NumStaticFields(); i++) {
       StaticField* field = klass->GetStaticField(i);
       EXPECT_TRUE(field != NULL);
+      EXPECT_TRUE(field->IsStatic());
     }
 
     // Confirm that all instances fields are packed together at the start
@@ -368,4 +370,4 @@
   EXPECT_NE(MyClass_1, MyClass_2);
 }
 
-}  // namespace art
+}// namespace art
diff --git a/src/object.h b/src/object.h
index 33db15e..6871dfb 100644
--- a/src/object.h
+++ b/src/object.h
@@ -25,7 +25,11 @@
 class Object;
 class String;
 template<class T> class ObjectArray;
+template<class T> class PrimitiveArray;
 class StaticField;
+typedef PrimitiveArray<uint16_t> CharArray;
+typedef PrimitiveArray<uint32_t> IntArray;
+typedef PrimitiveArray<uint64_t> LongArray;
 
 union JValue {
   uint8_t z;
@@ -258,7 +262,11 @@
   }
 
   const String* GetName() const {
-    return java_name_;
+    return name_;
+  }
+
+  bool IsStatic() const {
+    return (access_flags_ & kAccStatic) != 0;
   }
 
   char GetType() const {  // TODO: return type
@@ -275,15 +283,13 @@
   Class* java_declaring_class_;
   Object* java_generic_type_;
   uint32_t java_generic_types_are_initialized_;
-  String* java_name_;
+  String* name_;
   uint32_t java_slot_;
   Class* java_type_;
 
   // The class in which this field is declared.
   Class* declaring_class_;
 
-  StringPiece name_;
-
   // e.g. "I", "[C", "Landroid/os/Debug;"
   StringPiece descriptor_;
 
@@ -380,7 +386,7 @@
  public:
   // Returns the method name, e.g. "<init>" or "eatLunch"
   const String* GetName() const {
-    return java_name_;
+    return name_;
   }
 
   const String* GetDescriptor() const {
@@ -447,7 +453,7 @@
   Object* java_generic_parameter_types_;
   Object* java_generic_return_type_;
   Class* java_return_type_;
-  String* java_name_;
+  String* name_;
   ObjectArray<Class>* java_parameter_types_;
   uint32_t java_generic_types_are_initialized_;
   uint32_t java_slot_;
@@ -544,9 +550,6 @@
   uint16_t num_outs_;
   uint16_t num_ins_;
 
-  // method name, e.g. "<init>" or "eatLunch"
-  StringPiece name_;
-
   // The method descriptor.  This represents the parameters a method
   // takes and value it returns.  This string is a list of the type
   // descriptors for the parameters enclosed in parenthesis followed
@@ -596,18 +599,10 @@
   void SetLength(uint32_t length) {
     length_ = length;
   }
-  const void* GetData() const {
-    return &elements_;
-  }
-  void* GetData() {
-    return &elements_;
-  }
 
  private:
   // The number of array elements.
   uint32_t length_;
-  // Location of first element.
-  uint32_t elements_[0];
   Array();
 };
 
@@ -621,15 +616,19 @@
                                                    sizeof(uint32_t)));
   }
 
+  T* const * GetData() const {
+    return reinterpret_cast<T* const *>(&elements_);
+  }
+  T** GetData() {
+    return reinterpret_cast<T**>(&elements_);
+  }
   T* Get(uint32_t i) const {
     CHECK_LT(i, GetLength());
-    Object* const * data = reinterpret_cast<Object* const *>(GetData());
-    return down_cast<T*>(data[i]);
+    return GetData()[i];
   }
   void Set(uint32_t i, T* object) {
     CHECK_LT(i, GetLength());
-    T** data = reinterpret_cast<T**>(GetData());
-    data[i] = object;
+    GetData()[i] = object;
   }
   static void Copy(ObjectArray<T>* src, int src_pos, ObjectArray<T>* dst, int dst_pos, size_t length) {
     for (size_t i = 0; i < length; i++) {
@@ -644,6 +643,8 @@
 
  private:
   ObjectArray();
+  // Location of first element.
+  T* elements_[0];
 };
 
 // ClassLoader objects.
@@ -1055,6 +1056,10 @@
   // source file name, if known.  Otherwise, NULL.
   const char* source_file_;
 
+  ObjectArray<Object>* static_references_;
+  IntArray* static_32bit_primitives_;
+  LongArray* static_64bit_primitives_;
+
   // Static fields
   ObjectArray<StaticField>* sfields_;
 
@@ -1075,34 +1080,37 @@
   DataObject();
 };
 
-class CharArray : public Array {
+template<class T>
+class PrimitiveArray : public Array {
  public:
-  static CharArray* Alloc(Class* char_array_class, size_t length) {
-    return down_cast<CharArray*>(Array::Alloc(char_array_class,
-                                              length,
-                                              sizeof(uint16_t)));
+  static PrimitiveArray<T>* Alloc(Class* element_class, size_t length) {
+    return down_cast<PrimitiveArray<T>*>(Array::Alloc(element_class,
+                                         length,
+                                         sizeof(T)));
   }
 
-  uint16_t* GetChars() {
-    return reinterpret_cast<uint16_t*>(GetData());
+  const T* GetData() const {
+    return reinterpret_cast<const T*>(&elements_);
   }
 
-  const uint16_t* GetChars() const {
-    return reinterpret_cast<const uint16_t*>(GetData());
+  T* GetData() {
+    return reinterpret_cast<T*>(&elements_);
   }
 
-  uint16_t GetChar(uint32_t i) const {
+  T Get(T i) const {
     CHECK_LT(i, GetLength());
-    return GetChars()[i];
+    return GetData()[i];
   }
 
-  void SetChar(uint32_t i, uint16_t ch) {
+  void Set(uint32_t i, T value) {
     CHECK_LT(i, GetLength());
-    GetChars()[i] = ch;
+    GetData()[i] = value;
   }
 
  private:
-  CharArray();
+  PrimitiveArray();
+  // Location of first element.
+  T elements_[0];
 };
 
 class String : public Object {
@@ -1126,19 +1134,18 @@
   }
 
   uint16_t CharAt(int32_t index) const {
-    return GetCharArray()->GetChar(index + GetOffset());
+    return GetCharArray()->Get(index + GetOffset());
   }
 
   static String* AllocFromUtf16(int32_t utf16_length,
                                 uint16_t* utf16_data_in,
                                 int32_t hash_code) {
     String* string = Alloc(GetJavaLangString(), GetCharArrayClass(), utf16_length);
-    uint16_t* utf16_data_out = string->array_->GetChars();
     // TODO use 16-bit wide memset variant
     for (int i = 0; i < utf16_length; i++ ) {
-        utf16_data_out[i] = utf16_data_in[i];
+        string->array_->Set(i, utf16_data_in[i]);
     }
-    string->hash_code_ = hash_code;
+    string->ComputeHashCode();
     return string;
   }
 
@@ -1147,9 +1154,9 @@
                                        int32_t utf16_length,
                                        const char* utf8_data_in) {
     String* string = Alloc(java_lang_String, char_array, utf16_length);
-    uint16_t* utf16_data_out = string->array_->GetChars();
+    uint16_t* utf16_data_out = string->array_->GetData();
     ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
-    string->hash_code_ = ComputeUtf16Hash(utf16_data_out, utf16_length);
+    string->ComputeHashCode();
     return string;
   }
 
@@ -1248,7 +1255,6 @@
     return len;
   }
 
-
   // The java/lang/String.computeHashCode() algorithm
   static int32_t ComputeUtf16Hash(const uint16_t* string_data, size_t string_length) {
     int32_t hash = 0;
@@ -1258,6 +1264,10 @@
     return hash;
   }
 
+  void ComputeHashCode() {
+    hash_code_ = ComputeUtf16Hash(array_->GetData(), count_);
+  }
+
   bool Equals(const char* modified_utf8) const {
     for (int32_t i = 0; i < GetLength(); ++i) {
       uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
diff --git a/src/object_test.cc b/src/object_test.cc
index 2d32ad0..e5bdd35 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -30,11 +30,11 @@
     String* string = String::AllocFromModifiedUtf8(length, utf8_in);
     ASSERT_EQ(length, string->GetLength());
     ASSERT_TRUE(string->GetCharArray() != NULL);
-    ASSERT_TRUE(string->GetCharArray()->GetChars() != NULL);
+    ASSERT_TRUE(string->GetCharArray()->GetData() != NULL);
     // strlen is necessary because the 1-character string "\0" is interpreted as ""
     ASSERT_TRUE(string->Equals(utf8_in) || length != static_cast<int32_t>(strlen(utf8_in)));
     for (int32_t i = 0; i < length; i++) {
-      EXPECT_EQ(utf16_expected[i], string->GetCharArray()->GetChar(i));
+      EXPECT_EQ(utf16_expected[i], string->CharAt(i));
     }
     EXPECT_EQ(hash_expected, string->GetHashCode());
   }
@@ -162,4 +162,11 @@
   EXPECT_TRUE(m4_2->HasSameNameAndDescriptor(m4_1));
 }
 
+
+TEST_F(ObjectTest, StringHashCode) {
+  EXPECT_EQ(0, String::AllocFromAscii("")->GetHashCode());
+  EXPECT_EQ(65, String::AllocFromAscii("A")->GetHashCode());
+  EXPECT_EQ(64578, String::AllocFromAscii("ABC")->GetHashCode());
+}
+
 }  // namespace art