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     GET_GLUE(rINST_FULL)
     12     movzwl    2(rPC),%eax               # eax<- BBBB
     13     movl      offGlue_methodClassDex(rINST_FULL),%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      offGlue_method(rINST_FULL),%eax # eax<- method
     18     movzwl    4(rPC),rINST_FULL         # rINST_FULL<- GFED or CCCC
     19     .if       (!$isrange)
     20     andl      $$0xf,rINST_FULL          # rINST_FULL<- D (or stays CCCC)
     21     .endif
     22     GET_VREG(rINST_FULL,rINST_FULL)     # rINST_FULL<- "this" ptr
     23     testl     rINST_FULL,rINST_FULL     # null "this"?
     24     je        common_errNullObject      # yes, throw
     25     movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
     26     testl     %ecx,%ecx                 # already resolved?
     27     jne       .L${opcode}_continue      # yes - go on
     28     jmp       .L${opcode}_resolve
     29 %break
     30 
     31     /*
     32      * At this point:
     33      *  ecx = resolved base method [r0]
     34      *  eax = method->clazz [r9]
     35      */
     36 .L${opcode}_continue:
     37     movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
     38     movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
     39     cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
     40     jae     .L${opcode}_nsm           # method not present in superclass
     41     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
     42     movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
     43     jmp     common_invokeMethod${routine}
     44 
     45 
     46     /* At this point:
     47      * ecx = null (needs to be resolved base method)
     48      * eax = method->clazz
     49     */
     50 .L${opcode}_resolve:
     51     SPILL_TMP(%eax)                     # method->clazz
     52     movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
     53     movzwl  2(rPC),%ecx                 # ecx<- BBBB
     54     movl    $$METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
     55     movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
     56     SPILL(rPC)
     57     call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
     58     UNSPILL(rPC)
     59     testl   %eax,%eax                   # got null?
     60     movl    %eax,%ecx                   # ecx<- resolved base method
     61     UNSPILL_TMP(%eax)                   # restore method->clazz
     62     jne     .L${opcode}_continue        # good to go - continue
     63     jmp     common_exceptionThrown      # handle exception
     64 
     65     /*
     66      * Throw a NoSuchMethodError with the method name as the message.
     67      *  ecx = resolved base method
     68      */
     69 .L${opcode}_nsm:
     70     movl    offMethod_name(%ecx),%eax
     71     mov     %eax,OUT_ARG1(%esp)
     72     jmp     common_errNoSuchMethod
     73