summaryrefslogtreecommitdiff
path: root/src/compiler/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/codegen')
-rw-r--r--src/compiler/codegen/CodegenUtil.cc3
-rw-r--r--src/compiler/codegen/GenCommon.cc26
-rw-r--r--src/compiler/codegen/GenInvoke.cc337
-rw-r--r--src/compiler/codegen/MethodCodegenDriver.cc28
-rw-r--r--src/compiler/codegen/arm/ArmLIR.h1
-rw-r--r--src/compiler/codegen/arm/Thumb2/Factory.cc2
-rw-r--r--src/compiler/codegen/mips/MipsLIR.h1
-rw-r--r--src/compiler/codegen/x86/X86LIR.h1
8 files changed, 387 insertions, 12 deletions
diff --git a/src/compiler/codegen/CodegenUtil.cc b/src/compiler/codegen/CodegenUtil.cc
index f2449e50d9..2318a04d0b 100644
--- a/src/compiler/codegen/CodegenUtil.cc
+++ b/src/compiler/codegen/CodegenUtil.cc
@@ -296,6 +296,9 @@ void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr)
case kPseudoThrowTarget:
LOG(INFO) << "LT" << (void*)lir << ":";
break;
+ case kPseudoIntrinsicRetry:
+ LOG(INFO) << "IR" << (void*)lir << ":";
+ break;
case kPseudoSuspendTarget:
LOG(INFO) << "LS" << (void*)lir << ":";
break;
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 3ca0450e1c..0ef1641858 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -21,7 +21,8 @@ namespace art {
* be applicable to most targets. Only mid-level support utilities
* and "op" calls may be used here.
*/
-
+void genInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+ InvokeType type, bool isRange);
#if defined(TARGET_ARM)
LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide);
#endif
@@ -835,6 +836,7 @@ void handleSuspendLaunchpads(CompilationUnit *cUnit)
int numElems = cUnit->suspendLaunchpads.numUsed;
for (int i = 0; i < numElems; i++) {
oatResetRegPool(cUnit);
+ oatResetDefTracking(cUnit);
LIR* lab = suspendLabel[i];
LIR* resumeLab = (LIR*)lab->operands[0];
cUnit->currentDalvikOffset = lab->operands[1];
@@ -851,12 +853,34 @@ void handleSuspendLaunchpads(CompilationUnit *cUnit)
}
}
+void handleIntrinsicLaunchpads(CompilationUnit *cUnit)
+{
+ LIR** intrinsicLabel = (LIR **)cUnit->intrinsicLaunchpads.elemList;
+ int numElems = cUnit->intrinsicLaunchpads.numUsed;
+ for (int i = 0; i < numElems; i++) {
+ oatResetRegPool(cUnit);
+ oatResetDefTracking(cUnit);
+ LIR* lab = intrinsicLabel[i];
+ MIR* mir = (MIR*)lab->operands[0];
+ InvokeType type = (InvokeType)lab->operands[1];
+ BasicBlock* bb = (BasicBlock*)lab->operands[3];
+ cUnit->currentDalvikOffset = mir->offset;
+ oatAppendLIR(cUnit, lab);
+ genInvoke(cUnit, bb, mir, type, false /* isRange */);
+ LIR* resumeLab = (LIR*)lab->operands[2];
+ if (resumeLab != NULL) {
+ opUnconditionalBranch(cUnit, resumeLab);
+ }
+ }
+}
+
void handleThrowLaunchpads(CompilationUnit *cUnit)
{
LIR** throwLabel = (LIR **)cUnit->throwLaunchpads.elemList;
int numElems = cUnit->throwLaunchpads.numUsed;
for (int i = 0; i < numElems; i++) {
oatResetRegPool(cUnit);
+ oatResetDefTracking(cUnit);
LIR* lab = throwLabel[i];
cUnit->currentDalvikOffset = lab->operands[1];
oatAppendLIR(cUnit, lab);
diff --git a/src/compiler/codegen/GenInvoke.cc b/src/compiler/codegen/GenInvoke.cc
index ebc8bc28a4..ba027f0d07 100644
--- a/src/compiler/codegen/GenInvoke.cc
+++ b/src/compiler/codegen/GenInvoke.cc
@@ -25,6 +25,8 @@ namespace art {
typedef int (*NextCallInsn)(CompilationUnit*, MIR*, int, uint32_t dexIdx,
uint32_t methodIdx, uintptr_t directCode,
uintptr_t directMethod, InvokeType type);
+LIR* opCondBranch(CompilationUnit* cUnit, ConditionCode cc, LIR* target);
+
/*
* If there are any ins passed in registers that have not been promoted
* to a callee-save register, flush them to the frame. Perform intial
@@ -596,4 +598,339 @@ int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir,
return callState;
}
+RegLocation inlineTarget(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
+{
+ RegLocation res;
+ mir = oatFindMoveResult(cUnit, bb, mir, false);
+ if (mir == NULL) {
+ res = oatGetReturn(cUnit, false);
+ } else {
+ res = oatGetDest(cUnit, mir, 0);
+ mir->dalvikInsn.opcode = Instruction::NOP;
+ }
+ return res;
+}
+
+RegLocation inlineTargetWide(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
+{
+ RegLocation res;
+ mir = oatFindMoveResult(cUnit, bb, mir, true);
+ if (mir == NULL) {
+ res = oatGetReturnWide(cUnit, false);
+ } else {
+ res = oatGetDestWide(cUnit, mir, 0, 1);
+ mir->dalvikInsn.opcode = Instruction::NOP;
+ }
+ return res;
+}
+
+bool genInlinedCharAt(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+ InvokeType type, bool isRange)
+{
+#if defined(TARGET_ARM)
+ // Location of reference to data array
+ int valueOffset = String::ValueOffset().Int32Value();
+ // Location of count
+ int countOffset = String::CountOffset().Int32Value();
+ // Starting offset within data array
+ int offsetOffset = String::OffsetOffset().Int32Value();
+ // Start of char data with array_
+ int dataOffset = Array::DataOffset(sizeof(uint16_t)).Int32Value();
+
+ RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
+ RegLocation rlIdx = oatGetSrc(cUnit, mir, 1);
+ rlObj = loadValue(cUnit, rlObj, kCoreReg);
+ rlIdx = loadValue(cUnit, rlIdx, kCoreReg);
+ int regMax;
+ int regOff = oatAllocTemp(cUnit);
+ int regPtr = oatAllocTemp(cUnit);
+ genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);
+ bool rangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
+ if (rangeCheck) {
+ regMax = oatAllocTemp(cUnit);
+ loadWordDisp(cUnit, rlObj.lowReg, countOffset, regMax);
+ }
+ loadWordDisp(cUnit, rlObj.lowReg, offsetOffset, regOff);
+ loadWordDisp(cUnit, rlObj.lowReg, valueOffset, regPtr);
+ LIR* launchPad = NULL;
+ if (rangeCheck) {
+ // Set up a launch pad to allow retry in case of bounds violation */
+ launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
+ oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
+ (intptr_t)launchPad);
+ opRegReg(cUnit, kOpCmp, rlIdx.lowReg, regMax);
+ oatFreeTemp(cUnit, regMax);
+ opCondBranch(cUnit, kCondCs, launchPad);
+ }
+ opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
+ opRegReg(cUnit, kOpAdd, regOff, rlIdx.lowReg);
+ RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+ loadBaseIndexed(cUnit, regPtr, regOff, rlResult.lowReg, 1, kUnsignedHalf);
+ oatFreeTemp(cUnit, regOff);
+ oatFreeTemp(cUnit, regPtr);
+ storeValue(cUnit, rlDest, rlResult);
+ if (rangeCheck) {
+ launchPad->operands[2] = NULL; // no resumption
+ launchPad->operands[3] = (uintptr_t)bb;
+ }
+ // Record that we've already inlined & null checked
+ mir->optimizationFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool genInlinedMinMaxInt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir,
+ bool isMin)
+{
+#if defined(TARGET_ARM)
+ RegLocation rlSrc1 = oatGetSrc(cUnit, mir, 0);
+ RegLocation rlSrc2 = oatGetSrc(cUnit, mir, 1);
+ rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
+ rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
+ RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+ opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
+ opIT(cUnit, (isMin) ? kArmCondGt : kArmCondLt, "E");
+ opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
+ opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
+ genBarrier(cUnit);
+ storeValue(cUnit, rlDest, rlResult);
+ return true;
+#else
+ return false;
+#endif
+}
+
+// Generates an inlined String.isEmpty or String.length.
+bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit,
+ BasicBlock* bb, MIR* mir,
+ bool isEmpty)
+{
+#if defined(TARGET_ARM)
+ // dst = src.length();
+ RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
+ rlObj = loadValue(cUnit, rlObj, kCoreReg);
+ RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+ genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);
+ loadWordDisp(cUnit, rlObj.lowReg, String::CountOffset().Int32Value(),
+ rlResult.lowReg);
+ if (isEmpty) {
+ // dst = (dst == 0);
+ int tReg = oatAllocTemp(cUnit);
+ opRegReg(cUnit, kOpNeg, tReg, rlResult.lowReg);
+ opRegRegReg(cUnit, kOpAdc, rlResult.lowReg, rlResult.lowReg, tReg);
+ }
+ storeValue(cUnit, rlDest, rlResult);
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool genInlinedAbsInt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
+{
+#if defined(TARGET_ARM)
+ RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
+ rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+ RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+ int signReg = oatAllocTemp(cUnit);
+ // abs(x) = y<=x>>31, (x+y)^y.
+ opRegRegImm(cUnit, kOpAsr, signReg, rlSrc.lowReg, 31);
+ opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, signReg);
+ opRegReg(cUnit, kOpXor, rlResult.lowReg, signReg);
+ storeValue(cUnit, rlDest, rlResult);
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool genInlinedAbsLong(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
+{
+#if defined(TARGET_ARM)
+ RegLocation rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+ rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
+ RegLocation rlDest = inlineTargetWide(cUnit, bb, mir);
+ RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+ int signReg = oatAllocTemp(cUnit);
+ // abs(x) = y<=x>>31, (x+y)^y.
+ opRegRegImm(cUnit, kOpAsr, signReg, rlSrc.highReg, 31);
+ opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, signReg);
+ opRegRegReg(cUnit, kOpAdc, rlResult.highReg, rlSrc.highReg, signReg);
+ opRegReg(cUnit, kOpXor, rlResult.lowReg, signReg);
+ opRegReg(cUnit, kOpXor, rlResult.highReg, signReg);
+ storeValueWide(cUnit, rlDest, rlResult);
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool genInlinedFloatCvt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
+{
+#if defined(TARGET_ARM)
+ RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
+ RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ storeValue(cUnit, rlDest, rlSrc);
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool genInlinedDoubleCvt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
+{
+#if defined(TARGET_ARM)
+ RegLocation rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+ RegLocation rlDest = inlineTargetWide(cUnit, bb, mir);
+ storeValueWide(cUnit, rlDest, rlSrc);
+ return true;
+#else
+ return false;
+#endif
+}
+
+/*
+ * Fast string.indexOf(I) & (II). Tests for simple case of char <= 0xffff,
+ * otherwise bails to standard library code.
+ */
+bool genInlinedIndexOf(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+ InvokeType type, bool zeroBased)
+{
+#if defined(TARGET_ARM)
+
+ oatClobberCalleeSave(cUnit);
+ oatLockCallTemps(cUnit); // Using fixed registers
+ int regPtr = rARG0;
+ int regChar = rARG1;
+ int regStart = rARG2;
+
+ RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
+ RegLocation rlChar = oatGetSrc(cUnit, mir, 1);
+ RegLocation rlStart = oatGetSrc(cUnit, mir, 2);
+ loadValueDirectFixed(cUnit, rlObj, regPtr);
+ loadValueDirectFixed(cUnit, rlChar, regChar);
+ if (zeroBased) {
+ loadConstant(cUnit, regStart, 0);
+ } else {
+ loadValueDirectFixed(cUnit, rlStart, regStart);
+ }
+ int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pIndexOf));
+ genNullCheck(cUnit, rlObj.sRegLow, regPtr, mir);
+ LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
+ oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
+ (intptr_t)launchPad);
+ opCmpImmBranch(cUnit, kCondGt, regChar, 0xFFFF, launchPad);
+ opReg(cUnit, kOpBlx, rTgt);
+ LIR* resumeTgt = newLIR0(cUnit, kPseudoTargetLabel);
+ launchPad->operands[2] = (uintptr_t)resumeTgt;
+ launchPad->operands[3] = (uintptr_t)bb;
+ // Record that we've already inlined & null checked
+ mir->optimizationFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
+ return true;
+#else
+ return false;
+#endif
+}
+
+/* Fast string.compareTo(Ljava/lang/string;)I. */
+bool genInlinedStringCompareTo(CompilationUnit* cUnit, BasicBlock* bb,
+ MIR* mir, InvokeType type)
+{
+#if defined(TARGET_ARM)
+ oatClobberCalleeSave(cUnit);
+ oatLockCallTemps(cUnit); // Using fixed registers
+ int regThis = rARG0;
+ int regCmp = rARG1;
+
+ RegLocation rlThis = oatGetSrc(cUnit, mir, 0);
+ RegLocation rlCmp = oatGetSrc(cUnit, mir, 1);
+ loadValueDirectFixed(cUnit, rlThis, regThis);
+ loadValueDirectFixed(cUnit, rlCmp, regCmp);
+ int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pStringCompareTo));
+ genNullCheck(cUnit, rlThis.sRegLow, regThis, mir);
+ //TUNING: check if rlCmp.sRegLow is already null checked
+ LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
+ oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
+ (intptr_t)launchPad);
+ opCmpImmBranch(cUnit, kCondEq, regCmp, 0, launchPad);
+ opReg(cUnit, kOpBlx, rTgt);
+ launchPad->operands[2] = NULL; // No return possible
+ launchPad->operands[3] = (uintptr_t)bb;
+ // Record that we've already inlined & null checked
+ mir->optimizationFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool genIntrinsic(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+ InvokeType type, bool isRange)
+{
+ if ((mir->optimizationFlags & MIR_INLINED) || isRange) {
+ return false;
+ }
+ /*
+ * TODO: move these to a target-specific structured constant array
+ * and use a generic match function. The list of intrinsics may be
+ * slightly different depending on target.
+ * TODO: Fold this into a matching function that runs during
+ * basic block building. This should be part of the action for
+ * small method inlining and recognition of the special object init
+ * method. By doing this during basic block construction, we can also
+ * take advantage of/generate new useful dataflow info.
+ */
+ std::string tgtMethod = PrettyMethod(mir->dalvikInsn.vB, *cUnit->dex_file);
+ if (tgtMethod.compare("char java.lang.String.charAt(int)") == 0) {
+ return genInlinedCharAt(cUnit, bb, mir, type, isRange);
+ }
+ if (tgtMethod.compare("int java.lang.Math.min(int, int)") == 0) {
+ return genInlinedMinMaxInt(cUnit, bb, mir, true /* isMin */);
+ }
+ if (tgtMethod.compare("int java.lang.Math.max(int, int)") == 0) {
+ return genInlinedMinMaxInt(cUnit, bb, mir, false /* isMin */);
+ }
+ if (tgtMethod.compare("int java.lang.String.length()") == 0) {
+ return genInlinedStringIsEmptyOrLength(cUnit, bb, mir, false /* isEmpty */);
+ }
+ if (tgtMethod.compare("boolean java.lang.String.isEmpty()") == 0) {
+ return genInlinedStringIsEmptyOrLength(cUnit, bb, mir, true /* isEmpty */);
+ }
+ if (tgtMethod.compare("int java.lang.Math.abs(int)") == 0) {
+ return genInlinedAbsInt(cUnit, bb, mir);
+ }
+ if (tgtMethod.compare("long java.lang.Math.abs(long)") == 0) {
+ return genInlinedAbsLong(cUnit, bb, mir);
+ }
+ if (tgtMethod.compare("int java.lang.Float.floatToRawIntBits(float)") == 0) {
+ return genInlinedFloatCvt(cUnit, bb, mir);
+ }
+ if (tgtMethod.compare("float java.lang.Float.intBitsToFloat(int)") == 0) {
+ return genInlinedFloatCvt(cUnit, bb, mir);
+ }
+ if (tgtMethod.compare("long java.lang.Double.doubleToRawLongBits(double)") == 0) {
+ return genInlinedDoubleCvt(cUnit, bb, mir);
+ }
+ if (tgtMethod.compare("double java.lang.Double.longBitsToDouble(long)") == 0) {
+ return genInlinedDoubleCvt(cUnit, bb, mir);
+ }
+ if (tgtMethod.compare("int java.lang.String.indexOf(int, int)") == 0) {
+ return genInlinedIndexOf(cUnit, bb, mir, type, false /* base 0 */);
+ }
+ if (tgtMethod.compare("int java.lang.String.indexOf(int)") == 0) {
+ return genInlinedIndexOf(cUnit, bb, mir, type, true /* base 0 */);
+ }
+ if (tgtMethod.compare("int java.lang.String.compareTo(java.lang.String)") == 0) {
+ return genInlinedStringCompareTo(cUnit, bb, mir, type);
+ }
+ return false;
+}
+
+
} // namespace art
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 205a65ad2c..87a86eb6d4 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -52,8 +52,12 @@ RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat)
return res;
}
-void genInvoke(CompilationUnit* cUnit, MIR* mir, InvokeType type, bool isRange)
+void genInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+ InvokeType type, bool isRange)
{
+ if (genIntrinsic(cUnit, bb, mir, type, isRange)) {
+ return;
+ }
DecodedInstruction* dInsn = &mir->dalvikInsn;
InvokeType originalType = type; // avoiding mutation by ComputeInvokeInfo
int callState = 0;
@@ -543,38 +547,38 @@ bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
break;
case Instruction::INVOKE_STATIC_RANGE:
- genInvoke(cUnit, mir, kStatic, true /*range*/);
+ genInvoke(cUnit, bb, mir, kStatic, true /*range*/);
break;
case Instruction::INVOKE_STATIC:
- genInvoke(cUnit, mir, kStatic, false /*range*/);
+ genInvoke(cUnit, bb, mir, kStatic, false /*range*/);
break;
case Instruction::INVOKE_DIRECT:
- genInvoke(cUnit, mir, kDirect, false /*range*/);
+ genInvoke(cUnit, bb, mir, kDirect, false /*range*/);
break;
case Instruction::INVOKE_DIRECT_RANGE:
- genInvoke(cUnit, mir, kDirect, true /*range*/);
+ genInvoke(cUnit, bb, mir, kDirect, true /*range*/);
break;
case Instruction::INVOKE_VIRTUAL:
- genInvoke(cUnit, mir, kVirtual, false /*range*/);
+ genInvoke(cUnit, bb, mir, kVirtual, false /*range*/);
break;
case Instruction::INVOKE_VIRTUAL_RANGE:
- genInvoke(cUnit, mir, kVirtual, true /*range*/);
+ genInvoke(cUnit, bb, mir, kVirtual, true /*range*/);
break;
case Instruction::INVOKE_SUPER:
- genInvoke(cUnit, mir, kSuper, false /*range*/);
+ genInvoke(cUnit, bb, mir, kSuper, false /*range*/);
break;
case Instruction::INVOKE_SUPER_RANGE:
- genInvoke(cUnit, mir, kSuper, true /*range*/);
+ genInvoke(cUnit, bb, mir, kSuper, true /*range*/);
break;
case Instruction::INVOKE_INTERFACE:
- genInvoke(cUnit, mir, kInterface, false /*range*/);
+ genInvoke(cUnit, bb, mir, kInterface, false /*range*/);
break;
case Instruction::INVOKE_INTERFACE_RANGE:
- genInvoke(cUnit, mir, kInterface, true /*range*/);
+ genInvoke(cUnit, bb, mir, kInterface, true /*range*/);
break;
case Instruction::NEG_INT:
@@ -945,6 +949,8 @@ void oatMethodMIR2LIR(CompilationUnit* cUnit)
handleThrowLaunchpads(cUnit);
+ handleIntrinsicLaunchpads(cUnit);
+
if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
removeRedundantBranches(cUnit);
}
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h
index 2d3028a717..da39713f4e 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -290,6 +290,7 @@ enum ArmConditionCode {
* Assemble.cc.
*/
enum ArmOpcode {
+ kPseudoIntrinsicRetry = -16,
kPseudoSuspendTarget = -15,
kPseudoThrowTarget = -14,
kPseudoCaseLabel = -13,
diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc
index c79f7c6ce1..11d5bf4c96 100644
--- a/src/compiler/codegen/arm/Thumb2/Factory.cc
+++ b/src/compiler/codegen/arm/Thumb2/Factory.cc
@@ -681,6 +681,7 @@ LIR* loadBaseIndexed(CompilationUnit* cUnit, int rBase, int rIndex, int rDest,
opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
}
load = newLIR3(cUnit, opcode, rDest, regPtr, 0);
+ oatFreeTemp(cUnit, regPtr);
return load;
case kWord:
opcode = (thumbForm) ? kThumbLdrRRR : kThumb2LdrRRR;
@@ -745,6 +746,7 @@ LIR* storeBaseIndexed(CompilationUnit* cUnit, int rBase, int rIndex, int rSrc,
opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
}
store = newLIR3(cUnit, opcode, rSrc, regPtr, 0);
+ oatFreeTemp(cUnit, regPtr);
return store;
case kWord:
opcode = (thumbForm) ? kThumbStrRRR : kThumb2StrRRR;
diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h
index 5c8fc345e7..c0ff298326 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/MipsLIR.h
@@ -333,6 +333,7 @@ enum MipsShiftEncodings {
* Assemble.cc.
*/
enum MipsOpCode {
+ kPseudoIntrinsicRetry = -16,
kPseudoSuspendTarget = -15,
kPseudoThrowTarget = -14,
kPseudoCaseLabel = -13,
diff --git a/src/compiler/codegen/x86/X86LIR.h b/src/compiler/codegen/x86/X86LIR.h
index 378c24de68..1fc44b3add 100644
--- a/src/compiler/codegen/x86/X86LIR.h
+++ b/src/compiler/codegen/x86/X86LIR.h
@@ -292,6 +292,7 @@ enum X86ConditionCode {
* Assemble.cc.
*/
enum X86OpCode {
+ kPseudoIntrinsicRetry = -16,
kPseudoSuspendTarget = -15,
kPseudoThrowTarget = -14,
kPseudoCaseLabel = -13,