Make JIT inliner work under single-stepping mode.

Bug: 2936661

(cherry-picked from dalvik-dev)

Change-Id: I35a012bd4dba2a2f9541b96a2e787687bbc7cd19
diff --git a/vm/compiler/Compiler.h b/vm/compiler/Compiler.h
index 9aeb661..739d517 100644
--- a/vm/compiler/Compiler.h
+++ b/vm/compiler/Compiler.h
@@ -73,6 +73,10 @@
         dvmUnlockMutex(&gDvmJit.codeCacheProtectionLock);                      \
     }
 
+#define SINGLE_STEP_OP(opcode)                                                 \
+    (gDvmJit.includeSelectedOp !=                                              \
+     ((gDvmJit.opList[opcode >> 3] & (1 << (opcode & 0x7))) != 0))
+
 typedef enum JitInstructionSetType {
     DALVIK_JIT_NONE = 0,
     DALVIK_JIT_ARM,
diff --git a/vm/compiler/Frontend.c b/vm/compiler/Frontend.c
index 8e5a5e2..525ec72 100644
--- a/vm/compiler/Frontend.c
+++ b/vm/compiler/Frontend.c
@@ -206,18 +206,19 @@
                                int offset)
 {
     int flags = dexGetInstrFlags(gDvm.instrFlags, dalvikInsn->opCode);
+    int dalvikOpCode = dalvikInsn->opCode;
 
     if ((flags & kInstrInvoke) &&
-        (dalvikInsn->opCode != OP_INVOKE_DIRECT_EMPTY)) {
+        (dalvikOpCode != OP_INVOKE_DIRECT_EMPTY)) {
         attributes &= ~METHOD_IS_LEAF;
     }
 
     if (!(flags & kInstrCanReturn)) {
-        if (!(dvmCompilerDataFlowAttributes[dalvikInsn->opCode] &
+        if (!(dvmCompilerDataFlowAttributes[dalvikOpCode] &
               DF_IS_GETTER)) {
             attributes &= ~METHOD_IS_GETTER;
         }
-        if (!(dvmCompilerDataFlowAttributes[dalvikInsn->opCode] &
+        if (!(dvmCompilerDataFlowAttributes[dalvikOpCode] &
               DF_IS_SETTER)) {
             attributes &= ~METHOD_IS_SETTER;
         }
@@ -229,7 +230,7 @@
      * otherwise.
      */
     if (flags & kInstrCanReturn) {
-        if (dalvikInsn->opCode == OP_RETURN_VOID) {
+        if (dalvikOpCode == OP_RETURN_VOID) {
             attributes &= ~METHOD_IS_GETTER;
         }
         else {
@@ -241,10 +242,19 @@
         attributes &= ~METHOD_IS_THROW_FREE;
     }
 
-    if (offset == 0 && dalvikInsn->opCode == OP_RETURN_VOID) {
+    if (offset == 0 && dalvikOpCode == OP_RETURN_VOID) {
         attributes |= METHOD_IS_EMPTY;
     }
 
+    /*
+     * Check if this opcode is selected for single stepping.
+     * If so, don't inline the callee as there is no stack frame for the
+     * interpreter to single-step through the instruction.
+     */
+    if (SINGLE_STEP_OP(dalvikOpCode)) {
+        attributes &= ~(METHOD_IS_GETTER | METHOD_IS_SETTER);
+    }
+
     return attributes;
 }
 
@@ -956,7 +966,7 @@
  * with the callee is properly initialized. If not, we punt on this inline
  * target.
  *
- * TODO: volatile instructions will handled later.
+ * TODO: volatile instructions will be handled later.
  */
 bool dvmCompilerCanIncludeThisInstruction(const Method *method,
                                           const DecodedInstruction *insn)
diff --git a/vm/compiler/InlineTransformation.c b/vm/compiler/InlineTransformation.c
index 790cc5d..9559f5d 100644
--- a/vm/compiler/InlineTransformation.c
+++ b/vm/compiler/InlineTransformation.c
@@ -301,6 +301,13 @@
         if (opCode == OP_INVOKE_DIRECT_EMPTY)
             continue;
 
+        /*
+         * If the invoke itself is selected for single stepping, don't bother
+         * to inline it.
+         */
+        if (SINGLE_STEP_OP(opCode))
+            continue;
+
         const Method *calleeMethod;
 
         switch (opCode) {
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 1ff9409..7716eb2 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -4111,11 +4111,7 @@
              * Debugging: screen the opcode first to see if it is in the
              * do[-not]-compile list
              */
-            bool singleStepMe =
-                gDvmJit.includeSelectedOp !=
-                ((gDvmJit.opList[dalvikOpCode >> 3] &
-                  (1 << (dalvikOpCode & 0x7))) !=
-                 0);
+            bool singleStepMe = SINGLE_STEP_OP(dalvikOpCode);
 #if defined(WITH_SELF_VERIFICATION)
           if (singleStepMe == false) {
               singleStepMe = selfVerificationPuntOps(mir);