Index: src/crankshaft/arm64/lithium-codegen-arm64.cc |
diff --git a/src/crankshaft/arm64/lithium-codegen-arm64.cc b/src/crankshaft/arm64/lithium-codegen-arm64.cc |
index ff2a6d3a6982df35420bab1f3eeed21e0bd24a67..6540c5f2bb23ea929ca88d8976a7a1662a86d7da 100644 |
--- a/src/crankshaft/arm64/lithium-codegen-arm64.cc |
+++ b/src/crankshaft/arm64/lithium-codegen-arm64.cc |
@@ -39,6 +39,29 @@ class SafepointGenerator final : public CallWrapper { |
Safepoint::DeoptMode deopt_mode_; |
}; |
+LCodeGen::PushSafepointRegistersScope::PushSafepointRegistersScope( |
+ LCodeGen* codegen) |
+ : codegen_(codegen) { |
+ DCHECK(codegen_->info()->is_calling()); |
+ DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); |
+ codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; |
+ |
+ UseScratchRegisterScope temps(codegen_->masm_); |
+ // Preserve the value of lr which must be saved on the stack (the call to |
+ // the stub will clobber it). |
+ Register to_be_pushed_lr = |
+ temps.UnsafeAcquire(StoreRegistersStateStub::to_be_pushed_lr()); |
+ codegen_->masm_->Mov(to_be_pushed_lr, lr); |
+ StoreRegistersStateStub stub(codegen_->isolate()); |
+ codegen_->masm_->CallStub(&stub); |
+} |
+ |
+LCodeGen::PushSafepointRegistersScope::~PushSafepointRegistersScope() { |
+ DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); |
+ RestoreRegistersStateStub stub(codegen_->isolate()); |
+ codegen_->masm_->CallStub(&stub); |
+ codegen_->expected_safepoint_kind_ = Safepoint::kSimple; |
+} |
#define __ masm()-> |
@@ -1764,18 +1787,17 @@ void LCodeGen::DoBranch(LBranch* instr) { |
__ Ldr(temp, FieldMemOperand(value, String::kLengthOffset)); |
EmitCompareAndBranch(instr, ne, temp, 0); |
} else { |
- ToBooleanICStub::Types expected = |
- instr->hydrogen()->expected_input_types(); |
+ ToBooleanHints expected = instr->hydrogen()->expected_input_types(); |
// Avoid deopts in the case where we've never executed this path before. |
- if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); |
+ if (expected == ToBooleanHint::kNone) expected = ToBooleanHint::kAny; |
- if (expected.Contains(ToBooleanICStub::UNDEFINED)) { |
+ if (expected & ToBooleanHint::kUndefined) { |
// undefined -> false. |
__ JumpIfRoot( |
value, Heap::kUndefinedValueRootIndex, false_label); |
} |
- if (expected.Contains(ToBooleanICStub::BOOLEAN)) { |
+ if (expected & ToBooleanHint::kBoolean) { |
// Boolean -> its value. |
__ JumpIfRoot( |
value, Heap::kTrueValueRootIndex, true_label); |
@@ -1783,18 +1805,18 @@ void LCodeGen::DoBranch(LBranch* instr) { |
value, Heap::kFalseValueRootIndex, false_label); |
} |
- if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { |
+ if (expected & ToBooleanHint::kNull) { |
// 'null' -> false. |
__ JumpIfRoot( |
value, Heap::kNullValueRootIndex, false_label); |
} |
- if (expected.Contains(ToBooleanICStub::SMI)) { |
+ if (expected & ToBooleanHint::kSmallInteger) { |
// Smis: 0 -> false, all other -> true. |
DCHECK(Smi::kZero == 0); |
__ Cbz(value, false_label); |
__ JumpIfSmi(value, true_label); |
- } else if (expected.NeedsMap()) { |
+ } else if (expected & ToBooleanHint::kNeedsMap) { |
// If we need a map later and have a smi, deopt. |
DeoptimizeIfSmi(value, instr, DeoptimizeReason::kSmi); |
} |
@@ -1802,14 +1824,14 @@ void LCodeGen::DoBranch(LBranch* instr) { |
Register map = NoReg; |
Register scratch = NoReg; |
- if (expected.NeedsMap()) { |
+ if (expected & ToBooleanHint::kNeedsMap) { |
DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL)); |
map = ToRegister(instr->temp1()); |
scratch = ToRegister(instr->temp2()); |
__ Ldr(map, FieldMemOperand(value, HeapObject::kMapOffset)); |
- if (expected.CanBeUndetectable()) { |
+ if (expected & ToBooleanHint::kCanBeUndetectable) { |
// Undetectable -> false. |
__ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); |
__ TestAndBranchIfAnySet( |
@@ -1817,13 +1839,13 @@ void LCodeGen::DoBranch(LBranch* instr) { |
} |
} |
- if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { |
+ if (expected & ToBooleanHint::kReceiver) { |
// spec object -> true. |
__ CompareInstanceType(map, scratch, FIRST_JS_RECEIVER_TYPE); |
__ B(ge, true_label); |
} |
- if (expected.Contains(ToBooleanICStub::STRING)) { |
+ if (expected & ToBooleanHint::kString) { |
// String value -> false iff empty. |
Label not_string; |
__ CompareInstanceType(map, scratch, FIRST_NONSTRING_TYPE); |
@@ -1834,19 +1856,19 @@ void LCodeGen::DoBranch(LBranch* instr) { |
__ Bind(¬_string); |
} |
- if (expected.Contains(ToBooleanICStub::SYMBOL)) { |
+ if (expected & ToBooleanHint::kSymbol) { |
// Symbol value -> true. |
__ CompareInstanceType(map, scratch, SYMBOL_TYPE); |
__ B(eq, true_label); |
} |
- if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { |
+ if (expected & ToBooleanHint::kSimdValue) { |
// SIMD value -> true. |
__ CompareInstanceType(map, scratch, SIMD128_VALUE_TYPE); |
__ B(eq, true_label); |
} |
- if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { |
+ if (expected & ToBooleanHint::kHeapNumber) { |
Label not_heap_number; |
__ JumpIfNotRoot(map, Heap::kHeapNumberMapRootIndex, ¬_heap_number); |
@@ -1860,7 +1882,7 @@ void LCodeGen::DoBranch(LBranch* instr) { |
__ Bind(¬_heap_number); |
} |
- if (!expected.IsGeneric()) { |
+ if (expected != ToBooleanHint::kAny) { |
// We've seen something for the first time -> deopt. |
// This can only happen if we are not generic already. |
Deoptimize(instr, DeoptimizeReason::kUnexpectedObject); |