Make some constants' meaning clear for X64
R=danno@chromium.org Review URL: https://codereview.chromium.org/21721002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16061 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
3b347f45a6
commit
fe7df8c703
@ -373,13 +373,14 @@ void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
|
|||||||
|
|
||||||
bool RelocInfo::IsPatchedReturnSequence() {
|
bool RelocInfo::IsPatchedReturnSequence() {
|
||||||
// The recognized call sequence is:
|
// The recognized call sequence is:
|
||||||
// movq(kScratchRegister, immediate64); call(kScratchRegister);
|
// movq(kScratchRegister, address); call(kScratchRegister);
|
||||||
// It only needs to be distinguished from a return sequence
|
// It only needs to be distinguished from a return sequence
|
||||||
// movq(rsp, rbp); pop(rbp); ret(n); int3 *6
|
// movq(rsp, rbp); pop(rbp); ret(n); int3 *6
|
||||||
// The 11th byte is int3 (0xCC) in the return sequence and
|
// The 11th byte is int3 (0xCC) in the return sequence and
|
||||||
// REX.WB (0x48+register bit) for the call sequence.
|
// REX.WB (0x48+register bit) for the call sequence.
|
||||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||||
return pc_[2 + kPointerSize] != 0xCC;
|
return pc_[Assembler::kMoveAddressIntoScratchRegisterInstructionLength] !=
|
||||||
|
0xCC;
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
@ -164,10 +164,7 @@ void CpuFeatures::Probe() {
|
|||||||
// Patch the code at the current PC with a call to the target address.
|
// Patch the code at the current PC with a call to the target address.
|
||||||
// Additional guard int3 instructions can be added if required.
|
// Additional guard int3 instructions can be added if required.
|
||||||
void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
|
void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
|
||||||
// Load register with immediate 64 and call through a register instructions
|
int code_size = Assembler::kCallSequenceLength + guard_bytes;
|
||||||
// takes up 13 bytes and int3 takes up one byte.
|
|
||||||
static const int kCallCodeSize = 13;
|
|
||||||
int code_size = kCallCodeSize + guard_bytes;
|
|
||||||
|
|
||||||
// Create a code patcher.
|
// Create a code patcher.
|
||||||
CodePatcher patcher(pc_, code_size);
|
CodePatcher patcher(pc_, code_size);
|
||||||
@ -183,7 +180,7 @@ void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
|
|||||||
patcher.masm()->call(r10);
|
patcher.masm()->call(r10);
|
||||||
|
|
||||||
// Check that the size of the code generated is as expected.
|
// Check that the size of the code generated is as expected.
|
||||||
ASSERT_EQ(kCallCodeSize,
|
ASSERT_EQ(Assembler::kCallSequenceLength,
|
||||||
patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
|
patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
|
||||||
|
|
||||||
// Add the requested number of int3 instructions after the call.
|
// Add the requested number of int3 instructions after the call.
|
||||||
|
@ -579,29 +579,36 @@ class Assembler : public AssemblerBase {
|
|||||||
// Distance between the address of the code target in the call instruction
|
// Distance between the address of the code target in the call instruction
|
||||||
// and the return address pushed on the stack.
|
// and the return address pushed on the stack.
|
||||||
static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement.
|
static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement.
|
||||||
// Distance between the start of the JS return sequence and where the
|
// The length of call(kScratchRegister).
|
||||||
// 32-bit displacement of a near call would be, relative to the pushed
|
static const int kCallScratchRegisterInstructionLength = 3;
|
||||||
// return address. TODO: Use return sequence length instead.
|
// The length of call(Immediate32).
|
||||||
// Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
|
|
||||||
static const int kPatchReturnSequenceAddressOffset = 13 - 4;
|
|
||||||
// Distance between start of patched debug break slot and where the
|
|
||||||
// 32-bit displacement of a near call would be, relative to the pushed
|
|
||||||
// return address. TODO: Use return sequence length instead.
|
|
||||||
// Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
|
|
||||||
static const int kPatchDebugBreakSlotAddressOffset = 13 - 4;
|
|
||||||
// TODO(X64): Rename this, removing the "Real", after changing the above.
|
|
||||||
static const int kRealPatchReturnSequenceAddressOffset = 2;
|
|
||||||
|
|
||||||
// Some x64 JS code is padded with int3 to make it large
|
|
||||||
// enough to hold an instruction when the debugger patches it.
|
|
||||||
static const int kJumpInstructionLength = 13;
|
|
||||||
static const int kCallInstructionLength = 13;
|
|
||||||
static const int kJSReturnSequenceLength = 13;
|
|
||||||
static const int kShortCallInstructionLength = 5;
|
static const int kShortCallInstructionLength = 5;
|
||||||
static const int kPatchDebugBreakSlotReturnOffset = 4;
|
// The length of movq(kScratchRegister, address).
|
||||||
|
static const int kMoveAddressIntoScratchRegisterInstructionLength =
|
||||||
|
2 + kPointerSize;
|
||||||
|
// The length of movq(kScratchRegister, address) and call(kScratchRegister).
|
||||||
|
static const int kCallSequenceLength =
|
||||||
|
kMoveAddressIntoScratchRegisterInstructionLength +
|
||||||
|
kCallScratchRegisterInstructionLength;
|
||||||
|
|
||||||
// The debug break slot must be able to contain a call instruction.
|
// The js return and debug break slot must be able to contain an indirect
|
||||||
static const int kDebugBreakSlotLength = kCallInstructionLength;
|
// call sequence, some x64 JS code is padded with int3 to make it large
|
||||||
|
// enough to hold an instruction when the debugger patches it.
|
||||||
|
static const int kJSReturnSequenceLength = kCallSequenceLength;
|
||||||
|
static const int kDebugBreakSlotLength = kCallSequenceLength;
|
||||||
|
static const int kPatchDebugBreakSlotReturnOffset = kCallTargetAddressOffset;
|
||||||
|
// Distance between the start of the JS return sequence and where the
|
||||||
|
// 32-bit displacement of a short call would be. The short call is from
|
||||||
|
// SetDebugBreakAtIC from debug-x64.cc.
|
||||||
|
static const int kPatchReturnSequenceAddressOffset =
|
||||||
|
kJSReturnSequenceLength - kPatchDebugBreakSlotReturnOffset;
|
||||||
|
// Distance between the start of the JS return sequence and where the
|
||||||
|
// 32-bit displacement of a short call would be. The short call is from
|
||||||
|
// SetDebugBreakAtIC from debug-x64.cc.
|
||||||
|
static const int kPatchDebugBreakSlotAddressOffset =
|
||||||
|
kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset;
|
||||||
|
static const int kRealPatchReturnSequenceAddressOffset =
|
||||||
|
kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize;
|
||||||
|
|
||||||
// One byte opcode for test eax,0xXXXXXXXX.
|
// One byte opcode for test eax,0xXXXXXXXX.
|
||||||
static const byte kTestEaxByte = 0xA9;
|
static const byte kTestEaxByte = 0xA9;
|
||||||
|
@ -48,11 +48,10 @@ bool BreakLocationIterator::IsDebugBreakAtReturn() {
|
|||||||
// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-x64.cc
|
// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-x64.cc
|
||||||
// for the precise return instructions sequence.
|
// for the precise return instructions sequence.
|
||||||
void BreakLocationIterator::SetDebugBreakAtReturn() {
|
void BreakLocationIterator::SetDebugBreakAtReturn() {
|
||||||
ASSERT(Assembler::kJSReturnSequenceLength >=
|
ASSERT(Assembler::kJSReturnSequenceLength >= Assembler::kCallSequenceLength);
|
||||||
Assembler::kCallInstructionLength);
|
|
||||||
rinfo()->PatchCodeWithCall(
|
rinfo()->PatchCodeWithCall(
|
||||||
Isolate::Current()->debug()->debug_break_return()->entry(),
|
Isolate::Current()->debug()->debug_break_return()->entry(),
|
||||||
Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength);
|
Assembler::kJSReturnSequenceLength - Assembler::kCallSequenceLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -82,7 +81,7 @@ void BreakLocationIterator::SetDebugBreakAtSlot() {
|
|||||||
ASSERT(IsDebugBreakSlot());
|
ASSERT(IsDebugBreakSlot());
|
||||||
rinfo()->PatchCodeWithCall(
|
rinfo()->PatchCodeWithCall(
|
||||||
Isolate::Current()->debug()->debug_break_slot()->entry(),
|
Isolate::Current()->debug()->debug_break_slot()->entry(),
|
||||||
Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength);
|
Assembler::kDebugBreakSlotLength - Assembler::kCallSequenceLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ const int Deoptimizer::table_entry_size_ = 10;
|
|||||||
|
|
||||||
|
|
||||||
int Deoptimizer::patch_size() {
|
int Deoptimizer::patch_size() {
|
||||||
return Assembler::kCallInstructionLength;
|
return Assembler::kCallSequenceLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
|
|||||||
Address call_address = instruction_start + deopt_data->Pc(i)->value();
|
Address call_address = instruction_start + deopt_data->Pc(i)->value();
|
||||||
// There is room enough to write a long call instruction because we pad
|
// There is room enough to write a long call instruction because we pad
|
||||||
// LLazyBailout instructions with nops if necessary.
|
// LLazyBailout instructions with nops if necessary.
|
||||||
CodePatcher patcher(call_address, Assembler::kCallInstructionLength);
|
CodePatcher patcher(call_address, Assembler::kCallSequenceLength);
|
||||||
patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY),
|
patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY),
|
||||||
RelocInfo::NONE64);
|
RelocInfo::NONE64);
|
||||||
ASSERT(prev_call_address == NULL ||
|
ASSERT(prev_call_address == NULL ||
|
||||||
|
@ -155,7 +155,7 @@ int MacroAssembler::LoadAddressSize(ExternalReference source) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Size of movq(destination, src);
|
// Size of movq(destination, src);
|
||||||
return 10;
|
return Assembler::kMoveAddressIntoScratchRegisterInstructionLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2511,8 +2511,8 @@ void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) {
|
|||||||
|
|
||||||
int MacroAssembler::CallSize(ExternalReference ext) {
|
int MacroAssembler::CallSize(ExternalReference ext) {
|
||||||
// Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes).
|
// Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes).
|
||||||
const int kCallInstructionSize = 3;
|
return LoadAddressSize(ext) +
|
||||||
return LoadAddressSize(ext) + kCallInstructionSize;
|
Assembler::kCallScratchRegisterInstructionLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -841,7 +841,7 @@ class MacroAssembler: public Assembler {
|
|||||||
|
|
||||||
// The size of the code generated for different call instructions.
|
// The size of the code generated for different call instructions.
|
||||||
int CallSize(Address destination, RelocInfo::Mode rmode) {
|
int CallSize(Address destination, RelocInfo::Mode rmode) {
|
||||||
return kCallInstructionLength;
|
return kCallSequenceLength;
|
||||||
}
|
}
|
||||||
int CallSize(ExternalReference ext);
|
int CallSize(ExternalReference ext);
|
||||||
int CallSize(Handle<Code> code_object) {
|
int CallSize(Handle<Code> code_object) {
|
||||||
|
Loading…
Reference in New Issue
Block a user