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 <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 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 | 474 |
475 // Return debugger is not loaded. | 475 // Return debugger is not loaded. |
476 if (!is_loaded()) return; | 476 if (!is_loaded()) return; |
477 | 477 |
478 // Clear debugger context global handle. | 478 // Clear debugger context global handle. |
479 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); | 479 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); |
480 debug_context_ = Handle<Context>(); | 480 debug_context_ = Handle<Context>(); |
481 } | 481 } |
482 | 482 |
483 void Debug::Break(JavaScriptFrame* frame) { | 483 void Debug::Break(JavaScriptFrame* frame) { |
484 HandleScope scope(isolate_); | |
485 | |
486 // Initialize LiveEdit. | 484 // Initialize LiveEdit. |
487 LiveEdit::InitializeThreadLocal(this); | 485 LiveEdit::InitializeThreadLocal(this); |
488 | 486 |
489 // Just continue if breaks are disabled or debugger cannot be loaded. | 487 // Just continue if breaks are disabled or debugger cannot be loaded. |
490 if (break_disabled()) return; | 488 if (break_disabled()) return; |
491 | 489 |
492 // Enter the debugger. | 490 // Enter the debugger. |
493 DebugScope debug_scope(this); | 491 DebugScope debug_scope(this); |
494 if (debug_scope.failed()) return; | 492 if (debug_scope.failed()) return; |
495 | 493 |
(...skipping 1703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2199 save_(debug_->isolate_), | 2197 save_(debug_->isolate_), |
2200 no_termination_exceptons_(debug_->isolate_, | 2198 no_termination_exceptons_(debug_->isolate_, |
2201 StackGuard::TERMINATE_EXECUTION) { | 2199 StackGuard::TERMINATE_EXECUTION) { |
2202 // Link recursive debugger entry. | 2200 // Link recursive debugger entry. |
2203 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, | 2201 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, |
2204 reinterpret_cast<base::AtomicWord>(this)); | 2202 reinterpret_cast<base::AtomicWord>(this)); |
2205 | 2203 |
2206 // Store the previous break id, frame id and return value. | 2204 // Store the previous break id, frame id and return value. |
2207 break_id_ = debug_->break_id(); | 2205 break_id_ = debug_->break_id(); |
2208 break_frame_id_ = debug_->break_frame_id(); | 2206 break_frame_id_ = debug_->break_frame_id(); |
2209 return_value_ = handle(debug_->return_value(), isolate()); | |
2210 | 2207 |
2211 // Create the new break info. If there is no proper frames there is no break | 2208 // Create the new break info. If there is no proper frames there is no break |
2212 // frame id. | 2209 // frame id. |
2213 StackTraceFrameIterator it(isolate()); | 2210 StackTraceFrameIterator it(isolate()); |
2214 bool has_frames = !it.done(); | 2211 bool has_frames = !it.done(); |
2215 debug_->thread_local_.break_frame_id_ = | 2212 debug_->thread_local_.break_frame_id_ = |
2216 has_frames ? it.frame()->id() : StackFrame::NO_ID; | 2213 has_frames ? it.frame()->id() : StackFrame::NO_ID; |
2217 debug_->SetNextBreakId(); | 2214 debug_->SetNextBreakId(); |
2218 | 2215 |
2219 debug_->UpdateState(); | 2216 debug_->UpdateState(); |
2220 // Make sure that debugger is loaded and enter the debugger context. | 2217 // Make sure that debugger is loaded and enter the debugger context. |
2221 // The previous context is kept in save_. | 2218 // The previous context is kept in save_. |
2222 failed_ = !debug_->is_loaded(); | 2219 failed_ = !debug_->is_loaded(); |
2223 if (!failed_) isolate()->set_context(*debug->debug_context()); | 2220 if (!failed_) isolate()->set_context(*debug->debug_context()); |
2224 } | 2221 } |
2225 | 2222 |
2226 | 2223 |
2227 DebugScope::~DebugScope() { | 2224 DebugScope::~DebugScope() { |
2228 // Leaving this debugger entry. | 2225 // Leaving this debugger entry. |
2229 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, | 2226 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, |
2230 reinterpret_cast<base::AtomicWord>(prev_)); | 2227 reinterpret_cast<base::AtomicWord>(prev_)); |
2231 | 2228 |
2232 // Restore to the previous break state. | 2229 // Restore to the previous break state. |
2233 debug_->thread_local_.break_frame_id_ = break_frame_id_; | 2230 debug_->thread_local_.break_frame_id_ = break_frame_id_; |
2234 debug_->thread_local_.break_id_ = break_id_; | 2231 debug_->thread_local_.break_id_ = break_id_; |
2235 debug_->thread_local_.return_value_ = *return_value_; | |
2236 | 2232 |
2237 debug_->UpdateState(); | 2233 debug_->UpdateState(); |
2238 } | 2234 } |
2239 | 2235 |
| 2236 ReturnValueScope::ReturnValueScope(Debug* debug) : debug_(debug) { |
| 2237 return_value_ = debug_->return_value_handle(); |
| 2238 } |
| 2239 |
| 2240 ReturnValueScope::~ReturnValueScope() { |
| 2241 debug_->set_return_value(*return_value_); |
| 2242 } |
| 2243 |
2240 bool Debug::PerformSideEffectCheck(Handle<JSFunction> function) { | 2244 bool Debug::PerformSideEffectCheck(Handle<JSFunction> function) { |
2241 DCHECK(isolate_->needs_side_effect_check()); | 2245 DCHECK(isolate_->needs_side_effect_check()); |
2242 DisallowJavascriptExecution no_js(isolate_); | 2246 DisallowJavascriptExecution no_js(isolate_); |
2243 if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) return false; | 2247 if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) return false; |
2244 Deoptimizer::DeoptimizeFunction(*function); | 2248 Deoptimizer::DeoptimizeFunction(*function); |
2245 if (!function->shared()->HasNoSideEffect()) { | 2249 if (!function->shared()->HasNoSideEffect()) { |
2246 if (FLAG_trace_side_effect_free_debug_evaluate) { | 2250 if (FLAG_trace_side_effect_free_debug_evaluate) { |
2247 PrintF("[debug-evaluate] Function %s failed side effect check.\n", | 2251 PrintF("[debug-evaluate] Function %s failed side effect check.\n", |
2248 function->shared()->DebugName()->ToCString().get()); | 2252 function->shared()->DebugName()->ToCString().get()); |
2249 } | 2253 } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2413 isolate_->Throw(*isolate_->factory()->NewEvalError( | 2417 isolate_->Throw(*isolate_->factory()->NewEvalError( |
2414 MessageTemplate::kNoSideEffectDebugEvaluate)); | 2418 MessageTemplate::kNoSideEffectDebugEvaluate)); |
2415 } | 2419 } |
2416 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_); | 2420 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_); |
2417 isolate_->debug()->UpdateHookOnFunctionCall(); | 2421 isolate_->debug()->UpdateHookOnFunctionCall(); |
2418 isolate_->debug()->side_effect_check_failed_ = false; | 2422 isolate_->debug()->side_effect_check_failed_ = false; |
2419 } | 2423 } |
2420 | 2424 |
2421 } // namespace internal | 2425 } // namespace internal |
2422 } // namespace v8 | 2426 } // namespace v8 |
OLD | NEW |