Fix array-put-object

Change CanPutArrayElementFromCode to take an object and a class, rather
than two classes.  This allows the generated code to skip the null check
on the element (I believe this was the plan all along, but I must have
forgotten and the current codegen was dereferencing the element to find it's
class without checking for NULL).

Change-Id: I11865e0e625ab0e800718398fd911733718e6ce9
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 59aadcf..652899c06 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -1265,8 +1265,6 @@
                  OFFSETOF_MEMBER(Thread, pCanPutArrayElementFromCode), rLR);
     /* Get the array's clazz */
     loadWordDisp(cUnit, r1, Object::ClassOffset().Int32Value(), r1);
-    /* Get the object's clazz */
-    loadWordDisp(cUnit, r0, Object::ClassOffset().Int32Value(), r0);
     callUnwindableHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
 
diff --git a/src/object.cc b/src/object.cc
index c54364f..8d3a94f 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -764,9 +764,12 @@
   }
 }
 
-void Class::CanPutArrayElementFromCode(const Class* object_class, const Class* array_class) {
-  if (!CanPutArrayElement(object_class, array_class)) {
-    LOG(ERROR) << "Can't put a " << PrettyClass(object_class)
+void Class::CanPutArrayElementFromCode(const Object* element, const Class* array_class) {
+  if (element == NULL) {
+    return;
+  }
+  if (!CanPutArrayElement(element->GetClass(), array_class)) {
+    LOG(ERROR) << "Can't put a " << PrettyClass(element->GetClass())
                << " into a " << PrettyClass(array_class);
     UNIMPLEMENTED(FATAL) << "need to throw ArrayStoreException and unwind stack";
   }
diff --git a/src/object.h b/src/object.h
index 59909e1..02c98d8 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1427,7 +1427,7 @@
   static bool CanPutArrayElement(const Class* object_class, const Class* array_class);
   // Like CanPutArrayElement, but throws an exception and
   // unwinds the stack instead of returning false.
-  static void CanPutArrayElementFromCode(const Class* object_class, const Class* array_class);
+  static void CanPutArrayElementFromCode(const Object* element, const Class* array_class);
 
   // Given the context of a calling Method, use its DexCache to
   // resolve a type to a Class. If it cannot be resolved, throw an
diff --git a/src/thread.h b/src/thread.h
index c362a43..ef2fa12 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -206,7 +206,7 @@
   void (*pSet64Static)(uint32_t, const Method*, uint64_t);
   Object* (*pGetObjStatic)(uint32_t, const Method*);
   void (*pSetObjStatic)(uint32_t, const Method*, Object*);
-  void (*pCanPutArrayElementFromCode)(const Class*, const Class*);
+  void (*pCanPutArrayElementFromCode)(const Object*, const Class*);
   bool (*pInstanceofNonTrivialFromCode) (const Object*, const Class*);
   void (*pCheckCastFromCode) (const Class*, const Class*);
   Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*);