Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(551)

Unified Diff: src/debug.cc

Issue 2693002: More precise break points and stepping when debugging... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/debug.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/debug.cc
===================================================================
--- src/debug.cc (revision 4816)
+++ src/debug.cc (working copy)
@@ -129,10 +129,14 @@
ASSERT(statement_position_ >= 0);
}
- // Check for breakable code target. Look in the original code as setting
- // break points can cause the code targets in the running (debugged) code to
- // be of a different kind than in the original code.
- if (RelocInfo::IsCodeTarget(rmode())) {
+ if (IsDebugBreakSlot()) {
+ // There is always a possible break point at a debug break slot.
+ break_point_++;
+ return;
+ } else if (RelocInfo::IsCodeTarget(rmode())) {
+ // Check for breakable code target. Look in the original code as setting
+ // break points can cause the code targets in the running (debugged) code
+ // to be of a different kind than in the original code.
Address target = original_rinfo()->target_address();
Code* code = Code::GetCodeFromTargetAddress(target);
if ((code->is_inline_cache_stub() &&
@@ -329,6 +333,9 @@
if (RelocInfo::IsJSReturn(rmode())) {
// Patch the frame exit code with a break point.
SetDebugBreakAtReturn();
+ } else if (IsDebugBreakSlot()) {
+ // Patch the code in the break slot.
+ SetDebugBreakAtSlot();
} else {
// Patch the IC call.
SetDebugBreakAtIC();
@@ -346,6 +353,9 @@
if (RelocInfo::IsJSReturn(rmode())) {
// Restore the frame exit code.
ClearDebugBreakAtReturn();
+ } else if (IsDebugBreakSlot()) {
+ // Restore the code in the break slot.
+ ClearDebugBreakAtSlot();
} else {
// Patch the IC call.
ClearDebugBreakAtIC();
@@ -417,6 +427,8 @@
bool BreakLocationIterator::IsDebugBreak() {
if (RelocInfo::IsJSReturn(rmode())) {
return IsDebugBreakAtReturn();
+ } else if (IsDebugBreakSlot()) {
+ return IsDebugBreakAtSlot();
} else {
return Debug::IsDebugBreak(rinfo()->target_address());
}
@@ -478,6 +490,11 @@
}
+bool BreakLocationIterator::IsDebugBreakSlot() {
+ return RelocInfo::DEBUG_BREAK_SLOT == rmode();
+}
+
+
Object* BreakLocationIterator::BreakPointObjects() {
return debug_info_->GetBreakPointObjects(code_position());
}
@@ -573,6 +590,7 @@
Handle<Context> Debug::debug_context_ = Handle<Context>();
Code* Debug::debug_break_return_ = NULL;
+Code* Debug::debug_break_slot_ = NULL;
void ScriptCache::Add(Handle<Script> script) {
@@ -656,6 +674,10 @@
debug_break_return_ =
Builtins::builtin(Builtins::Return_DebugBreak);
ASSERT(debug_break_return_->IsCode());
+ // Get code to handle debug break in debug break slots.
+ debug_break_slot_ =
+ Builtins::builtin(Builtins::Slot_DebugBreak);
+ ASSERT(debug_break_slot_->IsCode());
}
}
@@ -824,6 +846,7 @@
void Debug::Iterate(ObjectVisitor* v) {
v->VisitPointer(BitCast<Object**, Code**>(&(debug_break_return_)));
+ v->VisitPointer(BitCast<Object**, Code**>(&(debug_break_slot_)));
}
@@ -1631,16 +1654,21 @@
// break point is still active after processing the break point.
Address addr = frame->pc() - Assembler::kCallTargetAddressOffset;
- // Check if the location is at JS exit.
+ // Check if the location is at JS exit or debug break slot.
bool at_js_return = false;
bool break_at_js_return_active = false;
+ bool at_debug_break_slot = false;
RelocIterator it(debug_info->code());
- while (!it.done()) {
+ while (!it.done() && !at_js_return && !at_debug_break_slot) {
if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
at_js_return = (it.rinfo()->pc() ==
addr - Assembler::kPatchReturnSequenceAddressOffset);
break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence();
}
+ if (RelocInfo::IsDebugBreakSlot(it.rinfo()->rmode())) {
+ at_debug_break_slot = (it.rinfo()->pc() ==
+ addr - Assembler::kPatchDebugBreakSlotAddressOffset);
+ }
it.next();
}
@@ -1657,25 +1685,30 @@
// Move back to where the call instruction sequence started.
thread_local_.after_break_target_ =
addr - Assembler::kPatchReturnSequenceAddressOffset;
- } else {
- // Check if there still is a debug break call at the target address. If the
- // break point has been removed it will have disappeared. If it have
- // disappeared don't try to look in the original code as the running code
- // will have the right address. This takes care of the case where the last
- // break point is removed from the function and therefore no "original code"
- // is available. If the debug break call is still there find the address in
- // the original code.
- if (IsDebugBreak(Assembler::target_address_at(addr))) {
- // If the break point is still there find the call address which was
- // overwritten in the original code by the call to DebugBreakXXX.
+ } else if (at_debug_break_slot) {
+ // Address of where the debug break slot starts.
+ addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset;
- // Find the corresponding address in the original code.
- addr += original_code->instruction_start() - code->instruction_start();
- }
+ // Continue just after the slot.
+ thread_local_.after_break_target_ = addr + Assembler::kDebugBreakSlotLength;
+ } else if (IsDebugBreak(Assembler::target_address_at(addr))) {
+ // We now know that there is still a debug break call at the target address,
+ // so the break point is still there and the original code will hold the
+ // address to jump to in order to complete the call which is replaced by a
+ // call to DebugBreakXXX.
+ // Find the corresponding address in the original code.
+ addr += original_code->instruction_start() - code->instruction_start();
+
// Install jump to the call address in the original code. This will be the
// call which was overwritten by the call to DebugBreakXXX.
thread_local_.after_break_target_ = Assembler::target_address_at(addr);
+ } else {
+ // There is no longer a break point present. Don't try to look in the
+ // original code as the running code will have the right address. This takes
+ // care of the case where the last break point is removed from the function
+ // and therefore no "original code" is available.
+ thread_local_.after_break_target_ = Assembler::target_address_at(addr);
}
}
« no previous file with comments | « src/debug.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698