Index: src/arm64/lithium-gap-resolver-arm64.cc |
diff --git a/src/arm64/lithium-gap-resolver-arm64.cc b/src/arm64/lithium-gap-resolver-arm64.cc |
index bd655eaae8324ab4a0806f7b28f548c67cdbfed5..e367709e0b4c569d90bd20e341748d2002a36c8b 100644 |
--- a/src/arm64/lithium-gap-resolver-arm64.cc |
+++ b/src/arm64/lithium-gap-resolver-arm64.cc |
@@ -4,36 +4,36 @@ |
#include "src/v8.h" |
+#include "src/arm64/delayed-masm-arm64-inl.h" |
#include "src/arm64/lithium-gap-resolver-arm64.h" |
#include "src/arm64/lithium-codegen-arm64.h" |
namespace v8 { |
namespace internal { |
-// We use the root register to spill a value while breaking a cycle in parallel |
-// moves. We don't need access to roots while resolving the move list and using |
-// the root register has two advantages: |
-// - It is not in crankshaft allocatable registers list, so it can't interfere |
-// with any of the moves we are resolving. |
-// - We don't need to push it on the stack, as we can reload it with its value |
-// once we have resolved a cycle. |
-#define kSavedValue root |
+#define __ ACCESS_MASM((&masm_)) |
-// We use the MacroAssembler floating-point scratch register to break a cycle |
-// involving double values as the MacroAssembler will not need it for the |
-// operations performed by the gap resolver. |
-#define kSavedDoubleValue fp_scratch |
+void DelayedGapMasm::EndDelayedUse() { |
+ DelayedMasm::EndDelayedUse(); |
+ if (scratch_register_used()) { |
+ ASSERT(ScratchRegister().Is(root)); |
+ ASSERT(!pending()); |
+ InitializeRootRegister(); |
+ reset_scratch_register_used(); |
+ } |
+} |
-LGapResolver::LGapResolver(LCodeGen* owner) |
- : cgen_(owner), moves_(32, owner->zone()), root_index_(0), in_cycle_(false), |
- saved_destination_(NULL), need_to_restore_root_(false) { } |
+LGapResolver::LGapResolver(LCodeGen* owner) |
+ : cgen_(owner), masm_(owner, owner->masm()), moves_(32, owner->zone()), |
+ root_index_(0), in_cycle_(false), saved_destination_(NULL) { |
+} |
-#define __ ACCESS_MASM(cgen_->masm()) |
void LGapResolver::Resolve(LParallelMove* parallel_move) { |
ASSERT(moves_.is_empty()); |
+ ASSERT(!masm_.pending()); |
// Build up a worklist of moves. |
BuildInitialMoveList(parallel_move); |
@@ -61,11 +61,7 @@ void LGapResolver::Resolve(LParallelMove* parallel_move) { |
} |
} |
- if (need_to_restore_root_) { |
- ASSERT(kSavedValue.Is(root)); |
- __ InitializeRootRegister(); |
- need_to_restore_root_ = false; |
- } |
+ __ EndDelayedUse(); |
moves_.Rewind(0); |
} |
@@ -152,11 +148,6 @@ void LGapResolver::BreakCycle(int index) { |
ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source())); |
ASSERT(!in_cycle_); |
- // We use registers which are not allocatable by crankshaft to break the cycle |
- // to be sure they don't interfere with the moves we are resolving. |
- ASSERT(!kSavedValue.IsAllocatable()); |
- ASSERT(!kSavedDoubleValue.IsAllocatable()); |
- |
// We save in a register the source of that move and we remember its |
// destination. Then we mark this move as resolved so the cycle is |
// broken and we can perform the other moves. |
@@ -165,19 +156,15 @@ void LGapResolver::BreakCycle(int index) { |
saved_destination_ = moves_[index].destination(); |
if (source->IsRegister()) { |
- need_to_restore_root_ = true; |
- __ Mov(kSavedValue, cgen_->ToRegister(source)); |
+ AcquireSavedValueRegister(); |
+ __ Mov(SavedValueRegister(), cgen_->ToRegister(source)); |
} else if (source->IsStackSlot()) { |
- need_to_restore_root_ = true; |
- __ Ldr(kSavedValue, cgen_->ToMemOperand(source)); |
+ AcquireSavedValueRegister(); |
+ __ Load(SavedValueRegister(), cgen_->ToMemOperand(source)); |
} else if (source->IsDoubleRegister()) { |
- ASSERT(cgen_->masm()->FPTmpList()->IncludesAliasOf(kSavedDoubleValue)); |
- cgen_->masm()->FPTmpList()->Remove(kSavedDoubleValue); |
- __ Fmov(kSavedDoubleValue, cgen_->ToDoubleRegister(source)); |
+ __ Fmov(SavedFPValueRegister(), cgen_->ToDoubleRegister(source)); |
} else if (source->IsDoubleStackSlot()) { |
- ASSERT(cgen_->masm()->FPTmpList()->IncludesAliasOf(kSavedDoubleValue)); |
- cgen_->masm()->FPTmpList()->Remove(kSavedDoubleValue); |
- __ Ldr(kSavedDoubleValue, cgen_->ToMemOperand(source)); |
+ __ Load(SavedFPValueRegister(), cgen_->ToMemOperand(source)); |
} else { |
UNREACHABLE(); |
} |
@@ -194,15 +181,16 @@ void LGapResolver::RestoreValue() { |
ASSERT(saved_destination_ != NULL); |
if (saved_destination_->IsRegister()) { |
- __ Mov(cgen_->ToRegister(saved_destination_), kSavedValue); |
+ __ Mov(cgen_->ToRegister(saved_destination_), SavedValueRegister()); |
+ ReleaseSavedValueRegister(); |
} else if (saved_destination_->IsStackSlot()) { |
- __ Str(kSavedValue, cgen_->ToMemOperand(saved_destination_)); |
+ __ Store(SavedValueRegister(), cgen_->ToMemOperand(saved_destination_)); |
+ ReleaseSavedValueRegister(); |
} else if (saved_destination_->IsDoubleRegister()) { |
- __ Fmov(cgen_->ToDoubleRegister(saved_destination_), kSavedDoubleValue); |
- cgen_->masm()->FPTmpList()->Combine(kSavedDoubleValue); |
+ __ Fmov(cgen_->ToDoubleRegister(saved_destination_), |
+ SavedFPValueRegister()); |
} else if (saved_destination_->IsDoubleStackSlot()) { |
- __ Str(kSavedDoubleValue, cgen_->ToMemOperand(saved_destination_)); |
- cgen_->masm()->FPTmpList()->Combine(kSavedDoubleValue); |
+ __ Store(SavedFPValueRegister(), cgen_->ToMemOperand(saved_destination_)); |
} else { |
UNREACHABLE(); |
} |
@@ -225,13 +213,13 @@ void LGapResolver::EmitMove(int index) { |
__ Mov(cgen_->ToRegister(destination), source_register); |
} else { |
ASSERT(destination->IsStackSlot()); |
- __ Str(source_register, cgen_->ToMemOperand(destination)); |
+ __ Store(source_register, cgen_->ToMemOperand(destination)); |
} |
} else if (source->IsStackSlot()) { |
MemOperand source_operand = cgen_->ToMemOperand(source); |
if (destination->IsRegister()) { |
- __ Ldr(cgen_->ToRegister(destination), source_operand); |
+ __ Load(cgen_->ToRegister(destination), source_operand); |
} else { |
ASSERT(destination->IsStackSlot()); |
EmitStackSlotMove(index); |
@@ -254,15 +242,28 @@ void LGapResolver::EmitMove(int index) { |
} else { |
ASSERT(destination->IsStackSlot()); |
ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone. |
- need_to_restore_root_ = true; |
if (cgen_->IsSmi(constant_source)) { |
- __ Mov(kSavedValue, cgen_->ToSmi(constant_source)); |
+ Smi* smi = cgen_->ToSmi(constant_source); |
+ __ StoreConstant(reinterpret_cast<intptr_t>(smi), |
+ cgen_->ToMemOperand(destination)); |
} else if (cgen_->IsInteger32Constant(constant_source)) { |
- __ Mov(kSavedValue, cgen_->ToInteger32(constant_source)); |
+ __ StoreConstant(cgen_->ToInteger32(constant_source), |
+ cgen_->ToMemOperand(destination)); |
} else { |
- __ LoadObject(kSavedValue, cgen_->ToHandle(constant_source)); |
+ Handle<Object> handle = cgen_->ToHandle(constant_source); |
+ AllowDeferredHandleDereference smi_object_check; |
+ if (handle->IsSmi()) { |
+ Object* obj = *handle; |
+ ASSERT(!obj->IsHeapObject()); |
+ __ StoreConstant(reinterpret_cast<intptr_t>(obj), |
+ cgen_->ToMemOperand(destination)); |
+ } else { |
+ AcquireSavedValueRegister(); |
+ __ LoadObject(SavedValueRegister(), handle); |
+ __ Store(SavedValueRegister(), cgen_->ToMemOperand(destination)); |
+ ReleaseSavedValueRegister(); |
+ } |
} |
- __ Str(kSavedValue, cgen_->ToMemOperand(destination)); |
} |
} else if (source->IsDoubleRegister()) { |
@@ -271,13 +272,13 @@ void LGapResolver::EmitMove(int index) { |
__ Fmov(cgen_->ToDoubleRegister(destination), src); |
} else { |
ASSERT(destination->IsDoubleStackSlot()); |
- __ Str(src, cgen_->ToMemOperand(destination)); |
+ __ Store(src, cgen_->ToMemOperand(destination)); |
} |
} else if (source->IsDoubleStackSlot()) { |
MemOperand src = cgen_->ToMemOperand(source); |
if (destination->IsDoubleRegister()) { |
- __ Ldr(cgen_->ToDoubleRegister(destination), src); |
+ __ Load(cgen_->ToDoubleRegister(destination), src); |
} else { |
ASSERT(destination->IsDoubleStackSlot()); |
EmitStackSlotMove(index); |
@@ -291,21 +292,4 @@ void LGapResolver::EmitMove(int index) { |
moves_[index].Eliminate(); |
} |
- |
-void LGapResolver::EmitStackSlotMove(int index) { |
- // We need a temp register to perform a stack slot to stack slot move, and |
- // the register must not be involved in breaking cycles. |
- |
- // Use the Crankshaft double scratch register as the temporary. |
- DoubleRegister temp = crankshaft_fp_scratch; |
- |
- LOperand* src = moves_[index].source(); |
- LOperand* dst = moves_[index].destination(); |
- |
- ASSERT(src->IsStackSlot()); |
- ASSERT(dst->IsStackSlot()); |
- __ Ldr(temp, cgen_->ToMemOperand(src)); |
- __ Str(temp, cgen_->ToMemOperand(dst)); |
-} |
- |
} } // namespace v8::internal |