Proxy tidy up and extra asserts.

Ensure we don't suspend when placing object args into IRT.
Ensure stack is sane.

Change-Id: I20a8c97002b74878831580da1dd03458363ece82
diff --git a/src/oat/runtime/support_proxy.cc b/src/oat/runtime/support_proxy.cc
index 7ece784..1fdab2a 100644
--- a/src/oat/runtime/support_proxy.cc
+++ b/src/oat/runtime/support_proxy.cc
@@ -38,6 +38,9 @@
 #define ARG2_OFFSET_IN_WORDS 8 // offset to 3rd arg; skip callee saves, LR, Method* and out arg spills for OUT0 to OUT2
 #else
 #error "Unsupported architecture"
+#define SP_OFFSET_IN_BYTES 0
+#define FRAME_SIZE_IN_BYTES 0
+#define ARG2_OFFSET_IN_WORDS 0
 #endif
 
 namespace art {
@@ -49,21 +52,25 @@
 extern "C" void artProxyInvokeHandler(AbstractMethod* proxy_method, Object* receiver,
                                       Thread* self, byte* stack_args)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  // Register the top of the managed stack
+  // Ensure we don't get thread suspension until the object arguments are safely in jobjects.
+  const char* old_cause =
+      self->StartAssertNoThreadSuspension("Adding to IRT proxy object arguments");
+  // Register the top of the managed stack, making stack crawlable.
   AbstractMethod** proxy_sp = reinterpret_cast<AbstractMethod**>(stack_args - SP_OFFSET_IN_BYTES);
   DCHECK_EQ(*proxy_sp, proxy_method);
   self->SetTopOfStack(proxy_sp, 0);
   DCHECK_EQ(proxy_method->GetFrameSizeInBytes(), FRAME_SIZE_IN_BYTES);
-  // Start new JNI local reference state
+  self->VerifyStack();
+  // Start new JNI local reference state.
   JNIEnvExt* env = self->GetJniEnv();
   ScopedObjectAccessUnchecked soa(env);
   ScopedJniEnvLocalRefState env_state(env);
-  // Create local ref. copies of proxy method and the receiver
+  // Create local ref. copies of proxy method and the receiver.
   jobject rcvr_jobj = soa.AddLocalReference<jobject>(receiver);
   jobject proxy_method_jobj = soa.AddLocalReference<jobject>(proxy_method);
 
   // Placing into local references incoming arguments from the caller's register arguments,
-  // replacing original Object* with jobject
+  // replacing original Object* with jobject.
   MethodHelper proxy_mh(proxy_method);
   const size_t num_params = proxy_mh.NumArgs();
   size_t args_in_regs = 0;
@@ -85,7 +92,7 @@
     cur_arg = cur_arg + (proxy_mh.IsParamALongOrDouble(param_index) ? 2 : 1);
     param_index++;
   }
-  // Placing into local references incoming arguments from the caller's stack arguments
+  // Placing into local references incoming arguments from the caller's stack arguments.
   cur_arg += ARG2_OFFSET_IN_WORDS;
   while (param_index < num_params) {
     if (proxy_mh.IsParamAReference(param_index)) {
@@ -96,11 +103,15 @@
     cur_arg = cur_arg + (proxy_mh.IsParamALongOrDouble(param_index) ? 2 : 1);
     param_index++;
   }
-  // Set up arguments array and place in local IRT during boxing (which may allocate/GC)
+  self->EndAssertNoThreadSuspension(old_cause);
+  // Sanity check writing the jobjects over the Object*s in place didn't damage the stack.
+  self->VerifyStack();
+
+  // Set up arguments array and place in local IRT during boxing (which may allocate/GC).
   jvalue args_jobj[3];
   args_jobj[0].l = rcvr_jobj;
   args_jobj[1].l = proxy_method_jobj;
-  // Args array, if no arguments then NULL (don't include receiver in argument count)
+  // Args array, if no arguments then NULL (don't include receiver in argument count).
   args_jobj[2].l = NULL;
   ObjectArray<Object>* args = NULL;
   if ((num_params - 1) > 0) {
@@ -111,14 +122,14 @@
     }
     args_jobj[2].l = soa.AddLocalReference<jobjectArray>(args);
   }
-  // Convert proxy method into expected interface method
+  // Convert proxy method into expected interface method.
   AbstractMethod* interface_method = proxy_method->FindOverriddenMethod();
   DCHECK(interface_method != NULL);
   DCHECK(!interface_method->IsProxyMethod()) << PrettyMethod(interface_method);
   args_jobj[1].l = soa.AddLocalReference<jobject>(interface_method);
-  // Box arguments
-  cur_arg = 0;  // reset stack location to read to start
-  // reset index, will index into param type array which doesn't include the receiver
+  // Box primitive type arguments.
+  cur_arg = 0;  // Stack location to read to start.
+  // Reset index, will index into param type array which doesn't include the receiver.
   param_index = 0;
   ObjectArray<Class>* param_types = proxy_mh.GetParameterTypes(self);
   if (param_types == NULL) {
@@ -135,8 +146,9 @@
     } else {
       JValue val = *reinterpret_cast<JValue*>(stack_args + (cur_arg * kPointerSize));
       if (cur_arg == 1 && (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble())) {
-        // long/double split over regs and stack, mask in high half from stack arguments
-        uint64_t high_half = *reinterpret_cast<uint32_t*>(stack_args + ((ARG2_OFFSET_IN_WORDS + 2) * kPointerSize));
+        // long/double split over regs and stack, mask in high half from stack arguments.
+        uint64_t high_half =
+            *reinterpret_cast<uint32_t*>(stack_args + ((ARG2_OFFSET_IN_WORDS + 2) * kPointerSize));
         val.SetJ((val.GetJ() & 0xffffffffULL) | (high_half << 32));
       }
       BoxPrimitive(param_type->GetPrimitiveType(), val);
@@ -149,7 +161,7 @@
     cur_arg = cur_arg + (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble() ? 2 : 1);
     param_index++;
   }
-  // Placing into local references incoming arguments from the caller's stack arguments
+  // Placing into local references incoming arguments from the caller's stack arguments.
   cur_arg += ARG2_OFFSET_IN_WORDS;
   while (param_index < (num_params - 1)) {
     Class* param_type = param_types->Get(param_index);
@@ -168,17 +180,20 @@
     cur_arg = cur_arg + (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble() ? 2 : 1);
     param_index++;
   }
-  // Get the InvocationHandler method and the field that holds it within the Proxy object
+  // Get the InvocationHandler method and the field that holds it within the Proxy object.
   DCHECK(env->IsInstanceOf(rcvr_jobj, WellKnownClasses::java_lang_reflect_Proxy));
   jobject inv_hand = env->GetObjectField(rcvr_jobj, WellKnownClasses::java_lang_reflect_Proxy_h);
-  // Call InvocationHandler.invoke
-  jobject result = env->CallObjectMethodA(inv_hand, WellKnownClasses::java_lang_reflect_InvocationHandler_invoke, args_jobj);
-  // Place result in stack args
+  // Call InvocationHandler.invoke.
+  jobject result =
+      env->CallObjectMethodA(inv_hand, WellKnownClasses::java_lang_reflect_InvocationHandler_invoke,
+                             args_jobj);
+  // Place result in stack args.
   if (!self->IsExceptionPending()) {
     Object* result_ref = self->DecodeJObject(result);
     if (result_ref != NULL) {
       JValue result_unboxed;
-      bool unboxed_okay = UnboxPrimitiveForResult(result_ref, proxy_mh.GetReturnType(), result_unboxed);
+      bool unboxed_okay = UnboxPrimitiveForResult(result_ref, proxy_mh.GetReturnType(),
+                                                  result_unboxed);
       if (!unboxed_okay) {
         self->ClearException();
         self->ThrowNewExceptionF("Ljava/lang/ClassCastException;",
diff --git a/src/thread.cc b/src/thread.cc
index f7c568f..fbd6a88 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -2064,8 +2064,8 @@
   // Visit roots on this thread's stack
   Context* context = GetLongJumpContext();
   RootCallbackVisitor visitorToCallback(visitor, arg);
-  ReferenceMapVisitor<RootCallbackVisitor> mapper(GetManagedStack(), GetInstrumentationStack(), context,
-                                                  visitorToCallback);
+  ReferenceMapVisitor<RootCallbackVisitor> mapper(GetManagedStack(), GetInstrumentationStack(),
+                                                  context, visitorToCallback);
   mapper.WalkStack();
   ReleaseLongJumpContext(context);
 }
@@ -2079,8 +2079,8 @@
 void Thread::VerifyStack() {
   UniquePtr<Context> context(Context::Create());
   RootCallbackVisitor visitorToCallback(VerifyObject, Runtime::Current()->GetHeap());
-  ReferenceMapVisitor<RootCallbackVisitor> mapper(GetManagedStack(), GetInstrumentationStack(), context.get(),
-                                                  visitorToCallback);
+  ReferenceMapVisitor<RootCallbackVisitor> mapper(GetManagedStack(), GetInstrumentationStack(),
+                                                  context.get(), visitorToCallback);
   mapper.WalkStack();
 }
 #endif