1 %default { "cccc":"2" } 2 %verify "executed" 3 %verify "finalizable class" 4 /* 5 * Invoke Object.<init> on an object. In practice we know that 6 * Object's nullary constructor doesn't do anything, so we just 7 * skip it unless a debugger is active. 8 */ 9 movzwl 4(rPC),%eax # eax<- CCCC, offset = 2 * cccc 10 GET_VREG_R %ecx, %eax # ecx<- "this" ptr 11 testl %ecx,%ecx # null this? 12 je common_errNullObject # yes, fail 13 movl offObject_clazz(%ecx), %eax # eax<- obj->clazz 14 SPILL_TMP1(rIBASE) # save %edx 15 movl offClassObject_accessFlags(%eax), %edx # edx<- clazz->accessFlags 16 andl $$CLASS_ISFINALIZABLE, %edx # is this class finalizable? 17 jnz .L${opcode}_setFinal # yes, go 18 .L${opcode}_finish: 19 movl rSELF, %ecx 20 movl offThread_subMode(%ecx), %eax 21 andl $$kSubModeDebuggerActive, %eax # debugger active? 22 jnz .L${opcode}_debugger # Yes - skip optimization 23 UNSPILL_TMP1(rIBASE) 24 FETCH_INST_OPCODE 3 %ecx # 3 = cccc + 1 25 ADVANCE_PC 3 26 GOTO_NEXT_R %ecx 27 %break 28 29 .L${opcode}_setFinal: 30 EXPORT_PC # can throw 31 movl %ecx, OUT_ARG0(%esp) # arg1<- obj 32 call dvmSetFinalizable # call dvmSetFinalizable(obj) 33 movl rSELF, %ecx 34 movl offThread_exception(%ecx), %eax # eax<- self->exception 35 cmpl $$0, %eax # exception pending? 36 jne common_exceptionThrown # yes, handle it 37 jmp .L${opcode}_finish 38 39 /* 40 * A debugger is attached, so we need to go ahead and do 41 * this. For simplicity, we'll just jump directly to the 42 * corresponding handler. Note that we can't use 43 * rIBASE here because it may be in single-step mode. 44 * Load the primary table base directly. 45 */ 46 .L${opcode}_debugger: 47 movl offThread_mainHandlerTable(%ecx), %ecx # load main handler table 48 movl $$OP_INVOKE_DIRECT_RANGE, %eax 49 /* 50 * We can't use GOTO_NEXT here since we want to jump directly to 51 * handler without touching rIBASE. 52 */ 53 jmp *(%ecx,%eax,4) 54