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

Side by Side Diff: src/debug.cc

Issue 301563004: Refactor after break target computation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/debug.h ('k') | src/liveedit.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/liveedit.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698