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

Unified Diff: src/debug/debug.cc

Issue 2622863003: [debugger] infrastructure for side-effect-free debug-evaluate. (Closed)
Patch Set: Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: src/debug/debug.cc
diff --git a/src/debug/debug.cc b/src/debug/debug.cc
index 1bd69cbc882ddf5faf10280abc9d1bd0a59b3602..71dc2cc55e9e701a7101a36eda2dd4b43ee534e7 100644
--- a/src/debug/debug.cc
+++ b/src/debug/debug.cc
@@ -42,6 +42,7 @@ Debug::Debug(Isolate* isolate)
command_received_(0),
command_queue_(isolate->logger(), kQueueInitialSize),
is_active_(false),
+ hook_on_function_call_(false),
is_suppressed_(false),
live_edit_enabled_(true), // TODO(yangguo): set to false by default.
break_disabled_(false),
@@ -49,6 +50,8 @@ Debug::Debug(Isolate* isolate)
in_debug_event_listener_(false),
break_on_exception_(false),
break_on_uncaught_exception_(false),
+ needs_readonly_check_(false),
+ readonly_check_failed_(false),
debug_info_list_(NULL),
feature_tracker_(isolate),
isolate_(isolate) {
@@ -405,6 +408,7 @@ void Debug::ThreadInit() {
// TODO(isolates): frames_are_dropped_?
base::NoBarrier_Store(&thread_local_.current_debug_scope_,
static_cast<base::AtomicWord>(0));
+ UpdateHookOnFunctionCall();
}
@@ -904,16 +908,19 @@ bool Debug::IsBreakOnException(ExceptionBreakType type) {
void Debug::PrepareStepIn(Handle<JSFunction> function) {
CHECK(last_step_action() >= StepIn);
- if (!is_active()) return;
+ if (ignore_events()) return;
if (in_debug_scope()) return;
+ if (break_disabled()) return;
FloodWithOneShot(function);
}
void Debug::PrepareStepInSuspendedGenerator() {
CHECK(has_suspended_generator());
- if (!is_active()) return;
+ if (ignore_events()) return;
if (in_debug_scope()) return;
+ if (break_disabled()) return;
thread_local_.last_step_action_ = StepIn;
+ UpdateHookOnFunctionCall();
Handle<JSFunction> function(
JSGeneratorObject::cast(thread_local_.suspended_generator_)->function());
FloodWithOneShot(function);
@@ -921,9 +928,10 @@ void Debug::PrepareStepInSuspendedGenerator() {
}
void Debug::PrepareStepOnThrow() {
- if (!is_active()) return;
if (last_step_action() == StepNone) return;
+ if (ignore_events()) return;
if (in_debug_scope()) return;
+ if (break_disabled()) return;
ClearOneShot();
@@ -974,6 +982,7 @@ void Debug::PrepareStep(StepAction step_action) {
feature_tracker()->Track(DebugFeatureTracker::kStepping);
thread_local_.last_step_action_ = step_action;
+ UpdateHookOnFunctionCall();
// If the function on the top frame is unresolved perform step out. This will
// be the case when calling unknown function and having the debugger stopped
@@ -1104,6 +1113,7 @@ void Debug::ClearStepping() {
thread_local_.last_statement_position_ = kNoSourcePosition;
thread_local_.last_fp_ = 0;
thread_local_.target_fp_ = 0;
+ UpdateHookOnFunctionCall();
}
@@ -2078,6 +2088,11 @@ void Debug::UpdateState() {
is_active_ = is_active;
}
+void Debug::UpdateHookOnFunctionCall() {
+ hook_on_function_call_ =
+ thread_local_.last_step_action_ >= StepIn || needs_readonly_check_;
+}
+
// Calls the registered debug message handler. This callback is part of the
// public API.
void Debug::InvokeMessageHandler(MessageImpl message) {
@@ -2275,6 +2290,38 @@ DebugScope::~DebugScope() {
debug_->UpdateState();
}
+bool Debug::PerformReadOnlyCheck(Handle<JSFunction> function) {
+ DCHECK(needs_readonly_check_);
+ if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) return false;
+ Deoptimizer::DeoptimizeFunction(*function);
+ if (!function->shared()->IsReadOnly()) {
+ if (FLAG_trace_readonly_debug_evaluate) {
+ PrintF("[ro] Function %s failed read-only check.\n",
+ function->shared()->DebugName()->ToCString().get());
+ }
+ readonly_check_failed_ = true;
+ // Throw an uncatchable termination exception.
+ isolate_->TerminateExecution();
+ return false;
+ }
+ return true;
+}
+
+ReadOnlyEvaluate::~ReadOnlyEvaluate() {
+ debug_->needs_readonly_check_ = old_state_;
+ debug_->UpdateHookOnFunctionCall();
+ Isolate* isolate = debug_->isolate_;
+ if (debug_->readonly_check_failed_ && isolate->has_pending_exception() &&
jgruber 2017/01/10 12:46:37 Doesn't readonly_check_failed_ imply the remaining
Yang 2017/01/10 14:14:06 Done.
+ isolate->pending_exception() ==
+ isolate->heap()->termination_exception()) {
+ // Convert the termination exception into a regular exception.
+ isolate->CancelTerminateExecution();
+ isolate->Throw(*isolate->factory()->NewEvalError(
+ MessageTemplate::kReadOnlyDebugEvaluate));
+ }
+ debug_->readonly_check_failed_ = false;
+}
+
MessageImpl MessageImpl::NewEvent(DebugEvent event, bool running,
Handle<JSObject> exec_state,
Handle<JSObject> event_data) {

Powered by Google App Engine
This is Rietveld 408576698