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  %edx rINST             # %edx<- "this" ptr
     23     testl     %edx,%edx                # null "this"?
     24     SPILL_TMP1(%edx)
     25     je        common_errNullObject      # yes, throw
     26     movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
     27     testl     %ecx,%ecx                 # already resolved?
     28     je       .L${opcode}_resolve
     29     /*
     30      * At this point:
     31      *  ecx = resolved base method [r0]
     32      *  eax = method->clazz [r9]
     33      */
     34 .L${opcode}_continue:
     35     movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
     36     movzwl  offMethod_methodIndex(%ecx),%edx  # edx<- baseMthod->methodIndex
     37     cmpl    offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount)
     38     jae     .L${opcode}_nsm           # method not present in superclass
     39     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
     40     movl    (%eax,%edx,4),%eax        # eax<- vtable[methodIndex]
     41     UNSPILL_TMP1(%edx)
     42     movl    %edx, %ecx
     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_TMP2(%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     call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
     57     testl   %eax,%eax                   # got null?
     58     movl    %eax,%ecx                   # ecx<- resolved base method
     59     UNSPILL_TMP2(%eax)                  # restore method->clazz
     60     jne     .L${opcode}_continue        # good to go - continue
     61     jmp     common_exceptionThrown      # handle exception
     62 
     63     /*
     64      * Throw a NoSuchMethodError with the method name as the message.
     65      *  ecx = resolved base method
     66      */
     67 .L${opcode}_nsm:
     68     movl    offMethod_name(%ecx),%eax
     69     jmp     common_errNoSuchMethod
     70