Merge "Fix oat_file_assistant_test32 flaky failures with GSS collector."
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 689f535..0a069a7 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -2312,9 +2312,12 @@
break;
}
case Primitive::kPrimLong: {
- locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RequiresRegister());
- locations->SetOut(Location::RequiresRegister());
+ InvokeRuntimeCallingConvention calling_convention;
+ locations->SetInAt(0, Location::RegisterPairLocation(
+ calling_convention.GetRegisterAt(0), calling_convention.GetRegisterAt(1)));
+ locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2)));
+ // The runtime helper puts the output in R0,R1.
+ locations->SetOut(Location::RegisterPairLocation(R0, R1));
break;
}
default:
@@ -2362,54 +2365,24 @@
break;
}
case Primitive::kPrimLong: {
- Register o_h = out.AsRegisterPairHigh<Register>();
- Register o_l = out.AsRegisterPairLow<Register>();
+ // TODO: Inline the assembly instead of calling the runtime.
+ InvokeRuntimeCallingConvention calling_convention;
+ DCHECK_EQ(calling_convention.GetRegisterAt(0), first.AsRegisterPairLow<Register>());
+ DCHECK_EQ(calling_convention.GetRegisterAt(1), first.AsRegisterPairHigh<Register>());
+ DCHECK_EQ(calling_convention.GetRegisterAt(2), second.AsRegister<Register>());
+ DCHECK_EQ(R0, out.AsRegisterPairLow<Register>());
+ DCHECK_EQ(R1, out.AsRegisterPairHigh<Register>());
- Register high = first.AsRegisterPairHigh<Register>();
- Register low = first.AsRegisterPairLow<Register>();
-
- Register second_reg = second.AsRegister<Register>();
-
+ int32_t entry_point_offset;
if (op->IsShl()) {
- // Shift the high part
- __ and_(second_reg, second_reg, ShifterOperand(63));
- __ Lsl(high, high, second_reg);
- // Shift the low part and `or` what overflowed on the high part
- __ rsb(IP, second_reg, ShifterOperand(32));
- __ Lsr(IP, low, IP);
- __ orr(o_h, high, ShifterOperand(IP));
- // If the shift is > 32 bits, override the high part
- __ subs(IP, second_reg, ShifterOperand(32));
- __ it(PL);
- __ Lsl(o_h, low, IP, false, PL);
- // Shift the low part
- __ Lsl(o_l, low, second_reg);
+ entry_point_offset = QUICK_ENTRY_POINT(pShlLong);
} else if (op->IsShr()) {
- // Shift the low part
- __ and_(second_reg, second_reg, ShifterOperand(63));
- __ Lsr(low, low, second_reg);
- // Shift the high part and `or` what underflowed on the low part
- __ rsb(IP, second_reg, ShifterOperand(32));
- __ Lsl(IP, high, IP);
- __ orr(o_l, low, ShifterOperand(IP));
- // If the shift is > 32 bits, override the low part
- __ subs(IP, second_reg, ShifterOperand(32));
- __ it(PL);
- __ Asr(o_l, high, IP, false, PL);
- // Shift the high part
- __ Asr(o_h, high, second_reg);
+ entry_point_offset = QUICK_ENTRY_POINT(pShrLong);
} else {
- // same as Shr except we use `Lsr`s and not `Asr`s
- __ and_(second_reg, second_reg, ShifterOperand(63));
- __ Lsr(low, low, second_reg);
- __ rsb(IP, second_reg, ShifterOperand(32));
- __ Lsl(IP, high, IP);
- __ orr(o_l, low, ShifterOperand(IP));
- __ subs(IP, second_reg, ShifterOperand(32));
- __ it(PL);
- __ Lsr(o_l, high, IP, false, PL);
- __ Lsr(o_h, high, second_reg);
+ entry_point_offset = QUICK_ENTRY_POINT(pUshrLong);
}
+ __ LoadFromOffset(kLoadWord, LR, TR, entry_point_offset);
+ __ blx(LR);
break;
}
default:
diff --git a/compiler/utils/arm/assembler_arm.h b/compiler/utils/arm/assembler_arm.h
index dd0dba2..8730f52 100644
--- a/compiler/utils/arm/assembler_arm.h
+++ b/compiler/utils/arm/assembler_arm.h
@@ -100,10 +100,6 @@
return rm_;
}
- Register GetSecondRegister() const {
- return rs_;
- }
-
enum Type {
kUnknown = -1,
kRegister,
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc
index e8eb019..6d0571e 100644
--- a/compiler/utils/arm/assembler_thumb2.cc
+++ b/compiler/utils/arm/assembler_thumb2.cc
@@ -826,9 +826,7 @@
// Check special cases.
if ((opcode == SUB || opcode == ADD) && (so.GetImmediate() < (1u << 12))) {
if (opcode == SUB) {
- if (!set_cc) {
- thumb_opcode = 5U /* 0b0101 */;
- }
+ thumb_opcode = 5U /* 0b0101 */;
} else {
thumb_opcode = 0;
}
@@ -838,14 +836,13 @@
uint32_t imm3 = (imm >> 8) & 7U /* 0b111 */;
uint32_t imm8 = imm & 0xff;
- encoding = B31 | B30 | B29 | B28 |
- (set_cc ? B20 : B25) |
- thumb_opcode << 21 |
- rn << 16 |
- rd << 8 |
- i << 26 |
- imm3 << 12 |
- imm8;
+ encoding = B31 | B30 | B29 | B28 | B25 |
+ thumb_opcode << 21 |
+ rn << 16 |
+ rd << 8 |
+ i << 26 |
+ imm3 << 12 |
+ imm8;
} else {
// Modified immediate.
uint32_t imm = ModifiedImmediate(so.encodingThumb());
@@ -861,13 +858,13 @@
imm;
}
} else if (so.IsRegister()) {
- // Register (possibly shifted)
- encoding = B31 | B30 | B29 | B27 | B25 |
- thumb_opcode << 21 |
- (set_cc ? 1 : 0) << 20 |
- rn << 16 |
- rd << 8 |
- so.encodingThumb();
+ // Register (possibly shifted)
+ encoding = B31 | B30 | B29 | B27 | B25 |
+ thumb_opcode << 21 |
+ (set_cc ? 1 : 0) << 20 |
+ rn << 16 |
+ rd << 8 |
+ so.encodingThumb();
}
Emit32(encoding);
}
@@ -924,8 +921,6 @@
use_immediate = true;
immediate = so.GetImmediate();
} else {
- CHECK(!(so.IsRegister() && so.IsShift() && so.GetSecondRegister() != kNoRegister))
- << "No register-shifted register instruction available in thumb";
// Adjust rn and rd: only two registers will be emitted.
switch (opcode) {
case AND:
diff --git a/compiler/utils/arm/assembler_thumb2_test.cc b/compiler/utils/arm/assembler_thumb2_test.cc
index d802852..ebea9d4 100644
--- a/compiler/utils/arm/assembler_thumb2_test.cc
+++ b/compiler/utils/arm/assembler_thumb2_test.cc
@@ -227,14 +227,4 @@
DriverStr(expected, "abs");
}
-TEST_F(AssemblerThumb2Test, sub) {
- __ subs(arm::R1, arm::R0, arm::ShifterOperand(42));
- __ sub(arm::R1, arm::R0, arm::ShifterOperand(42));
-
- const char* expected =
- "subs r1, r0, #42\n"
- "subw r1, r0, #42\n";
- DriverStr(expected, "sub");
-}
-
} // namespace art
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index c056adc..8395150 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -59,10 +59,11 @@
DEBUG_ENABLE_ASSERT = 1 << 2,
DEBUG_ENABLE_SAFEMODE = 1 << 3,
DEBUG_ENABLE_JNI_LOGGING = 1 << 4,
+ DEBUG_ENABLE_JIT = 1 << 5,
};
+ Runtime* const runtime = Runtime::Current();
if ((debug_flags & DEBUG_ENABLE_CHECKJNI) != 0) {
- Runtime* runtime = Runtime::Current();
JavaVMExt* vm = runtime->GetJavaVM();
if (!vm->IsCheckJniEnabled()) {
LOG(INFO) << "Late-enabling -Xcheck:jni";
@@ -86,13 +87,26 @@
}
debug_flags &= ~DEBUG_ENABLE_DEBUGGER;
- if ((debug_flags & DEBUG_ENABLE_SAFEMODE) != 0) {
+ const bool safe_mode = (debug_flags & DEBUG_ENABLE_SAFEMODE) != 0;
+ if (safe_mode) {
// Ensure that any (secondary) oat files will be interpreted.
- Runtime* runtime = Runtime::Current();
runtime->AddCompilerOption("--compiler-filter=interpret-only");
debug_flags &= ~DEBUG_ENABLE_SAFEMODE;
}
+ if ((debug_flags & DEBUG_ENABLE_JIT) != 0) {
+ if (safe_mode) {
+ LOG(INFO) << "Not enabling JIT due to VM safe mode";
+ } else {
+ if (runtime->GetJit() == nullptr) {
+ runtime->CreateJit();
+ } else {
+ LOG(INFO) << "Not late-enabling JIT (already on)";
+ }
+ }
+ debug_flags &= ~DEBUG_ENABLE_JIT;
+ }
+
// This is for backwards compatibility with Dalvik.
debug_flags &= ~DEBUG_ENABLE_ASSERT;