void StackGuard::EnableInterrupts() {
ExecutionAccess access;
- if (IsSet(access)) {
- set_limits(kInterruptLimit, access);
+ if (has_pending_interrupts(access)) {
+ set_interrupt_limits(access);
}
}
}
-bool StackGuard::IsSet(const ExecutionAccess& lock) {
- return thread_local_.interrupt_flags_ != 0;
-}
-
-
bool StackGuard::IsInterrupted() {
ExecutionAccess access;
return thread_local_.interrupt_flags_ & INTERRUPT;
void StackGuard::Interrupt() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= INTERRUPT;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
void StackGuard::Preempt() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= PREEMPT;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
void StackGuard::TerminateExecution() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= TERMINATE;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
void StackGuard::DebugBreak() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= DEBUGBREAK;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
if (FLAG_debugger_auto_break) {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
}
#endif
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);
}
}
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();
}