Add missing write barriers to Object::Clone, LinkInterfaceMethods

These functions were using memcpy without a write barrier, causing the sticky mark bits GC to occasionally corrupt the heap.

Added missing write barriers.

Change-Id: Ie1c483904e095bda467e6c000f2659a3332116ae
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 6e3d903..32e6c39 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -3093,8 +3093,7 @@
         }
         if (miranda_method.get() == NULL) {
           // point the interface table at a phantom slot
-          miranda_method.reset(AllocMethod());
-          memcpy(miranda_method.get(), interface_method, sizeof(Method));
+          miranda_method.reset(down_cast<Method*>(interface_method->Clone()));
           miranda_list.push_back(miranda_method.get());
         }
         method_array->Set(j, miranda_method.get());
diff --git a/src/object.cc b/src/object.cc
index dcf4ce9..fc89841 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -72,6 +72,24 @@
   size_t offset = sizeof(Object);
   memcpy(dst_bytes + offset, src_bytes + offset, num_bytes - offset);
 
+  // Perform write barriers on copied object references.
+  if (c->IsArrayClass()) {
+    if (!c->GetComponentType()->IsPrimitive()) {
+      const ObjectArray<Object>* array = copy->AsObjectArray<Object>();
+      heap->WriteBarrierArray(copy.get(), 0, array->GetLength());
+    }
+  } else {
+    for (const Class* klass = c; klass != NULL; klass = klass->GetSuperClass()) {
+      size_t num_reference_fields = klass->NumReferenceInstanceFields();
+      for (size_t i = 0; i < num_reference_fields; ++i) {
+        Field* field = klass->GetInstanceField(i);
+        MemberOffset field_offset = field->GetOffset();
+        const Object* ref = copy->GetFieldObject<const Object*>(field_offset, false);
+        heap->WriteBarrierField(copy.get(), field_offset, ref);
+      }
+    }
+  }
+
   if (c->IsFinalizable()) {
     heap->AddFinalizerReference(Thread::Current(), copy.get());
   }