blob: 5638e10efbee13108ea7a512fd248acd055148fd [file] [log] [blame]
%verify "executed"
%verify "class not resolved"
%verify "class cannot be resolved"
%verify "class not initialized"
%verify "class fails to initialize"
%verify "class already resolved/initialized"
%verify "class is abstract or interface"
%verify "allocation fails"
/*
* Create a new instance of a class.
*/
/* new-instance vAA, class@BBBB */
movl rSELF,%ecx
movzwl 2(rPC),%eax # eax<- BBBB
movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
SPILL(rIBASE)
SPILL_TMP2(%ebx)
movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
EXPORT_PC
#if defined(WITH_JIT)
lea (%ecx,%eax,4),%ebx # ebx <- &resolved class
#endif
movl (%ecx,%eax,4),%ecx # ecx<- resolved class
testl %ecx,%ecx # resolved?
je .L${opcode}_resolve # no, go do it
.L${opcode}_resolved: # on entry, ecx<- class
cmpb $$CLASS_INITIALIZED,offClassObject_status(%ecx)
jne .L${opcode}_needinit
.L${opcode}_initialized: # on entry, ecx<- class
movl $$ALLOC_DONT_TRACK,OUT_ARG1(%esp)
movl %ecx,OUT_ARG0(%esp)
call dvmAllocObject # eax<- new object
testl %eax,%eax # success?
je common_exceptionThrown # no, bail out
#if defined(WITH_JIT)
/*
* The JIT needs the class to be fully resolved before it can
* include this instruction in a trace.
*/
movl rSELF, %ecx
movl offThread_subMode(%ecx), %ecx
andl $$kSubModeJitTraceBuild, %ecx # under construction?
jne .L${opcode}_jitCheck
#endif
.L${opcode}_end:
UNSPILL_TMP2(%ebx)
SET_VREG %eax rINST
UNSPILL(rIBASE)
FETCH_INST_OPCODE 2 %ecx
ADVANCE_PC 2
GOTO_NEXT_R %ecx
#if defined(WITH_JIT)
/*
* Check to see if we need to stop the trace building early.
* eax: new object
*/
.L${opcode}_jitCheck:
cmp $$0, (%ebx) # okay?
jne .L${opcode}_end # yes, finish
SPILL_TMP1(%eax) # preserve new object
movl rSELF, %ecx
movl %ecx, OUT_ARG0(%esp)
movl rPC, OUT_ARG1(%esp)
call dvmJitEndTraceSelect # (self, pc)
UNSPILL_TMP1(%eax)
UNSPILL_TMP2(%ebx)
SET_VREG %eax rINST # vAA <- new object
UNSPILL(rIBASE)
FETCH_INST_OPCODE 2 %ecx
ADVANCE_PC 2
GOTO_NEXT_R %ecx
#endif
/*
* Class initialization required.
*
* ecx holds class object
*/
.L${opcode}_needinit:
SPILL_TMP1(%ecx) # save object
movl %ecx,OUT_ARG0(%esp)
call dvmInitClass # initialize class
UNSPILL_TMP1(%ecx) # restore object
testl %eax,%eax # success?
jne .L${opcode}_initialized # success, continue
jmp common_exceptionThrown # go deal with init exception
/*
* Resolution required. This is the least-likely path.
*
*/
.L${opcode}_resolve:
movl rSELF,%ecx
movzwl 2(rPC),%eax
movl offThread_method(%ecx),%ecx # ecx<- self->method
movl %eax,OUT_ARG1(%esp)
movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
movl $$0,OUT_ARG2(%esp)
movl %ecx,OUT_ARG0(%esp)
call dvmResolveClass # call(clazz,off,flags)
movl %eax,%ecx # ecx<- resolved ClassObject ptr
testl %ecx,%ecx # success?
jne .L${opcode}_resolved # good to go
jmp common_exceptionThrown # no, handle exception