lambda: Add support for invoke-interface for boxed innate lambdas

Lambda closures created with the 'create-lambda' instruction
(termed "innate lambdas") can be turned into an object with 'box-lambda'.

This CL enables support for those kinds of lambdas to work with
'invoke-interface' by generating a proxy class for the lambda.

Note: MIPS32/64 support not included.

Bug: 24618608
Bug: 25107649
Change-Id: Ic8f1bb66ebeaed4097e758a50becf1cff6ccaefb
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 9098d38..2ff9fd2 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -172,12 +172,23 @@
     } else {
       return cur_shadow_frame_->GetVRegReference(0);
     }
-  } else if (m->IsProxyMethod()) {
+  } else if (m->IsReflectProxyMethod()) {
     if (cur_quick_frame_ != nullptr) {
       return artQuickGetProxyThisObject(cur_quick_frame_);
     } else {
       return cur_shadow_frame_->GetVRegReference(0);
     }
+  } else if (m->IsLambdaProxyMethod()) {
+    if (cur_quick_frame_ != nullptr) {
+      // XX: Should be safe to return null here, the lambda proxies
+      // don't set up their own quick frame because they don't need to spill any registers.
+      // By the time we are executing inside of the final target of the proxy invoke,
+      // the original 'this' reference is no longer live.
+      LOG(WARNING) << "Lambda proxies don't have a quick frame, do they?!";
+      return nullptr;
+    } else {
+      return cur_shadow_frame_->GetVRegReference(0);
+    }
   } else {
     const DexFile::CodeItem* code_item = m->GetCodeItem();
     if (code_item == nullptr) {
@@ -814,7 +825,27 @@
     // compiled method without any stubs. Therefore the method must have a OatQuickMethodHeader.
     DCHECK(!method->IsDirect() && !method->IsConstructor())
         << "Constructors of proxy classes must have a OatQuickMethodHeader";
-    return runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs);
+
+    if (method->IsReflectProxyMethod()) {
+      return runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs);
+    } else if (method->IsLambdaProxyMethod()) {
+      // Set this to true later once every stub works without a frame.
+      // This is currently 'false' because using a closure as a "long"
+      // requires a quick frame to be set up on 32-bit architectures.
+      constexpr bool kLambdaProxyStubsSupportFrameless = false;
+      if (kIsDebugBuild || !kLambdaProxyStubsSupportFrameless) {
+        // When debugging we always use the 'RefAndArgs' quick frame to allow us
+        // to see a runtime stub when unwinding.
+        return runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs);
+      } else {
+        // Lambda proxies don't bother setting up a quick frame for release builds.
+        LOG(FATAL) << "Requested QuickMethodFrameInfo for a lambda proxy,"
+                   << "but it doesn't have one, for method: " << PrettyMethod(method);
+        UNREACHABLE();
+      }
+    } else {
+      LOG(FATAL) << "Unknown type of proxy method " << PrettyMethod(method);
+    }
   }
 
   // The only remaining case is if the method is native and uses the generic JNI stub.