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

955-lambda is flaky

Bug: 24618608
Bug: 25107649

This reverts commit 457e874459ae638145cab6d572e34d48480e39d2.

Change-Id: I24884344d21d7a4262e53e3f5dba57032687ddb7
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 717403f..dcde5ab 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -29,7 +29,6 @@
   GetMethodSignature \
   Instrumentation \
   Interfaces \
-  LambdaInterfaces \
   Lookup \
   Main \
   MultiDex \
@@ -78,7 +77,6 @@
 ART_GTEST_oat_test_DEX_DEPS := Main
 ART_GTEST_object_test_DEX_DEPS := ProtoCompare ProtoCompare2 StaticsFromCode XandY
 ART_GTEST_proxy_test_DEX_DEPS := Interfaces
-ART_GTEST_lambda_proxy_test_DEX_DEPS := LambdaInterfaces
 ART_GTEST_reflection_test_DEX_DEPS := Main NonStaticLeafMethods StaticLeafMethods
 ART_GTEST_stub_test_DEX_DEPS := AllFields
 ART_GTEST_transaction_test_DEX_DEPS := Transaction
@@ -99,7 +97,6 @@
 
 # TODO: document why this is needed.
 ART_GTEST_proxy_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
-ART_GTEST_lambda_proxy_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
 
 # The dexdump test requires an image and the dexdump utility.
 # TODO: rename into dexdump when migration completes
@@ -236,7 +233,6 @@
 
 COMPILER_GTEST_COMMON_SRC_FILES := \
   runtime/jni_internal_test.cc \
-  runtime/lambda_proxy_test.cc \
   runtime/proxy_test.cc \
   runtime/reflection_test.cc \
   compiler/compiled_method_test.cc \
@@ -745,7 +741,6 @@
 ART_GTEST_oat_file_assistant_test_TARGET_DEPS :=
 ART_GTEST_object_test_DEX_DEPS :=
 ART_GTEST_proxy_test_DEX_DEPS :=
-ART_GTEST_lambda_proxy_test_DEX_DEPS :=
 ART_GTEST_reflection_test_DEX_DEPS :=
 ART_GTEST_stub_test_DEX_DEPS :=
 ART_GTEST_transaction_test_DEX_DEPS :=
diff --git a/runtime/Android.mk b/runtime/Android.mk
index 4f4792a..0b0f094 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -106,7 +106,6 @@
   jit/profiling_info.cc \
   lambda/art_lambda_method.cc \
   lambda/box_table.cc \
-  lambda/box_class_table.cc \
   lambda/closure.cc \
   lambda/closure_builder.cc \
   lambda/leaking_allocator.cc \
diff --git a/runtime/arch/arch_test.cc b/runtime/arch/arch_test.cc
index 771c8b7..d6ba304 100644
--- a/runtime/arch/arch_test.cc
+++ b/runtime/arch/arch_test.cc
@@ -46,15 +46,9 @@
   }
 };
 
-}  // namespace art
-
 // Common tests are declared next to the constants.
 #define ADD_TEST_EQ(x, y) EXPECT_EQ(x, y);
 #include "asm_support.h"
-// Important: Do not include this inside of another namespace, since asm_support.h
-// defines its own namespace which must not be nested.
-
-namespace art {
 
 TEST_F(ArchTest, CheckCommonOffsetsAndSizes) {
   CheckAsmSupportOffsetsAndSizes();
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 588268d..631b784 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -1045,26 +1045,6 @@
     DELIVER_PENDING_EXCEPTION
 END art_quick_proxy_invoke_handler
 
-// Forward call from boxed innate lambda to the underlying lambda closure's target method.
-     .extern artQuickLambdaProxyInvokeHandler
-ENTRY art_quick_lambda_proxy_invoke_handler
-// TODO: have a faster handler that doesn't need to set up a frame
-    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_R0
-    mov     r2, r9                 @ pass Thread::Current
-    mov     r3, sp                 @ pass SP
-    blx     artQuickLambdaProxyInvokeHandler  @ (Method* proxy method, receiver, Thread*, SP)
-    ldr     r2, [r9, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
-    // Tear down the callee-save frame. Skip arg registers.
-    add     sp, #(FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)
-    .cfi_adjust_cfa_offset -(FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)
-    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
-    cbnz    r2, 1f                 @ success if no exception is pending
-    vmov    d0, r0, r1             @ store into fpr, for when it's a fpr return...
-    bx      lr                     @ return on success
-1:
-    DELIVER_PENDING_EXCEPTION
-END art_quick_lambda_proxy_invoke_handler
-
     /*
      * Called to resolve an imt conflict. r12 is a hidden argument that holds the target method's
      * dex method index.
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 177873d..9ccabad 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1582,28 +1582,6 @@
     DELIVER_PENDING_EXCEPTION
 END art_quick_proxy_invoke_handler
 
-     /*
-     * Called by managed code that is attempting to call a method on a lambda proxy class. On entry
-     * x0 holds the lambda proxy method and x1 holds the receiver; The frame size of the invoked
-     * lambda proxy method agrees with a ref and args callee save frame.
-     */
-     .extern artQuickLambdaProxyInvokeHandler
-ENTRY art_quick_lambda_proxy_invoke_handler
-// TODO: have a faster way to invoke lambda proxies without setting up the whole frame.
-    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_X0
-    mov     x2, xSELF                   // pass Thread::Current
-    mov     x3, sp                      // pass SP
-    bl      artQuickLambdaProxyInvokeHandler  // (Method* proxy method, receiver, Thread*, SP)
-    ldr     x2, [xSELF, THREAD_EXCEPTION_OFFSET]
-    cbnz    x2, .Lexception_in_lambda_proxy    // success if no exception is pending
-    RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME // Restore frame
-    fmov    d0, x0                      // Store result in d0 in case it was float or double
-    ret                                 // return on success
-.Lexception_in_lambda_proxy:
-    RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
-    DELIVER_PENDING_EXCEPTION
-END art_quick_lambda_proxy_invoke_handler
-
     /*
      * Called to resolve an imt conflict. xIP1 is a hidden argument that holds the target method's
      * dex method index.
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index af79f5e..0691f2a 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -1377,10 +1377,6 @@
     DELIVER_PENDING_EXCEPTION
 END art_quick_proxy_invoke_handler
 
-// Forward call from boxed innate lambda to the underlying lambda closure's target method.
-    .extern artQuickLambdaProxyInvokeHandler
-UNIMPLEMENTED art_quick_lambda_proxy_invoke_handler
-
     /*
      * Called to resolve an imt conflict. t0 is a hidden argument that holds the target method's
      * dex method index.
diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S
index 5e70a95..66c8aad 100644
--- a/runtime/arch/mips64/quick_entrypoints_mips64.S
+++ b/runtime/arch/mips64/quick_entrypoints_mips64.S
@@ -1431,10 +1431,6 @@
     DELIVER_PENDING_EXCEPTION
 END art_quick_proxy_invoke_handler
 
-// Forward call from boxed innate lambda to the underlying lambda closure's target method.
-    .extern artQuickLambdaProxyInvokeHandler
-UNIMPLEMENTED art_quick_lambda_proxy_invoke_handler
-
     /*
      * Called to resolve an imt conflict. t0 is a hidden argument that holds the target method's
      * dex method index.
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index 4fb6119..463c9cf 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -1391,149 +1391,6 @@
     RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
 END_FUNCTION art_quick_proxy_invoke_handler
 
-#if LAMBDA_INVOKE_USES_LONG
-#undef LAMBDA_PROXY_SETUP_FRAME
-// We need to always do a 'pop' to readjust the stack, so we have to use the slower call instruction.
-#define LAMBDA_PROXY_SETUP_FRAME 1
-#define LAMBDA_INVOKE_REALIGN_STACK_FRAME 1
-#else
-#define LAMBDA_INVOKE_REALIGN_STACK_FRAME 0
-#endif
-
-#define LAMBDA_INVOKE_CALLS_INTO_RUNTIME LAMBDA_INVOKE_REALIGN_STACK_FRAME
-
-// Forward call from boxed innate lambda to the underlying lambda closure's target method.
-DEFINE_FUNCTION art_quick_lambda_proxy_invoke_handler
-    // This function is always called when the lambda is innate.
-    // Therefore we can assume the box is to an innate lambda.
-    // TODO: perhaps there should be a DCHECK to make sure it's innate?
-
-#if LAMBDA_PROXY_SETUP_FRAME
-    // Set up a quick frame when debugging so we can see that it's going through a stub.
-    // An invoke-virtual + a stub invocation is enough of a hint that we *could* be
-    // going through a lambda proxy.
-    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_EAX
-#endif
-
-#if !LAMBDA_INVOKE_CALLS_INTO_RUNTIME
-    // Rewrite the following 2 arguments, stored on stack frame:
-    //
-    //   |--------|
-    //   |receiver|   <- esp-4
-    //   |--------|
-    //   | method |   <- esp
-    //   |--------|
-
-    // Set up the new correct method receiver (swap object with closure).
-    // -- The original object is no longer available after this.
-    //
-    // (Before)
-    // ecx == mirror::Object* boxed_lambda;  // lambda proxy object.
-    movl MIRROR_OBJECT_BOXED_INNATE_LAMBDA_CLOSURE_POINTER_OFFSET(%ecx), %ecx
-    // (After)
-    // lambda::Closure* closure = boxed_lambda->closure_;
-    // boxed_lambda = closure; // Overwrite lambda proxy object
-    // ecx == closure
-
-    // Look up the new correct method target.
-    // -- The original method target is no longer available after this.
-    //
-    // (Before)
-    // eax == ArtMethod* old_receiver_method;
-    movl LAMBDA_CLOSURE_METHOD_OFFSET(%ecx), %eax
-    // (After)
-    // ArtLambdaMethod* lambda_method_target = closure->lambda_info_;
-    // eax = lambda_method_target
-    //
-    // Set up the correct method target from the lambda info.
-    movl ART_LAMBDA_METHOD_ART_METHOD_OFFSET(%eax), %eax  // Load new receiver method
-    // (After)
-    // ArtMethod* target_method = lambda_method_target->target_
-    // eax = target_method
-#endif
-
-#if LAMBDA_INVOKE_CALLS_INTO_RUNTIME
-    PUSH esp                      // pass SP
-    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
-    CFI_ADJUST_CFA_OFFSET(4)
-    PUSH ecx                      // pass receiver
-    PUSH eax                      // pass proxy method
-    call SYMBOL(artQuickLambdaProxyInvokeHandler) // (proxy method, receiver, Thread*, SP)
-    movd %eax, %xmm0              // place return value also into floating point return value
-    movd %edx, %xmm1
-    punpckldq %xmm1, %xmm0
-    addl LITERAL(16 + FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE), %esp
-    CFI_ADJUST_CFA_OFFSET(-(16 + FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE))
-    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
-    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
-#endif
-
-#if LAMBDA_INVOKE_USES_LONG && !LAMBDA_INVOKE_REALIGN_STACK_FRAME
-    // As a temporary workaround, lambda functions look like
-    //  (J[Arg2][Arg3][Arg4]...)
-    // This means that we can't just pass in the lambda as a 32-bit pointer
-    // We pad the arguments with an extra 32-bit "0" where Arg2 used to be instead.
-
-    // Required arguments for a lambda method:
-    //
-    // Arg0 = eax = method
-    // Arg1 = ecx = closure (hi)
-    // Arg2 = edx = closure (lo)
-    // Arg3 = ebx = <?> (first user-defined argument)
-
-    // Transformation diagram:
-    //
-    // Arg0  Arg1  Arg2  Arg3 ... ArgN
-    //   |    |        \     \        \
-    //   |    |         \     \        \
-    // Arg0  Arg1  0x00  Arg2  Arg3 ... ArgN
-    //              /\
-    //           (inserted)
-    PUSH ebx          // Move out Arg3 into Arg4, and also for all K>3 ArgK into ArgK+1
-    mov %edx, %ebx    // Move out Arg2 into Arg3
-    xor %edx, %edx    // Clear closure 32-bit low register
-
-    // XX: Does this work at all ? This probably breaks the visitors (*and* its unaligned).
-
-    // FIXME: call into the runtime and do a proxy-like-invoke
-    // using a ShadowFrame quick visitor, and then use ArtMethod::Invoke
-    // to call into the actual method (which will take care of fixing up alignment).
-    // Trying to realign in the assembly itself won't actually work
-    // since then the visitor will unwind incorrectly (unless we also fixed up the ManagedStack).
-#endif
-
-    // TODO: avoid extra indirect load by subclass ArtLambdaMethod from ArtMethod.
-
-    // Forward the call to the overwritten receiver method.
-    // -- Arguments [2,N] are left completely untouched since the signature is otherwise identical.
-#if LAMBDA_PROXY_SETUP_FRAME
-  #if LAMBDA_INVOKE_CALLS_INTO_RUNTIME
-    // Have to call into runtime in order to re-align the stack frame to 16 bytes.
-    int3
-  #else
-    // Just call into the method directly. Don't worry about realigning.
-    call *ART_METHOD_QUICK_CODE_OFFSET_32(%eax)  // (new method, new receiver, old args...)
-
-    // The stack frame was manually adjusted, so make sure we have a pop here to fix it back.
-    #if LAMBDA_INVOKE_USES_LONG && !LAMBDA_INVOKE_REALIGN_STACK_FRAME
-
-    POP ecx   // OK: ecx is scratch register after the call.
-    // XX: use 'add esp, 4' instead if we need to keep the register? This way we get cleaner CFI.
-    #endif
-  #endif
-    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
-
-#else
-    // Do not use 'call' here since the stack visitors wouldn't know how to visit this frame.
-    jmp *ART_METHOD_QUICK_CODE_OFFSET_32(%eax)   // tailcall (new method, new receiver, old args...)
-#endif
-
-#if LAMBDA_PROXY_SETUP_FRAME
-    ret
-#endif
-
-END_FUNCTION art_quick_lambda_proxy_invoke_handler
-
     /*
      * Called to resolve an imt conflict. xmm7 is a hidden argument that holds the target method's
      * dex method index.
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 0a54aa3..17d277e 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -1297,6 +1297,7 @@
     RETURN_IF_EAX_ZERO                   // return or deliver exception
 END_FUNCTION art_quick_set64_static
 
+
 DEFINE_FUNCTION art_quick_proxy_invoke_handler
     SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_RDI
 
@@ -1308,60 +1309,6 @@
     RETURN_OR_DELIVER_PENDING_EXCEPTION
 END_FUNCTION art_quick_proxy_invoke_handler
 
-// Forward call from boxed innate lambda to the underlying lambda closure's target method.
-DEFINE_FUNCTION art_quick_lambda_proxy_invoke_handler
-    // This function is always called when the lambda is innate.
-    // Therefore we can assume the box is to an innate lambda.
-    // TODO: perhaps there should be a DCHECK to make sure it's innate?
-
-#if LAMBDA_PROXY_SETUP_FRAME
-    // Set up a quick frame when debugging so we can see that it's going through a stub.
-    // Our stack traces will contain the quick lambda proxy hander.
-    // Note that we *must* go through the handler (when spilling) otherwise we won't know how
-    // to move the spilled GC references from the caller to this stub.
-    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_RDI
-
-    movq %gs:THREAD_SELF_OFFSET, %rdx       // Pass Thread::Current().
-    movq %rsp, %rcx                         // Pass SP.
-    call SYMBOL(artQuickLambdaProxyInvokeHandler) // (proxy method, receiver, Thread*, SP)
-    RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
-    movq %rax, %xmm0                        // Copy return value in case of float returns.
-    RETURN_OR_DELIVER_PENDING_EXCEPTION
-#else
-    // Set up the new correct method receiver (swap object with closure).
-    // -- The original object is no longer available after this.
-    //
-    // (Before)
-    // rsi == mirror::Object* boxed_lambda;  // lambda proxy object.
-    movq MIRROR_OBJECT_BOXED_INNATE_LAMBDA_CLOSURE_POINTER_OFFSET(%rsi), %rsi
-    // (After)
-    // lambda::Closure* closure = boxed_lambda->closure_;  // Overwrite receiver object.
-    // rsi == closure
-
-    // Look up the new correct method target.
-    // -- The original method target is no longer available after this.
-    movq LAMBDA_CLOSURE_METHOD_OFFSET(%rsi), %rdi          // Overwrite old receiver method.
-    // (After)
-    // ArtLambdaMethod* lambda_method_target = closure->lambda_info_;
-    // rdi == lambda_method_target
-
-    // TODO: avoid extra indirect load by subclass ArtLambdaMethod from ArtMethod.
-
-    // Set up the correct method target from the lambda info.
-    movq ART_LAMBDA_METHOD_ART_METHOD_OFFSET(%rdi), %rdi  // Write new receiver method.
-    // (After)
-    // ArtMethod* method_target = lambda_method_target->target_;
-    // rdi == method_target
-
-    // Forward the call to the overwritten receiver method.
-    // -- Arguments [2,N] are left completely untouched since the signature is otherwise identical.
-    // Do not use 'call' here since the stack would be misaligned (8b instead of 16b).
-    // Also the stack visitors wouldn't know how to visit this frame if we used a call.
-    jmp *ART_METHOD_QUICK_CODE_OFFSET_64(%rdi)   // tailcall (new method, new receiver, old args...)
-#endif
-
-END_FUNCTION art_quick_lambda_proxy_invoke_handler
-
     /*
      * Called to resolve an imt conflict.
      * rax is a hidden argument that holds the target method's dex method index.
diff --git a/runtime/art_field-inl.h b/runtime/art_field-inl.h
index ab42d0e..4166e22 100644
--- a/runtime/art_field-inl.h
+++ b/runtime/art_field-inl.h
@@ -255,7 +255,7 @@
 
 inline const char* ArtField::GetName() SHARED_REQUIRES(Locks::mutator_lock_) {
   uint32_t field_index = GetDexFieldIndex();
-  if (UNLIKELY(GetDeclaringClass()->IsAnyProxyClass())) {
+  if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
     DCHECK(IsStatic());
     DCHECK_LT(field_index, 2U);
     return field_index == 0 ? "interfaces" : "throws";
@@ -266,7 +266,7 @@
 
 inline const char* ArtField::GetTypeDescriptor() SHARED_REQUIRES(Locks::mutator_lock_) {
   uint32_t field_index = GetDexFieldIndex();
-  if (UNLIKELY(GetDeclaringClass()->IsAnyProxyClass())) {
+  if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
     DCHECK(IsStatic());
     DCHECK_LT(field_index, 2U);
     // 0 == Class[] interfaces; 1 == Class[][] throws;
@@ -290,8 +290,8 @@
 inline mirror::Class* ArtField::GetType() {
   const uint32_t field_index = GetDexFieldIndex();
   auto* declaring_class = GetDeclaringClass();
-  if (UNLIKELY(declaring_class->IsAnyProxyClass())) {
-    return AnyProxyFindSystemClass(GetTypeDescriptor());
+  if (UNLIKELY(declaring_class->IsProxyClass())) {
+    return ProxyFindSystemClass(GetTypeDescriptor());
   }
   auto* dex_cache = declaring_class->GetDexCache();
   const DexFile* const dex_file = dex_cache->GetDexFile();
diff --git a/runtime/art_field.cc b/runtime/art_field.cc
index 3ac563a..3737e0d 100644
--- a/runtime/art_field.cc
+++ b/runtime/art_field.cc
@@ -69,8 +69,8 @@
   return nullptr;
 }
 
-mirror::Class* ArtField::AnyProxyFindSystemClass(const char* descriptor) {
-  DCHECK(GetDeclaringClass()->IsAnyProxyClass());
+mirror::Class* ArtField::ProxyFindSystemClass(const char* descriptor) {
+  DCHECK(GetDeclaringClass()->IsProxyClass());
   return Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(), descriptor);
 }
 
diff --git a/runtime/art_field.h b/runtime/art_field.h
index 4ebe6fb..a943a34 100644
--- a/runtime/art_field.h
+++ b/runtime/art_field.h
@@ -191,9 +191,7 @@
   }
 
  private:
-  mirror::Class* AnyProxyFindSystemClass(const char* descriptor)
-      SHARED_REQUIRES(Locks::mutator_lock_);
-  mirror::Class* LambdaProxyFindSystemClass(const char* descriptor)
+  mirror::Class* ProxyFindSystemClass(const char* descriptor)
       SHARED_REQUIRES(Locks::mutator_lock_);
   mirror::Class* ResolveGetType(uint32_t type_idx) SHARED_REQUIRES(Locks::mutator_lock_);
   mirror::String* ResolveGetStringName(Thread* self, const DexFile& dex_file, uint32_t string_idx,
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index b6e811f..cf548ad 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -292,7 +292,7 @@
 }
 
 inline const char* ArtMethod::GetShorty(uint32_t* out_length) {
-  DCHECK(!IsProxyMethod() || IsLambdaProxyMethod());  // OK: lambda proxies use parent dex cache.
+  DCHECK(!IsProxyMethod());
   const DexFile* dex_file = GetDexFile();
   return dex_file->GetMethodShorty(dex_file->GetMethodId(GetDexMethodIndex()), out_length);
 }
@@ -354,31 +354,10 @@
 }
 
 inline const DexFile::TypeList* ArtMethod::GetParameterTypeList() {
-  // XX: Do proxy methods have a dex file?  not sure.
+  DCHECK(!IsProxyMethod());
   const DexFile* dex_file = GetDexFile();
-  const DexFile::MethodId* method_id = nullptr;
-
-  if (kIsDebugBuild) {
-    if (UNLIKELY(IsProxyMethod())) {
-      // Proxy method case.
-      CHECK(IsLambdaProxyMethod()) << "Cannot GetParameterTypeList for java.lang.reflect.Proxy";
-
-      //
-      // We do not have a method ID, so look up one of the supers we overrode,
-      // it will have the same exact parameter type list as we do.
-
-      // Lambda proxy classes have the dex cache from their single interface parent.
-      // Proxy classes have multiple interface parents, so they use the root dexcache instead.
-      //
-      // For lambda proxy classes only, get the type list data from the parent.
-      // (code happens to look the same as the usual non-proxy path).
-    }
-  }
-
-  method_id = &dex_file->GetMethodId(GetDexMethodIndex());
-  DCHECK(method_id != nullptr);
-
-  const DexFile::ProtoId& proto = dex_file->GetMethodPrototype(*method_id);
+  const DexFile::ProtoId& proto = dex_file->GetMethodPrototype(
+      dex_file->GetMethodId(GetDexMethodIndex()));
   return dex_file->GetProtoParameters(proto);
 }
 
@@ -418,20 +397,12 @@
 }
 
 inline mirror::DexCache* ArtMethod::GetDexCache() {
-  DCHECK(!IsProxyMethod() || IsLambdaProxyMethod());  // OK: lambda proxies use parent dex cache.
+  DCHECK(!IsProxyMethod());
   return GetDeclaringClass()->GetDexCache();
 }
 
 inline bool ArtMethod::IsProxyMethod() {
-  return GetDeclaringClass()->IsAnyProxyClass();
-}
-
-inline bool ArtMethod::IsReflectProxyMethod() {
-  return GetDeclaringClass()->IsReflectProxyClass();
-}
-
-inline bool ArtMethod::IsLambdaProxyMethod() {
-  return GetDeclaringClass()->IsLambdaProxyClass();
+  return GetDeclaringClass()->IsProxyClass();
 }
 
 inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(size_t pointer_size) {
@@ -477,9 +448,9 @@
 void ArtMethod::VisitRoots(RootVisitorType& visitor, size_t pointer_size) {
   ArtMethod* interface_method = nullptr;
   mirror::Class* klass = declaring_class_.Read();
-  if (UNLIKELY(klass != nullptr && klass->IsAnyProxyClass())) {
+  if (UNLIKELY(klass != nullptr && klass->IsProxyClass())) {
     // For normal methods, dex cache shortcuts will be visited through the declaring class.
-    // However, for any proxies we need to keep the interface method alive, so we visit its roots.
+    // However, for proxies we need to keep the interface method alive, so we visit its roots.
     interface_method = mirror::DexCache::GetElementPtrSize(
         GetDexCacheResolvedMethods(pointer_size),
         GetDexMethodIndex(),
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 98f5aee..5a2d6c3 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -171,16 +171,8 @@
     return (GetAccessFlags() & kAccSynthetic) != 0;
   }
 
-  // Does this method live on a declaring class that is itself any proxy class?
-  // -- Returns true for both java.lang.reflect.Proxy and java.lang.LambdaProxy subclasses.
   bool IsProxyMethod() SHARED_REQUIRES(Locks::mutator_lock_);
 
-  // Does this method live in a java.lang.reflect.Proxy subclass?
-  bool IsReflectProxyMethod() SHARED_REQUIRES(Locks::mutator_lock_);
-
-  // Does this method live in a java.lang.LambdaProxy subclass?
-  bool IsLambdaProxyMethod() SHARED_REQUIRES(Locks::mutator_lock_);
-
   bool IsPreverified() {
     return (GetAccessFlags() & kAccPreverified) != 0;
   }
@@ -282,15 +274,7 @@
                                             uint32_t name_and_signature_idx)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
-  // Invoke this method, passing all the virtual registers in args.
-  // -- args_size must be the size in bytes (not size in words)!
-  // -- shorty must be the method shorty (i.e. it includes the return type).
-  // The result is set when the method finishes execution successfully.
-  void Invoke(Thread* self,
-              uint32_t* args,
-              uint32_t args_size,  // NOTE: size in bytes
-              /*out*/JValue* result,
-              const char* shorty)
+  void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
   const void* GetEntryPointFromQuickCompiledCode() {
@@ -444,9 +428,6 @@
 
   mirror::DexCache* GetDexCache() SHARED_REQUIRES(Locks::mutator_lock_);
 
-  // Returns the current method ('this') if this is a regular, non-proxy method.
-  // Otherwise, when this class is a proxy (IsProxyMethod), look-up the original interface's
-  // method (that the proxy is "overriding") and return that.
   ALWAYS_INLINE ArtMethod* GetInterfaceMethodIfProxy(size_t pointer_size)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index 785a9be..b548dfb 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -19,12 +19,9 @@
 
 #if defined(__cplusplus)
 #include "art_method.h"
-#include "lambda/art_lambda_method.h"
-#include "lambda/closure.h"
 #include "gc/allocator/rosalloc.h"
 #include "lock_word.h"
 #include "mirror/class.h"
-#include "mirror/lambda_proxy.h"
 #include "mirror/string.h"
 #include "runtime.h"
 #include "thread.h"
@@ -52,8 +49,6 @@
 #define ADD_TEST_EQ(x, y) CHECK_EQ(x, y);
 #endif
 
-namespace art {
-
 static inline void CheckAsmSupportOffsetsAndSizes() {
 #else
 #define ADD_TEST_EQ(x, y)
@@ -303,80 +298,9 @@
             static_cast<int32_t>(art::gc::allocator::RosAlloc::RunSlotNextOffset()))
 // Assert this so that we can avoid zeroing the next field by installing the class pointer.
 ADD_TEST_EQ(ROSALLOC_SLOT_NEXT_OFFSET, MIRROR_OBJECT_CLASS_OFFSET)
-// Working with raw lambdas (lambda::Closure) in raw memory:
-//
-//     |---------------------|
-//     | ArtLambdaMethod*    |  <-- pointer to lambda art method, has the info like the size.
-//     |---------------------|  <-- 'data offset'
-//     | [ Dynamic Size ]    |  <-- OPTIONAL: only if the ArtLambdaMethod::dynamic_size_ is true.
-//     |---------------------|
-//     | Captured Variables  |
-//     |        ...          |
-//     |---------------------|  <-- total length determined by "dynamic size" if it is present,
-//                                  otherwise by the ArtLambdaMethod::static_size_
-
-// Offset from start of lambda::Closure to the ArtLambdaMethod*.
-#define LAMBDA_CLOSURE_METHOD_OFFSET 0
-ADD_TEST_EQ(static_cast<size_t>(LAMBDA_CLOSURE_METHOD_OFFSET),
-            offsetof(art::lambda::ClosureStorage, lambda_info_))
-// Offset from the start of lambda::Closure to the data (captured vars or dynamic size).
-#define LAMBDA_CLOSURE_DATA_OFFSET __SIZEOF_POINTER__
-ADD_TEST_EQ(static_cast<size_t>(LAMBDA_CLOSURE_DATA_OFFSET),
-            offsetof(art::lambda::ClosureStorage, captured_))
-// Offsets to captured variables intentionally omitted as it needs a runtime branch.
-
-// The size of a lambda closure after it's been compressed down for storage.
-// -- Although a lambda closure is a virtual register pair (64-bit), we only need 32-bit
-//    to track the pointer when we are on 32-bit architectures.
-//    Both the compiler and the runtime therefore compress the closure down for 32-bit archs.
-#define LAMBDA_CLOSURE_COMPRESSED_POINTER_SIZE __SIZEOF_POINTER__
-ADD_TEST_EQ(static_cast<size_t>(LAMBDA_CLOSURE_COMPRESSED_POINTER_SIZE),
-            sizeof(art::lambda::Closure*))
-
-// Working with boxed innate lambdas (as a mirror::Object) in raw memory:
-// --- Note that this layout only applies to lambdas originally made with create-lambda.
-// --- Boxing a lambda created from a new-instance instruction is simply the original object.
-//
-//     |---------------------|
-//     |   object header     |
-//     |---------------------|
-//     | lambda::Closure*    | <-- long on 64-bit, int on 32-bit
-//     |---------------------|
-#define MIRROR_OBJECT_BOXED_INNATE_LAMBDA_CLOSURE_POINTER_OFFSET (MIRROR_OBJECT_HEADER_SIZE)
-ADD_TEST_EQ(static_cast<size_t>(MIRROR_OBJECT_BOXED_INNATE_LAMBDA_CLOSURE_POINTER_OFFSET),
-            art::mirror::LambdaProxy::GetInstanceFieldOffsetClosure().SizeValue())
-            // Equivalent to (private) offsetof(art::mirror::LambdaProxy, closure_))
-
-// Working with boxed innate lambdas (as a mirror::Object) in raw memory:
-// --- Note that this layout only applies to lambdas originally made with create-lambda.
-// --- Boxing a lambda created from a new-instance instruction is simply the original object.
-//
-//     |---------------------|
-//     |   object header     |
-//     |---------------------|
-//     | lambda::Closure*    | <-- long on 64-bit, int on 32-bit
-//     |---------------------|
-#define ART_LAMBDA_METHOD_ART_METHOD_OFFSET (0)
-ADD_TEST_EQ(static_cast<size_t>(ART_LAMBDA_METHOD_ART_METHOD_OFFSET),
-            art::lambda::ArtLambdaMethod::GetArtMethodOffset())
-
-#if defined(NDEBUG)
-// Release should be faaast. So just jump directly to the lambda method.
-#define LAMBDA_PROXY_SETUP_FRAME 0
-#else
-// Debug can be slower, and we want to get better stack traces. Set up a frame.
-#define LAMBDA_PROXY_SETUP_FRAME 1
-#endif
-
-// For WIP implementation, lambda types are all "longs"
-// which means on a 32-bit implementation we need to fill the argument with 32-bit 0s
-// whenever we invoke a method with a lambda in it.
-// TODO: remove all usages of this once we go to a proper \LambdaType; system.
-#define LAMBDA_INVOKE_USES_LONG 1
 
 #if defined(__cplusplus)
 }  // End of CheckAsmSupportOffsets.
-}  // namespace art
 #endif
 
 #endif  // ART_RUNTIME_ASM_SUPPORT_H_
diff --git a/runtime/base/allocator.h b/runtime/base/allocator.h
index e2ade07..969f5b9 100644
--- a/runtime/base/allocator.h
+++ b/runtime/base/allocator.h
@@ -53,7 +53,6 @@
   kAllocatorTagClassTable,
   kAllocatorTagInternTable,
   kAllocatorTagLambdaBoxTable,
-  kAllocatorTagLambdaProxyClassBoxTable,
   kAllocatorTagMaps,
   kAllocatorTagLOS,
   kAllocatorTagSafeMap,
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index 6ca56f5..70bd398 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -65,7 +65,6 @@
 Mutex* Locks::trace_lock_ = nullptr;
 Mutex* Locks::unexpected_signal_lock_ = nullptr;
 Mutex* Locks::lambda_table_lock_ = nullptr;
-Mutex* Locks::lambda_class_table_lock_ = nullptr;
 Uninterruptible Roles::uninterruptible_;
 
 struct AllMutexData {
@@ -955,7 +954,6 @@
     DCHECK(trace_lock_ != nullptr);
     DCHECK(unexpected_signal_lock_ != nullptr);
     DCHECK(lambda_table_lock_ != nullptr);
-    DCHECK(lambda_class_table_lock_ != nullptr);
   } else {
     // Create global locks in level order from highest lock level to lowest.
     LockLevel current_lock_level = kInstrumentEntrypointsLock;
@@ -1074,10 +1072,6 @@
     DCHECK(lambda_table_lock_ == nullptr);
     lambda_table_lock_ = new Mutex("lambda table lock", current_lock_level);
 
-    UPDATE_CURRENT_LOCK_LEVEL(kLambdaClassTableLock);
-    DCHECK(lambda_class_table_lock_ == nullptr);
-    lambda_class_table_lock_ = new Mutex("lambda class table lock", current_lock_level);
-
     UPDATE_CURRENT_LOCK_LEVEL(kAbortLock);
     DCHECK(abort_lock_ == nullptr);
     abort_lock_ = new Mutex("abort lock", current_lock_level, true);
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index e2d7062..d4c9057 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -60,7 +60,6 @@
   kUnexpectedSignalLock,
   kThreadSuspendCountLock,
   kAbortLock,
-  kLambdaClassTableLock,
   kLambdaTableLock,
   kJdwpSocketLock,
   kRegionSpaceRegionLock,
@@ -693,10 +692,6 @@
   // Allow reader-writer mutual exclusion on the boxed table of lambda objects.
   // TODO: this should be a RW mutex lock, except that ConditionVariables don't work with it.
   static Mutex* lambda_table_lock_ ACQUIRED_AFTER(mutator_lock_);
-
-  // Allow reader-writer mutual exclusion on the boxed table of lambda proxy classes.
-  // TODO: this should be a RW mutex lock, except that ConditionVariables don't work with it.
-  static Mutex* lambda_class_table_lock_ ACQUIRED_AFTER(lambda_table_lock_);
 };
 
 class Roles {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 8a0d8d4..2dd2a83 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -56,7 +56,6 @@
 #include "interpreter/interpreter.h"
 #include "jit/jit.h"
 #include "jit/jit_code_cache.h"
-#include "lambda/box_class_table.h"
 #include "leb128.h"
 #include "linear_alloc.h"
 #include "mirror/class.h"
@@ -65,7 +64,6 @@
 #include "mirror/dex_cache-inl.h"
 #include "mirror/field.h"
 #include "mirror/iftable-inl.h"
-#include "mirror/lambda_proxy.h"
 #include "mirror/method.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
@@ -583,9 +581,6 @@
   // Create java.lang.reflect.Proxy root.
   SetClassRoot(kJavaLangReflectProxy, FindSystemClass(self, "Ljava/lang/reflect/Proxy;"));
 
-  // Create java.lang.LambdaProxy root.
-  SetClassRoot(kJavaLangLambdaProxy, FindSystemClass(self, "Ljava/lang/LambdaProxy;"));
-
   // Create java.lang.reflect.Field.class root.
   auto* class_root = FindSystemClass(self, "Ljava/lang/reflect/Field;");
   CHECK(class_root != nullptr);
@@ -1262,7 +1257,6 @@
   }
   delete data.allocator;
   delete data.class_table;
-  delete data.lambda_box_class_table;
 }
 
 mirror::PointerArray* ClassLinker::AllocPointerArray(Thread* self, size_t length) {
@@ -1904,10 +1898,8 @@
 // Special case to get oat code without overwriting a trampoline.
 const void* ClassLinker::GetQuickOatCodeFor(ArtMethod* method) {
   CHECK(method->IsInvokable()) << PrettyMethod(method);
-  if (method->IsReflectProxyMethod()) {
+  if (method->IsProxyMethod()) {
     return GetQuickProxyInvokeHandler();
-  } else if (method->IsLambdaProxyMethod()) {
-    return GetQuickLambdaProxyInvokeHandler();
   }
   bool found;
   OatFile::OatMethod oat_method = FindOatMethodFor(method, &found);
@@ -3265,7 +3257,7 @@
   klass->SetName(soa.Decode<mirror::String*>(name));
   klass->SetDexCache(GetClassRoot(kJavaLangReflectProxy)->GetDexCache());
   mirror::Class::SetStatus(klass, mirror::Class::kStatusIdx, self);
-  std::string descriptor(GetDescriptorForAnyProxy(klass.Get()));
+  std::string descriptor(GetDescriptorForProxy(klass.Get()));
   const size_t hash = ComputeModifiedUtf8Hash(descriptor.c_str());
 
   // Needs to be before we insert the class so that the allocator field is set.
@@ -3385,228 +3377,23 @@
                                                decoded_name->ToModifiedUtf8().c_str()));
     CHECK_EQ(PrettyField(klass->GetStaticField(1)), throws_field_name);
 
-    CHECK_EQ(klass.Get()->GetInterfacesForAnyProxy(),
+    CHECK_EQ(klass.Get()->GetInterfaces(),
              soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces));
-    CHECK_EQ(klass.Get()->GetThrowsForAnyProxy(),
+    CHECK_EQ(klass.Get()->GetThrows(),
              soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class>>*>(throws));
   }
   return klass.Get();
 }
 
-mirror::Class* ClassLinker::CreateLambdaProxyClass(ScopedObjectAccessAlreadyRunnable& soa,
-                                                   jstring name,
-                                                   jobjectArray interfaces,
-                                                   jobject loader,
-                                                   jobjectArray methods,
-                                                   jobjectArray throws,
-                                                   bool* already_exists) {
-  DCHECK(already_exists != nullptr);
-  *already_exists = false;
-
-  Thread* self = soa.Self();
-  StackHandleScope<10> hs(self);
-
-  // Allocate a new java.lang.Class object for a mirror::Proxy.
-  MutableHandle<mirror::Class> klass =
-      hs.NewHandle(AllocClass(self, GetClassRoot(kJavaLangClass), sizeof(mirror::Class)));
-  if (klass.Get() == nullptr) {
-    CHECK(self->IsExceptionPending());  // OOME.
-    return nullptr;
-  }
-  DCHECK(klass->GetClass() != nullptr);
-  klass->SetObjectSize(sizeof(mirror::LambdaProxy));
-
-  // Set the class access flags incl. preverified, so we do not try to set the flag on the methods.
-  klass->SetAccessFlags(kAccClassIsLambdaProxy | kAccPublic | kAccFinal | kAccPreverified);
-  klass->SetClassLoader(soa.Decode<mirror::ClassLoader*>(loader));
-  DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
-  klass->SetName(soa.Decode<mirror::String*>(name));
-  klass->SetDexCache(GetClassRoot(kJavaLangLambdaProxy)->GetDexCache());
-  // Set the status to be just before after loading it, but before anything is resolved.
-  mirror::Class::SetStatus(klass, mirror::Class::kStatusIdx, self);
-  // Convert "foo.bar.baz" string to "Lfoo/bar/baz;"
-  std::string type_descriptor(GetDescriptorForAnyProxy(klass.Get()));
-
-  mirror::Class* existing;
-  {
-    const size_t hash = ComputeModifiedUtf8Hash(type_descriptor.c_str());
-
-    // Insert the class before loading the fields as the field roots
-    // (ArtField::declaring_class_) are only visited from the class
-    // table. There can't be any suspend points between inserting the
-    // class and setting the field arrays below.
-    existing = InsertClass(type_descriptor.c_str(), klass.Get(), hash);
-  }
-  if (UNLIKELY(existing != nullptr)) {
-    // We had already made the lambda proxy previously. Return it.
-
-    *already_exists = true;
-    return existing;
-    // Let the GC clean up the class we had already allocated but isn't being used.
-  }
-
-  // Needs to be after we insert the class so that the allocator field is set.
-  LinearAlloc* const allocator = GetOrCreateAllocatorForClassLoader(klass->GetClassLoader());
-
-  // Instance fields are inherited, but we add a couple of static fields...
-  LengthPrefixedArray<ArtField>* sfields =
-      AllocArtFieldArray(self, allocator, mirror::LambdaProxy::kStaticFieldCount);
-  klass->SetSFieldsPtr(sfields);
-
-  // 1. Create a static field 'interfaces' that holds the _declared_ interfaces implemented by
-  // our proxy, so Class.getInterfaces doesn't return the flattened set.
-  // -- private static java.lang.Class[] interfaces;  // list of declared interfaces
-  ArtField& interfaces_sfield = sfields->At(mirror::LambdaProxy::kStaticFieldIndexInterfaces);
-  interfaces_sfield.SetDexFieldIndex(mirror::LambdaProxy::kStaticFieldIndexInterfaces);
-  interfaces_sfield.SetDeclaringClass(klass.Get());
-  interfaces_sfield.SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
-
-  // 2. Create a static field 'throws' that holds the classes of exceptions thrown by our methods.
-  // This is returned by java.lang.reflect.Method#getExceptionTypes()
-  // --- private static java.lang.Class[][] throws;  // maps vtable id to list of classes.
-  ArtField& throws_sfield = sfields->At(mirror::LambdaProxy::kStaticFieldIndexThrows);
-  throws_sfield.SetDexFieldIndex(mirror::LambdaProxy::kStaticFieldIndexThrows);
-  throws_sfield.SetDeclaringClass(klass.Get());
-  throws_sfield.SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
-
-  // Set up the Constructor method.
-  {
-    // Lambda proxies have 1 direct method, the constructor.
-    static constexpr size_t kNumDirectMethods = 1;
-    LengthPrefixedArray<ArtMethod>* directs = AllocArtMethodArray(self,
-                                                                  allocator,
-                                                                  kNumDirectMethods);
-    // Currently AllocArtMethodArray cannot return null, but the OOM logic is left there in case we
-    // want to throw OOM in the future.
-    if (UNLIKELY(directs == nullptr)) {
-      self->AssertPendingOOMException();
-      return nullptr;
-    }
-    klass->SetDirectMethodsPtr(directs);
-    CreateLambdaProxyConstructor(klass, klass->GetDirectMethodUnchecked(0, image_pointer_size_));
-  }
-
-  // Create virtual method using specified prototypes.
-  auto h_methods = hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Method>*>(methods));
-  DCHECK_EQ(h_methods->GetClass(), mirror::Method::ArrayClass())
-      << PrettyClass(h_methods->GetClass());
-  const size_t num_virtual_methods = h_methods->GetLength();
-  auto* virtuals = AllocArtMethodArray(self, allocator, num_virtual_methods);
-  // Currently AllocArtMethodArray cannot return null, but the OOM logic is left there in case we
-  // want to throw OOM in the future.
-  if (UNLIKELY(virtuals == nullptr)) {
-    self->AssertPendingOOMException();
-    return nullptr;
-  }
-  klass->SetVirtualMethodsPtr(virtuals);
-  size_t abstract_methods = 0;
-  for (size_t i = 0; i < num_virtual_methods; ++i) {
-    ArtMethod* virtual_method = klass->GetVirtualMethodUnchecked(i, image_pointer_size_);
-    ArtMethod* prototype = h_methods->Get(i)->GetArtMethod();
-    if (UNLIKELY((prototype->GetAccessFlags() & kAccDefault) != 0)) {
-      UNIMPLEMENTED(FATAL) << "Lambda proxies don't support default methods yet";
-    }
-    if (prototype->IsAbstract()) {
-      abstract_methods++;
-    }
-    VLOG(class_linker) << "Creating lambda proxy method for " << PrettyMethod(prototype);
-
-    CreateLambdaProxyMethod(klass, prototype, virtual_method);
-    DCHECK(virtual_method->GetDeclaringClass() != nullptr);
-    DCHECK(prototype->GetDeclaringClass() != nullptr);
-  }
-  // Ignore any methods from Object and default methods, it doesn't matter.
-  // Sanity check that the prototype interface is indeed compatible with lambdas.
-  DCHECK_EQ(abstract_methods, 1u)
-      << "Interface must be a single-abstract-method type" << PrettyClass(klass.Get());
-
-  // The super class is java.lang.LambdaProxy
-  klass->SetSuperClass(GetClassRoot(kJavaLangLambdaProxy));
-  // Now effectively in the loaded state.
-  mirror::Class::SetStatus(klass, mirror::Class::kStatusLoaded, self);
-  self->AssertNoPendingException();
-
-  MutableHandle<mirror::Class> new_class = hs.NewHandle<mirror::Class>(nullptr);
-  {
-    // Must hold lock on object when resolved.
-    ObjectLock<mirror::Class> resolution_lock(self, klass);
-    // Link the fields and virtual methods, creating vtable and iftables.
-    // The new class will replace the old one in the class table.
-    Handle<mirror::ObjectArray<mirror::Class>> h_interfaces(
-        hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces)));
-
-    {
-      DCHECK_EQ(1, h_interfaces->GetLength()) << "Lambda proxies must implement 1 interface only";
-      mirror::Class* single_abstract_interface = h_interfaces->Get(0);
-      DCHECK(single_abstract_interface != nullptr);
-
-      // Use the dex cache from the interface, which will enable most of the
-      // dex-using mechanisms on the class and its methods will work.
-      klass->SetDexCache(single_abstract_interface->GetDexCache());
-    }
-
-    if (!LinkClass(self, type_descriptor.c_str(), klass, h_interfaces, &new_class)) {
-      mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
-      return nullptr;
-    }
-  }
-  CHECK(klass->IsRetired());
-  CHECK_NE(klass.Get(), new_class.Get());
-  klass.Assign(new_class.Get());
-
-  CHECK_EQ(interfaces_sfield.GetDeclaringClass(), klass.Get());
-  interfaces_sfield.SetObject<false>(klass.Get(),
-                                     soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces));
-
-  CHECK_EQ(throws_sfield.GetDeclaringClass(), klass.Get());
-  throws_sfield.SetObject<false>(
-      klass.Get(), soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >*>(throws));
-
-  {
-    // Lock on klass is released. Lock new class object.
-    ObjectLock<mirror::Class> initialization_lock(self, klass);
-    mirror::Class::SetStatus(klass, mirror::Class::kStatusInitialized, self);
-  }
-
-  // Sanity checks
-  if (kIsDebugBuild) {
-    CHECK(klass->GetIFieldsPtr() == nullptr);
-    CheckLambdaProxyConstructor(klass->GetDirectMethod(0, image_pointer_size_));
-
-    for (size_t i = 0; i < num_virtual_methods; ++i) {
-      ArtMethod* virtual_method = klass->GetVirtualMethodUnchecked(i, image_pointer_size_);
-      ArtMethod* prototype = h_methods->Get(i++)->GetArtMethod();
-      CheckLambdaProxyMethod(virtual_method, prototype);
-    }
-
-    StackHandleScope<1> hs2(self);
-    Handle<mirror::String> decoded_name = hs2.NewHandle(soa.Decode<mirror::String*>(name));
-    std::string interfaces_field_name(StringPrintf("java.lang.Class[] %s.interfaces",
-                                                   decoded_name->ToModifiedUtf8().c_str()));
-    CHECK_EQ(PrettyField(klass->GetStaticField(0)), interfaces_field_name);
-
-    std::string throws_field_name(StringPrintf("java.lang.Class[][] %s.throws",
-                                               decoded_name->ToModifiedUtf8().c_str()));
-    CHECK_EQ(PrettyField(klass->GetStaticField(1)), throws_field_name);
-
-    CHECK_EQ(klass.Get()->GetInterfacesForAnyProxy(),
-             soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces));
-    CHECK_EQ(klass.Get()->GetThrowsForAnyProxy(),
-             soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class>>*>(throws));
-  }
-  return klass.Get();
-}
-
-std::string ClassLinker::GetDescriptorForAnyProxy(mirror::Class* proxy_class) {
-  DCHECK(proxy_class != nullptr);
-  DCHECK(proxy_class->IsAnyProxyClass());
+std::string ClassLinker::GetDescriptorForProxy(mirror::Class* proxy_class) {
+  DCHECK(proxy_class->IsProxyClass());
   mirror::String* name = proxy_class->GetName();
   DCHECK(name != nullptr);
   return DotToDescriptor(name->ToModifiedUtf8().c_str());
 }
 
 ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class, ArtMethod* proxy_method) {
-  DCHECK(proxy_class->IsAnyProxyClass());
+  DCHECK(proxy_class->IsProxyClass());
   DCHECK(proxy_method->IsProxyMethod());
   {
     Thread* const self = Thread::Current();
@@ -3634,7 +3421,7 @@
 
 void ClassLinker::CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* out) {
   // Create constructor for Proxy that must initialize the method.
-  CHECK_EQ(GetClassRoot(kJavaLangReflectProxy)->NumDirectMethods(), 18u);
+  CHECK_EQ(GetClassRoot(kJavaLangReflectProxy)->NumDirectMethods(), 16u);
   ArtMethod* proxy_constructor = GetClassRoot(kJavaLangReflectProxy)->GetDirectMethodUnchecked(
       2, image_pointer_size_);
   // Ensure constructor is in dex cache so that we can use the dex cache to look up the overridden
@@ -3650,38 +3437,6 @@
   out->SetDeclaringClass(klass.Get());
 }
 
-void ClassLinker::CreateLambdaProxyConstructor(Handle<mirror::Class> klass,
-                                               /*out*/ArtMethod* method_constructor) {
-  DCHECK(klass.Get() != nullptr);
-  DCHECK(method_constructor != nullptr);
-
-  // Create constructor for Proxy that must initialize the method.
-  // Lambda proxy superclass only has 1 direct method, the constructor (<init>()V)
-  CHECK_EQ(GetClassRoot(kJavaLangLambdaProxy)->NumDirectMethods(),
-           mirror::LambdaProxy::kDirectMethodCount);
-  // Get the constructor method.
-  ArtMethod* proxy_constructor = GetClassRoot(kJavaLangLambdaProxy)->GetDirectMethodUnchecked(
-      mirror::LambdaProxy::kDirectMethodIndexConstructor,
-      image_pointer_size_);
-
-  // Verify constructor method is indeed a constructor.
-  CHECK(proxy_constructor != nullptr);
-
-  // Ensure constructor is in dex cache so that we can use the dex cache to look up the overridden
-  // constructor method.
-  GetClassRoot(kJavaLangLambdaProxy)->GetDexCache()->SetResolvedMethod(
-      proxy_constructor->GetDexMethodIndex(),
-      proxy_constructor,
-      image_pointer_size_);
-
-  // Clone the existing constructor of LambdaProxy
-  // (our constructor would just invoke it so steal its code_ too).
-  method_constructor->CopyFrom(proxy_constructor, image_pointer_size_);
-  // Make this constructor public and fix the class to be our LambdaProxy version
-  method_constructor->SetAccessFlags((method_constructor->GetAccessFlags() & ~kAccProtected) | kAccPublic);
-  method_constructor->SetDeclaringClass(klass.Get());
-}
-
 void ClassLinker::CheckProxyConstructor(ArtMethod* constructor) const {
   CHECK(constructor->IsConstructor());
   auto* np = constructor->GetInterfaceMethodIfProxy(image_pointer_size_);
@@ -3690,14 +3445,6 @@
   DCHECK(constructor->IsPublic());
 }
 
-void ClassLinker::CheckLambdaProxyConstructor(ArtMethod* constructor) const {
-  CHECK(constructor->IsConstructor());
-  auto* np = constructor->GetInterfaceMethodIfProxy(image_pointer_size_);
-  CHECK_STREQ(np->GetName(), "<init>");
-  CHECK_STREQ(np->GetSignature().ToString().c_str(), "()V");
-  DCHECK(constructor->IsPublic());
-}
-
 void ClassLinker::CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prototype,
                                     ArtMethod* out) {
   // Ensure prototype is in dex cache so that we can use the dex cache to look up the overridden
@@ -3709,7 +3456,6 @@
     dex_cache->SetResolvedMethod(
         prototype->GetDexMethodIndex(), prototype, image_pointer_size_);
   }
-
   // We steal everything from the prototype (such as DexCache, invoke stub, etc.) then specialize
   // as necessary
   DCHECK(out != nullptr);
@@ -3725,42 +3471,6 @@
   out->SetEntryPointFromQuickCompiledCode(GetQuickProxyInvokeHandler());
 }
 
-void ClassLinker::CreateLambdaProxyMethod(Handle<mirror::Class> klass,
-                                          ArtMethod* prototype,
-                                          ArtMethod* out) {
-  DCHECK(prototype != nullptr);
-  DCHECK(out != nullptr);
-
-  // DO NOT go through the proxy invoke handler for the default methods. They have no idea
-  // how to handle the raw closure, so they must get the regular object when invoked.
-  CHECK_EQ(prototype->GetAccessFlags() & kAccDefault, 0u) << "Default methods must not be proxied";
-
-  // Ensure prototype is in dex cache so that we can use the dex cache to look up the overridden
-  // prototype method
-  auto* dex_cache = prototype->GetDeclaringClass()->GetDexCache();
-  // Avoid dirtying the dex cache unless we need to.
-  if (dex_cache->GetResolvedMethod(prototype->GetDexMethodIndex(), image_pointer_size_) !=
-      prototype) {
-    dex_cache->SetResolvedMethod(
-        prototype->GetDexMethodIndex(), prototype, image_pointer_size_);
-  }
-  // We steal everything from the prototype (such as DexCache, invoke stub, etc.) then specialize
-  // as necessary
-  out->CopyFrom(prototype, image_pointer_size_);
-
-  // Set class to be the concrete proxy class and clear the abstract flag, modify exceptions to
-  // the intersection of throw exceptions as defined in Proxy
-  out->SetDeclaringClass(klass.Get());
-  out->SetAccessFlags((out->GetAccessFlags() & ~kAccAbstract) | kAccFinal);
-
-  // Setting the entry point isn't safe for AOT since ASLR loads it anywhere at runtime.
-  CHECK(!Runtime::Current()->IsAotCompiler());
-
-  // At runtime the method looks like a reference and argument saving method, clone the code
-  // related parameters from this method.
-  out->SetEntryPointFromQuickCompiledCode(GetQuickLambdaProxyInvokeHandler());
-}
-
 void ClassLinker::CheckProxyMethod(ArtMethod* method, ArtMethod* prototype) const {
   // Basic sanity
   CHECK(!prototype->IsFinal());
@@ -3782,11 +3492,6 @@
            prototype->GetReturnType(true /* resolve */, image_pointer_size_));
 }
 
-void ClassLinker::CheckLambdaProxyMethod(ArtMethod* method, ArtMethod* prototype) const {
-  // same as above.
-  return CheckProxyMethod(method, prototype);
-}
-
 bool ClassLinker::CanWeInitializeClass(mirror::Class* klass, bool can_init_statics,
                                        bool can_init_parents) {
   if (can_init_statics && can_init_parents) {
@@ -4418,9 +4123,7 @@
     class_loader->SetClassTable(data.class_table);
     // Should have been set when we registered the dex file.
     data.allocator = class_loader->GetAllocator();
-    CHECK(class_loader->GetLambdaProxyCache() == nullptr);
-    data.lambda_box_class_table = new lambda::BoxClassTable();
-    class_loader->SetLambdaProxyCache(data.lambda_box_class_table);
+    CHECK(data.allocator != nullptr);
     class_loaders_.push_back(data);
   }
   return class_table;
@@ -6863,7 +6566,6 @@
     "Ljava/lang/reflect/Field;",
     "Ljava/lang/reflect/Method;",
     "Ljava/lang/reflect/Proxy;",
-    "Ljava/lang/LambdaProxy;",
     "[Ljava/lang/String;",
     "[Ljava/lang/reflect/Constructor;",
     "[Ljava/lang/reflect/Field;",
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index f073cd8..29aac31 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -40,11 +40,6 @@
   class ImageSpace;
 }  // namespace space
 }  // namespace gc
-
-namespace lambda {
-  class BoxClassTable;
-}  // namespace lambda
-
 namespace mirror {
   class ClassLoader;
   class DexCache;
@@ -87,7 +82,6 @@
     kJavaLangReflectField,
     kJavaLangReflectMethod,
     kJavaLangReflectProxy,
-    kJavaLangLambdaProxy,
     kJavaLangStringArrayClass,
     kJavaLangReflectConstructorArrayClass,
     kJavaLangReflectFieldArrayClass,
@@ -430,46 +424,12 @@
                                   jobjectArray methods,
                                   jobjectArray throws)
       SHARED_REQUIRES(Locks::mutator_lock_);
-
-  // Get the long type descriptor, e.g. "LProxyName$1234;" for the requested proxy class.
-  static std::string GetDescriptorForAnyProxy(mirror::Class* proxy_class)
+  std::string GetDescriptorForProxy(mirror::Class* proxy_class)
       SHARED_REQUIRES(Locks::mutator_lock_);
   ArtMethod* FindMethodForProxy(mirror::Class* proxy_class, ArtMethod* proxy_method)
       REQUIRES(!dex_lock_)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
-  // Create a lambda proxy class.
-  // -- Nominally used when boxing an innate lambda, since that has no corresponding class.
-  //
-  // * name must be a fully-qualified class name (and dotted), e.g. "java.lang.Runnable"
-  // * interfaces is an array of java.lang.Class for interfaces that will be the supertype
-  //   (note that there must be exactly 1 element here for a lambda interface since lambda
-  //   types can only target 1 interface).
-  // * loader must be a java.lang.ClassLoader where the proxy class will be created
-  // * methods must be an array of java.lang.reflect.Method that consists of the
-  //   deduplicated methods from all of the interfaces specified.
-  // * throws must be an array of java.lang.Class[] where each index corresponds to that of
-  //   methods, and it signifies the "throws" keyword of each method
-  //   (this is not directly used by the runtime itself, but it is available via reflection).
-  //
-  // Returns a non-null pointer to a class upon success, otherwise null and throws an exception.
-  //
-  // If the class was already created previously (with the same name but potentially different
-  // parameters), already_exists is set to true; otherwise already_exists is set to false.
-  // The already_exists value is undefined when an exception was thrown.
-  //
-  // Sidenote: interfaces is an array to simplify the libcore code which creates a Java
-  // array in an attempt to reduce code duplication.
-  // TODO: this should probably also take the target single-abstract-method as well.
-  mirror::Class* CreateLambdaProxyClass(ScopedObjectAccessAlreadyRunnable& soa,
-                                        jstring name,
-                                        jobjectArray interfaces,
-                                        jobject loader,
-                                        jobjectArray methods,
-                                        jobjectArray throws,
-                                        /*out*/bool* already_exists)
-      SHARED_REQUIRES(Locks::mutator_lock_);
-
   // Get the oat code for a method when its class isn't yet initialized
   const void* GetQuickOatCodeFor(ArtMethod* method)
       SHARED_REQUIRES(Locks::mutator_lock_);
@@ -613,7 +573,6 @@
     jweak weak_root;  // Weak root to enable class unloading.
     ClassTable* class_table;
     LinearAlloc* allocator;
-    lambda::BoxClassTable* lambda_box_class_table;
   };
 
   // Ensures that the supertype of 'klass' ('supertype') is verified. Returns false and throws
@@ -948,12 +907,8 @@
 
   void CheckProxyConstructor(ArtMethod* constructor) const
       SHARED_REQUIRES(Locks::mutator_lock_);
-  void CheckLambdaProxyConstructor(ArtMethod* constructor) const
-      SHARED_REQUIRES(Locks::mutator_lock_);
   void CheckProxyMethod(ArtMethod* method, ArtMethod* prototype) const
       SHARED_REQUIRES(Locks::mutator_lock_);
-  void CheckLambdaProxyMethod(ArtMethod* method, ArtMethod* prototype) const
-      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // For use by ImageWriter to find DexCaches for its roots
   ReaderWriterMutex* DexLock()
@@ -971,19 +926,9 @@
 
   void CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* out)
       SHARED_REQUIRES(Locks::mutator_lock_);
-
-  // Copy the constructor from java.lang.LambdaProxy into the 'klass'.
-  // The copy is written into 'method_constructor'.
-  void CreateLambdaProxyConstructor(Handle<mirror::Class> klass,
-                                    /*out*/ArtMethod* method_constructor)
-      SHARED_REQUIRES(Locks::mutator_lock_);
-
   void CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prototype, ArtMethod* out)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
-  void CreateLambdaProxyMethod(Handle<mirror::Class> klass, ArtMethod* prototype, ArtMethod* out)
-      SHARED_REQUIRES(Locks::mutator_lock_);
-
   // Ensures that methods have the kAccPreverified bit set. We use the kAccPreverfied bit on the
   // class access flags to determine whether this has been done before.
   void EnsurePreverifiedMethods(Handle<mirror::Class> c)
@@ -995,10 +940,7 @@
   // Returns null if not found.
   ClassTable* ClassTableForClassLoader(mirror::ClassLoader* class_loader)
       SHARED_REQUIRES(Locks::mutator_lock_, Locks::classlinker_classes_lock_);
-
-  // Insert a new class table if not found. Uses bootclasspath if class_loader is null.
-  // Returns either the existing table, or the new one if there wasn't one previously
-  // (the return value is always non-null).
+  // Insert a new class table if not found.
   ClassTable* InsertClassTableForClassLoader(mirror::ClassLoader* class_loader)
       SHARED_REQUIRES(Locks::mutator_lock_)
       REQUIRES(Locks::classlinker_classes_lock_);
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 4a9db1d..2c086c5 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -31,7 +31,6 @@
 #include "mirror/class-inl.h"
 #include "mirror/dex_cache.h"
 #include "mirror/field.h"
-#include "mirror/lambda_proxy.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/proxy.h"
@@ -553,7 +552,6 @@
   ClassLoaderOffsets() : CheckOffsets<mirror::ClassLoader>(false, "Ljava/lang/ClassLoader;") {
     addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, allocator_), "allocator");
     addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, class_table_), "classTable");
-    addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, lambda_proxy_cache_), "lambdaProxyCache");
     addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, packages_), "packages");
     addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, parent_), "parent");
     addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, proxyCache_), "proxyCache");
@@ -566,13 +564,6 @@
   };
 };
 
-struct LambdaProxyOffsets : public CheckOffsets<mirror::LambdaProxy> {
-  LambdaProxyOffsets() : CheckOffsets<mirror::LambdaProxy>(false, "Ljava/lang/LambdaProxy;") {
-    addOffset(OFFSETOF_MEMBER(mirror::LambdaProxy, closure_), "closure");
-  };
-};
-
-
 struct DexCacheOffsets : public CheckOffsets<mirror::DexCache> {
   DexCacheOffsets() : CheckOffsets<mirror::DexCache>(false, "Ljava/lang/DexCache;") {
     addOffset(OFFSETOF_MEMBER(mirror::DexCache, dex_), "dex");
@@ -648,7 +639,6 @@
   EXPECT_TRUE(StackTraceElementOffsets().Check());
   EXPECT_TRUE(ClassLoaderOffsets().Check());
   EXPECT_TRUE(ProxyOffsets().Check());
-  EXPECT_TRUE(LambdaProxyOffsets().Check());
   EXPECT_TRUE(DexCacheOffsets().Check());
   EXPECT_TRUE(ReferenceOffsets().Check());
   EXPECT_TRUE(FinalizerReferenceOffsets().Check());
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index e84313c..f705a50 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -55,6 +55,7 @@
   // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
   // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
   // everything else. In case you want to see all messages, comment out the line.
+  setenv("ANDROID_LOG_TAGS", "*:e", 1);
 
   art::InitLogging(argv);
   LOG(::art::INFO) << "Running main() from common_runtime_test.cc...";
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 2a92226..87e29ae 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -313,7 +313,7 @@
           reinterpret_cast<uintptr_t>(virtual_methods)) / method_size;
       CHECK_LT(throws_index, static_cast<int>(num_virtuals));
       mirror::ObjectArray<mirror::Class>* declared_exceptions =
-          proxy_class->GetThrowsForAnyProxy()->Get(throws_index);
+          proxy_class->GetThrows()->Get(throws_index);
       mirror::Class* exception_class = exception->GetClass();
       bool declares_exception = false;
       for (int32_t i = 0; i < declared_exceptions->GetLength() && !declares_exception; i++) {
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 8c2dc3e..abf9ac4 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -23,12 +23,9 @@
 #include "entrypoints/runtime_asm_entrypoints.h"
 #include "gc/accounting/card_table-inl.h"
 #include "interpreter/interpreter.h"
-#include "lambda/closure.h"
-#include "lambda/art_lambda_method.h"
 #include "method_reference.h"
 #include "mirror/class-inl.h"
 #include "mirror/dex_cache-inl.h"
-#include "mirror/lambda_proxy.h"
 #include "mirror/method.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
@@ -297,8 +294,7 @@
   // 1st GPR.
   static mirror::Object* GetProxyThisObject(ArtMethod** sp)
       SHARED_REQUIRES(Locks::mutator_lock_) {
-    // TODO: Lambda proxies only set up a frame when debugging
-    CHECK((*sp)->IsReflectProxyMethod() || ((*sp)->IsLambdaProxyMethod() /*&& kIsDebugBuild*/));
+    CHECK((*sp)->IsProxyMethod());
     CHECK_GT(kNumQuickGprArgs, 0u);
     constexpr uint32_t kThisGprIndex = 0u;  // 'this' is in the 1st GPR.
     size_t this_arg_offset = kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset +
@@ -838,9 +834,8 @@
 extern "C" uint64_t artQuickProxyInvokeHandler(
     ArtMethod* proxy_method, mirror::Object* receiver, Thread* self, ArtMethod** sp)
     SHARED_REQUIRES(Locks::mutator_lock_) {
-  DCHECK(proxy_method->GetDeclaringClass()->IsReflectProxyClass()) << PrettyMethod(proxy_method);
-  DCHECK(proxy_method->IsReflectProxyMethod()) << PrettyMethod(proxy_method);
-  DCHECK(receiver->GetClass()->IsReflectProxyClass()) << PrettyMethod(proxy_method);
+  DCHECK(proxy_method->IsProxyMethod()) << PrettyMethod(proxy_method);
+  DCHECK(receiver->GetClass()->IsProxyClass()) << PrettyMethod(proxy_method);
   // 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");
@@ -883,175 +878,6 @@
   return result.GetJ();
 }
 
-extern "C" uint64_t artQuickLambdaProxyInvokeHandler(
-    ArtMethod* proxy_method, mirror::LambdaProxy* receiver, Thread* self, ArtMethod** sp)
-    SHARED_REQUIRES(Locks::mutator_lock_) {
-  using lambda::ShortyFieldType;
-
-  DCHECK(proxy_method->GetDeclaringClass()->IsLambdaProxyClass()) << PrettyMethod(proxy_method);
-  DCHECK(proxy_method->IsLambdaProxyMethod()) << PrettyMethod(proxy_method);
-  DCHECK(receiver->GetClass()->IsLambdaProxyClass()) << PrettyMethod(proxy_method);
-
-  lambda::Closure* lambda_closure = receiver->GetClosure();
-  DCHECK(lambda_closure != nullptr);  // Should've NPEd during the invoke-interface.
-  // Learned lambdas have their own implementation of the SAM, they must not go through here.
-  DCHECK(lambda_closure->GetLambdaInfo()->IsInnateLambda());
-  ArtMethod* target_method = lambda_closure->GetTargetMethod();
-
-  // Lambda targets are always static.
-  // TODO: This should really be a target_method->IsLambda(), once we add the access flag.
-  CHECK(target_method->IsStatic()) << PrettyMethod(proxy_method) << " "
-                                   << PrettyMethod(target_method);
-
-  // Ensure we don't get thread suspension until the object arguments are safely in jobjects.
-  const char* old_cause =
-      self->StartAssertNoThreadSuspension("Adding to IRT/SF lambda proxy object arguments");
-  // Register the top of the managed stack, making stack crawlable.
-  DCHECK_EQ((*sp), proxy_method) << PrettyMethod(proxy_method);
-  self->VerifyStack();
-  // Start new JNI local reference state.
-  JNIEnvExt* env = self->GetJniEnv();
-  ScopedObjectAccessUnchecked soa(env);
-
-  // Placing arguments into args vector and remove the receiver.
-  ArtMethod* non_proxy_method = proxy_method->GetInterfaceMethodIfProxy(sizeof(void*));
-  CHECK(!non_proxy_method->IsStatic()) << PrettyMethod(proxy_method) << " "
-                                       << PrettyMethod(non_proxy_method);
-  uint32_t shorty_len = 0;
-  const char* shorty = non_proxy_method->GetShorty(/*out*/&shorty_len);
-
-  std::vector<jvalue> args;
-  // Make a quick visitor so we can restore the refs incase they move after a GC.
-  BuildQuickArgumentVisitor local_ref_visitor(sp,
-                                              false /*is_static*/,
-                                              shorty,
-                                              shorty_len,
-                                              &soa,
-                                              /*out*/&args);
-  local_ref_visitor.VisitArguments();
-
-  static_assert(lambda::kClosureIsStoredAsLong,
-                "Need to update this code once closures are no "
-                "longer treated as a 'long' in quick abi");
-
-  // Allocate one vreg more than usual because we need to convert our
-  // receiver Object (1 vreg) into a long (2 vregs).
-  // TODO: Ugly... move to traits instead?
-  const uint32_t first_arg_reg = ShortyFieldType(ShortyFieldType::kLambda).GetVirtualRegisterCount()
-        - ShortyFieldType(ShortyFieldType::kObject).GetVirtualRegisterCount();
-  const uint32_t num_vregs = lambda_closure->GetLambdaInfo()->GetArgumentVRegCount();
-  DCHECK_GE(num_vregs, first_arg_reg);
-  if (kIsDebugBuild) {
-    const char* method_shorty = non_proxy_method->GetShorty();
-    DCHECK_NE(*method_shorty, '\0') << method_shorty;
-    const char* arg_shorty = method_shorty + 1;  // Skip return type.
-
-    // Proxy method should have an object (1 vreg) receiver,
-    // Lambda method should have a lambda (2 vregs) receiver.
-    // -- All other args are the same as before.
-    // -- Make sure vreg count is what we thought it was.
-    uint32_t non_proxy_num_vregs =
-        ShortyFieldType::CountVirtualRegistersRequired(arg_shorty)  // doesn't count receiver
-        + ShortyFieldType(ShortyFieldType::kObject).GetVirtualRegisterCount();  // implicit receiver
-
-    CHECK_EQ(non_proxy_num_vregs + first_arg_reg, num_vregs)
-        << PrettyMethod(non_proxy_method) << " " << PrettyMethod(lambda_closure->GetTargetMethod());
-  }
-
-  ShadowFrameAllocaUniquePtr shadow_frame = CREATE_SHADOW_FRAME(num_vregs,
-                                                                /*link*/nullptr,
-                                                                target_method,
-                                                                /*dex_pc*/0);
-
-  // Copy our proxy method caller's arguments into this ShadowFrame.
-  BuildQuickShadowFrameVisitor local_sf_visitor(sp,
-                                                /*is_static*/false,
-                                                shorty,
-                                                shorty_len,
-                                                shadow_frame.get(),
-                                                first_arg_reg);
-
-  local_sf_visitor.VisitArguments();
-  // Now fix up the arguments, with each ArgK being a vreg:
-
-  // (Before):
-  // Arg0 = proxy receiver (LambdaProxy)
-  // Arg1 = first-user defined argument
-  // Arg2 = second user-defined argument
-  // ....
-  // ArgN = ...
-
-  // (After)
-  // Arg0 = closure (hi)
-  // Arg1 =  closure (lo) = 0x00 on 32-bit
-  // Arg2 = <?> (first user-defined argument)
-  // Arg3 = <?> (first user-defined argument)
-  // ...
-  // argN+1 = ...
-
-  // Transformation diagram:
-  /*
-     Arg0  Arg2  Arg3 ... ArgN
-       |       \     \        \
-       |        \     \        \
-     ClHi  ClLo  Arg2  Arg3 ... ArgN:
-   */
-
-  // 1) memmove vregs 1-N into 2-N+1
-  uint32_t* shadow_frame_vregs = shadow_frame->GetVRegArgs(/*i*/0);
-  if (lambda::kClosureIsStoredAsLong ||
-      sizeof(void*) != sizeof(mirror::CompressedReference<mirror::LambdaProxy>)) {
-    // Suspending here would be very bad since we are doing a raw memmove
-
-    // Move the primitive vregs over.
-    {
-      size_t shadow_frame_vregs_size = num_vregs;
-      memmove(shadow_frame_vregs + first_arg_reg,
-              shadow_frame_vregs,
-              shadow_frame_vregs_size - first_arg_reg);
-    }
-
-    // Move the reference vregs over.
-    if (LIKELY(shadow_frame->HasReferenceArray())) {
-      uint32_t* shadow_frame_references = shadow_frame_vregs + num_vregs;
-      size_t shadow_frame_references_size = num_vregs;
-      memmove(shadow_frame_references + first_arg_reg,
-              shadow_frame_references,
-              shadow_frame_references_size - first_arg_reg);
-    }
-
-    static_assert(lambda::kClosureSupportsReadBarrier == false,
-                  "Using this memmove code with a read barrier GC seems like it could be unsafe.");
-
-    static_assert(sizeof(mirror::CompressedReference<mirror::LambdaProxy>) == sizeof(uint32_t),
-                  "This block of code assumes a compressed reference fits into exactly 1 vreg");
-  }
-  // 2) replace proxy receiver with lambda
-  shadow_frame->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<uintptr_t>(lambda_closure)));
-
-  // OK: After we do the invoke, the target method takes over managing the arguments
-  //     and we won't ever access the shadow frame again (if any references moved).
-  self->EndAssertNoThreadSuspension(old_cause);
-
-  // The shadow frame vreg contents are now 'owned' by the Invoke method, and
-  // will be managed by it during a GC despite being a raw uint32_t array.
-  // We however have no guarantee that it is updated on the way out, so do not read out of the
-  // shadow frame after this call.
-  JValue result;
-  target_method->Invoke(self,
-                        shadow_frame_vregs,
-                        num_vregs * sizeof(uint32_t),
-                        /*out*/&result,
-                        target_method->GetShorty());
-
-  // Restore references on the proxy caller stack frame which might have moved.
-  // -- This is necessary because the QuickFrameInfo is just the generic runtime "RefsAndArgs"
-  //    which means that the regular stack visitor wouldn't know how to GC-move any references
-  //    that we spilled ourselves in the proxy stub.
-  local_ref_visitor.FixupReferences();
-  return result.GetJ();
-}
-
 // Read object references held in arguments from quick frames and place in a JNI local references,
 // so they don't get garbage collected.
 class RememberForGcArgumentVisitor FINAL : public QuickArgumentVisitor {
diff --git a/runtime/entrypoints/runtime_asm_entrypoints.h b/runtime/entrypoints/runtime_asm_entrypoints.h
index 1ef7585..2842c5a 100644
--- a/runtime/entrypoints/runtime_asm_entrypoints.h
+++ b/runtime/entrypoints/runtime_asm_entrypoints.h
@@ -17,10 +17,6 @@
 #ifndef ART_RUNTIME_ENTRYPOINTS_RUNTIME_ASM_ENTRYPOINTS_H_
 #define ART_RUNTIME_ENTRYPOINTS_RUNTIME_ASM_ENTRYPOINTS_H_
 
-// Define entry points to assembly routines.
-// All extern "C" functions here are defined in a corresponding assembly-only file.
-// The exact file paths are runtime/arch/$ISA/quick_entrypoints_$ISA.s
-
 namespace art {
 
 #ifndef BUILDING_LIBART
@@ -56,13 +52,6 @@
   return reinterpret_cast<const void*>(art_quick_proxy_invoke_handler);
 }
 
-// Return the address of quick stub code for handling transitions into the lambda proxy
-// invoke handler.
-extern "C" void art_quick_lambda_proxy_invoke_handler();
-static inline const void* GetQuickLambdaProxyInvokeHandler() {
-  return reinterpret_cast<const void*>(art_quick_lambda_proxy_invoke_handler);
-}
-
 // Return the address of quick stub code for resolving a method at first call.
 extern "C" void art_quick_resolution_trampoline(ArtMethod*);
 static inline const void* GetQuickResolutionStub() {
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 07f0628..da9a79e 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -672,8 +672,8 @@
     return result;
   } else if (UNLIKELY(klass->IsPrimitive<kVerifyNone>())) {
     return Primitive::Descriptor(klass->GetPrimitiveType<kVerifyNone>());
-  } else if (UNLIKELY(klass->IsAnyProxyClass<kVerifyNone>())) {
-    return Runtime::Current()->GetClassLinker()->GetDescriptorForAnyProxy(klass);
+  } else if (UNLIKELY(klass->IsProxyClass<kVerifyNone>())) {
+    return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(klass);
   } else {
     mirror::DexCache* dex_cache = klass->GetDexCache<kVerifyNone>();
     if (!IsValidContinuousSpaceObjectAddress(dex_cache)) {
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 2de8e7e..9f6699f 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -888,56 +888,12 @@
     return false;
   }
 
-  StackHandleScope<1> hs{self};  // NOLINT: [readability/braces] [4];
-
-  // Use the lambda method's class loader since it's close enough.
-  // TODO: create-lambda should capture the current method's class loader and use that instead.
-  // TODO: Do we want create-lambda to work for static methods outside of the declaring class?
-  // --> then we need to store a classloader in the lambda method. otherwise we don't
-  //     because it would always use the declaring class's class loader.
-  // TODO: add a GetClassLoader to the lambda closure which knows how to do this,
-  //       don't hardcode this here.
-  Handle<ClassLoader> current_class_loader = hs.NewHandle(
-      lambda_closure->GetTargetMethod()->GetDeclaringClass()->GetClassLoader());
-
-  // TODO: get the type ID from the instruction
-  std::string class_name;
-  {
-    // Temporary hack to read the interface corresponding to a box-lambda.
-    // TODO: The box-lambda should encode the type ID instead, so we don't need to do this.
-    {
-      // Do a hack where we read from const-string the interface name
-      mirror::Object* string_reference = shadow_frame.GetVRegReference(vreg_target_object);
-
-      CHECK(string_reference != nullptr)
-          << "box-lambda needs the type name stored in string vA (target), but it was null";
-
-      CHECK(string_reference->IsString())
-          << "box-lambda needs the type name stored in string vA (target)";
-
-      mirror::String* as_string = string_reference->AsString();
-      class_name = as_string->ToModifiedUtf8();
-    }
-
-    // Trigger class loading of the functional interface.
-    // TODO: This should actually be done by the create-lambda...
-    if (Runtime::Current()->GetClassLinker()
-            ->FindClass(self, class_name.c_str(), current_class_loader) == nullptr) {
-      CHECK(self->IsExceptionPending());
-      self->AssertPendingException();
-      return false;
-    }
-  }
-
   mirror::Object* closure_as_object =
-      Runtime::Current()->GetLambdaBoxTable()->BoxLambda(lambda_closure,
-                                                         class_name.c_str(),
-                                                         current_class_loader.Get());
+      Runtime::Current()->GetLambdaBoxTable()->BoxLambda(lambda_closure);
 
   // Failed to box the lambda, an exception was raised.
   if (UNLIKELY(closure_as_object == nullptr)) {
     CHECK(self->IsExceptionPending());
-    shadow_frame.SetVRegReference(vreg_target_object, nullptr);
     return false;
   }
 
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 11a8c2e..bf95a0e 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -102,8 +102,6 @@
   size_t lambda_captured_variable_index = 0;
   while (true) {
     dex_pc = inst->GetDexPc(insns);
-    DCHECK_LE(dex_pc, code_item->insns_size_in_code_units_)
-        << "Dex PC overflowed code item size; missing return instruction?";
     shadow_frame.SetDexPC(dex_pc);
     TraceExecution(shadow_frame, inst, dex_pc);
     inst_data = inst->Fetch16(0);
diff --git a/runtime/lambda/art_lambda_method.cc b/runtime/lambda/art_lambda_method.cc
index 0690cd1..6f9f8bb 100644
--- a/runtime/lambda/art_lambda_method.cc
+++ b/runtime/lambda/art_lambda_method.cc
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include "art_method-inl.h"
 #include "lambda/art_lambda_method.h"
 
 #include "base/logging.h"
@@ -74,12 +73,5 @@
   }
 }
 
-size_t ArtLambdaMethod::GetArgumentVRegCount() const {
-  DCHECK(GetArtMethod()->IsStatic());  // Instance methods don't have receiver in shorty.
-  const char* method_shorty = GetArtMethod()->GetShorty();
-  DCHECK_NE(*method_shorty, '\0') << method_shorty;
-  return ShortyFieldType::CountVirtualRegistersRequired(method_shorty + 1);  // skip return type
-}
-
 }  // namespace lambda
 }  // namespace art
diff --git a/runtime/lambda/art_lambda_method.h b/runtime/lambda/art_lambda_method.h
index a858bf9..ea13eb7 100644
--- a/runtime/lambda/art_lambda_method.h
+++ b/runtime/lambda/art_lambda_method.h
@@ -90,17 +90,6 @@
     return strlen(captured_variables_shorty_);
   }
 
-  // Return the offset in bytes from the start of ArtLambdaMethod to the method_.
-  // -- Only should be used by assembly (stubs) support code and compiled code.
-  static constexpr size_t GetArtMethodOffset() {
-    return offsetof(ArtLambdaMethod, method_);
-  }
-
-  // Calculate how many vregs all the arguments will use when doing an invoke.
-  // (Most primitives are 1 vregs, double/long are 2, reference is 1, lambda is 2).
-  // -- This is used to know how big to set up shadow frame when invoking into the target method.
-  size_t GetArgumentVRegCount() const SHARED_REQUIRES(Locks::mutator_lock_);
-
  private:
   // TODO: ArtMethod, or at least the entry points should be inlined into this struct
   // to avoid an extra indirect load when doing invokes.
diff --git a/runtime/lambda/box_class_table-inl.h b/runtime/lambda/box_class_table-inl.h
deleted file mode 100644
index 2fc34a7..0000000
--- a/runtime/lambda/box_class_table-inl.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_LAMBDA_BOX_CLASS_TABLE_INL_H_
-#define ART_RUNTIME_LAMBDA_BOX_CLASS_TABLE_INL_H_
-
-#include "lambda/box_class_table.h"
-#include "thread.h"
-
-namespace art {
-namespace lambda {
-
-template <typename Visitor>
-inline void BoxClassTable::VisitRoots(const Visitor& visitor) {
-  MutexLock mu(Thread::Current(), *Locks::lambda_class_table_lock_);
-  for (std::pair<UnorderedMapKeyType, ValueType>& key_value : map_) {
-    ValueType& gc_root = key_value.second;
-    visitor.VisitRoot(gc_root.AddressWithoutBarrier());
-  }
-}
-
-}  // namespace lambda
-}  // namespace art
-
-#endif  // ART_RUNTIME_LAMBDA_BOX_CLASS_TABLE_INL_H_
diff --git a/runtime/lambda/box_class_table.cc b/runtime/lambda/box_class_table.cc
deleted file mode 100644
index 1e49886..0000000
--- a/runtime/lambda/box_class_table.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "lambda/box_class_table.h"
-
-#include "base/mutex.h"
-#include "common_throws.h"
-#include "gc_root-inl.h"
-#include "lambda/closure.h"
-#include "lambda/leaking_allocator.h"
-#include "mirror/method.h"
-#include "mirror/object-inl.h"
-#include "thread.h"
-
-#include <string>
-#include <vector>
-
-namespace art {
-namespace lambda {
-
-// Create the lambda proxy class given the name of the lambda interface (e.g. Ljava/lang/Runnable;)
-// Also needs a proper class loader (or null for bootclasspath) where the proxy will be created
-// into.
-//
-// The class must **not** have already been created.
-// Returns a non-null ptr on success, otherwise returns null and has an exception set.
-static mirror::Class* CreateClass(Thread* self,
-                                  const std::string& class_name,
-                                  const Handle<mirror::ClassLoader>& class_loader)
-    SHARED_REQUIRES(Locks::mutator_lock_) {
-  ScopedObjectAccessUnchecked soa(self);
-  StackHandleScope<2> hs(self);
-
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-
-  // Find the java.lang.Class for our class name (from the class loader).
-  Handle<mirror::Class> lambda_interface =
-      hs.NewHandle(class_linker->FindClass(self, class_name.c_str(), class_loader));
-  // TODO: use LookupClass in a loop
-  // TODO: DCHECK That this doesn't actually cause the class to be loaded,
-  //       since the create-lambda should've loaded it already
-  DCHECK(lambda_interface.Get() != nullptr) << "CreateClass with class_name=" << class_name;
-  DCHECK(lambda_interface->IsInterface()) << "CreateClass with class_name=" << class_name;
-  jobject lambda_interface_class = soa.AddLocalReference<jobject>(lambda_interface.Get());
-
-  // Look up java.lang.reflect.Proxy#getLambdaProxyClass method.
-  Handle<mirror::Class> java_lang_reflect_proxy =
-      hs.NewHandle(class_linker->FindSystemClass(soa.Self(), "Ljava/lang/reflect/Proxy;"));
-  jclass java_lang_reflect_proxy_class =
-      soa.AddLocalReference<jclass>(java_lang_reflect_proxy.Get());
-  DCHECK(java_lang_reflect_proxy.Get() != nullptr);
-
-  jmethodID proxy_factory_method_id =
-      soa.Env()->GetStaticMethodID(java_lang_reflect_proxy_class,
-                                  "getLambdaProxyClass",
-                                  "(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;");
-  DCHECK(!soa.Env()->ExceptionCheck());
-
-  // Call into the java code to do the hard work of figuring out which methods and throws
-  // our lambda interface proxy needs to implement. It then calls back into the class linker
-  // on our behalf to make the proxy itself.
-  jobject generated_lambda_proxy_class =
-      soa.Env()->CallStaticObjectMethod(java_lang_reflect_proxy_class,
-                                        proxy_factory_method_id,
-                                        class_loader.ToJObject(),
-                                        lambda_interface_class);
-
-  // This can throw in which case we return null. Caller must handle.
-  return soa.Decode<mirror::Class*>(generated_lambda_proxy_class);
-}
-
-BoxClassTable::BoxClassTable() {
-}
-
-BoxClassTable::~BoxClassTable() {
-  // Don't need to do anything, classes are deleted automatically by GC
-  // when the classloader is deleted.
-  //
-  // Our table will not outlive the classloader since the classloader owns it.
-}
-
-mirror::Class* BoxClassTable::GetOrCreateBoxClass(const char* class_name,
-                                                  const Handle<mirror::ClassLoader>& class_loader) {
-  DCHECK(class_name != nullptr);
-
-  Thread* self = Thread::Current();
-
-  std::string class_name_str = class_name;
-
-  {
-    MutexLock mu(self, *Locks::lambda_class_table_lock_);
-
-    // Attempt to look up this class, it's possible it was already created previously.
-    // If this is the case we *must* return the same class as before to maintain
-    // referential equality between box instances.
-    //
-    // In managed code:
-    //   Functional f = () -> 5;  // vF = create-lambda
-    //   Object a = f;            // vA = box-lambda vA
-    //   Object b = f;            // vB = box-lambda vB
-    //   assert(a.getClass() == b.getClass())
-    //   assert(a == b)
-    ValueType value = FindBoxedClass(class_name_str);
-    if (!value.IsNull()) {
-      return value.Read();
-    }
-  }
-
-  // Otherwise we need to generate a class ourselves and insert it into the hash map
-
-  // Release the table lock here, which implicitly allows other threads to suspend
-  // (since the GC callbacks will not block on trying to acquire our lock).
-  // We also don't want to call into the class linker with the lock held because
-  // our lock level is lower.
-  self->AllowThreadSuspension();
-
-  // Create a lambda proxy class, within the specified class loader.
-  mirror::Class* lambda_proxy_class = CreateClass(self, class_name_str, class_loader);
-
-  // There are no thread suspension points after this, so we don't need to put it into a handle.
-  ScopedAssertNoThreadSuspension soants{self, "BoxClassTable::GetOrCreateBoxClass"};  // NOLINT:  [readability/braces] [4]
-
-  if (UNLIKELY(lambda_proxy_class == nullptr)) {
-    // Most likely an OOM has occurred.
-    CHECK(self->IsExceptionPending());
-    return nullptr;
-  }
-
-  {
-    MutexLock mu(self, *Locks::lambda_class_table_lock_);
-
-    // Possible, but unlikely, that someone already came in and made a proxy class
-    // on another thread.
-    ValueType value = FindBoxedClass(class_name_str);
-    if (UNLIKELY(!value.IsNull())) {
-      DCHECK_EQ(lambda_proxy_class, value.Read());
-      return value.Read();
-    }
-
-    // Otherwise we made a brand new proxy class.
-    // The class itself is cleaned up by the GC (e.g. class unloading) later.
-
-    // Actually insert into the table.
-    map_.Insert({std::move(class_name_str), ValueType(lambda_proxy_class)});
-  }
-
-  return lambda_proxy_class;
-}
-
-BoxClassTable::ValueType BoxClassTable::FindBoxedClass(const std::string& class_name) const {
-  auto map_iterator = map_.Find(class_name);
-  if (map_iterator != map_.end()) {
-    const std::pair<UnorderedMapKeyType, ValueType>& key_value_pair = *map_iterator;
-    const ValueType& value = key_value_pair.second;
-
-    DCHECK(!value.IsNull());  // Never store null boxes.
-    return value;
-  }
-
-  return ValueType(nullptr);
-}
-
-void BoxClassTable::EmptyFn::MakeEmpty(std::pair<UnorderedMapKeyType, ValueType>& item) const {
-  item.first.clear();
-
-  Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
-  item.second = ValueType();  // Also clear the GC root.
-}
-
-bool BoxClassTable::EmptyFn::IsEmpty(const std::pair<UnorderedMapKeyType, ValueType>& item) const {
-  bool is_empty = item.first.empty();
-  DCHECK_EQ(item.second.IsNull(), is_empty);
-
-  return is_empty;
-}
-
-bool BoxClassTable::EqualsFn::operator()(const UnorderedMapKeyType& lhs,
-                                         const UnorderedMapKeyType& rhs) const {
-  // Be damn sure the classes don't just move around from under us.
-  Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
-
-  // Being the same class name isn't enough, must also have the same class loader.
-  // When we are in the same class loader, classes are equal via the pointer.
-  return lhs == rhs;
-}
-
-size_t BoxClassTable::HashFn::operator()(const UnorderedMapKeyType& key) const {
-  return std::hash<std::string>()(key);
-}
-
-}  // namespace lambda
-}  // namespace art
diff --git a/runtime/lambda/box_class_table.h b/runtime/lambda/box_class_table.h
deleted file mode 100644
index 17e1026..0000000
--- a/runtime/lambda/box_class_table.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ART_RUNTIME_LAMBDA_BOX_CLASS_TABLE_H_
-#define ART_RUNTIME_LAMBDA_BOX_CLASS_TABLE_H_
-
-#include "base/allocator.h"
-#include "base/hash_map.h"
-#include "gc_root.h"
-#include "base/macros.h"
-#include "base/mutex.h"
-#include "object_callbacks.h"
-
-#include <stdint.h>
-
-namespace art {
-
-class ArtMethod;  // forward declaration
-template<class T> class Handle;  // forward declaration
-
-namespace mirror {
-class Class;  // forward declaration
-class ClassLoader;  // forward declaration
-class LambdaProxy;  // forward declaration
-class Object;  // forward declaration
-}  // namespace mirror
-
-namespace lambda {
-struct Closure;  // forward declaration
-
-/*
- * Store a table of boxed lambdas. This is required to maintain object referential equality
- * when a lambda is re-boxed.
- *
- * Conceptually, we store a mapping of Class Name -> Weak Reference<Class>.
- * When too many objects get GCd, we shrink the underlying table to use less space.
- */
-class BoxClassTable FINAL {
- public:
-  // TODO: This should take a LambdaArtMethod instead, read class name from that.
-  // Note: null class_loader means bootclasspath.
-  mirror::Class* GetOrCreateBoxClass(const char* class_name,
-                                     const Handle<mirror::ClassLoader>& class_loader)
-      REQUIRES(!Locks::lambda_class_table_lock_, !Roles::uninterruptible_)
-      SHARED_REQUIRES(Locks::mutator_lock_);
-
-  // Sweep strong references to lambda class boxes. Update the addresses if the objects
-  // have been moved, and delete them from the table if the objects have been cleaned up.
-  template <typename Visitor>
-  void VisitRoots(const Visitor& visitor)
-      NO_THREAD_SAFETY_ANALYSIS  // for object marking requiring heap bitmap lock
-      REQUIRES(!Locks::lambda_class_table_lock_)
-      SHARED_REQUIRES(Locks::mutator_lock_);
-
-  BoxClassTable();
-  ~BoxClassTable();
-
- private:
-  // We only store strong GC roots in our table.
-  using ValueType = GcRoot<mirror::Class>;
-
-  // Attempt to look up the class in the map, or return null if it's not there yet.
-  ValueType FindBoxedClass(const std::string& class_name) const
-      SHARED_REQUIRES(Locks::lambda_class_table_lock_);
-
-  // Store the key as a string so that we can have our own copy of the class name.
-  using UnorderedMapKeyType = std::string;
-
-  // EmptyFn implementation for art::HashMap
-  struct EmptyFn {
-    void MakeEmpty(std::pair<UnorderedMapKeyType, ValueType>& item) const
-        NO_THREAD_SAFETY_ANALYSIS;
-        // SHARED_REQUIRES(Locks::mutator_lock_);
-
-    bool IsEmpty(const std::pair<UnorderedMapKeyType, ValueType>& item) const;
-  };
-
-  // HashFn implementation for art::HashMap
-  struct HashFn {
-    size_t operator()(const UnorderedMapKeyType& key) const
-        NO_THREAD_SAFETY_ANALYSIS;
-        // SHARED_REQUIRES(Locks::mutator_lock_);
-  };
-
-  // EqualsFn implementation for art::HashMap
-  struct EqualsFn {
-    bool operator()(const UnorderedMapKeyType& lhs, const UnorderedMapKeyType& rhs) const
-        NO_THREAD_SAFETY_ANALYSIS;
-        // SHARED_REQUIRES(Locks::mutator_lock_);
-  };
-
-  using UnorderedMap = art::HashMap<UnorderedMapKeyType,
-                                    ValueType,
-                                    EmptyFn,
-                                    HashFn,
-                                    EqualsFn,
-                                    TrackingAllocator<std::pair<UnorderedMapKeyType, ValueType>,
-                                                      kAllocatorTagLambdaProxyClassBoxTable>>;
-
-  // Map of strong GC roots (lambda interface name -> lambda proxy class)
-  UnorderedMap map_ GUARDED_BY(Locks::lambda_class_table_lock_);
-
-  // Shrink the map when we get below this load factor.
-  // (This is an arbitrary value that should be large enough to prevent aggressive map erases
-  // from shrinking the table too often.)
-  static constexpr double kMinimumLoadFactor = UnorderedMap::kDefaultMinLoadFactor / 2;
-
-  DISALLOW_COPY_AND_ASSIGN(BoxClassTable);
-};
-
-}  // namespace lambda
-}  // namespace art
-
-#endif  // ART_RUNTIME_LAMBDA_BOX_CLASS_TABLE_H_
diff --git a/runtime/lambda/box_table.cc b/runtime/lambda/box_table.cc
index 0032d08..9918bb7 100644
--- a/runtime/lambda/box_table.cc
+++ b/runtime/lambda/box_table.cc
@@ -18,10 +18,8 @@
 #include "base/mutex.h"
 #include "common_throws.h"
 #include "gc_root-inl.h"
-#include "lambda/box_class_table.h"
 #include "lambda/closure.h"
 #include "lambda/leaking_allocator.h"
-#include "mirror/lambda_proxy.h"
 #include "mirror/method.h"
 #include "mirror/object-inl.h"
 #include "thread.h"
@@ -30,13 +28,12 @@
 
 namespace art {
 namespace lambda {
-// All closures are boxed into a subtype of LambdaProxy which implements the lambda's interface.
-using BoxedClosurePointerType = mirror::LambdaProxy*;
+// Temporarily represent the lambda Closure as its raw bytes in an array.
+// TODO: Generate a proxy class for the closure when boxing the first time.
+using BoxedClosurePointerType = mirror::ByteArray*;
 
-// Returns the base class for all boxed closures.
-// Note that concrete closure boxes are actually a subtype of mirror::LambdaProxy.
-static mirror::Class* GetBoxedClosureBaseClass() SHARED_REQUIRES(Locks::mutator_lock_) {
-  return Runtime::Current()->GetClassLinker()->GetClassRoot(ClassLinker::kJavaLangLambdaProxy);
+static mirror::Class* GetBoxedClosureClass() SHARED_REQUIRES(Locks::mutator_lock_) {
+  return mirror::ByteArray::GetArrayClass();
 }
 
 namespace {
@@ -57,14 +54,6 @@
       return closure;
     }
   };
-
-  struct DeleterForClosure {
-    void operator()(Closure* closure) const {
-      ClosureAllocator::Delete(closure);
-    }
-  };
-
-  using UniqueClosurePtr = std::unique_ptr<Closure, DeleterForClosure>;
 }  // namespace
 
 BoxTable::BoxTable()
@@ -86,9 +75,7 @@
   }
 }
 
-mirror::Object* BoxTable::BoxLambda(const ClosureType& closure,
-                                    const char* class_name,
-                                    mirror::ClassLoader* class_loader) {
+mirror::Object* BoxTable::BoxLambda(const ClosureType& closure) {
   Thread* self = Thread::Current();
 
   {
@@ -104,7 +91,7 @@
     //   Functional f = () -> 5;  // vF = create-lambda
     //   Object a = f;            // vA = box-lambda vA
     //   Object b = f;            // vB = box-lambda vB
-    //   assert(a == b)
+    //   assert(a == f)
     ValueType value = FindBoxedLambda(closure);
     if (!value.IsNull()) {
       return value.Read();
@@ -113,62 +100,30 @@
     // Otherwise we need to box ourselves and insert it into the hash map
   }
 
-  // Convert the Closure into a managed object instance, whose supertype of java.lang.LambdaProxy.
-
-  // TODO: Boxing a learned lambda (i.e. made with unbox-lambda) should return the original object
-  StackHandleScope<2> hs{self};  // NOLINT: [readability/braces] [4]
-
-  Handle<mirror::ClassLoader> class_loader_handle = hs.NewHandle(class_loader);
-
   // Release the lambda table lock here, so that thread suspension is allowed.
-  self->AllowThreadSuspension();
 
-  lambda::BoxClassTable* lambda_box_class_table;
+  // Convert the Closure into a managed byte[] which will serve
+  // as the temporary 'boxed' version of the lambda. This is good enough
+  // to check all the basic object identities that a boxed lambda must retain.
+  // It's also good enough to contain all the captured primitive variables.
 
-  // Find the lambda box class table, which can be in the system class loader if classloader is null
-  if (class_loader == nullptr) {
-    ScopedObjectAccessUnchecked soa(self);
-    mirror::ClassLoader* system_class_loader =
-        soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
-    lambda_box_class_table = system_class_loader->GetLambdaProxyCache();
-  } else {
-    lambda_box_class_table = class_loader_handle->GetLambdaProxyCache();
-    // OK: can't be deleted while we hold a handle to the class loader.
-  }
-  DCHECK(lambda_box_class_table != nullptr);
+  // TODO: Boxing an innate lambda (i.e. made with create-lambda) should make a proxy class
+  // TODO: Boxing a learned lambda (i.e. made with unbox-lambda) should return the original object
+  BoxedClosurePointerType closure_as_array_object =
+      mirror::ByteArray::Alloc(self, closure->GetSize());
 
-  Handle<mirror::Class> closure_class(hs.NewHandle(
-      lambda_box_class_table->GetOrCreateBoxClass(class_name, class_loader_handle)));
-  if (UNLIKELY(closure_class.Get() == nullptr)) {
+  // There are no thread suspension points after this, so we don't need to put it into a handle.
+
+  if (UNLIKELY(closure_as_array_object == nullptr)) {
     // Most likely an OOM has occurred.
-    self->AssertPendingException();
+    CHECK(self->IsExceptionPending());
     return nullptr;
   }
 
-  BoxedClosurePointerType closure_as_object = nullptr;
-  UniqueClosurePtr closure_table_copy;
-  // Create an instance of the class, and assign the pointer to the closure into it.
-  {
-    closure_as_object = down_cast<BoxedClosurePointerType>(closure_class->AllocObject(self));
-    if (UNLIKELY(closure_as_object == nullptr)) {
-      self->AssertPendingOOMException();
-      return nullptr;
-    }
-
-    // Make a copy of the closure that we will store in the hash map.
-    // The proxy instance will also point to this same hash map.
-    // Note that the closure pointer is cleaned up only after the proxy is GCd.
-    closure_table_copy.reset(ClosureAllocator::Allocate(closure->GetSize()));
-    closure_as_object->SetClosure(closure_table_copy.get());
-  }
-
-  // There are no thread suspension points after this, so we don't need to put it into a handle.
-  ScopedAssertNoThreadSuspension soants{self,                                                    // NOLINT: [whitespace/braces] [5]
-                                        "box lambda table - box lambda - no more suspensions"};  // NOLINT: [whitespace/braces] [5]
-
-  // Write the raw closure data into the proxy instance's copy of the closure.
-  closure->CopyTo(closure_table_copy.get(),
-                  closure->GetSize());
+  // Write the raw closure data into the byte[].
+  closure->CopyTo(closure_as_array_object->GetRawData(sizeof(uint8_t),  // component size
+                                                      0 /*index*/),     // index
+                  closure_as_array_object->GetLength());
 
   // The method has been successfully boxed into an object, now insert it into the hash map.
   {
@@ -179,21 +134,24 @@
     // we were allocating the object before.
     ValueType value = FindBoxedLambda(closure);
     if (UNLIKELY(!value.IsNull())) {
-      // Let the GC clean up closure_as_object at a later time.
-      // (We will not see this object when sweeping, it wasn't inserted yet.)
-      closure_as_object->SetClosure(nullptr);
+      // Let the GC clean up method_as_object at a later time.
       return value.Read();
     }
 
     // Otherwise we need to insert it into the hash map in this thread.
 
-    // The closure_table_copy is deleted by us manually when we erase it from the map.
+    // Make a copy for the box table to keep, in case the closure gets collected from the stack.
+    // TODO: GC may need to sweep for roots in the box table's copy of the closure.
+    Closure* closure_table_copy = ClosureAllocator::Allocate(closure->GetSize());
+    closure->CopyTo(closure_table_copy, closure->GetSize());
+
+    // The closure_table_copy needs to be deleted by us manually when we erase it from the map.
 
     // Actually insert into the table.
-    map_.Insert({closure_table_copy.release(), ValueType(closure_as_object)});
+    map_.Insert({closure_table_copy, ValueType(closure_as_array_object)});
   }
 
-  return closure_as_object;
+  return closure_as_array_object;
 }
 
 bool BoxTable::UnboxLambda(mirror::Object* object, ClosureType* out_closure) {
@@ -207,35 +165,29 @@
 
   mirror::Object* boxed_closure_object = object;
 
-  // Raise ClassCastException if object is not instanceof LambdaProxy
-  if (UNLIKELY(!boxed_closure_object->InstanceOf(GetBoxedClosureBaseClass()))) {
-    ThrowClassCastException(GetBoxedClosureBaseClass(), boxed_closure_object->GetClass());
+  // Raise ClassCastException if object is not instanceof byte[]
+  if (UNLIKELY(!boxed_closure_object->InstanceOf(GetBoxedClosureClass()))) {
+    ThrowClassCastException(GetBoxedClosureClass(), boxed_closure_object->GetClass());
     return false;
   }
 
   // TODO(iam): We must check that the closure object extends/implements the type
-  // specified in [type id]. This is not currently implemented since the type id is unavailable.
+  // specified in [type id]. This is not currently implemented since it's always a byte[].
 
   // If we got this far, the inputs are valid.
-  // Shuffle the java.lang.LambdaProxy back into a raw closure, then allocate it, copy,
-  // and return it.
-  BoxedClosurePointerType boxed_closure =
+  // Shuffle the byte[] back into a raw closure, then allocate it, copy, and return it.
+  BoxedClosurePointerType boxed_closure_as_array =
       down_cast<BoxedClosurePointerType>(boxed_closure_object);
 
-  DCHECK_ALIGNED(boxed_closure->GetClosure(), alignof(Closure));
-  const Closure* aligned_interior_closure = boxed_closure->GetClosure();
-  DCHECK(aligned_interior_closure != nullptr);
-
-  // TODO: we probably don't need to make a copy here later on, once there's GC support.
+  const int8_t* unaligned_interior_closure = boxed_closure_as_array->GetData();
 
   // Allocate a copy that can "escape" and copy the closure data into that.
   Closure* unboxed_closure =
-      LeakingAllocator::MakeFlexibleInstance<Closure>(self, aligned_interior_closure->GetSize());
-  DCHECK_ALIGNED(unboxed_closure, alignof(Closure));
+      LeakingAllocator::MakeFlexibleInstance<Closure>(self, boxed_closure_as_array->GetLength());
   // TODO: don't just memcpy the closure, it's unsafe when we add references to the mix.
-  memcpy(unboxed_closure, aligned_interior_closure, aligned_interior_closure->GetSize());
+  memcpy(unboxed_closure, unaligned_interior_closure, boxed_closure_as_array->GetLength());
 
-  DCHECK_EQ(unboxed_closure->GetSize(), aligned_interior_closure->GetSize());
+  DCHECK_EQ(unboxed_closure->GetSize(), static_cast<size_t>(boxed_closure_as_array->GetLength()));
 
   *out_closure = unboxed_closure;
   return true;
@@ -284,10 +236,9 @@
 
     if (new_value == nullptr) {
       // The object has been swept away.
-      Closure* closure = key_value_pair.first;
+      const ClosureType& closure = key_value_pair.first;
 
       // Delete the entry from the map.
-      // (Remove from map first to avoid accessing dangling pointer).
       map_iterator = map_.Erase(map_iterator);
 
       // Clean up the memory by deleting the closure.
@@ -339,10 +290,7 @@
 }
 
 bool BoxTable::EmptyFn::IsEmpty(const std::pair<UnorderedMapKeyType, ValueType>& item) const {
-  bool is_empty = item.first == nullptr;
-  DCHECK_EQ(item.second.IsNull(), is_empty);
-
-  return is_empty;
+  return item.first == nullptr;
 }
 
 bool BoxTable::EqualsFn::operator()(const UnorderedMapKeyType& lhs,
diff --git a/runtime/lambda/box_table.h b/runtime/lambda/box_table.h
index 9dca6ab..adb7332 100644
--- a/runtime/lambda/box_table.h
+++ b/runtime/lambda/box_table.h
@@ -30,9 +30,6 @@
 class ArtMethod;  // forward declaration
 
 namespace mirror {
-class Class;   // forward declaration
-class ClassLoader;  // forward declaration
-class LambdaProxy;  // forward declaration
 class Object;  // forward declaration
 }  // namespace mirror
 
@@ -51,11 +48,8 @@
   using ClosureType = art::lambda::Closure*;
 
   // Boxes a closure into an object. Returns null and throws an exception on failure.
-  mirror::Object* BoxLambda(const ClosureType& closure,
-                            const char* class_name,
-                            mirror::ClassLoader* class_loader)
-      REQUIRES(!Locks::lambda_table_lock_, !Roles::uninterruptible_)
-      SHARED_REQUIRES(Locks::mutator_lock_);
+  mirror::Object* BoxLambda(const ClosureType& closure)
+      SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Locks::lambda_table_lock_);
 
   // Unboxes an object back into the lambda. Returns false and throws an exception on failure.
   bool UnboxLambda(mirror::Object* object, ClosureType* out_closure)
@@ -134,16 +128,7 @@
                                     TrackingAllocator<std::pair<ClosureType, ValueType>,
                                                       kAllocatorTagLambdaBoxTable>>;
 
-  using ClassMap = art::HashMap<std::string,
-                                GcRoot<mirror::Class>,
-                                EmptyFn,
-                                HashFn,
-                                EqualsFn,
-                                TrackingAllocator<std::pair<ClosureType, ValueType>,
-                                                      kAllocatorTagLambdaProxyClassBoxTable>>;
-
   UnorderedMap map_                                          GUARDED_BY(Locks::lambda_table_lock_);
-  UnorderedMap classes_map_                                  GUARDED_BY(Locks::lambda_table_lock_);
   bool allow_new_weaks_                                      GUARDED_BY(Locks::lambda_table_lock_);
   ConditionVariable new_weaks_condition_                     GUARDED_BY(Locks::lambda_table_lock_);
 
diff --git a/runtime/lambda/closure.cc b/runtime/lambda/closure.cc
index f935e04..179e4ee 100644
--- a/runtime/lambda/closure.cc
+++ b/runtime/lambda/closure.cc
@@ -20,6 +20,9 @@
 #include "lambda/art_lambda_method.h"
 #include "runtime/mirror/object_reference.h"
 
+static constexpr const bool kClosureSupportsReferences = false;
+static constexpr const bool kClosureSupportsGarbageCollection = false;
+
 namespace art {
 namespace lambda {
 
@@ -125,10 +128,6 @@
   return const_cast<ArtMethod*>(lambda_info_->GetArtMethod());
 }
 
-ArtLambdaMethod* Closure::GetLambdaInfo() const {
-  return const_cast<ArtLambdaMethod*>(lambda_info_);
-}
-
 uint32_t Closure::GetHashCode() const {
   // Start with a non-zero constant, a prime number.
   uint32_t result = 17;
diff --git a/runtime/lambda/closure.h b/runtime/lambda/closure.h
index 38ec063..31ff194 100644
--- a/runtime/lambda/closure.h
+++ b/runtime/lambda/closure.h
@@ -33,52 +33,12 @@
 class ArtLambdaMethod;  // forward declaration
 class ClosureBuilder;   // forward declaration
 
-// TODO: Remove these constants once closures are supported properly.
-
-// Does the lambda closure support containing references? If so, all the users of lambdas
-// must be updated to also support references.
-static constexpr const bool kClosureSupportsReferences = false;
-// Does the lambda closure support being garbage collected? If so, all the users of lambdas
-// must be updated to also support garbage collection.
-static constexpr const bool kClosureSupportsGarbageCollection = false;
-// Does the lambda closure support being garbage collected with a read barrier? If so,
-// all the users of the lambdas msut also be updated to support read barrier GC.
-static constexpr const bool kClosureSupportsReadBarrier = false;
-
-// Is this closure being stored as a 'long' in shadow frames and the quick ABI?
-static constexpr const bool kClosureIsStoredAsLong = true;
-
-
-// Raw memory layout for the lambda closure.
-//
-// WARNING:
-// * This should only be used by the compiler and tests, as they need to offsetof the raw fields.
-// * Runtime/interpreter should always access closures through a Closure pointer.
-struct ClosureStorage {
-  // Compile-time known lambda information such as the type descriptor and size.
-  ArtLambdaMethod* lambda_info_;
-
-  // A contiguous list of captured variables, and possibly the closure size.
-  // The runtime size can always be determined through GetSize().
-  union {
-    // Read from here if the closure size is static (ArtLambdaMethod::IsStatic)
-    uint8_t static_variables_[0];
-    struct {
-      // Read from here if the closure size is dynamic (ArtLambdaMethod::IsDynamic)
-      size_t size_;  // The lambda_info_ and the size_ itself is also included as part of the size.
-      uint8_t variables_[0];
-    } dynamic_;
-  } captured_[0];
-  // captured_ will always consist of one array element at runtime.
-  // Set to [0] so that 'size_' is not counted in sizeof(Closure).
-};
-
 // Inline representation of a lambda closure.
 // Contains the target method and the set of packed captured variables as a copy.
 //
 // The closure itself is logically immutable, although in practice any object references
 // it (recursively) contains can be moved and updated by the GC.
-struct Closure : private ClosureStorage {
+struct PACKED(sizeof(ArtLambdaMethod*)) Closure {
   // Get the size of the Closure in bytes.
   // This is necessary in order to allocate a large enough area to copy the Closure into.
   // Do *not* copy the closure with memcpy, since references also need to get moved.
@@ -92,9 +52,6 @@
   // Get the target method, i.e. the method that will be dispatched into with invoke-lambda.
   ArtMethod* GetTargetMethod() const;
 
-  // Get the static lambda info that never changes.
-  ArtLambdaMethod* GetLambdaInfo() const;
-
   // Calculates the hash code. Value is recomputed each time.
   uint32_t GetHashCode() const SHARED_REQUIRES(Locks::mutator_lock_);
 
@@ -199,15 +156,28 @@
   static size_t GetClosureSize(const uint8_t* closure);
 
   ///////////////////////////////////////////////////////////////////////////////////
-  // NOTE: Actual fields are declared in ClosureStorage.
+
+  // Compile-time known lambda information such as the type descriptor and size.
+  ArtLambdaMethod* lambda_info_;
+
+  // A contiguous list of captured variables, and possibly the closure size.
+  // The runtime size can always be determined through GetSize().
+  union {
+    // Read from here if the closure size is static (ArtLambdaMethod::IsStatic)
+    uint8_t static_variables_[0];
+    struct {
+      // Read from here if the closure size is dynamic (ArtLambdaMethod::IsDynamic)
+      size_t size_;  // The lambda_info_ and the size_ itself is also included as part of the size.
+      uint8_t variables_[0];
+    } dynamic_;
+  } captured_[0];
+  // captured_ will always consist of one array element at runtime.
+  // Set to [0] so that 'size_' is not counted in sizeof(Closure).
+
+  friend class ClosureBuilder;
   friend class ClosureTest;
 };
 
-// ABI guarantees:
-// * Closure same size as a ClosureStorage
-// * ClosureStorage begins at the same point a Closure would begin.
-static_assert(sizeof(Closure) == sizeof(ClosureStorage), "Closure size must match ClosureStorage");
-
 }  // namespace lambda
 }  // namespace art
 
diff --git a/runtime/lambda/closure_builder.cc b/runtime/lambda/closure_builder.cc
index 7b36042..739e965 100644
--- a/runtime/lambda/closure_builder.cc
+++ b/runtime/lambda/closure_builder.cc
@@ -75,7 +75,7 @@
   if (LIKELY(is_dynamic_size_ == false)) {
     // Write in the extra bytes to store the dynamic size the first time.
     is_dynamic_size_ = true;
-    size_ += sizeof(ClosureStorage::captured_[0].dynamic_.size_);
+    size_ += sizeof(Closure::captured_[0].dynamic_.size_);
   }
 
   // A closure may be sized dynamically, so always query it for the true size.
@@ -107,40 +107,38 @@
     << "number of variables captured at runtime does not match "
     << "number of variables captured at compile time";
 
-  ClosureStorage* closure_storage = new (memory) ClosureStorage;
-  closure_storage->lambda_info_ = target_method;
+  Closure* closure = new (memory) Closure;
+  closure->lambda_info_ = target_method;
 
-  static_assert(offsetof(ClosureStorage, captured_) == kInitialSize, "wrong initial size");
+  static_assert(offsetof(Closure, captured_) == kInitialSize, "wrong initial size");
 
   size_t written_size;
   if (UNLIKELY(is_dynamic_size_)) {
     // The closure size must be set dynamically (i.e. nested lambdas).
-    closure_storage->captured_[0].dynamic_.size_ = GetSize();
-    size_t header_size = offsetof(ClosureStorage, captured_[0].dynamic_.variables_);
+    closure->captured_[0].dynamic_.size_ = GetSize();
+    size_t header_size = offsetof(Closure, captured_[0].dynamic_.variables_);
     DCHECK_LE(header_size, GetSize());
     size_t variables_size = GetSize() - header_size;
     written_size =
         WriteValues(target_method,
-                    closure_storage->captured_[0].dynamic_.variables_,
+                    closure->captured_[0].dynamic_.variables_,
                     header_size,
                     variables_size);
   } else {
     // The closure size is known statically (i.e. no nested lambdas).
     DCHECK(GetSize() == target_method->GetStaticClosureSize());
-    size_t header_size = offsetof(ClosureStorage, captured_[0].static_variables_);
+    size_t header_size = offsetof(Closure, captured_[0].static_variables_);
     DCHECK_LE(header_size, GetSize());
     size_t variables_size = GetSize() - header_size;
     written_size =
         WriteValues(target_method,
-                    closure_storage->captured_[0].static_variables_,
+                    closure->captured_[0].static_variables_,
                     header_size,
                     variables_size);
   }
 
-  // OK: The closure storage is guaranteed to be the same as a closure.
-  Closure* closure = reinterpret_cast<Closure*>(closure_storage);
-
   DCHECK_EQ(written_size, closure->GetSize());
+
   return closure;
 }
 
diff --git a/runtime/lambda/shorty_field_type.h b/runtime/lambda/shorty_field_type.h
index 54bb4d4..46ddaa9 100644
--- a/runtime/lambda/shorty_field_type.h
+++ b/runtime/lambda/shorty_field_type.h
@@ -285,39 +285,6 @@
     }
   }
 
-  // Get the number of virtual registers necessary to represent this type as a stack local.
-  inline size_t GetVirtualRegisterCount() const {
-    if (IsPrimitiveNarrow()) {
-      return 1;
-    } else if (IsPrimitiveWide()) {
-      return 2;
-    } else if (IsObject()) {
-      return kObjectReferenceSize / sizeof(uint32_t);
-    } else if (IsLambda()) {
-      return 2;
-    } else {
-      DCHECK(false) << "unknown shorty field type '" << static_cast<char>(value_) << "'";
-      UNREACHABLE();
-    }
-  }
-
-  // Count how many virtual registers would be necessary in order to store this list of shorty
-  // field types.
-  inline size_t static CountVirtualRegistersRequired(const char* shorty) {
-    size_t size = 0;
-
-    while (shorty != nullptr && *shorty != '\0') {
-      // Each argument appends to the size.
-      ShortyFieldType shorty_field{*shorty};  // NOLINT [readability/braces] [4]
-
-      size += shorty_field.GetVirtualRegisterCount();
-
-      ++shorty;
-  }
-
-    return size;
-  }
-
   // Implicitly convert to the anonymous nested inner type. Used for exhaustive switch detection.
   inline operator decltype(kByte)() const {
     return value_;
diff --git a/runtime/lambda/shorty_field_type_test.cc b/runtime/lambda/shorty_field_type_test.cc
index 430e39e..32bade9 100644
--- a/runtime/lambda/shorty_field_type_test.cc
+++ b/runtime/lambda/shorty_field_type_test.cc
@@ -218,56 +218,6 @@
   }
 }  // TEST_F
 
-TEST_F(ShortyFieldTypeTest, TestCalculateVRegSize) {
-  // Make sure the single calculation for each value is correct.
-  std::pair<size_t, char> expected_actual_single[] = {
-      // Primitives
-      { 1u, 'Z' },
-      { 1u, 'B' },
-      { 1u, 'C' },
-      { 1u, 'S' },
-      { 1u, 'I' },
-      { 1u, 'F' },
-      { 2u, 'J' },
-      { 2u, 'D' },
-      // Non-primitives
-      { 1u, 'L' },
-      { 2u, '\\' },
-  };
-
-  for (auto pair : expected_actual_single) {
-    SCOPED_TRACE(pair.second);
-    EXPECT_EQ(pair.first, ShortyFieldType(pair.second).GetVirtualRegisterCount());
-  }
-
-  // Make sure we are correctly calculating how many virtual registers a shorty descriptor takes.
-  std::pair<size_t, const char*> expected_actual[] = {
-      // Empty list
-      { 0u, "" },
-      // Primitives
-      { 1u, "Z" },
-      { 1u, "B" },
-      { 1u, "C" },
-      { 1u, "S" },
-      { 1u, "I" },
-      { 1u, "F" },
-      { 2u, "J" },
-      { 2u, "D" },
-      // Non-primitives
-      { 1u, "L" },
-      { 2u, "\\" },
-      // Multiple things at once:
-      { 10u, "ZBCSIFJD" },
-      { 5u, "LLSSI" },
-      { 6u, "LLL\\L" }
-  };
-
-  for (auto pair : expected_actual) {
-    SCOPED_TRACE(pair.second);
-    EXPECT_EQ(pair.first, ShortyFieldType::CountVirtualRegistersRequired(pair.second));
-  }
-}  // TEST_F
-
 // Helper class to probe a shorty's characteristics by minimizing copy-and-paste tests.
 template <typename T, decltype(ShortyFieldType::kByte) kShortyEnum>
 struct ShortyTypeCharacteristics {
diff --git a/runtime/lambda_proxy_test.cc b/runtime/lambda_proxy_test.cc
deleted file mode 100644
index 63d6ccc..0000000
--- a/runtime/lambda_proxy_test.cc
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <jni.h>
-#include <vector>
-
-#include "art_field-inl.h"
-#include "class_linker-inl.h"
-#include "compiler_callbacks.h"
-#include "common_compiler_test.h"
-#include "mirror/field-inl.h"
-#include "mirror/lambda_proxy.h"
-#include "mirror/method.h"
-#include "scoped_thread_state_change.h"
-
-namespace art {
-
-// The enclosing class of all the interfaces used by this test.
-// -- Defined as a macro to allow for string concatenation.
-#define TEST_INTERFACE_ENCLOSING_CLASS_NAME "LambdaInterfaces"
-// Generate out "LLambdaInterfaces$<<iface>>;" , replacing <<iface>> with the interface name.
-#define MAKE_TEST_INTERFACE_NAME(iface) ("L" TEST_INTERFACE_ENCLOSING_CLASS_NAME "$" iface ";")
-
-#define ASSERT_NOT_NULL(x) ASSERT_TRUE((x) != nullptr)
-#define ASSERT_NULL(x) ASSERT_TRUE((x) == nullptr)
-#define EXPECT_NULL(x) EXPECT_TRUE((x) == nullptr)
-
-class LambdaProxyTest  // : public CommonCompilerTest {
-    : public CommonRuntimeTest {
- public:
-  // Generate a lambda proxy class with the given name and interfaces. This is a simplification from what
-  // libcore does to fit to our test needs. We do not check for duplicated interfaces or methods and
-  // we do not declare exceptions.
-  mirror::Class* GenerateProxyClass(ScopedObjectAccess& soa,
-                                    jobject jclass_loader,
-                                    const char* class_name,
-                                    const std::vector<mirror::Class*>& interfaces)
-      SHARED_REQUIRES(Locks::mutator_lock_) {
-    CHECK(class_name != nullptr);
-    CHECK(jclass_loader != nullptr);
-
-    mirror::Class* java_lang_object =
-        class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
-    CHECK(java_lang_object != nullptr);
-
-    jclass java_lang_class = soa.AddLocalReference<jclass>(mirror::Class::GetJavaLangClass());
-
-    // Builds the interfaces array.
-    jobjectArray proxy_class_interfaces = soa.Env()->NewObjectArray(interfaces.size(),
-                                                                    java_lang_class,
-                                                                    nullptr);  // No initial element.
-    soa.Self()->AssertNoPendingException();
-    for (size_t i = 0; i < interfaces.size(); ++i) {
-      soa.Env()->SetObjectArrayElement(proxy_class_interfaces,
-                                       i,
-                                       soa.AddLocalReference<jclass>(interfaces[i]));
-    }
-
-    // Builds the method array.
-    jsize methods_count = 3;  // Object.equals, Object.hashCode and Object.toString.
-    for (mirror::Class* interface : interfaces) {
-      methods_count += interface->NumVirtualMethods();
-    }
-    jobjectArray proxy_class_methods =
-        soa.Env()->NewObjectArray(methods_count,
-                                  soa.AddLocalReference<jclass>(mirror::Method::StaticClass()),
-                                  nullptr);  // No initial element.
-    soa.Self()->AssertNoPendingException();
-
-    jsize array_index = 0;
-
-    //
-    // Fill the method array with the Object and all the interface's virtual methods.
-    //
-
-    // Add a method to 'proxy_class_methods'
-    auto add_method_to_array = [&](ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_) {
-      CHECK(method != nullptr);
-      soa.Env()->SetObjectArrayElement(proxy_class_methods,
-                                       array_index++,
-                                       soa.AddLocalReference<jobject>(
-                                           mirror::Method::CreateFromArtMethod(soa.Self(),
-                                                                               method))
-                                      );  // NOLINT: [whitespace/parens] [2]
-
-      LOG(DEBUG) << "Add " << PrettyMethod(method) << " to list of methods to generate proxy";
-    };
-    // Add a method to 'proxy_class_methods' by looking it up from java.lang.Object
-    auto add_method_to_array_by_lookup = [&](const char* name, const char* method_descriptor)
-        SHARED_REQUIRES(Locks::mutator_lock_) {
-      ArtMethod* method = java_lang_object->FindDeclaredVirtualMethod(name,
-                                                                      method_descriptor,
-                                                                      sizeof(void*));
-      add_method_to_array(method);
-    };
-
-    // Add all methods from Object.
-    add_method_to_array_by_lookup("equals",   "(Ljava/lang/Object;)Z");
-    add_method_to_array_by_lookup("hashCode", "()I");
-    add_method_to_array_by_lookup("toString", "()Ljava/lang/String;");
-
-    // Now adds all interfaces virtual methods.
-    for (mirror::Class* interface : interfaces) {
-      mirror::Class* next_class = interface;
-      do {
-        for (ArtMethod& method : next_class->GetVirtualMethods(sizeof(void*))) {
-          add_method_to_array(&method);
-        }
-        next_class = next_class->GetSuperClass();
-      } while (!next_class->IsObjectClass());
-      // Skip adding any methods from "Object".
-    }
-    CHECK_EQ(array_index, methods_count);
-
-    // Builds an empty exception array.
-    jobjectArray proxy_class_throws = soa.Env()->NewObjectArray(0 /* length */,
-                                                                java_lang_class,
-                                                                nullptr /* initial element*/);
-    soa.Self()->AssertNoPendingException();
-
-    bool already_exists;
-    mirror::Class* proxy_class =
-        class_linker_->CreateLambdaProxyClass(soa,
-                                              soa.Env()->NewStringUTF(class_name),
-                                              proxy_class_interfaces,
-                                              jclass_loader,
-                                              proxy_class_methods,
-                                              proxy_class_throws,
-                                              /*out*/&already_exists);
-
-    CHECK(!already_exists);
-
-    soa.Self()->AssertNoPendingException();
-    return proxy_class;
-  }
-
-  LambdaProxyTest() {
-  }
-
-  virtual void SetUp() {
-    CommonRuntimeTest::SetUp();
-  }
-
-  virtual void SetUpRuntimeOptions(RuntimeOptions* options ATTRIBUTE_UNUSED) {
-    // Do not have any compiler options because we don't want to run as an AOT
-    // (In particular the lambda proxy class generation isn't currently supported for AOT).
-    this->callbacks_.reset();
-  }
-
-  template <typename THandleScope>
-  Handle<mirror::Class> GenerateProxyClass(THandleScope& hs,
-                                           const char* name,
-                                           const std::vector<mirror::Class*>& interfaces)
-      SHARED_REQUIRES(Locks::mutator_lock_) {
-    return hs.NewHandle(GenerateProxyClass(*soa_, jclass_loader_, name, interfaces));
-  }
-
- protected:
-  ScopedObjectAccess* soa_ = nullptr;
-  jobject jclass_loader_ = nullptr;
-};
-
-// Creates a lambda proxy class and check ClassHelper works correctly.
-TEST_F(LambdaProxyTest, ProxyClassHelper) {
-  // gLogVerbosity.class_linker = true;  // Uncomment to enable class linker logging.
-
-  ASSERT_NOT_NULL(Thread::Current());
-
-  ScopedObjectAccess soa(Thread::Current());
-  soa_ = &soa;
-
-  // Must happen after CommonRuntimeTest finishes constructing the runtime.
-  jclass_loader_ = LoadDex(TEST_INTERFACE_ENCLOSING_CLASS_NAME);
-  jobject jclass_loader = jclass_loader_;
-
-  StackHandleScope<4> hs(soa.Self());
-  Handle<mirror::ClassLoader> class_loader(
-      hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
-
-  Handle<mirror::Class> J(hs.NewHandle(
-      class_linker_->FindClass(soa.Self(), MAKE_TEST_INTERFACE_NAME("J"), class_loader)));
-  ASSERT_TRUE(J.Get() != nullptr);
-
-  std::vector<mirror::Class*> interfaces;
-  interfaces.push_back(J.Get());
-  Handle<mirror::Class> proxy_class(hs.NewHandle(
-      GenerateProxyClass(soa, jclass_loader, "$Proxy1234", interfaces)));
-  interfaces.clear();  // Don't least possibly stale objects in the array as good practice.
-  ASSERT_TRUE(proxy_class.Get() != nullptr);
-  ASSERT_TRUE(proxy_class->IsLambdaProxyClass());
-  ASSERT_TRUE(proxy_class->IsInitialized());
-
-  EXPECT_EQ(1U, proxy_class->NumDirectInterfaces());  // LambdaInterfaces$J.
-  EXPECT_EQ(J.Get(), mirror::Class::GetDirectInterface(soa.Self(), proxy_class, 0));
-  std::string temp;
-  const char* proxy_class_descriptor = proxy_class->GetDescriptor(&temp);
-  EXPECT_STREQ("L$Proxy1234;", proxy_class_descriptor);
-  EXPECT_EQ(nullptr, proxy_class->GetSourceFile());
-
-  // Make sure all the virtual methods are marked as a proxy
-  for (ArtMethod& method : proxy_class->GetVirtualMethods(sizeof(void*))) {
-    SCOPED_TRACE(PrettyMethod(&method, /* with_signature */true));
-    EXPECT_TRUE(method.IsProxyMethod());
-    EXPECT_TRUE(method.IsLambdaProxyMethod());
-    EXPECT_FALSE(method.IsReflectProxyMethod());
-  }
-}
-
-// Creates a proxy class and check FieldHelper works correctly.
-TEST_F(LambdaProxyTest, ProxyFieldHelper) {
-  // gLogVerbosity.class_linker = true;  // Uncomment to enable class linker logging.
-
-  ASSERT_NOT_NULL(Thread::Current());
-
-  ScopedObjectAccess soa(Thread::Current());
-  soa_ = &soa;
-
-  // Must happen after CommonRuntimeTest finishes constructing the runtime.
-  jclass_loader_ = LoadDex(TEST_INTERFACE_ENCLOSING_CLASS_NAME);
-  jobject jclass_loader = jclass_loader_;
-
-  StackHandleScope<9> hs(soa.Self());
-  Handle<mirror::ClassLoader> class_loader(
-      hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
-
-  Handle<mirror::Class> I(hs.NewHandle(
-      class_linker_->FindClass(soa.Self(), MAKE_TEST_INTERFACE_NAME("I"), class_loader)));
-  ASSERT_NOT_NULL(I.Get());
-
-  // Create the lambda proxy which implements interfaces "I".
-  Handle<mirror::Class> proxy_class = GenerateProxyClass(hs,
-                                                         "$Proxy1234",
-                                                         { I.Get() });  // Interfaces.
-
-  ASSERT_NOT_NULL(proxy_class.Get());
-  EXPECT_TRUE(proxy_class->IsLambdaProxyClass());
-  EXPECT_TRUE(proxy_class->IsInitialized());
-  EXPECT_NULL(proxy_class->GetIFieldsPtr());
-
-  LengthPrefixedArray<ArtField>* static_fields = proxy_class->GetSFieldsPtr();
-  ASSERT_NOT_NULL(static_fields);
-
-  // Must have "throws" and "interfaces" static fields.
-  ASSERT_EQ(+mirror::LambdaProxy::kStaticFieldCount, proxy_class->NumStaticFields());
-
-  static constexpr const char* kInterfacesClassName = "[Ljava/lang/Class;";
-  static constexpr const char* kThrowsClassName     = "[[Ljava/lang/Class;";
-
-  // Class for "interfaces" field.
-  Handle<mirror::Class> interfaces_field_class =
-      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), kInterfacesClassName));
-  ASSERT_NOT_NULL(interfaces_field_class.Get());
-
-  // Class for "throws" field.
-  Handle<mirror::Class> throws_field_class =
-      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), kThrowsClassName));
-  ASSERT_NOT_NULL(throws_field_class.Get());
-
-  // Helper to test the static fields for correctness.
-  auto test_static_field = [&](size_t index,
-                               const char* field_name,
-                               Handle<mirror::Class>& handle_class,
-                               const char* class_name)
-      SHARED_REQUIRES(Locks::mutator_lock_) {
-    ArtField* field = &static_fields->At(index);
-    EXPECT_STREQ(field_name, field->GetName());
-    EXPECT_STREQ(class_name, field->GetTypeDescriptor());
-    EXPECT_EQ(handle_class.Get(), field->GetType</*kResolve*/true>())
-        << "Expected: " << PrettyClass(interfaces_field_class.Get()) << ", "
-        << "Actual: " << PrettyClass(field->GetType</*kResolve*/true>()) << ", "
-        << "field_name: " << field_name;
-    std::string temp;
-    EXPECT_STREQ("L$Proxy1234;", field->GetDeclaringClass()->GetDescriptor(&temp));
-    EXPECT_FALSE(field->IsPrimitiveType());
-  };
-
-  // Test "Class[] interfaces" field.
-  test_static_field(mirror::LambdaProxy::kStaticFieldIndexInterfaces,
-                    "interfaces",
-                    interfaces_field_class,
-                    kInterfacesClassName);
-
-  // Test "Class[][] throws" field.
-  test_static_field(mirror::LambdaProxy::kStaticFieldIndexThrows,
-                    "throws",
-                    throws_field_class,
-                    kThrowsClassName);
-}
-
-// Creates two proxy classes and check the art/mirror fields of their static fields.
-TEST_F(LambdaProxyTest, CheckArtMirrorFieldsOfProxyStaticFields) {
-  // gLogVerbosity.class_linker = true;  // Uncomment to enable class linker logging.
-
-  ASSERT_NOT_NULL(Thread::Current());
-
-  ScopedObjectAccess soa(Thread::Current());
-  soa_ = &soa;
-
-  // Must happen after CommonRuntimeTest finishes constructing the runtime.
-  jclass_loader_ = LoadDex(TEST_INTERFACE_ENCLOSING_CLASS_NAME);
-  jobject jclass_loader = jclass_loader_;
-
-  StackHandleScope<8> hs(soa.Self());
-  Handle<mirror::ClassLoader> class_loader(
-      hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
-
-  Handle<mirror::Class> proxyClass0;
-  Handle<mirror::Class> proxyClass1;
-  {
-    Handle<mirror::Class> L(hs.NewHandle(
-        class_linker_->FindClass(soa.Self(), MAKE_TEST_INTERFACE_NAME("L"), class_loader)));
-    ASSERT_TRUE(L.Get() != nullptr);
-
-    std::vector<mirror::Class*> interfaces = { L.Get() };
-    proxyClass0 = hs.NewHandle(GenerateProxyClass(soa, jclass_loader, "$Proxy0", interfaces));
-    proxyClass1 = hs.NewHandle(GenerateProxyClass(soa, jclass_loader, "$Proxy1", interfaces));
-  }
-
-  ASSERT_TRUE(proxyClass0.Get() != nullptr);
-  ASSERT_TRUE(proxyClass0->IsLambdaProxyClass());
-  ASSERT_TRUE(proxyClass0->IsInitialized());
-  ASSERT_TRUE(proxyClass1.Get() != nullptr);
-  ASSERT_TRUE(proxyClass1->IsLambdaProxyClass());
-  ASSERT_TRUE(proxyClass1->IsInitialized());
-
-  LengthPrefixedArray<ArtField>* static_fields0 = proxyClass0->GetSFieldsPtr();
-  ASSERT_TRUE(static_fields0 != nullptr);
-  ASSERT_EQ(2u, static_fields0->size());
-  LengthPrefixedArray<ArtField>* static_fields1 = proxyClass1->GetSFieldsPtr();
-  ASSERT_TRUE(static_fields1 != nullptr);
-  ASSERT_EQ(2u, static_fields1->size());
-
-  EXPECT_EQ(static_fields0->At(0).GetDeclaringClass(), proxyClass0.Get());
-  EXPECT_EQ(static_fields0->At(1).GetDeclaringClass(), proxyClass0.Get());
-  EXPECT_EQ(static_fields1->At(0).GetDeclaringClass(), proxyClass1.Get());
-  EXPECT_EQ(static_fields1->At(1).GetDeclaringClass(), proxyClass1.Get());
-
-  Handle<mirror::Field> field00 =
-      hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields0->At(0), true));
-  Handle<mirror::Field> field01 =
-      hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields0->At(1), true));
-  Handle<mirror::Field> field10 =
-      hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields1->At(0), true));
-  Handle<mirror::Field> field11 =
-      hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields1->At(1), true));
-  EXPECT_EQ(field00->GetArtField(), &static_fields0->At(0));
-  EXPECT_EQ(field01->GetArtField(), &static_fields0->At(1));
-  EXPECT_EQ(field10->GetArtField(), &static_fields1->At(0));
-  EXPECT_EQ(field11->GetArtField(), &static_fields1->At(1));
-}
-
-// TODO: make sure there's a non-abstract implementation of the single-abstract-method on the class.
-
-}  // namespace art
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index a8685b8..9e416dc 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -695,11 +695,7 @@
 }
 
 inline const DexFile& Class::GetDexFile() {
-  DexCache* dex_cache = GetDexCache();
-  DCHECK(dex_cache != nullptr);
-  const DexFile* dex_file = dex_cache->GetDexFile();
-  DCHECK(dex_file != nullptr);
-  return *dex_file;
+  return *GetDexCache()->GetDexFile();
 }
 
 inline bool Class::DescriptorEquals(const char* match) {
@@ -707,8 +703,8 @@
     return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1);
   } else if (IsPrimitive()) {
     return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0;
-  } else if (IsAnyProxyClass()) {
-    return AnyProxyDescriptorEquals(match);
+  } else if (IsProxyClass()) {
+    return ProxyDescriptorEquals(match);
   } else {
     const DexFile& dex_file = GetDexFile();
     const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
@@ -724,32 +720,22 @@
   }
 }
 
-inline ObjectArray<Class>* Class::GetInterfacesForAnyProxy() {
-  CHECK(IsAnyProxyClass());
+inline ObjectArray<Class>* Class::GetInterfaces() {
+  CHECK(IsProxyClass());
   // First static field.
   auto* field = GetStaticField(0);
   DCHECK_STREQ(field->GetName(), "interfaces");
   MemberOffset field_offset = field->GetOffset();
-  ObjectArray<Class>* interfaces_array = GetFieldObject<ObjectArray<Class>>(field_offset);
-
-  CHECK(interfaces_array != nullptr);
-  if (UNLIKELY(IsLambdaProxyClass())) {
-    DCHECK_EQ(1, interfaces_array->GetLength())
-        << "Lambda proxies cannot have multiple direct interfaces implemented";
-  }
-  return interfaces_array;
+  return GetFieldObject<ObjectArray<Class>>(field_offset);
 }
 
-inline ObjectArray<ObjectArray<Class>>* Class::GetThrowsForAnyProxy() {
-  CHECK(IsAnyProxyClass());
+inline ObjectArray<ObjectArray<Class>>* Class::GetThrows() {
+  CHECK(IsProxyClass());
   // Second static field.
   auto* field = GetStaticField(1);
   DCHECK_STREQ(field->GetName(), "throws");
-
   MemberOffset field_offset = field->GetOffset();
-  auto* throws_array = GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
-  CHECK(throws_array != nullptr);
-  return throws_array;
+  return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
 }
 
 inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
@@ -810,8 +796,8 @@
     return 0;
   } else if (IsArrayClass()) {
     return 2;
-  } else if (IsAnyProxyClass()) {
-    mirror::ObjectArray<mirror::Class>* interfaces = GetInterfacesForAnyProxy();
+  } else if (IsProxyClass()) {
+    mirror::ObjectArray<mirror::Class>* interfaces = GetInterfaces();
     return interfaces != nullptr ? interfaces->GetLength() : 0;
   } else {
     const DexFile::TypeList* interfaces = GetInterfaceTypeList();
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index b201293..05a9039 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -538,7 +538,6 @@
 
 ArtMethod* Class::FindClassInitializer(size_t pointer_size) {
   for (ArtMethod& method : GetDirectMethods(pointer_size)) {
-    DCHECK(reinterpret_cast<volatile void*>(&method) != nullptr);
     if (method.IsClassInitializer()) {
       DCHECK_STREQ(method.GetName(), "<clinit>");
       DCHECK_STREQ(method.GetSignature().ToString().c_str(), "()V");
@@ -743,8 +742,8 @@
     return Primitive::Descriptor(GetPrimitiveType());
   } else if (IsArrayClass()) {
     return GetArrayDescriptor(storage);
-  } else if (IsAnyProxyClass()) {
-    *storage = Runtime::Current()->GetClassLinker()->GetDescriptorForAnyProxy(this);
+  } else if (IsProxyClass()) {
+    *storage = Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this);
     return storage->c_str();
   } else {
     const DexFile& dex_file = GetDexFile();
@@ -787,10 +786,8 @@
       DCHECK_EQ(1U, idx);
       return class_linker->FindSystemClass(self, "Ljava/io/Serializable;");
     }
-  } else if (klass->IsAnyProxyClass()) {
-    // Proxies don't have a dex cache, so look at the
-    // interfaces through the magic static field "interfaces" from the proxy class itself.
-    mirror::ObjectArray<mirror::Class>* interfaces = klass.Get()->GetInterfacesForAnyProxy();
+  } else if (klass->IsProxyClass()) {
+    mirror::ObjectArray<mirror::Class>* interfaces = klass.Get()->GetInterfaces();
     DCHECK(interfaces != nullptr);
     return interfaces->Get(idx);
   } else {
@@ -829,7 +826,7 @@
 
 std::string Class::GetLocation() {
   mirror::DexCache* dex_cache = GetDexCache();
-  if (dex_cache != nullptr && !IsAnyProxyClass()) {
+  if (dex_cache != nullptr && !IsProxyClass()) {
     return dex_cache->GetLocation()->ToModifiedUtf8();
   }
   // Arrays and proxies are generated and have no corresponding dex file location.
@@ -947,9 +944,9 @@
   return new_class->AsClass();
 }
 
-bool Class::AnyProxyDescriptorEquals(const char* match) {
-  DCHECK(IsAnyProxyClass());
-  return Runtime::Current()->GetClassLinker()->GetDescriptorForAnyProxy(this) == match;
+bool Class::ProxyDescriptorEquals(const char* match) {
+  DCHECK(IsProxyClass());
+  return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this) == match;
 }
 
 // TODO: Move this to java_lang_Class.cc?
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index fcfb4b9..0ab5b97 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -352,16 +352,8 @@
   static String* ComputeName(Handle<Class> h_this) SHARED_REQUIRES(Locks::mutator_lock_)
       REQUIRES(!Roles::uninterruptible_);
 
-  // Is this either a java.lang.reflect.Proxy or a boxed lambda (java.lang.LambdaProxy)?
-  // -- Most code doesn't need to make the distinction, and this is the preferred thing to check.
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
-  bool IsAnyProxyClass() SHARED_REQUIRES(Locks::mutator_lock_) {
-    return IsReflectProxyClass() || IsLambdaProxyClass();
-  }
-
-  // Is this a java.lang.reflect.Proxy ?
-  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
-  bool IsReflectProxyClass() SHARED_REQUIRES(Locks::mutator_lock_) {
+  bool IsProxyClass() SHARED_REQUIRES(Locks::mutator_lock_) {
     // Read access flags without using getter as whether something is a proxy can be check in
     // any loaded state
     // TODO: switch to a check if the super class is java.lang.reflect.Proxy?
@@ -369,17 +361,6 @@
     return (access_flags & kAccClassIsProxy) != 0;
   }
 
-  // Is this a boxed lambda (java.lang.LambdaProxy)?
-  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
-  bool IsLambdaProxyClass() SHARED_REQUIRES(Locks::mutator_lock_) {
-    // Read access flags without using getter as whether something is a proxy can be check in
-    // any loaded state
-    // TODO: switch to a check if the super class is java.lang.reflect.Proxy?
-    uint32_t access_flags = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
-    return (access_flags & kAccClassIsLambdaProxy) != 0;
-  }
-
-
   static MemberOffset PrimitiveTypeOffset() {
     return OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_);
   }
@@ -696,8 +677,6 @@
     return MemberOffset(OFFSETOF_MEMBER(Class, super_class_));
   }
 
-  // Returns the class's ClassLoader.
-  // A null value is returned if and only if this is a boot classpath class.
   ClassLoader* GetClassLoader() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_);
 
   void SetClassLoader(ClassLoader* new_cl) SHARED_REQUIRES(Locks::mutator_lock_);
@@ -1097,8 +1076,6 @@
 
   bool DescriptorEquals(const char* match) SHARED_REQUIRES(Locks::mutator_lock_);
 
-  // Returns the backing DexFile's class definition for this class.
-  // This returns null if and only if the class has no backing DexFile.
   const DexFile::ClassDef* GetClassDef() SHARED_REQUIRES(Locks::mutator_lock_);
 
   ALWAYS_INLINE uint32_t NumDirectInterfaces() SHARED_REQUIRES(Locks::mutator_lock_);
@@ -1125,15 +1102,11 @@
                 size_t pointer_size)
       SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  // For any proxy class only. Returns list of directly implemented interfaces.
-  // The value returned is always non-null.
-  ObjectArray<Class>* GetInterfacesForAnyProxy() SHARED_REQUIRES(Locks::mutator_lock_);
+  // For proxy class only.
+  ObjectArray<Class>* GetInterfaces() SHARED_REQUIRES(Locks::mutator_lock_);
 
-  // For any proxy class only. Returns a 2d array of classes.
-  // -- The 0th dimension correponds to the vtable index.
-  // -- The 1st dimension is a list of checked exception classes.
-  // The value returned is always non-null.
-  ObjectArray<ObjectArray<Class>>* GetThrowsForAnyProxy() SHARED_REQUIRES(Locks::mutator_lock_);
+  // For proxy class only.
+  ObjectArray<ObjectArray<Class>>* GetThrows() SHARED_REQUIRES(Locks::mutator_lock_);
 
   // For reference class only.
   MemberOffset GetDisableIntrinsicFlagOffset() SHARED_REQUIRES(Locks::mutator_lock_);
@@ -1221,7 +1194,7 @@
   IterationRange<StrideIterator<ArtField>> GetIFieldsUnchecked()
       SHARED_REQUIRES(Locks::mutator_lock_);
 
-  bool AnyProxyDescriptorEquals(const char* match) SHARED_REQUIRES(Locks::mutator_lock_);
+  bool ProxyDescriptorEquals(const char* match) SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Check that the pointer size matches the one in the class linker.
   ALWAYS_INLINE static void CheckPointerSize(size_t pointer_size);
diff --git a/runtime/mirror/class_loader-inl.h b/runtime/mirror/class_loader-inl.h
index 3139117..e22ddd7 100644
--- a/runtime/mirror/class_loader-inl.h
+++ b/runtime/mirror/class_loader-inl.h
@@ -21,7 +21,6 @@
 
 #include "base/mutex-inl.h"
 #include "class_table-inl.h"
-#include "lambda/box_class_table-inl.h"
 
 namespace art {
 namespace mirror {
@@ -36,10 +35,6 @@
   if (class_table != nullptr) {
     class_table->VisitRoots(visitor);
   }
-  lambda::BoxClassTable* const lambda_box_class_table = GetLambdaProxyCache();
-  if (lambda_box_class_table != nullptr) {
-    lambda_box_class_table->VisitRoots(visitor);
-  }
 }
 
 }  // namespace mirror
diff --git a/runtime/mirror/class_loader.h b/runtime/mirror/class_loader.h
index 9d4fe96..c2a65d6 100644
--- a/runtime/mirror/class_loader.h
+++ b/runtime/mirror/class_loader.h
@@ -24,12 +24,6 @@
 struct ClassLoaderOffsets;
 class ClassTable;
 
-namespace lambda {
-
-class BoxClassTable;
-
-}  // namespace lambda
-
 namespace mirror {
 
 class Class;
@@ -66,16 +60,6 @@
                       reinterpret_cast<uint64_t>(allocator));
   }
 
-  lambda::BoxClassTable* GetLambdaProxyCache() SHARED_REQUIRES(Locks::mutator_lock_) {
-    return reinterpret_cast<lambda::BoxClassTable*>(
-        GetField64(OFFSET_OF_OBJECT_MEMBER(ClassLoader, lambda_proxy_cache_)));
-  }
-
-  void SetLambdaProxyCache(lambda::BoxClassTable* cache) SHARED_REQUIRES(Locks::mutator_lock_) {
-    SetField64<false>(OFFSET_OF_OBJECT_MEMBER(ClassLoader, lambda_proxy_cache_),
-                      reinterpret_cast<uint64_t>(cache));
-  }
-
  private:
   // Visit instance fields of the class loader as well as its associated classes.
   // Null class loader is handled by ClassLinker::VisitClassRoots.
@@ -92,7 +76,6 @@
   uint32_t padding_ ATTRIBUTE_UNUSED;
   uint64_t allocator_;
   uint64_t class_table_;
-  uint64_t lambda_proxy_cache_;
 
   friend struct art::ClassLoaderOffsets;  // for verifying offset information
   friend class Object;  // For VisitReferences
diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h
index 49c443e..8a0daec 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -57,15 +57,14 @@
   const auto pointer_size = kTransactionActive ?
       Runtime::Current()->GetClassLinker()->GetImagePointerSize() : sizeof(void*);
   auto dex_field_index = field->GetDexFieldIndex();
-  if (field->GetDeclaringClass()->IsAnyProxyClass()) {
+  auto* resolved_field = field->GetDexCache()->GetResolvedField(dex_field_index, pointer_size);
+  if (field->GetDeclaringClass()->IsProxyClass()) {
     DCHECK(field->IsStatic());
     DCHECK_LT(dex_field_index, 2U);
     // The two static fields (interfaces, throws) of all proxy classes
     // share the same dex file indices 0 and 1. So, we can't resolve
     // them in the dex cache.
   } else {
-    ArtField* resolved_field =
-        field->GetDexCache()->GetResolvedField(dex_field_index, pointer_size);
     if (resolved_field != nullptr) {
       DCHECK_EQ(resolved_field, field);
     } else {
diff --git a/runtime/mirror/field.cc b/runtime/mirror/field.cc
index b02e5b5..ff6847c 100644
--- a/runtime/mirror/field.cc
+++ b/runtime/mirror/field.cc
@@ -56,7 +56,7 @@
 
 ArtField* Field::GetArtField() {
   mirror::Class* declaring_class = GetDeclaringClass();
-  if (UNLIKELY(declaring_class->IsAnyProxyClass())) {
+  if (UNLIKELY(declaring_class->IsProxyClass())) {
     DCHECK(IsStatic());
     DCHECK_EQ(declaring_class->NumStaticFields(), 2U);
     // 0 == Class[] interfaces; 1 == Class[][] throws;
diff --git a/runtime/mirror/lambda_proxy.h b/runtime/mirror/lambda_proxy.h
deleted file mode 100644
index cff3a12..0000000
--- a/runtime/mirror/lambda_proxy.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_MIRROR_LAMBDA_PROXY_H_
-#define ART_RUNTIME_MIRROR_LAMBDA_PROXY_H_
-
-#include "lambda/closure.h"
-#include "object.h"
-
-namespace art {
-
-struct LambdaProxyOffsets;
-
-namespace mirror {
-
-// C++ mirror of a lambda proxy. Does not yet have a Java-equivalent source file.
-class MANAGED LambdaProxy FINAL : public Object {
- public:
-  // Note that the runtime subclasses generate the following static fields:
-
-  // private static java.lang.Class[] interfaces;  // Declared interfaces for the lambda interface.
-  static constexpr size_t kStaticFieldIndexInterfaces = 0;
-  // private static java.lang.Class[][] throws;    // Maps vtable id to list of classes.
-  static constexpr size_t kStaticFieldIndexThrows = 1;
-  static constexpr size_t kStaticFieldCount = 2;   // Number of fields total.
-
-  // The offset from the start of 'LambdaProxy' object, to the closure_ field, in bytes.
-  // -- This is exposed publically in order to avoid exposing 'closure_' publically.
-  // -- Only meant to be used in stubs and other compiled code, not in runtime.
-  static inline MemberOffset GetInstanceFieldOffsetClosure() {
-    return OFFSET_OF_OBJECT_MEMBER(LambdaProxy, closure_);
-  }
-
-  // Direct methods available on the class:
-  static constexpr size_t kDirectMethodIndexConstructor = 0;  // <init>()V
-  static constexpr size_t kDirectMethodCount = 1;             // Only the constructor.
-
-  // Accessors to the fields:
-
-  // Get the native closure pointer. Usually non-null outside of lambda proxy contexts.
-  lambda::Closure* GetClosure() SHARED_REQUIRES(Locks::mutator_lock_) {
-    return reinterpret_cast<lambda::Closure*>(
-        GetField64(GetInstanceFieldOffsetClosure()));
-  }
-
-  // Set the native closure pointer. Usually should be non-null outside of lambda proxy contexts.
-  void SetClosure(lambda::Closure* closure) SHARED_REQUIRES(Locks::mutator_lock_) {
-    SetField64<false>(GetInstanceFieldOffsetClosure(),
-                      reinterpret_cast<uint64_t>(closure));
-  }
-
- private:
-  // Instance fields, present in the base class and every generated subclass:
-
-  // private long closure;
-  union {
-    lambda::Closure* actual;
-    uint64_t padding;         // Don't trip up GetObjectSize checks, since the Java code has a long.
-  } closure_;
-
-  // Friends for generating offset tests:
-  friend struct art::LambdaProxyOffsets;              // for verifying offset information
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(LambdaProxy);
-};
-
-}  // namespace mirror
-}  // namespace art
-
-#endif  // ART_RUNTIME_MIRROR_LAMBDA_PROXY_H_
diff --git a/runtime/modifiers.h b/runtime/modifiers.h
index 36aa57f..9946eab 100644
--- a/runtime/modifiers.h
+++ b/runtime/modifiers.h
@@ -54,8 +54,6 @@
 // if any particular method needs to be a default conflict. Used to figure out at runtime if
 // invoking this method will throw an exception.
 static constexpr uint32_t kAccDefaultConflict =      0x00800000;  // method (runtime)
-// Set by the class linker when creating a class that's a subtype of LambdaProxy.
-static constexpr uint32_t kAccClassIsLambdaProxy =   0x01000000;  // class  (dex only)
 
 // Special runtime-only flags.
 // Interface and all its super-interfaces with default methods have been recursively initialized.
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 6cebd4d..5e42392 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -103,7 +103,7 @@
 static jobjectArray Class_getProxyInterfaces(JNIEnv* env, jobject javaThis) {
   ScopedFastNativeObjectAccess soa(env);
   mirror::Class* c = DecodeClass(soa, javaThis);
-  return soa.AddLocalReference<jobjectArray>(c->GetInterfacesForAnyProxy()->Clone(soa.Self()));
+  return soa.AddLocalReference<jobjectArray>(c->GetInterfaces()->Clone(soa.Self()));
 }
 
 static mirror::ObjectArray<mirror::Field>* GetDeclaredFields(
@@ -489,7 +489,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<2> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     return nullptr;
   }
   Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
@@ -501,7 +501,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     // Return an empty array instead of a null pointer.
     mirror::Class* annotation_array_class =
         soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array);
@@ -517,7 +517,7 @@
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
   mirror::ObjectArray<mirror::Class>* classes = nullptr;
-  if (!klass->IsAnyProxyClass() && klass->GetDexCache() != nullptr) {
+  if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) {
     classes = klass->GetDexFile().GetDeclaredClasses(klass);
   }
   if (classes == nullptr) {
@@ -543,7 +543,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     return nullptr;
   }
   return soa.AddLocalReference<jclass>(klass->GetDexFile().GetEnclosingClass(klass));
@@ -553,7 +553,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     return nullptr;
   }
   mirror::Object* method = klass->GetDexFile().GetEnclosingMethod(klass);
@@ -570,7 +570,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     return nullptr;
   }
   mirror::Object* method = klass->GetDexFile().GetEnclosingMethod(klass);
@@ -587,7 +587,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     return defaultValue;
   }
   uint32_t flags;
@@ -601,7 +601,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     return nullptr;
   }
   mirror::String* class_name = nullptr;
@@ -615,7 +615,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     return false;
   }
   mirror::String* class_name = nullptr;
@@ -630,7 +630,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<2> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     return false;
   }
   Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
@@ -641,7 +641,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
-  if (klass->IsAnyProxyClass() || klass->GetDexCache() == nullptr) {
+  if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
     return nullptr;
   }
   // Return null for anonymous classes.
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc
index 9166ecc..aac800a 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -419,7 +419,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField();
-  if (field->GetDeclaringClass()->IsAnyProxyClass()) {
+  if (field->GetDeclaringClass()->IsProxyClass()) {
     return nullptr;
   }
   Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
@@ -429,7 +429,7 @@
 static jobjectArray Field_getDeclaredAnnotations(JNIEnv* env, jobject javaField) {
   ScopedFastNativeObjectAccess soa(env);
   ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField();
-  if (field->GetDeclaringClass()->IsAnyProxyClass()) {
+  if (field->GetDeclaringClass()->IsProxyClass()) {
     // Return an empty array instead of a null pointer.
     mirror::Class* annotation_array_class =
         soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array);
@@ -443,7 +443,7 @@
 static jobjectArray Field_getSignatureAnnotation(JNIEnv* env, jobject javaField) {
   ScopedFastNativeObjectAccess soa(env);
   ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField();
-  if (field->GetDeclaringClass()->IsAnyProxyClass()) {
+  if (field->GetDeclaringClass()->IsProxyClass()) {
     return nullptr;
   }
   return soa.AddLocalReference<jobjectArray>(
@@ -455,7 +455,7 @@
   ScopedFastNativeObjectAccess soa(env);
   StackHandleScope<1> hs(soa.Self());
   ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField();
-  if (field->GetDeclaringClass()->IsAnyProxyClass()) {
+  if (field->GetDeclaringClass()->IsProxyClass()) {
     return false;
   }
   Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc
index 7894c9b..caacba6 100644
--- a/runtime/native/java_lang_reflect_Method.cc
+++ b/runtime/native/java_lang_reflect_Method.cc
@@ -32,7 +32,7 @@
 static jobject Method_getAnnotationNative(JNIEnv* env, jobject javaMethod, jclass annotationType) {
   ScopedFastNativeObjectAccess soa(env);
   ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->GetDeclaringClass()->IsAnyProxyClass()) {
+  if (method->GetDeclaringClass()->IsProxyClass()) {
     return nullptr;
   }
   StackHandleScope<1> hs(soa.Self());
@@ -44,7 +44,7 @@
 static jobjectArray Method_getDeclaredAnnotations(JNIEnv* env, jobject javaMethod) {
   ScopedFastNativeObjectAccess soa(env);
   ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->GetDeclaringClass()->IsAnyProxyClass()) {
+  if (method->GetDeclaringClass()->IsProxyClass()) {
     // Return an empty array instead of a null pointer.
     mirror::Class* annotation_array_class =
         soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array);
@@ -67,7 +67,7 @@
 static jobjectArray Method_getExceptionTypes(JNIEnv* env, jobject javaMethod) {
   ScopedFastNativeObjectAccess soa(env);
   ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->GetDeclaringClass()->IsAnyProxyClass()) {
+  if (method->GetDeclaringClass()->IsProxyClass()) {
     mirror::Class* klass = method->GetDeclaringClass();
     int throws_index = -1;
     size_t i = 0;
@@ -79,8 +79,7 @@
       ++i;
     }
     CHECK_NE(throws_index, -1);
-    mirror::ObjectArray<mirror::Class>* declared_exceptions =
-        klass->GetThrowsForAnyProxy()->Get(throws_index);
+    mirror::ObjectArray<mirror::Class>* declared_exceptions = klass->GetThrows()->Get(throws_index);
     return soa.AddLocalReference<jobjectArray>(declared_exceptions->Clone(soa.Self()));
   } else {
     mirror::ObjectArray<mirror::Class>* result_array =
@@ -105,7 +104,7 @@
 static jobjectArray Method_getParameterAnnotationsNative(JNIEnv* env, jobject javaMethod) {
   ScopedFastNativeObjectAccess soa(env);
   ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->GetDeclaringClass()->IsAnyProxyClass()) {
+  if (method->GetDeclaringClass()->IsProxyClass()) {
     return nullptr;
   }
   return soa.AddLocalReference<jobjectArray>(method->GetDexFile()->GetParameterAnnotations(method));
@@ -121,7 +120,7 @@
                                                  jclass annotationType) {
   ScopedFastNativeObjectAccess soa(env);
   ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->GetDeclaringClass()->IsAnyProxyClass()) {
+  if (method->GetDeclaringClass()->IsProxyClass()) {
     return false;
   }
   StackHandleScope<1> hs(soa.Self());
diff --git a/runtime/native/java_lang_reflect_Proxy.cc b/runtime/native/java_lang_reflect_Proxy.cc
index 647cec0..4a6ab40 100644
--- a/runtime/native/java_lang_reflect_Proxy.cc
+++ b/runtime/native/java_lang_reflect_Proxy.cc
@@ -27,31 +27,15 @@
 namespace art {
 
 static jclass Proxy_generateProxy(JNIEnv* env, jclass, jstring name, jobjectArray interfaces,
-                                  jobject loader, jobjectArray methods, jobjectArray throws,
-                                  jboolean is_lambda_proxy) {
+                                  jobject loader, jobjectArray methods, jobjectArray throws) {
   ScopedFastNativeObjectAccess soa(env);
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-
-  mirror::Class* proxy_class = nullptr;
-
-  if (UNLIKELY(is_lambda_proxy)) {
-    bool already_exists;  // XX: Perhaps add lambdaProxyCache to java.lang.ClassLoader ?
-    proxy_class = class_linker->CreateLambdaProxyClass(soa,
-                                                       name,
-                                                       interfaces,
-                                                       loader,
-                                                       methods,
-                                                       throws,
-                                                       /*out*/&already_exists);
-  } else {
-    proxy_class = class_linker->CreateProxyClass(soa, name, interfaces, loader, methods, throws);
-  }
-
-  return soa.AddLocalReference<jclass>(proxy_class);
+  return soa.AddLocalReference<jclass>(class_linker->CreateProxyClass(
+      soa, name, interfaces, loader, methods, throws));
 }
 
 static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(Proxy, generateProxy, "!(Ljava/lang/String;[Ljava/lang/Class;Ljava/lang/ClassLoader;[Ljava/lang/reflect/Method;[[Ljava/lang/Class;Z)Ljava/lang/Class;"),
+  NATIVE_METHOD(Proxy, generateProxy, "!(Ljava/lang/String;[Ljava/lang/Class;Ljava/lang/ClassLoader;[Ljava/lang/reflect/Method;[[Ljava/lang/Class;)Ljava/lang/Class;"),
 };
 
 void register_java_lang_reflect_Proxy(JNIEnv* env) {
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index 57aafcc..57472ad 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -121,7 +121,7 @@
       GenerateProxyClass(soa, jclass_loader, "$Proxy1234", interfaces)));
   interfaces.clear();  // Don't least possibly stale objects in the array as good practice.
   ASSERT_TRUE(proxy_class.Get() != nullptr);
-  ASSERT_TRUE(proxy_class->IsReflectProxyClass());
+  ASSERT_TRUE(proxy_class->IsProxyClass());
   ASSERT_TRUE(proxy_class->IsInitialized());
 
   EXPECT_EQ(2U, proxy_class->NumDirectInterfaces());  // Interfaces$I and Interfaces$J.
@@ -157,7 +157,7 @@
   }
 
   ASSERT_TRUE(proxyClass.Get() != nullptr);
-  ASSERT_TRUE(proxyClass->IsReflectProxyClass());
+  ASSERT_TRUE(proxyClass->IsProxyClass());
   ASSERT_TRUE(proxyClass->IsInitialized());
 
   EXPECT_TRUE(proxyClass->GetIFieldsPtr() == nullptr);
@@ -208,10 +208,10 @@
   }
 
   ASSERT_TRUE(proxyClass0.Get() != nullptr);
-  ASSERT_TRUE(proxyClass0->IsReflectProxyClass());
+  ASSERT_TRUE(proxyClass0->IsProxyClass());
   ASSERT_TRUE(proxyClass0->IsInitialized());
   ASSERT_TRUE(proxyClass1.Get() != nullptr);
-  ASSERT_TRUE(proxyClass1->IsReflectProxyClass());
+  ASSERT_TRUE(proxyClass1->IsProxyClass());
   ASSERT_TRUE(proxyClass1->IsInitialized());
 
   LengthPrefixedArray<ArtField>* static_fields0 = proxyClass0->GetSFieldsPtr();
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 2ff9fd2..9098d38 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -172,23 +172,12 @@
     } else {
       return cur_shadow_frame_->GetVRegReference(0);
     }
-  } else if (m->IsReflectProxyMethod()) {
+  } else if (m->IsProxyMethod()) {
     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) {
@@ -825,27 +814,7 @@
     // 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";
-
-    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);
-    }
+    return runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs);
   }
 
   // The only remaining case is if the method is native and uses the generic JNI stub.
diff --git a/test/955-lambda-smali/expected.txt b/test/955-lambda-smali/expected.txt
index 8afe4bc..16381e4 100644
--- a/test/955-lambda-smali/expected.txt
+++ b/test/955-lambda-smali/expected.txt
@@ -26,5 +26,3 @@
 (CaptureVariables) (0-args, 1 captured variable 'D'): value is -Infinity
 (CaptureVariables) (0-args, 8 captured variable 'ZBCSIJFD'): value is true,R,∂,1000,12345678,3287471278325742,Infinity,-Infinity
 (CaptureVariables) Caught NPE
-(BoxInvoke) Hello boxing world! (0-args, no closure) void
-(BoxInvoke) Hello boxing world!(1-args, no closure) returned: 12345678
diff --git a/test/955-lambda-smali/smali/BoxInvoke.smali b/test/955-lambda-smali/smali/BoxInvoke.smali
deleted file mode 100644
index 8b53333..0000000
--- a/test/955-lambda-smali/smali/BoxInvoke.smali
+++ /dev/null
@@ -1,103 +0,0 @@
-#  Copyright (C) 2015 The Android Open Source Project
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-.class public LBoxInvoke;
-.super Ljava/lang/Object;
-
-.method public constructor <init>()V
-.registers 1
-    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
-    return-void
-.end method
-
-.method public static run()V
-    .registers 0
-
-    invoke-static {}, LBoxInvoke;->testBoxInvoke()V
-    invoke-static {}, LBoxInvoke;->forceGC()V
-
-    return-void
-.end method
-
-# Test that invoke-virtual works on boxed innate lambdas.
-.method public static testBoxInvoke()V
-    .registers 100
-
-    # Try invoking 0-arg void return lambda
-    create-lambda v0, LBoxInvoke;->doHelloWorld0(J)V
-    const-string v2, "Ljava/lang/Runnable;"
-    box-lambda v2, v0 # Ljava/lang/Runnable;
-    invoke-interface {v2}, Ljava/lang/Runnable;->run()V
-
-    # Try invoking 1-arg int return lambda
-    create-lambda v3, LBoxInvoke;->doHelloWorld1(JLjava/lang/Object;)I
-    const-string v5, "Ljava/lang/Comparable;"
-    box-lambda v5, v3 # Ljava/lang/Comparable;
-    const-string v6, "Hello boxing world!"
-    invoke-interface {v5, v6}, Ljava/lang/Comparable;->compareTo(Ljava/lang/Object;)I
-    move-result v7
-    sget-object v8, Ljava/lang/System;->out:Ljava/io/PrintStream;
-    invoke-virtual {v8, v7}, Ljava/io/PrintStream;->println(I)V
-
-    return-void
-
-    # TODO: more tests once box-lambda can take a type descriptor.
-
-.end method
-
-#TODO: should use a closure type instead of a long.
-.method public static doHelloWorld0(J)V
-    .registers 4 # 1 wide parameters, 2 locals
-
-    const-string v0, "(BoxInvoke) Hello boxing world! (0-args, no closure) void"
-
-    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
-    invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
-
-    return-void
-.end method
-
-#TODO: should use a closure type instead of a long.
-.method public static doHelloWorld1(JLjava/lang/Object;)I
-    # J = closure, L = obj, I = return type
-    .registers 6 # 1 wide parameters, 1 narrow parameter, 3 locals
-
-    # Prints "<before> $parameter1(Object) <after>:" without the line terminator. 
-
-    const-string v0, "(BoxInvoke) "
-
-    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
-    # System.out.print("<before>");
-    invoke-virtual {v1, v0}, Ljava/io/PrintStream;->print(Ljava/lang/String;)V
-
-    # System.out.print(obj);
-    invoke-virtual {v1, p2}, Ljava/io/PrintStream;->print(Ljava/lang/Object;)V
-
-    # System.out.print("<after>: ");
-    const-string v0, "(1-args, no closure) returned: "
-    invoke-virtual {v1, v0}, Ljava/io/PrintStream;->print(Ljava/lang/String;)V
-
-    const v2, 12345678
-    return v2
-.end method
-
-# Force a GC. Used to ensure our weak reference table of boxed lambdas is getting swept.
-.method private static forceGC()V
-    .registers 1
-    invoke-static {}, Ljava/lang/Runtime;->getRuntime()Ljava/lang/Runtime;
-    move-result-object v0
-    invoke-virtual {v0}, Ljava/lang/Runtime;->gc()V
-
-    return-void
-.end method
diff --git a/test/955-lambda-smali/smali/BoxUnbox.smali b/test/955-lambda-smali/smali/BoxUnbox.smali
index 157adb3..915de2d 100644
--- a/test/955-lambda-smali/smali/BoxUnbox.smali
+++ b/test/955-lambda-smali/smali/BoxUnbox.smali
@@ -51,7 +51,6 @@
     .registers 3
 
     create-lambda v0, LBoxUnbox;->doHelloWorld(J)V
-    const-string v2, "Ljava/lang/Runnable;"
     box-lambda v2, v0 # v2 = box(v0)
     unbox-lambda v0, v2, J # v0 = unbox(v2)
     invoke-lambda v0, {}
@@ -64,9 +63,7 @@
    .registers 6 # 0 parameters, 6 locals
 
     create-lambda v0, LBoxUnbox;->doHelloWorld(J)V
-    const-string v2, "Ljava/lang/Runnable;"
     box-lambda v2, v0 # v2 = box(v0)
-    const-string v3, "Ljava/lang/Runnable;"
     box-lambda v3, v0 # v3 = box(v0)
 
     # The objects should be not-null, and they should have the same reference
@@ -119,7 +116,6 @@
     const v0, 0  # v0 = null
     const v1, 0  # v1 = null
 :start
-    const-string v2, "Ljava/lang/Runnable;"
     box-lambda v2, v0  # attempting to box a null lambda will throw NPE
 :end
     return-void
diff --git a/test/955-lambda-smali/smali/CaptureVariables.smali b/test/955-lambda-smali/smali/CaptureVariables.smali
index 531c259..f18b7ff 100644
--- a/test/955-lambda-smali/smali/CaptureVariables.smali
+++ b/test/955-lambda-smali/smali/CaptureVariables.smali
@@ -243,8 +243,6 @@
     # TODO: create-lambda should not write to both v0 and v1
     invoke-lambda v0, {}
 
-    return-void
-
 .end method
 
 #TODO: should use a closure type instead of a long
diff --git a/test/955-lambda-smali/smali/Main.smali b/test/955-lambda-smali/smali/Main.smali
index e8ab84c..9892d61 100644
--- a/test/955-lambda-smali/smali/Main.smali
+++ b/test/955-lambda-smali/smali/Main.smali
@@ -25,7 +25,6 @@
     invoke-static {}, LBoxUnbox;->run()V
     invoke-static {}, LMoveResult;->run()V
     invoke-static {}, LCaptureVariables;->run()V
-    invoke-static {}, LBoxInvoke;->run()V
 
 # TODO: add tests when verification fails
 
diff --git a/test/LambdaInterfaces/LambdaInterfaces.java b/test/LambdaInterfaces/LambdaInterfaces.java
deleted file mode 100644
index 261163d..0000000
--- a/test/LambdaInterfaces/LambdaInterfaces.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class LambdaInterfaces {
-    interface I {
-        public int i();
-    }
-    interface J {
-        public String foo = "foo";
-        public void j1();
-    }
-    interface K extends J {
-    }
-    interface L {
-      public int sum(int a, int b);
-    }
-    interface C {
-      public String concat(String a, String b);
-    }
-}