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."