| 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" | 
|    11 #include "src/codegen.h" |    11 #include "src/codegen.h" | 
|    12 #include "src/compilation-cache.h" |    12 #include "src/compilation-cache.h" | 
|    13 #include "src/compiler.h" |    13 #include "src/compiler.h" | 
|    14 #include "src/deoptimizer.h" |    14 #include "src/deoptimizer.h" | 
|    15 #include "src/execution.h" |    15 #include "src/execution.h" | 
|    16 #include "src/frames-inl.h" |    16 #include "src/frames-inl.h" | 
|    17 #include "src/full-codegen/full-codegen.h" |    17 #include "src/full-codegen/full-codegen.h" | 
|    18 #include "src/global-handles.h" |    18 #include "src/global-handles.h" | 
|    19 #include "src/interpreter/interpreter.h" |    19 #include "src/interpreter/interpreter.h" | 
|    20 #include "src/isolate-inl.h" |    20 #include "src/isolate-inl.h" | 
|    21 #include "src/list.h" |    21 #include "src/list.h" | 
|    22 #include "src/log.h" |    22 #include "src/log.h" | 
|    23 #include "src/messages.h" |    23 #include "src/messages.h" | 
|    24 #include "src/snapshot/natives.h" |    24 #include "src/snapshot/natives.h" | 
 |    25 #include "src/wasm/wasm-debug.h" | 
 |    26 #include "src/wasm/wasm-module.h" | 
|    25  |    27  | 
|    26 #include "include/v8-debug.h" |    28 #include "include/v8-debug.h" | 
|    27  |    29  | 
|    28 namespace v8 { |    30 namespace v8 { | 
|    29 namespace internal { |    31 namespace internal { | 
|    30  |    32  | 
 |    33 namespace { | 
 |    34  | 
 |    35 inline int CallOffsetFromCodeOffset(int code_offset, bool is_interpreted) { | 
 |    36   // Code offset points to the instruction after the call. Subtract 1 to | 
 |    37   // exclude that instruction from the search. For bytecode, the code offset | 
 |    38   // still points to the call. | 
 |    39   return is_interpreted ? code_offset : code_offset - 1; | 
 |    40 } | 
 |    41  | 
 |    42 }  // namespace | 
 |    43  | 
|    31 Debug::Debug(Isolate* isolate) |    44 Debug::Debug(Isolate* isolate) | 
|    32     : debug_context_(Handle<Context>()), |    45     : debug_context_(Handle<Context>()), | 
|    33       event_listener_(Handle<Object>()), |    46       event_listener_(Handle<Object>()), | 
|    34       event_listener_data_(Handle<Object>()), |    47       event_listener_data_(Handle<Object>()), | 
|    35       message_handler_(NULL), |    48       message_handler_(NULL), | 
|    36       command_received_(0), |    49       command_received_(0), | 
|    37       command_queue_(isolate->logger(), kQueueInitialSize), |    50       command_queue_(isolate->logger(), kQueueInitialSize), | 
|    38       is_active_(false), |    51       is_active_(false), | 
|    39       is_suppressed_(false), |    52       is_suppressed_(false), | 
|    40       live_edit_enabled_(true),  // TODO(yangguo): set to false by default. |    53       live_edit_enabled_(true),  // TODO(yangguo): set to false by default. | 
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   253  |   266  | 
|   254 // Find the break point at the supplied address, or the closest one before |   267 // Find the break point at the supplied address, or the closest one before | 
|   255 // the address. |   268 // the address. | 
|   256 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info, |   269 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info, | 
|   257                                             int offset) { |   270                                             int offset) { | 
|   258   base::SmartPointer<Iterator> it(GetIterator(debug_info)); |   271   base::SmartPointer<Iterator> it(GetIterator(debug_info)); | 
|   259   it->SkipTo(BreakIndexFromCodeOffset(debug_info, offset)); |   272   it->SkipTo(BreakIndexFromCodeOffset(debug_info, offset)); | 
|   260   return it->GetBreakLocation(); |   273   return it->GetBreakLocation(); | 
|   261 } |   274 } | 
|   262  |   275  | 
|   263 int CallOffsetFromCodeOffset(int code_offset, bool is_interpreted) { |  | 
|   264   // Code offset points to the instruction after the call. Subtract 1 to |  | 
|   265   // exclude that instruction from the search. For bytecode, the code offset |  | 
|   266   // still points to the call. |  | 
|   267   return is_interpreted ? code_offset : code_offset - 1; |  | 
|   268 } |  | 
|   269  |  | 
|   270 BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info, |   276 BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info, | 
|   271                                        JavaScriptFrame* frame) { |   277                                        JavaScriptFrame* frame) { | 
|   272   FrameSummary summary = FrameSummary::GetFirst(frame); |   278   int code_offset = FrameSummary::GetFirst(frame).code_offset(); | 
|   273   int call_offset = |   279   int call_offset = | 
|   274       CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted()); |   280       CallOffsetFromCodeOffset(code_offset, frame->is_interpreted()); | 
|   275   return FromCodeOffset(debug_info, call_offset); |   281   return FromCodeOffset(debug_info, call_offset); | 
|   276 } |   282 } | 
|   277  |   283  | 
|   278 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info, |   284 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info, | 
|   279                                             int statement_position, |   285                                             int statement_position, | 
|   280                                             List<BreakLocation>* result_out) { |   286                                             List<BreakLocation>* result_out) { | 
|   281   for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done(); |   287   for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done(); | 
|   282        it->Next()) { |   288        it->Next()) { | 
|   283     if (it->statement_position() == statement_position) { |   289     if (it->statement_position() == statement_position) { | 
|   284       result_out->Add(it->GetBreakLocation()); |   290       result_out->Add(it->GetBreakLocation()); | 
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   786  |   792  | 
|   787   // At least one active break point now. |   793   // At least one active break point now. | 
|   788   return debug_info->GetBreakPointCount() > 0; |   794   return debug_info->GetBreakPointCount() > 0; | 
|   789 } |   795 } | 
|   790  |   796  | 
|   791  |   797  | 
|   792 bool Debug::SetBreakPointForScript(Handle<Script> script, |   798 bool Debug::SetBreakPointForScript(Handle<Script> script, | 
|   793                                    Handle<Object> break_point_object, |   799                                    Handle<Object> break_point_object, | 
|   794                                    int* source_position, |   800                                    int* source_position, | 
|   795                                    BreakPositionAlignment alignment) { |   801                                    BreakPositionAlignment alignment) { | 
 |   802   if (script->type() == Script::TYPE_WASM) { | 
 |   803     // TODO(clemensh): set breakpoint for wasm. | 
 |   804     return false; | 
 |   805   } | 
|   796   HandleScope scope(isolate_); |   806   HandleScope scope(isolate_); | 
|   797  |   807  | 
|   798   // Obtain shared function info for the function. |   808   // Obtain shared function info for the function. | 
|   799   Handle<Object> result = |   809   Handle<Object> result = | 
|   800       FindSharedFunctionInfoInScript(script, *source_position); |   810       FindSharedFunctionInfoInScript(script, *source_position); | 
|   801   if (result->IsUndefined(isolate_)) return false; |   811   if (result->IsUndefined(isolate_)) return false; | 
|   802  |   812  | 
|   803   // Make sure the function has set up the debug info. |   813   // Make sure the function has set up the debug info. | 
|   804   Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result); |   814   Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result); | 
|   805   if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { |   815   if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { | 
| (...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1594 } |  1604 } | 
|  1595  |  1605  | 
|  1596 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { |  1606 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { | 
|  1597   after_break_target_ = NULL; |  1607   after_break_target_ = NULL; | 
|  1598   if (!LiveEdit::SetAfterBreakTarget(this)) { |  1608   if (!LiveEdit::SetAfterBreakTarget(this)) { | 
|  1599     // Continue just after the slot. |  1609     // Continue just after the slot. | 
|  1600     after_break_target_ = frame->pc(); |  1610     after_break_target_ = frame->pc(); | 
|  1601   } |  1611   } | 
|  1602 } |  1612 } | 
|  1603  |  1613  | 
|  1604  |  | 
|  1605 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { |  1614 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { | 
|  1606   HandleScope scope(isolate_); |  1615   HandleScope scope(isolate_); | 
|  1607  |  1616  | 
|  1608   // Get the executing function in which the debug break occurred. |  1617   // Get the executing function in which the debug break occurred. | 
|  1609   Handle<JSFunction> function(JSFunction::cast(frame->function())); |  1618   Handle<SharedFunctionInfo> shared(frame->function()->shared()); | 
|  1610   Handle<SharedFunctionInfo> shared(function->shared()); |  | 
|  1611  |  1619  | 
|  1612   // With no debug info there are no break points, so we can't be at a return. |  1620   // With no debug info there are no break points, so we can't be at a return. | 
|  1613   if (!shared->HasDebugInfo()) return false; |  1621   if (!shared->HasDebugInfo()) return false; | 
|  1614  |  1622  | 
|  1615   DCHECK(!frame->is_optimized()); |  1623   DCHECK(!frame->is_optimized()); | 
|  1616   FrameSummary summary = FrameSummary::GetFirst(frame); |  1624   int code_offset = FrameSummary::GetFirst(frame).code_offset(); | 
|  1617  |  | 
|  1618   Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |  1625   Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 
|  1619   BreakLocation location = |  1626   BreakLocation location = | 
|  1620       BreakLocation::FromCodeOffset(debug_info, summary.code_offset()); |  1627       BreakLocation::FromCodeOffset(debug_info, code_offset); | 
|  1621   return location.IsReturn() || location.IsTailCall(); |  1628   return location.IsReturn() || location.IsTailCall(); | 
|  1622 } |  1629 } | 
|  1623  |  1630  | 
|  1624  |  1631  | 
|  1625 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, |  1632 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, | 
|  1626                                   LiveEdit::FrameDropMode mode) { |  1633                                   LiveEdit::FrameDropMode mode) { | 
|  1627   if (mode != LiveEdit::CURRENTLY_SET_MODE) { |  1634   if (mode != LiveEdit::CURRENTLY_SET_MODE) { | 
|  1628     thread_local_.frame_drop_mode_ = mode; |  1635     thread_local_.frame_drop_mode_ = mode; | 
|  1629   } |  1636   } | 
|  1630   thread_local_.break_frame_id_ = new_break_frame_id; |  1637   thread_local_.break_frame_id_ = new_break_frame_id; | 
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2296                                 StackGuard::TERMINATE_EXECUTION) { |  2303                                 StackGuard::TERMINATE_EXECUTION) { | 
|  2297   // Link recursive debugger entry. |  2304   // Link recursive debugger entry. | 
|  2298   base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, |  2305   base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, | 
|  2299                         reinterpret_cast<base::AtomicWord>(this)); |  2306                         reinterpret_cast<base::AtomicWord>(this)); | 
|  2300  |  2307  | 
|  2301   // Store the previous break id, frame id and return value. |  2308   // Store the previous break id, frame id and return value. | 
|  2302   break_id_ = debug_->break_id(); |  2309   break_id_ = debug_->break_id(); | 
|  2303   break_frame_id_ = debug_->break_frame_id(); |  2310   break_frame_id_ = debug_->break_frame_id(); | 
|  2304   return_value_ = debug_->return_value(); |  2311   return_value_ = debug_->return_value(); | 
|  2305  |  2312  | 
|  2306   // Create the new break info. If there is no JavaScript frames there is no |  2313   // Create the new break info. If there is no proper frames there is no break | 
|  2307   // break frame id. |  2314   // frame id. | 
|  2308   JavaScriptFrameIterator it(isolate()); |  2315   StackTraceFrameIterator it(isolate()); | 
|  2309   bool has_js_frames = !it.done(); |  2316   bool has_frames = !it.done(); | 
|  2310   debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id() |  2317   // We don't currently support breaking inside wasm framess. | 
|  2311                                                         : StackFrame::NO_ID; |  2318   DCHECK(!has_frames || !it.is_wasm()); | 
 |  2319   debug_->thread_local_.break_frame_id_ = | 
 |  2320       has_frames ? it.frame()->id() : StackFrame::NO_ID; | 
|  2312   debug_->SetNextBreakId(); |  2321   debug_->SetNextBreakId(); | 
|  2313  |  2322  | 
|  2314   debug_->UpdateState(); |  2323   debug_->UpdateState(); | 
|  2315   // Make sure that debugger is loaded and enter the debugger context. |  2324   // Make sure that debugger is loaded and enter the debugger context. | 
|  2316   // The previous context is kept in save_. |  2325   // The previous context is kept in save_. | 
|  2317   failed_ = !debug_->is_loaded(); |  2326   failed_ = !debug_->is_loaded(); | 
|  2318   if (!failed_) isolate()->set_context(*debug->debug_context()); |  2327   if (!failed_) isolate()->set_context(*debug->debug_context()); | 
|  2319 } |  2328 } | 
|  2320  |  2329  | 
|  2321  |  2330  | 
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2596 } |  2605 } | 
|  2597  |  2606  | 
|  2598  |  2607  | 
|  2599 void LockingCommandMessageQueue::Clear() { |  2608 void LockingCommandMessageQueue::Clear() { | 
|  2600   base::LockGuard<base::Mutex> lock_guard(&mutex_); |  2609   base::LockGuard<base::Mutex> lock_guard(&mutex_); | 
|  2601   queue_.Clear(); |  2610   queue_.Clear(); | 
|  2602 } |  2611 } | 
|  2603  |  2612  | 
|  2604 }  // namespace internal |  2613 }  // namespace internal | 
|  2605 }  // namespace v8 |  2614 }  // namespace v8 | 
| OLD | NEW |