diff options
Diffstat (limited to 'deps/v8/src/arm64/assembler-arm64.cc')
-rw-r--r-- | deps/v8/src/arm64/assembler-arm64.cc | 169 |
1 files changed, 68 insertions, 101 deletions
diff --git a/deps/v8/src/arm64/assembler-arm64.cc b/deps/v8/src/arm64/assembler-arm64.cc index eb581b472b..be0a4a9519 100644 --- a/deps/v8/src/arm64/assembler-arm64.cc +++ b/deps/v8/src/arm64/assembler-arm64.cc @@ -33,7 +33,6 @@ #include "src/arm64/assembler-arm64-inl.h" #include "src/base/bits.h" #include "src/base/cpu.h" -#include "src/code-stubs.h" #include "src/frame-constants.h" #include "src/register-configuration.h" #include "src/string-constants.h" @@ -68,7 +67,7 @@ CPURegister CPURegList::PopLowestIndex() { return NoCPUReg; } int index = CountTrailingZeros(list_, kRegListSizeInBits); - DCHECK((1 << index) & list_); + DCHECK((1LL << index) & list_); Remove(index); return CPURegister::Create(index, size_, type_); } @@ -81,7 +80,7 @@ CPURegister CPURegList::PopHighestIndex() { } int index = CountLeadingZeros(list_, kRegListSizeInBits); index = kRegListSizeInBits - 1 - index; - DCHECK((1 << index) & list_); + DCHECK((1LL << index) & list_); Remove(index); return CPURegister::Create(index, size_, type_); } @@ -110,8 +109,14 @@ CPURegList CPURegList::GetCalleeSavedV(int size) { CPURegList CPURegList::GetCallerSaved(int size) { +#if defined(V8_OS_WIN) + // x18 is reserved as platform register on Windows arm64. + // Registers x0-x17 and lr (x30) are caller-saved. + CPURegList list = CPURegList(CPURegister::kRegister, size, 0, 17); +#else // Registers x0-x18 and lr (x30) are caller-saved. CPURegList list = CPURegList(CPURegister::kRegister, size, 0, 18); +#endif list.Combine(lr); return list; } @@ -144,9 +149,13 @@ CPURegList CPURegList::GetSafepointSavedRegisters() { list.Remove(16); list.Remove(17); +// Don't add x18 to safepoint list on Windows arm64 because it is reserved +// as platform register. +#if !defined(V8_OS_WIN) // Add x18 to the safepoint list, as although it's not in kJSCallerSaved, it // is a caller-saved register according to the procedure call standard. list.Combine(18); +#endif // Add the link register (x30) to the safepoint list. list.Combine(30); @@ -181,29 +190,6 @@ bool RelocInfo::IsInConstantPool() { return instr->IsLdrLiteralX(); } -int RelocInfo::GetDeoptimizationId(Isolate* isolate, DeoptimizeKind kind) { - DCHECK(IsRuntimeEntry(rmode_)); - Instruction* movz_instr = reinterpret_cast<Instruction*>(pc_)->preceding(); - DCHECK(movz_instr->IsMovz()); - uint64_t imm = static_cast<uint64_t>(movz_instr->ImmMoveWide()) - << (16 * movz_instr->ShiftMoveWide()); - DCHECK_LE(imm, INT_MAX); - - return static_cast<int>(imm); -} - -void RelocInfo::set_js_to_wasm_address(Address address, - ICacheFlushMode icache_flush_mode) { - DCHECK_EQ(rmode_, JS_TO_WASM_CALL); - Assembler::set_target_address_at(pc_, constant_pool_, address, - icache_flush_mode); -} - -Address RelocInfo::js_to_wasm_address() const { - DCHECK_EQ(rmode_, JS_TO_WASM_CALL); - return Assembler::target_address_at(pc_, constant_pool_); -} - uint32_t RelocInfo::wasm_call_tag() const { DCHECK(rmode_ == WASM_CALL || rmode_ == WASM_STUB_CALL); Instruction* instr = reinterpret_cast<Instruction*>(pc_); @@ -334,8 +320,7 @@ bool ConstPool::AddSharedEntry(SharedEntryMap& entry_map, uint64_t data, // Constant Pool. bool ConstPool::RecordEntry(intptr_t data, RelocInfo::Mode mode) { - DCHECK(mode != RelocInfo::COMMENT && mode != RelocInfo::CONST_POOL && - mode != RelocInfo::VENEER_POOL && + DCHECK(mode != RelocInfo::CONST_POOL && mode != RelocInfo::VENEER_POOL && mode != RelocInfo::DEOPT_SCRIPT_OFFSET && mode != RelocInfo::DEOPT_INLINING_ID && mode != RelocInfo::DEOPT_REASON && mode != RelocInfo::DEOPT_ID); @@ -506,11 +491,11 @@ MemOperand::PairResult MemOperand::AreConsistentForPair( } // Step two: check that the offsets are contiguous and that the range // is OK for ldp/stp. - if ((operandB.offset() == operandA.offset() + (1 << access_size_log2)) && + if ((operandB.offset() == operandA.offset() + (1LL << access_size_log2)) && is_int7(operandA.offset() >> access_size_log2)) { return kPairAB; } - if ((operandA.offset() == operandB.offset() + (1 << access_size_log2)) && + if ((operandA.offset() == operandB.offset() + (1LL << access_size_log2)) && is_int7(operandB.offset() >> access_size_log2)) { return kPairBA; } @@ -548,9 +533,9 @@ void ConstPool::EmitEntries() { // Assembler -Assembler::Assembler(const AssemblerOptions& options, void* buffer, - int buffer_size) - : AssemblerBase(options, buffer, buffer_size), +Assembler::Assembler(const AssemblerOptions& options, + std::unique_ptr<AssemblerBuffer> buffer) + : AssemblerBase(options, std::move(buffer)), constpool_(this), unresolved_branches_() { const_pool_blocked_nesting_ = 0; @@ -558,7 +543,6 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer, Reset(); } - Assembler::~Assembler() { DCHECK(constpool_.IsEmpty()); DCHECK_EQ(const_pool_blocked_nesting_, 0); @@ -568,15 +552,15 @@ Assembler::~Assembler() { void Assembler::Reset() { #ifdef DEBUG - DCHECK((pc_ >= buffer_) && (pc_ < buffer_ + buffer_size_)); + DCHECK((pc_ >= buffer_start_) && (pc_ < buffer_start_ + buffer_->size())); DCHECK_EQ(const_pool_blocked_nesting_, 0); DCHECK_EQ(veneer_pool_blocked_nesting_, 0); DCHECK(unresolved_branches_.empty()); - memset(buffer_, 0, pc_ - buffer_); + memset(buffer_start_, 0, pc_ - buffer_start_); #endif - pc_ = buffer_; + pc_ = buffer_start_; ReserveCodeTargetSpace(64); - reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); + reloc_info_writer.Reposition(buffer_start_ + buffer_->size(), pc_); constpool_.Clear(); next_constant_pool_check_ = 0; next_veneer_pool_check_ = kMaxInt; @@ -586,7 +570,7 @@ void Assembler::Reset() { void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { DCHECK_IMPLIES(isolate == nullptr, heap_object_requests_.empty()); for (auto& request : heap_object_requests_) { - Address pc = reinterpret_cast<Address>(buffer_) + request.offset(); + Address pc = reinterpret_cast<Address>(buffer_start_) + request.offset(); switch (request.kind()) { case HeapObjectRequest::kHeapNumber: { Handle<HeapObject> object = @@ -594,15 +578,6 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { set_target_address_at(pc, 0 /* unused */, object.address()); break; } - case HeapObjectRequest::kCodeStub: { - request.code_stub()->set_isolate(isolate); - Instruction* instr = reinterpret_cast<Instruction*>(pc); - DCHECK(instr->IsBranchAndLink() || instr->IsUnconditionalBranch()); - DCHECK_EQ(instr->ImmPCOffset() % kInstrSize, 0); - UpdateCodeTarget(instr->ImmPCOffset() >> kInstrSizeLog2, - request.code_stub()->GetCode()); - break; - } case HeapObjectRequest::kStringConstant: { const StringConstantBase* str = request.string(); CHECK_NOT_NULL(str); @@ -619,20 +594,22 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) { CheckConstPool(true, false); DCHECK(constpool_.IsEmpty()); + int code_comments_size = WriteCodeComments(); + AllocateAndInstallRequestedHeapObjects(isolate); // Set up code descriptor. if (desc) { - desc->buffer = reinterpret_cast<byte*>(buffer_); - desc->buffer_size = buffer_size_; + desc->buffer = buffer_start_; + desc->buffer_size = buffer_->size(); desc->instr_size = pc_offset(); - desc->reloc_size = - static_cast<int>((reinterpret_cast<byte*>(buffer_) + buffer_size_) - - reloc_info_writer.pos()); + desc->reloc_size = static_cast<int>((buffer_start_ + desc->buffer_size) - + reloc_info_writer.pos()); desc->origin = this; desc->constant_pool_size = 0; desc->unwinding_info_size = 0; desc->unwinding_info = nullptr; + desc->code_comments_size = code_comments_size; } } @@ -644,6 +621,10 @@ void Assembler::Align(int m) { } } +void Assembler::CodeTargetAlign() { + // Preferred alignment of jump targets on some ARM chips. + Align(8); +} void Assembler::CheckLabelLinkChain(Label const * label) { #ifdef DEBUG @@ -696,7 +677,7 @@ void Assembler::RemoveBranchFromLabelLinkChain(Instruction* branch, label->Unuse(); } else { label->link_to( - static_cast<int>(reinterpret_cast<byte*>(next_link) - buffer_)); + static_cast<int>(reinterpret_cast<byte*>(next_link) - buffer_start_)); } } else if (branch == next_link) { @@ -1116,6 +1097,12 @@ void Assembler::adr(const Register& rd, Label* label) { } +void Assembler::nop(NopMarkerTypes n) { + DCHECK((FIRST_NOP_MARKER <= n) && (n <= LAST_NOP_MARKER)); + mov(Register::XRegFromCode(n), Register::XRegFromCode(n)); +} + + void Assembler::add(const Register& rd, const Register& rn, const Operand& operand) { @@ -1719,13 +1706,6 @@ Operand Operand::EmbeddedNumber(double number) { return result; } -Operand Operand::EmbeddedCode(CodeStub* stub) { - Operand result(0, RelocInfo::CODE_TARGET); - result.heap_object_request_.emplace(stub); - DCHECK(result.IsHeapObjectRequest()); - return result; -} - Operand Operand::EmbeddedStringConstant(const StringConstantBase* str) { Operand result(0, RelocInfo::EMBEDDED_OBJECT); result.heap_object_request_.emplace(str); @@ -3925,7 +3905,7 @@ void Assembler::dcptr(Label* label) { // In this case, label->pos() returns the offset of the label from the // start of the buffer. internal_reference_positions_.push_back(pc_offset()); - dc64(reinterpret_cast<uintptr_t>(buffer_ + label->pos())); + dc64(reinterpret_cast<uintptr_t>(buffer_start_ + label->pos())); } else { int32_t offset; if (label->is_linked()) { @@ -4002,16 +3982,16 @@ void Assembler::MoveWide(const Register& rd, uint64_t imm, int shift, // Calculate a new immediate and shift combination to encode the immediate // argument. shift = 0; - if ((imm & ~0xFFFFUL) == 0) { + if ((imm & ~0xFFFFULL) == 0) { // Nothing to do. - } else if ((imm & ~(0xFFFFUL << 16)) == 0) { + } else if ((imm & ~(0xFFFFULL << 16)) == 0) { imm >>= 16; shift = 1; - } else if ((imm & ~(0xFFFFUL << 32)) == 0) { + } else if ((imm & ~(0xFFFFULL << 32)) == 0) { DCHECK(rd.Is64Bits()); imm >>= 32; shift = 2; - } else if ((imm & ~(0xFFFFUL << 48)) == 0) { + } else if ((imm & ~(0xFFFFULL << 48)) == 0) { DCHECK(rd.Is64Bits()); imm >>= 48; shift = 3; @@ -4710,45 +4690,33 @@ bool Assembler::IsImmFP64(double imm) { void Assembler::GrowBuffer() { - if (!own_buffer_) FATAL("external code buffer is too small"); - // Compute new buffer size. - CodeDesc desc; // the new buffer - if (buffer_size_ < 1 * MB) { - desc.buffer_size = 2 * buffer_size_; - } else { - desc.buffer_size = buffer_size_ + 1 * MB; - } + int old_size = buffer_->size(); + int new_size = std::min(2 * old_size, old_size + 1 * MB); // Some internal data structures overflow for very large buffers, // they must ensure that kMaximalBufferSize is not too large. - if (desc.buffer_size > kMaximalBufferSize) { + if (new_size > kMaximalBufferSize) { V8::FatalProcessOutOfMemory(nullptr, "Assembler::GrowBuffer"); } - byte* buffer = reinterpret_cast<byte*>(buffer_); - // Set up new buffer. - desc.buffer = NewArray<byte>(desc.buffer_size); - desc.origin = this; - - desc.instr_size = pc_offset(); - desc.reloc_size = - static_cast<int>((buffer + buffer_size_) - reloc_info_writer.pos()); + std::unique_ptr<AssemblerBuffer> new_buffer = buffer_->Grow(new_size); + DCHECK_EQ(new_size, new_buffer->size()); + byte* new_start = new_buffer->start(); // Copy the data. - intptr_t pc_delta = desc.buffer - buffer; - intptr_t rc_delta = (desc.buffer + desc.buffer_size) - - (buffer + buffer_size_); - memmove(desc.buffer, buffer, desc.instr_size); - memmove(reloc_info_writer.pos() + rc_delta, - reloc_info_writer.pos(), desc.reloc_size); + intptr_t pc_delta = new_start - buffer_start_; + intptr_t rc_delta = (new_start + new_size) - (buffer_start_ + old_size); + size_t reloc_size = (buffer_start_ + old_size) - reloc_info_writer.pos(); + memmove(new_start, buffer_start_, pc_offset()); + memmove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(), + reloc_size); // Switch buffers. - DeleteArray(buffer_); - buffer_ = desc.buffer; - buffer_size_ = desc.buffer_size; - pc_ = pc_ + pc_delta; + buffer_ = std::move(new_buffer); + buffer_start_ = new_start; + pc_ += pc_delta; reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, reloc_info_writer.last_pc() + pc_delta); @@ -4758,7 +4726,7 @@ void Assembler::GrowBuffer() { // Relocate internal references. for (auto pos : internal_reference_positions_) { - intptr_t* p = reinterpret_cast<intptr_t*>(buffer_ + pos); + intptr_t* p = reinterpret_cast<intptr_t*>(buffer_start_ + pos); *p += pc_delta; } @@ -4767,15 +4735,14 @@ void Assembler::GrowBuffer() { void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data, ConstantPoolMode constant_pool_mode) { - if ((rmode == RelocInfo::COMMENT) || - (rmode == RelocInfo::INTERNAL_REFERENCE) || + if ((rmode == RelocInfo::INTERNAL_REFERENCE) || (rmode == RelocInfo::CONST_POOL) || (rmode == RelocInfo::VENEER_POOL) || (rmode == RelocInfo::DEOPT_SCRIPT_OFFSET) || (rmode == RelocInfo::DEOPT_INLINING_ID) || (rmode == RelocInfo::DEOPT_REASON) || (rmode == RelocInfo::DEOPT_ID)) { // Adjust code for new modes. - DCHECK(RelocInfo::IsComment(rmode) || RelocInfo::IsDeoptReason(rmode) || - RelocInfo::IsDeoptId(rmode) || RelocInfo::IsDeoptPosition(rmode) || + DCHECK(RelocInfo::IsDeoptReason(rmode) || RelocInfo::IsDeoptId(rmode) || + RelocInfo::IsDeoptPosition(rmode) || RelocInfo::IsInternalReference(rmode) || RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode)); // These modes do not need an entry in the constant pool. @@ -4792,7 +4759,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data, if (!ShouldRecordRelocInfo(rmode)) return; // We do not try to reuse pool constants. - RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, nullptr); + RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, Code()); DCHECK_GE(buffer_space(), kMaxRelocSize); // too late to grow buffer here reloc_info_writer.Write(&rinfo); @@ -4894,8 +4861,8 @@ bool Assembler::ShouldEmitVeneer(int max_reachable_pc, int margin) { void Assembler::RecordVeneerPool(int location_offset, int size) { - RelocInfo rinfo(reinterpret_cast<Address>(buffer_) + location_offset, - RelocInfo::VENEER_POOL, static_cast<intptr_t>(size), nullptr); + RelocInfo rinfo(reinterpret_cast<Address>(buffer_start_) + location_offset, + RelocInfo::VENEER_POOL, static_cast<intptr_t>(size), Code()); reloc_info_writer.Write(&rinfo); } |