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

Unified Diff: src/debug.cc

Issue 967323002: Refactor BreakLocationIterator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: static_cast instead Created 5 years, 10 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/ia32/assembler-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/debug.cc
diff --git a/src/debug.cc b/src/debug.cc
index ea402ffa3d8c44865b509c7a2b60dbcf1c887593..0cd20ad5b134c9a3c2db796efebeb45d9fd23e7d 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -60,47 +60,29 @@ static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
}
-BreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info,
- BreakLocatorType type) {
- debug_info_ = debug_info;
- type_ = type;
- reloc_iterator_ = NULL;
- reloc_iterator_original_ = NULL;
- Reset(); // Initialize the rest of the member variables.
-}
-
-
-BreakLocationIterator::~BreakLocationIterator() {
- DCHECK(reloc_iterator_ != NULL);
- DCHECK(reloc_iterator_original_ != NULL);
- delete reloc_iterator_;
- delete reloc_iterator_original_;
-}
-
-
-// Check whether a code stub with the specified major key is a possible break
-// point location when looking for source break locations.
-static bool IsSourceBreakStub(Code* code) {
- CodeStub::Major major_key = CodeStub::GetMajorKey(code);
- return major_key == CodeStub::CallFunction;
-}
-
-
-// Check whether a code stub with the specified major key is a possible break
-// location.
-static bool IsBreakStub(Code* code) {
- CodeStub::Major major_key = CodeStub::GetMajorKey(code);
- return major_key == CodeStub::CallFunction;
+BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info,
+ BreakLocatorType type)
+ : debug_info_(debug_info),
+ type_(type),
+ reloc_iterator_(debug_info->code(),
+ ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)),
+ reloc_iterator_original_(
+ debug_info->original_code(),
+ ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)),
+ break_index_(-1),
+ position_(1),
+ statement_position_(1) {
+ Next();
}
-void BreakLocationIterator::Next() {
+void BreakLocation::Iterator::Next() {
DisallowHeapAllocation no_gc;
DCHECK(!RinfoDone());
// Iterate through reloc info for code and original code stopping at each
// breakable code target.
- bool first = break_point_ == -1;
+ bool first = break_index_ == -1;
while (!RinfoDone()) {
if (!first) RinfoNext();
first = false;
@@ -115,8 +97,8 @@ void BreakLocationIterator::Next() {
}
// Always update the position as we don't want that to be before the
// statement position.
- position_ = static_cast<int>(
- rinfo()->data() - debug_info_->shared()->start_position());
+ position_ = static_cast<int>(rinfo()->data() -
+ debug_info_->shared()->start_position());
DCHECK(position_ >= 0);
DCHECK(statement_position_ >= 0);
}
@@ -131,7 +113,7 @@ void BreakLocationIterator::Next() {
position_ = 0;
}
statement_position_ = position_;
- break_point_++;
+ break_index_++;
return;
}
@@ -143,7 +125,7 @@ void BreakLocationIterator::Next() {
Code* code = Code::GetCodeFromTargetAddress(target);
if (RelocInfo::IsConstructCall(rmode()) || code->is_call_stub()) {
- break_point_++;
+ break_index_++;
return;
}
@@ -152,144 +134,117 @@ void BreakLocationIterator::Next() {
if ((code->is_inline_cache_stub() && !code->is_binary_op_stub() &&
!code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) {
- break_point_++;
+ break_index_++;
return;
}
if (code->kind() == Code::STUB) {
- if (IsDebuggerStatement()) {
- break_point_++;
+ if (RelocInfo::IsDebuggerStatement(rmode())) {
+ break_index_++;
+ return;
+ } else if (CodeStub::GetMajorKey(code) == CodeStub::CallFunction) {
+ break_index_++;
return;
- } else if (type_ == ALL_BREAK_LOCATIONS) {
- if (IsBreakStub(code)) {
- break_point_++;
- return;
- }
- } else {
- DCHECK(type_ == SOURCE_BREAK_LOCATIONS);
- if (IsSourceBreakStub(code)) {
- break_point_++;
- return;
- }
}
}
}
- if (IsDebugBreakSlot() && type_ != CALLS_AND_RETURNS) {
+ if (RelocInfo::IsDebugBreakSlot(rmode()) && type_ != CALLS_AND_RETURNS) {
// There is always a possible break point at a debug break slot.
- break_point_++;
+ break_index_++;
return;
}
}
}
-void BreakLocationIterator::Next(int count) {
- while (count > 0) {
- Next();
- count--;
- }
+// Find the break point at the supplied address, or the closest one before
+// the address.
+BreakLocation BreakLocation::FromAddress(Handle<DebugInfo> debug_info,
+ BreakLocatorType type, Address pc) {
+ Iterator it(debug_info, type);
+ it.SkipTo(BreakIndexFromAddress(debug_info, type, pc));
+ return it.GetBreakLocation();
}
// Find the break point at the supplied address, or the closest one before
// the address.
-void BreakLocationIterator::FindBreakLocationFromAddress(Address pc) {
+void BreakLocation::FromAddressSameStatement(Handle<DebugInfo> debug_info,
+ BreakLocatorType type, Address pc,
+ List<BreakLocation>* result_out) {
+ int break_index = BreakIndexFromAddress(debug_info, type, pc);
+ Iterator it(debug_info, type);
+ it.SkipTo(break_index);
+ int statement_position = it.statement_position();
+ while (!it.Done() && it.statement_position() == statement_position) {
+ result_out->Add(it.GetBreakLocation());
+ it.Next();
+ }
+}
+
+
+int BreakLocation::BreakIndexFromAddress(Handle<DebugInfo> debug_info,
+ BreakLocatorType type, Address pc) {
// Run through all break points to locate the one closest to the address.
- int closest_break_point = 0;
+ int closest_break = 0;
int distance = kMaxInt;
- while (!Done()) {
+ for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
// Check if this break point is closer that what was previously found.
- if (this->pc() <= pc && pc - this->pc() < distance) {
- closest_break_point = break_point();
- distance = static_cast<int>(pc - this->pc());
+ if (it.pc() <= pc && pc - it.pc() < distance) {
+ closest_break = it.break_index();
+ distance = static_cast<int>(pc - it.pc());
// Check whether we can't get any closer.
if (distance == 0) break;
}
- Next();
}
-
- // Move to the break point found.
- Reset();
- Next(closest_break_point);
+ return closest_break;
}
-// Find the break point closest to the supplied source position.
-void BreakLocationIterator::FindBreakLocationFromPosition(int position,
- BreakPositionAlignment alignment) {
+BreakLocation BreakLocation::FromPosition(Handle<DebugInfo> debug_info,
+ BreakLocatorType type, int position,
+ BreakPositionAlignment alignment) {
// Run through all break points to locate the one closest to the source
// position.
- int closest_break_point = 0;
+ int closest_break = 0;
int distance = kMaxInt;
- while (!Done()) {
+ for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
int next_position;
- switch (alignment) {
- case STATEMENT_ALIGNED:
- next_position = this->statement_position();
- break;
- case BREAK_POSITION_ALIGNED:
- next_position = this->position();
- break;
- default:
- UNREACHABLE();
- next_position = this->statement_position();
+ if (alignment == STATEMENT_ALIGNED) {
+ next_position = it.statement_position();
+ } else {
+ DCHECK(alignment == BREAK_POSITION_ALIGNED);
+ next_position = it.position();
}
- // Check if this break point is closer that what was previously found.
if (position <= next_position && next_position - position < distance) {
- closest_break_point = break_point();
+ closest_break = it.break_index();
distance = next_position - position;
// Check whether we can't get any closer.
if (distance == 0) break;
}
- Next();
}
- // Move to the break point found.
- Reset();
- Next(closest_break_point);
+ Iterator it(debug_info, type);
+ it.SkipTo(closest_break);
+ return it.GetBreakLocation();
}
-void BreakLocationIterator::Reset() {
- // Create relocation iterators for the two code objects.
- if (reloc_iterator_ != NULL) delete reloc_iterator_;
- if (reloc_iterator_original_ != NULL) delete reloc_iterator_original_;
- reloc_iterator_ = new RelocIterator(
- debug_info_->code(),
- ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE));
- reloc_iterator_original_ = new RelocIterator(
- debug_info_->original_code(),
- ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE));
-
- // Position at the first break point.
- break_point_ = -1;
- position_ = 1;
- statement_position_ = 1;
- Next();
-}
-
-
-bool BreakLocationIterator::Done() const {
- return RinfoDone();
-}
-
-
-void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) {
+void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) {
// If there is not already a real break point here patch code with debug
// break.
if (!HasBreakPoint()) SetDebugBreak();
DCHECK(IsDebugBreak() || IsDebuggerStatement());
// Set the break point information.
- DebugInfo::SetBreakPoint(debug_info_, code_position(),
- position(), statement_position(),
- break_point_object);
+ DebugInfo::SetBreakPoint(debug_info_, pc_offset_, position_,
+ statement_position_, break_point_object);
}
-void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
+void BreakLocation::ClearBreakPoint(Handle<Object> break_point_object) {
// Clear the break point information.
- DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
+ DebugInfo::ClearBreakPoint(debug_info_, pc_offset_, break_point_object);
// If there are no more break points here remove the debug break.
if (!HasBreakPoint()) {
ClearDebugBreak();
@@ -298,7 +253,7 @@ void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
}
-void BreakLocationIterator::SetOneShot() {
+void BreakLocation::SetOneShot() {
// Debugger statement always calls debugger. No need to modify it.
if (IsDebuggerStatement()) return;
@@ -313,7 +268,7 @@ void BreakLocationIterator::SetOneShot() {
}
-void BreakLocationIterator::ClearOneShot() {
+void BreakLocation::ClearOneShot() {
// Debugger statement always calls debugger. No need to modify it.
if (IsDebuggerStatement()) return;
@@ -329,7 +284,7 @@ void BreakLocationIterator::ClearOneShot() {
}
-void BreakLocationIterator::SetDebugBreak() {
+void BreakLocation::SetDebugBreak() {
// Debugger statement always calls debugger. No need to modify it.
if (IsDebuggerStatement()) return;
@@ -339,7 +294,7 @@ void BreakLocationIterator::SetDebugBreak() {
// handler as the handler and the function is the same.
if (IsDebugBreak()) return;
- if (RelocInfo::IsJSReturn(rmode())) {
+ if (IsExit()) {
// Patch the frame exit code with a break point.
SetDebugBreakAtReturn();
} else if (IsDebugBreakSlot()) {
@@ -353,59 +308,48 @@ void BreakLocationIterator::SetDebugBreak() {
}
-void BreakLocationIterator::ClearDebugBreak() {
+void BreakLocation::ClearDebugBreak() {
// Debugger statement always calls debugger. No need to modify it.
if (IsDebuggerStatement()) return;
- if (RelocInfo::IsJSReturn(rmode())) {
- // Restore the frame exit code.
- ClearDebugBreakAtReturn();
+ if (IsExit()) {
+ // Restore the frame exit code with a break point.
+ RestoreFromOriginal(Assembler::kJSReturnSequenceLength);
} else if (IsDebugBreakSlot()) {
// Restore the code in the break slot.
- ClearDebugBreakAtSlot();
+ RestoreFromOriginal(Assembler::kDebugBreakSlotLength);
} else {
- // Patch the IC call.
- ClearDebugBreakAtIC();
+ // Restore the IC call.
+ rinfo().set_target_address(original_rinfo().target_address());
}
DCHECK(!IsDebugBreak());
}
-bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) {
- if (RelocInfo::IsConstructCall(original_rmode())) {
- return true;
- } else if (RelocInfo::IsCodeTarget(rmode())) {
+void BreakLocation::RestoreFromOriginal(int length_in_bytes) {
+ memcpy(pc(), original_pc(), length_in_bytes);
+ CpuFeatures::FlushICache(pc(), length_in_bytes);
+}
+
+
+bool BreakLocation::IsStepInLocation() const {
+ if (IsConstructCall()) return true;
+ if (RelocInfo::IsCodeTarget(rmode())) {
HandleScope scope(debug_info_->GetIsolate());
- Address target = original_rinfo()->target_address();
- Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
- if (target_code->kind() == Code::STUB) {
- return CodeStub::GetMajorKey(*target_code) == CodeStub::CallFunction;
- }
+ Handle<Code> target_code = CodeTarget();
return target_code->is_call_stub();
}
return false;
}
-// Check whether the break point is at a position which will exit the function.
-bool BreakLocationIterator::IsExit() const {
- return (RelocInfo::IsJSReturn(rmode()));
-}
-
-
-bool BreakLocationIterator::HasBreakPoint() {
- return debug_info_->HasBreakPoint(code_position());
-}
-
-
-// Check whether there is a debug break at the current position.
-bool BreakLocationIterator::IsDebugBreak() {
- if (RelocInfo::IsJSReturn(rmode())) {
- return IsDebugBreakAtReturn();
+bool BreakLocation::IsDebugBreak() const {
+ if (IsExit()) {
+ return rinfo().IsPatchedReturnSequence();
} else if (IsDebugBreakSlot()) {
- return IsDebugBreakAtSlot();
+ return rinfo().IsPatchedDebugBreakSlotSequence();
} else {
- return Debug::IsDebugBreak(rinfo()->target_address());
+ return Debug::IsDebugBreak(rinfo().target_address());
}
}
@@ -457,70 +401,53 @@ static Handle<Code> DebugBreakForIC(Handle<Code> code, RelocInfo::Mode mode) {
}
-void BreakLocationIterator::SetDebugBreakAtIC() {
+void BreakLocation::SetDebugBreakAtIC() {
// Patch the original code with the current address as the current address
// might have changed by the inline caching since the code was copied.
- original_rinfo()->set_target_address(rinfo()->target_address());
+ original_rinfo().set_target_address(rinfo().target_address());
- RelocInfo::Mode mode = rmode();
- if (RelocInfo::IsCodeTarget(mode)) {
- Address target = rinfo()->target_address();
- Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
+ if (RelocInfo::IsCodeTarget(rmode_)) {
+ Handle<Code> target_code = CodeTarget();
// Patch the code to invoke the builtin debug break function matching the
// calling convention used by the call site.
- Handle<Code> dbgbrk_code = DebugBreakForIC(target_code, mode);
- rinfo()->set_target_address(dbgbrk_code->entry());
+ Handle<Code> debug_break_code = DebugBreakForIC(target_code, rmode_);
+ rinfo().set_target_address(debug_break_code->entry());
}
}
-void BreakLocationIterator::ClearDebugBreakAtIC() {
- // Patch the code to the original invoke.
- rinfo()->set_target_address(original_rinfo()->target_address());
+Handle<Object> BreakLocation::BreakPointObjects() const {
+ return debug_info_->GetBreakPointObjects(pc_offset_);
}
-bool BreakLocationIterator::IsDebuggerStatement() {
- return RelocInfo::DEBUG_BREAK == rmode();
+Handle<Code> BreakLocation::CodeTarget() const {
+ DCHECK(IsCodeTarget());
+ Address target = rinfo().target_address();
+ return Handle<Code>(Code::GetCodeFromTargetAddress(target));
}
-bool BreakLocationIterator::IsDebugBreakSlot() {
- return RelocInfo::DEBUG_BREAK_SLOT == rmode();
+Handle<Code> BreakLocation::OriginalCodeTarget() const {
+ DCHECK(IsCodeTarget());
+ Address target = original_rinfo().target_address();
+ return Handle<Code>(Code::GetCodeFromTargetAddress(target));
}
-Object* BreakLocationIterator::BreakPointObjects() {
- return debug_info_->GetBreakPointObjects(code_position());
+bool BreakLocation::Iterator::RinfoDone() const {
+ DCHECK(reloc_iterator_.done() == reloc_iterator_original_.done());
+ return reloc_iterator_.done();
}
-// Clear out all the debug break code. This is ONLY supposed to be used when
-// shutting down the debugger as it will leave the break point information in
-// DebugInfo even though the code is patched back to the non break point state.
-void BreakLocationIterator::ClearAllDebugBreak() {
- while (!Done()) {
- ClearDebugBreak();
- Next();
- }
-}
-
-
-bool BreakLocationIterator::RinfoDone() const {
- DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done());
- return reloc_iterator_->done();
-}
-
-
-void BreakLocationIterator::RinfoNext() {
- reloc_iterator_->next();
- reloc_iterator_original_->next();
+void BreakLocation::Iterator::RinfoNext() {
+ reloc_iterator_.next();
+ reloc_iterator_original_.next();
#ifdef DEBUG
- DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done());
- if (!reloc_iterator_->done()) {
- DCHECK(rmode() == original_rmode());
- }
+ DCHECK(reloc_iterator_.done() == reloc_iterator_original_.done());
+ DCHECK(reloc_iterator_.done() || rmode() == original_rmode());
#endif
}
@@ -854,14 +781,14 @@ void Debug::Break(Arguments args, JavaScriptFrame* frame) {
Handle<DebugInfo> debug_info = GetDebugInfo(shared);
// Find the break point where execution has stopped.
- BreakLocationIterator break_location_iterator(debug_info,
- ALL_BREAK_LOCATIONS);
- // pc points to the instruction after the current one, possibly a break
+ // PC points to the instruction after the current one, possibly a break
// location as well. So the "- 1" to exclude it from the search.
- break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
+ Address call_pc = frame->pc() - 1;
+ BreakLocation break_location =
+ BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
// Check whether step next reached a new statement.
- if (!StepNextContinue(&break_location_iterator, frame)) {
+ if (!StepNextContinue(&break_location, frame)) {
// Decrease steps left if performing multiple steps.
if (thread_local_.step_count_ > 0) {
thread_local_.step_count_--;
@@ -871,9 +798,8 @@ void Debug::Break(Arguments args, JavaScriptFrame* frame) {
// If there is one or more real break points check whether any of these are
// triggered.
Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
- if (break_location_iterator.HasBreakPoint()) {
- Handle<Object> break_point_objects =
- Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_);
+ if (break_location.HasBreakPoint()) {
+ Handle<Object> break_point_objects = break_location.BreakPointObjects();
break_points_hit = CheckBreakPoints(break_point_objects);
}
@@ -1058,11 +984,10 @@ bool Debug::SetBreakPoint(Handle<JSFunction> function,
DCHECK(*source_position >= 0);
// Find the break point and change it.
- BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
- it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED);
- it.SetBreakPoint(break_point_object);
-
- *source_position = it.statement_position();
+ BreakLocation location = BreakLocation::FromPosition(
+ debug_info, SOURCE_BREAK_LOCATIONS, *source_position, STATEMENT_ALIGNED);
+ *source_position = location.statement_position();
+ location.SetBreakPoint(break_point_object);
// At least one active break point now.
return debug_info->GetBreakPointCount() > 0;
@@ -1078,11 +1003,12 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,
PrepareForBreakPoints();
// Obtain shared function info for the function.
- Object* result = FindSharedFunctionInfoInScript(script, *source_position);
+ Handle<Object> result =
+ FindSharedFunctionInfoInScript(script, *source_position);
if (result->IsUndefined()) return false;
// Make sure the function has set up the debug info.
- Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
+ Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
// Return if retrieving debug info failed.
return false;
@@ -1102,12 +1028,12 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,
DCHECK(position >= 0);
// Find the break point and change it.
- BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
- it.FindBreakLocationFromPosition(position, alignment);
- it.SetBreakPoint(break_point_object);
+ BreakLocation location = BreakLocation::FromPosition(
+ debug_info, SOURCE_BREAK_LOCATIONS, position, alignment);
+ location.SetBreakPoint(break_point_object);
- position = (alignment == STATEMENT_ALIGNED) ? it.statement_position()
- : it.position();
+ position = (alignment == STATEMENT_ALIGNED) ? location.statement_position()
+ : location.position();
*source_position = position + shared->start_position();
@@ -1122,18 +1048,21 @@ void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
DebugInfoListNode* node = debug_info_list_;
while (node != NULL) {
- Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(),
- break_point_object);
+ Handle<Object> result =
+ DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object);
if (!result->IsUndefined()) {
// Get information in the break point.
- BreakPointInfo* break_point_info = BreakPointInfo::cast(result);
+ Handle<BreakPointInfo> break_point_info =
+ Handle<BreakPointInfo>::cast(result);
Handle<DebugInfo> debug_info = node->debug_info();
// Find the break point and clear it.
- BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
- it.FindBreakLocationFromAddress(debug_info->code()->entry() +
- break_point_info->code_position()->value());
- it.ClearBreakPoint(break_point_object);
+ Address pc = debug_info->code()->entry() +
+ break_point_info->code_position()->value();
+
+ BreakLocation location =
+ BreakLocation::FromAddress(debug_info, SOURCE_BREAK_LOCATIONS, pc);
+ location.ClearBreakPoint(break_point_object);
// If there are no more break points left remove the debug info for this
// function.
@@ -1148,15 +1077,17 @@ void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
}
+// Clear out all the debug break code. This is ONLY supposed to be used when
+// shutting down the debugger as it will leave the break point information in
+// DebugInfo even though the code is patched back to the non break point state.
void Debug::ClearAllBreakPoints() {
- DebugInfoListNode* node = debug_info_list_;
- while (node != NULL) {
- // Remove all debug break code.
- BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
- it.ClearAllDebugBreak();
- node = node->next();
+ for (DebugInfoListNode* node = debug_info_list_; node != NULL;
+ node = node->next()) {
+ for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
+ !it.Done(); it.Next()) {
+ it.GetBreakLocation().ClearDebugBreak();
+ }
}
-
// Remove all debug info.
while (debug_info_list_ != NULL) {
RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
@@ -1179,10 +1110,9 @@ void Debug::FloodWithOneShot(Handle<JSFunction> function,
}
// Flood the function with break points.
- BreakLocationIterator it(GetDebugInfo(shared), type);
- while (!it.Done()) {
- it.SetOneShot();
- it.Next();
+ for (BreakLocation::Iterator it(GetDebugInfo(shared), type); !it.Done();
+ it.Next()) {
+ it.GetBreakLocation().SetOneShot();
}
}
@@ -1341,64 +1271,49 @@ void Debug::PrepareStep(StepAction step_action,
bool is_load_or_store = false;
bool is_inline_cache_stub = false;
bool is_at_restarted_function = false;
- bool is_exit = false;
- bool is_construct_call = false;
Handle<Code> call_function_stub;
- {
- // Find the break location where execution has stopped.
- DisallowHeapAllocation no_gc;
- BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS);
-
- // pc points to the instruction after the current one, possibly a break
- // location as well. So the "- 1" to exclude it from the search.
- it.FindBreakLocationFromAddress(frame->pc() - 1);
-
- is_exit = it.IsExit();
- is_construct_call = RelocInfo::IsConstructCall(it.rmode());
-
- if (thread_local_.restarter_frame_function_pointer_ == NULL) {
- if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
- bool is_call_target = false;
- Address target = it.rinfo()->target_address();
- Code* code = Code::GetCodeFromTargetAddress(target);
-
- is_call_target = code->is_call_stub();
- is_inline_cache_stub = code->is_inline_cache_stub();
- is_load_or_store = is_inline_cache_stub && !is_call_target;
-
- // Check if target code is CallFunction stub.
- Code* maybe_call_function_stub = code;
- // If there is a breakpoint at this line look at the original code to
- // check if it is a CallFunction stub.
- if (it.IsDebugBreak()) {
- Address original_target = it.original_rinfo()->target_address();
- maybe_call_function_stub =
- Code::GetCodeFromTargetAddress(original_target);
- }
- if ((maybe_call_function_stub->kind() == Code::STUB &&
- CodeStub::GetMajorKey(maybe_call_function_stub) ==
- CodeStub::CallFunction) ||
- maybe_call_function_stub->is_call_stub()) {
- // Save reference to the code as we may need it to find out arguments
- // count for 'step in' later.
- call_function_stub = Handle<Code>(maybe_call_function_stub);
- }
+ // PC points to the instruction after the current one, possibly a break
+ // location as well. So the "- 1" to exclude it from the search.
+ Address call_pc = frame->pc() - 1;
+ BreakLocation location =
+ BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
+
+ if (thread_local_.restarter_frame_function_pointer_ == NULL) {
+ if (location.IsCodeTarget()) {
+ Handle<Code> target_code = location.CodeTarget();
+ is_inline_cache_stub = target_code->is_inline_cache_stub();
+ is_load_or_store = is_inline_cache_stub && !target_code->is_call_stub();
+
+ // Check if target code is CallFunction stub.
+ Handle<Code> maybe_call_function_stub = target_code;
+ // If there is a breakpoint at this line look at the original code to
+ // check if it is a CallFunction stub.
+ if (location.IsDebugBreak()) {
+ maybe_call_function_stub = location.OriginalCodeTarget();
+ }
+ if ((maybe_call_function_stub->kind() == Code::STUB &&
+ CodeStub::GetMajorKey(*maybe_call_function_stub) ==
+ CodeStub::CallFunction) ||
+ maybe_call_function_stub->is_call_stub()) {
+ // Save reference to the code as we may need it to find out arguments
+ // count for 'step in' later.
+ call_function_stub = maybe_call_function_stub;
}
- } else {
- is_at_restarted_function = true;
}
+ } else {
+ is_at_restarted_function = true;
}
// If this is the last break code target step out is the only possibility.
- if (is_exit || step_action == StepOut) {
+ if (location.IsExit() || step_action == StepOut) {
if (step_action == StepOut) {
// Skip step_count frames starting with the current one.
while (step_count-- > 0 && !frames_it.done()) {
frames_it.Advance();
}
} else {
- DCHECK(is_exit);
+ DCHECK(location.IsExit());
frames_it.Advance();
}
// Skip builtin functions on the stack.
@@ -1415,7 +1330,7 @@ void Debug::PrepareStep(StepAction step_action,
// Set target frame pointer.
ActivateStepOut(frames_it.frame());
}
- } else if (!(is_inline_cache_stub || is_construct_call ||
+ } else if (!(is_inline_cache_stub || location.IsConstructCall() ||
!call_function_stub.is_null() || is_at_restarted_function) ||
step_action == StepNext || step_action == StepMin) {
// Step next or step min.
@@ -1511,7 +1426,7 @@ void Debug::PrepareStep(StepAction step_action,
// Step in through CallFunction stub should also be prepared by caller of
// this function (Debug::PrepareStep) which should flood target function
// with breakpoints.
- DCHECK(is_construct_call || is_inline_cache_stub ||
+ DCHECK(location.IsConstructCall() || is_inline_cache_stub ||
!call_function_stub.is_null() || is_at_restarted_function);
ActivateStepIn(frame);
}
@@ -1524,7 +1439,7 @@ void Debug::PrepareStep(StepAction step_action,
// there will be several break points in the same statement when the code is
// flooded with one-shot break points. This function helps to perform several
// steps before reporting break back to the debugger.
-bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
+bool Debug::StepNextContinue(BreakLocation* break_location,
JavaScriptFrame* frame) {
// StepNext and StepOut shouldn't bring us deeper in code, so last frame
// shouldn't be a parent of current frame.
@@ -1543,11 +1458,11 @@ bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
// statement is hit.
if (step_action == StepNext || step_action == StepIn) {
// Never continue if returning from function.
- if (break_location_iterator->IsExit()) return false;
+ if (break_location->IsExit()) return false;
// Continue if we are still on the same frame and in the same statement.
int current_statement_position =
- break_location_iterator->code()->SourceStatementPosition(frame->pc());
+ break_location->code()->SourceStatementPosition(frame->pc());
return thread_local_.last_fp_ == frame->UnpaddedFP() &&
thread_local_.last_statement_position_ == current_statement_position;
}
@@ -1565,9 +1480,6 @@ bool Debug::IsDebugBreak(Address addr) {
}
-
-
-
// Simple function for returning the source positions for active break points.
Handle<Object> Debug::GetSourceBreakLocations(
Handle<SharedFunctionInfo> shared,
@@ -1655,15 +1567,12 @@ void Debug::ClearOneShot() {
// The current implementation just runs through all the breakpoints. When the
// last break point for a function is removed that function is automatically
// removed from the list.
-
- DebugInfoListNode* node = debug_info_list_;
- while (node != NULL) {
- BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
- while (!it.Done()) {
- it.ClearOneShot();
- it.Next();
+ for (DebugInfoListNode* node = debug_info_list_; node != NULL;
+ node = node->next()) {
+ for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
+ !it.Done(); it.Next()) {
+ it.GetBreakLocation().ClearOneShot();
}
- node = node->next();
}
}
@@ -2080,8 +1989,8 @@ void Debug::PrepareForBreakPoints() {
}
-Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
- int position) {
+Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
+ int position) {
// Iterate the heap looking for SharedFunctionInfo generated from the
// script. The inner most SharedFunctionInfo containing the source position
// for the requested break point is found.
@@ -2164,7 +2073,7 @@ Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
} // End for loop.
} // End no-allocation scope.
- if (target.is_null()) return heap->undefined_value();
+ if (target.is_null()) return isolate_->factory()->undefined_value();
// There will be at least one break point when we are done.
has_break_points_ = true;
@@ -2180,11 +2089,11 @@ Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
MaybeHandle<Code> maybe_result = target_function.is_null()
? Compiler::GetUnoptimizedCode(target)
: Compiler::GetUnoptimizedCode(target_function);
- if (maybe_result.is_null()) return isolate_->heap()->undefined_value();
+ if (maybe_result.is_null()) return isolate_->factory()->undefined_value();
}
} // End while loop.
- return *target;
+ return target;
}
« no previous file with comments | « src/debug.h ('k') | src/ia32/assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698