diff options
Diffstat (limited to 'deps/v8/src/x64/macro-assembler-x64.cc')
-rw-r--r-- | deps/v8/src/x64/macro-assembler-x64.cc | 229 |
1 files changed, 171 insertions, 58 deletions
diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc index 74e3fcc33a..69abc5454f 100644 --- a/deps/v8/src/x64/macro-assembler-x64.cc +++ b/deps/v8/src/x64/macro-assembler-x64.cc @@ -285,16 +285,17 @@ void MacroAssembler::InNewSpace(Register object, cmpq(scratch, kScratchRegister); j(cc, branch, distance); } else { - ASSERT(is_int32(static_cast<int64_t>(HEAP->NewSpaceMask()))); + ASSERT(is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask()))); intptr_t new_space_start = - reinterpret_cast<intptr_t>(HEAP->NewSpaceStart()); + reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart()); movq(kScratchRegister, -new_space_start, RelocInfo::NONE64); if (scratch.is(object)) { addq(scratch, kScratchRegister); } else { lea(scratch, Operand(object, kScratchRegister, times_1, 0)); } - and_(scratch, Immediate(static_cast<int32_t>(HEAP->NewSpaceMask()))); + and_(scratch, + Immediate(static_cast<int32_t>(isolate()->heap()->NewSpaceMask()))); j(cc, branch, distance); } } @@ -524,7 +525,13 @@ void MacroAssembler::Abort(BailoutReason reason) { RecordComment("Abort message: "); RecordComment(msg); } + + if (FLAG_trap_on_abort) { + int3(); + return; + } #endif + push(rax); movq(kScratchRegister, p0, RelocInfo::NONE64); push(kScratchRegister); @@ -679,22 +686,8 @@ static int Offset(ExternalReference ref0, ExternalReference ref1) { } -void MacroAssembler::PrepareCallApiFunction(int arg_stack_space, - bool returns_handle) { -#if defined(_WIN64) && !defined(__MINGW64__) - if (!returns_handle) { - EnterApiExitFrame(arg_stack_space); - return; - } - // We need to prepare a slot for result handle on stack and put - // a pointer to it into 1st arg register. - EnterApiExitFrame(arg_stack_space + 1); - - // rcx must be used to pass the pointer to the return value slot. - lea(rcx, StackSpaceOperand(arg_stack_space)); -#else +void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { EnterApiExitFrame(arg_stack_space); -#endif } @@ -702,7 +695,6 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address, Address thunk_address, Register thunk_last_arg, int stack_space, - bool returns_handle, int return_value_offset) { Label prologue; Label promote_scheduled_exception; @@ -775,23 +767,6 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address, PopSafepointRegisters(); } - // Can skip the result check for new-style callbacks - // TODO(dcarney): may need to pass this information down - // as some function_addresses might not have been registered - if (returns_handle) { - Label empty_result; -#if defined(_WIN64) && !defined(__MINGW64__) - // rax keeps a pointer to v8::Handle, unpack it. - movq(rax, Operand(rax, 0)); -#endif - // Check if the result handle holds 0. - testq(rax, rax); - j(zero, &empty_result); - // It was non-zero. Dereference to get the result value. - movq(rax, Operand(rax, 0)); - jmp(&prologue); - bind(&empty_result); - } // Load the value from ReturnValue movq(rax, Operand(rbp, return_value_offset * kPointerSize)); bind(&prologue); @@ -984,7 +959,10 @@ void MacroAssembler::Set(const Operand& dst, int64_t x) { } -bool MacroAssembler::IsUnsafeInt(const int x) { +// ---------------------------------------------------------------------------- +// Smi tagging, untagging and tag detection. + +bool MacroAssembler::IsUnsafeInt(const int32_t x) { static const int kMaxBits = 17; return !is_intn(x, kMaxBits); } @@ -992,7 +970,7 @@ bool MacroAssembler::IsUnsafeInt(const int x) { void MacroAssembler::SafeMove(Register dst, Smi* src) { ASSERT(!dst.is(kScratchRegister)); - ASSERT(kSmiValueSize == 32); // JIT cookie can be converted to Smi. + ASSERT(SmiValuesAre32Bits()); // JIT cookie can be converted to Smi. if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { Move(dst, Smi::FromInt(src->value() ^ jit_cookie())); Move(kScratchRegister, Smi::FromInt(jit_cookie())); @@ -1004,7 +982,7 @@ void MacroAssembler::SafeMove(Register dst, Smi* src) { void MacroAssembler::SafePush(Smi* src) { - ASSERT(kSmiValueSize == 32); // JIT cookie can be converted to Smi. + ASSERT(SmiValuesAre32Bits()); // JIT cookie can be converted to Smi. if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { Push(Smi::FromInt(src->value() ^ jit_cookie())); Move(kScratchRegister, Smi::FromInt(jit_cookie())); @@ -1015,9 +993,6 @@ void MacroAssembler::SafePush(Smi* src) { } -// ---------------------------------------------------------------------------- -// Smi tagging, untagging and tag detection. - Register MacroAssembler::GetSmiConstant(Smi* source) { int value = source->value(); if (value == 0) { @@ -2222,6 +2197,49 @@ void MacroAssembler::AddSmiField(Register dst, const Operand& src) { } +void MacroAssembler::Push(Smi* source) { + intptr_t smi = reinterpret_cast<intptr_t>(source); + if (is_int32(smi)) { + push(Immediate(static_cast<int32_t>(smi))); + } else { + Register constant = GetSmiConstant(source); + push(constant); + } +} + + +void MacroAssembler::PushInt64AsTwoSmis(Register src, Register scratch) { + movq(scratch, src); + // High bits. + shr(src, Immediate(64 - kSmiShift)); + shl(src, Immediate(kSmiShift)); + push(src); + // Low bits. + shl(scratch, Immediate(kSmiShift)); + push(scratch); +} + + +void MacroAssembler::PopInt64AsTwoSmis(Register dst, Register scratch) { + pop(scratch); + // Low bits. + shr(scratch, Immediate(kSmiShift)); + pop(dst); + shr(dst, Immediate(kSmiShift)); + // High bits. + shl(dst, Immediate(64 - kSmiShift)); + or_(dst, scratch); +} + + +void MacroAssembler::Test(const Operand& src, Smi* source) { + testl(Operand(src, kIntSize), Immediate(source->value())); +} + + +// ---------------------------------------------------------------------------- + + void MacroAssembler::JumpIfNotString(Register object, Register object_map, Label* not_string, @@ -2461,17 +2479,6 @@ void MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) { } -void MacroAssembler::Push(Smi* source) { - intptr_t smi = reinterpret_cast<intptr_t>(source); - if (is_int32(smi)) { - push(Immediate(static_cast<int32_t>(smi))); - } else { - Register constant = GetSmiConstant(source); - push(constant); - } -} - - void MacroAssembler::Drop(int stack_elements) { if (stack_elements > 0) { addq(rsp, Immediate(stack_elements * kPointerSize)); @@ -2479,11 +2486,6 @@ void MacroAssembler::Drop(int stack_elements) { } -void MacroAssembler::Test(const Operand& src, Smi* source) { - testl(Operand(src, kIntSize), Immediate(source->value())); -} - - void MacroAssembler::TestBit(const Operand& src, int bits) { int byte_offset = bits / kBitsPerByte; int bit_in_byte = bits & (kBitsPerByte - 1); @@ -2991,6 +2993,117 @@ void MacroAssembler::LoadUint32(XMMRegister dst, } +void MacroAssembler::SlowTruncateToI(Register result_reg, + Register input_reg, + int offset) { + DoubleToIStub stub(input_reg, result_reg, offset, true); + call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); +} + + +void MacroAssembler::TruncateHeapNumberToI(Register result_reg, + Register input_reg) { + Label done; + movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); + cvttsd2siq(result_reg, xmm0); + Set(kScratchRegister, V8_UINT64_C(0x8000000000000000)); + cmpq(result_reg, kScratchRegister); + j(not_equal, &done, Label::kNear); + + // Slow case. + if (input_reg.is(result_reg)) { + subq(rsp, Immediate(kDoubleSize)); + movsd(MemOperand(rsp, 0), xmm0); + SlowTruncateToI(result_reg, rsp, 0); + addq(rsp, Immediate(kDoubleSize)); + } else { + SlowTruncateToI(result_reg, input_reg); + } + + bind(&done); +} + + +void MacroAssembler::TruncateDoubleToI(Register result_reg, + XMMRegister input_reg) { + Label done; + cvttsd2siq(result_reg, input_reg); + movq(kScratchRegister, + V8_INT64_C(0x8000000000000000), + RelocInfo::NONE64); + cmpq(result_reg, kScratchRegister); + j(not_equal, &done, Label::kNear); + + subq(rsp, Immediate(kDoubleSize)); + movsd(MemOperand(rsp, 0), input_reg); + SlowTruncateToI(result_reg, rsp, 0); + addq(rsp, Immediate(kDoubleSize)); + + bind(&done); +} + + +void MacroAssembler::DoubleToI(Register result_reg, + XMMRegister input_reg, + XMMRegister scratch, + MinusZeroMode minus_zero_mode, + Label* conversion_failed, + Label::Distance dst) { + cvttsd2si(result_reg, input_reg); + cvtlsi2sd(xmm0, result_reg); + ucomisd(xmm0, input_reg); + j(not_equal, conversion_failed, dst); + j(parity_even, conversion_failed, dst); // NaN. + if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { + Label done; + // The integer converted back is equal to the original. We + // only have to test if we got -0 as an input. + testl(result_reg, result_reg); + j(not_zero, &done, Label::kNear); + movmskpd(result_reg, input_reg); + // Bit 0 contains the sign of the double in input_reg. + // If input was positive, we are ok and return 0, otherwise + // jump to conversion_failed. + andl(result_reg, Immediate(1)); + j(not_zero, conversion_failed, dst); + bind(&done); + } +} + + +void MacroAssembler::TaggedToI(Register result_reg, + Register input_reg, + XMMRegister temp, + MinusZeroMode minus_zero_mode, + Label* lost_precision, + Label::Distance dst) { + Label done; + ASSERT(!temp.is(xmm0)); + + // Heap number map check. + CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), + Heap::kHeapNumberMapRootIndex); + j(not_equal, lost_precision, dst); + + movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); + cvttsd2si(result_reg, xmm0); + cvtlsi2sd(temp, result_reg); + ucomisd(xmm0, temp); + RecordComment("Deferred TaggedToI: lost precision"); + j(not_equal, lost_precision, dst); + RecordComment("Deferred TaggedToI: NaN"); + j(parity_even, lost_precision, dst); // NaN. + if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { + testl(result_reg, result_reg); + j(not_zero, &done, Label::kNear); + movmskpd(result_reg, xmm0); + andl(result_reg, Immediate(1)); + j(not_zero, lost_precision, dst); + } + bind(&done); +} + + void MacroAssembler::LoadInstanceDescriptors(Register map, Register descriptors) { movq(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); |