Add ObjectArray::CopyOf

As part of doing this, moved Heap::Alloc* helpers to the corresponding
classes in object.h to break heap.h<->object.h cycle due to use of
Heap from ObjectArray::CopyOf (which is templatized and needs to be
defined in .h file).

Change-Id: I1870af6e9dc6552820034ead5e20d13ae4da67da
diff --git a/src/object.h b/src/object.h
index bf965df..a154959 100644
--- a/src/object.h
+++ b/src/object.h
@@ -6,6 +6,7 @@
 #include "constants.h"
 #include "casts.h"
 #include "globals.h"
+#include "heap.h"
 #include "logging.h"
 #include "macros.h"
 #include "offsets.h"
@@ -104,6 +105,8 @@
 
 class Object {
  public:
+  static Object* Alloc(Class* klass);
+
   Class* GetClass() const {
     return klass_;
   }
@@ -563,6 +566,16 @@
 
 class Array : public Object {
  public:
+  static Array* Alloc(Class* array_class,
+                      size_t component_count,
+                      size_t component_size) {
+    size_t size = sizeof(Array) + component_count * component_size;
+    Array* array = down_cast<Array*>(Heap::AllocObject(array_class, size));
+    if (array != NULL) {
+      array->SetLength(component_count);
+    }
+    return array;
+  }
   uint32_t GetLength() const {
     return length_;
   }
@@ -587,21 +600,33 @@
 template<class T>
 class ObjectArray : public Array {
  public:
-  C* Get(uint32_t i) const {
+  static ObjectArray<T>* Alloc(Class* object_array_class,
+                               size_t length) {
+    return down_cast<ObjectArray<T>*>(Array::Alloc(object_array_class,
+                                                   length,
+                                                   sizeof(uint32_t)));
+  }
+
+  T* Get(uint32_t i) const {
     DCHECK_LT(i, GetLength());
     Object* const * data = reinterpret_cast<Object* const *>(GetData());
-    return down_cast<C*>(data[i]);
+    return down_cast<T*>(data[i]);
   }
-  void Set(uint32_t i, C* object) {
+  void Set(uint32_t i, T* object) {
     DCHECK_LT(i, GetLength());
-    C** data = reinterpret_cast<C**>(GetData());
+    T** data = reinterpret_cast<T**>(GetData());
     data[i] = object;
   }
-  static void Copy(ObjectArray<C>* src, int src_pos, ObjectArray<C>* dst, int dst_pos, size_t length) {
+  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++) {
       dst->Set(dst_pos + i, src->Get(src_pos + i));
     }
   }
+  ObjectArray<T>* CopyOf(size_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;
+  }
 
  private:
   ObjectArray();
@@ -945,6 +970,10 @@
 };
 std::ostream& operator<<(std::ostream& os, const Class::Status& rhs);
 
+inline Object* Object::Alloc(Class* klass) {
+  return Heap::AllocObject(klass, klass->object_size_);
+}
+
 class DataObject : public Object {
  public:
   uint32_t fields_[0];
@@ -953,12 +982,34 @@
 };
 
 class CharArray : 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)));
+  }
  private:
   CharArray();
 };
 
 class String : public Object {
  public:
+  static String* Alloc(Class* java_lang_String) {
+    return down_cast<String*>(Object::Alloc(java_lang_String));
+  }
+
+  static String* AllocFromModifiedUtf8(Class* java_lang_String,
+                                       Class* char_array,
+                                       const char* data) {
+    String* string = Alloc(java_lang_String);
+    uint32_t count = strlen(data);  // TODO
+    CharArray* array = CharArray::Alloc(char_array, count);
+    string->array_ = array;
+    string->count_ = count;
+    return string;
+  }
+
+ public: // TODO: private
   CharArray* array_;
 
   uint32_t hash_code_;