Implement JNI NewBooleanArray et cetera.

(Primitive types only. NewObjectArray to come...)

Change-Id: I2f54031d96062d666089c91ba40e16028ae21bd4
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 50b1a07..3437a5a 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -27,7 +27,7 @@
 }
 
 void ClassLinker::Init(const std::vector<DexFile*>& boot_class_path) {
-  init_done_ = false;
+  CHECK(!init_done_);
 
   // java_lang_Class comes first, its needed for AllocClass
   Class* java_lang_Class = down_cast<Class*>(Heap::AllocObject(NULL, sizeof(Class)));
@@ -61,14 +61,17 @@
   Class* char_array_class = AllocClass(java_lang_Class);
   CHECK(char_array_class != NULL);
   char_array_class->descriptor_ = "[C";
+  CharArray::SetArrayClass(char_array_class);
 
   // 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_ = "[I";
+  IntArray::SetArrayClass(int_array_class);
   Class* long_array_class = AllocClass(java_lang_Class);
   CHECK(long_array_class != NULL);
   long_array_class->descriptor_ = "[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);
@@ -95,7 +98,7 @@
   class_roots_->Set(kJavaLangReflectMethod, java_lang_reflect_Method);
   // now that these are registered, we can use AllocClass() and AllocObjectArray
 
-  String::InitClasses(java_lang_String, char_array_class);
+  String::InitClasses(java_lang_String);
   // Now AllocString* can be used
 
   // setup boot_class_path_ now that we can use AllocObjectArray to
@@ -172,6 +175,7 @@
   CHECK_EQ(java_io_Serializable, object_array_class->GetInterface(1));
 
   // Setup the primitive type classes.
+  class_roots_->Set(kPrimitiveBoolean, CreatePrimitiveClass("Z"));
   class_roots_->Set(kPrimitiveByte, CreatePrimitiveClass("B"));
   class_roots_->Set(kPrimitiveChar, CreatePrimitiveClass("C"));
   class_roots_->Set(kPrimitiveDouble, CreatePrimitiveClass("D"));
@@ -179,7 +183,6 @@
   class_roots_->Set(kPrimitiveInt, CreatePrimitiveClass("I"));
   class_roots_->Set(kPrimitiveLong, CreatePrimitiveClass("J"));
   class_roots_->Set(kPrimitiveShort, CreatePrimitiveClass("S"));
-  class_roots_->Set(kPrimitiveBoolean, CreatePrimitiveClass("Z"));
   class_roots_->Set(kPrimitiveVoid, CreatePrimitiveClass("V"));
   // now we can use FindSystemClass for anything, including for "[C"
 
@@ -191,6 +194,19 @@
   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.
+  class_roots_->Set(kBooleanArrayClass, FindSystemClass("[Z"));
+  class_roots_->Set(kByteArrayClass, FindSystemClass("[B"));
+  class_roots_->Set(kDoubleArrayClass, FindSystemClass("[D"));
+  class_roots_->Set(kFloatArrayClass, FindSystemClass("[F"));
+  class_roots_->Set(kShortArrayClass, FindSystemClass("[S"));
+  BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
+  ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
+  DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
+  FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
+  ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
+
   // ensure all class_roots_ were initialized
   for (size_t i = 0; i < kClassRootsMax; i++) {
     CHECK(GetClassRoot(static_cast<ClassRoot>(i)));
@@ -1378,12 +1394,10 @@
     klass->static_references_ = ObjectArray<Object>::Alloc(array_class, next_reference_slot);
   }
   if (next_32bit_primitive_slot > 0) {
-    Class* array_class = GetClassRoot(kIntArrayClass);
-    klass->static_32bit_primitives_ = IntArray::Alloc(array_class, next_32bit_primitive_slot);
+    klass->static_32bit_primitives_ = IntArray::Alloc(next_32bit_primitive_slot);
   }
   if (next_64bit_primitive_slot > 0) {
-    Class* array_class = GetClassRoot(kLongArrayClass);
-    klass->static_64bit_primitives_ = LongArray::Alloc(array_class, next_64bit_primitive_slot);
+    klass->static_64bit_primitives_ = LongArray::Alloc(next_64bit_primitive_slot);
   }
 
   return true;
diff --git a/src/class_linker.h b/src/class_linker.h
index fa50537..b2b4c95 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -31,6 +31,8 @@
   Class* FindClass(const StringPiece& descriptor,
                    ClassLoader* class_loader);
 
+  Class* FindPrimitiveClass(char type);
+
   Class* FindSystemClass(const StringPiece& descriptor) {
     return FindClass(descriptor, NULL);
   }
@@ -42,8 +44,9 @@
   void VisitRoots(Heap::RootVistor* root_visitor, void* arg);
 
  private:
-  ClassLinker() {
-    classes_lock_ = Mutex::Create("ClassLinker::Lock");
+  ClassLinker()
+      : classes_lock_(Mutex::Create("ClassLinker::Lock")),
+        init_done_(false) {
   }
 
   void Init(const std::vector<DexFile*>& boot_class_path_);
@@ -69,8 +72,6 @@
   Class* CreateArrayClass(const StringPiece& descriptor,
                           ClassLoader* class_loader);
 
-  Class* FindPrimitiveClass(char type);
-
   const DexFile& FindDexFile(const DexCache* dex_cache) const;
 
   DexCache* FindDexCache(const DexFile* dex_file) const;
@@ -165,23 +166,28 @@
     kJavaLangObject,
     kObjectArrayClass,
     kJavaLangString,
-    kCharArrayClass,
-    kIntArrayClass,
-    kLongArrayClass,
     kJavaLangReflectField,
     kJavaLangReflectMethod,
     kJavaLangClassLoader,
     kDalvikSystemBaseDexClassLoader,
     kDalvikSystemPathClassLoader,
     kPrimitiveBoolean,
-    kPrimitiveChar,
-    kPrimitiveFloat,
-    kPrimitiveDouble,
     kPrimitiveByte,
-    kPrimitiveShort,
+    kPrimitiveChar,
+    kPrimitiveDouble,
+    kPrimitiveFloat,
     kPrimitiveInt,
     kPrimitiveLong,
+    kPrimitiveShort,
     kPrimitiveVoid,
+    kBooleanArrayClass,
+    kByteArrayClass,
+    kCharArrayClass,
+    kDoubleArrayClass,
+    kFloatArrayClass,
+    kIntArrayClass,
+    kLongArrayClass,
+    kShortArrayClass,
     kClassRootsMax,
   };
   ObjectArray<Class>* class_roots_;
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 25b03b2..683310d 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -372,8 +372,8 @@
 }
 
 TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) {
-  Class* array_class = class_linker_->FindSystemClass("[J");
-  LongArray* array = LongArray::Alloc(array_class, 0);
+  LongArray* array = LongArray::Alloc(0);
+  EXPECT_EQ(class_linker_->FindSystemClass("[J"), array->GetClass());
   uint32_t array_offset = reinterpret_cast<uint32_t>(array);
   uint32_t data_offset = reinterpret_cast<uint32_t>(array->GetData());
   EXPECT_EQ(16U, data_offset - array_offset);
diff --git a/src/image_writer.cc b/src/image_writer.cc
index 0014724..6ac5803 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -22,7 +22,7 @@
   }
   CalculateNewObjectOffsets();
   CopyAndFixupObjects();
-  
+
   scoped_ptr<File> file(OS::OpenBinaryFile(filename, true));
   if (file == NULL) {
     return false;
@@ -72,7 +72,7 @@
   DCHECK(obj != NULL);
   DCHECK(arg != NULL);
   ImageWriter* image_writer = reinterpret_cast<ImageWriter*>(arg);
-  
+
   size_t offset = image_writer->GetImageOffset(obj);
   byte* dst = image_writer->mem_map_->GetAddress() + offset;
   byte* src = reinterpret_cast<byte*>(obj);
@@ -96,7 +96,7 @@
 }
 
 void ImageWriter::FixupObjectArray(ObjectArray<Object>* orig, ObjectArray<Object>* copy) {
-  for (size_t i = 0; i < orig->GetLength(); ++i) {
+  for (int32_t i = 0; i < orig->GetLength(); ++i) {
     const Object* element = orig->Get(i);
     copy->Set(i, GetImageAddress(element));
   }
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 23c8273..0e9cb84 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -79,7 +79,7 @@
   return true;
 }
 
-static byte* CreateArgArray(Method* method, va_list ap) {
+byte* CreateArgArray(Method* method, va_list ap) {
   size_t num_bytes = method->NumArgArrayBytes();
   scoped_array<byte> arg_array(new byte[num_bytes]);
   const StringPiece& shorty = method->GetShorty();
@@ -117,7 +117,7 @@
   return arg_array.release();
 }
 
-static byte* CreateArgArray(Method* method, jvalue* args) {
+byte* CreateArgArray(Method* method, jvalue* args) {
   size_t num_bytes = method->NumArgArrayBytes();
   scoped_array<byte> arg_array(new byte[num_bytes]);
   const StringPiece& shorty = method->GetShorty();
@@ -1301,52 +1301,52 @@
   UNIMPLEMENTED(FATAL);
 }
 
+template<typename JniT, typename ArtT>
+JniT NewPrimitiveArray(ScopedJniThreadState& ts, jsize length) {
+  CHECK_GE(length, 0); // TODO: ReportJniError
+  ArtT* result = ArtT::Alloc(length);
+  // TODO: local reference
+  return reinterpret_cast<JniT>(result);
+}
+
 jbooleanArray NewBooleanArray(JNIEnv* env, jsize len) {
   ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  return NewPrimitiveArray<jbooleanArray, BooleanArray>(ts, len);
 }
 
 jbyteArray NewByteArray(JNIEnv* env, jsize len) {
   ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  return NewPrimitiveArray<jbyteArray, ByteArray>(ts, len);
 }
 
 jcharArray NewCharArray(JNIEnv* env, jsize len) {
   ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jshortArray NewShortArray(JNIEnv* env, jsize len) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jintArray NewIntArray(JNIEnv* env, jsize len) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jlongArray NewLongArray(JNIEnv* env, jsize len) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jfloatArray NewFloatArray(JNIEnv* env, jsize len) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  return NewPrimitiveArray<jcharArray, CharArray>(ts, len);
 }
 
 jdoubleArray NewDoubleArray(JNIEnv* env, jsize len) {
   ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  return NewPrimitiveArray<jdoubleArray, DoubleArray>(ts, len);
+}
+
+jfloatArray NewFloatArray(JNIEnv* env, jsize len) {
+  ScopedJniThreadState ts(env);
+  return NewPrimitiveArray<jfloatArray, FloatArray>(ts, len);
+}
+
+jintArray NewIntArray(JNIEnv* env, jsize len) {
+  ScopedJniThreadState ts(env);
+  return NewPrimitiveArray<jintArray, IntArray>(ts, len);
+}
+
+jlongArray NewLongArray(JNIEnv* env, jsize len) {
+  ScopedJniThreadState ts(env);
+  return NewPrimitiveArray<jlongArray, LongArray>(ts, len);
+}
+
+jshortArray NewShortArray(JNIEnv* env, jsize len) {
+  ScopedJniThreadState ts(env);
+  return NewPrimitiveArray<jshortArray, ShortArray>(ts, len);
 }
 
 jboolean* GetBooleanArrayElements(JNIEnv* env,
diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc
index 457bae8..ce640e2 100644
--- a/src/jni_internal_test.cc
+++ b/src/jni_internal_test.cc
@@ -57,6 +57,28 @@
   EXPECT_CLASS_NOT_FOUND("K");
 }
 
+TEST_F(JniInternalTest, NewPrimitiveArray) {
+  // TODO: death tests for negative array sizes.
+
+  CHECK(env_->NewBooleanArray(0) != NULL);
+  CHECK(env_->NewByteArray(0) != NULL);
+  CHECK(env_->NewCharArray(0) != NULL);
+  CHECK(env_->NewDoubleArray(0) != NULL);
+  CHECK(env_->NewFloatArray(0) != NULL);
+  CHECK(env_->NewIntArray(0) != NULL);
+  CHECK(env_->NewLongArray(0) != NULL);
+  CHECK(env_->NewShortArray(0) != NULL);
+
+  CHECK(env_->NewBooleanArray(1) != NULL);
+  CHECK(env_->NewByteArray(1) != NULL);
+  CHECK(env_->NewCharArray(1) != NULL);
+  CHECK(env_->NewDoubleArray(1) != NULL);
+  CHECK(env_->NewFloatArray(1) != NULL);
+  CHECK(env_->NewIntArray(1) != NULL);
+  CHECK(env_->NewLongArray(1) != NULL);
+  CHECK(env_->NewShortArray(1) != NULL);
+}
+
 bool EnsureInvokeStub(Method* method);
 
 byte* AllocateCode(void* code, size_t length) {
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc
index 5d7c139..06a1c92 100644
--- a/src/mark_sweep.cc
+++ b/src/mark_sweep.cc
@@ -204,7 +204,7 @@
   MarkObject(obj->GetClass());
   if (obj->IsObjectArray()) {
     const ObjectArray<Object>* array = obj->AsObjectArray<Object>();
-    for (size_t i = 0; i < array->GetLength(); ++i) {
+    for (int32_t i = 0; i < array->GetLength(); ++i) {
       const Object* element = array->Get(i);
       MarkObject(element);
     }
diff --git a/src/object.cc b/src/object.cc
index 34b0bb9..21f3537 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -5,6 +5,7 @@
 #include <string.h>
 #include <algorithm>
 
+#include "class_linker.h"
 #include "globals.h"
 #include "heap.h"
 #include "logging.h"
@@ -441,13 +442,29 @@
   return NULL;
 }
 
+template<typename T>
+PrimitiveArray<T>* PrimitiveArray<T>::Alloc(size_t length) {
+  Array* raw_array = Array::Alloc(array_class_, length, sizeof(T));
+  return down_cast<PrimitiveArray<T>*>(raw_array);
+}
+
+template <typename T> Class* PrimitiveArray<T>::array_class_ = NULL;
+
+// Explicitly instantiate all the primitive array types.
+template class PrimitiveArray<uint8_t>;   // BooleanArray
+template class PrimitiveArray<int8_t>;    // ByteArray
+template class PrimitiveArray<uint16_t>;  // CharArray
+template class PrimitiveArray<double>;    // DoubleArray
+template class PrimitiveArray<float>;     // FloatArray
+template class PrimitiveArray<int32_t>;   // IntArray
+template class PrimitiveArray<int64_t>;   // LongArray
+template class PrimitiveArray<int16_t>;   // ShortArray
+
 // TODO: get global references for these
 Class* String::java_lang_String_ = NULL;
-Class* String::char_array_ = NULL;
 
-void String::InitClasses(Class* java_lang_String, Class* char_array) {
+void String::InitClasses(Class* java_lang_String) {
   java_lang_String_ = java_lang_String;
-  char_array_ = char_array;
 }
 
 static const char* kClassStatusNames[] = {
diff --git a/src/object.h b/src/object.h
index cb7f379..5110992 100644
--- a/src/object.h
+++ b/src/object.h
@@ -27,9 +27,14 @@
 class String;
 template<class T> class ObjectArray;
 template<class T> class PrimitiveArray;
+typedef PrimitiveArray<uint8_t> BooleanArray;
+typedef PrimitiveArray<int8_t> ByteArray;
 typedef PrimitiveArray<uint16_t> CharArray;
-typedef PrimitiveArray<uint32_t> IntArray;
-typedef PrimitiveArray<uint64_t> LongArray;
+typedef PrimitiveArray<double> DoubleArray;
+typedef PrimitiveArray<float> FloatArray;
+typedef PrimitiveArray<int32_t> IntArray;
+typedef PrimitiveArray<int64_t> LongArray;
+typedef PrimitiveArray<int16_t> ShortArray;
 
 union JValue {
   uint8_t z;
@@ -611,7 +616,7 @@
 
   size_t Size() const;
 
-  uint32_t GetLength() const {
+  int32_t GetLength() const {
     return length_;
   }
 
@@ -644,12 +649,12 @@
     return reinterpret_cast<T**>(&elements_);
   }
 
-  T* Get(uint32_t i) const {
+  T* Get(int32_t i) const {
     CHECK_LT(i, GetLength());
     return GetData()[i];
   }
 
-  void Set(uint32_t i, T* object) {
+  void Set(int32_t i, T* object) {
     CHECK_LT(i, GetLength());
     GetData()[i] = object;  // TODO: write barrier
   }
@@ -662,7 +667,7 @@
     }
   }
 
-  ObjectArray<T>* CopyOf(size_t new_length) {
+  ObjectArray<T>* CopyOf(int32_t new_length) {
     ObjectArray<T>* new_array = Alloc(klass_, new_length);
     Copy(this, 0, new_array, 0, std::min(GetLength(), new_length));
     return new_array;
@@ -795,24 +800,28 @@
     return component_type_;
   }
 
-  size_t GetComponentSize() const {
-    switch (component_type_->descriptor_[0]) {
-      case 'B': return 1;  // byte
-      case 'C': return 2;  // char
-      case 'D': return 8;  // double
-      case 'F': return 4;  // float
-      case 'I': return 4;  // int
-      case 'J': return 8;  // long
-      case 'S': return 2;  // short
-      case 'Z': return 1;  // boolean
-      case 'L': return sizeof(Object*);
-      case '[': return sizeof(Array*);
-      default: 
-        LOG(ERROR) << "Unknown component type " << component_type_->descriptor_;
-        return 0;
+  static size_t GetTypeSize(const StringPiece& descriptor) {
+    switch (descriptor[0]) {
+    case 'B': return 1;  // byte
+    case 'C': return 2;  // char
+    case 'D': return 8;  // double
+    case 'F': return 4;  // float
+    case 'I': return 4;  // int
+    case 'J': return 8;  // long
+    case 'S': return 2;  // short
+    case 'Z': return 1;  // boolean
+    case 'L': return sizeof(Object*);
+    case '[': return sizeof(Array*);
+    default:
+      LOG(ERROR) << "Unknown type " << descriptor;
+      return 0;
     }
   }
 
+  size_t GetComponentSize() const {
+    return GetTypeSize(component_type_->descriptor_);
+  }
+
   const StringPiece& GetDescriptor() const {
     DCHECK_NE(0, descriptor_.size());
     return descriptor_;
@@ -902,7 +911,7 @@
     return (direct_methods_ != NULL) ? direct_methods_->GetLength() : 0;
   }
 
-  Method* GetDirectMethod(uint32_t i) const {
+  Method* GetDirectMethod(int32_t i) const {
     DCHECK_NE(NumDirectMethods(), 0U);
     return direct_methods_->Get(i);
   }
@@ -1186,11 +1195,7 @@
 template<class T>
 class PrimitiveArray : public Array {
  public:
-  static PrimitiveArray<T>* Alloc(Class* element_class, size_t length) {
-    return down_cast<PrimitiveArray<T>*>(Array::Alloc(element_class,
-                                         length,
-                                         sizeof(T)));
-  }
+  static PrimitiveArray<T>* Alloc(size_t length);
 
   const T* GetData() const {
     return reinterpret_cast<const T*>(&elements_);
@@ -1200,20 +1205,27 @@
     return reinterpret_cast<T*>(&elements_);
   }
 
-  T Get(T i) const {
+  T Get(int32_t i) const {
     CHECK_LT(i, GetLength());
     return GetData()[i];
   }
 
-  void Set(uint32_t i, T value) {
+  void Set(int32_t i, T value) {
     CHECK_LT(i, GetLength());
     GetData()[i] = value;
   }
 
+  static void SetArrayClass(Class* array_class) {
+    CHECK(array_class != NULL);
+    array_class_ = array_class;
+  }
+
  private:
   // Location of first element.
   T elements_[0];
 
+  static Class* array_class_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(PrimitiveArray);
 };
 
@@ -1245,7 +1257,6 @@
                                 uint16_t* utf16_data_in,
                                 int32_t hash_code) {
     String* string = Alloc(GetJavaLangString(),
-                           GetCharArrayClass(),
                            utf16_length);
     // TODO use 16-bit wide memset variant
     for (int i = 0; i < utf16_length; i++ ) {
@@ -1256,10 +1267,9 @@
   }
 
   static String* AllocFromModifiedUtf8(Class* java_lang_String,
-                                       Class* char_array,
                                        int32_t utf16_length,
                                        const char* utf8_data_in) {
-    String* string = Alloc(java_lang_String, char_array, utf16_length);
+    String* string = Alloc(java_lang_String, utf16_length);
     uint16_t* utf16_data_out = string->array_->GetData();
     ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
     string->ComputeHashCode();
@@ -1270,24 +1280,22 @@
   // using non-ASCII characters as this function assumes one char per byte.
   static String* AllocFromAscii(const char* ascii_data_in) {
     return AllocFromModifiedUtf8(GetJavaLangString(),
-                                 GetCharArrayClass(),
                                  strlen(ascii_data_in),
                                  ascii_data_in);
   }
 
   static String* AllocFromModifiedUtf8(int32_t utf16_length,
                                        const char* utf8_data_in) {
-    return AllocFromModifiedUtf8(GetJavaLangString(), GetCharArrayClass(),
+    return AllocFromModifiedUtf8(GetJavaLangString(),
                                  utf16_length, utf8_data_in);
   }
 
-  static void InitClasses(Class* java_lang_String, Class* char_array);
+  static void InitClasses(Class* java_lang_String);
 
   static String* Alloc(Class* java_lang_String,
-                       Class* char_array,
                        int32_t utf16_length) {
     String* string = down_cast<String*>(java_lang_String->NewInstance());
-    CharArray* array = CharArray::Alloc(char_array, utf16_length);
+    CharArray* array = CharArray::Alloc(utf16_length);
     string->array_ = array;
     string->count_ = utf16_length;
     return string;
@@ -1428,13 +1436,8 @@
     DCHECK(java_lang_String_ != NULL);
     return java_lang_String_;
   }
-  static Class* GetCharArrayClass() {
-    DCHECK(char_array_ != NULL);
-    return char_array_;
-  }
 
   static Class* java_lang_String_;
-  static Class* char_array_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(String);
 };
diff --git a/src/object_test.cc b/src/object_test.cc
index 52fb288..28aecb0 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -55,7 +55,7 @@
 
 TEST_F(ObjectTest, AllocObjectArray) {
   ObjectArray<Object>* oa = class_linker_->AllocObjectArray<Object>(2);
-  EXPECT_EQ(2U, oa->GetLength());
+  EXPECT_EQ(2, oa->GetLength());
   EXPECT_TRUE(oa->Get(0) == NULL);
   EXPECT_TRUE(oa->Get(1) == NULL);
   oa->Set(0, oa);