aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/arm64/assembler-arm64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/arm64/assembler-arm64.cc')
-rw-r--r--deps/v8/src/arm64/assembler-arm64.cc169
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);
}