1 %default { "isrange":"0", "routine":"NoRange" }
3 %verify "unknown method"
5 * Handle a direct method call.
7 * (We could defer the "is 'this' pointer null" test to the common
8 * method invocation code, and use a flag to indicate that static
9 * calls don't count. If we do this as part of copying the arguments
10 * out we could avoiding loading the first arg twice.)
12 * for: invoke-direct, invoke-direct/range
14 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
15 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
17 movzwl 2(rPC),%eax # eax<- BBBB
18 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
21 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
22 movzwl 4(rPC),rPC # rPC<- GFED or CCCC
23 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall
25 andl $$0xf,rPC # rPC<- D (or stays CCCC)
27 testl %eax,%eax # already resolved?
28 GET_VREG(%ecx,rPC) # ecx<- "this" ptr
29 je .L${opcode}_resolve # not resolved, do it now
32 testl %ecx,%ecx # null "this"?
34 #jne common_invokeMethod${routine} # no, continue on
35 jne common_invokeOld # no, continue on, eax<- method, ecx<- methodCallRange
36 jmp common_errNullObject
41 * TMP_SPILL <- "this" register
42 * Things a bit ugly on this path, but it's the less
43 * frequent one. We'll have to do some reloading.
49 movl offGlue_method(%ecx),%ecx # ecx<- glue->method
50 movzwl 2(rPC),%eax # reference (BBBB or CCCC)
51 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
52 movl $$METHOD_DIRECT,OUT_ARG2(%esp)
53 movl %eax,OUT_ARG1(%esp)
54 movl %ecx,OUT_ARG0(%esp)
55 call dvmResolveMethod # eax<- call(clazz, ref, flags)
58 jne .L${opcode}_finish
60 jmp common_exceptionThrown