summaryrefslogtreecommitdiffstats
path: root/vm/mterp/mips/OP_NEW_INSTANCE.S
blob: f40ddd531e7614bfdf825804d032c83a977992ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
%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