diff options
Diffstat (limited to 'deps/v8/src/x64/macro-assembler-x64.cc')
-rw-r--r-- | deps/v8/src/x64/macro-assembler-x64.cc | 139 |
1 files changed, 132 insertions, 7 deletions
diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc index 50b689b23f..e7d02d2003 100644 --- a/deps/v8/src/x64/macro-assembler-x64.cc +++ b/deps/v8/src/x64/macro-assembler-x64.cc @@ -1442,10 +1442,17 @@ void MacroAssembler::Pushad() { // r13 is kRootRegister. push(r14); // r15 is kSmiConstantRegister + STATIC_ASSERT(11 == kNumSafepointSavedRegisters); + // Use lea for symmetry with Popad. + lea(rsp, Operand(rsp, + -(kNumSafepointRegisters-kNumSafepointSavedRegisters) * kPointerSize)); } void MacroAssembler::Popad() { + // Popad must not change the flags, so use lea instead of addq. + lea(rsp, Operand(rsp, + (kNumSafepointRegisters-kNumSafepointSavedRegisters) * kPointerSize)); pop(r14); pop(r12); pop(r11); @@ -1461,8 +1468,7 @@ void MacroAssembler::Popad() { void MacroAssembler::Dropad() { - const int kRegistersPushedByPushad = 11; - addq(rsp, Immediate(kRegistersPushedByPushad * kPointerSize)); + addq(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); } @@ -1536,11 +1542,113 @@ void MacroAssembler::PopTryHandler() { } +void MacroAssembler::Throw(Register value) { + // Check that stack should contain next handler, frame pointer, state and + // return address in that order. + STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize == + StackHandlerConstants::kStateOffset); + STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize == + StackHandlerConstants::kPCOffset); + // Keep thrown value in rax. + if (!value.is(rax)) { + movq(rax, value); + } + + ExternalReference handler_address(Top::k_handler_address); + movq(kScratchRegister, handler_address); + movq(rsp, Operand(kScratchRegister, 0)); + // get next in chain + pop(rcx); + movq(Operand(kScratchRegister, 0), rcx); + pop(rbp); // pop frame pointer + pop(rdx); // remove state + + // Before returning we restore the context from the frame pointer if not NULL. + // The frame pointer is NULL in the exception handler of a JS entry frame. + Set(rsi, 0); // Tentatively set context pointer to NULL + NearLabel skip; + cmpq(rbp, Immediate(0)); + j(equal, &skip); + movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); + bind(&skip); + ret(0); +} + + +void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, + Register value) { + // Keep thrown value in rax. + if (!value.is(rax)) { + movq(rax, value); + } + // Fetch top stack handler. + ExternalReference handler_address(Top::k_handler_address); + movq(kScratchRegister, handler_address); + movq(rsp, Operand(kScratchRegister, 0)); + + // Unwind the handlers until the ENTRY handler is found. + NearLabel loop, done; + bind(&loop); + // Load the type of the current stack handler. + const int kStateOffset = StackHandlerConstants::kStateOffset; + cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY)); + j(equal, &done); + // Fetch the next handler in the list. + const int kNextOffset = StackHandlerConstants::kNextOffset; + movq(rsp, Operand(rsp, kNextOffset)); + jmp(&loop); + bind(&done); + + // Set the top handler address to next handler past the current ENTRY handler. + movq(kScratchRegister, handler_address); + pop(Operand(kScratchRegister, 0)); + + if (type == OUT_OF_MEMORY) { + // Set external caught exception to false. + ExternalReference external_caught(Top::k_external_caught_exception_address); + movq(rax, Immediate(false)); + store_rax(external_caught); + + // Set pending exception and rax to out of memory exception. + ExternalReference pending_exception(Top::k_pending_exception_address); + movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); + store_rax(pending_exception); + } + + // Clear the context pointer. + Set(rsi, 0); + + // Restore registers from handler. + STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize == + StackHandlerConstants::kFPOffset); + pop(rbp); // FP + STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize == + StackHandlerConstants::kStateOffset); + pop(rdx); // State + + STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize == + StackHandlerConstants::kPCOffset); + ret(0); +} + + void MacroAssembler::Ret() { ret(0); } +void MacroAssembler::Ret(int bytes_dropped, Register scratch) { + if (is_uint16(bytes_dropped)) { + ret(bytes_dropped); + } else { + pop(scratch); + addq(rsp, Immediate(bytes_dropped)); + push(scratch); + ret(0); + } +} + + void MacroAssembler::FCmp() { fucomip(); fstp(0); @@ -1598,6 +1706,17 @@ void MacroAssembler::AbortIfNotSmi(Register object) { } +void MacroAssembler::AbortIfNotString(Register object) { + testb(object, Immediate(kSmiTagMask)); + Assert(not_equal, "Operand is not a string"); + push(object); + movq(object, FieldOperand(object, HeapObject::kMapOffset)); + CmpInstanceType(object, FIRST_NONSTRING_TYPE); + pop(object); + Assert(below, "Operand is not a string"); +} + + void MacroAssembler::AbortIfNotRootValue(Register src, Heap::RootListIndex root_value_index, const char* message) { @@ -2098,11 +2217,11 @@ void MacroAssembler::AllocateInNewSpace(int object_size, Register top_reg = result_end.is_valid() ? result_end : result; - if (top_reg.is(result)) { - addq(top_reg, Immediate(object_size)); - } else { - lea(top_reg, Operand(result, object_size)); + if (!top_reg.is(result)) { + movq(top_reg, result); } + addq(top_reg, Immediate(object_size)); + j(carry, gc_required); movq(kScratchRegister, new_space_allocation_limit); cmpq(top_reg, Operand(kScratchRegister, 0)); j(above, gc_required); @@ -2152,7 +2271,12 @@ void MacroAssembler::AllocateInNewSpace(int header_size, // Calculate new top and bail out if new space is exhausted. ExternalReference new_space_allocation_limit = ExternalReference::new_space_allocation_limit_address(); - lea(result_end, Operand(result, element_count, element_size, header_size)); + + // We assume that element_count*element_size + header_size does not + // overflow. + lea(result_end, Operand(element_count, element_size, header_size)); + addq(result_end, result); + j(carry, gc_required); movq(kScratchRegister, new_space_allocation_limit); cmpq(result_end, Operand(kScratchRegister, 0)); j(above, gc_required); @@ -2198,6 +2322,7 @@ void MacroAssembler::AllocateInNewSpace(Register object_size, movq(result_end, object_size); } addq(result_end, result); + j(carry, gc_required); movq(kScratchRegister, new_space_allocation_limit); cmpq(result_end, Operand(kScratchRegister, 0)); j(above, gc_required); |