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);