OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 return v8::Utils::ToLocal(native_context); | 59 return v8::Utils::ToLocal(native_context); |
60 } | 60 } |
61 | 61 |
62 BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, DebugBreakType type, | 62 BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, DebugBreakType type, |
63 int code_offset, int position, | 63 int code_offset, int position, |
64 int statement_position) | 64 int statement_position) |
65 : debug_info_(debug_info), | 65 : debug_info_(debug_info), |
66 code_offset_(code_offset), | 66 code_offset_(code_offset), |
67 type_(type), | 67 type_(type), |
68 position_(position), | 68 position_(position), |
69 statement_position_(statement_position) {} | 69 statement_position_(statement_position) { |
| 70 #ifdef DEBUG |
| 71 if (type == DEBUG_BREAK_SLOT_AT_RETURN) { |
| 72 int return_position = 0; |
| 73 SharedFunctionInfo* shared = debug_info->shared(); |
| 74 if (shared->HasSourceCode()) { |
| 75 return_position = |
| 76 std::max(shared->end_position() - shared->start_position() - 1, 0); |
| 77 } |
| 78 CHECK_EQ(return_position, position); |
| 79 CHECK_EQ(return_position, statement_position); |
| 80 } |
| 81 #endif // DEBUG |
| 82 } |
70 | 83 |
71 BreakLocation::Iterator* BreakLocation::GetIterator( | 84 BreakLocation::Iterator* BreakLocation::GetIterator( |
72 Handle<DebugInfo> debug_info, BreakLocatorType type) { | 85 Handle<DebugInfo> debug_info, BreakLocatorType type) { |
73 if (debug_info->abstract_code()->IsBytecodeArray()) { | 86 if (debug_info->abstract_code()->IsBytecodeArray()) { |
74 return new BytecodeArrayIterator(debug_info, type); | 87 return new BytecodeArrayIterator(debug_info, type); |
75 } else { | 88 } else { |
76 return new CodeIterator(debug_info, type); | 89 return new CodeIterator(debug_info, type); |
77 } | 90 } |
78 } | 91 } |
79 | 92 |
80 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info) | 93 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info) |
81 : debug_info_(debug_info), | 94 : debug_info_(debug_info), |
82 break_index_(-1), | 95 break_index_(-1), |
83 position_(1), | 96 position_(1), |
84 statement_position_(1) {} | 97 statement_position_(1) {} |
85 | 98 |
86 int BreakLocation::Iterator::ReturnPosition() { | |
87 if (debug_info_->shared()->HasSourceCode()) { | |
88 return debug_info_->shared()->end_position() - | |
89 debug_info_->shared()->start_position() - 1; | |
90 } else { | |
91 return 0; | |
92 } | |
93 } | |
94 | |
95 BreakLocation::CodeIterator::CodeIterator(Handle<DebugInfo> debug_info, | 99 BreakLocation::CodeIterator::CodeIterator(Handle<DebugInfo> debug_info, |
96 BreakLocatorType type) | 100 BreakLocatorType type) |
97 : Iterator(debug_info), | 101 : Iterator(debug_info), |
98 reloc_iterator_(debug_info->abstract_code()->GetCode(), | 102 reloc_iterator_(debug_info->abstract_code()->GetCode(), |
99 GetModeMask(type)) { | 103 GetModeMask(type)), |
| 104 source_position_iterator_( |
| 105 debug_info->abstract_code()->GetCode()->source_position_table()), |
| 106 start_position_(debug_info_->shared()->start_position()) { |
100 // There is at least one break location. | 107 // There is at least one break location. |
101 DCHECK(!Done()); | 108 DCHECK(!Done()); |
102 Next(); | 109 Next(); |
103 } | 110 } |
104 | 111 |
105 int BreakLocation::CodeIterator::GetModeMask(BreakLocatorType type) { | 112 int BreakLocation::CodeIterator::GetModeMask(BreakLocatorType type) { |
106 int mask = 0; | 113 int mask = 0; |
107 mask |= RelocInfo::ModeMask(RelocInfo::POSITION); | |
108 mask |= RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION); | |
109 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN); | 114 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN); |
110 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL); | 115 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL); |
111 if (isolate()->is_tail_call_elimination_enabled()) { | 116 if (isolate()->is_tail_call_elimination_enabled()) { |
112 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL); | 117 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL); |
113 } | 118 } |
114 if (type == ALL_BREAK_LOCATIONS) { | 119 if (type == ALL_BREAK_LOCATIONS) { |
115 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION); | 120 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION); |
116 mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT); | 121 mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT); |
117 } | 122 } |
118 return mask; | 123 return mask; |
119 } | 124 } |
120 | 125 |
121 void BreakLocation::CodeIterator::Next() { | 126 void BreakLocation::CodeIterator::Next() { |
122 DisallowHeapAllocation no_gc; | 127 DisallowHeapAllocation no_gc; |
123 DCHECK(!Done()); | 128 DCHECK(!Done()); |
124 | 129 |
125 // Iterate through reloc info stopping at each breakable code target. | 130 // Iterate through reloc info stopping at each breakable code target. |
126 bool first = break_index_ == -1; | 131 bool first = break_index_ == -1; |
127 while (!Done()) { | |
128 if (!first) reloc_iterator_.next(); | |
129 first = false; | |
130 if (Done()) return; | |
131 | 132 |
132 // Whenever a statement position or (plain) position is passed update the | 133 if (!first) reloc_iterator_.next(); |
133 // current value of these. | 134 first = false; |
134 if (RelocInfo::IsPosition(rmode())) { | 135 if (Done()) return; |
135 if (RelocInfo::IsStatementPosition(rmode())) { | 136 |
136 statement_position_ = static_cast<int>( | 137 int offset = code_offset(); |
137 rinfo()->data() - debug_info_->shared()->start_position()); | 138 while (!source_position_iterator_.done() && |
138 } | 139 source_position_iterator_.code_offset() <= offset) { |
139 // Always update the position as we don't want that to be before the | 140 position_ = source_position_iterator_.source_position() - start_position_; |
140 // statement position. | 141 if (source_position_iterator_.is_statement()) { |
141 position_ = static_cast<int>(rinfo()->data() - | 142 statement_position_ = position_; |
142 debug_info_->shared()->start_position()); | |
143 DCHECK(position_ >= 0); | |
144 DCHECK(statement_position_ >= 0); | |
145 continue; | |
146 } | 143 } |
| 144 source_position_iterator_.Advance(); |
| 145 } |
147 | 146 |
148 DCHECK(RelocInfo::IsDebugBreakSlot(rmode()) || | 147 DCHECK(RelocInfo::IsDebugBreakSlot(rmode()) || |
149 RelocInfo::IsDebuggerStatement(rmode())); | 148 RelocInfo::IsDebuggerStatement(rmode())); |
150 | |
151 if (RelocInfo::IsDebugBreakSlotAtReturn(rmode())) { | |
152 // Set the positions to the end of the function. | |
153 statement_position_ = position_ = ReturnPosition(); | |
154 } | |
155 | |
156 break; | |
157 } | |
158 break_index_++; | 149 break_index_++; |
159 } | 150 } |
160 | 151 |
161 BreakLocation BreakLocation::CodeIterator::GetBreakLocation() { | 152 BreakLocation BreakLocation::CodeIterator::GetBreakLocation() { |
162 DebugBreakType type; | 153 DebugBreakType type; |
163 if (RelocInfo::IsDebugBreakSlotAtReturn(rmode())) { | 154 if (RelocInfo::IsDebugBreakSlotAtReturn(rmode())) { |
164 type = DEBUG_BREAK_SLOT_AT_RETURN; | 155 type = DEBUG_BREAK_SLOT_AT_RETURN; |
165 } else if (RelocInfo::IsDebugBreakSlotAtCall(rmode())) { | 156 } else if (RelocInfo::IsDebugBreakSlotAtCall(rmode())) { |
166 type = DEBUG_BREAK_SLOT_AT_CALL; | 157 type = DEBUG_BREAK_SLOT_AT_CALL; |
167 } else if (RelocInfo::IsDebugBreakSlotAtTailCall(rmode())) { | 158 } else if (RelocInfo::IsDebugBreakSlotAtTailCall(rmode())) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 DCHECK(position_ >= 0); | 198 DCHECK(position_ >= 0); |
208 DCHECK(statement_position_ >= 0); | 199 DCHECK(statement_position_ >= 0); |
209 | 200 |
210 enum DebugBreakType type = GetDebugBreakType(); | 201 enum DebugBreakType type = GetDebugBreakType(); |
211 if (type == NOT_DEBUG_BREAK) continue; | 202 if (type == NOT_DEBUG_BREAK) continue; |
212 | 203 |
213 if (break_locator_type_ == ALL_BREAK_LOCATIONS) break; | 204 if (break_locator_type_ == ALL_BREAK_LOCATIONS) break; |
214 | 205 |
215 DCHECK_EQ(CALLS_AND_RETURNS, break_locator_type_); | 206 DCHECK_EQ(CALLS_AND_RETURNS, break_locator_type_); |
216 if (type == DEBUG_BREAK_SLOT_AT_CALL) break; | 207 if (type == DEBUG_BREAK_SLOT_AT_CALL) break; |
217 if (type == DEBUG_BREAK_SLOT_AT_RETURN) { | 208 if (type == DEBUG_BREAK_SLOT_AT_RETURN) break; |
218 DCHECK_EQ(ReturnPosition(), position_); | |
219 DCHECK_EQ(ReturnPosition(), statement_position_); | |
220 break; | |
221 } | |
222 } | 209 } |
223 break_index_++; | 210 break_index_++; |
224 } | 211 } |
225 | 212 |
226 BreakLocation::DebugBreakType | 213 BreakLocation::DebugBreakType |
227 BreakLocation::BytecodeArrayIterator::GetDebugBreakType() { | 214 BreakLocation::BytecodeArrayIterator::GetDebugBreakType() { |
228 BytecodeArray* bytecode_array = debug_info_->original_bytecode_array(); | 215 BytecodeArray* bytecode_array = debug_info_->original_bytecode_array(); |
229 interpreter::Bytecode bytecode = | 216 interpreter::Bytecode bytecode = |
230 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset())); | 217 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset())); |
231 | 218 |
(...skipping 2364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2596 } | 2583 } |
2597 | 2584 |
2598 | 2585 |
2599 void LockingCommandMessageQueue::Clear() { | 2586 void LockingCommandMessageQueue::Clear() { |
2600 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2587 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
2601 queue_.Clear(); | 2588 queue_.Clear(); |
2602 } | 2589 } |
2603 | 2590 |
2604 } // namespace internal | 2591 } // namespace internal |
2605 } // namespace v8 | 2592 } // namespace v8 |
OLD | NEW |