| 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/v8.h" | 5 #include "src/v8.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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { | 53 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { |
| 54 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); | 54 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); |
| 55 // Isolate::context() may have been NULL when "script collected" event | 55 // Isolate::context() may have been NULL when "script collected" event |
| 56 // occured. | 56 // occured. |
| 57 if (context.is_null()) return v8::Local<v8::Context>(); | 57 if (context.is_null()) return v8::Local<v8::Context>(); |
| 58 Handle<Context> native_context(context->native_context()); | 58 Handle<Context> native_context(context->native_context()); |
| 59 return v8::Utils::ToLocal(native_context); | 59 return v8::Utils::ToLocal(native_context); |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 BreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info, | 63 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info, |
| 64 BreakLocatorType type) { | 64 BreakLocatorType type) |
| 65 debug_info_ = debug_info; | 65 : debug_info_(debug_info), |
| 66 type_ = type; | 66 type_(type), |
| 67 reloc_iterator_ = NULL; | 67 reloc_iterator_(debug_info->code(), |
| 68 reloc_iterator_original_ = NULL; | 68 ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)), |
| 69 Reset(); // Initialize the rest of the member variables. | 69 reloc_iterator_original_( |
| 70 debug_info->original_code(), |
| 71 ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)), |
| 72 break_index_(-1), |
| 73 position_(1), |
| 74 statement_position_(1) { |
| 75 Next(); |
| 70 } | 76 } |
| 71 | 77 |
| 72 | 78 |
| 73 BreakLocationIterator::~BreakLocationIterator() { | 79 void BreakLocation::Iterator::Next() { |
| 74 DCHECK(reloc_iterator_ != NULL); | |
| 75 DCHECK(reloc_iterator_original_ != NULL); | |
| 76 delete reloc_iterator_; | |
| 77 delete reloc_iterator_original_; | |
| 78 } | |
| 79 | |
| 80 | |
| 81 // Check whether a code stub with the specified major key is a possible break | |
| 82 // point location when looking for source break locations. | |
| 83 static bool IsSourceBreakStub(Code* code) { | |
| 84 CodeStub::Major major_key = CodeStub::GetMajorKey(code); | |
| 85 return major_key == CodeStub::CallFunction; | |
| 86 } | |
| 87 | |
| 88 | |
| 89 // Check whether a code stub with the specified major key is a possible break | |
| 90 // location. | |
| 91 static bool IsBreakStub(Code* code) { | |
| 92 CodeStub::Major major_key = CodeStub::GetMajorKey(code); | |
| 93 return major_key == CodeStub::CallFunction; | |
| 94 } | |
| 95 | |
| 96 | |
| 97 void BreakLocationIterator::Next() { | |
| 98 DisallowHeapAllocation no_gc; | 80 DisallowHeapAllocation no_gc; |
| 99 DCHECK(!RinfoDone()); | 81 DCHECK(!RinfoDone()); |
| 100 | 82 |
| 101 // Iterate through reloc info for code and original code stopping at each | 83 // Iterate through reloc info for code and original code stopping at each |
| 102 // breakable code target. | 84 // breakable code target. |
| 103 bool first = break_point_ == -1; | 85 bool first = break_index_ == -1; |
| 104 while (!RinfoDone()) { | 86 while (!RinfoDone()) { |
| 105 if (!first) RinfoNext(); | 87 if (!first) RinfoNext(); |
| 106 first = false; | 88 first = false; |
| 107 if (RinfoDone()) return; | 89 if (RinfoDone()) return; |
| 108 | 90 |
| 109 // Whenever a statement position or (plain) position is passed update the | 91 // Whenever a statement position or (plain) position is passed update the |
| 110 // current value of these. | 92 // current value of these. |
| 111 if (RelocInfo::IsPosition(rmode())) { | 93 if (RelocInfo::IsPosition(rmode())) { |
| 112 if (RelocInfo::IsStatementPosition(rmode())) { | 94 if (RelocInfo::IsStatementPosition(rmode())) { |
| 113 statement_position_ = static_cast<int>( | 95 statement_position_ = static_cast<int>( |
| 114 rinfo()->data() - debug_info_->shared()->start_position()); | 96 rinfo()->data() - debug_info_->shared()->start_position()); |
| 115 } | 97 } |
| 116 // Always update the position as we don't want that to be before the | 98 // Always update the position as we don't want that to be before the |
| 117 // statement position. | 99 // statement position. |
| 118 position_ = static_cast<int>( | 100 position_ = static_cast<int>(rinfo()->data() - |
| 119 rinfo()->data() - debug_info_->shared()->start_position()); | 101 debug_info_->shared()->start_position()); |
| 120 DCHECK(position_ >= 0); | 102 DCHECK(position_ >= 0); |
| 121 DCHECK(statement_position_ >= 0); | 103 DCHECK(statement_position_ >= 0); |
| 122 } | 104 } |
| 123 | 105 |
| 124 // Check for break at return. | 106 // Check for break at return. |
| 125 if (RelocInfo::IsJSReturn(rmode())) { | 107 if (RelocInfo::IsJSReturn(rmode())) { |
| 126 // Set the positions to the end of the function. | 108 // Set the positions to the end of the function. |
| 127 if (debug_info_->shared()->HasSourceCode()) { | 109 if (debug_info_->shared()->HasSourceCode()) { |
| 128 position_ = debug_info_->shared()->end_position() - | 110 position_ = debug_info_->shared()->end_position() - |
| 129 debug_info_->shared()->start_position() - 1; | 111 debug_info_->shared()->start_position() - 1; |
| 130 } else { | 112 } else { |
| 131 position_ = 0; | 113 position_ = 0; |
| 132 } | 114 } |
| 133 statement_position_ = position_; | 115 statement_position_ = position_; |
| 134 break_point_++; | 116 break_index_++; |
| 135 return; | 117 return; |
| 136 } | 118 } |
| 137 | 119 |
| 138 if (RelocInfo::IsCodeTarget(rmode())) { | 120 if (RelocInfo::IsCodeTarget(rmode())) { |
| 139 // Check for breakable code target. Look in the original code as setting | 121 // Check for breakable code target. Look in the original code as setting |
| 140 // break points can cause the code targets in the running (debugged) code | 122 // break points can cause the code targets in the running (debugged) code |
| 141 // to be of a different kind than in the original code. | 123 // to be of a different kind than in the original code. |
| 142 Address target = original_rinfo()->target_address(); | 124 Address target = original_rinfo()->target_address(); |
| 143 Code* code = Code::GetCodeFromTargetAddress(target); | 125 Code* code = Code::GetCodeFromTargetAddress(target); |
| 144 | 126 |
| 145 if (RelocInfo::IsConstructCall(rmode()) || code->is_call_stub()) { | 127 if (RelocInfo::IsConstructCall(rmode()) || code->is_call_stub()) { |
| 146 break_point_++; | 128 break_index_++; |
| 147 return; | 129 return; |
| 148 } | 130 } |
| 149 | 131 |
| 150 // Skip below if we only want locations for calls and returns. | 132 // Skip below if we only want locations for calls and returns. |
| 151 if (type_ == CALLS_AND_RETURNS) continue; | 133 if (type_ == CALLS_AND_RETURNS) continue; |
| 152 | 134 |
| 153 if ((code->is_inline_cache_stub() && !code->is_binary_op_stub() && | 135 if ((code->is_inline_cache_stub() && !code->is_binary_op_stub() && |
| 154 !code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) { | 136 !code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) { |
| 155 break_point_++; | 137 break_index_++; |
| 156 return; | 138 return; |
| 157 } | 139 } |
| 158 if (code->kind() == Code::STUB) { | 140 if (code->kind() == Code::STUB) { |
| 159 if (IsDebuggerStatement()) { | 141 if (RelocInfo::IsDebuggerStatement(rmode())) { |
| 160 break_point_++; | 142 break_index_++; |
| 161 return; | 143 return; |
| 162 } else if (type_ == ALL_BREAK_LOCATIONS) { | 144 } else if (CodeStub::GetMajorKey(code) == CodeStub::CallFunction) { |
| 163 if (IsBreakStub(code)) { | 145 break_index_++; |
| 164 break_point_++; | 146 return; |
| 165 return; | |
| 166 } | |
| 167 } else { | |
| 168 DCHECK(type_ == SOURCE_BREAK_LOCATIONS); | |
| 169 if (IsSourceBreakStub(code)) { | |
| 170 break_point_++; | |
| 171 return; | |
| 172 } | |
| 173 } | 147 } |
| 174 } | 148 } |
| 175 } | 149 } |
| 176 | 150 |
| 177 if (IsDebugBreakSlot() && type_ != CALLS_AND_RETURNS) { | 151 if (RelocInfo::IsDebugBreakSlot(rmode()) && type_ != CALLS_AND_RETURNS) { |
| 178 // There is always a possible break point at a debug break slot. | 152 // There is always a possible break point at a debug break slot. |
| 179 break_point_++; | 153 break_index_++; |
| 180 return; | 154 return; |
| 181 } | 155 } |
| 182 } | 156 } |
| 183 } | 157 } |
| 184 | 158 |
| 185 | 159 |
| 186 void BreakLocationIterator::Next(int count) { | 160 // Find the break point at the supplied address, or the closest one before |
| 187 while (count > 0) { | 161 // the address. |
| 188 Next(); | 162 BreakLocation BreakLocation::FromAddress(Handle<DebugInfo> debug_info, |
| 189 count--; | 163 BreakLocatorType type, Address pc) { |
| 190 } | 164 Iterator it(debug_info, type); |
| 165 it.SkipTo(BreakIndexFromAddress(debug_info, type, pc)); |
| 166 return it.GetBreakLocation(); |
| 191 } | 167 } |
| 192 | 168 |
| 193 | 169 |
| 194 // Find the break point at the supplied address, or the closest one before | 170 // Find the break point at the supplied address, or the closest one before |
| 195 // the address. | 171 // the address. |
| 196 void BreakLocationIterator::FindBreakLocationFromAddress(Address pc) { | 172 void BreakLocation::FromAddressSameStatement(Handle<DebugInfo> debug_info, |
| 173 BreakLocatorType type, Address pc, |
| 174 List<BreakLocation>* result_out) { |
| 175 int break_index = BreakIndexFromAddress(debug_info, type, pc); |
| 176 Iterator it(debug_info, type); |
| 177 it.SkipTo(break_index); |
| 178 int statement_position = it.statement_position(); |
| 179 while (!it.Done() && it.statement_position() == statement_position) { |
| 180 result_out->Add(it.GetBreakLocation()); |
| 181 it.Next(); |
| 182 } |
| 183 } |
| 184 |
| 185 |
| 186 int BreakLocation::BreakIndexFromAddress(Handle<DebugInfo> debug_info, |
| 187 BreakLocatorType type, Address pc) { |
| 197 // Run through all break points to locate the one closest to the address. | 188 // Run through all break points to locate the one closest to the address. |
| 198 int closest_break_point = 0; | 189 int closest_break = 0; |
| 199 int distance = kMaxInt; | 190 int distance = kMaxInt; |
| 200 while (!Done()) { | 191 for (Iterator it(debug_info, type); !it.Done(); it.Next()) { |
| 201 // Check if this break point is closer that what was previously found. | 192 // Check if this break point is closer that what was previously found. |
| 202 if (this->pc() <= pc && pc - this->pc() < distance) { | 193 if (it.pc() <= pc && pc - it.pc() < distance) { |
| 203 closest_break_point = break_point(); | 194 closest_break = it.break_index(); |
| 204 distance = static_cast<int>(pc - this->pc()); | 195 distance = static_cast<int>(pc - it.pc()); |
| 205 // Check whether we can't get any closer. | 196 // Check whether we can't get any closer. |
| 206 if (distance == 0) break; | 197 if (distance == 0) break; |
| 207 } | 198 } |
| 208 Next(); | |
| 209 } | 199 } |
| 210 | 200 return closest_break; |
| 211 // Move to the break point found. | |
| 212 Reset(); | |
| 213 Next(closest_break_point); | |
| 214 } | 201 } |
| 215 | 202 |
| 216 | 203 |
| 217 // Find the break point closest to the supplied source position. | 204 BreakLocation BreakLocation::FromPosition(Handle<DebugInfo> debug_info, |
| 218 void BreakLocationIterator::FindBreakLocationFromPosition(int position, | 205 BreakLocatorType type, int position, |
| 219 BreakPositionAlignment alignment) { | 206 BreakPositionAlignment alignment) { |
| 220 // Run through all break points to locate the one closest to the source | 207 // Run through all break points to locate the one closest to the source |
| 221 // position. | 208 // position. |
| 222 int closest_break_point = 0; | 209 int closest_break = 0; |
| 223 int distance = kMaxInt; | 210 int distance = kMaxInt; |
| 224 | 211 |
| 225 while (!Done()) { | 212 for (Iterator it(debug_info, type); !it.Done(); it.Next()) { |
| 226 int next_position; | 213 int next_position; |
| 227 switch (alignment) { | 214 if (alignment == STATEMENT_ALIGNED) { |
| 228 case STATEMENT_ALIGNED: | 215 next_position = it.statement_position(); |
| 229 next_position = this->statement_position(); | 216 } else { |
| 230 break; | 217 DCHECK(alignment == BREAK_POSITION_ALIGNED); |
| 231 case BREAK_POSITION_ALIGNED: | 218 next_position = it.position(); |
| 232 next_position = this->position(); | |
| 233 break; | |
| 234 default: | |
| 235 UNREACHABLE(); | |
| 236 next_position = this->statement_position(); | |
| 237 } | 219 } |
| 238 // Check if this break point is closer that what was previously found. | |
| 239 if (position <= next_position && next_position - position < distance) { | 220 if (position <= next_position && next_position - position < distance) { |
| 240 closest_break_point = break_point(); | 221 closest_break = it.break_index(); |
| 241 distance = next_position - position; | 222 distance = next_position - position; |
| 242 // Check whether we can't get any closer. | 223 // Check whether we can't get any closer. |
| 243 if (distance == 0) break; | 224 if (distance == 0) break; |
| 244 } | 225 } |
| 245 Next(); | |
| 246 } | 226 } |
| 247 | 227 |
| 248 // Move to the break point found. | 228 Iterator it(debug_info, type); |
| 249 Reset(); | 229 it.SkipTo(closest_break); |
| 250 Next(closest_break_point); | 230 return it.GetBreakLocation(); |
| 251 } | 231 } |
| 252 | 232 |
| 253 | 233 |
| 254 void BreakLocationIterator::Reset() { | 234 void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) { |
| 255 // Create relocation iterators for the two code objects. | |
| 256 if (reloc_iterator_ != NULL) delete reloc_iterator_; | |
| 257 if (reloc_iterator_original_ != NULL) delete reloc_iterator_original_; | |
| 258 reloc_iterator_ = new RelocIterator( | |
| 259 debug_info_->code(), | |
| 260 ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)); | |
| 261 reloc_iterator_original_ = new RelocIterator( | |
| 262 debug_info_->original_code(), | |
| 263 ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)); | |
| 264 | |
| 265 // Position at the first break point. | |
| 266 break_point_ = -1; | |
| 267 position_ = 1; | |
| 268 statement_position_ = 1; | |
| 269 Next(); | |
| 270 } | |
| 271 | |
| 272 | |
| 273 bool BreakLocationIterator::Done() const { | |
| 274 return RinfoDone(); | |
| 275 } | |
| 276 | |
| 277 | |
| 278 void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) { | |
| 279 // If there is not already a real break point here patch code with debug | 235 // If there is not already a real break point here patch code with debug |
| 280 // break. | 236 // break. |
| 281 if (!HasBreakPoint()) SetDebugBreak(); | 237 if (!HasBreakPoint()) SetDebugBreak(); |
| 282 DCHECK(IsDebugBreak() || IsDebuggerStatement()); | 238 DCHECK(IsDebugBreak() || IsDebuggerStatement()); |
| 283 // Set the break point information. | 239 // Set the break point information. |
| 284 DebugInfo::SetBreakPoint(debug_info_, code_position(), | 240 DebugInfo::SetBreakPoint(debug_info_, pc_offset_, position_, |
| 285 position(), statement_position(), | 241 statement_position_, break_point_object); |
| 286 break_point_object); | |
| 287 } | 242 } |
| 288 | 243 |
| 289 | 244 |
| 290 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) { | 245 void BreakLocation::ClearBreakPoint(Handle<Object> break_point_object) { |
| 291 // Clear the break point information. | 246 // Clear the break point information. |
| 292 DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object); | 247 DebugInfo::ClearBreakPoint(debug_info_, pc_offset_, break_point_object); |
| 293 // If there are no more break points here remove the debug break. | 248 // If there are no more break points here remove the debug break. |
| 294 if (!HasBreakPoint()) { | 249 if (!HasBreakPoint()) { |
| 295 ClearDebugBreak(); | 250 ClearDebugBreak(); |
| 296 DCHECK(!IsDebugBreak()); | 251 DCHECK(!IsDebugBreak()); |
| 297 } | 252 } |
| 298 } | 253 } |
| 299 | 254 |
| 300 | 255 |
| 301 void BreakLocationIterator::SetOneShot() { | 256 void BreakLocation::SetOneShot() { |
| 302 // Debugger statement always calls debugger. No need to modify it. | 257 // Debugger statement always calls debugger. No need to modify it. |
| 303 if (IsDebuggerStatement()) return; | 258 if (IsDebuggerStatement()) return; |
| 304 | 259 |
| 305 // If there is a real break point here no more to do. | 260 // If there is a real break point here no more to do. |
| 306 if (HasBreakPoint()) { | 261 if (HasBreakPoint()) { |
| 307 DCHECK(IsDebugBreak()); | 262 DCHECK(IsDebugBreak()); |
| 308 return; | 263 return; |
| 309 } | 264 } |
| 310 | 265 |
| 311 // Patch code with debug break. | 266 // Patch code with debug break. |
| 312 SetDebugBreak(); | 267 SetDebugBreak(); |
| 313 } | 268 } |
| 314 | 269 |
| 315 | 270 |
| 316 void BreakLocationIterator::ClearOneShot() { | 271 void BreakLocation::ClearOneShot() { |
| 317 // Debugger statement always calls debugger. No need to modify it. | 272 // Debugger statement always calls debugger. No need to modify it. |
| 318 if (IsDebuggerStatement()) return; | 273 if (IsDebuggerStatement()) return; |
| 319 | 274 |
| 320 // If there is a real break point here no more to do. | 275 // If there is a real break point here no more to do. |
| 321 if (HasBreakPoint()) { | 276 if (HasBreakPoint()) { |
| 322 DCHECK(IsDebugBreak()); | 277 DCHECK(IsDebugBreak()); |
| 323 return; | 278 return; |
| 324 } | 279 } |
| 325 | 280 |
| 326 // Patch code removing debug break. | 281 // Patch code removing debug break. |
| 327 ClearDebugBreak(); | 282 ClearDebugBreak(); |
| 328 DCHECK(!IsDebugBreak()); | 283 DCHECK(!IsDebugBreak()); |
| 329 } | 284 } |
| 330 | 285 |
| 331 | 286 |
| 332 void BreakLocationIterator::SetDebugBreak() { | 287 void BreakLocation::SetDebugBreak() { |
| 333 // Debugger statement always calls debugger. No need to modify it. | 288 // Debugger statement always calls debugger. No need to modify it. |
| 334 if (IsDebuggerStatement()) return; | 289 if (IsDebuggerStatement()) return; |
| 335 | 290 |
| 336 // If there is already a break point here just return. This might happen if | 291 // If there is already a break point here just return. This might happen if |
| 337 // the same code is flooded with break points twice. Flooding the same | 292 // the same code is flooded with break points twice. Flooding the same |
| 338 // function twice might happen when stepping in a function with an exception | 293 // function twice might happen when stepping in a function with an exception |
| 339 // handler as the handler and the function is the same. | 294 // handler as the handler and the function is the same. |
| 340 if (IsDebugBreak()) return; | 295 if (IsDebugBreak()) return; |
| 341 | 296 |
| 342 if (RelocInfo::IsJSReturn(rmode())) { | 297 if (IsExit()) { |
| 343 // Patch the frame exit code with a break point. | 298 // Patch the frame exit code with a break point. |
| 344 SetDebugBreakAtReturn(); | 299 SetDebugBreakAtReturn(); |
| 345 } else if (IsDebugBreakSlot()) { | 300 } else if (IsDebugBreakSlot()) { |
| 346 // Patch the code in the break slot. | 301 // Patch the code in the break slot. |
| 347 SetDebugBreakAtSlot(); | 302 SetDebugBreakAtSlot(); |
| 348 } else { | 303 } else { |
| 349 // Patch the IC call. | 304 // Patch the IC call. |
| 350 SetDebugBreakAtIC(); | 305 SetDebugBreakAtIC(); |
| 351 } | 306 } |
| 352 DCHECK(IsDebugBreak()); | 307 DCHECK(IsDebugBreak()); |
| 353 } | 308 } |
| 354 | 309 |
| 355 | 310 |
| 356 void BreakLocationIterator::ClearDebugBreak() { | 311 void BreakLocation::ClearDebugBreak() { |
| 357 // Debugger statement always calls debugger. No need to modify it. | 312 // Debugger statement always calls debugger. No need to modify it. |
| 358 if (IsDebuggerStatement()) return; | 313 if (IsDebuggerStatement()) return; |
| 359 | 314 |
| 360 if (RelocInfo::IsJSReturn(rmode())) { | 315 if (IsExit()) { |
| 361 // Restore the frame exit code. | 316 // Restore the frame exit code with a break point. |
| 362 ClearDebugBreakAtReturn(); | 317 RestoreFromOriginal(Assembler::kJSReturnSequenceLength); |
| 363 } else if (IsDebugBreakSlot()) { | 318 } else if (IsDebugBreakSlot()) { |
| 364 // Restore the code in the break slot. | 319 // Restore the code in the break slot. |
| 365 ClearDebugBreakAtSlot(); | 320 RestoreFromOriginal(Assembler::kDebugBreakSlotLength); |
| 366 } else { | 321 } else { |
| 367 // Patch the IC call. | 322 // Restore the IC call. |
| 368 ClearDebugBreakAtIC(); | 323 rinfo().set_target_address(original_rinfo().target_address()); |
| 369 } | 324 } |
| 370 DCHECK(!IsDebugBreak()); | 325 DCHECK(!IsDebugBreak()); |
| 371 } | 326 } |
| 372 | 327 |
| 373 | 328 |
| 374 bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) { | 329 void BreakLocation::RestoreFromOriginal(int length_in_bytes) { |
| 375 if (RelocInfo::IsConstructCall(original_rmode())) { | 330 memcpy(pc(), original_pc(), length_in_bytes); |
| 376 return true; | 331 CpuFeatures::FlushICache(pc(), length_in_bytes); |
| 377 } else if (RelocInfo::IsCodeTarget(rmode())) { | 332 } |
| 333 |
| 334 |
| 335 bool BreakLocation::IsStepInLocation() const { |
| 336 if (IsConstructCall()) return true; |
| 337 if (RelocInfo::IsCodeTarget(rmode())) { |
| 378 HandleScope scope(debug_info_->GetIsolate()); | 338 HandleScope scope(debug_info_->GetIsolate()); |
| 379 Address target = original_rinfo()->target_address(); | 339 Handle<Code> target_code = CodeTarget(); |
| 380 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); | |
| 381 if (target_code->kind() == Code::STUB) { | |
| 382 return CodeStub::GetMajorKey(*target_code) == CodeStub::CallFunction; | |
| 383 } | |
| 384 return target_code->is_call_stub(); | 340 return target_code->is_call_stub(); |
| 385 } | 341 } |
| 386 return false; | 342 return false; |
| 387 } | 343 } |
| 388 | 344 |
| 389 | 345 |
| 390 // Check whether the break point is at a position which will exit the function. | 346 bool BreakLocation::IsDebugBreak() const { |
| 391 bool BreakLocationIterator::IsExit() const { | 347 if (IsExit()) { |
| 392 return (RelocInfo::IsJSReturn(rmode())); | 348 return rinfo().IsPatchedReturnSequence(); |
| 393 } | |
| 394 | |
| 395 | |
| 396 bool BreakLocationIterator::HasBreakPoint() { | |
| 397 return debug_info_->HasBreakPoint(code_position()); | |
| 398 } | |
| 399 | |
| 400 | |
| 401 // Check whether there is a debug break at the current position. | |
| 402 bool BreakLocationIterator::IsDebugBreak() { | |
| 403 if (RelocInfo::IsJSReturn(rmode())) { | |
| 404 return IsDebugBreakAtReturn(); | |
| 405 } else if (IsDebugBreakSlot()) { | 349 } else if (IsDebugBreakSlot()) { |
| 406 return IsDebugBreakAtSlot(); | 350 return rinfo().IsPatchedDebugBreakSlotSequence(); |
| 407 } else { | 351 } else { |
| 408 return Debug::IsDebugBreak(rinfo()->target_address()); | 352 return Debug::IsDebugBreak(rinfo().target_address()); |
| 409 } | 353 } |
| 410 } | 354 } |
| 411 | 355 |
| 412 | 356 |
| 413 // Find the builtin to use for invoking the debug break | 357 // Find the builtin to use for invoking the debug break |
| 414 static Handle<Code> DebugBreakForIC(Handle<Code> code, RelocInfo::Mode mode) { | 358 static Handle<Code> DebugBreakForIC(Handle<Code> code, RelocInfo::Mode mode) { |
| 415 Isolate* isolate = code->GetIsolate(); | 359 Isolate* isolate = code->GetIsolate(); |
| 416 | 360 |
| 417 // Find the builtin debug break function matching the calling convention | 361 // Find the builtin debug break function matching the calling convention |
| 418 // used by the call site. | 362 // used by the call site. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 if (code->kind() == Code::STUB) { | 394 if (code->kind() == Code::STUB) { |
| 451 DCHECK(CodeStub::GetMajorKey(*code) == CodeStub::CallFunction); | 395 DCHECK(CodeStub::GetMajorKey(*code) == CodeStub::CallFunction); |
| 452 return isolate->builtins()->CallFunctionStub_DebugBreak(); | 396 return isolate->builtins()->CallFunctionStub_DebugBreak(); |
| 453 } | 397 } |
| 454 | 398 |
| 455 UNREACHABLE(); | 399 UNREACHABLE(); |
| 456 return Handle<Code>::null(); | 400 return Handle<Code>::null(); |
| 457 } | 401 } |
| 458 | 402 |
| 459 | 403 |
| 460 void BreakLocationIterator::SetDebugBreakAtIC() { | 404 void BreakLocation::SetDebugBreakAtIC() { |
| 461 // Patch the original code with the current address as the current address | 405 // Patch the original code with the current address as the current address |
| 462 // might have changed by the inline caching since the code was copied. | 406 // might have changed by the inline caching since the code was copied. |
| 463 original_rinfo()->set_target_address(rinfo()->target_address()); | 407 original_rinfo().set_target_address(rinfo().target_address()); |
| 464 | 408 |
| 465 RelocInfo::Mode mode = rmode(); | 409 if (RelocInfo::IsCodeTarget(rmode_)) { |
| 466 if (RelocInfo::IsCodeTarget(mode)) { | 410 Handle<Code> target_code = CodeTarget(); |
| 467 Address target = rinfo()->target_address(); | |
| 468 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); | |
| 469 | 411 |
| 470 // Patch the code to invoke the builtin debug break function matching the | 412 // Patch the code to invoke the builtin debug break function matching the |
| 471 // calling convention used by the call site. | 413 // calling convention used by the call site. |
| 472 Handle<Code> dbgbrk_code = DebugBreakForIC(target_code, mode); | 414 Handle<Code> debug_break_code = DebugBreakForIC(target_code, rmode_); |
| 473 rinfo()->set_target_address(dbgbrk_code->entry()); | 415 rinfo().set_target_address(debug_break_code->entry()); |
| 474 } | 416 } |
| 475 } | 417 } |
| 476 | 418 |
| 477 | 419 |
| 478 void BreakLocationIterator::ClearDebugBreakAtIC() { | 420 Handle<Object> BreakLocation::BreakPointObjects() const { |
| 479 // Patch the code to the original invoke. | 421 return debug_info_->GetBreakPointObjects(pc_offset_); |
| 480 rinfo()->set_target_address(original_rinfo()->target_address()); | |
| 481 } | 422 } |
| 482 | 423 |
| 483 | 424 |
| 484 bool BreakLocationIterator::IsDebuggerStatement() { | 425 Handle<Code> BreakLocation::CodeTarget() const { |
| 485 return RelocInfo::DEBUG_BREAK == rmode(); | 426 DCHECK(IsCodeTarget()); |
| 427 Address target = rinfo().target_address(); |
| 428 return Handle<Code>(Code::GetCodeFromTargetAddress(target)); |
| 486 } | 429 } |
| 487 | 430 |
| 488 | 431 |
| 489 bool BreakLocationIterator::IsDebugBreakSlot() { | 432 Handle<Code> BreakLocation::OriginalCodeTarget() const { |
| 490 return RelocInfo::DEBUG_BREAK_SLOT == rmode(); | 433 DCHECK(IsCodeTarget()); |
| 434 Address target = original_rinfo().target_address(); |
| 435 return Handle<Code>(Code::GetCodeFromTargetAddress(target)); |
| 491 } | 436 } |
| 492 | 437 |
| 493 | 438 |
| 494 Object* BreakLocationIterator::BreakPointObjects() { | 439 bool BreakLocation::Iterator::RinfoDone() const { |
| 495 return debug_info_->GetBreakPointObjects(code_position()); | 440 DCHECK(reloc_iterator_.done() == reloc_iterator_original_.done()); |
| 441 return reloc_iterator_.done(); |
| 496 } | 442 } |
| 497 | 443 |
| 498 | 444 |
| 499 // Clear out all the debug break code. This is ONLY supposed to be used when | 445 void BreakLocation::Iterator::RinfoNext() { |
| 500 // shutting down the debugger as it will leave the break point information in | 446 reloc_iterator_.next(); |
| 501 // DebugInfo even though the code is patched back to the non break point state. | 447 reloc_iterator_original_.next(); |
| 502 void BreakLocationIterator::ClearAllDebugBreak() { | |
| 503 while (!Done()) { | |
| 504 ClearDebugBreak(); | |
| 505 Next(); | |
| 506 } | |
| 507 } | |
| 508 | |
| 509 | |
| 510 bool BreakLocationIterator::RinfoDone() const { | |
| 511 DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done()); | |
| 512 return reloc_iterator_->done(); | |
| 513 } | |
| 514 | |
| 515 | |
| 516 void BreakLocationIterator::RinfoNext() { | |
| 517 reloc_iterator_->next(); | |
| 518 reloc_iterator_original_->next(); | |
| 519 #ifdef DEBUG | 448 #ifdef DEBUG |
| 520 DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done()); | 449 DCHECK(reloc_iterator_.done() == reloc_iterator_original_.done()); |
| 521 if (!reloc_iterator_->done()) { | 450 DCHECK(reloc_iterator_.done() || rmode() == original_rmode()); |
| 522 DCHECK(rmode() == original_rmode()); | |
| 523 } | |
| 524 #endif | 451 #endif |
| 525 } | 452 } |
| 526 | 453 |
| 527 | 454 |
| 528 // Threading support. | 455 // Threading support. |
| 529 void Debug::ThreadInit() { | 456 void Debug::ThreadInit() { |
| 530 thread_local_.break_count_ = 0; | 457 thread_local_.break_count_ = 0; |
| 531 thread_local_.break_id_ = 0; | 458 thread_local_.break_id_ = 0; |
| 532 thread_local_.break_frame_id_ = StackFrame::NO_ID; | 459 thread_local_.break_frame_id_ = StackFrame::NO_ID; |
| 533 thread_local_.last_step_action_ = StepNone; | 460 thread_local_.last_step_action_ = StepNone; |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 | 774 |
| 848 // Postpone interrupt during breakpoint processing. | 775 // Postpone interrupt during breakpoint processing. |
| 849 PostponeInterruptsScope postpone(isolate_); | 776 PostponeInterruptsScope postpone(isolate_); |
| 850 | 777 |
| 851 // Get the debug info (create it if it does not exist). | 778 // Get the debug info (create it if it does not exist). |
| 852 Handle<SharedFunctionInfo> shared = | 779 Handle<SharedFunctionInfo> shared = |
| 853 Handle<SharedFunctionInfo>(frame->function()->shared()); | 780 Handle<SharedFunctionInfo>(frame->function()->shared()); |
| 854 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 781 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| 855 | 782 |
| 856 // Find the break point where execution has stopped. | 783 // Find the break point where execution has stopped. |
| 857 BreakLocationIterator break_location_iterator(debug_info, | 784 // PC points to the instruction after the current one, possibly a break |
| 858 ALL_BREAK_LOCATIONS); | |
| 859 // pc points to the instruction after the current one, possibly a break | |
| 860 // location as well. So the "- 1" to exclude it from the search. | 785 // location as well. So the "- 1" to exclude it from the search. |
| 861 break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1); | 786 Address call_pc = frame->pc() - 1; |
| 787 BreakLocation break_location = |
| 788 BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc); |
| 862 | 789 |
| 863 // Check whether step next reached a new statement. | 790 // Check whether step next reached a new statement. |
| 864 if (!StepNextContinue(&break_location_iterator, frame)) { | 791 if (!StepNextContinue(&break_location, frame)) { |
| 865 // Decrease steps left if performing multiple steps. | 792 // Decrease steps left if performing multiple steps. |
| 866 if (thread_local_.step_count_ > 0) { | 793 if (thread_local_.step_count_ > 0) { |
| 867 thread_local_.step_count_--; | 794 thread_local_.step_count_--; |
| 868 } | 795 } |
| 869 } | 796 } |
| 870 | 797 |
| 871 // If there is one or more real break points check whether any of these are | 798 // If there is one or more real break points check whether any of these are |
| 872 // triggered. | 799 // triggered. |
| 873 Handle<Object> break_points_hit(heap->undefined_value(), isolate_); | 800 Handle<Object> break_points_hit(heap->undefined_value(), isolate_); |
| 874 if (break_location_iterator.HasBreakPoint()) { | 801 if (break_location.HasBreakPoint()) { |
| 875 Handle<Object> break_point_objects = | 802 Handle<Object> break_point_objects = break_location.BreakPointObjects(); |
| 876 Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_); | |
| 877 break_points_hit = CheckBreakPoints(break_point_objects); | 803 break_points_hit = CheckBreakPoints(break_point_objects); |
| 878 } | 804 } |
| 879 | 805 |
| 880 // If step out is active skip everything until the frame where we need to step | 806 // If step out is active skip everything until the frame where we need to step |
| 881 // out to is reached, unless real breakpoint is hit. | 807 // out to is reached, unless real breakpoint is hit. |
| 882 if (StepOutActive() && | 808 if (StepOutActive() && |
| 883 frame->fp() != thread_local_.step_out_fp_ && | 809 frame->fp() != thread_local_.step_out_fp_ && |
| 884 break_points_hit->IsUndefined() ) { | 810 break_points_hit->IsUndefined() ) { |
| 885 // Step count should always be 0 for StepOut. | 811 // Step count should always be 0 for StepOut. |
| 886 DCHECK(thread_local_.step_count_ == 0); | 812 DCHECK(thread_local_.step_count_ == 0); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 if (!EnsureDebugInfo(shared, function)) { | 977 if (!EnsureDebugInfo(shared, function)) { |
| 1052 // Return if retrieving debug info failed. | 978 // Return if retrieving debug info failed. |
| 1053 return true; | 979 return true; |
| 1054 } | 980 } |
| 1055 | 981 |
| 1056 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 982 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| 1057 // Source positions starts with zero. | 983 // Source positions starts with zero. |
| 1058 DCHECK(*source_position >= 0); | 984 DCHECK(*source_position >= 0); |
| 1059 | 985 |
| 1060 // Find the break point and change it. | 986 // Find the break point and change it. |
| 1061 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); | 987 BreakLocation location = BreakLocation::FromPosition( |
| 1062 it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED); | 988 debug_info, SOURCE_BREAK_LOCATIONS, *source_position, STATEMENT_ALIGNED); |
| 1063 it.SetBreakPoint(break_point_object); | 989 *source_position = location.statement_position(); |
| 1064 | 990 location.SetBreakPoint(break_point_object); |
| 1065 *source_position = it.statement_position(); | |
| 1066 | 991 |
| 1067 // At least one active break point now. | 992 // At least one active break point now. |
| 1068 return debug_info->GetBreakPointCount() > 0; | 993 return debug_info->GetBreakPointCount() > 0; |
| 1069 } | 994 } |
| 1070 | 995 |
| 1071 | 996 |
| 1072 bool Debug::SetBreakPointForScript(Handle<Script> script, | 997 bool Debug::SetBreakPointForScript(Handle<Script> script, |
| 1073 Handle<Object> break_point_object, | 998 Handle<Object> break_point_object, |
| 1074 int* source_position, | 999 int* source_position, |
| 1075 BreakPositionAlignment alignment) { | 1000 BreakPositionAlignment alignment) { |
| 1076 HandleScope scope(isolate_); | 1001 HandleScope scope(isolate_); |
| 1077 | 1002 |
| 1078 PrepareForBreakPoints(); | 1003 PrepareForBreakPoints(); |
| 1079 | 1004 |
| 1080 // Obtain shared function info for the function. | 1005 // Obtain shared function info for the function. |
| 1081 Object* result = FindSharedFunctionInfoInScript(script, *source_position); | 1006 Handle<Object> result = |
| 1007 FindSharedFunctionInfoInScript(script, *source_position); |
| 1082 if (result->IsUndefined()) return false; | 1008 if (result->IsUndefined()) return false; |
| 1083 | 1009 |
| 1084 // Make sure the function has set up the debug info. | 1010 // Make sure the function has set up the debug info. |
| 1085 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); | 1011 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result); |
| 1086 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { | 1012 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { |
| 1087 // Return if retrieving debug info failed. | 1013 // Return if retrieving debug info failed. |
| 1088 return false; | 1014 return false; |
| 1089 } | 1015 } |
| 1090 | 1016 |
| 1091 // Find position within function. The script position might be before the | 1017 // Find position within function. The script position might be before the |
| 1092 // source position of the first function. | 1018 // source position of the first function. |
| 1093 int position; | 1019 int position; |
| 1094 if (shared->start_position() > *source_position) { | 1020 if (shared->start_position() > *source_position) { |
| 1095 position = 0; | 1021 position = 0; |
| 1096 } else { | 1022 } else { |
| 1097 position = *source_position - shared->start_position(); | 1023 position = *source_position - shared->start_position(); |
| 1098 } | 1024 } |
| 1099 | 1025 |
| 1100 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1026 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| 1101 // Source positions starts with zero. | 1027 // Source positions starts with zero. |
| 1102 DCHECK(position >= 0); | 1028 DCHECK(position >= 0); |
| 1103 | 1029 |
| 1104 // Find the break point and change it. | 1030 // Find the break point and change it. |
| 1105 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); | 1031 BreakLocation location = BreakLocation::FromPosition( |
| 1106 it.FindBreakLocationFromPosition(position, alignment); | 1032 debug_info, SOURCE_BREAK_LOCATIONS, position, alignment); |
| 1107 it.SetBreakPoint(break_point_object); | 1033 location.SetBreakPoint(break_point_object); |
| 1108 | 1034 |
| 1109 position = (alignment == STATEMENT_ALIGNED) ? it.statement_position() | 1035 position = (alignment == STATEMENT_ALIGNED) ? location.statement_position() |
| 1110 : it.position(); | 1036 : location.position(); |
| 1111 | 1037 |
| 1112 *source_position = position + shared->start_position(); | 1038 *source_position = position + shared->start_position(); |
| 1113 | 1039 |
| 1114 // At least one active break point now. | 1040 // At least one active break point now. |
| 1115 DCHECK(debug_info->GetBreakPointCount() > 0); | 1041 DCHECK(debug_info->GetBreakPointCount() > 0); |
| 1116 return true; | 1042 return true; |
| 1117 } | 1043 } |
| 1118 | 1044 |
| 1119 | 1045 |
| 1120 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { | 1046 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { |
| 1121 HandleScope scope(isolate_); | 1047 HandleScope scope(isolate_); |
| 1122 | 1048 |
| 1123 DebugInfoListNode* node = debug_info_list_; | 1049 DebugInfoListNode* node = debug_info_list_; |
| 1124 while (node != NULL) { | 1050 while (node != NULL) { |
| 1125 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), | 1051 Handle<Object> result = |
| 1126 break_point_object); | 1052 DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object); |
| 1127 if (!result->IsUndefined()) { | 1053 if (!result->IsUndefined()) { |
| 1128 // Get information in the break point. | 1054 // Get information in the break point. |
| 1129 BreakPointInfo* break_point_info = BreakPointInfo::cast(result); | 1055 Handle<BreakPointInfo> break_point_info = |
| 1056 Handle<BreakPointInfo>::cast(result); |
| 1130 Handle<DebugInfo> debug_info = node->debug_info(); | 1057 Handle<DebugInfo> debug_info = node->debug_info(); |
| 1131 | 1058 |
| 1132 // Find the break point and clear it. | 1059 // Find the break point and clear it. |
| 1133 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); | 1060 Address pc = debug_info->code()->entry() + |
| 1134 it.FindBreakLocationFromAddress(debug_info->code()->entry() + | 1061 break_point_info->code_position()->value(); |
| 1135 break_point_info->code_position()->value()); | 1062 |
| 1136 it.ClearBreakPoint(break_point_object); | 1063 BreakLocation location = |
| 1064 BreakLocation::FromAddress(debug_info, SOURCE_BREAK_LOCATIONS, pc); |
| 1065 location.ClearBreakPoint(break_point_object); |
| 1137 | 1066 |
| 1138 // If there are no more break points left remove the debug info for this | 1067 // If there are no more break points left remove the debug info for this |
| 1139 // function. | 1068 // function. |
| 1140 if (debug_info->GetBreakPointCount() == 0) { | 1069 if (debug_info->GetBreakPointCount() == 0) { |
| 1141 RemoveDebugInfoAndClearFromShared(debug_info); | 1070 RemoveDebugInfoAndClearFromShared(debug_info); |
| 1142 } | 1071 } |
| 1143 | 1072 |
| 1144 return; | 1073 return; |
| 1145 } | 1074 } |
| 1146 node = node->next(); | 1075 node = node->next(); |
| 1147 } | 1076 } |
| 1148 } | 1077 } |
| 1149 | 1078 |
| 1150 | 1079 |
| 1080 // Clear out all the debug break code. This is ONLY supposed to be used when |
| 1081 // shutting down the debugger as it will leave the break point information in |
| 1082 // DebugInfo even though the code is patched back to the non break point state. |
| 1151 void Debug::ClearAllBreakPoints() { | 1083 void Debug::ClearAllBreakPoints() { |
| 1152 DebugInfoListNode* node = debug_info_list_; | 1084 for (DebugInfoListNode* node = debug_info_list_; node != NULL; |
| 1153 while (node != NULL) { | 1085 node = node->next()) { |
| 1154 // Remove all debug break code. | 1086 for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS); |
| 1155 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); | 1087 !it.Done(); it.Next()) { |
| 1156 it.ClearAllDebugBreak(); | 1088 it.GetBreakLocation().ClearDebugBreak(); |
| 1157 node = node->next(); | 1089 } |
| 1158 } | 1090 } |
| 1159 | |
| 1160 // Remove all debug info. | 1091 // Remove all debug info. |
| 1161 while (debug_info_list_ != NULL) { | 1092 while (debug_info_list_ != NULL) { |
| 1162 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); | 1093 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); |
| 1163 } | 1094 } |
| 1164 } | 1095 } |
| 1165 | 1096 |
| 1166 | 1097 |
| 1167 void Debug::FloodWithOneShot(Handle<JSFunction> function, | 1098 void Debug::FloodWithOneShot(Handle<JSFunction> function, |
| 1168 BreakLocatorType type) { | 1099 BreakLocatorType type) { |
| 1169 // Do not ever break in native functions. | 1100 // Do not ever break in native functions. |
| 1170 if (function->IsFromNativeScript()) return; | 1101 if (function->IsFromNativeScript()) return; |
| 1171 | 1102 |
| 1172 PrepareForBreakPoints(); | 1103 PrepareForBreakPoints(); |
| 1173 | 1104 |
| 1174 // Make sure the function is compiled and has set up the debug info. | 1105 // Make sure the function is compiled and has set up the debug info. |
| 1175 Handle<SharedFunctionInfo> shared(function->shared()); | 1106 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1176 if (!EnsureDebugInfo(shared, function)) { | 1107 if (!EnsureDebugInfo(shared, function)) { |
| 1177 // Return if we failed to retrieve the debug info. | 1108 // Return if we failed to retrieve the debug info. |
| 1178 return; | 1109 return; |
| 1179 } | 1110 } |
| 1180 | 1111 |
| 1181 // Flood the function with break points. | 1112 // Flood the function with break points. |
| 1182 BreakLocationIterator it(GetDebugInfo(shared), type); | 1113 for (BreakLocation::Iterator it(GetDebugInfo(shared), type); !it.Done(); |
| 1183 while (!it.Done()) { | 1114 it.Next()) { |
| 1184 it.SetOneShot(); | 1115 it.GetBreakLocation().SetOneShot(); |
| 1185 it.Next(); | |
| 1186 } | 1116 } |
| 1187 } | 1117 } |
| 1188 | 1118 |
| 1189 | 1119 |
| 1190 void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) { | 1120 void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) { |
| 1191 Handle<FixedArray> new_bindings(function->function_bindings()); | 1121 Handle<FixedArray> new_bindings(function->function_bindings()); |
| 1192 Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex), | 1122 Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex), |
| 1193 isolate_); | 1123 isolate_); |
| 1194 | 1124 |
| 1195 if (!bindee.is_null() && bindee->IsJSFunction() && | 1125 if (!bindee.is_null() && bindee->IsJSFunction() && |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 if (!EnsureDebugInfo(shared, function)) { | 1264 if (!EnsureDebugInfo(shared, function)) { |
| 1335 // Return if ensuring debug info failed. | 1265 // Return if ensuring debug info failed. |
| 1336 return; | 1266 return; |
| 1337 } | 1267 } |
| 1338 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1268 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| 1339 | 1269 |
| 1340 // Compute whether or not the target is a call target. | 1270 // Compute whether or not the target is a call target. |
| 1341 bool is_load_or_store = false; | 1271 bool is_load_or_store = false; |
| 1342 bool is_inline_cache_stub = false; | 1272 bool is_inline_cache_stub = false; |
| 1343 bool is_at_restarted_function = false; | 1273 bool is_at_restarted_function = false; |
| 1344 bool is_exit = false; | |
| 1345 bool is_construct_call = false; | |
| 1346 Handle<Code> call_function_stub; | 1274 Handle<Code> call_function_stub; |
| 1347 | 1275 |
| 1348 { | 1276 // PC points to the instruction after the current one, possibly a break |
| 1349 // Find the break location where execution has stopped. | 1277 // location as well. So the "- 1" to exclude it from the search. |
| 1350 DisallowHeapAllocation no_gc; | 1278 Address call_pc = frame->pc() - 1; |
| 1351 BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS); | 1279 BreakLocation location = |
| 1280 BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc); |
| 1352 | 1281 |
| 1353 // pc points to the instruction after the current one, possibly a break | 1282 if (thread_local_.restarter_frame_function_pointer_ == NULL) { |
| 1354 // location as well. So the "- 1" to exclude it from the search. | 1283 if (location.IsCodeTarget()) { |
| 1355 it.FindBreakLocationFromAddress(frame->pc() - 1); | 1284 Handle<Code> target_code = location.CodeTarget(); |
| 1285 is_inline_cache_stub = target_code->is_inline_cache_stub(); |
| 1286 is_load_or_store = is_inline_cache_stub && !target_code->is_call_stub(); |
| 1356 | 1287 |
| 1357 is_exit = it.IsExit(); | 1288 // Check if target code is CallFunction stub. |
| 1358 is_construct_call = RelocInfo::IsConstructCall(it.rmode()); | 1289 Handle<Code> maybe_call_function_stub = target_code; |
| 1359 | 1290 // If there is a breakpoint at this line look at the original code to |
| 1360 if (thread_local_.restarter_frame_function_pointer_ == NULL) { | 1291 // check if it is a CallFunction stub. |
| 1361 if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { | 1292 if (location.IsDebugBreak()) { |
| 1362 bool is_call_target = false; | 1293 maybe_call_function_stub = location.OriginalCodeTarget(); |
| 1363 Address target = it.rinfo()->target_address(); | |
| 1364 Code* code = Code::GetCodeFromTargetAddress(target); | |
| 1365 | |
| 1366 is_call_target = code->is_call_stub(); | |
| 1367 is_inline_cache_stub = code->is_inline_cache_stub(); | |
| 1368 is_load_or_store = is_inline_cache_stub && !is_call_target; | |
| 1369 | |
| 1370 // Check if target code is CallFunction stub. | |
| 1371 Code* maybe_call_function_stub = code; | |
| 1372 // If there is a breakpoint at this line look at the original code to | |
| 1373 // check if it is a CallFunction stub. | |
| 1374 if (it.IsDebugBreak()) { | |
| 1375 Address original_target = it.original_rinfo()->target_address(); | |
| 1376 maybe_call_function_stub = | |
| 1377 Code::GetCodeFromTargetAddress(original_target); | |
| 1378 } | |
| 1379 if ((maybe_call_function_stub->kind() == Code::STUB && | |
| 1380 CodeStub::GetMajorKey(maybe_call_function_stub) == | |
| 1381 CodeStub::CallFunction) || | |
| 1382 maybe_call_function_stub->is_call_stub()) { | |
| 1383 // Save reference to the code as we may need it to find out arguments | |
| 1384 // count for 'step in' later. | |
| 1385 call_function_stub = Handle<Code>(maybe_call_function_stub); | |
| 1386 } | |
| 1387 } | 1294 } |
| 1388 } else { | 1295 if ((maybe_call_function_stub->kind() == Code::STUB && |
| 1389 is_at_restarted_function = true; | 1296 CodeStub::GetMajorKey(*maybe_call_function_stub) == |
| 1297 CodeStub::CallFunction) || |
| 1298 maybe_call_function_stub->is_call_stub()) { |
| 1299 // Save reference to the code as we may need it to find out arguments |
| 1300 // count for 'step in' later. |
| 1301 call_function_stub = maybe_call_function_stub; |
| 1302 } |
| 1390 } | 1303 } |
| 1304 } else { |
| 1305 is_at_restarted_function = true; |
| 1391 } | 1306 } |
| 1392 | 1307 |
| 1393 // If this is the last break code target step out is the only possibility. | 1308 // If this is the last break code target step out is the only possibility. |
| 1394 if (is_exit || step_action == StepOut) { | 1309 if (location.IsExit() || step_action == StepOut) { |
| 1395 if (step_action == StepOut) { | 1310 if (step_action == StepOut) { |
| 1396 // Skip step_count frames starting with the current one. | 1311 // Skip step_count frames starting with the current one. |
| 1397 while (step_count-- > 0 && !frames_it.done()) { | 1312 while (step_count-- > 0 && !frames_it.done()) { |
| 1398 frames_it.Advance(); | 1313 frames_it.Advance(); |
| 1399 } | 1314 } |
| 1400 } else { | 1315 } else { |
| 1401 DCHECK(is_exit); | 1316 DCHECK(location.IsExit()); |
| 1402 frames_it.Advance(); | 1317 frames_it.Advance(); |
| 1403 } | 1318 } |
| 1404 // Skip builtin functions on the stack. | 1319 // Skip builtin functions on the stack. |
| 1405 while (!frames_it.done() && | 1320 while (!frames_it.done() && |
| 1406 frames_it.frame()->function()->IsFromNativeScript()) { | 1321 frames_it.frame()->function()->IsFromNativeScript()) { |
| 1407 frames_it.Advance(); | 1322 frames_it.Advance(); |
| 1408 } | 1323 } |
| 1409 // Step out: If there is a JavaScript caller frame, we need to | 1324 // Step out: If there is a JavaScript caller frame, we need to |
| 1410 // flood it with breakpoints. | 1325 // flood it with breakpoints. |
| 1411 if (!frames_it.done()) { | 1326 if (!frames_it.done()) { |
| 1412 // Fill the function to return to with one-shot break points. | 1327 // Fill the function to return to with one-shot break points. |
| 1413 JSFunction* function = frames_it.frame()->function(); | 1328 JSFunction* function = frames_it.frame()->function(); |
| 1414 FloodWithOneShot(Handle<JSFunction>(function)); | 1329 FloodWithOneShot(Handle<JSFunction>(function)); |
| 1415 // Set target frame pointer. | 1330 // Set target frame pointer. |
| 1416 ActivateStepOut(frames_it.frame()); | 1331 ActivateStepOut(frames_it.frame()); |
| 1417 } | 1332 } |
| 1418 } else if (!(is_inline_cache_stub || is_construct_call || | 1333 } else if (!(is_inline_cache_stub || location.IsConstructCall() || |
| 1419 !call_function_stub.is_null() || is_at_restarted_function) || | 1334 !call_function_stub.is_null() || is_at_restarted_function) || |
| 1420 step_action == StepNext || step_action == StepMin) { | 1335 step_action == StepNext || step_action == StepMin) { |
| 1421 // Step next or step min. | 1336 // Step next or step min. |
| 1422 | 1337 |
| 1423 // Fill the current function with one-shot break points. | 1338 // Fill the current function with one-shot break points. |
| 1424 // If we are stepping into another frame, only fill calls and returns. | 1339 // If we are stepping into another frame, only fill calls and returns. |
| 1425 FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS | 1340 FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS |
| 1426 : ALL_BREAK_LOCATIONS); | 1341 : ALL_BREAK_LOCATIONS); |
| 1427 | 1342 |
| 1428 // Remember source position and frame to handle step next. | 1343 // Remember source position and frame to handle step next. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 } | 1419 } |
| 1505 | 1420 |
| 1506 // Step in or Step in min | 1421 // Step in or Step in min |
| 1507 // Step in through construct call requires no changes to the running code. | 1422 // Step in through construct call requires no changes to the running code. |
| 1508 // Step in through getters/setters should already be prepared as well | 1423 // Step in through getters/setters should already be prepared as well |
| 1509 // because caller of this function (Debug::PrepareStep) is expected to | 1424 // because caller of this function (Debug::PrepareStep) is expected to |
| 1510 // flood the top frame's function with one shot breakpoints. | 1425 // flood the top frame's function with one shot breakpoints. |
| 1511 // Step in through CallFunction stub should also be prepared by caller of | 1426 // Step in through CallFunction stub should also be prepared by caller of |
| 1512 // this function (Debug::PrepareStep) which should flood target function | 1427 // this function (Debug::PrepareStep) which should flood target function |
| 1513 // with breakpoints. | 1428 // with breakpoints. |
| 1514 DCHECK(is_construct_call || is_inline_cache_stub || | 1429 DCHECK(location.IsConstructCall() || is_inline_cache_stub || |
| 1515 !call_function_stub.is_null() || is_at_restarted_function); | 1430 !call_function_stub.is_null() || is_at_restarted_function); |
| 1516 ActivateStepIn(frame); | 1431 ActivateStepIn(frame); |
| 1517 } | 1432 } |
| 1518 } | 1433 } |
| 1519 | 1434 |
| 1520 | 1435 |
| 1521 // Check whether the current debug break should be reported to the debugger. It | 1436 // Check whether the current debug break should be reported to the debugger. It |
| 1522 // is used to have step next and step in only report break back to the debugger | 1437 // is used to have step next and step in only report break back to the debugger |
| 1523 // if on a different frame or in a different statement. In some situations | 1438 // if on a different frame or in a different statement. In some situations |
| 1524 // there will be several break points in the same statement when the code is | 1439 // there will be several break points in the same statement when the code is |
| 1525 // flooded with one-shot break points. This function helps to perform several | 1440 // flooded with one-shot break points. This function helps to perform several |
| 1526 // steps before reporting break back to the debugger. | 1441 // steps before reporting break back to the debugger. |
| 1527 bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, | 1442 bool Debug::StepNextContinue(BreakLocation* break_location, |
| 1528 JavaScriptFrame* frame) { | 1443 JavaScriptFrame* frame) { |
| 1529 // StepNext and StepOut shouldn't bring us deeper in code, so last frame | 1444 // StepNext and StepOut shouldn't bring us deeper in code, so last frame |
| 1530 // shouldn't be a parent of current frame. | 1445 // shouldn't be a parent of current frame. |
| 1531 StepAction step_action = thread_local_.last_step_action_; | 1446 StepAction step_action = thread_local_.last_step_action_; |
| 1532 | 1447 |
| 1533 if (step_action == StepNext || step_action == StepOut) { | 1448 if (step_action == StepNext || step_action == StepOut) { |
| 1534 if (frame->fp() < thread_local_.last_fp_) return true; | 1449 if (frame->fp() < thread_local_.last_fp_) return true; |
| 1535 } | 1450 } |
| 1536 | 1451 |
| 1537 // We stepped into a new frame if the frame pointer changed. | 1452 // We stepped into a new frame if the frame pointer changed. |
| 1538 if (step_action == StepFrame) { | 1453 if (step_action == StepFrame) { |
| 1539 return frame->UnpaddedFP() == thread_local_.last_fp_; | 1454 return frame->UnpaddedFP() == thread_local_.last_fp_; |
| 1540 } | 1455 } |
| 1541 | 1456 |
| 1542 // If the step last action was step next or step in make sure that a new | 1457 // If the step last action was step next or step in make sure that a new |
| 1543 // statement is hit. | 1458 // statement is hit. |
| 1544 if (step_action == StepNext || step_action == StepIn) { | 1459 if (step_action == StepNext || step_action == StepIn) { |
| 1545 // Never continue if returning from function. | 1460 // Never continue if returning from function. |
| 1546 if (break_location_iterator->IsExit()) return false; | 1461 if (break_location->IsExit()) return false; |
| 1547 | 1462 |
| 1548 // Continue if we are still on the same frame and in the same statement. | 1463 // Continue if we are still on the same frame and in the same statement. |
| 1549 int current_statement_position = | 1464 int current_statement_position = |
| 1550 break_location_iterator->code()->SourceStatementPosition(frame->pc()); | 1465 break_location->code()->SourceStatementPosition(frame->pc()); |
| 1551 return thread_local_.last_fp_ == frame->UnpaddedFP() && | 1466 return thread_local_.last_fp_ == frame->UnpaddedFP() && |
| 1552 thread_local_.last_statement_position_ == current_statement_position; | 1467 thread_local_.last_statement_position_ == current_statement_position; |
| 1553 } | 1468 } |
| 1554 | 1469 |
| 1555 // No step next action - don't continue. | 1470 // No step next action - don't continue. |
| 1556 return false; | 1471 return false; |
| 1557 } | 1472 } |
| 1558 | 1473 |
| 1559 | 1474 |
| 1560 // Check whether the code object at the specified address is a debug break code | 1475 // Check whether the code object at the specified address is a debug break code |
| 1561 // object. | 1476 // object. |
| 1562 bool Debug::IsDebugBreak(Address addr) { | 1477 bool Debug::IsDebugBreak(Address addr) { |
| 1563 Code* code = Code::GetCodeFromTargetAddress(addr); | 1478 Code* code = Code::GetCodeFromTargetAddress(addr); |
| 1564 return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK; | 1479 return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK; |
| 1565 } | 1480 } |
| 1566 | 1481 |
| 1567 | 1482 |
| 1568 | |
| 1569 | |
| 1570 | |
| 1571 // Simple function for returning the source positions for active break points. | 1483 // Simple function for returning the source positions for active break points. |
| 1572 Handle<Object> Debug::GetSourceBreakLocations( | 1484 Handle<Object> Debug::GetSourceBreakLocations( |
| 1573 Handle<SharedFunctionInfo> shared, | 1485 Handle<SharedFunctionInfo> shared, |
| 1574 BreakPositionAlignment position_alignment) { | 1486 BreakPositionAlignment position_alignment) { |
| 1575 Isolate* isolate = shared->GetIsolate(); | 1487 Isolate* isolate = shared->GetIsolate(); |
| 1576 Heap* heap = isolate->heap(); | 1488 Heap* heap = isolate->heap(); |
| 1577 if (!HasDebugInfo(shared)) { | 1489 if (!HasDebugInfo(shared)) { |
| 1578 return Handle<Object>(heap->undefined_value(), isolate); | 1490 return Handle<Object>(heap->undefined_value(), isolate); |
| 1579 } | 1491 } |
| 1580 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1492 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1648 } | 1560 } |
| 1649 | 1561 |
| 1650 | 1562 |
| 1651 // Clears all the one-shot break points that are currently set. Normally this | 1563 // Clears all the one-shot break points that are currently set. Normally this |
| 1652 // function is called each time a break point is hit as one shot break points | 1564 // function is called each time a break point is hit as one shot break points |
| 1653 // are used to support stepping. | 1565 // are used to support stepping. |
| 1654 void Debug::ClearOneShot() { | 1566 void Debug::ClearOneShot() { |
| 1655 // The current implementation just runs through all the breakpoints. When the | 1567 // The current implementation just runs through all the breakpoints. When the |
| 1656 // last break point for a function is removed that function is automatically | 1568 // last break point for a function is removed that function is automatically |
| 1657 // removed from the list. | 1569 // removed from the list. |
| 1658 | 1570 for (DebugInfoListNode* node = debug_info_list_; node != NULL; |
| 1659 DebugInfoListNode* node = debug_info_list_; | 1571 node = node->next()) { |
| 1660 while (node != NULL) { | 1572 for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS); |
| 1661 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); | 1573 !it.Done(); it.Next()) { |
| 1662 while (!it.Done()) { | 1574 it.GetBreakLocation().ClearOneShot(); |
| 1663 it.ClearOneShot(); | |
| 1664 it.Next(); | |
| 1665 } | 1575 } |
| 1666 node = node->next(); | |
| 1667 } | 1576 } |
| 1668 } | 1577 } |
| 1669 | 1578 |
| 1670 | 1579 |
| 1671 void Debug::ActivateStepIn(StackFrame* frame) { | 1580 void Debug::ActivateStepIn(StackFrame* frame) { |
| 1672 DCHECK(!StepOutActive()); | 1581 DCHECK(!StepOutActive()); |
| 1673 thread_local_.step_into_fp_ = frame->UnpaddedFP(); | 1582 thread_local_.step_into_fp_ = frame->UnpaddedFP(); |
| 1674 } | 1583 } |
| 1675 | 1584 |
| 1676 | 1585 |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2073 RedirectActivationsToRecompiledCodeOnThread(isolate_, | 1982 RedirectActivationsToRecompiledCodeOnThread(isolate_, |
| 2074 isolate_->thread_local_top()); | 1983 isolate_->thread_local_top()); |
| 2075 | 1984 |
| 2076 ActiveFunctionsRedirector active_functions_redirector; | 1985 ActiveFunctionsRedirector active_functions_redirector; |
| 2077 isolate_->thread_manager()->IterateArchivedThreads( | 1986 isolate_->thread_manager()->IterateArchivedThreads( |
| 2078 &active_functions_redirector); | 1987 &active_functions_redirector); |
| 2079 } | 1988 } |
| 2080 } | 1989 } |
| 2081 | 1990 |
| 2082 | 1991 |
| 2083 Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script, | 1992 Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script, |
| 2084 int position) { | 1993 int position) { |
| 2085 // Iterate the heap looking for SharedFunctionInfo generated from the | 1994 // Iterate the heap looking for SharedFunctionInfo generated from the |
| 2086 // script. The inner most SharedFunctionInfo containing the source position | 1995 // script. The inner most SharedFunctionInfo containing the source position |
| 2087 // for the requested break point is found. | 1996 // for the requested break point is found. |
| 2088 // NOTE: This might require several heap iterations. If the SharedFunctionInfo | 1997 // NOTE: This might require several heap iterations. If the SharedFunctionInfo |
| 2089 // which is found is not compiled it is compiled and the heap is iterated | 1998 // which is found is not compiled it is compiled and the heap is iterated |
| 2090 // again as the compilation might create inner functions from the newly | 1999 // again as the compilation might create inner functions from the newly |
| 2091 // compiled function and the actual requested break point might be in one of | 2000 // compiled function and the actual requested break point might be in one of |
| 2092 // these functions. | 2001 // these functions. |
| 2093 // NOTE: The below fix-point iteration depends on all functions that cannot be | 2002 // NOTE: The below fix-point iteration depends on all functions that cannot be |
| 2094 // compiled lazily without a context to not be compiled at all. Compilation | 2003 // compiled lazily without a context to not be compiled at all. Compilation |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2157 target_start_position = start_position; | 2066 target_start_position = start_position; |
| 2158 target_function = function; | 2067 target_function = function; |
| 2159 target = shared; | 2068 target = shared; |
| 2160 } | 2069 } |
| 2161 } | 2070 } |
| 2162 } | 2071 } |
| 2163 } | 2072 } |
| 2164 } // End for loop. | 2073 } // End for loop. |
| 2165 } // End no-allocation scope. | 2074 } // End no-allocation scope. |
| 2166 | 2075 |
| 2167 if (target.is_null()) return heap->undefined_value(); | 2076 if (target.is_null()) return isolate_->factory()->undefined_value(); |
| 2168 | 2077 |
| 2169 // There will be at least one break point when we are done. | 2078 // There will be at least one break point when we are done. |
| 2170 has_break_points_ = true; | 2079 has_break_points_ = true; |
| 2171 | 2080 |
| 2172 // If the candidate found is compiled we are done. | 2081 // If the candidate found is compiled we are done. |
| 2173 done = target->is_compiled(); | 2082 done = target->is_compiled(); |
| 2174 if (!done) { | 2083 if (!done) { |
| 2175 // If the candidate is not compiled, compile it to reveal any inner | 2084 // If the candidate is not compiled, compile it to reveal any inner |
| 2176 // functions which might contain the requested source position. This | 2085 // functions which might contain the requested source position. This |
| 2177 // will compile all inner functions that cannot be compiled without a | 2086 // will compile all inner functions that cannot be compiled without a |
| 2178 // context, because Compiler::BuildFunctionInfo checks whether the | 2087 // context, because Compiler::BuildFunctionInfo checks whether the |
| 2179 // debugger is active. | 2088 // debugger is active. |
| 2180 MaybeHandle<Code> maybe_result = target_function.is_null() | 2089 MaybeHandle<Code> maybe_result = target_function.is_null() |
| 2181 ? Compiler::GetUnoptimizedCode(target) | 2090 ? Compiler::GetUnoptimizedCode(target) |
| 2182 : Compiler::GetUnoptimizedCode(target_function); | 2091 : Compiler::GetUnoptimizedCode(target_function); |
| 2183 if (maybe_result.is_null()) return isolate_->heap()->undefined_value(); | 2092 if (maybe_result.is_null()) return isolate_->factory()->undefined_value(); |
| 2184 } | 2093 } |
| 2185 } // End while loop. | 2094 } // End while loop. |
| 2186 | 2095 |
| 2187 return *target; | 2096 return target; |
| 2188 } | 2097 } |
| 2189 | 2098 |
| 2190 | 2099 |
| 2191 // Ensures the debug information is present for shared. | 2100 // Ensures the debug information is present for shared. |
| 2192 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, | 2101 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, |
| 2193 Handle<JSFunction> function) { | 2102 Handle<JSFunction> function) { |
| 2194 Isolate* isolate = shared->GetIsolate(); | 2103 Isolate* isolate = shared->GetIsolate(); |
| 2195 | 2104 |
| 2196 // Return if we already have the debug info for shared. | 2105 // Return if we already have the debug info for shared. |
| 2197 if (HasDebugInfo(shared)) { | 2106 if (HasDebugInfo(shared)) { |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3472 logger_->DebugEvent("Put", message.text()); | 3381 logger_->DebugEvent("Put", message.text()); |
| 3473 } | 3382 } |
| 3474 | 3383 |
| 3475 | 3384 |
| 3476 void LockingCommandMessageQueue::Clear() { | 3385 void LockingCommandMessageQueue::Clear() { |
| 3477 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 3386 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 3478 queue_.Clear(); | 3387 queue_.Clear(); |
| 3479 } | 3388 } |
| 3480 | 3389 |
| 3481 } } // namespace v8::internal | 3390 } } // namespace v8::internal |
| OLD | NEW |