Further proxy refactorings.

Factor the crawling of the quick stack arguments into a common visitor.
Factor the proxy invocation dispatch into common runtime support code,
fix numerous bugs relating to GC in the LLVM runtime support with this.
Clean up BoxPrimitive to not use an in argument as an out.

Change-Id: I7b12c8d88d5083614e480b8fb1d2f2ef7c0a51b7
diff --git a/src/reflection.cc b/src/reflection.cc
index c793d2c..1ffad3f 100644
--- a/src/reflection.cc
+++ b/src/reflection.cc
@@ -90,8 +90,7 @@
   }
 
   // Box if necessary and return.
-  BoxPrimitive(mh.GetReturnType()->GetPrimitiveType(), value);
-  return soa.AddLocalReference<jobject>(value.GetL());
+  return soa.AddLocalReference<jobject>(BoxPrimitive(mh.GetReturnType()->GetPrimitiveType(), value));
 }
 
 bool VerifyObjectInClass(Object* o, Class* c) {
@@ -195,9 +194,9 @@
   return false;
 }
 
-void BoxPrimitive(Primitive::Type src_class, JValue& value) {
+Object* BoxPrimitive(Primitive::Type src_class, const JValue& value) {
   if (src_class == Primitive::kPrimNot) {
-    return;
+    return value.GetL();
   }
 
   jmethodID m = NULL;
@@ -228,8 +227,7 @@
     break;
   case Primitive::kPrimVoid:
     // There's no such thing as a void field, and void methods invoked via reflection return null.
-    value.SetL(NULL);
-    return;
+    return NULL;
   default:
     LOG(FATAL) << static_cast<int>(src_class);
   }
@@ -239,7 +237,9 @@
     CHECK_EQ(soa.Self()->GetState(), kRunnable);
   }
   JValue args[1] = { value };
-  soa.DecodeMethod(m)->Invoke(soa.Self(), NULL, args, &value);
+  JValue result;
+  soa.DecodeMethod(m)->Invoke(soa.Self(), NULL, args, &result);
+  return result.GetL();
 }
 
 static std::string UnboxingFailureKind(AbstractMethod* m, int index, Field* f)