Home | History | Annotate | Download | only in x86
      1 %default { "isrange":"0", "routine":"NoRange" }
      2 %verify "executed"
      3 %verify "unknown method"
      4     /*
      5      * Handle a "super" method call.
      6      *
      7      * for: invoke-super, invoke-super/range
      8      */
      9     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
     10     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
     11     movl      rSELF,rINST
     12     movzwl    2(rPC),%eax               # eax<- BBBB
     13     movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
     14     EXPORT_PC
     15     movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
     16     movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
     17     movl      offThread_method(rINST),%eax # eax<- method
     18     movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
     19     .if       (!$isrange)
     20     andl      $$0xf,rINST               # rINST<- D (or stays CCCC)
     21     .endif
     22     GET_VREG_R  rINST rINST             # rINST<- "this" ptr
     23     testl     rINST,rINST               # null "this"?
     24     je        common_errNullObject      # yes, throw
     25     movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
     26     testl     %ecx,%ecx                 # already resolved?
     27     je       .L${opcode}_resolve
     28     /*
     29      * At this point:
     30      *  ecx = resolved base method [r0]
     31      *  eax = method->clazz [r9]
     32      */
     33 .L${opcode}_continue:
     34     movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
     35     movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
     36     cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
     37     jae     .L${opcode}_nsm           # method not present in superclass
     38     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
     39     movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
     40     jmp     common_invokeMethod${routine}
     41 
     42 
     43     /* At this point:
     44      * ecx = null (needs to be resolved base method)
     45      * eax = method->clazz
     46     */
     47 .L${opcode}_resolve:
     48     SPILL_TMP1(%eax)                    # method->clazz
     49     movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
     50     movzwl  2(rPC),%ecx                 # ecx<- BBBB
     51     movl    $$METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
     52     movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
     53     call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
     54     testl   %eax,%eax                   # got null?
     55     movl    %eax,%ecx                   # ecx<- resolved base method
     56     UNSPILL_TMP1(%eax)                  # restore method->clazz
     57     jne     .L${opcode}_continue        # good to go - continue
     58     jmp     common_exceptionThrown      # handle exception
     59 
     60     /*
     61      * Throw a NoSuchMethodError with the method name as the message.
     62      *  ecx = resolved base method
     63      */
     64 .L${opcode}_nsm:
     65     movl    offMethod_name(%ecx),%eax
     66     jmp     common_errNoSuchMethod
     67