Commit a85f5c86 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Moved some IA32 specific code from to the architecture dependent part of the debugger code.

Renamed functions related to patching of code with call instructions to match the naming conversion.

BUG=1240753
Review URL: http://codereview.chromium.org/20176

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1239 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 14f66ff7
......@@ -103,39 +103,39 @@ Address* RelocInfo::target_reference_address() {
Address RelocInfo::call_address() {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
UNIMPLEMENTED();
return NULL;
}
void RelocInfo::set_call_address(Address target) {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
UNIMPLEMENTED();
}
Object* RelocInfo::call_object() {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
UNIMPLEMENTED();
return NULL;
}
Object** RelocInfo::call_object_address() {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
UNIMPLEMENTED();
return NULL;
}
void RelocInfo::set_call_object(Object* target) {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
UNIMPLEMENTED();
}
bool RelocInfo::is_call_instruction() {
bool RelocInfo::IsCallInstruction() {
UNIMPLEMENTED();
return false;
}
......
......@@ -139,15 +139,15 @@ int PcStoreOffset() {
const int RelocInfo::kApplyMask = 0;
void RelocInfo::patch_code(byte* instructions, int instruction_count) {
void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
// Patch the code at the current address with the supplied instructions.
UNIMPLEMENTED();
}
// Patch the code at the current PC with a call to the target address.
// Additional guard int3 instructions can be added if required.
void RelocInfo::patch_code_with_call(Address target, int guard_bytes) {
// Additional guard instructions can be added if required.
void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
// Patch the code at the current address with a call to the target.
UNIMPLEMENTED();
}
......
......@@ -51,7 +51,7 @@ void RelocInfo::apply(int delta) {
if (rmode_ == RUNTIME_ENTRY || IsCodeTarget(rmode_)) {
int32_t* p = reinterpret_cast<int32_t*>(pc_);
*p -= delta; // relocate entry
} else if (rmode_ == JS_RETURN && is_call_instruction()) {
} else if (rmode_ == JS_RETURN && IsCallInstruction()) {
// Special handling of js_return when a break point is set (call
// instruction has been inserted).
int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
......@@ -107,36 +107,36 @@ Address* RelocInfo::target_reference_address() {
Address RelocInfo::call_address() {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
return Assembler::target_address_at(pc_ + 1);
}
void RelocInfo::set_call_address(Address target) {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
Assembler::set_target_address_at(pc_ + 1, target);
}
Object* RelocInfo::call_object() {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
return *call_object_address();
}
Object** RelocInfo::call_object_address() {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
return reinterpret_cast<Object**>(pc_ + 1);
}
void RelocInfo::set_call_object(Object* target) {
ASSERT(is_call_instruction());
ASSERT(IsCallInstruction());
*call_object_address() = target;
}
bool RelocInfo::is_call_instruction() {
bool RelocInfo::IsCallInstruction() {
return *pc_ == 0xE8;
}
......
......@@ -156,7 +156,7 @@ const int RelocInfo::kApplyMask =
1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE;
void RelocInfo::patch_code(byte* instructions, int instruction_count) {
void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
// Patch the code at the current address with the supplied instructions.
for (int i = 0; i < instruction_count; i++) {
*(pc_ + i) = *(instructions + i);
......@@ -166,7 +166,7 @@ void RelocInfo::patch_code(byte* instructions, int instruction_count) {
// Patch the code at the current PC with a call to the target address.
// Additional guard int3 instructions can be added if required.
void RelocInfo::patch_code_with_call(Address target, int guard_bytes) {
void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
// Call instruction takes up 5 bytes and int3 takes up one byte.
int code_size = 5 + guard_bytes;
......
......@@ -257,11 +257,11 @@ class RelocInfo BASE_EMBEDDED {
INLINE(void set_call_object(Object* target));
// Patch the code with some other code.
void patch_code(byte* instructions, int instruction_count);
void PatchCode(byte* instructions, int instruction_count);
// Patch the code with a call.
void patch_code_with_call(Address target, int guard_bytes);
INLINE(bool is_call_instruction());
void PatchCodeWithCall(Address target, int guard_bytes);
INLINE(bool IsCallInstruction());
#ifdef ENABLE_DISASSEMBLER
// Printing
......
......@@ -33,6 +33,24 @@
namespace v8 { namespace internal {
// Currently debug break is not supported in frame exit code on ARM.
bool BreakLocationIterator::IsDebugBreakAtReturn() {
return false;
}
// Currently debug break is not supported in frame exit code on ARM.
void BreakLocationIterator::SetDebugBreakAtReturn() {
UNIMPLEMENTED();
}
// Currently debug break is not supported in frame exit code on ARM.
void BreakLocationIterator::ClearDebugBreakAtReturn() {
UNIMPLEMENTED();
}
#define __ masm->
......
......@@ -34,6 +34,31 @@
namespace v8 { namespace internal {
// A debug break in the frame exit code is identified by a call instruction.
bool BreakLocationIterator::IsDebugBreakAtReturn() {
// Opcode E8 is call.
return (*(rinfo()->pc()) == 0xE8);
}
// Patch the JS frame exit code with a debug break call. See
// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-ia32.cc
// for the precise return instructions sequence.
void BreakLocationIterator::SetDebugBreakAtReturn() {
ASSERT(Debug::kIa32JSReturnSequenceLength >=
Debug::kIa32CallInstructionLength);
rinfo()->PatchCodeWithCall(Debug::debug_break_return_entry()->entry(),
Debug::kIa32JSReturnSequenceLength - Debug::kIa32CallInstructionLength);
}
// Restore the JS frame exit code.
void BreakLocationIterator::ClearDebugBreakAtReturn() {
rinfo()->PatchCode(original_rinfo()->pc(),
Debug::kIa32JSReturnSequenceLength);
}
#define __ masm->
......
......@@ -285,15 +285,8 @@ void BreakLocationIterator::SetDebugBreak() {
}
if (RelocInfo::IsJSReturn(rmode())) {
// This path is currently only used on IA32 as JSExitFrame on ARM uses a
// stub.
// Patch the JS frame exit code with a debug break call. See
// VisitReturnStatement and ExitJSFrame in codegen-ia32.cc for the
// precise return instructions sequence.
ASSERT(Debug::kIa32JSReturnSequenceLength >=
Debug::kIa32CallInstructionLength);
rinfo()->patch_code_with_call(Debug::debug_break_return_entry()->entry(),
Debug::kIa32JSReturnSequenceLength - Debug::kIa32CallInstructionLength);
// Patch the frame exit code with a break point.
SetDebugBreakAtReturn();
} else {
// Patch the original code with the current address as the current address
// might have changed by the inline caching since the code was copied.
......@@ -310,9 +303,8 @@ void BreakLocationIterator::SetDebugBreak() {
void BreakLocationIterator::ClearDebugBreak() {
if (RelocInfo::IsJSReturn(rmode())) {
// Restore the JS frame exit code.
rinfo()->patch_code(original_rinfo()->pc(),
Debug::kIa32JSReturnSequenceLength);
// Restore the frame exit code.
ClearDebugBreakAtReturn();
} else {
// Patch the code to the original invoke.
rinfo()->set_target_address(original_rinfo()->target_address());
......@@ -359,12 +351,7 @@ bool BreakLocationIterator::HasBreakPoint() {
// Check whether there is a debug break at the current position.
bool BreakLocationIterator::IsDebugBreak() {
if (RelocInfo::IsJSReturn(rmode())) {
// This is IA32 specific but works as long as the ARM version
// still uses a stub for JSExitFrame.
//
// TODO(1240753): Make the test architecture independent or split
// parts of the debugger into architecture dependent files.
return (*(rinfo()->pc()) == 0xE8);
return IsDebugBreakAtReturn();
} else {
return Debug::IsDebugBreak(rinfo()->target_address());
}
......
......@@ -123,6 +123,9 @@ class BreakLocationIterator {
private:
void SetDebugBreak();
void ClearDebugBreak();
bool IsDebugBreakAtReturn();
void SetDebugBreakAtReturn();
void ClearDebugBreakAtReturn();
DISALLOW_COPY_AND_ASSIGN(BreakLocationIterator);
};
......
......@@ -287,7 +287,7 @@ class MarkingVisitor : public ObjectVisitor {
void VisitDebugTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) &&
rinfo->is_call_instruction());
rinfo->IsCallInstruction());
HeapObject* code = CodeFromDerivedPointer(rinfo->call_address());
MarkCompactCollector::MarkObject(code);
// When compacting we convert the call to a real object pointer.
......
......@@ -4480,7 +4480,7 @@ void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) {
void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) && rinfo->is_call_instruction());
ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) && rinfo->IsCallInstruction());
VisitPointer(rinfo->call_object_address());
}
......@@ -4504,7 +4504,7 @@ void Code::ConvertICTargetsFromAddressToObject() {
for (RelocIterator it(this, RelocInfo::ModeMask(RelocInfo::JS_RETURN));
!it.done();
it.next()) {
if (it.rinfo()->is_call_instruction()) {
if (it.rinfo()->IsCallInstruction()) {
Address addr = it.rinfo()->call_address();
ASSERT(addr != NULL);
HeapObject* code = HeapObject::FromAddress(addr - Code::kHeaderSize);
......@@ -4536,7 +4536,7 @@ void Code::CodeIterateBody(ObjectVisitor* v) {
v->VisitExternalReference(it.rinfo()->target_reference_address());
} else if (Debug::has_break_points() &&
RelocInfo::IsJSReturn(rmode) &&
it.rinfo()->is_call_instruction()) {
it.rinfo()->IsCallInstruction()) {
v->VisitDebugTarget(it.rinfo());
} else if (rmode == RelocInfo::RUNTIME_ENTRY) {
v->VisitRuntimeEntry(it.rinfo());
......@@ -4566,7 +4566,7 @@ void Code::ConvertICTargetsFromObjectToAddress() {
for (RelocIterator it(this, RelocInfo::ModeMask(RelocInfo::JS_RETURN));
!it.done();
it.next()) {
if (it.rinfo()->is_call_instruction()) {
if (it.rinfo()->IsCallInstruction()) {
Code* code = reinterpret_cast<Code*>(it.rinfo()->call_object());
ASSERT((code != NULL) && code->IsHeapObject());
it.rinfo()->set_call_address(code->instruction_start());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment