Support unwinding though the switch interpreter.
Wrap the switch interpreter in small assembly method which defines
DEX PC in CFI and thus it allows libunwind to backtrace through it.
Bug: 22414682
Test: testrunner.py --host -t 137
Test: testrunner.py --target -t 137
Change-Id: I31dad9f0fb446151baaa99234b64f25c8ca2fa87
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index aa77187..98214fb 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -15,6 +15,7 @@
*/
#include "asm_support_arm.S"
+#include "interpreter/cfi_asm_support.h"
#include "arch/quick_alloc_entrypoints.S"
@@ -2719,3 +2720,18 @@
HANDLER_TABLE_OFFSET(.Lstore_boolean_result) // Z (boolean)
.purgem HANDLER_TABLE_OFFSET
END art_quick_invoke_polymorphic
+
+// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
+// Argument 0: r0: The context pointer for ExecuteSwitchImpl.
+// Argument 1: r1: Pointer to the templated ExecuteSwitchImpl to call.
+// Argument 2: r2: The value of DEX PC (memory address of the methods bytecode).
+ENTRY ExecuteSwitchImplAsm
+ push {r4, lr} // 2 words of callee saves.
+ .cfi_adjust_cfa_offset 8
+ .cfi_rel_offset r4, 0
+ .cfi_rel_offset lr, 4
+ mov r4, r2 // r4 = DEX PC
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* r0 */, 4 /* r4 */, 0)
+ blx r1 // Call the wrapped method.
+ pop {r4, pc}
+END ExecuteSwitchImplAsm
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 375b050..fb449ed 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -15,6 +15,7 @@
*/
#include "asm_support_arm64.S"
+#include "interpreter/cfi_asm_support.h"
#include "arch/quick_alloc_entrypoints.S"
@@ -2928,3 +2929,16 @@
.text
END art_quick_invoke_polymorphic
+
+// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
+// Argument 0: x0: The context pointer for ExecuteSwitchImpl.
+// Argument 1: x1: Pointer to the templated ExecuteSwitchImpl to call.
+// Argument 2: x2: The value of DEX PC (memory address of the methods bytecode).
+ENTRY ExecuteSwitchImplAsm
+ SAVE_TWO_REGS_INCREASE_FRAME x19, xLR, 16
+ mov x19, x2 // x19 = DEX PC
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* x0 */, 19 /* x19 */, 0)
+ blr x1 // Call the wrapped method.
+ RESTORE_TWO_REGS_DECREASE_FRAME x19, xLR, 16
+ ret
+END ExecuteSwitchImplAsm
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index 9251161..5c4ae4e 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -15,6 +15,7 @@
*/
#include "asm_support_x86.S"
+#include "interpreter/cfi_asm_support.h"
#include "arch/quick_alloc_entrypoints.S"
@@ -2516,5 +2517,28 @@
END_FUNCTION art_quick_invoke_polymorphic
+// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
+// Argument 0: ESP+4: The context pointer for ExecuteSwitchImpl.
+// Argument 1: ESP+8: Pointer to the templated ExecuteSwitchImpl to call.
+// Argument 2: ESP+12: The value of DEX PC (memory address of the methods bytecode).
+DEFINE_FUNCTION ExecuteSwitchImplAsm
+ PUSH ebx // Spill EBX; Increments ESP, so arg0 is at ESP+8 now.
+ mov 12(%esp), %eax // EAX = C++ templated interpreter function
+ mov 16(%esp), %ebx // EBX = DEX PC (callee save register)
+ mov 8(%esp), %ecx // ECX = Context argument for the function
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* EAX */, 3 /* EBX */, 0)
+
+ sub LITERAL(4), %esp // Alignment padding
+ CFI_ADJUST_CFA_OFFSET(4)
+ push %ecx // Push argument
+ CFI_ADJUST_CFA_OFFSET(4)
+ call *%eax // Call the wrapped function
+ addl LITERAL(8), %esp
+ CFI_ADJUST_CFA_OFFSET(-8)
+
+ POP ebx // Restore EBX
+ ret
+END_FUNCTION ExecuteSwitchImplAsm
+
// TODO: implement these!
UNIMPLEMENTED art_quick_memcmp16
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 6116844..a813200 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -15,6 +15,7 @@
*/
#include "asm_support_x86_64.S"
+#include "interpreter/cfi_asm_support.h"
#include "arch/quick_alloc_entrypoints.S"
@@ -2481,3 +2482,18 @@
RESTORE_SAVE_REFS_AND_ARGS_FRAME
RETURN_OR_DELIVER_PENDING_EXCEPTION
END_FUNCTION art_quick_invoke_polymorphic
+
+// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
+// Argument 0: RDI: The context pointer for ExecuteSwitchImpl.
+// Argument 1: RSI: Pointer to the templated ExecuteSwitchImpl to call.
+// Argument 2: RDX: The value of DEX PC (memory address of the methods bytecode).
+DEFINE_FUNCTION ExecuteSwitchImplAsm
+ PUSH rbx // Spill RBX
+ movq %rdx, %rbx // RBX = DEX PC (callee save register)
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* RAX */, 3 /* RBX */, 0)
+
+ call *%rsi // Call the wrapped function
+
+ POP rbx // Restore RBX
+ ret
+END_FUNCTION ExecuteSwitchImplAsm
diff --git a/runtime/interpreter/mterp/cfi_asm_support.h b/runtime/interpreter/cfi_asm_support.h
similarity index 92%
rename from runtime/interpreter/mterp/cfi_asm_support.h
rename to runtime/interpreter/cfi_asm_support.h
index 0df4eb4..a9f01af 100644
--- a/runtime/interpreter/mterp/cfi_asm_support.h
+++ b/runtime/interpreter/cfi_asm_support.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ART_RUNTIME_INTERPRETER_MTERP_CFI_ASM_SUPPORT_H_
-#define ART_RUNTIME_INTERPRETER_MTERP_CFI_ASM_SUPPORT_H_
+#ifndef ART_RUNTIME_INTERPRETER_CFI_ASM_SUPPORT_H_
+#define ART_RUNTIME_INTERPRETER_CFI_ASM_SUPPORT_H_
/*
* Define the DEX PC (memory address of the currently interpreted bytecode)
@@ -44,4 +44,4 @@
0x13 /* DW_OP_drop */, \
0x92 /* DW_OP_bregx */, dexReg, (dexOffset & 0x7F) /* 1-byte SLEB128 */
-#endif // ART_RUNTIME_INTERPRETER_MTERP_CFI_ASM_SUPPORT_H_
+#endif // ART_RUNTIME_INTERPRETER_CFI_ASM_SUPPORT_H_
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index e35d80f..283885e 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -39,7 +39,8 @@
/* Signal mterp to return to caller */ \
shadow_frame.SetDexPC(dex::kDexNoIndex); \
} \
- return JValue(); /* Handled in caller. */ \
+ ctx->result = JValue(); /* Handled in caller. */ \
+ return; \
} else { \
int32_t displacement = \
static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
@@ -96,7 +97,8 @@
/* OSR has completed execution of the method. Signal mterp to return to caller */ \
shadow_frame.SetDexPC(dex::kDexNoIndex); \
} \
- return result; \
+ ctx->result = result; \
+ return; \
} \
} while (false)
@@ -193,13 +195,17 @@
}
template<bool do_access_check, bool transaction_active>
-JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction) {
+void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
+ Thread* self = ctx->self;
+ const CodeItemDataAccessor& accessor = ctx->accessor;
+ ShadowFrame& shadow_frame = ctx->shadow_frame;
+ JValue result_register = ctx->result_register;
+ bool interpret_one_instruction = ctx->interpret_one_instruction;
constexpr bool do_assignability_check = do_access_check;
if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
LOG(FATAL) << "Invalid shadow frame for interpreter use";
- return JValue();
+ ctx->result = JValue();
+ return;
}
self->VerifyStack();
@@ -317,7 +323,8 @@
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::RETURN_VOID: {
PREAMBLE();
@@ -339,7 +346,8 @@
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::RETURN: {
PREAMBLE();
@@ -362,7 +370,8 @@
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::RETURN_WIDE: {
PREAMBLE();
@@ -384,7 +393,8 @@
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::RETURN_OBJECT: {
PREAMBLE();
@@ -428,7 +438,8 @@
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::CONST_4: {
PREAMBLE();
@@ -2487,26 +2498,19 @@
} while (!interpret_one_instruction);
// Record where we stopped.
shadow_frame.SetDexPC(inst->GetDexPc(insns));
- return result_register;
+ ctx->result = result_register;
+ return;
} // NOLINT(readability/fn_size)
-// Explicit definitions of ExecuteSwitchImpl.
+// Explicit definitions of ExecuteSwitchImplCpp.
template HOT_ATTR
-JValue ExecuteSwitchImpl<true, false>(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction);
+void ExecuteSwitchImplCpp<true, false>(SwitchImplContext* ctx);
template HOT_ATTR
-JValue ExecuteSwitchImpl<false, false>(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction);
+void ExecuteSwitchImplCpp<false, false>(SwitchImplContext* ctx);
template
-JValue ExecuteSwitchImpl<true, true>(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction);
+void ExecuteSwitchImplCpp<true, true>(SwitchImplContext* ctx);
template
-JValue ExecuteSwitchImpl<false, true>(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction);
+void ExecuteSwitchImplCpp<false, true>(SwitchImplContext* ctx);
} // namespace interpreter
} // namespace art
diff --git a/runtime/interpreter/interpreter_switch_impl.h b/runtime/interpreter/interpreter_switch_impl.h
index 50db337..9fc4239 100644
--- a/runtime/interpreter/interpreter_switch_impl.h
+++ b/runtime/interpreter/interpreter_switch_impl.h
@@ -20,23 +20,59 @@
#include "base/macros.h"
#include "base/mutex.h"
#include "dex/dex_file.h"
+#include "dex/code_item_accessors.h"
#include "jvalue.h"
#include "obj_ptr.h"
namespace art {
-class CodeItemDataAccessor;
class ShadowFrame;
class Thread;
namespace interpreter {
+// Group all the data that is needed in the switch interpreter.
+// We need to pass it to the hand-written assembly and back,
+// so it is easier to pass it through a single pointer.
+// Similarly, returning the JValue type would be non-trivial.
+struct SwitchImplContext {
+ Thread* self;
+ const CodeItemDataAccessor& accessor;
+ ShadowFrame& shadow_frame;
+ JValue& result_register;
+ bool interpret_one_instruction;
+ JValue result;
+};
+
+// The actual internal implementation of the switch interpreter.
template<bool do_access_check, bool transaction_active>
-JValue ExecuteSwitchImpl(Thread* self,
- const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame,
- JValue result_register,
- bool interpret_one_instruction) REQUIRES_SHARED(Locks::mutator_lock_);
+void ExecuteSwitchImplCpp(SwitchImplContext* ctx)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
+// Hand-written assembly method which wraps the C++ implementation,
+// while defining the DEX PC in the CFI so that libunwind can resolve it.
+extern "C" void ExecuteSwitchImplAsm(SwitchImplContext* ctx, void* impl, const uint16_t* dexpc)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
+// Wrapper around the switch interpreter which ensures we can unwind through it.
+template<bool do_access_check, bool transaction_active>
+ALWAYS_INLINE JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
+ ShadowFrame& shadow_frame, JValue result_register,
+ bool interpret_one_instruction)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ SwitchImplContext ctx {
+ .self = self,
+ .accessor = accessor,
+ .shadow_frame = shadow_frame,
+ .result_register = result_register,
+ .interpret_one_instruction = interpret_one_instruction,
+ .result = JValue(),
+ };
+ void* impl = reinterpret_cast<void*>(&ExecuteSwitchImplCpp<do_access_check, transaction_active>);
+ const uint16_t* dex_pc = ctx.accessor.Insns();
+ ExecuteSwitchImplAsm(&ctx, impl, dex_pc);
+ return ctx.result;
+}
} // namespace interpreter
} // namespace art
diff --git a/runtime/interpreter/mterp/arm/header.S b/runtime/interpreter/mterp/arm/header.S
index 1f15f87..8d9cab5 100644
--- a/runtime/interpreter/mterp/arm/header.S
+++ b/runtime/interpreter/mterp/arm/header.S
@@ -85,7 +85,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
#define MTERP_PROFILE_BRANCHES 1
#define MTERP_LOGGING 0
diff --git a/runtime/interpreter/mterp/arm64/header.S b/runtime/interpreter/mterp/arm64/header.S
index f0bf8ca..7017dd1 100644
--- a/runtime/interpreter/mterp/arm64/header.S
+++ b/runtime/interpreter/mterp/arm64/header.S
@@ -87,7 +87,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
#define MTERP_PROFILE_BRANCHES 1
#define MTERP_LOGGING 0
diff --git a/runtime/interpreter/mterp/gen_mterp.py b/runtime/interpreter/mterp/gen_mterp.py
index 40d99df..64114d7 100755
--- a/runtime/interpreter/mterp/gen_mterp.py
+++ b/runtime/interpreter/mterp/gen_mterp.py
@@ -22,7 +22,7 @@
import sys, string, re, time
from string import Template
-interp_defs_file = "../../dex/dex_instruction_list.h" # need opcode list
+interp_defs_file = "../../../libdexfile/dex/dex_instruction_list.h" # need opcode list
kNumPackedOpcodes = 256
splitops = False
diff --git a/runtime/interpreter/mterp/mips/header.S b/runtime/interpreter/mterp/mips/header.S
index 014628f..bef9eeb 100644
--- a/runtime/interpreter/mterp/mips/header.S
+++ b/runtime/interpreter/mterp/mips/header.S
@@ -32,7 +32,7 @@
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
#if (__mips==32) && (__mips_isa_rev>=2)
#define MIPS32REVGE2 /* mips32r2 and greater */
diff --git a/runtime/interpreter/mterp/mips64/header.S b/runtime/interpreter/mterp/mips64/header.S
index 4947aff..7e1446c 100644
--- a/runtime/interpreter/mterp/mips64/header.S
+++ b/runtime/interpreter/mterp/mips64/header.S
@@ -104,7 +104,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
/*
* Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S
index 5c1a13b..7ea7982 100644
--- a/runtime/interpreter/mterp/out/mterp_arm.S
+++ b/runtime/interpreter/mterp/out/mterp_arm.S
@@ -92,7 +92,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
#define MTERP_PROFILE_BRANCHES 1
#define MTERP_LOGGING 0
diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S
index 72446ba..d5374d2 100644
--- a/runtime/interpreter/mterp/out/mterp_arm64.S
+++ b/runtime/interpreter/mterp/out/mterp_arm64.S
@@ -94,7 +94,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
#define MTERP_PROFILE_BRANCHES 1
#define MTERP_LOGGING 0
diff --git a/runtime/interpreter/mterp/out/mterp_mips.S b/runtime/interpreter/mterp/out/mterp_mips.S
index d5861b2..69568ea 100644
--- a/runtime/interpreter/mterp/out/mterp_mips.S
+++ b/runtime/interpreter/mterp/out/mterp_mips.S
@@ -39,7 +39,7 @@
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
#if (__mips==32) && (__mips_isa_rev>=2)
#define MIPS32REVGE2 /* mips32r2 and greater */
diff --git a/runtime/interpreter/mterp/out/mterp_mips64.S b/runtime/interpreter/mterp/out/mterp_mips64.S
index 5224df9..83a6613 100644
--- a/runtime/interpreter/mterp/out/mterp_mips64.S
+++ b/runtime/interpreter/mterp/out/mterp_mips64.S
@@ -111,7 +111,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
/*
* Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
diff --git a/runtime/interpreter/mterp/out/mterp_x86.S b/runtime/interpreter/mterp/out/mterp_x86.S
index f98fa5b..6f4752f 100644
--- a/runtime/interpreter/mterp/out/mterp_x86.S
+++ b/runtime/interpreter/mterp/out/mterp_x86.S
@@ -95,7 +95,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
/*
* Handle mac compiler specific
diff --git a/runtime/interpreter/mterp/out/mterp_x86_64.S b/runtime/interpreter/mterp/out/mterp_x86_64.S
index d82a2d2..fca2515 100644
--- a/runtime/interpreter/mterp/out/mterp_x86_64.S
+++ b/runtime/interpreter/mterp/out/mterp_x86_64.S
@@ -91,7 +91,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
/*
* Handle mac compiler specific
diff --git a/runtime/interpreter/mterp/x86/header.S b/runtime/interpreter/mterp/x86/header.S
index 2e3bbdf..9d826c2 100644
--- a/runtime/interpreter/mterp/x86/header.S
+++ b/runtime/interpreter/mterp/x86/header.S
@@ -88,7 +88,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
/*
* Handle mac compiler specific
diff --git a/runtime/interpreter/mterp/x86_64/header.S b/runtime/interpreter/mterp/x86_64/header.S
index eabaade..5563810 100644
--- a/runtime/interpreter/mterp/x86_64/header.S
+++ b/runtime/interpreter/mterp/x86_64/header.S
@@ -84,7 +84,7 @@
* to expand the macros into assembler assignment statements.
*/
#include "asm_support.h"
-#include "interpreter/mterp/cfi_asm_support.h"
+#include "interpreter/cfi_asm_support.h"
/*
* Handle mac compiler specific
diff --git a/test/137-cfi/cfi.cc b/test/137-cfi/cfi.cc
index b91d983..49db0c8 100644
--- a/test/137-cfi/cfi.cc
+++ b/test/137-cfi/cfi.cc
@@ -128,7 +128,6 @@
// "mini-debug-info" does not include parameters to save space.
std::vector<std::string> seq = {
"Java_Main_unwindInProcess", // This function.
- "Main.unwindInProcess", // The corresponding Java native method frame.
"java.util.Arrays.binarySearch0", // Framework method.
"Base.runBase", // Method in other dex file.
"Main.main" // The Java entry method.
@@ -225,11 +224,7 @@
// See comment in unwindInProcess for non-exact stack matching.
// "mini-debug-info" does not include parameters to save space.
std::vector<std::string> seq = {
- // "Java_Main_sleep", // The sleep function being executed in the
- // other runtime.
- // Note: For some reason, the name isn't
- // resolved, so don't look for it right now.
- "Main.sleep", // The corresponding Java native method frame.
+ "Java_Main_sleep", // The sleep function in the other process.
"java.util.Arrays.binarySearch0", // Framework method.
"Base.runBase", // Method in other dex file.
"Main.main" // The Java entry method.
diff --git a/test/knownfailures.json b/test/knownfailures.json
index b2f579d..3bc71b7 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -75,13 +75,6 @@
"--relocate"]
},
{
- "tests": "137-cfi",
- "variant": "interp-ac",
- "description": ["Temporarily disable some broken tests when forcing",
- "access checks in interpreter"],
- "bug": "http://b/22414682"
- },
- {
"tests" : "629-vdex-speed",
"variant": "interp-ac | no-dex2oat | interpreter | jit | relocate-npatchoat",
"description": "629 requires compilation."