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.cc b/runtime/interpreter/interpreter_common.cc
index 11b7ef4..ac146b3 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -30,9 +30,6 @@
namespace art {
namespace interpreter {
-// All lambda closures have to be a consecutive pair of virtual registers.
-static constexpr size_t kLambdaVirtualRegisterWidth = 2;
-
void ThrowNullPointerExceptionFromInterpreter() {
ThrowNullPointerExceptionFromDexPC();
}
@@ -732,7 +729,6 @@
// Fast path: no extra checks.
if (is_range) {
- // TODO: Implement the range version of invoke-lambda
uint16_t first_src_reg = vregC;
for (size_t src_reg = first_src_reg, dest_reg = first_dest_reg; dest_reg < num_regs;
@@ -772,34 +768,6 @@
}
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 ATTRIBUTE_UNUSED, JValue* result) {
- const uint4_t num_additional_registers = inst->VRegB_25x();
- // Argument word count.
- const uint16_t number_of_inputs = num_additional_registers + kLambdaVirtualRegisterWidth;
- // The lambda closure register is always present and is not encoded in the count.
- // Furthermore, the lambda closure register is always wide, so it counts as 2 inputs.
-
- // TODO: find a cleaner way to separate non-range and range information without duplicating
- // code.
- uint32_t arg[Instruction::kMaxVarArgRegs25x]; // only used in invoke-XXX.
- uint32_t vregC = 0; // only used in invoke-XXX-range.
- if (is_range) {
- vregC = inst->VRegC_3rc();
- } else {
- // TODO(iam): See if it's possible to remove inst_data dependency from 35x to avoid this path
- inst->GetAllArgs25x(arg);
- }
-
- // TODO: if there's an assignability check, throw instead?
- DCHECK(called_method->IsStatic());
-
- return DoCallCommon<is_range, do_assignability_check>(
- called_method, self, shadow_frame,
- result, number_of_inputs, arg, vregC);
-}
-
-template<bool is_range, bool do_assignability_check>
bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame,
const Instruction* inst, uint16_t inst_data, JValue* result) {
// Argument word count.
@@ -947,20 +915,6 @@
EXPLICIT_DO_CALL_TEMPLATE_DECL(true, true);
#undef EXPLICIT_DO_CALL_TEMPLATE_DECL
-// Explicit DoLambdaCall template function declarations.
-#define EXPLICIT_DO_LAMBDA_CALL_TEMPLATE_DECL(_is_range, _do_assignability_check) \
- template SHARED_REQUIRES(Locks::mutator_lock_) \
- bool DoLambdaCall<_is_range, _do_assignability_check>(ArtMethod* method, Thread* self, \
- ShadowFrame& shadow_frame, \
- const Instruction* inst, \
- uint16_t inst_data, \
- JValue* result)
-EXPLICIT_DO_LAMBDA_CALL_TEMPLATE_DECL(false, false);
-EXPLICIT_DO_LAMBDA_CALL_TEMPLATE_DECL(false, true);
-EXPLICIT_DO_LAMBDA_CALL_TEMPLATE_DECL(true, false);
-EXPLICIT_DO_LAMBDA_CALL_TEMPLATE_DECL(true, true);
-#undef EXPLICIT_DO_LAMBDA_CALL_TEMPLATE_DECL
-
// Explicit DoFilledNewArray template function declarations.
#define EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(_is_range_, _check, _transaction_active) \
template SHARED_REQUIRES(Locks::mutator_lock_) \
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
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index 3b6e015..43b2778 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -18,14 +18,11 @@
// Clang 3.4 fails to build the goto interpreter implementation.
-#include "base/stl_util.h" // MakeUnique
#include "experimental_flags.h"
#include "interpreter_common.h"
#include "jit/jit.h"
#include "safe_math.h"
-#include <memory> // std::unique_ptr
-
namespace art {
namespace interpreter {
@@ -93,16 +90,6 @@
#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
-// Use with instructions labeled with kExperimental flag:
-#define HANDLE_EXPERIMENTAL_INSTRUCTION_START(opcode) \
- HANDLE_INSTRUCTION_START(opcode); \
- DCHECK(inst->IsExperimental()); \
- if (Runtime::Current()->AreExperimentalFlagsEnabled(ExperimentalFlags::kLambdas)) {
-#define HANDLE_EXPERIMENTAL_INSTRUCTION_END() \
- } else { \
- UnexpectedOpcode(inst, shadow_frame); \
- } HANDLE_INSTRUCTION_END();
-
#define HANDLE_MONITOR_CHECKS() \
if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
HANDLE_PENDING_EXCEPTION(); \
@@ -190,8 +177,6 @@
uint16_t inst_data;
const void* const* currentHandlersTable;
UPDATE_HANDLER_TABLE();
- std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
- size_t lambda_captured_variable_index = 0;
const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
ArtMethod* method = shadow_frame.GetMethod();
jit::Jit* jit = Runtime::Current()->GetJit();
@@ -1668,14 +1653,6 @@
}
HANDLE_INSTRUCTION_END();
- HANDLE_EXPERIMENTAL_INSTRUCTION_START(INVOKE_LAMBDA) {
- bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
- &result_register);
- UPDATE_HANDLER_TABLE();
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
- }
- HANDLE_EXPERIMENTAL_INSTRUCTION_END();
-
HANDLE_INSTRUCTION_START(NEG_INT)
shadow_frame.SetVReg(
inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
@@ -2457,62 +2434,6 @@
ADVANCE(2);
HANDLE_INSTRUCTION_END();
- HANDLE_EXPERIMENTAL_INSTRUCTION_START(CREATE_LAMBDA) {
- if (lambda_closure_builder == nullptr) {
- // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
- lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
- }
-
- // TODO: these allocations should not leak, and the lambda method should not be local.
- lambda::Closure* lambda_closure =
- reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
- bool success = DoCreateLambda<do_access_check>(self,
- inst,
- /*inout*/shadow_frame,
- /*inout*/lambda_closure_builder.get(),
- /*inout*/lambda_closure);
- lambda_closure_builder.reset(nullptr); // reset state of variables captured
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
- }
- HANDLE_EXPERIMENTAL_INSTRUCTION_END();
-
- HANDLE_EXPERIMENTAL_INSTRUCTION_START(BOX_LAMBDA) {
- bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
- }
- HANDLE_EXPERIMENTAL_INSTRUCTION_END();
-
- HANDLE_EXPERIMENTAL_INSTRUCTION_START(UNBOX_LAMBDA) {
- bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
- }
- HANDLE_EXPERIMENTAL_INSTRUCTION_END();
-
- HANDLE_EXPERIMENTAL_INSTRUCTION_START(CAPTURE_VARIABLE) {
- if (lambda_closure_builder == nullptr) {
- lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
- }
-
- bool success = DoCaptureVariable<do_access_check>(self,
- inst,
- /*inout*/shadow_frame,
- /*inout*/lambda_closure_builder.get());
-
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
- }
- HANDLE_EXPERIMENTAL_INSTRUCTION_END();
-
- HANDLE_EXPERIMENTAL_INSTRUCTION_START(LIBERATE_VARIABLE) {
- bool success = DoLiberateVariable<do_access_check>(self,
- inst,
- lambda_captured_variable_index,
- /*inout*/shadow_frame);
- // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
- lambda_captured_variable_index++;
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
- }
- HANDLE_EXPERIMENTAL_INSTRUCTION_END();
-
HANDLE_INSTRUCTION_START(UNUSED_3E)
UnexpectedOpcode(inst, shadow_frame);
HANDLE_INSTRUCTION_END();
@@ -2545,10 +2466,34 @@
UnexpectedOpcode(inst, shadow_frame);
HANDLE_INSTRUCTION_END();
+ HANDLE_INSTRUCTION_START(UNUSED_F3)
+ UnexpectedOpcode(inst, shadow_frame);
+ HANDLE_INSTRUCTION_END();
+
HANDLE_INSTRUCTION_START(UNUSED_F4)
UnexpectedOpcode(inst, shadow_frame);
HANDLE_INSTRUCTION_END();
+ HANDLE_INSTRUCTION_START(UNUSED_F5)
+ UnexpectedOpcode(inst, shadow_frame);
+ HANDLE_INSTRUCTION_END();
+
+ HANDLE_INSTRUCTION_START(UNUSED_F6)
+ UnexpectedOpcode(inst, shadow_frame);
+ HANDLE_INSTRUCTION_END();
+
+ HANDLE_INSTRUCTION_START(UNUSED_F7)
+ UnexpectedOpcode(inst, shadow_frame);
+ HANDLE_INSTRUCTION_END();
+
+ HANDLE_INSTRUCTION_START(UNUSED_F8)
+ UnexpectedOpcode(inst, shadow_frame);
+ HANDLE_INSTRUCTION_END();
+
+ HANDLE_INSTRUCTION_START(UNUSED_F9)
+ UnexpectedOpcode(inst, shadow_frame);
+ HANDLE_INSTRUCTION_END();
+
HANDLE_INSTRUCTION_START(UNUSED_FA)
UnexpectedOpcode(inst, shadow_frame);
HANDLE_INSTRUCTION_END();
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 8bfc10c..3623db2 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -15,14 +15,11 @@
*/
#include "base/enums.h"
-#include "base/stl_util.h" // MakeUnique
#include "experimental_flags.h"
#include "interpreter_common.h"
#include "jit/jit.h"
#include "safe_math.h"
-#include <memory> // std::unique_ptr
-
namespace art {
namespace interpreter {
@@ -92,11 +89,6 @@
} \
} while (false)
-static bool IsExperimentalInstructionEnabled(const Instruction *inst) {
- DCHECK(inst->IsExperimental());
- return Runtime::Current()->AreExperimentalFlagsEnabled(ExperimentalFlags::kLambdas);
-}
-
template<bool do_access_check, bool transaction_active>
JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
ShadowFrame& shadow_frame, JValue result_register,
@@ -116,10 +108,6 @@
ArtMethod* method = shadow_frame.GetMethod();
jit::Jit* jit = Runtime::Current()->GetJit();
- // TODO: collapse capture-variable+create-lambda into one opcode, then we won't need
- // to keep this live for the scope of the entire function call.
- std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
- size_t lambda_captured_variable_index = 0;
do {
dex_pc = inst->GetDexPc(insns);
shadow_frame.SetDexPC(dex_pc);
@@ -2333,103 +2321,8 @@
(inst->VRegC_22b() & 0x1f));
inst = inst->Next_2xx();
break;
- case Instruction::INVOKE_LAMBDA: {
- if (!IsExperimentalInstructionEnabled(inst)) {
- UnexpectedOpcode(inst, shadow_frame);
- }
-
- PREAMBLE();
- bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
- &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
- break;
- }
- case Instruction::CAPTURE_VARIABLE: {
- if (!IsExperimentalInstructionEnabled(inst)) {
- UnexpectedOpcode(inst, shadow_frame);
- }
-
- if (lambda_closure_builder == nullptr) {
- lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
- }
-
- PREAMBLE();
- bool success = DoCaptureVariable<do_access_check>(self,
- inst,
- /*inout*/shadow_frame,
- /*inout*/lambda_closure_builder.get());
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
- break;
- }
- case Instruction::CREATE_LAMBDA: {
- if (!IsExperimentalInstructionEnabled(inst)) {
- UnexpectedOpcode(inst, shadow_frame);
- }
-
- PREAMBLE();
-
- if (lambda_closure_builder == nullptr) {
- // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
- lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
- }
-
- // TODO: these allocations should not leak, and the lambda method should not be local.
- lambda::Closure* lambda_closure =
- reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
- bool success = DoCreateLambda<do_access_check>(self,
- inst,
- /*inout*/shadow_frame,
- /*inout*/lambda_closure_builder.get(),
- /*inout*/lambda_closure);
- lambda_closure_builder.reset(nullptr); // reset state of variables captured
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
- break;
- }
- case Instruction::LIBERATE_VARIABLE: {
- if (!IsExperimentalInstructionEnabled(inst)) {
- UnexpectedOpcode(inst, shadow_frame);
- }
-
- PREAMBLE();
- bool success = DoLiberateVariable<do_access_check>(self,
- inst,
- lambda_captured_variable_index,
- /*inout*/shadow_frame);
- // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
- lambda_captured_variable_index++;
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
- break;
- }
- case Instruction::UNUSED_F4: {
- if (!IsExperimentalInstructionEnabled(inst)) {
- UnexpectedOpcode(inst, shadow_frame);
- }
-
- CHECK(false); // TODO(iam): Implement opcodes for lambdas
- break;
- }
- case Instruction::BOX_LAMBDA: {
- if (!IsExperimentalInstructionEnabled(inst)) {
- UnexpectedOpcode(inst, shadow_frame);
- }
-
- PREAMBLE();
- bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
- break;
- }
- case Instruction::UNBOX_LAMBDA: {
- if (!IsExperimentalInstructionEnabled(inst)) {
- UnexpectedOpcode(inst, shadow_frame);
- }
-
- PREAMBLE();
- bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
- POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
- break;
- }
case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
- case Instruction::UNUSED_FA ... Instruction::UNUSED_FF:
+ case Instruction::UNUSED_F3 ... Instruction::UNUSED_FF:
case Instruction::UNUSED_79:
case Instruction::UNUSED_7A:
UnexpectedOpcode(inst, shadow_frame);
diff --git a/runtime/interpreter/mterp/config_arm b/runtime/interpreter/mterp/config_arm
index 436dcd2..b6caf11 100644
--- a/runtime/interpreter/mterp/config_arm
+++ b/runtime/interpreter/mterp/config_arm
@@ -279,13 +279,13 @@
# op op_iget_byte_quick FALLBACK
# op op_iget_char_quick FALLBACK
# op op_iget_short_quick FALLBACK
- op op_invoke_lambda FALLBACK
+ # op op_unused_f3 FALLBACK
# op op_unused_f4 FALLBACK
- op op_capture_variable FALLBACK
- op op_create_lambda FALLBACK
- op op_liberate_variable FALLBACK
- op op_box_lambda FALLBACK
- op op_unbox_lambda FALLBACK
+ # op op_unused_f5 FALLBACK
+ # op op_unused_f6 FALLBACK
+ # op op_unused_f7 FALLBACK
+ # op op_unused_f8 FALLBACK
+ # op op_unused_f9 FALLBACK
# op op_unused_fa FALLBACK
# op op_unused_fb FALLBACK
# op op_unused_fc FALLBACK
diff --git a/runtime/interpreter/mterp/config_arm64 b/runtime/interpreter/mterp/config_arm64
index 6427ead..c5e06c7 100644
--- a/runtime/interpreter/mterp/config_arm64
+++ b/runtime/interpreter/mterp/config_arm64
@@ -277,13 +277,13 @@
# op op_iget_byte_quick FALLBACK
# op op_iget_char_quick FALLBACK
# op op_iget_short_quick FALLBACK
- op op_invoke_lambda FALLBACK
+ # op op_unused_f3 FALLBACK
# op op_unused_f4 FALLBACK
- op op_capture_variable FALLBACK
- op op_create_lambda FALLBACK
- op op_liberate_variable FALLBACK
- op op_box_lambda FALLBACK
- op op_unbox_lambda FALLBACK
+ # op op_unused_f5 FALLBACK
+ # op op_unused_f6 FALLBACK
+ # op op_unused_f7 FALLBACK
+ # op op_unused_f8 FALLBACK
+ # op op_unused_f9 FALLBACK
# op op_unused_fa FALLBACK
# op op_unused_fb FALLBACK
# op op_unused_fc FALLBACK
diff --git a/runtime/interpreter/mterp/config_mips b/runtime/interpreter/mterp/config_mips
index c6292c3..515cb0b 100644
--- a/runtime/interpreter/mterp/config_mips
+++ b/runtime/interpreter/mterp/config_mips
@@ -279,13 +279,13 @@
# op op_iget_byte_quick FALLBACK
# op op_iget_char_quick FALLBACK
# op op_iget_short_quick FALLBACK
- op op_invoke_lambda FALLBACK
+ # op op_unused_f3 FALLBACK
# op op_unused_f4 FALLBACK
- op op_capture_variable FALLBACK
- op op_create_lambda FALLBACK
- op op_liberate_variable FALLBACK
- op op_box_lambda FALLBACK
- op op_unbox_lambda FALLBACK
+ # op op_unused_f5 FALLBACK
+ # op op_unused_f6 FALLBACK
+ # op op_unused_f7 FALLBACK
+ # op op_unused_f8 FALLBACK
+ # op op_unused_f9 FALLBACK
# op op_unused_fa FALLBACK
# op op_unused_fb FALLBACK
# op op_unused_fc FALLBACK
diff --git a/runtime/interpreter/mterp/config_mips64 b/runtime/interpreter/mterp/config_mips64
index c40c007..aafd248 100644
--- a/runtime/interpreter/mterp/config_mips64
+++ b/runtime/interpreter/mterp/config_mips64
@@ -279,13 +279,13 @@
# op op_iget_byte_quick FALLBACK
# op op_iget_char_quick FALLBACK
# op op_iget_short_quick FALLBACK
- op op_invoke_lambda FALLBACK
+ # op op_unused_f3 FALLBACK
# op op_unused_f4 FALLBACK
- op op_capture_variable FALLBACK
- op op_create_lambda FALLBACK
- op op_liberate_variable FALLBACK
- op op_box_lambda FALLBACK
- op op_unbox_lambda FALLBACK
+ # op op_unused_f5 FALLBACK
+ # op op_unused_f6 FALLBACK
+ # op op_unused_f7 FALLBACK
+ # op op_unused_f8 FALLBACK
+ # op op_unused_f9 FALLBACK
# op op_unused_fa FALLBACK
# op op_unused_fb FALLBACK
# op op_unused_fc FALLBACK
diff --git a/runtime/interpreter/mterp/config_x86 b/runtime/interpreter/mterp/config_x86
index f1501e1..64d8ee8 100644
--- a/runtime/interpreter/mterp/config_x86
+++ b/runtime/interpreter/mterp/config_x86
@@ -283,13 +283,13 @@
# op op_iget_byte_quick FALLBACK
# op op_iget_char_quick FALLBACK
# op op_iget_short_quick FALLBACK
- op op_invoke_lambda FALLBACK
+ # op op_unused_f3 FALLBACK
# op op_unused_f4 FALLBACK
- op op_capture_variable FALLBACK
- op op_create_lambda FALLBACK
- op op_liberate_variable FALLBACK
- op op_box_lambda FALLBACK
- op op_unbox_lambda FALLBACK
+ # op op_unused_f5 FALLBACK
+ # op op_unused_f6 FALLBACK
+ # op op_unused_f7 FALLBACK
+ # op op_unused_f8 FALLBACK
+ # op op_unused_f9 FALLBACK
# op op_unused_fa FALLBACK
# op op_unused_fb FALLBACK
# op op_unused_fc FALLBACK
diff --git a/runtime/interpreter/mterp/config_x86_64 b/runtime/interpreter/mterp/config_x86_64
index 1d7eb03..7c357db 100644
--- a/runtime/interpreter/mterp/config_x86_64
+++ b/runtime/interpreter/mterp/config_x86_64
@@ -283,13 +283,13 @@
# op op_iget_byte_quick FALLBACK
# op op_iget_char_quick FALLBACK
# op op_iget_short_quick FALLBACK
- op op_invoke_lambda FALLBACK
+ # op op_unused_f3 FALLBACK
# op op_unused_f4 FALLBACK
- op op_capture_variable FALLBACK
- op op_create_lambda FALLBACK
- op op_liberate_variable FALLBACK
- op op_box_lambda FALLBACK
- op op_unbox_lambda FALLBACK
+ # op op_unused_f5 FALLBACK
+ # op op_unused_f6 FALLBACK
+ # op op_unused_f7 FALLBACK
+ # op op_unused_f8 FALLBACK
+ # op op_unused_f9 FALLBACK
# op op_unused_fa FALLBACK
# op op_unused_fb FALLBACK
# op op_unused_fc FALLBACK
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f3.S b/runtime/interpreter/mterp/mips64/op_unused_f3.S
new file mode 100644
index 0000000..29463d7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/op_unused_f3.S
@@ -0,0 +1 @@
+%include "mips64/unused.S"
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f5.S b/runtime/interpreter/mterp/mips64/op_unused_f5.S
new file mode 100644
index 0000000..29463d7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/op_unused_f5.S
@@ -0,0 +1 @@
+%include "mips64/unused.S"
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f6.S b/runtime/interpreter/mterp/mips64/op_unused_f6.S
new file mode 100644
index 0000000..29463d7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/op_unused_f6.S
@@ -0,0 +1 @@
+%include "mips64/unused.S"
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f7.S b/runtime/interpreter/mterp/mips64/op_unused_f7.S
new file mode 100644
index 0000000..29463d7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/op_unused_f7.S
@@ -0,0 +1 @@
+%include "mips64/unused.S"
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f8.S b/runtime/interpreter/mterp/mips64/op_unused_f8.S
new file mode 100644
index 0000000..29463d7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/op_unused_f8.S
@@ -0,0 +1 @@
+%include "mips64/unused.S"
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f9.S b/runtime/interpreter/mterp/mips64/op_unused_f9.S
new file mode 100644
index 0000000..29463d7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/op_unused_f9.S
@@ -0,0 +1 @@
+%include "mips64/unused.S"
diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S
index df25767..1bcdd76 100644
--- a/runtime/interpreter/mterp/out/mterp_arm.S
+++ b/runtime/interpreter/mterp/out/mterp_arm.S
@@ -7201,9 +7201,13 @@
/* ------------------------------ */
.balign 128
-.L_op_invoke_lambda: /* 0xf3 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f3: /* 0xf3 */
+/* File: arm/op_unused_f3.S */
+/* File: arm/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
@@ -7219,37 +7223,57 @@
/* ------------------------------ */
.balign 128
-.L_op_capture_variable: /* 0xf5 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f5: /* 0xf5 */
+/* File: arm/op_unused_f5.S */
+/* File: arm/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_create_lambda: /* 0xf6 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f6: /* 0xf6 */
+/* File: arm/op_unused_f6.S */
+/* File: arm/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_liberate_variable: /* 0xf7 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f7: /* 0xf7 */
+/* File: arm/op_unused_f7.S */
+/* File: arm/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_box_lambda: /* 0xf8 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f8: /* 0xf8 */
+/* File: arm/op_unused_f8.S */
+/* File: arm/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_unbox_lambda: /* 0xf9 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f9: /* 0xf9 */
+/* File: arm/op_unused_f9.S */
+/* File: arm/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
@@ -11564,7 +11588,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_invoke_lambda: /* 0xf3 */
+.L_ALT_op_unused_f3: /* 0xf3 */
/* File: arm/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11598,7 +11622,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_capture_variable: /* 0xf5 */
+.L_ALT_op_unused_f5: /* 0xf5 */
/* File: arm/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11615,7 +11639,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_create_lambda: /* 0xf6 */
+.L_ALT_op_unused_f6: /* 0xf6 */
/* File: arm/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11632,7 +11656,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_liberate_variable: /* 0xf7 */
+.L_ALT_op_unused_f7: /* 0xf7 */
/* File: arm/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11649,7 +11673,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_box_lambda: /* 0xf8 */
+.L_ALT_op_unused_f8: /* 0xf8 */
/* File: arm/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11666,7 +11690,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_unbox_lambda: /* 0xf9 */
+.L_ALT_op_unused_f9: /* 0xf9 */
/* File: arm/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S
index de37e07..136bf20 100644
--- a/runtime/interpreter/mterp/out/mterp_arm64.S
+++ b/runtime/interpreter/mterp/out/mterp_arm64.S
@@ -6741,9 +6741,13 @@
/* ------------------------------ */
.balign 128
-.L_op_invoke_lambda: /* 0xf3 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f3: /* 0xf3 */
+/* File: arm64/op_unused_f3.S */
+/* File: arm64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
@@ -6759,37 +6763,57 @@
/* ------------------------------ */
.balign 128
-.L_op_capture_variable: /* 0xf5 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f5: /* 0xf5 */
+/* File: arm64/op_unused_f5.S */
+/* File: arm64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_create_lambda: /* 0xf6 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f6: /* 0xf6 */
+/* File: arm64/op_unused_f6.S */
+/* File: arm64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_liberate_variable: /* 0xf7 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f7: /* 0xf7 */
+/* File: arm64/op_unused_f7.S */
+/* File: arm64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_box_lambda: /* 0xf8 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f8: /* 0xf8 */
+/* File: arm64/op_unused_f8.S */
+/* File: arm64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_unbox_lambda: /* 0xf9 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f9: /* 0xf9 */
+/* File: arm64/op_unused_f9.S */
+/* File: arm64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
/* ------------------------------ */
@@ -11332,7 +11356,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_invoke_lambda: /* 0xf3 */
+.L_ALT_op_unused_f3: /* 0xf3 */
/* File: arm64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11366,7 +11390,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_capture_variable: /* 0xf5 */
+.L_ALT_op_unused_f5: /* 0xf5 */
/* File: arm64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11383,7 +11407,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_create_lambda: /* 0xf6 */
+.L_ALT_op_unused_f6: /* 0xf6 */
/* File: arm64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11400,7 +11424,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_liberate_variable: /* 0xf7 */
+.L_ALT_op_unused_f7: /* 0xf7 */
/* File: arm64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11417,7 +11441,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_box_lambda: /* 0xf8 */
+.L_ALT_op_unused_f8: /* 0xf8 */
/* File: arm64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11434,7 +11458,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_unbox_lambda: /* 0xf9 */
+.L_ALT_op_unused_f9: /* 0xf9 */
/* File: arm64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
diff --git a/runtime/interpreter/mterp/out/mterp_mips.S b/runtime/interpreter/mterp/out/mterp_mips.S
index 5e0c19f..fef7dc6 100644
--- a/runtime/interpreter/mterp/out/mterp_mips.S
+++ b/runtime/interpreter/mterp/out/mterp_mips.S
@@ -7547,9 +7547,14 @@
/* ------------------------------ */
.balign 128
-.L_op_invoke_lambda: /* 0xf3 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f3: /* 0xf3 */
+/* File: mips/op_unused_f3.S */
+/* File: mips/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
/* ------------------------------ */
.balign 128
@@ -7564,33 +7569,58 @@
/* ------------------------------ */
.balign 128
-.L_op_capture_variable: /* 0xf5 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f5: /* 0xf5 */
+/* File: mips/op_unused_f5.S */
+/* File: mips/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
/* ------------------------------ */
.balign 128
-.L_op_create_lambda: /* 0xf6 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f6: /* 0xf6 */
+/* File: mips/op_unused_f6.S */
+/* File: mips/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
/* ------------------------------ */
.balign 128
-.L_op_liberate_variable: /* 0xf7 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f7: /* 0xf7 */
+/* File: mips/op_unused_f7.S */
+/* File: mips/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
/* ------------------------------ */
.balign 128
-.L_op_box_lambda: /* 0xf8 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f8: /* 0xf8 */
+/* File: mips/op_unused_f8.S */
+/* File: mips/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
/* ------------------------------ */
.balign 128
-.L_op_unbox_lambda: /* 0xf9 */
-/* Transfer stub to alternate interpreter */
- b MterpFallback
+.L_op_unused_f9: /* 0xf9 */
+/* File: mips/op_unused_f9.S */
+/* File: mips/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
/* ------------------------------ */
.balign 128
@@ -12381,7 +12411,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_invoke_lambda: /* 0xf3 */
+.L_ALT_op_unused_f3: /* 0xf3 */
/* File: mips/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12417,7 +12447,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_capture_variable: /* 0xf5 */
+.L_ALT_op_unused_f5: /* 0xf5 */
/* File: mips/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12435,7 +12465,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_create_lambda: /* 0xf6 */
+.L_ALT_op_unused_f6: /* 0xf6 */
/* File: mips/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12453,7 +12483,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_liberate_variable: /* 0xf7 */
+.L_ALT_op_unused_f7: /* 0xf7 */
/* File: mips/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12471,7 +12501,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_box_lambda: /* 0xf8 */
+.L_ALT_op_unused_f8: /* 0xf8 */
/* File: mips/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12489,7 +12519,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_unbox_lambda: /* 0xf9 */
+.L_ALT_op_unused_f9: /* 0xf9 */
/* File: mips/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
diff --git a/runtime/interpreter/mterp/out/mterp_mips64.S b/runtime/interpreter/mterp/out/mterp_mips64.S
index 35fbe94..a061f1e 100644
--- a/runtime/interpreter/mterp/out/mterp_mips64.S
+++ b/runtime/interpreter/mterp/out/mterp_mips64.S
@@ -7003,10 +7003,15 @@
/* ------------------------------ */
.balign 128
-.L_op_invoke_lambda: /* 0xf3 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f3: /* 0xf3 */
+/* File: mips64/op_unused_f3.S */
+/* File: mips64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
b MterpFallback
+
/* ------------------------------ */
.balign 128
.L_op_unused_f4: /* 0xf4 */
@@ -7020,34 +7025,59 @@
/* ------------------------------ */
.balign 128
-.L_op_capture_variable: /* 0xf5 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f5: /* 0xf5 */
+/* File: mips64/op_unused_f5.S */
+/* File: mips64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
b MterpFallback
+
/* ------------------------------ */
.balign 128
-.L_op_create_lambda: /* 0xf6 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f6: /* 0xf6 */
+/* File: mips64/op_unused_f6.S */
+/* File: mips64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
b MterpFallback
+
/* ------------------------------ */
.balign 128
-.L_op_liberate_variable: /* 0xf7 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f7: /* 0xf7 */
+/* File: mips64/op_unused_f7.S */
+/* File: mips64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
b MterpFallback
+
/* ------------------------------ */
.balign 128
-.L_op_box_lambda: /* 0xf8 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f8: /* 0xf8 */
+/* File: mips64/op_unused_f8.S */
+/* File: mips64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
b MterpFallback
+
/* ------------------------------ */
.balign 128
-.L_op_unbox_lambda: /* 0xf9 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f9: /* 0xf9 */
+/* File: mips64/op_unused_f9.S */
+/* File: mips64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
b MterpFallback
+
/* ------------------------------ */
.balign 128
.L_op_unused_fa: /* 0xfa */
@@ -11799,7 +11829,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_invoke_lambda: /* 0xf3 */
+.L_ALT_op_unused_f3: /* 0xf3 */
/* File: mips64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11837,7 +11867,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_capture_variable: /* 0xf5 */
+.L_ALT_op_unused_f5: /* 0xf5 */
/* File: mips64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11856,7 +11886,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_create_lambda: /* 0xf6 */
+.L_ALT_op_unused_f6: /* 0xf6 */
/* File: mips64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11875,7 +11905,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_liberate_variable: /* 0xf7 */
+.L_ALT_op_unused_f7: /* 0xf7 */
/* File: mips64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11894,7 +11924,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_box_lambda: /* 0xf8 */
+.L_ALT_op_unused_f8: /* 0xf8 */
/* File: mips64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11913,7 +11943,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_unbox_lambda: /* 0xf9 */
+.L_ALT_op_unused_f9: /* 0xf9 */
/* File: mips64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
diff --git a/runtime/interpreter/mterp/out/mterp_x86.S b/runtime/interpreter/mterp/out/mterp_x86.S
index 5caaa80..29ee248 100644
--- a/runtime/interpreter/mterp/out/mterp_x86.S
+++ b/runtime/interpreter/mterp/out/mterp_x86.S
@@ -6201,8 +6201,12 @@
/* ------------------------------ */
.balign 128
-.L_op_invoke_lambda: /* 0xf3 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f3: /* 0xf3 */
+/* File: x86/op_unused_f3.S */
+/* File: x86/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
@@ -6219,36 +6223,56 @@
/* ------------------------------ */
.balign 128
-.L_op_capture_variable: /* 0xf5 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f5: /* 0xf5 */
+/* File: x86/op_unused_f5.S */
+/* File: x86/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_create_lambda: /* 0xf6 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f6: /* 0xf6 */
+/* File: x86/op_unused_f6.S */
+/* File: x86/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_liberate_variable: /* 0xf7 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f7: /* 0xf7 */
+/* File: x86/op_unused_f7.S */
+/* File: x86/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_box_lambda: /* 0xf8 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f8: /* 0xf8 */
+/* File: x86/op_unused_f8.S */
+/* File: x86/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_unbox_lambda: /* 0xf9 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f9: /* 0xf9 */
+/* File: x86/op_unused_f9.S */
+/* File: x86/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
@@ -12178,7 +12202,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_invoke_lambda: /* 0xf3 */
+.L_ALT_op_unused_f3: /* 0xf3 */
/* File: x86/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12226,7 +12250,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_capture_variable: /* 0xf5 */
+.L_ALT_op_unused_f5: /* 0xf5 */
/* File: x86/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12250,7 +12274,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_create_lambda: /* 0xf6 */
+.L_ALT_op_unused_f6: /* 0xf6 */
/* File: x86/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12274,7 +12298,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_liberate_variable: /* 0xf7 */
+.L_ALT_op_unused_f7: /* 0xf7 */
/* File: x86/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12298,7 +12322,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_box_lambda: /* 0xf8 */
+.L_ALT_op_unused_f8: /* 0xf8 */
/* File: x86/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -12322,7 +12346,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_unbox_lambda: /* 0xf9 */
+.L_ALT_op_unused_f9: /* 0xf9 */
/* File: x86/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
diff --git a/runtime/interpreter/mterp/out/mterp_x86_64.S b/runtime/interpreter/mterp/out/mterp_x86_64.S
index 2f7b854..bc1abcc 100644
--- a/runtime/interpreter/mterp/out/mterp_x86_64.S
+++ b/runtime/interpreter/mterp/out/mterp_x86_64.S
@@ -5966,8 +5966,12 @@
/* ------------------------------ */
.balign 128
-.L_op_invoke_lambda: /* 0xf3 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f3: /* 0xf3 */
+/* File: x86_64/op_unused_f3.S */
+/* File: x86_64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
@@ -5984,36 +5988,56 @@
/* ------------------------------ */
.balign 128
-.L_op_capture_variable: /* 0xf5 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f5: /* 0xf5 */
+/* File: x86_64/op_unused_f5.S */
+/* File: x86_64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_create_lambda: /* 0xf6 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f6: /* 0xf6 */
+/* File: x86_64/op_unused_f6.S */
+/* File: x86_64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_liberate_variable: /* 0xf7 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f7: /* 0xf7 */
+/* File: x86_64/op_unused_f7.S */
+/* File: x86_64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_box_lambda: /* 0xf8 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f8: /* 0xf8 */
+/* File: x86_64/op_unused_f8.S */
+/* File: x86_64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
/* ------------------------------ */
.balign 128
-.L_op_unbox_lambda: /* 0xf9 */
-/* Transfer stub to alternate interpreter */
+.L_op_unused_f9: /* 0xf9 */
+/* File: x86_64/op_unused_f9.S */
+/* File: x86_64/unused.S */
+/*
+ * Bail to reference interpreter to throw.
+ */
jmp MterpFallback
@@ -11457,7 +11481,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_invoke_lambda: /* 0xf3 */
+.L_ALT_op_unused_f3: /* 0xf3 */
/* File: x86_64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11501,7 +11525,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_capture_variable: /* 0xf5 */
+.L_ALT_op_unused_f5: /* 0xf5 */
/* File: x86_64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11523,7 +11547,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_create_lambda: /* 0xf6 */
+.L_ALT_op_unused_f6: /* 0xf6 */
/* File: x86_64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11545,7 +11569,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_liberate_variable: /* 0xf7 */
+.L_ALT_op_unused_f7: /* 0xf7 */
/* File: x86_64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11567,7 +11591,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_box_lambda: /* 0xf8 */
+.L_ALT_op_unused_f8: /* 0xf8 */
/* File: x86_64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
@@ -11589,7 +11613,7 @@
/* ------------------------------ */
.balign 128
-.L_ALT_op_unbox_lambda: /* 0xf9 */
+.L_ALT_op_unused_f9: /* 0xf9 */
/* File: x86_64/alt_stub.S */
/*
* Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
diff --git a/runtime/interpreter/mterp/x86/op_unused_f3.S b/runtime/interpreter/mterp/x86/op_unused_f3.S
new file mode 100644
index 0000000..31d98c1
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/op_unused_f3.S
@@ -0,0 +1 @@
+%include "x86/unused.S"
diff --git a/runtime/interpreter/mterp/x86/op_unused_f5.S b/runtime/interpreter/mterp/x86/op_unused_f5.S
new file mode 100644
index 0000000..31d98c1
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/op_unused_f5.S
@@ -0,0 +1 @@
+%include "x86/unused.S"
diff --git a/runtime/interpreter/mterp/x86/op_unused_f6.S b/runtime/interpreter/mterp/x86/op_unused_f6.S
new file mode 100644
index 0000000..31d98c1
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/op_unused_f6.S
@@ -0,0 +1 @@
+%include "x86/unused.S"
diff --git a/runtime/interpreter/mterp/x86/op_unused_f7.S b/runtime/interpreter/mterp/x86/op_unused_f7.S
new file mode 100644
index 0000000..31d98c1
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/op_unused_f7.S
@@ -0,0 +1 @@
+%include "x86/unused.S"
diff --git a/runtime/interpreter/mterp/x86/op_unused_f8.S b/runtime/interpreter/mterp/x86/op_unused_f8.S
new file mode 100644
index 0000000..31d98c1
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/op_unused_f8.S
@@ -0,0 +1 @@
+%include "x86/unused.S"
diff --git a/runtime/interpreter/mterp/x86/op_unused_f9.S b/runtime/interpreter/mterp/x86/op_unused_f9.S
new file mode 100644
index 0000000..31d98c1
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/op_unused_f9.S
@@ -0,0 +1 @@
+%include "x86/unused.S"
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f3.S b/runtime/interpreter/mterp/x86_64/op_unused_f3.S
new file mode 100644
index 0000000..280615f
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/op_unused_f3.S
@@ -0,0 +1 @@
+%include "x86_64/unused.S"
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f5.S b/runtime/interpreter/mterp/x86_64/op_unused_f5.S
new file mode 100644
index 0000000..280615f
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/op_unused_f5.S
@@ -0,0 +1 @@
+%include "x86_64/unused.S"
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f6.S b/runtime/interpreter/mterp/x86_64/op_unused_f6.S
new file mode 100644
index 0000000..280615f
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/op_unused_f6.S
@@ -0,0 +1 @@
+%include "x86_64/unused.S"
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f7.S b/runtime/interpreter/mterp/x86_64/op_unused_f7.S
new file mode 100644
index 0000000..280615f
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/op_unused_f7.S
@@ -0,0 +1 @@
+%include "x86_64/unused.S"
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f8.S b/runtime/interpreter/mterp/x86_64/op_unused_f8.S
new file mode 100644
index 0000000..280615f
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/op_unused_f8.S
@@ -0,0 +1 @@
+%include "x86_64/unused.S"
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f9.S b/runtime/interpreter/mterp/x86_64/op_unused_f9.S
new file mode 100644
index 0000000..280615f
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/op_unused_f9.S
@@ -0,0 +1 @@
+%include "x86_64/unused.S"
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 57443f1..a0e0e62 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -41,6 +41,7 @@
#include "mirror/array-inl.h"
#include "mirror/class.h"
#include "mirror/field-inl.h"
+#include "mirror/method.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/string-inl.h"