Revert experimental lambda feature.

This is a revert of the following changes :

30c475a2046951a81769c2db0b2dad66cd71e189.
lambda: Minor capture-variable/liberate-variable clean-up after post-merge reviews.

6918bf13eb855b3aa8ccdddda2d27ae8c60cec56.
lambda: Experimental support for capture-variable and liberate-variable

fc1ccd740b7c8e96dfac675cfc580122cd1b40a6.
lambda: Infrastructure to support capture/liberate-variable dex opcodes

e2facc5b18cd756a8b5500fb3d90da69c9ee0fb7.
runtime: Add lambda box/unbox object equality

2ee54e249ad21c74f29a161e248bebe7d22fddf1.
runtime: Partially implement box-lambda and unbox-lambda experimental opcodes

158f35c98e2ec0d40d2c032b8cdce5fb60944a7f.
interpreter: Add experimental lambda opcodes for invoke/create-lambda

a3bb72036f5454e410467f7151dc89f725ae1151.
Added format 25x to dexdump(2).

Plus surrounding cleanups.

Test: make test-art
Change-Id: Ic6f999ad17385ef933f763641049cf721510b202
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 174d4e0..4fd1514 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -36,14 +36,7 @@
 #include "entrypoints/entrypoint_utils-inl.h"
 #include "handle_scope-inl.h"
 #include "jit/jit.h"
-#include "lambda/art_lambda_method.h"
-#include "lambda/box_table.h"
-#include "lambda/closure.h"
-#include "lambda/closure_builder-inl.h"
-#include "lambda/leaking_allocator.h"
-#include "lambda/shorty_field_type.h"
 #include "mirror/class-inl.h"
-#include "mirror/method.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/string-inl.h"
@@ -142,488 +135,7 @@
 bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame,
             const Instruction* inst, uint16_t inst_data, JValue* result);
 
-// Invokes the given lambda closure. This is part of the invocation support and is used by
-// DoLambdaInvoke functions.
-// Returns true on success, otherwise throws an exception and returns false.
-template<bool is_range, bool do_assignability_check>
-bool DoLambdaCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame,
-                  const Instruction* inst, uint16_t inst_data, JValue* result);
-
-// Validates that the art method corresponding to a lambda method target
-// is semantically valid:
-//
-// Must be ACC_STATIC and ACC_LAMBDA. Must be a concrete managed implementation
-// (i.e. not native, not proxy, not abstract, ...).
-//
-// If the validation fails, return false and raise an exception.
-static inline bool IsValidLambdaTargetOrThrow(ArtMethod* called_method)
-    SHARED_REQUIRES(Locks::mutator_lock_) {
-  bool success = false;
-
-  if (UNLIKELY(called_method == nullptr)) {
-    // The shadow frame should already be pushed, so we don't need to update it.
-  } else if (UNLIKELY(!called_method->IsInvokable())) {
-    called_method->ThrowInvocationTimeError();
-    // We got an error.
-    // TODO(iam): Also handle the case when the method is non-static, what error do we throw?
-    // TODO(iam): Also make sure that ACC_LAMBDA is set.
-  } else if (UNLIKELY(called_method->GetCodeItem() == nullptr)) {
-    // Method could be native, proxy method, etc. Lambda targets have to be concrete impls,
-    // so don't allow this.
-  } else {
-    success = true;
-  }
-
-  return success;
-}
-
-// Write out the 'Closure*' into vreg and vreg+1, as if it was a jlong.
-static inline void WriteLambdaClosureIntoVRegs(ShadowFrame& shadow_frame,
-                                               const lambda::Closure& lambda_closure,
-                                               uint32_t vreg) {
-  // Split the method into a lo and hi 32 bits so we can encode them into 2 virtual registers.
-  uint32_t closure_lo = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(&lambda_closure));
-  uint32_t closure_hi = static_cast<uint32_t>(reinterpret_cast<uint64_t>(&lambda_closure)
-                                                    >> BitSizeOf<uint32_t>());
-  // Use uint64_t instead of uintptr_t to allow shifting past the max on 32-bit.
-  static_assert(sizeof(uint64_t) >= sizeof(uintptr_t), "Impossible");
-
-  DCHECK_NE(closure_lo | closure_hi, 0u);
-
-  shadow_frame.SetVReg(vreg, closure_lo);
-  shadow_frame.SetVReg(vreg + 1, closure_hi);
-}
-
-// Handles create-lambda instructions.
-// Returns true on success, otherwise throws an exception and returns false.
-// (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
-//
-// The closure must be allocated big enough to hold the data, and should not be
-// pre-initialized. It is initialized with the actual captured variables as a side-effect,
-// although this should be unimportant to the caller since this function also handles storing it to
-// the ShadowFrame.
-//
-// As a work-in-progress implementation, this shoves the ArtMethod object corresponding
-// to the target dex method index into the target register vA and vA + 1.
-template<bool do_access_check>
-static inline bool DoCreateLambda(Thread* self,
-                                  const Instruction* inst,
-                                  /*inout*/ShadowFrame& shadow_frame,
-                                  /*inout*/lambda::ClosureBuilder* closure_builder,
-                                  /*inout*/lambda::Closure* uninitialized_closure) {
-  DCHECK(closure_builder != nullptr);
-  DCHECK(uninitialized_closure != nullptr);
-  DCHECK_ALIGNED(uninitialized_closure, alignof(lambda::Closure));
-
-  using lambda::ArtLambdaMethod;
-  using lambda::LeakingAllocator;
-
-  /*
-   * create-lambda is opcode 0x21c
-   * - vA is the target register where the closure will be stored into
-   *   (also stores into vA + 1)
-   * - vB is the method index which will be the target for a later invoke-lambda
-   */
-  const uint32_t method_idx = inst->VRegB_21c();
-  mirror::Object* receiver = nullptr;  // Always static. (see 'kStatic')
-  ArtMethod* sf_method = shadow_frame.GetMethod();
-  ArtMethod* const called_method = FindMethodFromCode<kStatic, do_access_check>(
-      method_idx, &receiver, sf_method, self);
-
-  uint32_t vreg_dest_closure = inst->VRegA_21c();
-
-  if (UNLIKELY(!IsValidLambdaTargetOrThrow(called_method))) {
-    CHECK(self->IsExceptionPending());
-    shadow_frame.SetVReg(vreg_dest_closure, 0u);
-    shadow_frame.SetVReg(vreg_dest_closure + 1, 0u);
-    return false;
-  }
-
-  ArtLambdaMethod* initialized_lambda_method;
-  // Initialize the ArtLambdaMethod with the right data.
-  {
-    // Allocate enough memory to store a well-aligned ArtLambdaMethod.
-    // This is not the final type yet since the data starts out uninitialized.
-    LeakingAllocator::AlignedMemoryStorage<ArtLambdaMethod>* uninitialized_lambda_method =
-            LeakingAllocator::AllocateMemory<ArtLambdaMethod>(self);
-
-    std::string captured_variables_shorty = closure_builder->GetCapturedVariableShortyTypes();
-    std::string captured_variables_long_type_desc;
-
-    // Synthesize a long type descriptor from the short one.
-    for (char shorty : captured_variables_shorty) {
-      lambda::ShortyFieldType shorty_field_type(shorty);
-      if (shorty_field_type.IsObject()) {
-        // Not the true type, but good enough until we implement verifier support.
-        captured_variables_long_type_desc += "Ljava/lang/Object;";
-        UNIMPLEMENTED(FATAL) << "create-lambda with an object captured variable";
-      } else if (shorty_field_type.IsLambda()) {
-        // Not the true type, but good enough until we implement verifier support.
-        captured_variables_long_type_desc += "Ljava/lang/Runnable;";
-        UNIMPLEMENTED(FATAL) << "create-lambda with a lambda captured variable";
-      } else {
-        // The primitive types have the same length shorty or not, so this is always correct.
-        DCHECK(shorty_field_type.IsPrimitive());
-        captured_variables_long_type_desc += shorty_field_type;
-      }
-    }
-
-    // Copy strings to dynamically allocated storage. This leaks, but that's ok. Fix it later.
-    // TODO: Strings need to come from the DexFile, so they won't need their own allocations.
-    char* captured_variables_type_desc = LeakingAllocator::MakeFlexibleInstance<char>(
-        self,
-        captured_variables_long_type_desc.size() + 1);
-    strcpy(captured_variables_type_desc, captured_variables_long_type_desc.c_str());
-    char* captured_variables_shorty_copy = LeakingAllocator::MakeFlexibleInstance<char>(
-        self,
-        captured_variables_shorty.size() + 1);
-    strcpy(captured_variables_shorty_copy, captured_variables_shorty.c_str());
-
-    // After initialization, the object at the storage is well-typed. Use strong type going forward.
-    initialized_lambda_method =
-        new (uninitialized_lambda_method) ArtLambdaMethod(called_method,
-                                                          captured_variables_type_desc,
-                                                          captured_variables_shorty_copy,
-                                                          true);  // innate lambda
-  }
-
-  // Write all the closure captured variables and the closure header into the closure.
-  lambda::Closure* initialized_closure =
-      closure_builder->CreateInPlace(uninitialized_closure, initialized_lambda_method);
-
-  WriteLambdaClosureIntoVRegs(/*inout*/shadow_frame, *initialized_closure, vreg_dest_closure);
-  return true;
-}
-
-// Reads out the 'ArtMethod*' stored inside of vreg and vreg+1
-//
-// Validates that the art method points to a valid lambda function, otherwise throws
-// an exception and returns null.
-// (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
-static inline lambda::Closure* ReadLambdaClosureFromVRegsOrThrow(ShadowFrame& shadow_frame,
-                                                                 uint32_t vreg)
-    SHARED_REQUIRES(Locks::mutator_lock_) {
-  // Lambda closures take up a consecutive pair of 2 virtual registers.
-  // On 32-bit the high bits are always 0.
-  uint32_t vc_value_lo = shadow_frame.GetVReg(vreg);
-  uint32_t vc_value_hi = shadow_frame.GetVReg(vreg + 1);
-
-  uint64_t vc_value_ptr = (static_cast<uint64_t>(vc_value_hi) << BitSizeOf<uint32_t>())
-                           | vc_value_lo;
-
-  // Use uint64_t instead of uintptr_t to allow left-shifting past the max on 32-bit.
-  static_assert(sizeof(uint64_t) >= sizeof(uintptr_t), "Impossible");
-  lambda::Closure* const lambda_closure = reinterpret_cast<lambda::Closure*>(vc_value_ptr);
-  DCHECK_ALIGNED(lambda_closure, alignof(lambda::Closure));
-
-  // Guard against the user passing a null closure, which is odd but (sadly) semantically valid.
-  if (UNLIKELY(lambda_closure == nullptr)) {
-    ThrowNullPointerExceptionFromInterpreter();
-    return nullptr;
-  } else if (UNLIKELY(!IsValidLambdaTargetOrThrow(lambda_closure->GetTargetMethod()))) {
-    // Sanity check against data corruption.
-    return nullptr;
-  }
-
-  return lambda_closure;
-}
-
-// Forward declaration for lock annotations. See below for documentation.
-template <bool do_access_check>
-static inline const char* GetStringDataByDexStringIndexOrThrow(ShadowFrame& shadow_frame,
-                                                               uint32_t string_idx)
-    SHARED_REQUIRES(Locks::mutator_lock_);
-
-// Find the c-string data corresponding to a dex file's string index.
-// Otherwise, returns null if not found and throws a VerifyError.
-//
-// Note that with do_access_check=false, we never return null because the verifier
-// must guard against invalid string indices.
-// (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
-template <bool do_access_check>
-static inline const char* GetStringDataByDexStringIndexOrThrow(ShadowFrame& shadow_frame,
-                                                               uint32_t string_idx) {
-  ArtMethod* method = shadow_frame.GetMethod();
-  const DexFile* dex_file = method->GetDexFile();
-
-  mirror::Class* declaring_class = method->GetDeclaringClass();
-  if (!do_access_check) {
-    // MethodVerifier refuses methods with string_idx out of bounds.
-    DCHECK_LT(string_idx, declaring_class->GetDexCache()->NumStrings());
-  } else {
-    // Access checks enabled: perform string index bounds ourselves.
-    if (string_idx >= dex_file->GetHeader().string_ids_size_) {
-      ThrowVerifyError(declaring_class, "String index '%" PRIu32 "' out of bounds",
-                       string_idx);
-      return nullptr;
-    }
-  }
-
-  const char* type_string = dex_file->StringDataByIdx(string_idx);
-
-  if (UNLIKELY(type_string == nullptr)) {
-    CHECK_EQ(false, do_access_check)
-        << " verifier should've caught invalid string index " << string_idx;
-    CHECK_EQ(true, do_access_check)
-        << " string idx size check should've caught invalid string index " << string_idx;
-  }
-
-  return type_string;
-}
-
-// Handles capture-variable instructions.
-// Returns true on success, otherwise throws an exception and returns false.
-// (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
-template<bool do_access_check>
-static inline bool DoCaptureVariable(Thread* self,
-                                     const Instruction* inst,
-                                     /*inout*/ShadowFrame& shadow_frame,
-                                     /*inout*/lambda::ClosureBuilder* closure_builder) {
-  DCHECK(closure_builder != nullptr);
-  using lambda::ShortyFieldType;
-  /*
-   * capture-variable is opcode 0xf6, fmt 0x21c
-   * - vA is the source register of the variable that will be captured
-   * - vB is the string ID of the variable's type that will be captured
-   */
-  const uint32_t source_vreg = inst->VRegA_21c();
-  const uint32_t string_idx = inst->VRegB_21c();
-  // TODO: this should be a proper [type id] instead of a [string ID] pointing to a type.
-
-  const char* type_string = GetStringDataByDexStringIndexOrThrow<do_access_check>(shadow_frame,
-                                                                                  string_idx);
-  if (UNLIKELY(type_string == nullptr)) {
-    CHECK(self->IsExceptionPending());
-    return false;
-  }
-
-  char type_first_letter = type_string[0];
-  ShortyFieldType shorty_type;
-  if (do_access_check &&
-      UNLIKELY(!ShortyFieldType::MaybeCreate(type_first_letter, /*out*/&shorty_type))) {  // NOLINT: [whitespace/comma] [3]
-    ThrowVerifyError(shadow_frame.GetMethod()->GetDeclaringClass(),
-                     "capture-variable vB must be a valid type");
-    return false;
-  } else {
-    // Already verified that the type is valid.
-    shorty_type = ShortyFieldType(type_first_letter);
-  }
-
-  const size_t captured_variable_count = closure_builder->GetCaptureCount();
-
-  // Note: types are specified explicitly so that the closure is packed tightly.
-  switch (shorty_type) {
-    case ShortyFieldType::kBoolean: {
-      uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
-      closure_builder->CaptureVariablePrimitive<bool>(primitive_narrow_value);
-      break;
-    }
-    case ShortyFieldType::kByte: {
-      uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
-      closure_builder->CaptureVariablePrimitive<int8_t>(primitive_narrow_value);
-      break;
-    }
-    case ShortyFieldType::kChar: {
-      uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
-      closure_builder->CaptureVariablePrimitive<uint16_t>(primitive_narrow_value);
-      break;
-    }
-    case ShortyFieldType::kShort: {
-      uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
-      closure_builder->CaptureVariablePrimitive<int16_t>(primitive_narrow_value);
-      break;
-    }
-    case ShortyFieldType::kInt: {
-      uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
-      closure_builder->CaptureVariablePrimitive<int32_t>(primitive_narrow_value);
-      break;
-    }
-    case ShortyFieldType::kDouble: {
-      closure_builder->CaptureVariablePrimitive(shadow_frame.GetVRegDouble(source_vreg));
-      break;
-    }
-    case ShortyFieldType::kFloat: {
-      closure_builder->CaptureVariablePrimitive(shadow_frame.GetVRegFloat(source_vreg));
-      break;
-    }
-    case ShortyFieldType::kLambda: {
-      UNIMPLEMENTED(FATAL) << " capture-variable with type kLambda";
-      // TODO: Capturing lambdas recursively will be done at a later time.
-      UNREACHABLE();
-    }
-    case ShortyFieldType::kLong: {
-      closure_builder->CaptureVariablePrimitive(shadow_frame.GetVRegLong(source_vreg));
-      break;
-    }
-    case ShortyFieldType::kObject: {
-      closure_builder->CaptureVariableObject(shadow_frame.GetVRegReference(source_vreg));
-      UNIMPLEMENTED(FATAL) << " capture-variable with type kObject";
-      // TODO: finish implementing this. disabled for now since we can't track lambda refs for GC.
-      UNREACHABLE();
-    }
-
-    default:
-      LOG(FATAL) << "Invalid shorty type value " << shorty_type;
-      UNREACHABLE();
-  }
-
-  DCHECK_EQ(captured_variable_count + 1, closure_builder->GetCaptureCount());
-
-  return true;
-}
-
-// Handles capture-variable instructions.
-// Returns true on success, otherwise throws an exception and returns false.
-// (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
-template<bool do_access_check>
-static inline bool DoLiberateVariable(Thread* self,
-                                     const Instruction* inst,
-                                     size_t captured_variable_index,
-                                     /*inout*/ShadowFrame& shadow_frame) {
-  using lambda::ShortyFieldType;
-  /*
-   * liberate-variable is opcode 0xf7, fmt 0x22c
-   * - vA is the destination register
-   * - vB is the register with the lambda closure in it
-   * - vC is the string ID which needs to be a valid field type descriptor
-   */
-
-  const uint32_t dest_vreg = inst->VRegA_22c();
-  const uint32_t closure_vreg = inst->VRegB_22c();
-  const uint32_t string_idx = inst->VRegC_22c();
-  // TODO: this should be a proper [type id] instead of a [string ID] pointing to a type.
-
-
-  // Synthesize a long type descriptor from a shorty type descriptor list.
-  // TODO: Fix the dex encoding to contain the long and short type descriptors.
-  const char* type_string = GetStringDataByDexStringIndexOrThrow<do_access_check>(shadow_frame,
-                                                                                  string_idx);
-  if (UNLIKELY(do_access_check && type_string == nullptr)) {
-    CHECK(self->IsExceptionPending());
-    shadow_frame.SetVReg(dest_vreg, 0);
-    return false;
-  }
-
-  char type_first_letter = type_string[0];
-  ShortyFieldType shorty_type;
-  if (do_access_check &&
-      UNLIKELY(!ShortyFieldType::MaybeCreate(type_first_letter, /*out*/&shorty_type))) {  // NOLINT: [whitespace/comma] [3]
-    ThrowVerifyError(shadow_frame.GetMethod()->GetDeclaringClass(),
-                     "liberate-variable vC must be a valid type");
-    shadow_frame.SetVReg(dest_vreg, 0);
-    return false;
-  } else {
-    // Already verified that the type is valid.
-    shorty_type = ShortyFieldType(type_first_letter);
-  }
-
-  // Check for closure being null *after* the type check.
-  // This way we can access the type info in case we fail later, to know how many vregs to clear.
-  const lambda::Closure* lambda_closure =
-      ReadLambdaClosureFromVRegsOrThrow(/*inout*/shadow_frame, closure_vreg);
-
-  // Failed lambda target runtime check, an exception was raised.
-  if (UNLIKELY(lambda_closure == nullptr)) {
-    CHECK(self->IsExceptionPending());
-
-    // Clear the destination vreg(s) to be safe.
-    shadow_frame.SetVReg(dest_vreg, 0);
-    if (shorty_type.IsPrimitiveWide() || shorty_type.IsLambda()) {
-      shadow_frame.SetVReg(dest_vreg + 1, 0);
-    }
-    return false;
-  }
-
-  if (do_access_check &&
-      UNLIKELY(captured_variable_index >= lambda_closure->GetNumberOfCapturedVariables())) {
-    ThrowVerifyError(shadow_frame.GetMethod()->GetDeclaringClass(),
-                     "liberate-variable captured variable index %zu out of bounds",
-                     lambda_closure->GetNumberOfCapturedVariables());
-    // Clear the destination vreg(s) to be safe.
-    shadow_frame.SetVReg(dest_vreg, 0);
-    if (shorty_type.IsPrimitiveWide() || shorty_type.IsLambda()) {
-      shadow_frame.SetVReg(dest_vreg + 1, 0);
-    }
-    return false;
-  }
-
-  // Verify that the runtime type of the captured-variable matches the requested dex type.
-  if (do_access_check) {
-    ShortyFieldType actual_type = lambda_closure->GetCapturedShortyType(captured_variable_index);
-    if (actual_type != shorty_type) {
-      ThrowVerifyError(shadow_frame.GetMethod()->GetDeclaringClass(),
-                     "cannot liberate-variable of runtime type '%c' to dex type '%c'",
-                     static_cast<char>(actual_type),
-                     static_cast<char>(shorty_type));
-
-      shadow_frame.SetVReg(dest_vreg, 0);
-      if (shorty_type.IsPrimitiveWide() || shorty_type.IsLambda()) {
-        shadow_frame.SetVReg(dest_vreg + 1, 0);
-      }
-      return false;
-    }
-
-    if (actual_type.IsLambda() || actual_type.IsObject()) {
-      UNIMPLEMENTED(FATAL) << "liberate-variable type checks needs to "
-                           << "parse full type descriptor for objects and lambdas";
-    }
-  }
-
-  // Unpack the captured variable from the closure into the correct type, then save it to the vreg.
-  if (shorty_type.IsPrimitiveNarrow()) {
-    uint32_t primitive_narrow_value =
-        lambda_closure->GetCapturedPrimitiveNarrow(captured_variable_index);
-    shadow_frame.SetVReg(dest_vreg, primitive_narrow_value);
-  } else if (shorty_type.IsPrimitiveWide()) {
-      uint64_t primitive_wide_value =
-          lambda_closure->GetCapturedPrimitiveWide(captured_variable_index);
-      shadow_frame.SetVRegLong(dest_vreg, static_cast<int64_t>(primitive_wide_value));
-  } else if (shorty_type.IsObject()) {
-    mirror::Object* unpacked_object =
-        lambda_closure->GetCapturedObject(captured_variable_index);
-    shadow_frame.SetVRegReference(dest_vreg, unpacked_object);
-
-    UNIMPLEMENTED(FATAL) << "liberate-variable cannot unpack objects yet";
-  } else if (shorty_type.IsLambda()) {
-    UNIMPLEMENTED(FATAL) << "liberate-variable cannot unpack lambdas yet";
-  } else {
-    LOG(FATAL) << "unreachable";
-    UNREACHABLE();
-  }
-
-  return true;
-}
-
-template<bool do_access_check>
-static inline bool DoInvokeLambda(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,
-                                  uint16_t inst_data, JValue* result) {
-  /*
-   * invoke-lambda is opcode 0x25
-   *
-   * - vC is the closure register (both vC and vC + 1 will be used to store the closure).
-   * - vB is the number of additional registers up to |{vD,vE,vF,vG}| (4)
-   * - the rest of the registers are always var-args
-   *
-   * - reading var-args for 0x25 gets us vD,vE,vF,vG (but not vB)
-   */
-  uint32_t vreg_closure = inst->VRegC_25x();
-  const lambda::Closure* lambda_closure =
-      ReadLambdaClosureFromVRegsOrThrow(shadow_frame, vreg_closure);
-
-  // Failed lambda target runtime check, an exception was raised.
-  if (UNLIKELY(lambda_closure == nullptr)) {
-    CHECK(self->IsExceptionPending());
-    result->SetJ(0);
-    return false;
-  }
-
-  ArtMethod* const called_method = lambda_closure->GetTargetMethod();
-  // Invoke a non-range lambda
-  return DoLambdaCall<false, do_access_check>(called_method, self, shadow_frame, inst, inst_data,
-                                              result);
-}
-
-// Handles invoke-XXX/range instructions (other than invoke-lambda[-range]).
+// Handles invoke-XXX/range instructions.
 // Returns true on success, otherwise throws an exception and returns false.
 template<InvokeType type, bool is_range, bool do_access_check>
 static inline bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,
@@ -904,74 +416,6 @@
   return 3;
 }
 
-template <bool _do_check>
-static inline bool DoBoxLambda(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,
-                               uint16_t inst_data) SHARED_REQUIRES(Locks::mutator_lock_) {
-  /*
-   * box-lambda vA, vB /// opcode 0xf8, format 22x
-   * - vA is the target register where the Object representation of the closure will be stored into
-   * - vB is a closure (made by create-lambda)
-   *   (also reads vB + 1)
-   */
-  uint32_t vreg_target_object = inst->VRegA_22x(inst_data);
-  uint32_t vreg_source_closure = inst->VRegB_22x();
-
-  lambda::Closure* lambda_closure = ReadLambdaClosureFromVRegsOrThrow(shadow_frame,
-                                                                      vreg_source_closure);
-
-  // Failed lambda target runtime check, an exception was raised.
-  if (UNLIKELY(lambda_closure == nullptr)) {
-    CHECK(self->IsExceptionPending());
-    return false;
-  }
-
-  mirror::Object* closure_as_object =
-      Runtime::Current()->GetLambdaBoxTable()->BoxLambda(lambda_closure);
-
-  // Failed to box the lambda, an exception was raised.
-  if (UNLIKELY(closure_as_object == nullptr)) {
-    CHECK(self->IsExceptionPending());
-    return false;
-  }
-
-  shadow_frame.SetVRegReference(vreg_target_object, closure_as_object);
-  return true;
-}
-
-template <bool _do_check> SHARED_REQUIRES(Locks::mutator_lock_)
-static inline bool DoUnboxLambda(Thread* self,
-                                 ShadowFrame& shadow_frame,
-                                 const Instruction* inst,
-                                 uint16_t inst_data) {
-  /*
-   * unbox-lambda vA, vB, [type id] /// opcode 0xf9, format 22c
-   * - vA is the target register where the closure will be written into
-   *   (also writes vA + 1)
-   * - vB is the Object representation of the closure (made by box-lambda)
-   */
-  uint32_t vreg_target_closure = inst->VRegA_22c(inst_data);
-  uint32_t vreg_source_object = inst->VRegB_22c();
-
-  // Raise NullPointerException if object is null
-  mirror::Object* boxed_closure_object = shadow_frame.GetVRegReference(vreg_source_object);
-  if (UNLIKELY(boxed_closure_object == nullptr)) {
-    ThrowNullPointerExceptionFromInterpreter();
-    return false;
-  }
-
-  lambda::Closure* unboxed_closure = nullptr;
-  // Raise an exception if unboxing fails.
-  if (!Runtime::Current()->GetLambdaBoxTable()->UnboxLambda(boxed_closure_object,
-                                                            /*out*/&unboxed_closure)) {
-    CHECK(self->IsExceptionPending());
-    return false;
-  }
-
-  DCHECK(unboxed_closure != nullptr);
-  WriteLambdaClosureIntoVRegs(/*inout*/shadow_frame, *unboxed_closure, vreg_target_closure);
-  return true;
-}
-
 uint32_t FindNextInstructionFollowingException(Thread* self, ShadowFrame& shadow_frame,
     uint32_t dex_pc, const instrumentation::Instrumentation* instrumentation)
         SHARED_REQUIRES(Locks::mutator_lock_);
@@ -1058,72 +502,6 @@
 EXPLICIT_DO_INVOKE_VIRTUAL_QUICK_TEMPLATE_DECL(true);   // invoke-virtual-quick-range.
 #undef EXPLICIT_INSTANTIATION_DO_INVOKE_VIRTUAL_QUICK
 
-// Explicitly instantiate all DoCreateLambda functions.
-#define EXPLICIT_DO_CREATE_LAMBDA_DECL(_do_check)                                                 \
-template SHARED_REQUIRES(Locks::mutator_lock_)                                                    \
-bool DoCreateLambda<_do_check>(Thread* self,                                                      \
-                               const Instruction* inst,                                           \
-                               /*inout*/ShadowFrame& shadow_frame,                                \
-                               /*inout*/lambda::ClosureBuilder* closure_builder,                  \
-                               /*inout*/lambda::Closure* uninitialized_closure);
-
-EXPLICIT_DO_CREATE_LAMBDA_DECL(false);  // create-lambda
-EXPLICIT_DO_CREATE_LAMBDA_DECL(true);   // create-lambda
-#undef EXPLICIT_DO_CREATE_LAMBDA_DECL
-
-// Explicitly instantiate all DoInvokeLambda functions.
-#define EXPLICIT_DO_INVOKE_LAMBDA_DECL(_do_check)                                    \
-template SHARED_REQUIRES(Locks::mutator_lock_)                                 \
-bool DoInvokeLambda<_do_check>(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, \
-                               uint16_t inst_data, JValue* result);
-
-EXPLICIT_DO_INVOKE_LAMBDA_DECL(false);  // invoke-lambda
-EXPLICIT_DO_INVOKE_LAMBDA_DECL(true);   // invoke-lambda
-#undef EXPLICIT_DO_INVOKE_LAMBDA_DECL
-
-// Explicitly instantiate all DoBoxLambda functions.
-#define EXPLICIT_DO_BOX_LAMBDA_DECL(_do_check)                                                \
-template SHARED_REQUIRES(Locks::mutator_lock_)                                          \
-bool DoBoxLambda<_do_check>(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, \
-                            uint16_t inst_data);
-
-EXPLICIT_DO_BOX_LAMBDA_DECL(false);  // box-lambda
-EXPLICIT_DO_BOX_LAMBDA_DECL(true);   // box-lambda
-#undef EXPLICIT_DO_BOX_LAMBDA_DECL
-
-// Explicitly instantiate all DoUnBoxLambda functions.
-#define EXPLICIT_DO_UNBOX_LAMBDA_DECL(_do_check)                                                \
-template SHARED_REQUIRES(Locks::mutator_lock_)                                            \
-bool DoUnboxLambda<_do_check>(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, \
-                              uint16_t inst_data);
-
-EXPLICIT_DO_UNBOX_LAMBDA_DECL(false);  // unbox-lambda
-EXPLICIT_DO_UNBOX_LAMBDA_DECL(true);   // unbox-lambda
-#undef EXPLICIT_DO_BOX_LAMBDA_DECL
-
-// Explicitly instantiate all DoCaptureVariable functions.
-#define EXPLICIT_DO_CAPTURE_VARIABLE_DECL(_do_check)                                    \
-template SHARED_REQUIRES(Locks::mutator_lock_)                                          \
-bool DoCaptureVariable<_do_check>(Thread* self,                                         \
-                                  const Instruction* inst,                              \
-                                  ShadowFrame& shadow_frame,                            \
-                                  lambda::ClosureBuilder* closure_builder);
-
-EXPLICIT_DO_CAPTURE_VARIABLE_DECL(false);  // capture-variable
-EXPLICIT_DO_CAPTURE_VARIABLE_DECL(true);   // capture-variable
-#undef EXPLICIT_DO_CREATE_LAMBDA_DECL
-
-// Explicitly instantiate all DoLiberateVariable functions.
-#define EXPLICIT_DO_LIBERATE_VARIABLE_DECL(_do_check)                                   \
-template SHARED_REQUIRES(Locks::mutator_lock_)                                          \
-bool DoLiberateVariable<_do_check>(Thread* self,                                        \
-                                   const Instruction* inst,                             \
-                                   size_t captured_variable_index,                      \
-                                   ShadowFrame& shadow_frame);                          \
-
-EXPLICIT_DO_LIBERATE_VARIABLE_DECL(false);  // liberate-variable
-EXPLICIT_DO_LIBERATE_VARIABLE_DECL(true);   // liberate-variable
-#undef EXPLICIT_DO_LIBERATE_LAMBDA_DECL
 }  // namespace interpreter
 }  // namespace art