Commit b266a9ec authored by kasperl@chromium.org's avatar kasperl@chromium.org

Avoid messing with the stack overflow limits while interrupts

are postponed. This way, V8 will wait until interrupts are
re-enabled before artifically lowering the stack limit thereby 
forcing the interruption of the JavaScript executing thread.
Review URL: http://codereview.chromium.org/1638009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4403 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 238b2112
......@@ -221,8 +221,8 @@ bool StackGuard::IsStackOverflow() {
void StackGuard::EnableInterrupts() {
ExecutionAccess access;
if (IsSet(access)) {
set_limits(kInterruptLimit, access);
if (has_pending_interrupts(access)) {
set_interrupt_limits(access);
}
}
......@@ -249,11 +249,6 @@ void StackGuard::DisableInterrupts() {
}
bool StackGuard::IsSet(const ExecutionAccess& lock) {
return thread_local_.interrupt_flags_ != 0;
}
bool StackGuard::IsInterrupted() {
ExecutionAccess access;
return thread_local_.interrupt_flags_ & INTERRUPT;
......@@ -263,7 +258,7 @@ bool StackGuard::IsInterrupted() {
void StackGuard::Interrupt() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= INTERRUPT;
set_limits(kInterruptLimit, access);
set_interrupt_limits(access);
}
......@@ -276,7 +271,7 @@ bool StackGuard::IsPreempted() {
void StackGuard::Preempt() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= PREEMPT;
set_limits(kInterruptLimit, access);
set_interrupt_limits(access);
}
......@@ -289,7 +284,7 @@ bool StackGuard::IsTerminateExecution() {
void StackGuard::TerminateExecution() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= TERMINATE;
set_limits(kInterruptLimit, access);
set_interrupt_limits(access);
}
......@@ -303,7 +298,7 @@ bool StackGuard::IsDebugBreak() {
void StackGuard::DebugBreak() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= DEBUGBREAK;
set_limits(kInterruptLimit, access);
set_interrupt_limits(access);
}
......@@ -317,7 +312,7 @@ void StackGuard::DebugCommand() {
if (FLAG_debugger_auto_break) {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
set_limits(kInterruptLimit, access);
set_interrupt_limits(access);
}
}
#endif
......@@ -325,7 +320,7 @@ void StackGuard::DebugCommand() {
void StackGuard::Continue(InterruptFlag after_what) {
ExecutionAccess access;
thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
if (thread_local_.interrupt_flags_ == 0) {
if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
reset_limits(access);
}
}
......
......@@ -199,12 +199,24 @@ class StackGuard : public AllStatic {
private:
// You should hold the ExecutionAccess lock when calling this method.
static bool IsSet(const ExecutionAccess& lock);
static bool has_pending_interrupts(const ExecutionAccess& lock) {
// Sanity check: We shouldn't be asking about pending interrupts
// unless we're not postponing them anymore.
ASSERT(!should_postpone_interrupts(lock));
return thread_local_.interrupt_flags_ != 0;
}
// You should hold the ExecutionAccess lock when calling this method.
static bool should_postpone_interrupts(const ExecutionAccess& lock) {
return thread_local_.postpone_interrupts_nesting_ > 0;
}
// You should hold the ExecutionAccess lock when calling this method.
static void set_limits(uintptr_t value, const ExecutionAccess& lock) {
thread_local_.jslimit_ = value;
thread_local_.climit_ = value;
static void set_interrupt_limits(const ExecutionAccess& lock) {
// Ignore attempts to interrupt when interrupts are postponed.
if (should_postpone_interrupts(lock)) return;
thread_local_.jslimit_ = kInterruptLimit;
thread_local_.climit_ = kInterruptLimit;
Heap::SetStackLimits();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment