Revision: 22074
Author:   [email protected]
Date:     Mon Jun 30 06:45:23 2014 UTC
Log:      Revert "Add mechanism to postpone interrupts selectively."

This reverts commit r22073.

[email protected]

Review URL: https://codereview.chromium.org/362493002
http://code.google.com/p/v8/source/detail?r=22074

Modified:
 /branches/bleeding_edge/src/execution.cc
 /branches/bleeding_edge/src/execution.h
 /branches/bleeding_edge/src/isolate.cc
 /branches/bleeding_edge/src/isolate.h
 /branches/bleeding_edge/test/cctest/test-thread-termination.cc

=======================================
--- /branches/bleeding_edge/src/execution.cc    Mon Jun 30 06:27:20 2014 UTC
+++ /branches/bleeding_edge/src/execution.cc    Mon Jun 30 06:45:23 2014 UTC
@@ -20,6 +20,8 @@

 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();
@@ -335,62 +337,36 @@
 }


-void StackGuard::PushPostponeInterruptsScope(PostponeInterruptsScope* scope) {
+bool StackGuard::CheckInterrupt(int flagbit) {
   ExecutionAccess access(isolate_);
-  scope->prev_ = thread_local_.postpone_interrupts_;
-  thread_local_.postpone_interrupts_ = scope;
+  return thread_local_.interrupt_flags_ & flagbit;
 }


-void StackGuard::PopPostponeInterruptsScope() {
+void StackGuard::RequestInterrupt(int flagbit) {
   ExecutionAccess access(isolate_);
-  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;
+  thread_local_.interrupt_flags_ |= flagbit;
   set_interrupt_limits(access);
 }


-void StackGuard::ClearInterrupt(InterruptFlag flag) {
+void StackGuard::ClearInterrupt(int flagbit) {
   ExecutionAccess access(isolate_);
-  // 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;
+  thread_local_.interrupt_flags_ &= ~flagbit;
+ if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
+    reset_limits(access);
   }
-
-  // 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_);
-  bool result = (thread_local_.interrupt_flags_ & flag);
-  thread_local_.interrupt_flags_ &= ~flag;
-  if (!has_pending_interrupts(access)) reset_limits(access);
+  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);
+  }
   return result;
 }

@@ -432,7 +408,8 @@
   jslimit_ = kIllegalLimit;
   real_climit_ = kIllegalLimit;
   climit_ = kIllegalLimit;
-  postpone_interrupts_ = NULL;
+  nesting_ = 0;
+  postpone_interrupts_nesting_ = 0;
   interrupt_flags_ = 0;
 }

@@ -451,7 +428,8 @@
     climit_ = limit;
     should_set_stack_limits = true;
   }
-  postpone_interrupts_ = NULL;
+  nesting_ = 0;
+  postpone_interrupts_nesting_ = 0;
   interrupt_flags_ = 0;
   return should_set_stack_limits;
 }
@@ -670,6 +648,13 @@


 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");
   }
=======================================
--- /branches/bleeding_edge/src/execution.h     Mon Jun 30 06:27:20 2014 UTC
+++ /branches/bleeding_edge/src/execution.h     Mon Jun 30 06:45:23 2014 UTC
@@ -122,7 +122,6 @@


 class ExecutionAccess;
-class PostponeInterruptsScope;


// StackGuard contains the handling of the limits that are used to limit the
@@ -146,32 +145,22 @@
   // it has been set up.
   void ClearThread(const ExecutionAccess& lock);

-#define INTERRUPT_LIST(V)                                          \
-  V(DEBUGBREAK, DebugBreak, 0)                                     \
-  V(DEBUGCOMMAND, DebugCommand, 1)                                 \
-  V(TERMINATE_EXECUTION, TerminateExecution, 2)                    \
-  V(GC_REQUEST, GC, 3)                                             \
-  V(INSTALL_CODE, InstallCode, 4)                                  \
-  V(API_INTERRUPT, ApiInterrupt, 5)                                \
-  V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites, 6)
+#define INTERRUPT_LIST(V)                                       \
+  V(DEBUGBREAK, DebugBreak)                                     \
+  V(DEBUGCOMMAND, DebugCommand)                                 \
+  V(TERMINATE_EXECUTION, TerminateExecution)                    \
+  V(GC_REQUEST, GC)                                             \
+  V(INSTALL_CODE, InstallCode)                                  \
+  V(API_INTERRUPT, ApiInterrupt)                                \
+  V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites)

-#define V(NAME, Name, id)                                          \
-  inline bool Check##Name() { return CheckInterrupt(NAME); }  \
-  inline void Request##Name() { RequestInterrupt(NAME); }     \
-  inline void Clear##Name() { ClearInterrupt(NAME); }
+#define V(NAME, Name)                                              \
+  inline bool Check##Name() { return CheckInterrupt(1 << NAME); }  \
+  inline void Request##Name() { RequestInterrupt(1 << NAME); }     \
+  inline void Clear##Name() { ClearInterrupt(1 << NAME); }
   INTERRUPT_LIST(V)
 #undef V

-  // Flag used to set the interrupt causes.
-  enum InterruptFlag {
-  #define V(NAME, Name, id) NAME = (1 << id),
-    INTERRUPT_LIST(V)
-  #undef V
-  #define V(NAME, Name, id) NAME |
-    ALL_INTERRUPTS = INTERRUPT_LIST(V) 0
-  #undef V
-  };
-
   // This provides an asynchronous read of the stack limits for the current
// thread. There are no locks protecting this, but it is assumed that you
   // have the global V8 lock if you are using multiple V8 threads.
@@ -201,15 +190,31 @@
  private:
   StackGuard();

-  bool CheckInterrupt(InterruptFlag flag);
-  void RequestInterrupt(InterruptFlag flag);
-  void ClearInterrupt(InterruptFlag flag);
+// Flag used to set the interrupt causes.
+enum InterruptFlag {
+#define V(NAME, Name) NAME,
+  INTERRUPT_LIST(V)
+#undef V
+  NUMBER_OF_INTERRUPTS
+};
+
+  bool CheckInterrupt(int flagbit);
+  void RequestInterrupt(int flagbit);
+  void ClearInterrupt(int flagbit);
   bool CheckAndClearInterrupt(InterruptFlag flag);

   // You should hold the ExecutionAccess lock when calling this method.
   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.
+  bool should_postpone_interrupts(const ExecutionAccess& lock) {
+    return thread_local_.postpone_interrupts_nesting_ > 0;
+  }

   // You should hold the ExecutionAccess lock when calling this method.
   inline void set_interrupt_limits(const ExecutionAccess& lock);
@@ -230,9 +235,6 @@
   static const uintptr_t kIllegalLimit = 0xfffffff8;
 #endif

-  void PushPostponeInterruptsScope(PostponeInterruptsScope* scope);
-  void PopPostponeInterruptsScope();
-
   class ThreadLocal V8_FINAL {
    public:
     ThreadLocal() { Clear(); }
@@ -257,7 +259,8 @@
     uintptr_t real_climit_;  // Actual C++ stack limit set for the VM.
     uintptr_t climit_;

-    PostponeInterruptsScope* postpone_interrupts_;
+    int nesting_;
+    int postpone_interrupts_nesting_;
     int interrupt_flags_;
   };

=======================================
--- /branches/bleeding_edge/src/isolate.cc      Mon Jun 30 06:27:20 2014 UTC
+++ /branches/bleeding_edge/src/isolate.cc      Mon Jun 30 06:45:23 2014 UTC
@@ -2371,15 +2371,4 @@
 }


-bool PostponeInterruptsScope::Intercept(StackGuard::InterruptFlag flag) {
-  // First check whether the previous scope intercepts.
-  if (prev_ && prev_->Intercept(flag)) return true;
-  // Then check whether this scope intercepts.
-  if ((flag & intercept_mask_)) {
-    intercepted_flags_ |= flag;
-    return true;
-  }
-  return false;
-}
-
 } }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/isolate.h       Mon Jun 30 06:27:20 2014 UTC
+++ /branches/bleeding_edge/src/isolate.h       Mon Jun 30 06:45:23 2014 UTC
@@ -1420,29 +1420,22 @@
 // account.
 class PostponeInterruptsScope BASE_EMBEDDED {
  public:
-  PostponeInterruptsScope(Isolate* isolate,
-                          int intercept_mask = StackGuard::ALL_INTERRUPTS)
-      : stack_guard_(isolate->stack_guard()),
-        intercept_mask_(intercept_mask),
-        intercepted_flags_(0) {
-    stack_guard_->PushPostponeInterruptsScope(this);
+  explicit PostponeInterruptsScope(Isolate* isolate)
+      : stack_guard_(isolate->stack_guard()), isolate_(isolate) {
+    ExecutionAccess access(isolate_);
+    stack_guard_->thread_local_.postpone_interrupts_nesting_++;
+    stack_guard_->DisableInterrupts();
   }

   ~PostponeInterruptsScope() {
-    stack_guard_->PopPostponeInterruptsScope();
+    ExecutionAccess access(isolate_);
+    if (--stack_guard_->thread_local_.postpone_interrupts_nesting_ == 0) {
+      stack_guard_->EnableInterrupts();
+    }
   }
-
-  // Find the bottom-most scope that intercepts this interrupt.
-  // Return whether the interrupt has been intercepted.
-  bool Intercept(StackGuard::InterruptFlag flag);
-
  private:
   StackGuard* stack_guard_;
-  int intercept_mask_;
-  int intercepted_flags_;
-  PostponeInterruptsScope* prev_;
-
-  friend class StackGuard;
+  Isolate* isolate_;
 };


=======================================
--- /branches/bleeding_edge/test/cctest/test-thread-termination.cc Mon Jun 30 06:27:20 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-thread-termination.cc Mon Jun 30 06:45:23 2014 UTC
@@ -403,59 +403,3 @@
   delete semaphore;
   semaphore = NULL;
 }
-
-
-static int callback_counter = 0;
-
-
-static void CounterCallback(v8::Isolate* isolate, void* data) {
-  callback_counter++;
-}
-
-
-TEST(PostponeTerminateException) {
-  v8::Isolate* isolate = CcTest::isolate();
-  v8::HandleScope scope(isolate);
-  v8::Handle<v8::ObjectTemplate> global =
- CreateGlobalTemplate(CcTest::isolate(), TerminateCurrentThread, DoLoop);
-  v8::Handle<v8::Context> context =
-      v8::Context::New(CcTest::isolate(), NULL, global);
-  v8::Context::Scope context_scope(context);
-
-  v8::TryCatch try_catch;
-  static const char* terminate_and_loop =
-      "terminate(); for (var i = 0; i < 10000; i++);";
-
-  { // Postpone terminate execution interrupts.
-    i::PostponeInterruptsScope p1(CcTest::i_isolate(),
-                                  i::StackGuard::TERMINATE_EXECUTION) ;
-
-    // API interrupts should still be triggered.
-    CcTest::isolate()->RequestInterrupt(&CounterCallback, NULL);
-    CHECK_EQ(0, callback_counter);
-    CompileRun(terminate_and_loop);
-    CHECK(!try_catch.HasTerminated());
-    CHECK_EQ(1, callback_counter);
-
-    { // Postpone API interrupts as well.
-      i::PostponeInterruptsScope p2(CcTest::i_isolate(),
-                                    i::StackGuard::API_INTERRUPT);
-
-      // None of the two interrupts should trigger.
-      CcTest::isolate()->RequestInterrupt(&CounterCallback, NULL);
-      CompileRun(terminate_and_loop);
-      CHECK(!try_catch.HasTerminated());
-      CHECK_EQ(1, callback_counter);
-    }
-
-    // Now the previously requested API interrupt should trigger.
-    CompileRun(terminate_and_loop);
-    CHECK(!try_catch.HasTerminated());
-    CHECK_EQ(2, callback_counter);
-  }
-
- // Now the previously requested terminate execution interrupt should trigger.
-  CompileRun("for (var i = 0; i < 10000; i++);");
-  CHECK(try_catch.HasTerminated());
-  CHECK_EQ(2, callback_counter);
-}

--
--
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.

Reply via email to