| 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 "v8.h" |     5 #include "v8.h" | 
|     6  |     6  | 
|     7 #include "api.h" |     7 #include "api.h" | 
|     8 #include "arguments.h" |     8 #include "arguments.h" | 
|     9 #include "bootstrapper.h" |     9 #include "bootstrapper.h" | 
|    10 #include "code-stubs.h" |    10 #include "code-stubs.h" | 
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   507   thread_local_.break_count_ = 0; |   507   thread_local_.break_count_ = 0; | 
|   508   thread_local_.break_id_ = 0; |   508   thread_local_.break_id_ = 0; | 
|   509   thread_local_.break_frame_id_ = StackFrame::NO_ID; |   509   thread_local_.break_frame_id_ = StackFrame::NO_ID; | 
|   510   thread_local_.last_step_action_ = StepNone; |   510   thread_local_.last_step_action_ = StepNone; | 
|   511   thread_local_.last_statement_position_ = RelocInfo::kNoPosition; |   511   thread_local_.last_statement_position_ = RelocInfo::kNoPosition; | 
|   512   thread_local_.step_count_ = 0; |   512   thread_local_.step_count_ = 0; | 
|   513   thread_local_.last_fp_ = 0; |   513   thread_local_.last_fp_ = 0; | 
|   514   thread_local_.queued_step_count_ = 0; |   514   thread_local_.queued_step_count_ = 0; | 
|   515   thread_local_.step_into_fp_ = 0; |   515   thread_local_.step_into_fp_ = 0; | 
|   516   thread_local_.step_out_fp_ = 0; |   516   thread_local_.step_out_fp_ = 0; | 
|   517   thread_local_.after_break_target_ = 0; |  | 
|   518   // TODO(isolates): frames_are_dropped_? |   517   // TODO(isolates): frames_are_dropped_? | 
|   519   thread_local_.debugger_entry_ = NULL; |   518   thread_local_.debugger_entry_ = NULL; | 
|   520   thread_local_.has_pending_interrupt_ = false; |   519   thread_local_.has_pending_interrupt_ = false; | 
|   521   thread_local_.restarter_frame_function_pointer_ = NULL; |   520   thread_local_.restarter_frame_function_pointer_ = NULL; | 
|   522   thread_local_.promise_on_stack_ = NULL; |   521   thread_local_.promise_on_stack_ = NULL; | 
|   523 } |   522 } | 
|   524  |   523  | 
|   525  |   524  | 
|   526 char* Debug::ArchiveDebug(char* storage) { |   525 char* Debug::ArchiveDebug(char* storage) { | 
|   527   char* to = storage; |   526   char* to = storage; | 
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   799  |   798  | 
|   800   // Clear the script cache. |   799   // Clear the script cache. | 
|   801   DestroyScriptCache(); |   800   DestroyScriptCache(); | 
|   802  |   801  | 
|   803   // Clear debugger context global handle. |   802   // Clear debugger context global handle. | 
|   804   GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); |   803   GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); | 
|   805   debug_context_ = Handle<Context>(); |   804   debug_context_ = Handle<Context>(); | 
|   806 } |   805 } | 
|   807  |   806  | 
|   808  |   807  | 
|   809 Object* Debug::Break(Arguments args) { |   808 void Debug::Break(Arguments args, JavaScriptFrame* frame) { | 
|   810   Heap* heap = isolate_->heap(); |   809   Heap* heap = isolate_->heap(); | 
|   811   HandleScope scope(isolate_); |   810   HandleScope scope(isolate_); | 
|   812   ASSERT(args.length() == 0); |   811   ASSERT(args.length() == 0); | 
|   813  |   812  | 
|   814   thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED; |   813   if (live_edit_enabled()) { | 
|   815  |   814     thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED; | 
|   816   // Get the top-most JavaScript frame. |   815   } | 
|   817   JavaScriptFrameIterator it(isolate_); |  | 
|   818   JavaScriptFrame* frame = it.frame(); |  | 
|   819  |   816  | 
|   820   // Just continue if breaks are disabled or debugger cannot be loaded. |   817   // Just continue if breaks are disabled or debugger cannot be loaded. | 
|   821   if (disable_break()) { |   818   if (disable_break()) return; | 
|   822     SetAfterBreakTarget(frame); |  | 
|   823     return heap->undefined_value(); |  | 
|   824   } |  | 
|   825  |   819  | 
|   826   // Enter the debugger. |   820   // Enter the debugger. | 
|   827   EnterDebugger debugger(isolate_); |   821   EnterDebugger debugger(isolate_); | 
|   828   if (debugger.FailedToEnter()) { |   822   if (debugger.FailedToEnter()) return; | 
|   829     return heap->undefined_value(); |  | 
|   830   } |  | 
|   831  |   823  | 
|   832   // Postpone interrupt during breakpoint processing. |   824   // Postpone interrupt during breakpoint processing. | 
|   833   PostponeInterruptsScope postpone(isolate_); |   825   PostponeInterruptsScope postpone(isolate_); | 
|   834  |   826  | 
|   835   // Get the debug info (create it if it does not exist). |   827   // Get the debug info (create it if it does not exist). | 
|   836   Handle<SharedFunctionInfo> shared = |   828   Handle<SharedFunctionInfo> shared = | 
|   837       Handle<SharedFunctionInfo>(frame->function()->shared()); |   829       Handle<SharedFunctionInfo>(frame->function()->shared()); | 
|   838   Handle<DebugInfo> debug_info = GetDebugInfo(shared); |   830   Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 
|   839  |   831  | 
|   840   // Find the break point where execution has stopped. |   832   // Find the break point where execution has stopped. | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   916       step_action = StepOut; |   908       step_action = StepOut; | 
|   917       step_count = count; |   909       step_count = count; | 
|   918     } |   910     } | 
|   919  |   911  | 
|   920     // Clear all current stepping setup. |   912     // Clear all current stepping setup. | 
|   921     ClearStepping(); |   913     ClearStepping(); | 
|   922  |   914  | 
|   923     // Set up for the remaining steps. |   915     // Set up for the remaining steps. | 
|   924     PrepareStep(step_action, step_count, StackFrame::NO_ID); |   916     PrepareStep(step_action, step_count, StackFrame::NO_ID); | 
|   925   } |   917   } | 
|   926  |  | 
|   927   if (thread_local_.frame_drop_mode_ == LiveEdit::FRAMES_UNTOUCHED) { |  | 
|   928     SetAfterBreakTarget(frame); |  | 
|   929   } else if (thread_local_.frame_drop_mode_ == |  | 
|   930       LiveEdit::FRAME_DROPPED_IN_IC_CALL) { |  | 
|   931     // We must have been calling IC stub. Do not go there anymore. |  | 
|   932     Code* plain_return = isolate_->builtins()->builtin( |  | 
|   933         Builtins::kPlainReturn_LiveEdit); |  | 
|   934     thread_local_.after_break_target_ = plain_return->entry(); |  | 
|   935   } else if (thread_local_.frame_drop_mode_ == |  | 
|   936       LiveEdit::FRAME_DROPPED_IN_DEBUG_SLOT_CALL) { |  | 
|   937     // Debug break slot stub does not return normally, instead it manually |  | 
|   938     // cleans the stack and jumps. We should patch the jump address. |  | 
|   939     Code* plain_return = isolate_->builtins()->builtin( |  | 
|   940         Builtins::kFrameDropper_LiveEdit); |  | 
|   941     thread_local_.after_break_target_ = plain_return->entry(); |  | 
|   942   } else if (thread_local_.frame_drop_mode_ == |  | 
|   943       LiveEdit::FRAME_DROPPED_IN_DIRECT_CALL) { |  | 
|   944     // Nothing to do, after_break_target is not used here. |  | 
|   945   } else if (thread_local_.frame_drop_mode_ == |  | 
|   946       LiveEdit::FRAME_DROPPED_IN_RETURN_CALL) { |  | 
|   947     Code* plain_return = isolate_->builtins()->builtin( |  | 
|   948         Builtins::kFrameDropper_LiveEdit); |  | 
|   949     thread_local_.after_break_target_ = plain_return->entry(); |  | 
|   950   } else { |  | 
|   951     UNREACHABLE(); |  | 
|   952   } |  | 
|   953  |  | 
|   954   return heap->undefined_value(); |  | 
|   955 } |   918 } | 
|   956  |   919  | 
|   957  |   920  | 
|   958 RUNTIME_FUNCTION(Debug_Break) { |   921 RUNTIME_FUNCTION(Debug_Break) { | 
|   959   return isolate->debug()->Break(args); |   922   // Get the top-most JavaScript frame. | 
 |   923   JavaScriptFrameIterator it(isolate); | 
 |   924   isolate->debug()->Break(args, it.frame()); | 
 |   925   isolate->debug()->SetAfterBreakTarget(it.frame()); | 
 |   926   return isolate->heap()->undefined_value(); | 
|   960 } |   927 } | 
|   961  |   928  | 
|   962  |   929  | 
|   963 // Check the break point objects for whether one or more are actually |   930 // Check the break point objects for whether one or more are actually | 
|   964 // triggered. This function returns a JSArray with the break point objects |   931 // triggered. This function returns a JSArray with the break point objects | 
|   965 // which is triggered. |   932 // which is triggered. | 
|   966 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) { |   933 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) { | 
|   967   Factory* factory = isolate_->factory(); |   934   Factory* factory = isolate_->factory(); | 
|   968  |   935  | 
|   969   // Count the number of break points hit. If there are multiple break points |   936   // Count the number of break points hit. If there are multiple break points | 
| (...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2328     } |  2295     } | 
|  2329     // Move to next in list. |  2296     // Move to next in list. | 
|  2330     prev = current; |  2297     prev = current; | 
|  2331     current = current->next(); |  2298     current = current->next(); | 
|  2332   } |  2299   } | 
|  2333   UNREACHABLE(); |  2300   UNREACHABLE(); | 
|  2334 } |  2301 } | 
|  2335  |  2302  | 
|  2336  |  2303  | 
|  2337 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { |  2304 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { | 
 |  2305   if (live_edit_enabled()) { | 
 |  2306     after_break_target_ = | 
 |  2307         LiveEdit::AfterBreakTarget(thread_local_.frame_drop_mode_, isolate_); | 
 |  2308     if (after_break_target_ != NULL) return;  // LiveEdit did the job. | 
 |  2309   } | 
 |  2310  | 
|  2338   HandleScope scope(isolate_); |  2311   HandleScope scope(isolate_); | 
|  2339  |  | 
|  2340   PrepareForBreakPoints(); |  2312   PrepareForBreakPoints(); | 
|  2341  |  2313  | 
|  2342   // Get the executing function in which the debug break occurred. |  2314   // Get the executing function in which the debug break occurred. | 
|  2343   Handle<JSFunction> function(JSFunction::cast(frame->function())); |  2315   Handle<JSFunction> function(JSFunction::cast(frame->function())); | 
|  2344   Handle<SharedFunctionInfo> shared(function->shared()); |  2316   Handle<SharedFunctionInfo> shared(function->shared()); | 
|  2345   if (!EnsureDebugInfo(shared, function)) { |  2317   if (!EnsureDebugInfo(shared, function)) { | 
|  2346     // Return if we failed to retrieve the debug info. |  2318     // Return if we failed to retrieve the debug info. | 
|  2347     return; |  2319     return; | 
|  2348   } |  2320   } | 
|  2349   Handle<DebugInfo> debug_info = GetDebugInfo(shared); |  2321   Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|  2378     it.next(); |  2350     it.next(); | 
|  2379   } |  2351   } | 
|  2380  |  2352  | 
|  2381   // Handle the jump to continue execution after break point depending on the |  2353   // Handle the jump to continue execution after break point depending on the | 
|  2382   // break location. |  2354   // break location. | 
|  2383   if (at_js_return) { |  2355   if (at_js_return) { | 
|  2384     // If the break point as return is still active jump to the corresponding |  2356     // If the break point as return is still active jump to the corresponding | 
|  2385     // place in the original code. If not the break point was removed during |  2357     // place in the original code. If not the break point was removed during | 
|  2386     // break point processing. |  2358     // break point processing. | 
|  2387     if (break_at_js_return_active) { |  2359     if (break_at_js_return_active) { | 
|  2388       addr +=  original_code->instruction_start() - code->instruction_start(); |  2360       addr += original_code->instruction_start() - code->instruction_start(); | 
|  2389     } |  2361     } | 
|  2390  |  2362  | 
|  2391     // Move back to where the call instruction sequence started. |  2363     // Move back to where the call instruction sequence started. | 
|  2392     thread_local_.after_break_target_ = |  2364     after_break_target_ = addr - Assembler::kPatchReturnSequenceAddressOffset; | 
|  2393         addr - Assembler::kPatchReturnSequenceAddressOffset; |  | 
|  2394   } else if (at_debug_break_slot) { |  2365   } else if (at_debug_break_slot) { | 
|  2395     // Address of where the debug break slot starts. |  2366     // Address of where the debug break slot starts. | 
|  2396     addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset; |  2367     addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset; | 
|  2397  |  2368  | 
|  2398     // Continue just after the slot. |  2369     // Continue just after the slot. | 
|  2399     thread_local_.after_break_target_ = addr + Assembler::kDebugBreakSlotLength; |  2370     after_break_target_ = addr + Assembler::kDebugBreakSlotLength; | 
|  2400   } else if (IsDebugBreak(Assembler::target_address_at(addr, *code))) { |  2371   } else if (IsDebugBreak(Assembler::target_address_at(addr, *code))) { | 
|  2401     // We now know that there is still a debug break call at the target address, |  2372     // We now know that there is still a debug break call at the target address, | 
|  2402     // so the break point is still there and the original code will hold the |  2373     // so the break point is still there and the original code will hold the | 
|  2403     // address to jump to in order to complete the call which is replaced by a |  2374     // address to jump to in order to complete the call which is replaced by a | 
|  2404     // call to DebugBreakXXX. |  2375     // call to DebugBreakXXX. | 
|  2405  |  2376  | 
|  2406     // Find the corresponding address in the original code. |  2377     // Find the corresponding address in the original code. | 
|  2407     addr += original_code->instruction_start() - code->instruction_start(); |  2378     addr += original_code->instruction_start() - code->instruction_start(); | 
|  2408  |  2379  | 
|  2409     // Install jump to the call address in the original code. This will be the |  2380     // Install jump to the call address in the original code. This will be the | 
|  2410     // call which was overwritten by the call to DebugBreakXXX. |  2381     // call which was overwritten by the call to DebugBreakXXX. | 
|  2411     thread_local_.after_break_target_ = |  2382     after_break_target_ = Assembler::target_address_at(addr, *original_code); | 
|  2412         Assembler::target_address_at(addr, *original_code); |  | 
|  2413   } else { |  2383   } else { | 
|  2414     // There is no longer a break point present. Don't try to look in the |  2384     // There is no longer a break point present. Don't try to look in the | 
|  2415     // original code as the running code will have the right address. This takes |  2385     // original code as the running code will have the right address. This takes | 
|  2416     // care of the case where the last break point is removed from the function |  2386     // care of the case where the last break point is removed from the function | 
|  2417     // and therefore no "original code" is available. |  2387     // and therefore no "original code" is available. | 
|  2418     thread_local_.after_break_target_ = |  2388     after_break_target_ = Assembler::target_address_at(addr, *code); | 
|  2419         Assembler::target_address_at(addr, *code); |  | 
|  2420   } |  2389   } | 
|  2421 } |  2390 } | 
|  2422  |  2391  | 
|  2423  |  2392  | 
|  2424 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { |  2393 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { | 
|  2425   HandleScope scope(isolate_); |  2394   HandleScope scope(isolate_); | 
|  2426  |  2395  | 
|  2427   // If there are no break points this cannot be break at return, as |  2396   // If there are no break points this cannot be break at return, as | 
|  2428   // the debugger statement and stack guard bebug break cannot be at |  2397   // the debugger statement and stack guard bebug break cannot be at | 
|  2429   // return. |  2398   // return. | 
| (...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3493   logger_->DebugEvent("Put", message.text()); |  3462   logger_->DebugEvent("Put", message.text()); | 
|  3494 } |  3463 } | 
|  3495  |  3464  | 
|  3496  |  3465  | 
|  3497 void LockingCommandMessageQueue::Clear() { |  3466 void LockingCommandMessageQueue::Clear() { | 
|  3498   LockGuard<Mutex> lock_guard(&mutex_); |  3467   LockGuard<Mutex> lock_guard(&mutex_); | 
|  3499   queue_.Clear(); |  3468   queue_.Clear(); | 
|  3500 } |  3469 } | 
|  3501  |  3470  | 
|  3502 } }  // namespace v8::internal |  3471 } }  // namespace v8::internal | 
| OLD | NEW |