From b71277947915c4ba7f7397e6d7682b5dd244fd15 Mon Sep 17 00:00:00 2001 From: "haitao.feng@intel.com" Date: Wed, 8 Jan 2014 07:02:02 +0000 Subject: [PATCH] Refactor loading a pointer into a register instruction for X64 R=verwaest@chromium.org Review URL: https://codereview.chromium.org/64453002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18479 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/assembler-x64.cc | 31 ++++---------------- src/x64/assembler-x64.h | 4 +-- src/x64/code-stubs-x64.cc | 10 +++---- src/x64/full-codegen-x64.cc | 6 ++-- src/x64/lithium-codegen-x64.cc | 10 +++---- src/x64/macro-assembler-x64.cc | 50 ++++++++++++++++----------------- src/x64/macro-assembler-x64.h | 21 ++++++++++++-- src/x64/stub-cache-x64.cc | 4 +-- test/cctest/test-macro-assembler-x64.cc | 2 +- 9 files changed, 68 insertions(+), 70 deletions(-) diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc index bc875d6..910d760 100644 --- a/src/x64/assembler-x64.cc +++ b/src/x64/assembler-x64.cc @@ -110,7 +110,7 @@ void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { #endif // Patch the code. - patcher.masm()->movq(kScratchRegister, target, RelocInfo::NONE64); + patcher.masm()->movp(kScratchRegister, target, RelocInfo::NONE64); patcher.masm()->call(kScratchRegister); // Check that the size of the code generated is as expected. @@ -1448,18 +1448,11 @@ void Assembler::emit_mov(const Operand& dst, Immediate value, int size) { } -void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) { - // This method must not be used with heap object references. The stored - // address is not GC safe. Use the handle version instead. - ASSERT(rmode > RelocInfo::LAST_GCED_ENUM); - if (RelocInfo::IsNone(rmode)) { - movq(dst, reinterpret_cast(value)); - } else { - EnsureSpace ensure_space(this); - emit_rex_64(dst); - emit(0xB8 | dst.low_bits()); - emitp(value, rmode); - } +void Assembler::movp(Register dst, void* value, RelocInfo::Mode rmode) { + EnsureSpace ensure_space(this); + emit_rex(dst, kPointerSize); + emit(0xB8 | dst.low_bits()); + emitp(value, rmode); } @@ -1499,18 +1492,6 @@ void Assembler::movl(const Operand& dst, Label* src) { } -void Assembler::movq(Register dst, Handle value, RelocInfo::Mode mode) { - AllowDeferredHandleDereference using_raw_address; - ASSERT(!RelocInfo::IsNone(mode)); - EnsureSpace ensure_space(this); - ASSERT(value->IsHeapObject()); - ASSERT(!isolate()->heap()->InNewSpace(*value)); - emit_rex_64(dst); - emit(0xB8 | dst.low_bits()); - emitp(value.location(), mode); -} - - void Assembler::movsxbq(Register dst, const Operand& src) { EnsureSpace ensure_space(this); emit_rex_64(dst, src); diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h index 1f1316f..39a6863 100644 --- a/src/x64/assembler-x64.h +++ b/src/x64/assembler-x64.h @@ -722,11 +722,11 @@ class Assembler : public AssemblerBase { void movl(const Operand& dst, Label* src); // Loads a pointer into a register with a relocation mode. - void movq(Register dst, void* ptr, RelocInfo::Mode rmode); + void movp(Register dst, void* ptr, RelocInfo::Mode rmode); + // Loads a 64-bit immediate into a register. void movq(Register dst, int64_t value); void movq(Register dst, uint64_t value); - void movq(Register dst, Handle handle, RelocInfo::Mode rmode); void movsxbq(Register dst, const Operand& src); void movsxwq(Register dst, const Operand& src); diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index cffb8a6..1927b6b 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -2738,7 +2738,7 @@ void CEntryStub::Generate(MacroAssembler* masm) { // Do full GC and retry runtime call one final time. Failure* failure = Failure::InternalError(); - __ movq(rax, failure, RelocInfo::NONE64); + __ Move(rax, failure, RelocInfo::NONE64); GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, @@ -2759,7 +2759,7 @@ void CEntryStub::Generate(MacroAssembler* masm) { isolate); Label already_have_failure; JumpIfOOM(masm, rax, kScratchRegister, &already_have_failure); - __ movq(rax, Failure::OutOfMemoryException(0x1), RelocInfo::NONE64); + __ Move(rax, Failure::OutOfMemoryException(0x1), RelocInfo::NONE64); __ bind(&already_have_failure); __ Store(pending_exception, rax); // Fall through to the next label. @@ -2789,7 +2789,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Scratch register is neither callee-save, nor an argument register on any // platform. It's free to use at this point. // Cannot use smi-register for loading yet. - __ movq(kScratchRegister, Smi::FromInt(marker), RelocInfo::NONE64); + __ Move(kScratchRegister, Smi::FromInt(marker), RelocInfo::NONE64); __ push(kScratchRegister); // context slot __ push(kScratchRegister); // function slot // Save callee-saved registers (X64/Win64 calling conventions). @@ -2857,7 +2857,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { ExternalReference pending_exception(Isolate::kPendingExceptionAddress, isolate); __ Store(pending_exception, rax); - __ movq(rax, Failure::Exception(), RelocInfo::NONE64); + __ Move(rax, Failure::Exception(), RelocInfo::NONE64); __ jmp(&exit); // Invoke: Link this frame into the handler chain. There's only one @@ -5186,7 +5186,7 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) { masm->PushCallerSaved(kSaveFPRegs, arg_reg_1, arg_reg_2); // Call the entry hook function. - __ movq(rax, FUNCTION_ADDR(masm->isolate()->function_entry_hook()), + __ Move(rax, FUNCTION_ADDR(masm->isolate()->function_entry_hook()), RelocInfo::NONE64); AllowExternalCallThatCantCauseGC scope(masm); diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 00c27f9..674f64e 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -302,7 +302,7 @@ void FullCodeGenerator::ClearAccumulator() { void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { - __ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); + __ Move(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); __ SmiAddConstant(FieldOperand(rbx, Cell::kValueOffset), Smi::FromInt(-delta)); } @@ -310,7 +310,7 @@ void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { void FullCodeGenerator::EmitProfilingCounterReset() { int reset_value = FLAG_interrupt_budget; - __ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); + __ Move(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); __ Move(kScratchRegister, Smi::FromInt(reset_value)); __ movq(FieldOperand(rbx, Cell::kValueOffset), kScratchRegister); } @@ -3342,7 +3342,7 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) { __ bind(&runtime); __ PrepareCallCFunction(2); __ movq(arg_reg_1, object); - __ movq(arg_reg_2, index, RelocInfo::NONE64); + __ Move(arg_reg_2, index, RelocInfo::NONE64); __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); __ jmp(&done); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 9b32e68..72190e6 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -1639,7 +1639,7 @@ void LCodeGen::DoDateField(LDateField* instr) { __ bind(&runtime); __ PrepareCallCFunction(2); __ movq(arg_reg_1, object); - __ movq(arg_reg_2, index, RelocInfo::NONE64); + __ Move(arg_reg_2, index, RelocInfo::NONE64); __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); __ bind(&done); } @@ -2560,7 +2560,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { __ movq(map, FieldOperand(object, HeapObject::kMapOffset)); __ bind(deferred->map_check()); // Label for calculating code patching. Handle cache_cell = factory()->NewCell(factory()->the_hole_value()); - __ movq(kScratchRegister, cache_cell, RelocInfo::CELL); + __ Move(kScratchRegister, cache_cell, RelocInfo::CELL); __ cmpq(map, Operand(kScratchRegister, 0)); __ j(not_equal, &cache_miss, Label::kNear); // Patched to load either true or false. @@ -2726,14 +2726,14 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { // We have a temp because CompareRoot might clobber kScratchRegister. Register cell = ToRegister(instr->temp()); ASSERT(!value.is(cell)); - __ movq(cell, cell_handle, RelocInfo::CELL); + __ Move(cell, cell_handle, RelocInfo::CELL); __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex); DeoptimizeIf(equal, instr->environment()); // Store the value. __ movq(Operand(cell, 0), value); } else { // Store the value. - __ movq(kScratchRegister, cell_handle, RelocInfo::CELL); + __ Move(kScratchRegister, cell_handle, RelocInfo::CELL); __ movq(Operand(kScratchRegister, 0), value); } // Cells are always rescanned, so no write barrier here. @@ -4348,7 +4348,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { __ j(not_equal, ¬_applicable); if (IsSimpleMapChangeTransition(from_kind, to_kind)) { Register new_map_reg = ToRegister(instr->new_map_temp()); - __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); + __ Move(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); // Write barrier. ASSERT_NE(instr->temp(), NULL); diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index 6c3f501..e160dbb 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -163,7 +163,7 @@ void MacroAssembler::PushAddress(ExternalReference source) { int64_t address = reinterpret_cast(source.address()); if (is_int32(address) && !Serializer::enabled()) { if (emit_debug_code()) { - movq(kScratchRegister, kZapValue, RelocInfo::NONE64); + Move(kScratchRegister, kZapValue, RelocInfo::NONE64); } push(Immediate(static_cast(address))); return; @@ -288,7 +288,7 @@ void MacroAssembler::InNewSpace(Register object, ASSERT(is_int32(static_cast(isolate()->heap()->NewSpaceMask()))); intptr_t new_space_start = reinterpret_cast(isolate()->heap()->NewSpaceStart()); - movq(kScratchRegister, reinterpret_cast
(-new_space_start), + Move(kScratchRegister, reinterpret_cast
(-new_space_start), RelocInfo::NONE64); if (scratch.is(object)) { addq(scratch, kScratchRegister); @@ -340,8 +340,8 @@ void MacroAssembler::RecordWriteField( // Clobber clobbered input registers when running with the debug-code flag // turned on to provoke errors. if (emit_debug_code()) { - movq(value, kZapValue, RelocInfo::NONE64); - movq(dst, kZapValue, RelocInfo::NONE64); + Move(value, kZapValue, RelocInfo::NONE64); + Move(dst, kZapValue, RelocInfo::NONE64); } } @@ -374,8 +374,8 @@ void MacroAssembler::RecordWriteArray(Register object, // Clobber clobbered input registers when running with the debug-code flag // turned on to provoke errors. if (emit_debug_code()) { - movq(value, kZapValue, RelocInfo::NONE64); - movq(index, kZapValue, RelocInfo::NONE64); + Move(value, kZapValue, RelocInfo::NONE64); + Move(index, kZapValue, RelocInfo::NONE64); } } @@ -439,8 +439,8 @@ void MacroAssembler::RecordWrite(Register object, // Clobber clobbered registers when running with the debug-code flag // turned on to provoke errors. if (emit_debug_code()) { - movq(address, kZapValue, RelocInfo::NONE64); - movq(value, kZapValue, RelocInfo::NONE64); + Move(address, kZapValue, RelocInfo::NONE64); + Move(value, kZapValue, RelocInfo::NONE64); } } @@ -528,9 +528,9 @@ void MacroAssembler::Abort(BailoutReason reason) { #endif push(rax); - movq(kScratchRegister, reinterpret_cast(p0), RelocInfo::NONE64); + Move(kScratchRegister, reinterpret_cast(p0), RelocInfo::NONE64); push(kScratchRegister); - movq(kScratchRegister, Smi::FromInt(static_cast(p1 - p0)), + Move(kScratchRegister, Smi::FromInt(static_cast(p1 - p0)), RelocInfo::NONE64); push(kScratchRegister); @@ -720,18 +720,18 @@ void MacroAssembler::CallApiFunctionAndReturn( bool* is_profiling_flag = isolate()->cpu_profiler()->is_profiling_address(); STATIC_ASSERT(sizeof(*is_profiling_flag) == 1); - movq(rax, is_profiling_flag, RelocInfo::EXTERNAL_REFERENCE); + Move(rax, is_profiling_flag, RelocInfo::EXTERNAL_REFERENCE); cmpb(Operand(rax, 0), Immediate(0)); j(zero, &profiler_disabled); // Third parameter is the address of the actual getter function. - movq(thunk_last_arg, function_address, RelocInfo::EXTERNAL_REFERENCE); - movq(rax, thunk_address, RelocInfo::EXTERNAL_REFERENCE); + Move(thunk_last_arg, function_address, RelocInfo::EXTERNAL_REFERENCE); + Move(rax, thunk_address, RelocInfo::EXTERNAL_REFERENCE); jmp(&end_profiler_check); bind(&profiler_disabled); // Call the api function! - movq(rax, reinterpret_cast
(function_address), + Move(rax, reinterpret_cast
(function_address), RelocInfo::EXTERNAL_REFERENCE); bind(&end_profiler_check); @@ -1043,7 +1043,7 @@ Register MacroAssembler::GetSmiConstant(Smi* source) { void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { if (emit_debug_code()) { - movq(dst, Smi::FromInt(kSmiConstantRegisterValue), RelocInfo::NONE64); + Move(dst, Smi::FromInt(kSmiConstantRegisterValue), RelocInfo::NONE64); cmpq(dst, kSmiConstantRegister); Assert(equal, kUninitializedKSmiConstantRegister); } @@ -1083,7 +1083,7 @@ void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { UNREACHABLE(); return; default: - movq(dst, source, RelocInfo::NONE64); + Move(dst, source, RelocInfo::NONE64); return; } if (negative) { @@ -2551,10 +2551,10 @@ void MacroAssembler::MoveHeapObject(Register result, ASSERT(object->IsHeapObject()); if (isolate()->heap()->InNewSpace(*object)) { Handle cell = isolate()->factory()->NewCell(object); - movq(result, cell, RelocInfo::CELL); + Move(result, cell, RelocInfo::CELL); movq(result, Operand(result, 0)); } else { - movq(result, object, RelocInfo::EMBEDDED_OBJECT); + Move(result, object, RelocInfo::EMBEDDED_OBJECT); } } @@ -2564,7 +2564,7 @@ void MacroAssembler::LoadGlobalCell(Register dst, Handle cell) { AllowDeferredHandleDereference embedding_raw_address; load_rax(cell.location(), RelocInfo::CELL); } else { - movq(dst, cell, RelocInfo::CELL); + Move(dst, cell, RelocInfo::CELL); movq(dst, Operand(dst, 0)); } } @@ -2591,7 +2591,7 @@ void MacroAssembler::Jump(ExternalReference ext) { void MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) { - movq(kScratchRegister, destination, rmode); + Move(kScratchRegister, destination, rmode); jmp(kScratchRegister); } @@ -2625,7 +2625,7 @@ void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { #ifdef DEBUG int end_position = pc_offset() + CallSize(destination, rmode); #endif - movq(kScratchRegister, destination, rmode); + Move(kScratchRegister, destination, rmode); call(kScratchRegister); #ifdef DEBUG CHECK_EQ(pc_offset(), end_position); @@ -3667,7 +3667,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, if (!definitely_matches) { Handle adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); if (!code_constant.is_null()) { - movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); + Move(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); } else if (!code_register.is(rdx)) { movq(rdx, code_register); @@ -3719,10 +3719,10 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) { movq(rbp, rsp); push(rsi); // Context. Push(Smi::FromInt(type)); - movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); + Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); push(kScratchRegister); if (emit_debug_code()) { - movq(kScratchRegister, + Move(kScratchRegister, isolate()->factory()->undefined_value(), RelocInfo::EMBEDDED_OBJECT); cmpq(Operand(rsp, 0), kScratchRegister); @@ -3755,7 +3755,7 @@ void MacroAssembler::EnterExitFramePrologue(bool save_rax) { // Reserve room for entry stack pointer and push the code object. ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); push(Immediate(0)); // Saved entry sp, patched before call. - movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); + Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); push(kScratchRegister); // Accessed from EditFrame::code_slot. // Save the frame pointer and the context in top. diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h index 98808a8..e69cb6e 100644 --- a/src/x64/macro-assembler-x64.h +++ b/src/x64/macro-assembler-x64.h @@ -407,7 +407,7 @@ class MacroAssembler: public Assembler { void SafePush(Smi* src); void InitializeSmiConstantRegister() { - movq(kSmiConstantRegister, Smi::FromInt(kSmiConstantRegisterValue), + Move(kSmiConstantRegister, Smi::FromInt(kSmiConstantRegisterValue), RelocInfo::NONE64); } @@ -860,11 +860,28 @@ class MacroAssembler: public Assembler { void PopReturnAddressTo(Register dst) { pop(dst); } void MoveDouble(Register dst, const Operand& src) { movq(dst, src); } void MoveDouble(const Operand& dst, Register src) { movq(dst, src); } + void Move(Register dst, ExternalReference ext) { - movq(dst, reinterpret_cast
(ext.address()), + movp(dst, reinterpret_cast
(ext.address()), RelocInfo::EXTERNAL_REFERENCE); } + // Loads a pointer into a register with a relocation mode. + void Move(Register dst, void* ptr, RelocInfo::Mode rmode) { + // This method must not be used with heap object references. The stored + // address is not GC safe. Use the handle version instead. + ASSERT(rmode > RelocInfo::LAST_GCED_ENUM); + movp(dst, ptr, rmode); + } + + void Move(Register dst, Handle value, RelocInfo::Mode rmode) { + AllowDeferredHandleDereference using_raw_address; + ASSERT(!RelocInfo::IsNone(rmode)); + ASSERT(value->IsHeapObject()); + ASSERT(!isolate()->heap()->InNewSpace(*value)); + movp(dst, value.location(), rmode); + } + // Control Flow void Jump(Address destination, RelocInfo::Mode rmode); void Jump(ExternalReference ext); diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 4095922..49c46f9 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -1304,7 +1304,7 @@ Register LoadStubCompiler::CallbackHandlerFrontend( __ movq(scratch2(), Operand(dictionary, index, times_pointer_size, kValueOffset - kHeapObjectTag)); - __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT); + __ Move(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT); __ cmpq(scratch2(), scratch3()); __ j(not_equal, &miss); } @@ -2684,7 +2684,7 @@ Handle KeyedStoreStubCompiler::CompileStorePolymorphic( } else { Label next_map; __ j(not_equal, &next_map, Label::kNear); - __ movq(transition_map(), + __ Move(transition_map(), transitioned_maps->at(i), RelocInfo::EMBEDDED_OBJECT); __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); diff --git a/test/cctest/test-macro-assembler-x64.cc b/test/cctest/test-macro-assembler-x64.cc index 3f25162..ad8ee84 100644 --- a/test/cctest/test-macro-assembler-x64.cc +++ b/test/cctest/test-macro-assembler-x64.cc @@ -2347,7 +2347,7 @@ TEST(OperandOffset) { __ lea(r13, Operand(rbp, -3 * kPointerSize)); __ lea(rbx, Operand(rbp, -5 * kPointerSize)); __ movl(rcx, Immediate(2)); - __ movq(r8, reinterpret_cast
(&data[128]), RelocInfo::NONE64); + __ Move(r8, reinterpret_cast
(&data[128]), RelocInfo::NONE64); __ movl(rax, Immediate(1)); Operand sp0 = Operand(rsp, 0); -- 2.7.4