| Index: src/execution.cc
|
| diff --git a/src/execution.cc b/src/execution.cc
|
| index 2766e76b8caa5454923542d8861a6a581977f946..5cb55311bc04f72006b0ea4da71ddb34d91a4b20 100644
|
| --- a/src/execution.cc
|
| +++ b/src/execution.cc
|
| @@ -20,8 +20,6 @@ StackGuard::StackGuard()
|
|
|
| void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
|
| ASSERT(isolate_ != NULL);
|
| - // Ignore attempts to interrupt when interrupts are postponed.
|
| - if (should_postpone_interrupts(lock)) return;
|
| thread_local_.jslimit_ = kInterruptLimit;
|
| thread_local_.climit_ = kInterruptLimit;
|
| isolate_->heap()->SetStackLimits();
|
| @@ -337,36 +335,62 @@ void StackGuard::DisableInterrupts() {
|
| }
|
|
|
|
|
| -bool StackGuard::CheckInterrupt(int flagbit) {
|
| +void StackGuard::PushPostponeInterruptsScope(PostponeInterruptsScope* scope) {
|
| ExecutionAccess access(isolate_);
|
| - return thread_local_.interrupt_flags_ & flagbit;
|
| + scope->prev_ = thread_local_.postpone_interrupts_;
|
| + thread_local_.postpone_interrupts_ = scope;
|
| }
|
|
|
|
|
| -void StackGuard::RequestInterrupt(int flagbit) {
|
| +void StackGuard::PopPostponeInterruptsScope() {
|
| ExecutionAccess access(isolate_);
|
| - thread_local_.interrupt_flags_ |= flagbit;
|
| + PostponeInterruptsScope* top = thread_local_.postpone_interrupts_;
|
| + thread_local_.interrupt_flags_ |= top->intercepted_flags_;
|
| + thread_local_.postpone_interrupts_ = top->prev_;
|
| + if (has_pending_interrupts(access)) set_interrupt_limits(access);
|
| +}
|
| +
|
| +
|
| +bool StackGuard::CheckInterrupt(InterruptFlag flag) {
|
| + ExecutionAccess access(isolate_);
|
| + return thread_local_.interrupt_flags_ & flag;
|
| +}
|
| +
|
| +
|
| +void StackGuard::RequestInterrupt(InterruptFlag flag) {
|
| + ExecutionAccess access(isolate_);
|
| + // Check the chain of PostponeInterruptsScopes for interception.
|
| + if (thread_local_.postpone_interrupts_ &&
|
| + thread_local_.postpone_interrupts_->Intercept(flag)) {
|
| + return;
|
| + }
|
| +
|
| + // Not intercepted. Set as active interrupt flag.
|
| + thread_local_.interrupt_flags_ |= flag;
|
| set_interrupt_limits(access);
|
| }
|
|
|
|
|
| -void StackGuard::ClearInterrupt(int flagbit) {
|
| +void StackGuard::ClearInterrupt(InterruptFlag flag) {
|
| ExecutionAccess access(isolate_);
|
| - thread_local_.interrupt_flags_ &= ~flagbit;
|
| - if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
|
| - reset_limits(access);
|
| + // Clear the interrupt flag from the chain of PostponeInterruptsScopes.
|
| + for (PostponeInterruptsScope* current = thread_local_.postpone_interrupts_;
|
| + current != NULL;
|
| + current = current->prev_) {
|
| + current->intercepted_flags_ &= ~flag;
|
| }
|
| +
|
| + // Clear the interrupt flag from the active interrupt flags.
|
| + thread_local_.interrupt_flags_ &= ~flag;
|
| + if (!has_pending_interrupts(access)) reset_limits(access);
|
| }
|
|
|
|
|
| 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(access) && !has_pending_interrupts(access)) {
|
| - reset_limits(access);
|
| - }
|
| + bool result = (thread_local_.interrupt_flags_ & flag);
|
| + thread_local_.interrupt_flags_ &= ~flag;
|
| + if (!has_pending_interrupts(access)) reset_limits(access);
|
| return result;
|
| }
|
|
|
| @@ -408,8 +432,7 @@ void StackGuard::ThreadLocal::Clear() {
|
| jslimit_ = kIllegalLimit;
|
| real_climit_ = kIllegalLimit;
|
| climit_ = kIllegalLimit;
|
| - nesting_ = 0;
|
| - postpone_interrupts_nesting_ = 0;
|
| + postpone_interrupts_ = NULL;
|
| interrupt_flags_ = 0;
|
| }
|
|
|
| @@ -428,8 +451,7 @@ bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
|
| climit_ = limit;
|
| should_set_stack_limits = true;
|
| }
|
| - nesting_ = 0;
|
| - postpone_interrupts_nesting_ = 0;
|
| + postpone_interrupts_ = NULL;
|
| interrupt_flags_ = 0;
|
| return should_set_stack_limits;
|
| }
|
| @@ -648,13 +670,6 @@ Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
|
|
|
|
|
| Object* StackGuard::HandleInterrupts() {
|
| - {
|
| - ExecutionAccess access(isolate_);
|
| - if (should_postpone_interrupts(access)) {
|
| - return isolate_->heap()->undefined_value();
|
| - }
|
| - }
|
| -
|
| if (CheckAndClearInterrupt(GC_REQUEST)) {
|
| isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt");
|
| }
|
|
|