17a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng/*
27a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng * Copyright (C) 2010 The Android Open Source Project
37a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng *
47a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng * Licensed under the Apache License, Version 2.0 (the "License");
57a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng * you may not use this file except in compliance with the License.
67a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng * You may obtain a copy of the License at
77a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng *
87a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng *      http://www.apache.org/licenses/LICENSE-2.0
97a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng *
107a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng * Unless required by applicable law or agreed to in writing, software
117a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng * distributed under the License is distributed on an "AS IS" BASIS,
127a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng * See the License for the specific language governing permissions and
147a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng * limitations under the License.
157a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng */
167a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
177a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#include "Dalvik.h"
187a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#include "Dataflow.h"
19df4daaf8f41e3dcaa8221f54273338160dd43138Dan Bornstein#include "libdex/DexOpcodes.h"
207a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
217a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng/* Convert the reg id from the callee to the original id passed by the caller */
227a2697d327936e20ef5484f7819e2e4bf91c891fBen Chengstatic inline u4 convertRegId(const DecodedInstruction *invoke,
237a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                              const Method *calleeMethod,
247a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                              int calleeRegId, bool isRange)
257a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng{
267a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /* The order in the original arg passing list */
277a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    int rank = calleeRegId -
287a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng               (calleeMethod->registersSize - calleeMethod->insSize);
297a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    assert(rank >= 0);
307a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (!isRange) {
317a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        return invoke->arg[rank];
327a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    } else {
337a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        return invoke->vC + rank;
347a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
357a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng}
367a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
37cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Chengstatic bool inlineGetter(CompilationUnit *cUnit,
387a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         const Method *calleeMethod,
397a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         MIR *invokeMIR,
407a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         BasicBlock *invokeBB,
417a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         bool isPredicted,
427a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         bool isRange)
437a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng{
447a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    BasicBlock *moveResultBB = invokeBB->fallThrough;
457a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    MIR *moveResultMIR = moveResultBB->firstMIRInsn;
46fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    MIR *newGetterMIR = (MIR *)dvmCompilerNew(sizeof(MIR), true);
477a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    DecodedInstruction getterInsn;
487a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
49a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng    /*
50a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng     * Not all getter instructions have vC but vC will be read by
51a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng     * dvmCompilerGetDalvikDisassembly unconditionally.
52a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng     * Initialize it here to get Valgrind happy.
53a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng     */
54a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng    getterInsn.vC = 0;
55a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng
56543223954993a19fa96670692bc7aa55d851966bDan Bornstein    dexDecodeInstruction(calleeMethod->insns, &getterInsn);
577a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
587a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (!dvmCompilerCanIncludeThisInstruction(calleeMethod, &getterInsn))
59cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng        return false;
607a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
617a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /*
627a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     * Some getters (especially invoked through interface) are not followed
637a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     * by a move result.
647a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     */
657a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if ((moveResultMIR == NULL) ||
669a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein        (moveResultMIR->dalvikInsn.opcode != OP_MOVE_RESULT &&
679a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein         moveResultMIR->dalvikInsn.opcode != OP_MOVE_RESULT_OBJECT &&
689a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein         moveResultMIR->dalvikInsn.opcode != OP_MOVE_RESULT_WIDE)) {
69cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng        return false;
707a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
717a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
729a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    int dfFlags = dvmCompilerDataFlowAttributes[getterInsn.opcode];
737a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
747a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /* Expecting vA to be the destination register */
7552d4cd28a5d6d946934704e11e1d41450c10aa05Ben Cheng    if (dfFlags & (DF_UA | DF_UA_WIDE)) {
76c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block        ALOGE("opcode %d has DF_UA set (not expected)", getterInsn.opcode);
777a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        dvmAbort();
787a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
797a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
807a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (dfFlags & DF_UB) {
817a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        getterInsn.vB = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
827a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     getterInsn.vB, isRange);
837a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
847a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
857a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (dfFlags & DF_UC) {
867a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        getterInsn.vC = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
877a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     getterInsn.vC, isRange);
887a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
897a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
907a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    getterInsn.vA = moveResultMIR->dalvikInsn.vA;
917a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
927a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /* Now setup the Dalvik instruction with converted src/dst registers */
937a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newGetterMIR->dalvikInsn = getterInsn;
947a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
95e485276c6ba778cafa373b3b5c867f84e91b0bfdDan Bornstein    newGetterMIR->width = dexGetWidthFromOpcode(getterInsn.opcode);
967a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
977a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newGetterMIR->OptimizationFlags |= MIR_CALLEE;
987a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
997a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /*
1007a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     * If the getter instruction is about to raise any exception, punt to the
1017a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     * interpreter and re-execute the invoke.
1027a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     */
1037a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newGetterMIR->offset = invokeMIR->offset;
1047a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1057a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newGetterMIR->meta.calleeMethod = calleeMethod;
1067a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1077a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    dvmCompilerInsertMIRAfter(invokeBB, invokeMIR, newGetterMIR);
1087a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1097a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (isPredicted) {
110fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro        MIR *invokeMIRSlow = (MIR *)dvmCompilerNew(sizeof(MIR), true);
1117a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        *invokeMIRSlow = *invokeMIR;
1125d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro        invokeMIR->dalvikInsn.opcode = (Opcode)kMirOpCheckInlinePrediction;
1137a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1147a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        /* Use vC to denote the first argument (ie this) */
1157a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        if (!isRange) {
1167a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            invokeMIR->dalvikInsn.vC = invokeMIRSlow->dalvikInsn.arg[0];
1177a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        }
1187a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1197a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        moveResultMIR->OptimizationFlags |= MIR_INLINED_PRED;
1207a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1217a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        dvmCompilerInsertMIRAfter(invokeBB, newGetterMIR, invokeMIRSlow);
1227a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        invokeMIRSlow->OptimizationFlags |= MIR_INLINED_PRED;
1237a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#if defined(WITH_JIT_TUNING)
1247a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        gDvmJit.invokePolyGetterInlined++;
1257a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#endif
1267a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    } else {
1277a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        invokeMIR->OptimizationFlags |= MIR_INLINED;
1287a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        moveResultMIR->OptimizationFlags |= MIR_INLINED;
1297a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#if defined(WITH_JIT_TUNING)
1307a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        gDvmJit.invokeMonoGetterInlined++;
1317a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#endif
1327a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
1337a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
134cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng    return true;
1357a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng}
1367a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
137cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Chengstatic bool inlineSetter(CompilationUnit *cUnit,
1387a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         const Method *calleeMethod,
1397a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         MIR *invokeMIR,
1407a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         BasicBlock *invokeBB,
1417a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         bool isPredicted,
1427a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                         bool isRange)
1437a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng{
144fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    MIR *newSetterMIR = (MIR *)dvmCompilerNew(sizeof(MIR), true);
1457a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    DecodedInstruction setterInsn;
1467a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
147a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng    /*
148a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng     * Not all setter instructions have vC but vC will be read by
149a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng     * dvmCompilerGetDalvikDisassembly unconditionally.
150a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng     * Initialize it here to get Valgrind happy.
151a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng     */
152a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng    setterInsn.vC = 0;
153a18e6d135a869f9c62f9ec8bac8b9e78d92c697fBen Cheng
154543223954993a19fa96670692bc7aa55d851966bDan Bornstein    dexDecodeInstruction(calleeMethod->insns, &setterInsn);
1557a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1567a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (!dvmCompilerCanIncludeThisInstruction(calleeMethod, &setterInsn))
157cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng        return false;
1587a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1599a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    int dfFlags = dvmCompilerDataFlowAttributes[setterInsn.opcode];
1607a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
16152d4cd28a5d6d946934704e11e1d41450c10aa05Ben Cheng    if (dfFlags & (DF_UA | DF_UA_WIDE)) {
1627a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        setterInsn.vA = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
1637a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     setterInsn.vA, isRange);
1647a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1657a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
1667a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1677a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (dfFlags & DF_UB) {
1687a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        setterInsn.vB = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
1697a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     setterInsn.vB, isRange);
1707a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1717a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
1727a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1737a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (dfFlags & DF_UC) {
1747a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        setterInsn.vC = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
1757a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     setterInsn.vC, isRange);
1767a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
1777a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1787a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /* Now setup the Dalvik instruction with converted src/dst registers */
1797a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newSetterMIR->dalvikInsn = setterInsn;
1807a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
181e485276c6ba778cafa373b3b5c867f84e91b0bfdDan Bornstein    newSetterMIR->width = dexGetWidthFromOpcode(setterInsn.opcode);
1827a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1837a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newSetterMIR->OptimizationFlags |= MIR_CALLEE;
1847a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1857a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /*
1867a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     * If the setter instruction is about to raise any exception, punt to the
1877a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     * interpreter and re-execute the invoke.
1887a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     */
1897a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newSetterMIR->offset = invokeMIR->offset;
1907a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1917a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newSetterMIR->meta.calleeMethod = calleeMethod;
1927a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1937a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    dvmCompilerInsertMIRAfter(invokeBB, invokeMIR, newSetterMIR);
1947a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
1957a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (isPredicted) {
196fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro        MIR *invokeMIRSlow = (MIR *)dvmCompilerNew(sizeof(MIR), true);
1977a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        *invokeMIRSlow = *invokeMIR;
1985d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro        invokeMIR->dalvikInsn.opcode = (Opcode)kMirOpCheckInlinePrediction;
1997a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
2007a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        /* Use vC to denote the first argument (ie this) */
2017a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        if (!isRange) {
2027a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            invokeMIR->dalvikInsn.vC = invokeMIRSlow->dalvikInsn.arg[0];
2037a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        }
2047a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
2057a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        dvmCompilerInsertMIRAfter(invokeBB, newSetterMIR, invokeMIRSlow);
2067a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        invokeMIRSlow->OptimizationFlags |= MIR_INLINED_PRED;
2077a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#if defined(WITH_JIT_TUNING)
2087a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        gDvmJit.invokePolySetterInlined++;
2097a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#endif
2107a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    } else {
21133c1cf94f41ee042709e3c7b83f189970a637da2Ben Cheng        /*
21233c1cf94f41ee042709e3c7b83f189970a637da2Ben Cheng         * The invoke becomes no-op so it needs an explicit branch to jump to
21333c1cf94f41ee042709e3c7b83f189970a637da2Ben Cheng         * the chaining cell.
21433c1cf94f41ee042709e3c7b83f189970a637da2Ben Cheng         */
21533c1cf94f41ee042709e3c7b83f189970a637da2Ben Cheng        invokeBB->needFallThroughBranch = true;
2167a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        invokeMIR->OptimizationFlags |= MIR_INLINED;
2177a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#if defined(WITH_JIT_TUNING)
2187a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        gDvmJit.invokeMonoSetterInlined++;
2197a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#endif
2207a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
2217a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
222cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng    return true;
2237a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng}
2247a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
225cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Chengstatic bool tryInlineSingletonCallsite(CompilationUnit *cUnit,
2267a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                       const Method *calleeMethod,
2277a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                       MIR *invokeMIR,
2287a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                       BasicBlock *invokeBB,
2297a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                       bool isRange)
2307a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng{
2317a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /* Not a Java method */
232cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng    if (dvmIsNativeMethod(calleeMethod)) return false;
2337a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
2347a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    CompilerMethodStats *methodStats =
2357a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        dvmCompilerAnalyzeMethodBody(calleeMethod, true);
2367a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
2377a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /* Empty callee - do nothing */
2387a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (methodStats->attributes & METHOD_IS_EMPTY) {
2397a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        /* The original invoke instruction is effectively turned into NOP */
2407a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        invokeMIR->OptimizationFlags |= MIR_INLINED;
24123608ab40900463fc5c8461671ba3aa5d0a4260eBen Cheng        /*
24223608ab40900463fc5c8461671ba3aa5d0a4260eBen Cheng         * Need to insert an explicit branch to catch the falling knife (into
24323608ab40900463fc5c8461671ba3aa5d0a4260eBen Cheng         * the PC reconstruction or chaining cell).
24423608ab40900463fc5c8461671ba3aa5d0a4260eBen Cheng         */
24523608ab40900463fc5c8461671ba3aa5d0a4260eBen Cheng        invokeBB->needFallThroughBranch = true;
246cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng        return true;
2477a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
2487a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
2497a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (methodStats->attributes & METHOD_IS_GETTER) {
250cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng        return inlineGetter(cUnit, calleeMethod, invokeMIR, invokeBB, false,
251cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                            isRange);
2527a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    } else if (methodStats->attributes & METHOD_IS_SETTER) {
253cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng        return inlineSetter(cUnit, calleeMethod, invokeMIR, invokeBB, false,
254cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                            isRange);
2557a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
256cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng    return false;
2577a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng}
2587a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
259cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Chengstatic bool inlineEmptyVirtualCallee(CompilationUnit *cUnit,
2607a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     const Method *calleeMethod,
2617a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     MIR *invokeMIR,
2627a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     BasicBlock *invokeBB)
2637a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng{
264fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    MIR *invokeMIRSlow = (MIR *)dvmCompilerNew(sizeof(MIR), true);
2657a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    *invokeMIRSlow = *invokeMIR;
2665d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro    invokeMIR->dalvikInsn.opcode = (Opcode)kMirOpCheckInlinePrediction;
2677a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
2687a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    dvmCompilerInsertMIRAfter(invokeBB, invokeMIR, invokeMIRSlow);
2697a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    invokeMIRSlow->OptimizationFlags |= MIR_INLINED_PRED;
270cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng    return true;
2717a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng}
2727a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
273cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Chengstatic bool tryInlineVirtualCallsite(CompilationUnit *cUnit,
2747a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     const Method *calleeMethod,
2757a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     MIR *invokeMIR,
2767a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     BasicBlock *invokeBB,
2777a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                                     bool isRange)
2787a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng{
2797a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /* Not a Java method */
280cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng    if (dvmIsNativeMethod(calleeMethod)) return false;
2817a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
2827a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    CompilerMethodStats *methodStats =
2837a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        dvmCompilerAnalyzeMethodBody(calleeMethod, true);
2847a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
2857a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /* Empty callee - do nothing by checking the clazz pointer */
2867a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (methodStats->attributes & METHOD_IS_EMPTY) {
287cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng        return inlineEmptyVirtualCallee(cUnit, calleeMethod, invokeMIR,
288cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                                        invokeBB);
2897a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
2907a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
2917a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (methodStats->attributes & METHOD_IS_GETTER) {
292cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng        return inlineGetter(cUnit, calleeMethod, invokeMIR, invokeBB, true,
293cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                            isRange);
2947a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    } else if (methodStats->attributes & METHOD_IS_SETTER) {
295cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng        return inlineSetter(cUnit, calleeMethod, invokeMIR, invokeBB, true,
296cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                            isRange);
2977a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
298cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng    return false;
2997a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng}
3007a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
3017a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
302cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Chengvoid dvmCompilerInlineMIR(CompilationUnit *cUnit, JitTranslationInfo *info)
3037a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng{
3047a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    bool isRange = false;
30500603079b8723b32c955513eae63a8f97898074dBen Cheng    GrowableListIterator iterator;
3067a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
30700603079b8723b32c955513eae63a8f97898074dBen Cheng    dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
3087a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    /*
3097a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     * Analyze the basic block containing an invoke to see if it can be inlined
3107a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng     */
31100603079b8723b32c955513eae63a8f97898074dBen Cheng    while (true) {
31200603079b8723b32c955513eae63a8f97898074dBen Cheng        BasicBlock *bb = (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
31300603079b8723b32c955513eae63a8f97898074dBen Cheng        if (bb == NULL) break;
3147a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        if (bb->blockType != kDalvikByteCode)
3157a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            continue;
3167a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        MIR *lastMIRInsn = bb->lastMIRInsn;
3175d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro        Opcode opcode = lastMIRInsn->dalvikInsn.opcode;
3185d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro        int flags = (int)dexGetFlagsFromOpcode(opcode);
3197a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
3207a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        /* No invoke - continue */
3217a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        if ((flags & kInstrInvoke) == 0)
3227a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            continue;
3237a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
32418fba346582c08d81aa96d9508c0e935bad5f36fbuzbee        /* Disable inlining when doing method tracing */
32518fba346582c08d81aa96d9508c0e935bad5f36fbuzbee        if (gDvmJit.methodTraceSupport)
32618fba346582c08d81aa96d9508c0e935bad5f36fbuzbee            continue;
32718fba346582c08d81aa96d9508c0e935bad5f36fbuzbee
3287eb3f7aaf43f07caf0de05ba4ae59e8ea6add796Ben Cheng        /*
3297eb3f7aaf43f07caf0de05ba4ae59e8ea6add796Ben Cheng         * If the invoke itself is selected for single stepping, don't bother
3307eb3f7aaf43f07caf0de05ba4ae59e8ea6add796Ben Cheng         * to inline it.
3317eb3f7aaf43f07caf0de05ba4ae59e8ea6add796Ben Cheng         */
3329a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein        if (SINGLE_STEP_OP(opcode))
3337eb3f7aaf43f07caf0de05ba4ae59e8ea6add796Ben Cheng            continue;
3347eb3f7aaf43f07caf0de05ba4ae59e8ea6add796Ben Cheng
3357a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        const Method *calleeMethod;
3367a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
3379a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein        switch (opcode) {
3387a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_SUPER:
3397a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_DIRECT:
3407a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_STATIC:
3417a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_SUPER_QUICK:
3427a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                calleeMethod = lastMIRInsn->meta.callsiteInfo->method;
3437a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                break;
3447a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_SUPER_RANGE:
3457a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_DIRECT_RANGE:
3467a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_STATIC_RANGE:
3477a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_SUPER_QUICK_RANGE:
3487a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                isRange = true;
3497a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                calleeMethod = lastMIRInsn->meta.callsiteInfo->method;
3507a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                break;
3517a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            default:
3527a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                calleeMethod = NULL;
3537a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                break;
3547a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        }
3557a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
3567a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        if (calleeMethod) {
357cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng            bool inlined = tryInlineSingletonCallsite(cUnit, calleeMethod,
358cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                                                      lastMIRInsn, bb, isRange);
359cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng            if (!inlined &&
360cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                !(gDvmJit.disableOpt & (1 << kMethodJit)) &&
361cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                !dvmIsNativeMethod(calleeMethod)) {
362cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                CompilerMethodStats *methodStats =
363cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    dvmCompilerAnalyzeMethodBody(calleeMethod, true);
364cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                if ((methodStats->attributes & METHOD_IS_LEAF) &&
365cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    !(methodStats->attributes & METHOD_CANNOT_COMPILE)) {
366cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    /* Callee has been previously compiled */
367cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    if (dvmJitGetMethodAddr(calleeMethod->insns)) {
368cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        lastMIRInsn->OptimizationFlags |= MIR_INVOKE_METHOD_JIT;
369cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    } else {
370cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        /* Compile the callee first */
371cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        dvmCompileMethod(calleeMethod, info);
372cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        if (dvmJitGetMethodAddr(calleeMethod->insns)) {
373cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                            lastMIRInsn->OptimizationFlags |=
374cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                                MIR_INVOKE_METHOD_JIT;
375cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        } else {
376cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                            methodStats->attributes |= METHOD_CANNOT_COMPILE;
377cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        }
378cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    }
379cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                }
380cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng            }
3817a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            return;
3827a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        }
3837a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
3849a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein        switch (opcode) {
3857a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_VIRTUAL:
3867a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_VIRTUAL_QUICK:
3877a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_INTERFACE:
3887a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                isRange = false;
3897a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                calleeMethod = lastMIRInsn->meta.callsiteInfo->method;
3907a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                break;
3917a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_VIRTUAL_RANGE:
3927a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_VIRTUAL_QUICK_RANGE:
3937a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            case OP_INVOKE_INTERFACE_RANGE:
3947a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                isRange = true;
3957a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                calleeMethod = lastMIRInsn->meta.callsiteInfo->method;
3967a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                break;
3977a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            default:
3987a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng                break;
3997a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        }
4007a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
4017a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        if (calleeMethod) {
402cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng            bool inlined = tryInlineVirtualCallsite(cUnit, calleeMethod,
403cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                                                    lastMIRInsn, bb, isRange);
404cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng            if (!inlined &&
405cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                !(gDvmJit.disableOpt & (1 << kMethodJit)) &&
406cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                !dvmIsNativeMethod(calleeMethod)) {
407cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                CompilerMethodStats *methodStats =
408cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    dvmCompilerAnalyzeMethodBody(calleeMethod, true);
409cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                if ((methodStats->attributes & METHOD_IS_LEAF) &&
410cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    !(methodStats->attributes & METHOD_CANNOT_COMPILE)) {
411cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    /* Callee has been previously compiled */
412cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    if (dvmJitGetMethodAddr(calleeMethod->insns)) {
413cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        lastMIRInsn->OptimizationFlags |= MIR_INVOKE_METHOD_JIT;
414cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    } else {
415cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        /* Compile the callee first */
416cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        dvmCompileMethod(calleeMethod, info);
417cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        if (dvmJitGetMethodAddr(calleeMethod->insns)) {
418cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                            lastMIRInsn->OptimizationFlags |=
419cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                                MIR_INVOKE_METHOD_JIT;
420cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        } else {
421cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                            methodStats->attributes |= METHOD_CANNOT_COMPILE;
422cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                        }
423cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                    }
424cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng                }
425cfdeca37fcaa27c37bad5077223e4d1e87f1182eBen Cheng            }
4267a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng            return;
4277a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        }
4287a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
4297a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng}
430