Revision: 21605
Author: [email protected]
Date: Mon Jun 2 12:07:37 2014 UTC
Log: Release execution lock before dispatching interrupt handling.
[email protected]
Review URL: https://codereview.chromium.org/309533009
http://code.google.com/p/v8/source/detail?r=21605
Modified:
/branches/bleeding_edge/src/debug.cc
/branches/bleeding_edge/src/execution.cc
/branches/bleeding_edge/src/execution.h
/branches/bleeding_edge/test/cctest/test-debug.cc
=======================================
--- /branches/bleeding_edge/src/debug.cc Mon Jun 2 11:41:50 2014 UTC
+++ /branches/bleeding_edge/src/debug.cc Mon Jun 2 12:07:37 2014 UTC
@@ -2541,6 +2541,8 @@
isolate_, isolate_->global_object(),
constructor_name).ToHandleChecked();
ASSERT(constructor->IsJSFunction());
if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
+ // We do not handle interrupts here. In particular, termination
interrupts.
+ PostponeInterruptsScope no_interrupts(isolate_);
return Execution::TryCall(Handle<JSFunction>::cast(constructor),
Handle<JSObject>(debug_context()->global_object()),
argc,
@@ -2852,6 +2854,9 @@
Handle<JSObject> exec_state,
Handle<JSObject> event_data,
bool auto_continue) {
+ // Prevent other interrupts from triggering, for example API callbacks,
+ // while dispatching message handler callbacks.
+ PostponeInterruptsScope no_interrupts(isolate_);
ASSERT(is_active_);
HandleScope scope(isolate_);
// Process the individual events.
=======================================
--- /branches/bleeding_edge/src/execution.cc Mon Jun 2 11:41:50 2014 UTC
+++ /branches/bleeding_edge/src/execution.cc Mon Jun 2 12:07:37 2014 UTC
@@ -366,13 +366,13 @@
}
-bool StackGuard::CheckAndClearInterrupt(InterruptFlag flag,
- const ExecutionAccess& lock) {
+bool StackGuard::CheckAndClearInterrupt(InterruptFlag flag) {
+ ExecutionAccess access(isolate_);
int flagbit = 1 << flag;
bool result = (thread_local_.interrupt_flags_ & flagbit);
thread_local_.interrupt_flags_ &= ~flagbit;
- if (!should_postpone_interrupts(lock) && !has_pending_interrupts(lock)) {
- reset_limits(lock);
+ if (!should_postpone_interrupts(access)
&& !has_pending_interrupts(access)) {
+ reset_limits(access);
}
return result;
}
@@ -655,45 +655,42 @@
Object* StackGuard::HandleInterrupts() {
- bool has_api_interrupt = false;
{
ExecutionAccess access(isolate_);
if (should_postpone_interrupts(access)) {
return isolate_->heap()->undefined_value();
}
+ }
- if (CheckAndClearInterrupt(GC_REQUEST, access)) {
- isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC
interrupt");
- }
+ if (CheckAndClearInterrupt(GC_REQUEST)) {
+ isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt");
+ }
- if (CheckDebugBreak() || CheckDebugCommand()) {
- isolate_->debug()->DebugBreakHelper();
- }
+ if (CheckDebugBreak() || CheckDebugCommand()) {
+ isolate_->debug()->DebugBreakHelper();
+ }
- if (CheckAndClearInterrupt(TERMINATE_EXECUTION, access)) {
- return isolate_->TerminateExecution();
- }
-
- if (CheckAndClearInterrupt(DEOPT_MARKED_ALLOCATION_SITES, access)) {
- isolate_->heap()->DeoptMarkedAllocationSites();
- }
-
- if (CheckAndClearInterrupt(INSTALL_CODE, access)) {
- ASSERT(isolate_->concurrent_recompilation_enabled());
- isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions();
- }
+ if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) {
+ return isolate_->TerminateExecution();
+ }
- has_api_interrupt = CheckAndClearInterrupt(API_INTERRUPT, access);
+ if (CheckAndClearInterrupt(DEOPT_MARKED_ALLOCATION_SITES)) {
+ isolate_->heap()->DeoptMarkedAllocationSites();
+ }
- isolate_->counters()->stack_interrupts()->Increment();
- isolate_->counters()->runtime_profiler_ticks()->Increment();
- isolate_->runtime_profiler()->OptimizeNow();
+ if (CheckAndClearInterrupt(INSTALL_CODE)) {
+ ASSERT(isolate_->concurrent_recompilation_enabled());
+ isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions();
}
- if (has_api_interrupt) {
+ if (CheckAndClearInterrupt(API_INTERRUPT)) {
// Callback must be invoked outside of ExecusionAccess lock.
isolate_->InvokeApiInterruptCallback();
}
+
+ isolate_->counters()->stack_interrupts()->Increment();
+ isolate_->counters()->runtime_profiler_ticks()->Increment();
+ isolate_->runtime_profiler()->OptimizeNow();
return isolate_->heap()->undefined_value();
}
=======================================
--- /branches/bleeding_edge/src/execution.h Mon Jun 2 11:41:50 2014 UTC
+++ /branches/bleeding_edge/src/execution.h Mon Jun 2 12:07:37 2014 UTC
@@ -203,7 +203,7 @@
bool CheckInterrupt(int flagbit);
void RequestInterrupt(int flagbit);
void ClearInterrupt(int flagbit);
- bool CheckAndClearInterrupt(InterruptFlag flag, const ExecutionAccess&
lock);
+ bool CheckAndClearInterrupt(InterruptFlag flag);
// You should hold the ExecutionAccess lock when calling this method.
bool has_pending_interrupts(const ExecutionAccess& lock) {
=======================================
--- /branches/bleeding_edge/test/cctest/test-debug.cc Mon Jun 2 11:41:50
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-debug.cc Mon Jun 2 12:07:37
2014 UTC
@@ -7425,3 +7425,49 @@
" }"
"})()");
}
+
+
+v8::internal::Semaphore terminate_requested_semaphore(0);
+v8::internal::Semaphore terminate_fired_semaphore(0);
+bool terminate_already_fired = false;
+
+
+static void DebugBreakTriggerTerminate(
+ const v8::Debug::EventDetails& event_details) {
+ if (event_details.GetEvent() != v8::Break || terminate_already_fired)
return;
+ terminate_requested_semaphore.Signal();
+ // Wait for at most 2 seconds for the terminate request.
+ CHECK(terminate_fired_semaphore.WaitFor(i::TimeDelta::FromSeconds(2)));
+ terminate_already_fired = true;
+ v8::internal::Isolate* isolate =
+
v8::Utils::OpenHandle(*event_details.GetEventContext())->GetIsolate();
+ CHECK(isolate->stack_guard()->CheckTerminateExecution());
+}
+
+
+class TerminationThread : public v8::internal::Thread {
+ public:
+ explicit TerminationThread(v8::Isolate* isolate) : Thread("terminator"),
+ isolate_(isolate) { }
+
+ virtual void Run() {
+ terminate_requested_semaphore.Wait();
+ v8::V8::TerminateExecution(isolate_);
+ terminate_fired_semaphore.Signal();
+ }
+
+ private:
+ v8::Isolate* isolate_;
+};
+
+
+TEST(DebugBreakOffThreadTerminate) {
+ DebugLocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate);
+ TerminationThread terminator(isolate);
+ terminator.Start();
+ v8::Debug::DebugBreak(isolate);
+ CompileRun("while (true);");
+}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.