summaryrefslogtreecommitdiff
path: root/deps/v8/src/x64/macro-assembler-x64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/x64/macro-assembler-x64.cc')
-rw-r--r--deps/v8/src/x64/macro-assembler-x64.cc692
1 files changed, 168 insertions, 524 deletions
diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc
index d92fe983a6..4255e583e3 100644
--- a/deps/v8/src/x64/macro-assembler-x64.cc
+++ b/deps/v8/src/x64/macro-assembler-x64.cc
@@ -8,6 +8,7 @@
#include "src/base/division-by-constant.h"
#include "src/base/utils/random-number-generator.h"
#include "src/bootstrapper.h"
+#include "src/callable.h"
#include "src/codegen.h"
#include "src/counters.h"
#include "src/debug/debug.h"
@@ -27,6 +28,15 @@ MacroAssembler::MacroAssembler(Isolate* isolate, void* buffer, int size,
CodeObjectRequired create_code_object)
: TurboAssembler(isolate, buffer, size, create_code_object) {}
+TurboAssembler::TurboAssembler(Isolate* isolate, void* buffer, int buffer_size,
+ CodeObjectRequired create_code_object)
+ : Assembler(isolate, buffer, buffer_size), isolate_(isolate) {
+ if (create_code_object == CodeObjectRequired::kYes) {
+ code_object_ =
+ Handle<HeapObject>::New(isolate->heap()->undefined_value(), isolate);
+ }
+}
+
static const int64_t kInvalidRootRegisterDelta = -1;
int64_t TurboAssembler::RootRegisterDelta(ExternalReference other) {
@@ -76,7 +86,7 @@ void MacroAssembler::Load(Register destination, ExternalReference source) {
}
}
// Safe code.
- if (destination.is(rax)) {
+ if (destination == rax) {
load_rax(source);
} else {
Move(kScratchRegister, source);
@@ -94,7 +104,7 @@ void MacroAssembler::Store(ExternalReference destination, Register source) {
}
}
// Safe code.
- if (source.is(rax)) {
+ if (source == rax) {
store_rax(destination);
} else {
Move(kScratchRegister, destination);
@@ -155,17 +165,6 @@ void TurboAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
(index << kPointerSizeLog2) - kRootRegisterBias));
}
-void MacroAssembler::LoadRootIndexed(Register destination,
- Register variable_offset,
- int fixed_offset) {
- DCHECK(root_array_available_);
- movp(destination,
- Operand(kRootRegister,
- variable_offset, times_pointer_size,
- (fixed_offset << kPointerSizeLog2) - kRootRegisterBias));
-}
-
-
void MacroAssembler::PushRoot(Heap::RootListIndex index) {
DCHECK(root_array_available_);
Push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias));
@@ -185,12 +184,9 @@ void TurboAssembler::CompareRoot(const Operand& with,
cmpp(with, kScratchRegister);
}
-
void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
- Register addr,
- Register scratch,
- SaveFPRegsMode save_fp,
- RememberedSetFinalAction and_then) {
+ Register addr, Register scratch,
+ SaveFPRegsMode save_fp) {
if (emit_debug_code()) {
Label ok;
JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear);
@@ -200,7 +196,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
// Load store buffer top.
ExternalReference store_buffer =
ExternalReference::store_buffer_top(isolate());
- DCHECK(!scratch.is(kScratchRegister));
+ DCHECK(scratch != kScratchRegister);
Move(kScratchRegister, store_buffer);
movp(scratch, Operand(kScratchRegister, 0));
// Store pointer to buffer.
@@ -213,23 +209,13 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
Label done;
// Check for end of buffer.
testp(scratch, Immediate(StoreBuffer::kStoreBufferMask));
- if (and_then == kReturnAtEnd) {
- Label buffer_overflowed;
- j(equal, &buffer_overflowed, Label::kNear);
- ret(0);
- bind(&buffer_overflowed);
- } else {
- DCHECK(and_then == kFallThroughAtEnd);
- j(not_equal, &done, Label::kNear);
- }
+ Label buffer_overflowed;
+ j(equal, &buffer_overflowed, Label::kNear);
+ ret(0);
+ bind(&buffer_overflowed);
StoreBufferOverflowStub store_buffer_overflow(isolate(), save_fp);
CallStub(&store_buffer_overflow);
- if (and_then == kReturnAtEnd) {
- ret(0);
- } else {
- DCHECK(and_then == kFallThroughAtEnd);
- bind(&done);
- }
+ ret(0);
}
@@ -242,16 +228,11 @@ void MacroAssembler::InNewSpace(Register object,
distance);
}
-
-void MacroAssembler::RecordWriteField(
- Register object,
- int offset,
- Register value,
- Register dst,
- SaveFPRegsMode save_fp,
- RememberedSetAction remembered_set_action,
- SmiCheck smi_check,
- PointersToHereCheck pointers_to_here_check_for_value) {
+void MacroAssembler::RecordWriteField(Register object, int offset,
+ Register value, Register dst,
+ SaveFPRegsMode save_fp,
+ RememberedSetAction remembered_set_action,
+ SmiCheck smi_check) {
// First, check if a write barrier is even needed. The tests below
// catch stores of Smis.
Label done;
@@ -275,7 +256,7 @@ void MacroAssembler::RecordWriteField(
}
RecordWrite(object, dst, value, save_fp, remembered_set_action,
- OMIT_SMI_CHECK, pointers_to_here_check_for_value);
+ OMIT_SMI_CHECK);
bind(&done);
@@ -287,89 +268,65 @@ void MacroAssembler::RecordWriteField(
}
}
-
-void MacroAssembler::RecordWriteForMap(Register object,
- Register map,
- Register dst,
- SaveFPRegsMode fp_mode) {
- DCHECK(!object.is(kScratchRegister));
- DCHECK(!object.is(map));
- DCHECK(!object.is(dst));
- DCHECK(!map.is(dst));
- AssertNotSmi(object);
-
- if (emit_debug_code()) {
- Label ok;
- if (map.is(kScratchRegister)) pushq(map);
- CompareMap(map, isolate()->factory()->meta_map());
- if (map.is(kScratchRegister)) popq(map);
- j(equal, &ok, Label::kNear);
- int3();
- bind(&ok);
- }
-
- if (!FLAG_incremental_marking) {
- return;
+void TurboAssembler::SaveRegisters(RegList registers) {
+ DCHECK(NumRegs(registers) > 0);
+ for (int i = 0; i < Register::kNumRegisters; ++i) {
+ if ((registers >> i) & 1u) {
+ pushq(Register::from_code(i));
+ }
}
+}
- if (emit_debug_code()) {
- Label ok;
- if (map.is(kScratchRegister)) pushq(map);
- cmpp(map, FieldOperand(object, HeapObject::kMapOffset));
- if (map.is(kScratchRegister)) popq(map);
- j(equal, &ok, Label::kNear);
- int3();
- bind(&ok);
+void TurboAssembler::RestoreRegisters(RegList registers) {
+ DCHECK(NumRegs(registers) > 0);
+ for (int i = Register::kNumRegisters - 1; i >= 0; --i) {
+ if ((registers >> i) & 1u) {
+ popq(Register::from_code(i));
+ }
}
+}
- // Compute the address.
- leap(dst, FieldOperand(object, HeapObject::kMapOffset));
+void TurboAssembler::CallRecordWriteStub(
+ Register object, Register address,
+ RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
+ Callable const callable =
+ Builtins::CallableFor(isolate(), Builtins::kRecordWrite);
+ RegList registers = callable.descriptor().allocatable_registers();
- // First, check if a write barrier is even needed. The tests below
- // catch stores of smis and stores into the young generation.
- Label done;
+ SaveRegisters(registers);
- // A single check of the map's pages interesting flag suffices, since it is
- // only set during incremental collection, and then it's also guaranteed that
- // the from object's page's interesting flag is also set. This optimization
- // relies on the fact that maps can never be in new space.
- CheckPageFlag(map,
- map, // Used as scratch.
- MemoryChunk::kPointersToHereAreInterestingMask,
- zero,
- &done,
- Label::kNear);
+ Register object_parameter(callable.descriptor().GetRegisterParameter(
+ RecordWriteDescriptor::kObject));
+ Register slot_parameter(
+ callable.descriptor().GetRegisterParameter(RecordWriteDescriptor::kSlot));
+ Register isolate_parameter(callable.descriptor().GetRegisterParameter(
+ RecordWriteDescriptor::kIsolate));
+ Register remembered_set_parameter(callable.descriptor().GetRegisterParameter(
+ RecordWriteDescriptor::kRememberedSet));
+ Register fp_mode_parameter(callable.descriptor().GetRegisterParameter(
+ RecordWriteDescriptor::kFPMode));
- RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET,
- fp_mode);
- CallStub(&stub);
+ pushq(object);
+ pushq(address);
- bind(&done);
+ popq(slot_parameter);
+ popq(object_parameter);
- // Count number of write barriers in generated code.
- isolate()->counters()->write_barriers_static()->Increment();
- IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
+ LoadAddress(isolate_parameter, ExternalReference::isolate_address(isolate()));
+ Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
+ Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
+ Call(callable.code(), RelocInfo::CODE_TARGET);
- // Clobber clobbered registers when running with the debug-code flag
- // turned on to provoke errors.
- if (emit_debug_code()) {
- Move(dst, kZapValue, Assembler::RelocInfoNone());
- Move(map, kZapValue, Assembler::RelocInfoNone());
- }
+ RestoreRegisters(registers);
}
-
-void MacroAssembler::RecordWrite(
- Register object,
- Register address,
- Register value,
- SaveFPRegsMode fp_mode,
- RememberedSetAction remembered_set_action,
- SmiCheck smi_check,
- PointersToHereCheck pointers_to_here_check_for_value) {
- DCHECK(!object.is(value));
- DCHECK(!object.is(address));
- DCHECK(!value.is(address));
+void MacroAssembler::RecordWrite(Register object, Register address,
+ Register value, SaveFPRegsMode fp_mode,
+ RememberedSetAction remembered_set_action,
+ SmiCheck smi_check) {
+ DCHECK(object != value);
+ DCHECK(object != address);
+ DCHECK(value != address);
AssertNotSmi(object);
if (remembered_set_action == OMIT_REMEMBERED_SET &&
@@ -394,14 +351,10 @@ void MacroAssembler::RecordWrite(
JumpIfSmi(value, &done);
}
- if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) {
- CheckPageFlag(value,
- value, // Used as scratch.
- MemoryChunk::kPointersToHereAreInterestingMask,
- zero,
- &done,
- Label::kNear);
- }
+ CheckPageFlag(value,
+ value, // Used as scratch.
+ MemoryChunk::kPointersToHereAreInterestingMask, zero, &done,
+ Label::kNear);
CheckPageFlag(object,
value, // Used as scratch.
@@ -410,9 +363,13 @@ void MacroAssembler::RecordWrite(
&done,
Label::kNear);
+#ifdef V8_CSA_WRITE_BARRIER
+ CallRecordWriteStub(object, address, remembered_set_action, fp_mode);
+#else
RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
fp_mode);
CallStub(&stub);
+#endif
bind(&done);
@@ -563,55 +520,81 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
}
-#define REG(Name) \
- { Register::kCode_##Name }
+static constexpr Register saved_regs[] = {rax, rcx, rdx, rbx, rbp, rsi,
+ rdi, r8, r9, r10, r11};
-static const Register saved_regs[] = {
- REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8),
- REG(r9), REG(r10), REG(r11)
-};
+static constexpr int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register);
-#undef REG
+int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
+ Register exclusion1,
+ Register exclusion2,
+ Register exclusion3) const {
+ int bytes = 0;
+ for (int i = 0; i < kNumberOfSavedRegs; i++) {
+ Register reg = saved_regs[i];
+ if (reg != exclusion1 && reg != exclusion2 && reg != exclusion3) {
+ bytes += kPointerSize;
+ }
+ }
-static const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register);
+ // R12 to r15 are callee save on all platforms.
+ if (fp_mode == kSaveFPRegs) {
+ bytes += kDoubleSize * XMMRegister::kNumRegisters;
+ }
-void TurboAssembler::PushCallerSaved(SaveFPRegsMode fp_mode,
- Register exclusion1, Register exclusion2,
- Register exclusion3) {
+ return bytes;
+}
+
+int TurboAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
+ Register exclusion2, Register exclusion3) {
// We don't allow a GC during a store buffer overflow so there is no need to
// store the registers in any particular way, but we do have to store and
// restore them.
+ int bytes = 0;
for (int i = 0; i < kNumberOfSavedRegs; i++) {
Register reg = saved_regs[i];
- if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
+ if (reg != exclusion1 && reg != exclusion2 && reg != exclusion3) {
pushq(reg);
+ bytes += kPointerSize;
}
}
+
// R12 to r15 are callee save on all platforms.
if (fp_mode == kSaveFPRegs) {
- subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
- for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
+ int delta = kDoubleSize * XMMRegister::kNumRegisters;
+ subp(rsp, Immediate(delta));
+ for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
XMMRegister reg = XMMRegister::from_code(i);
Movsd(Operand(rsp, i * kDoubleSize), reg);
}
+ bytes += delta;
}
+
+ return bytes;
}
-void TurboAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
- Register exclusion2, Register exclusion3) {
+int TurboAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
+ Register exclusion2, Register exclusion3) {
+ int bytes = 0;
if (fp_mode == kSaveFPRegs) {
- for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
+ for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
XMMRegister reg = XMMRegister::from_code(i);
Movsd(reg, Operand(rsp, i * kDoubleSize));
}
- addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
+ int delta = kDoubleSize * XMMRegister::kNumRegisters;
+ addp(rsp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
+ bytes += delta;
}
+
for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) {
Register reg = saved_regs[i];
- if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
+ if (reg != exclusion1 && reg != exclusion2 && reg != exclusion3) {
popq(reg);
+ bytes += kPointerSize;
}
}
+
+ return bytes;
}
void TurboAssembler::Cvtss2sd(XMMRegister dst, XMMRegister src) {
@@ -934,7 +917,7 @@ void TurboAssembler::Move(Register dst, Smi* source) {
void MacroAssembler::Integer32ToSmi(Register dst, Register src) {
STATIC_ASSERT(kSmiTag == 0);
- if (!dst.is(src)) {
+ if (dst != src) {
movl(dst, src);
}
shlp(dst, Immediate(kSmiShift));
@@ -942,7 +925,7 @@ void MacroAssembler::Integer32ToSmi(Register dst, Register src) {
void TurboAssembler::SmiToInteger32(Register dst, Register src) {
STATIC_ASSERT(kSmiTag == 0);
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
@@ -967,7 +950,7 @@ void TurboAssembler::SmiToInteger32(Register dst, const Operand& src) {
void MacroAssembler::SmiToInteger64(Register dst, Register src) {
STATIC_ASSERT(kSmiTag == 0);
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
sarp(dst, Immediate(kSmiShift));
@@ -1009,7 +992,7 @@ void MacroAssembler::SmiCompare(Register dst, Smi* src) {
void MacroAssembler::Cmp(Register dst, Smi* src) {
- DCHECK(!dst.is(kScratchRegister));
+ DCHECK(dst != kScratchRegister);
if (src->value() == 0) {
testp(dst, dst);
} else {
@@ -1061,7 +1044,7 @@ void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
SmiToInteger64(dst, src);
return;
}
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
if (power < kSmiShift) {
@@ -1083,41 +1066,6 @@ Condition TurboAssembler::CheckSmi(const Operand& src) {
return zero;
}
-Condition MacroAssembler::CheckBothSmi(Register first, Register second) {
- if (first.is(second)) {
- return CheckSmi(first);
- }
- STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3);
- if (SmiValuesAre32Bits()) {
- leal(kScratchRegister, Operand(first, second, times_1, 0));
- testb(kScratchRegister, Immediate(0x03));
- } else {
- DCHECK(SmiValuesAre31Bits());
- movl(kScratchRegister, first);
- orl(kScratchRegister, second);
- testb(kScratchRegister, Immediate(kSmiTagMask));
- }
- return zero;
-}
-
-Condition MacroAssembler::CheckEitherSmi(Register first,
- Register second,
- Register scratch) {
- if (first.is(second)) {
- return CheckSmi(first);
- }
- if (scratch.is(second)) {
- andl(scratch, first);
- } else {
- if (!scratch.is(first)) {
- movl(scratch, first);
- }
- andl(scratch, second);
- }
- testb(scratch, Immediate(kSmiTagMask));
- return zero;
-}
-
void TurboAssembler::JumpIfSmi(Register src, Label* on_smi,
Label::Distance near_jump) {
Condition smi = CheckSmi(src);
@@ -1138,22 +1086,14 @@ void MacroAssembler::JumpIfNotSmi(Operand src, Label* on_not_smi,
j(NegateCondition(smi), on_not_smi, near_jump);
}
-void MacroAssembler::JumpIfNotBothSmi(Register src1,
- Register src2,
- Label* on_not_both_smi,
- Label::Distance near_jump) {
- Condition both_smi = CheckBothSmi(src1, src2);
- j(NegateCondition(both_smi), on_not_both_smi, near_jump);
-}
-
void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) {
if (constant->value() == 0) {
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
return;
- } else if (dst.is(src)) {
- DCHECK(!dst.is(kScratchRegister));
+ } else if (dst == src) {
+ DCHECK(dst != kScratchRegister);
Register constant_reg = GetSmiConstant(constant);
addp(dst, constant_reg);
} else {
@@ -1180,11 +1120,11 @@ void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant,
Label* bailout_label,
Label::Distance near_jump) {
if (constant->value() == 0) {
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
- } else if (dst.is(src)) {
- DCHECK(!dst.is(kScratchRegister));
+ } else if (dst == src) {
+ DCHECK(dst != kScratchRegister);
Move(kScratchRegister, constant);
addp(dst, kScratchRegister);
if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) {
@@ -1216,11 +1156,11 @@ void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant,
void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) {
if (constant->value() == 0) {
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
- } else if (dst.is(src)) {
- DCHECK(!dst.is(kScratchRegister));
+ } else if (dst == src) {
+ DCHECK(dst != kScratchRegister);
Register constant_reg = GetSmiConstant(constant);
subp(dst, constant_reg);
} else {
@@ -1242,11 +1182,11 @@ void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant,
Label* bailout_label,
Label::Distance near_jump) {
if (constant->value() == 0) {
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
- } else if (dst.is(src)) {
- DCHECK(!dst.is(kScratchRegister));
+ } else if (dst == src) {
+ DCHECK(dst != kScratchRegister);
Move(kScratchRegister, constant);
subp(dst, kScratchRegister);
if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) {
@@ -1271,7 +1211,7 @@ void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant,
DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister);
DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow);
if (constant->value() == Smi::kMinValue) {
- DCHECK(!dst.is(kScratchRegister));
+ DCHECK(dst != kScratchRegister);
movp(dst, src);
Move(kScratchRegister, constant);
subp(dst, kScratchRegister);
@@ -1292,7 +1232,7 @@ static void SmiAddHelper(MacroAssembler* masm,
T src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
- if (dst.is(src1)) {
+ if (dst == src1) {
Label done;
masm->addp(dst, src2);
masm->j(no_overflow, &done, Label::kNear);
@@ -1314,7 +1254,7 @@ void MacroAssembler::SmiAdd(Register dst,
Label* on_not_smi_result,
Label::Distance near_jump) {
DCHECK_NOT_NULL(on_not_smi_result);
- DCHECK(!dst.is(src2));
+ DCHECK(dst != src2);
SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
}
@@ -1334,7 +1274,7 @@ void MacroAssembler::SmiAdd(Register dst,
Register src2) {
// No overflow checking. Use only when it's known that
// overflowing is impossible.
- if (!dst.is(src1)) {
+ if (dst != src1) {
if (emit_debug_code()) {
movp(kScratchRegister, src1);
addp(kScratchRegister, src2);
@@ -1355,7 +1295,7 @@ static void SmiSubHelper(MacroAssembler* masm,
T src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
- if (dst.is(src1)) {
+ if (dst == src1) {
Label done;
masm->subp(dst, src2);
masm->j(no_overflow, &done, Label::kNear);
@@ -1376,7 +1316,7 @@ void MacroAssembler::SmiSub(Register dst,
Label* on_not_smi_result,
Label::Distance near_jump) {
DCHECK_NOT_NULL(on_not_smi_result);
- DCHECK(!dst.is(src2));
+ DCHECK(dst != src2);
SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
}
@@ -1397,7 +1337,7 @@ static void SmiSubNoOverflowHelper(MacroAssembler* masm,
T src2) {
// No overflow checking. Use only when it's known that
// overflowing is impossible (e.g., subtracting two positive smis).
- if (!dst.is(src1)) {
+ if (dst != src1) {
masm->movp(dst, src1);
}
masm->subp(dst, src2);
@@ -1406,7 +1346,7 @@ static void SmiSubNoOverflowHelper(MacroAssembler* masm,
void MacroAssembler::SmiSub(Register dst, Register src1, Register src2) {
- DCHECK(!dst.is(src2));
+ DCHECK(dst != src2);
SmiSubNoOverflowHelper<Register>(this, dst, src1, src2);
}
@@ -1417,43 +1357,6 @@ void MacroAssembler::SmiSub(Register dst,
SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2);
}
-void MacroAssembler::SelectNonSmi(Register dst,
- Register src1,
- Register src2,
- Label* on_not_smis,
- Label::Distance near_jump) {
- DCHECK(!dst.is(kScratchRegister));
- DCHECK(!src1.is(kScratchRegister));
- DCHECK(!src2.is(kScratchRegister));
- DCHECK(!dst.is(src1));
- DCHECK(!dst.is(src2));
- // Both operands must not be smis.
-#ifdef DEBUG
- Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2));
- Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi);
-#endif
- STATIC_ASSERT(kSmiTag == 0);
- DCHECK_EQ(static_cast<Smi*>(0), Smi::kZero);
- movl(kScratchRegister, Immediate(kSmiTagMask));
- andp(kScratchRegister, src1);
- testl(kScratchRegister, src2);
- // If non-zero then both are smis.
- j(not_zero, on_not_smis, near_jump);
-
- // Exactly one operand is a smi.
- DCHECK_EQ(1, static_cast<int>(kSmiTagMask));
- // kScratchRegister still holds src1 & kSmiTag, which is either zero or one.
- subp(kScratchRegister, Immediate(1));
- // If src1 is a smi, then scratch register all 1s, else it is all 0s.
- movp(dst, src1);
- xorp(dst, src2);
- andp(dst, kScratchRegister);
- // If src1 is a smi, dst holds src1 ^ src2, else it is zero.
- xorp(dst, src1);
- // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi.
-}
-
-
SmiIndex MacroAssembler::SmiToIndex(Register dst,
Register src,
int shift) {
@@ -1461,7 +1364,7 @@ SmiIndex MacroAssembler::SmiToIndex(Register dst,
DCHECK(is_uint6(shift));
// There is a possible optimization if shift is in the range 60-63, but that
// will (and must) never happen.
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
if (shift < kSmiShift) {
@@ -1473,7 +1376,7 @@ SmiIndex MacroAssembler::SmiToIndex(Register dst,
} else {
DCHECK(SmiValuesAre31Bits());
DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1));
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
// We have to sign extend the index register to 64-bit as the SMI might
@@ -1508,64 +1411,6 @@ void TurboAssembler::Push(Smi* source) {
// ----------------------------------------------------------------------------
-void MacroAssembler::JumpIfNotBothSequentialOneByteStrings(
- Register first_object, Register second_object, Register scratch1,
- Register scratch2, Label* on_fail, Label::Distance near_jump) {
- // Check that both objects are not smis.
- Condition either_smi = CheckEitherSmi(first_object, second_object);
- j(either_smi, on_fail, near_jump);
-
- // Load instance type for both strings.
- movp(scratch1, FieldOperand(first_object, HeapObject::kMapOffset));
- movp(scratch2, FieldOperand(second_object, HeapObject::kMapOffset));
- movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset));
- movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset));
-
- // Check that both are flat one-byte strings.
- DCHECK(kNotStringTag != 0);
- const int kFlatOneByteStringMask =
- kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
- const int kFlatOneByteStringTag =
- kStringTag | kOneByteStringTag | kSeqStringTag;
-
- andl(scratch1, Immediate(kFlatOneByteStringMask));
- andl(scratch2, Immediate(kFlatOneByteStringMask));
- // Interleave the bits to check both scratch1 and scratch2 in one test.
- const int kShift = 8;
- DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << kShift));
- shlp(scratch2, Immediate(kShift));
- orp(scratch1, scratch2);
- cmpl(scratch1,
- Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << kShift)));
- j(not_equal, on_fail, near_jump);
-}
-
-void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte(
- Register first_object_instance_type, Register second_object_instance_type,
- Register scratch1, Register scratch2, Label* on_fail,
- Label::Distance near_jump) {
- // Load instance type for both strings.
- movp(scratch1, first_object_instance_type);
- movp(scratch2, second_object_instance_type);
-
- // Check that both are flat one-byte strings.
- DCHECK(kNotStringTag != 0);
- const int kFlatOneByteStringMask =
- kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
- const int kFlatOneByteStringTag =
- kStringTag | kOneByteStringTag | kSeqStringTag;
-
- andl(scratch1, Immediate(kFlatOneByteStringMask));
- andl(scratch2, Immediate(kFlatOneByteStringMask));
- // Interleave the bits to check both scratch1 and scratch2 in one test.
- DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3));
- leap(scratch1, Operand(scratch1, scratch2, times_8, 0));
- cmpl(scratch1,
- Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3)));
- j(not_equal, on_fail, near_jump);
-}
-
-
template<class T>
static void JumpIfNotUniqueNameHelper(MacroAssembler* masm,
T operand_or_register,
@@ -1597,7 +1442,7 @@ void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg,
}
void TurboAssembler::Move(Register dst, Register src) {
- if (!dst.is(src)) {
+ if (dst != src) {
movp(dst, src);
}
}
@@ -2073,7 +1918,7 @@ void MacroAssembler::Pop(const Operand& dst) {
movp(scratch, Operand(rsp, 0));
movp(dst, scratch);
leal(rsp, Operand(rsp, 4));
- if (scratch.is(kRootRegister)) {
+ if (scratch == kRootRegister) {
// Restore kRootRegister.
InitializeRootRegister();
}
@@ -2131,7 +1976,7 @@ void TurboAssembler::Call(ExternalReference ext) {
LoadAddress(kScratchRegister, ext);
call(kScratchRegister);
#ifdef DEBUG
- CHECK_EQ(end_position, pc_offset());
+ DCHECK_EQ(end_position, pc_offset());
#endif
}
@@ -2151,7 +1996,7 @@ void TurboAssembler::Call(Address destination, RelocInfo::Mode rmode) {
Move(kScratchRegister, destination, rmode);
call(kScratchRegister);
#ifdef DEBUG
- CHECK_EQ(pc_offset(), end_position);
+ DCHECK_EQ(pc_offset(), end_position);
#endif
}
@@ -2162,7 +2007,7 @@ void TurboAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
DCHECK(RelocInfo::IsCodeTarget(rmode));
call(code_object, rmode);
#ifdef DEBUG
- CHECK_EQ(end_position, pc_offset());
+ DCHECK_EQ(end_position, pc_offset());
#endif
}
@@ -2474,23 +2319,6 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
Immediate(static_cast<int8_t>(type)));
}
-void MacroAssembler::CompareMap(Register obj, Handle<Map> map) {
- Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
-}
-
-
-void MacroAssembler::CheckMap(Register obj,
- Handle<Map> map,
- Label* fail,
- SmiCheckType smi_check_type) {
- if (smi_check_type == DO_SMI_CHECK) {
- JumpIfSmi(obj, fail);
- }
-
- CompareMap(obj, map);
- j(not_equal, fail);
-}
-
void TurboAssembler::SlowTruncateToIDelayed(Zone* zone, Register result_reg,
Register input_reg, int offset) {
CallStubDelayed(
@@ -2577,7 +2405,7 @@ void MacroAssembler::AssertFixedArray(Register object) {
void TurboAssembler::AssertZeroExtended(Register int32_register) {
if (emit_debug_code()) {
- DCHECK(!int32_register.is(kScratchRegister));
+ DCHECK(int32_register != kScratchRegister);
movq(kScratchRegister, V8_INT64_C(0x0000000100000000));
cmpq(kScratchRegister, int32_register);
Check(above_equal, k32BitValueInRegisterIsNotZeroExtended);
@@ -2657,14 +2485,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
bind(&done);
}
-void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
- if (FLAG_native_code_counters && counter->Enabled()) {
- Operand counter_operand = ExternalOperand(ExternalReference(counter));
- movl(counter_operand, Immediate(value));
- }
-}
-
-
void MacroAssembler::IncrementCounter(StatsCounter* counter, int value) {
DCHECK(value > 0);
if (FLAG_native_code_counters && counter->Enabled()) {
@@ -2787,7 +2607,7 @@ void MacroAssembler::InvokeFunction(Register function, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag) {
- DCHECK(function.is(rdi));
+ DCHECK(function == rdi);
movp(rsi, FieldOperand(function, JSFunction::kContextOffset));
InvokeFunctionCode(rdi, new_target, expected, actual, flag);
}
@@ -2798,8 +2618,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
InvokeFlag flag) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
- DCHECK(function.is(rdi));
- DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx));
+ DCHECK(function == rdi);
+ DCHECK_IMPLIES(new_target.is_valid(), new_target == rdx);
// On function call, call into the debugger if necessary.
CheckDebugHook(function, new_target, expected, actual);
@@ -2863,14 +2683,14 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
Set(rax, actual.immediate());
cmpp(expected.reg(), Immediate(actual.immediate()));
j(equal, &invoke, Label::kNear);
- DCHECK(expected.reg().is(rbx));
- } else if (!expected.reg().is(actual.reg())) {
+ DCHECK(expected.reg() == rbx);
+ } else if (expected.reg() != actual.reg()) {
// Both expected and actual are in (different) registers. This
// is the case when we invoke functions using call and apply.
cmpp(expected.reg(), actual.reg());
j(equal, &invoke, Label::kNear);
- DCHECK(actual.reg().is(rax));
- DCHECK(expected.reg().is(rbx));
+ DCHECK(actual.reg() == rax);
+ DCHECK(expected.reg() == rbx);
} else {
definitely_matches = true;
Move(rax, actual.reg());
@@ -3030,7 +2850,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
#endif
// Optionally save all XMM registers.
if (save_doubles) {
- int space = XMMRegister::kMaxNumRegisters * kDoubleSize +
+ int space = XMMRegister::kNumRegisters * kDoubleSize +
arg_stack_space * kRegisterSize;
subp(rsp, Immediate(space));
int offset = -ExitFrameConstants::kFixedFrameSizeFromFp;
@@ -3135,168 +2955,6 @@ void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) {
}
-void MacroAssembler::LoadAllocationTopHelper(Register result,
- Register scratch,
- AllocationFlags flags) {
- ExternalReference allocation_top =
- AllocationUtils::GetAllocationTopReference(isolate(), flags);
-
- // Just return if allocation top is already known.
- if ((flags & RESULT_CONTAINS_TOP) != 0) {
- // No use of scratch if allocation top is provided.
- DCHECK(!scratch.is_valid());
-#ifdef DEBUG
- // Assert that result actually contains top on entry.
- Operand top_operand = ExternalOperand(allocation_top);
- cmpp(result, top_operand);
- Check(equal, kUnexpectedAllocationTop);
-#endif
- return;
- }
-
- // Move address of new object to result. Use scratch register if available,
- // and keep address in scratch until call to UpdateAllocationTopHelper.
- if (scratch.is_valid()) {
- LoadAddress(scratch, allocation_top);
- movp(result, Operand(scratch, 0));
- } else {
- Load(result, allocation_top);
- }
-}
-
-
-void MacroAssembler::MakeSureDoubleAlignedHelper(Register result,
- Register scratch,
- Label* gc_required,
- AllocationFlags flags) {
- if (kPointerSize == kDoubleSize) {
- if (FLAG_debug_code) {
- testl(result, Immediate(kDoubleAlignmentMask));
- Check(zero, kAllocationIsNotDoubleAligned);
- }
- } else {
- // Align the next allocation. Storing the filler map without checking top
- // is safe in new-space because the limit of the heap is aligned there.
- DCHECK(kPointerSize * 2 == kDoubleSize);
- DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
- // Make sure scratch is not clobbered by this function as it might be
- // used in UpdateAllocationTopHelper later.
- DCHECK(!scratch.is(kScratchRegister));
- Label aligned;
- testl(result, Immediate(kDoubleAlignmentMask));
- j(zero, &aligned, Label::kNear);
- if ((flags & PRETENURE) != 0) {
- ExternalReference allocation_limit =
- AllocationUtils::GetAllocationLimitReference(isolate(), flags);
- cmpp(result, ExternalOperand(allocation_limit));
- j(above_equal, gc_required);
- }
- LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex);
- movp(Operand(result, 0), kScratchRegister);
- addp(result, Immediate(kDoubleSize / 2));
- bind(&aligned);
- }
-}
-
-
-void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
- Register scratch,
- AllocationFlags flags) {
- if (emit_debug_code()) {
- testp(result_end, Immediate(kObjectAlignmentMask));
- Check(zero, kUnalignedAllocationInNewSpace);
- }
-
- ExternalReference allocation_top =
- AllocationUtils::GetAllocationTopReference(isolate(), flags);
-
- // Update new top.
- if (scratch.is_valid()) {
- // Scratch already contains address of allocation top.
- movp(Operand(scratch, 0), result_end);
- } else {
- Store(allocation_top, result_end);
- }
-}
-
-
-void MacroAssembler::Allocate(int object_size,
- Register result,
- Register result_end,
- Register scratch,
- Label* gc_required,
- AllocationFlags flags) {
- DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
- DCHECK(object_size <= kMaxRegularHeapObjectSize);
- if (!FLAG_inline_new) {
- if (emit_debug_code()) {
- // Trash the registers to simulate an allocation failure.
- movl(result, Immediate(0x7091));
- if (result_end.is_valid()) {
- movl(result_end, Immediate(0x7191));
- }
- if (scratch.is_valid()) {
- movl(scratch, Immediate(0x7291));
- }
- }
- jmp(gc_required);
- return;
- }
- DCHECK(!result.is(result_end));
-
- // Load address of new object into result.
- LoadAllocationTopHelper(result, scratch, flags);
-
- if ((flags & DOUBLE_ALIGNMENT) != 0) {
- MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags);
- }
-
- // Calculate new top and bail out if new space is exhausted.
- ExternalReference allocation_limit =
- AllocationUtils::GetAllocationLimitReference(isolate(), flags);
-
- Register top_reg = result_end.is_valid() ? result_end : result;
-
- if (!top_reg.is(result)) {
- movp(top_reg, result);
- }
- addp(top_reg, Immediate(object_size));
- Operand limit_operand = ExternalOperand(allocation_limit);
- cmpp(top_reg, limit_operand);
- j(above, gc_required);
-
- UpdateAllocationTopHelper(top_reg, scratch, flags);
-
- if (top_reg.is(result)) {
- subp(result, Immediate(object_size - kHeapObjectTag));
- } else {
- // Tag the result.
- DCHECK(kHeapObjectTag == 1);
- incp(result);
- }
-}
-
-void MacroAssembler::AllocateJSValue(Register result, Register constructor,
- Register value, Register scratch,
- Label* gc_required) {
- DCHECK(!result.is(constructor));
- DCHECK(!result.is(scratch));
- DCHECK(!result.is(value));
-
- // Allocate JSValue in new space.
- Allocate(JSValue::kSize, result, scratch, no_reg, gc_required,
- NO_ALLOCATION_FLAGS);
-
- // Initialize the JSValue.
- LoadGlobalFunctionInitialMap(constructor, scratch);
- movp(FieldOperand(result, HeapObject::kMapOffset), scratch);
- LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex);
- movp(FieldOperand(result, JSObject::kPropertiesOrHashOffset), scratch);
- movp(FieldOperand(result, JSObject::kElementsOffset), scratch);
- movp(FieldOperand(result, JSValue::kValueOffset), value);
- STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
-}
-
#ifdef _WIN64
static const int kRegisterPassedArguments = 4;
#else
@@ -3310,20 +2968,6 @@ void MacroAssembler::LoadNativeContextSlot(int index, Register dst) {
}
-void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
- Register map) {
- // Load the initial map. The global functions all have initial maps.
- movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
- if (emit_debug_code()) {
- Label ok, fail;
- CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK);
- jmp(&ok);
- bind(&fail);
- Abort(kGlobalFunctionsMustHaveInitialMap);
- bind(&ok);
- }
-}
-
int TurboAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) {
// On Windows 64 stack slots are reserved by the caller for all arguments
// including the ones passed in registers, and space is always allocated for
@@ -3433,7 +3077,7 @@ void TurboAssembler::CheckPageFlag(Register object, Register scratch, int mask,
Condition cc, Label* condition_met,
Label::Distance condition_met_distance) {
DCHECK(cc == zero || cc == not_zero);
- if (scratch.is(object)) {
+ if (scratch == object) {
andp(scratch, Immediate(~Page::kPageAlignmentMask));
} else {
movp(scratch, Immediate(~Page::kPageAlignmentMask));