Throw an exception in JIT'ed code if dvmFindInterfaceMethodInCache returns NULL
Bug: 2642019
Change-Id: Iec2be8f61388d99b1500bb144e56b86febe76c0b
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 0a59ea4..e9f00dd 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -2672,69 +2672,76 @@
calleeMethod);
break;
}
- /*
+ /*
* calleeMethod = dvmFindInterfaceMethodInCache(this->clazz,
* BBBB, method, method->clazz->pDvmDex)
*
- * Given "invoke-interface {v0}", the following is the generated code:
+ * The following is an example of generated code for
+ * "invoke-interface v0"
*
- * 0x426a9abe : ldr r0, [r5, #0] --+
- * 0x426a9ac0 : mov r7, r5 |
- * 0x426a9ac2 : sub r7, #24 |
- * 0x426a9ac4 : cmp r0, #0 | genProcessArgsNoRange
- * 0x426a9ac6 : beq 0x426a9afe |
- * 0x426a9ac8 : stmia r7, <r0> --+
- * 0x426a9aca : ldr r4, [pc, #104] --> r4 <- dalvikPC of this invoke
- * 0x426a9acc : add r1, pc, #52 --> r1 <- &retChainingCell
- * 0x426a9ace : add r2, pc, #60 --> r2 <- &predictedChainingCell
- * 0x426a9ad0 : blx_1 0x426a918c --+ TEMPLATE_INVOKE_METHOD_
- * 0x426a9ad2 : blx_2 see above --+ PREDICTED_CHAIN
- * 0x426a9ad4 : b 0x426a9b0c --> off to the predicted chain
- * 0x426a9ad6 : b 0x426a9afe --> punt to the interpreter
- * 0x426a9ad8 : mov r8, r1 --+
- * 0x426a9ada : mov r9, r2 |
- * 0x426a9adc : mov r10, r3 |
- * 0x426a9ade : mov r0, r3 |
- * 0x426a9ae0 : mov r1, #74 | dvmFindInterfaceMethodInCache
- * 0x426a9ae2 : ldr r2, [pc, #76] |
- * 0x426a9ae4 : ldr r3, [pc, #68] |
- * 0x426a9ae6 : ldr r7, [pc, #64] |
- * 0x426a9ae8 : blx r7 --+
- * 0x426a9aea : mov r1, r8 --> r1 <- rechain count
- * 0x426a9aec : cmp r1, #0 --> compare against 0
- * 0x426a9aee : bgt 0x426a9af8 --> >=0? don't rechain
- * 0x426a9af0 : ldr r7, [r6, #96] --+
- * 0x426a9af2 : mov r2, r9 | dvmJitToPatchPredictedChain
- * 0x426a9af4 : mov r3, r10 |
- * 0x426a9af6 : blx r7 --+
- * 0x426a9af8 : add r1, pc, #8 --> r1 <- &retChainingCell
- * 0x426a9afa : blx_1 0x426a9098 --+ TEMPLATE_INVOKE_METHOD_NO_OPT
- * 0x426a9afc : blx_2 see above --+
- * -------- reconstruct dalvik PC : 0x428b786c @ +0x001e
- * 0x426a9afe (0042): ldr r0, [pc, #52]
+ * -------- dalvik offset: 0x0008 @ invoke-interface v0
+ * 0x47357e36 : ldr r0, [r5, #0] --+
+ * 0x47357e38 : sub r7,r5,#24 |
+ * 0x47357e3c : cmp r0, #0 | genProcessArgsNoRange
+ * 0x47357e3e : beq 0x47357e82 |
+ * 0x47357e40 : stmia r7, <r0> --+
+ * 0x47357e42 : ldr r4, [pc, #120] --> r4 <- dalvikPC of this invoke
+ * 0x47357e44 : add r1, pc, #64 --> r1 <- &retChainingCell
+ * 0x47357e46 : add r2, pc, #72 --> r2 <- &predictedChainingCell
+ * 0x47357e48 : blx_1 0x47348190 --+ TEMPLATE_INVOKE_METHOD_
+ * 0x47357e4a : blx_2 see above --+ PREDICTED_CHAIN
+ * 0x47357e4c : b 0x47357e90 --> off to the predicted chain
+ * 0x47357e4e : b 0x47357e82 --> punt to the interpreter
+ * 0x47357e50 : mov r8, r1 --+
+ * 0x47357e52 : mov r9, r2 |
+ * 0x47357e54 : ldr r2, [pc, #96] |
+ * 0x47357e56 : mov r10, r3 |
+ * 0x47357e58 : movs r0, r3 | dvmFindInterfaceMethodInCache
+ * 0x47357e5a : ldr r3, [pc, #88] |
+ * 0x47357e5c : ldr r7, [pc, #80] |
+ * 0x47357e5e : mov r1, #1452 |
+ * 0x47357e62 : blx r7 --+
+ * 0x47357e64 : cmp r0, #0 --> calleeMethod == NULL?
+ * 0x47357e66 : bne 0x47357e6e --> branch over the throw if !r0
+ * 0x47357e68 : ldr r0, [pc, #80] --> load Dalvik PC of the invoke
+ * 0x47357e6a : blx_1 0x47348494 --+ TEMPLATE_THROW_EXCEPTION_
+ * 0x47357e6c : blx_2 see above --+ COMMON
+ * 0x47357e6e : mov r1, r8 --> r1 <- &retChainingCell
+ * 0x47357e70 : cmp r1, #0 --> compare against 0
+ * 0x47357e72 : bgt 0x47357e7c --> >=0? don't rechain
+ * 0x47357e74 : ldr r7, [r6, #108] --+
+ * 0x47357e76 : mov r2, r9 | dvmJitToPatchPredictedChain
+ * 0x47357e78 : mov r3, r10 |
+ * 0x47357e7a : blx r7 --+
+ * 0x47357e7c : add r1, pc, #8 --> r1 <- &retChainingCell
+ * 0x47357e7e : blx_1 0x4734809c --+ TEMPLATE_INVOKE_METHOD_NO_OPT
+ * 0x47357e80 : blx_2 see above --+
+ * -------- reconstruct dalvik PC : 0x425719dc @ +0x0008
+ * 0x47357e82 : ldr r0, [pc, #56]
* Exception_Handling:
- * 0x426a9b00 (0044): ldr r1, [r6, #84]
- * 0x426a9b02 (0046): blx r1
- * 0x426a9b04 (0048): .align4
- * -------- chaining cell (hot): 0x0021
- * 0x426a9b04 (0048): ldr r0, [r6, #92]
- * 0x426a9b06 (004a): blx r0
- * 0x426a9b08 (004c): data 0x7872(30834)
- * 0x426a9b0a (004e): data 0x428b(17035)
- * 0x426a9b0c (0050): .align4
+ * 0x47357e84 : ldr r1, [r6, #92]
+ * 0x47357e86 : blx r1
+ * 0x47357e88 : .align4
+ * -------- chaining cell (hot): 0x000b
+ * 0x47357e88 : ldr r0, [r6, #104]
+ * 0x47357e8a : blx r0
+ * 0x47357e8c : data 0x19e2(6626)
+ * 0x47357e8e : data 0x4257(16983)
+ * 0x47357e90 : .align4
* -------- chaining cell (predicted)
- * 0x426a9b0c (0050): data 0x0000(0) --> will be patched into bx
- * 0x426a9b0e (0052): data 0x0000(0)
- * 0x426a9b10 (0054): data 0x0000(0) --> class
- * 0x426a9b12 (0056): data 0x0000(0)
- * 0x426a9b14 (0058): data 0x0000(0) --> method
- * 0x426a9b16 (005a): data 0x0000(0)
- * 0x426a9b18 (005c): data 0x0000(0) --> reset count
- * 0x426a9b1a (005e): data 0x0000(0)
- * 0x426a9b28 (006c): .word (0xad0392a5)
- * 0x426a9b2c (0070): .word (0x6e750)
- * 0x426a9b30 (0074): .word (0x4109a618)
- * 0x426a9b34 (0078): .word (0x428b786c)
+ * 0x47357e90 : data 0xe7fe(59390) --> will be patched into bx
+ * 0x47357e92 : data 0x0000(0)
+ * 0x47357e94 : data 0x0000(0) --> class
+ * 0x47357e96 : data 0x0000(0)
+ * 0x47357e98 : data 0x0000(0) --> method
+ * 0x47357e9a : data 0x0000(0)
+ * 0x47357e9c : data 0x0000(0) --> rechain count
+ * 0x47357e9e : data 0x0000(0)
+ * -------- end of chaining cells (0x006c)
+ * 0x47357eb0 : .word (0xad03e369)
+ * 0x47357eb4 : .word (0x28a90)
+ * 0x47357eb8 : .word (0x41a63394)
+ * 0x47357ebc : .word (0x425719dc)
*/
case OP_INVOKE_INTERFACE:
case OP_INVOKE_INTERFACE_RANGE: {
@@ -2816,9 +2823,24 @@
LOAD_FUNC_ADDR(cUnit, r7,
(intptr_t) dvmFindInterfaceMethodInCache);
opReg(cUnit, kOpBlx, r7);
-
/* r0 = calleeMethod (returned from dvmFindInterfaceMethodInCache */
+ dvmCompilerClobberCallRegs(cUnit);
+ /* generate a branch over if the interface method is resolved */
+ opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
+ ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+ /*
+ * calleeMethod == NULL -> throw
+ */
+ loadConstant(cUnit, r0,
+ (int) (cUnit->method->insns + mir->offset));
+ genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
+ /* noreturn */
+
+ ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
+ target->defMask = ENCODE_ALL;
+ branchOver->generic.target = (LIR *) target;
+
genRegCopy(cUnit, r1, r8);
/* Check if rechain limit is reached */