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

Side by Side Diff: src/debug/debug.cc

Issue 2636913002: [liveedit] reimplement frame restarting. (Closed)
Patch Set: rebase Created 3 years, 10 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
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/ia32/debug-ia32.cc » ('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 "src/debug/debug.h" 5 #include "src/debug/debug.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 394
395 // Threading support. 395 // Threading support.
396 void Debug::ThreadInit() { 396 void Debug::ThreadInit() {
397 thread_local_.break_count_ = 0; 397 thread_local_.break_count_ = 0;
398 thread_local_.break_id_ = 0; 398 thread_local_.break_id_ = 0;
399 thread_local_.break_frame_id_ = StackFrame::NO_ID; 399 thread_local_.break_frame_id_ = StackFrame::NO_ID;
400 thread_local_.last_step_action_ = StepNone; 400 thread_local_.last_step_action_ = StepNone;
401 thread_local_.last_statement_position_ = kNoSourcePosition; 401 thread_local_.last_statement_position_ = kNoSourcePosition;
402 thread_local_.last_fp_ = 0; 402 thread_local_.last_fp_ = 0;
403 thread_local_.target_fp_ = 0; 403 thread_local_.target_fp_ = 0;
404 thread_local_.return_value_ = Handle<Object>(); 404 thread_local_.return_value_ = Smi::kZero;
405 thread_local_.async_task_count_ = 0; 405 thread_local_.async_task_count_ = 0;
406 clear_suspended_generator(); 406 clear_suspended_generator();
407 // TODO(isolates): frames_are_dropped_? 407 thread_local_.restart_fp_ = nullptr;
408 base::NoBarrier_Store(&thread_local_.current_debug_scope_, 408 base::NoBarrier_Store(&thread_local_.current_debug_scope_,
409 static_cast<base::AtomicWord>(0)); 409 static_cast<base::AtomicWord>(0));
410 UpdateHookOnFunctionCall(); 410 UpdateHookOnFunctionCall();
411 } 411 }
412 412
413 413
414 char* Debug::ArchiveDebug(char* storage) { 414 char* Debug::ArchiveDebug(char* storage) {
415 // Simply reset state. Don't archive anything. 415 // Simply reset state. Don't archive anything.
416 ThreadInit(); 416 ThreadInit();
417 return storage + ArchiveSpacePerThread(); 417 return storage + ArchiveSpacePerThread();
418 } 418 }
419 419
420 420
421 char* Debug::RestoreDebug(char* storage) { 421 char* Debug::RestoreDebug(char* storage) {
422 // Simply reset state. Don't restore anything. 422 // Simply reset state. Don't restore anything.
423 ThreadInit(); 423 ThreadInit();
424 return storage + ArchiveSpacePerThread(); 424 return storage + ArchiveSpacePerThread();
425 } 425 }
426 426
427 int Debug::ArchiveSpacePerThread() { return 0; } 427 int Debug::ArchiveSpacePerThread() { return 0; }
428 428
429 void Debug::Iterate(ObjectVisitor* v) { 429 void Debug::Iterate(ObjectVisitor* v) {
430 v->VisitPointer(&thread_local_.return_value_);
430 v->VisitPointer(&thread_local_.suspended_generator_); 431 v->VisitPointer(&thread_local_.suspended_generator_);
431 } 432 }
432 433
433 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { 434 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
434 // Globalize the request debug info object and make it weak. 435 // Globalize the request debug info object and make it weak.
435 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); 436 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
436 debug_info_ = 437 debug_info_ =
437 Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location(); 438 Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location();
438 } 439 }
439 440
(...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 return; 1579 return;
1579 } 1580 }
1580 // Move to next in list. 1581 // Move to next in list.
1581 prev = current; 1582 prev = current;
1582 current = current->next(); 1583 current = current->next();
1583 } 1584 }
1584 1585
1585 UNREACHABLE(); 1586 UNREACHABLE();
1586 } 1587 }
1587 1588
1588 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
1589 after_break_target_ = NULL;
1590 if (!LiveEdit::SetAfterBreakTarget(this)) {
1591 // Continue just after the slot.
1592 after_break_target_ = frame->pc();
1593 }
1594 }
1595
1596 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 1589 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
1597 HandleScope scope(isolate_); 1590 HandleScope scope(isolate_);
1598 1591
1599 // Get the executing function in which the debug break occurred. 1592 // Get the executing function in which the debug break occurred.
1600 Handle<SharedFunctionInfo> shared(frame->function()->shared()); 1593 Handle<SharedFunctionInfo> shared(frame->function()->shared());
1601 1594
1602 // With no debug info there are no break points, so we can't be at a return. 1595 // With no debug info there are no break points, so we can't be at a return.
1603 if (!shared->HasDebugInfo()) return false; 1596 if (!shared->HasDebugInfo()) return false;
1604 1597
1605 DCHECK(!frame->is_optimized()); 1598 DCHECK(!frame->is_optimized());
1606 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1599 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1607 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); 1600 BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
1608 return location.IsReturn() || location.IsTailCall(); 1601 return location.IsReturn() || location.IsTailCall();
1609 } 1602 }
1610 1603
1611 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, 1604 void Debug::ScheduleFrameRestart(StackFrame* frame) {
1612 LiveEditFrameDropMode mode) { 1605 // Set a target FP for the FrameDropperTrampoline builtin to drop to once
1613 if (mode != LIVE_EDIT_CURRENTLY_SET_MODE) { 1606 // we return from the debugger.
1614 thread_local_.frame_drop_mode_ = mode; 1607 DCHECK(frame->is_java_script());
1608 // Only reschedule to a frame further below a frame we already scheduled for.
1609 if (frame->fp() <= thread_local_.restart_fp_) return;
1610 // If the frame is optimized, trigger a deopt and jump into the
1611 // FrameDropperTrampoline in the deoptimizer.
1612 thread_local_.restart_fp_ = frame->fp();
1613
1614 // Reset break frame ID to the frame below the restarted frame.
1615 StackTraceFrameIterator it(isolate_);
1616 thread_local_.break_frame_id_ = StackFrame::NO_ID;
1617 for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) {
1618 if (it.frame()->fp() > thread_local_.restart_fp_) {
1619 thread_local_.break_frame_id_ = it.frame()->id();
1620 return;
1621 }
1615 } 1622 }
1616 thread_local_.break_frame_id_ = new_break_frame_id;
1617 } 1623 }
1618 1624
1619 1625
1620 bool Debug::IsDebugGlobal(JSGlobalObject* global) { 1626 bool Debug::IsDebugGlobal(JSGlobalObject* global) {
1621 return is_loaded() && global == debug_context()->global_object(); 1627 return is_loaded() && global == debug_context()->global_object();
1622 } 1628 }
1623 1629
1624 1630
1625 void Debug::ClearMirrorCache() { 1631 void Debug::ClearMirrorCache() {
1626 PostponeInterruptsScope postpone(isolate_); 1632 PostponeInterruptsScope postpone(isolate_);
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 return Execution::Call( 2201 return Execution::Call(
2196 isolate_, 2202 isolate_,
2197 fun, 2203 fun,
2198 Handle<Object>(debug_context()->global_proxy(), isolate_), 2204 Handle<Object>(debug_context()->global_proxy(), isolate_),
2199 arraysize(argv), 2205 arraysize(argv),
2200 argv); 2206 argv);
2201 } 2207 }
2202 2208
2203 2209
2204 void Debug::HandleDebugBreak() { 2210 void Debug::HandleDebugBreak() {
2211 // Initialize LiveEdit.
2212 LiveEdit::InitializeThreadLocal(this);
2205 // Ignore debug break during bootstrapping. 2213 // Ignore debug break during bootstrapping.
2206 if (isolate_->bootstrapper()->IsActive()) return; 2214 if (isolate_->bootstrapper()->IsActive()) return;
2207 // Just continue if breaks are disabled. 2215 // Just continue if breaks are disabled.
2208 if (break_disabled()) return; 2216 if (break_disabled()) return;
2209 // Ignore debug break if debugger is not active. 2217 // Ignore debug break if debugger is not active.
2210 if (!is_active()) return; 2218 if (!is_active()) return;
2211 2219
2212 StackLimitCheck check(isolate_); 2220 StackLimitCheck check(isolate_);
2213 if (check.HasOverflowed()) return; 2221 if (check.HasOverflowed()) return;
2214 2222
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 save_(debug_->isolate_), 2304 save_(debug_->isolate_),
2297 no_termination_exceptons_(debug_->isolate_, 2305 no_termination_exceptons_(debug_->isolate_,
2298 StackGuard::TERMINATE_EXECUTION) { 2306 StackGuard::TERMINATE_EXECUTION) {
2299 // Link recursive debugger entry. 2307 // Link recursive debugger entry.
2300 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, 2308 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
2301 reinterpret_cast<base::AtomicWord>(this)); 2309 reinterpret_cast<base::AtomicWord>(this));
2302 2310
2303 // Store the previous break id, frame id and return value. 2311 // Store the previous break id, frame id and return value.
2304 break_id_ = debug_->break_id(); 2312 break_id_ = debug_->break_id();
2305 break_frame_id_ = debug_->break_frame_id(); 2313 break_frame_id_ = debug_->break_frame_id();
2306 return_value_ = debug_->return_value(); 2314 return_value_ = handle(debug_->return_value(), isolate());
2307 2315
2308 // Create the new break info. If there is no proper frames there is no break 2316 // Create the new break info. If there is no proper frames there is no break
2309 // frame id. 2317 // frame id.
2310 StackTraceFrameIterator it(isolate()); 2318 StackTraceFrameIterator it(isolate());
2311 bool has_frames = !it.done(); 2319 bool has_frames = !it.done();
2312 debug_->thread_local_.break_frame_id_ = 2320 debug_->thread_local_.break_frame_id_ =
2313 has_frames ? it.frame()->id() : StackFrame::NO_ID; 2321 has_frames ? it.frame()->id() : StackFrame::NO_ID;
2314 debug_->SetNextBreakId(); 2322 debug_->SetNextBreakId();
2315 2323
2316 debug_->UpdateState(); 2324 debug_->UpdateState();
(...skipping 13 matching lines...) Expand all
2330 if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache(); 2338 if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
2331 } 2339 }
2332 2340
2333 // Leaving this debugger entry. 2341 // Leaving this debugger entry.
2334 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, 2342 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
2335 reinterpret_cast<base::AtomicWord>(prev_)); 2343 reinterpret_cast<base::AtomicWord>(prev_));
2336 2344
2337 // Restore to the previous break state. 2345 // Restore to the previous break state.
2338 debug_->thread_local_.break_frame_id_ = break_frame_id_; 2346 debug_->thread_local_.break_frame_id_ = break_frame_id_;
2339 debug_->thread_local_.break_id_ = break_id_; 2347 debug_->thread_local_.break_id_ = break_id_;
2340 debug_->thread_local_.return_value_ = return_value_; 2348 debug_->thread_local_.return_value_ = *return_value_;
2341 2349
2342 debug_->UpdateState(); 2350 debug_->UpdateState();
2343 } 2351 }
2344 2352
2345 bool Debug::PerformSideEffectCheck(Handle<JSFunction> function) { 2353 bool Debug::PerformSideEffectCheck(Handle<JSFunction> function) {
2346 DCHECK(isolate_->needs_side_effect_check()); 2354 DCHECK(isolate_->needs_side_effect_check());
2347 DisallowJavascriptExecution no_js(isolate_); 2355 DisallowJavascriptExecution no_js(isolate_);
2348 if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) return false; 2356 if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) return false;
2349 Deoptimizer::DeoptimizeFunction(*function); 2357 Deoptimizer::DeoptimizeFunction(*function);
2350 if (!function->shared()->HasNoSideEffect()) { 2358 if (!function->shared()->HasNoSideEffect()) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2419 return v8::Utils::ToLocal(callback_data_); 2427 return v8::Utils::ToLocal(callback_data_);
2420 } 2428 }
2421 2429
2422 2430
2423 v8::Isolate* EventDetailsImpl::GetIsolate() const { 2431 v8::Isolate* EventDetailsImpl::GetIsolate() const {
2424 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); 2432 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
2425 } 2433 }
2426 2434
2427 } // namespace internal 2435 } // namespace internal
2428 } // namespace v8 2436 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/ia32/debug-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698