Move allocation of fields and methods to heap

Also make Object and subclasses constructors private to prevent
accidental non-heap allocation.

Change-Id: If9513967ba012748eb0d54c04e92df0f0944d385
diff --git a/src/class_linker.cc b/src/class_linker.cc
index a205a06..15c2e40 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -172,36 +172,42 @@
   // Load static fields.
   if (klass->num_sfields_ != 0) {
     // TODO: allocate on the object heap.
-    klass->sfields_ = new StaticField[klass->NumStaticFields()]();
+    klass->sfields_ = new StaticField*[klass->NumStaticFields()]();
     uint32_t last_idx = 0;
     for (size_t i = 0; i < klass->num_sfields_; ++i) {
       RawDexFile::Field raw_field;
       raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
-      LoadField(klass, raw_field, &klass->sfields_[i]);
+      StaticField* sfield = Heap::AllocStaticField();
+      klass->sfields_[i] = sfield;
+      LoadField(klass, raw_field, sfield);
     }
   }
 
   // Load instance fields.
   if (klass->NumInstanceFields() != 0) {
     // TODO: allocate on the object heap.
-    klass->ifields_ = new InstanceField[klass->NumInstanceFields()]();
+    klass->ifields_ = new InstanceField*[klass->NumInstanceFields()]();
     uint32_t last_idx = 0;
     for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
       RawDexFile::Field raw_field;
       raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
-      LoadField(klass, raw_field, klass->GetInstanceField(i));
+      InstanceField* ifield = Heap::AllocInstanceField();
+      klass->ifields_[i] = ifield;
+      LoadField(klass, raw_field, ifield);
     }
   }
 
   // Load direct methods.
   if (klass->NumDirectMethods() != 0) {
     // TODO: append direct methods to class object
-    klass->direct_methods_ = new Method[klass->NumDirectMethods()]();
+    klass->direct_methods_ = new Method*[klass->NumDirectMethods()]();
     uint32_t last_idx = 0;
     for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
       RawDexFile::Method raw_method;
       raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
-      LoadMethod(klass, raw_method, klass->GetDirectMethod(i));
+      Method* meth = Heap::AllocMethod();
+      klass->direct_methods_[i] = meth;
+      LoadMethod(klass, raw_method, meth);
       // TODO: register maps
     }
   }
@@ -209,12 +215,14 @@
   // Load virtual methods.
   if (klass->NumVirtualMethods() != 0) {
     // TODO: append virtual methods to class object
-    klass->virtual_methods_ = new Method[klass->NumVirtualMethods()]();
+    klass->virtual_methods_ = new Method*[klass->NumVirtualMethods()]();
     uint32_t last_idx = 0;
     for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
       RawDexFile::Method raw_method;
       raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
-      LoadMethod(klass, raw_method, klass->GetVirtualMethod(i));
+      Method* meth = Heap::AllocMethod();
+      klass->virtual_methods_[i] = meth;
+      LoadMethod(klass, raw_method, meth);
       // TODO: register maps
     }
   }
@@ -922,39 +930,28 @@
     }
   }
   if (miranda_count != 0) {
-    Method* newVirtualMethods;
-    Method* meth;
-    int oldMethodCount, oldVtableCount;
-    if (klass->virtual_methods_ == NULL) {
-      newVirtualMethods = new Method[klass->NumVirtualMethods() + miranda_count];
-
-    } else {
-      newVirtualMethods = new Method[klass->NumVirtualMethods() + miranda_count];
+    int oldMethodCount = klass->NumVirtualMethods();
+    int newMethodCount = oldMethodCount + miranda_count;
+    Method** newVirtualMethods = new Method*[newMethodCount];
+    if (klass->virtual_methods_ != NULL) {
       memcpy(newVirtualMethods,
              klass->virtual_methods_,
-             klass->NumVirtualMethods() * sizeof(Method));
-
+             klass->NumVirtualMethods() * sizeof(Method*));
     }
-    if (newVirtualMethods != klass->virtual_methods_) {
-      Method* meth = newVirtualMethods;
-      for (size_t i = 0; i < klass->NumVirtualMethods(); i++, meth++) {
-        klass->vtable_[meth->method_index_] = meth;
-      }
-    }
-    oldMethodCount = klass->NumVirtualMethods();
     klass->virtual_methods_ = newVirtualMethods;
-    klass->num_virtual_methods_ += miranda_count;
+    klass->num_virtual_methods_ = newMethodCount;
 
     CHECK(klass->vtable_ != NULL);
-    oldVtableCount = klass->vtable_count_;
+    int oldVtableCount = klass->vtable_count_;
     klass->vtable_count_ += miranda_count;
 
-    meth = klass->virtual_methods_ + oldMethodCount;
-    for (int i = 0; i < miranda_count; i++, meth++) {
+    for (int i = 0; i < miranda_count; i++) {
+      Method* meth = Heap::AllocMethod();
       memcpy(meth, miranda_list[i], sizeof(Method));
       meth->klass_ = klass;
       meth->access_flags_ |= kAccMiranda;
       meth->method_index_ = 0xFFFF & (oldVtableCount + i);
+      klass->virtual_methods_[oldMethodCount+i] = meth;
       klass->vtable_[oldVtableCount + i] = meth;
     }
   }
@@ -980,17 +977,18 @@
   // Move references to the front.
   klass->num_reference_ifields_ = 0;
   size_t i = 0;
-  size_t j = klass->NumInstanceFields() - 1;
-  for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
+  for ( ; i < klass->NumInstanceFields(); i++) {
     InstanceField* pField = klass->GetInstanceField(i);
     char c = pField->GetType();
 
     if (c != '[' && c != 'L') {
-      while (j > i) {
-        InstanceField* refField = klass->GetInstanceField(j--);
+      for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
+        InstanceField* refField = klass->GetInstanceField(j);
         char rc = refField->GetType();
         if (rc == '[' || rc == 'L') {
-          pField->Swap(refField);
+          klass->SetInstanceField(i, refField);
+          klass->SetInstanceField(j, pField);
+          pField = refField;
           c = rc;
           klass->num_reference_ifields_++;
           break;
@@ -1023,12 +1021,13 @@
       // Next field is 64-bit, so search for a 32-bit field we can
       // swap into it.
       bool found = false;
-      j = klass->NumInstanceFields() - 1;
-      while (j > i) {
-        InstanceField* singleField = klass->GetInstanceField(j--);
+      for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
+        InstanceField* singleField = klass->GetInstanceField(j);
         char rc = singleField->GetType();
         if (rc != 'J' && rc != 'D') {
-          pField->Swap(singleField);
+          klass->SetInstanceField(i, singleField);
+          klass->SetInstanceField(j, pField);
+          pField = singleField;
           pField->SetOffset(fieldOffset);
           fieldOffset += sizeof(uint32_t);
           found = true;
@@ -1045,16 +1044,17 @@
   // Alignment is good, shuffle any double-wide fields forward, and
   // finish assigning field offsets to all fields.
   assert(i == klass->NumInstanceFields() || (fieldOffset & 0x04) == 0);
-  j = klass->NumInstanceFields() - 1;
   for ( ; i < klass->NumInstanceFields(); i++) {
     InstanceField* pField = klass->GetInstanceField(i);
     char c = pField->GetType();
     if (c != 'D' && c != 'J') {
-      while (j > i) {
-        InstanceField* doubleField = klass->GetInstanceField(j--);
+      for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
+        InstanceField* doubleField = klass->GetInstanceField(j);
         char rc = doubleField->GetType();
         if (rc == 'D' || rc == 'J') {
-          pField->Swap(doubleField);
+          klass->SetInstanceField(i, doubleField);
+          klass->SetInstanceField(j, pField);
+          pField = doubleField;
           c = rc;
           break;
         }
diff --git a/src/heap.h b/src/heap.h
index 7c679eb..b9f7937 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -26,6 +26,24 @@
     return klass;
   }
 
+  static StaticField* AllocStaticField() {
+    size_t size = sizeof(StaticField);
+    byte* raw = new byte[size]();
+    return reinterpret_cast<StaticField*>(raw);
+  }
+
+  static InstanceField* AllocInstanceField() {
+    size_t size = sizeof(InstanceField);
+    byte* raw = new byte[size]();
+    return reinterpret_cast<InstanceField*>(raw);
+  }
+
+  static Method* AllocMethod() {
+    size_t size = sizeof(Method);
+    byte* raw = new byte[size]();
+    return reinterpret_cast<Method*>(raw);
+  }
+
   static CharArray* AllocCharArray(size_t length) {
     size_t size = sizeof(Array) + length * sizeof(uint16_t);
     byte* raw = new byte[size]();
diff --git a/src/object.h b/src/object.h
index ac42081..d7df9dc 100644
--- a/src/object.h
+++ b/src/object.h
@@ -156,6 +156,7 @@
   Monitor* monitor_;
 
  private:
+  Object();
   DISALLOW_COPY_AND_ASSIGN(Object);
 };
 
@@ -187,7 +188,7 @@
   DISALLOW_COPY_AND_ASSIGN(ObjectLock);
 };
 
-class Field {
+class Field : public Object {
  public:
   Class* GetClass() const {
     return klass_;
@@ -206,6 +207,17 @@
   }
 
  public:  // TODO: private
+#define FIELD_FIELD_SLOTS 1+6
+  // AccessibleObject #0 flag
+  // Field #0 declaringClass
+  // Field #1 genericType
+  // Field #2 genericTypesAreInitialized
+  // Field #3 name
+  // Field #4 slot
+  // Field #5 type
+  uint32_t instance_data_[FIELD_FIELD_SLOTS];
+#undef FIELD_FIELD_SLOTS
+
   // The class in which this field is declared.
   Class* klass_;
 
@@ -215,6 +227,9 @@
   const char* signature_;
 
   uint32_t access_flags_;
+
+ private:
+  Field();
 };
 
 // Instance fields.
@@ -228,16 +243,9 @@
     offset_ = num_bytes;
   }
 
-  // TODO: stl::swap
-  void Swap(InstanceField* that) {
-    InstanceField tmp;
-    memcpy(&tmp, this, sizeof(InstanceField));
-    memcpy(this, that, sizeof(InstanceField));
-    memcpy(that, &tmp, sizeof(InstanceField));
-  }
-
  private:
   size_t offset_;
+  InstanceField();
 };
 
 // Static fields.
@@ -296,9 +304,10 @@
 
  private:
   JValue value_;
+  StaticField();
 };
 
-class Method {
+class Method : public Object {
  public:
   // Returns the method name.
   // TODO: example
@@ -374,6 +383,22 @@
   bool HasSameArgumentTypes(const Method* that) const;
 
  public:  // TODO: private
+#define METHOD_FIELD_SLOTS 1+11
+  // AccessibleObject #0 flag
+  // Method #0  declaringClass
+  // Method #1  exceptionTypes
+  // Method #2  formalTypeParameters
+  // Method #3  genericExceptionTypes
+  // Method #4  genericParameterTypes
+  // Method #5  genericReturnType
+  // Method #6  genericTypesAreInitialized
+  // Method #7  name
+  // Method #8  parameterTypes
+  // Method #9  returnType
+  // Method #10 slot
+  uint32_t instance_data_[METHOD_FIELD_SLOTS];
+#undef METHOD_FIELD_SLOTS
+
   // the class we are a part of
   Class* klass_;
 
@@ -406,6 +431,9 @@
 
   // A pointer to the memory-mapped DEX code.
   const uint16_t* insns_;
+
+ private:
+  Method();
 };
 
 // Class objects.
@@ -533,7 +561,7 @@
   }
 
   Method* GetDirectMethod(uint32_t i) const {
-    return &direct_methods_[i];
+    return direct_methods_[i];
   }
 
   // Returns the number of non-inherited virtual methods.
@@ -542,7 +570,7 @@
   }
 
   Method* GetVirtualMethod(uint32_t i) const {
-    return &virtual_methods_[i];
+    return virtual_methods_[i];
   }
 
   size_t NumInstanceFields() const {
@@ -554,7 +582,11 @@
   }
 
   InstanceField* GetInstanceField(uint32_t i) {  // TODO: uint16_t
-    return &ifields_[i];
+    return ifields_[i];
+  }
+
+  void SetInstanceField(uint32_t i, InstanceField* f) {  // TODO: uint16_t
+    ifields_[i] = f;
   }
 
   size_t NumStaticFields() const {
@@ -562,7 +594,7 @@
   }
 
   StaticField* GetStaticField(uint32_t i) {  // TODO: uint16_t
-    return &sfields_[i];
+    return sfields_[i];
   }
 
   uint32_t GetReferenceOffsets() const {
@@ -579,7 +611,8 @@
  public: // TODO: private
   // leave space for instance data; we could access fields directly if
   // we freeze the definition of java/lang/Class
-#define CLASS_FIELD_SLOTS 4
+#define CLASS_FIELD_SLOTS 1
+  // Class.#0 name
   uint32_t instance_data_[CLASS_FIELD_SLOTS];
 #undef CLASS_FIELD_SLOTS
 
@@ -642,11 +675,11 @@
 
   // static, private, and <init> methods
   size_t num_direct_methods_;
-  Method* direct_methods_;
+  Method** direct_methods_;
 
   // virtual methods defined in this class; invoked through vtable
   size_t num_virtual_methods_;
-  Method* virtual_methods_;
+  Method** virtual_methods_;
 
   // Virtual method table (vtable), for use by "invoke-virtual".  The
   // vtable from the superclass is copied in, and virtual methods from
@@ -690,7 +723,7 @@
 
   // number of fields that are object refs
   size_t num_reference_ifields_;
-  InstanceField* ifields_;
+  InstanceField** ifields_;
 
   // Bitmap of offsets of ifields.
   uint32_t reference_offsets_;
@@ -700,13 +733,18 @@
 
   // Static fields
   size_t num_sfields_;
-  StaticField* sfields_;
+  StaticField** sfields_;
+
+ private:
+  Class();
 };
 std::ostream& operator<<(std::ostream& os, const Class::Status& rhs);
 
 class DataObject : public Object {
  public:
   uint32_t fields_[1];
+ private:
+  DataObject();
 };
 
 class Array : public Object {
@@ -718,9 +756,13 @@
  private:
   // The number of array elements.
   uint32_t length_;
+  Array();
 };
 
-class CharArray : public Array {};
+class CharArray : public Array {
+ private:
+  CharArray();
+};
 
 class String : public Object {
  public:
@@ -731,6 +773,9 @@
   uint32_t offset_;
 
   uint32_t count_;
+
+ private:
+  String();
 };
 
 class InterfaceEntry {