blob: f40ddd531e7614bfdf825804d032c83a977992ed [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 */
LOAD_rSELF_methodClassDex(a3) # a3 <- pDvmDex
FETCH(a1, 1) # a1 <- BBBB
LOAD_base_offDvmDex_pResClasses(a3, a3) # a3 <- pDvmDex->pResClasses
LOAD_eas2(a0, a3, a1) # a0 <- resolved class
#if defined(WITH_JIT)
EAS2(rBIX, a3, a1) # rBIX <- &resolved_class
#endif
EXPORT_PC() # req'd for init, resolve, alloc
# already resolved?
beqz a0, .L${opcode}_resolve # no, resolve it now
.L${opcode}_resolved: # a0=class
lbu a1, offClassObject_status(a0) # a1 <- ClassStatus enum
# has class been initialized?
li t0, CLASS_INITIALIZED
move rOBJ, a0 # save a0
bne a1, t0, .L${opcode}_needinit # no, init class now
.L${opcode}_initialized: # a0=class
LOAD_base_offClassObject_accessFlags(a3, a0) # a3 <- clazz->accessFlags
li a1, ALLOC_DONT_TRACK # flags for alloc call
# a0=class
JAL(dvmAllocObject) # v0 <- new object
GET_OPA(a3) # a3 <- AA
#if defined(WITH_JIT)
/*
* The JIT needs the class to be fully resolved before it can
* include this instruction in a trace.
*/
lhu a1, offThread_subMode(rSELF)
beqz v0, common_exceptionThrown # yes, handle the exception
and a1, kSubModeJitTraceBuild # under construction?
bnez a1, .L${opcode}_jitCheck
#else
# failed?
beqz v0, common_exceptionThrown # yes, handle the exception
#endif
b .L${opcode}_continue
%break
.L${opcode}_continue:
FETCH_ADVANCE_INST(2) # advance rPC, load rINST
SET_VREG(v0, a3) # vAA <- v0
GET_INST_OPCODE(t0) # extract opcode from rINST
GOTO_OPCODE(t0) # jump to next instruction
#if defined(WITH_JIT)
/*
* Check to see if we need to stop the trace building early.
* v0: new object
* a3: vAA
*/
.L${opcode}_jitCheck:
lw a1, 0(rBIX) # reload resolved class
# okay?
bnez a1, .L${opcode}_continue # yes, finish
move rOBJ, v0 # preserve new object
move rBIX, a3 # preserve vAA
move a0, rSELF
move a1, rPC
JAL(dvmJitEndTraceSelect) # (self, pc)
FETCH_ADVANCE_INST(2) # advance rPC, load rINST
SET_VREG(rOBJ, rBIX) # vAA <- new object
GET_INST_OPCODE(t0) # extract opcode from rINST
GOTO_OPCODE(t0) # jump to next instruction
#endif
/*
* Class initialization required.
*
* a0 holds class object
*/
.L${opcode}_needinit:
JAL(dvmInitClass) # initialize class
move a0, rOBJ # restore a0
# check boolean result
bnez v0, .L${opcode}_initialized # success, continue
b common_exceptionThrown # failed, deal with init exception
/*
* Resolution required. This is the least-likely path.
*
* a1 holds BBBB
*/
.L${opcode}_resolve:
LOAD_rSELF_method(a3) # a3 <- self->method
li a2, 0 # a2 <- false
LOAD_base_offMethod_clazz(a0, a3) # a0 <- method->clazz
JAL(dvmResolveClass) # v0 <- resolved ClassObject ptr
move a0, v0
# got null?
bnez v0, .L${opcode}_resolved # no, continue
b common_exceptionThrown # yes, handle exception