Version 5.2.361.20 (cherry-pick)

Merged 84ee947013003d481b1222d975e4456122b6efe9

Workaround for glibc semaphore bug.

BUG=chromium:609249
LOG=N
R=mlippautz@chromium.org

Review URL: https://codereview.chromium.org/2048313002 .

Cr-Commit-Position: refs/branch-heads/5.2@{#26}
Cr-Branched-From: 2cd36d6d0439ddfbe84cd90e112dced85084ec95-refs/heads/5.2.361@{#1}
Cr-Branched-From: 3fef34e02388e07d46067c516320f1ff12304c8e-refs/heads/master@{#36332}
diff --git a/include/v8-version.h b/include/v8-version.h
index 78b4561..6cd2dd6 100644
--- a/include/v8-version.h
+++ b/include/v8-version.h
@@ -11,7 +11,7 @@
 #define V8_MAJOR_VERSION 5
 #define V8_MINOR_VERSION 2
 #define V8_BUILD_NUMBER 361
-#define V8_PATCH_LEVEL 19
+#define V8_PATCH_LEVEL 20
 
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/base/platform/semaphore.cc b/src/base/platform/semaphore.cc
index 64489f9..a7e522a 100644
--- a/src/base/platform/semaphore.cc
+++ b/src/base/platform/semaphore.cc
@@ -34,11 +34,10 @@
   USE(result);
 }
 
-void Semaphore::Signal(const char* caller) {
+void Semaphore::Signal() {
   kern_return_t result = semaphore_signal(native_handle_);
   DCHECK_EQ(KERN_SUCCESS, result);
   USE(result);
-  USE(caller);
 }
 
 
@@ -104,12 +103,9 @@
   USE(result);
 }
 
-void Semaphore::Signal(const char* caller) {
+void Semaphore::Signal() {
   int result = sem_post(&native_handle_);
-  if (result != 0) {
-    V8_Fatal(__FILE__, __LINE__,
-             "Semaphore signal failure: %d called by '%s'\n", errno, caller);
-  }
+  CHECK_EQ(0, result);
 }
 
 
@@ -177,12 +173,11 @@
   USE(result);
 }
 
-void Semaphore::Signal(const char* caller) {
+void Semaphore::Signal() {
   LONG dummy;
   BOOL result = ReleaseSemaphore(native_handle_, 1, &dummy);
   DCHECK(result);
   USE(result);
-  USE(caller);
 }
 
 
diff --git a/src/base/platform/semaphore.h b/src/base/platform/semaphore.h
index ad8c7ec..18700d1 100644
--- a/src/base/platform/semaphore.h
+++ b/src/base/platform/semaphore.h
@@ -37,8 +37,7 @@
   ~Semaphore();
 
   // Increments the semaphore counter.
-  // TODO(ulan): remove caller parameter once crbug.com/609249 is fixed.
-  void Signal(const char* caller = nullptr);
+  void Signal();
 
   // Suspends the calling thread until the semaphore counter is non zero
   // and then decrements the semaphore counter.
diff --git a/src/debug/debug.cc b/src/debug/debug.cc
index 7272ee6..3b5fb5f 100644
--- a/src/debug/debug.cc
+++ b/src/debug/debug.cc
@@ -2159,7 +2159,7 @@
       client_data);
   isolate_->logger()->DebugTag("Put command on command_queue.");
   command_queue_.Put(message);
-  command_received_.Signal("Debug::EnqueueCommandMessage");
+  command_received_.Signal();
 
   // Set the debug command break flag to have the command processed.
   if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index ad0c58e..0f43ad9 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -49,19 +49,21 @@
 
 MarkCompactCollector::MarkCompactCollector(Heap* heap)
     :  // NOLINT
+      heap_(heap),
+      page_parallel_job_semaphore_(0),
 #ifdef DEBUG
       state_(IDLE),
 #endif
       marking_parity_(ODD_MARKING_PARITY),
       was_marked_incrementally_(false),
       evacuation_(false),
-      heap_(heap),
+      compacting_(false),
+      black_allocation_(false),
+      have_code_to_deoptimize_(false),
       marking_deque_memory_(NULL),
       marking_deque_memory_committed_(0),
       code_flusher_(nullptr),
       embedder_heap_tracer_(nullptr),
-      have_code_to_deoptimize_(false),
-      compacting_(false),
       sweeper_(heap) {
 }
 
@@ -480,7 +482,7 @@
       DCHECK_LE(space_id, LAST_PAGED_SPACE);
       sweeper_->ParallelSweepSpace(static_cast<AllocationSpace>(space_id), 0);
     }
-    pending_sweeper_tasks_->Signal("SweeperTask::Run");
+    pending_sweeper_tasks_->Signal();
   }
 
   Sweeper* sweeper_;
@@ -585,7 +587,7 @@
           base::TimeDelta::FromSeconds(0))) {
     return false;
   }
-  pending_sweeper_tasks_semaphore_.Signal("Sweeper::IsSweepingCompleted");
+  pending_sweeper_tasks_semaphore_.Signal();
   return true;
 }
 
@@ -3278,7 +3280,8 @@
 
 void MarkCompactCollector::EvacuatePagesInParallel() {
   PageParallelJob<EvacuationJobTraits> job(
-      heap_, heap_->isolate()->cancelable_task_manager());
+      heap_, heap_->isolate()->cancelable_task_manager(),
+      &page_parallel_job_semaphore_);
 
   int abandoned_pages = 0;
   intptr_t live_bytes = 0;
@@ -3634,9 +3637,9 @@
 }
 
 template <PointerDirection direction>
-void UpdatePointersInParallel(Heap* heap) {
+void UpdatePointersInParallel(Heap* heap, base::Semaphore* semaphore) {
   PageParallelJob<PointerUpdateJobTraits<direction> > job(
-      heap, heap->isolate()->cancelable_task_manager());
+      heap, heap->isolate()->cancelable_task_manager(), semaphore);
   RememberedSet<direction>::IterateMemoryChunks(
       heap, [&job](MemoryChunk* chunk) { job.AddPage(chunk, 0); });
   PointersUpdatingVisitor visitor(heap);
@@ -3666,9 +3669,9 @@
   }
 };
 
-void UpdateToSpacePointersInParallel(Heap* heap) {
+void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) {
   PageParallelJob<ToSpacePointerUpdateJobTraits> job(
-      heap, heap->isolate()->cancelable_task_manager());
+      heap, heap->isolate()->cancelable_task_manager(), semaphore);
   Address space_start = heap->new_space()->bottom();
   Address space_end = heap->new_space()->top();
   NewSpacePageIterator it(space_start, space_end);
@@ -3692,17 +3695,17 @@
   {
     TRACE_GC(heap()->tracer(),
              GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW);
-    UpdateToSpacePointersInParallel(heap_);
+    UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_);
     // Update roots.
     heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE);
-    UpdatePointersInParallel<OLD_TO_NEW>(heap_);
+    UpdatePointersInParallel<OLD_TO_NEW>(heap_, &page_parallel_job_semaphore_);
   }
 
   {
     Heap* heap = this->heap();
     TRACE_GC(heap->tracer(),
              GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED);
-    UpdatePointersInParallel<OLD_TO_OLD>(heap_);
+    UpdatePointersInParallel<OLD_TO_OLD>(heap_, &page_parallel_job_semaphore_);
   }
 
   {
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h
index d6f10e6..d6adb03 100644
--- a/src/heap/mark-compact.h
+++ b/src/heap/mark-compact.h
@@ -644,27 +644,6 @@
                                    int* target_fragmentation_percent,
                                    int* max_evacuated_bytes);
 
-#ifdef DEBUG
-  enum CollectorState {
-    IDLE,
-    PREPARE_GC,
-    MARK_LIVE_OBJECTS,
-    SWEEP_SPACES,
-    ENCODE_FORWARDING_ADDRESSES,
-    UPDATE_POINTERS,
-    RELOCATE_OBJECTS
-  };
-
-  // The current stage of the collector.
-  CollectorState state_;
-#endif
-
-  MarkingParity marking_parity_;
-
-  bool was_marked_incrementally_;
-
-  bool evacuation_;
-
   // Finishes GC, performs heap verification if enabled.
   void Finish();
 
@@ -850,6 +829,38 @@
 #endif
 
   Heap* heap_;
+
+  base::Semaphore page_parallel_job_semaphore_;
+
+#ifdef DEBUG
+  enum CollectorState {
+    IDLE,
+    PREPARE_GC,
+    MARK_LIVE_OBJECTS,
+    SWEEP_SPACES,
+    ENCODE_FORWARDING_ADDRESSES,
+    UPDATE_POINTERS,
+    RELOCATE_OBJECTS
+  };
+
+  // The current stage of the collector.
+  CollectorState state_;
+#endif
+
+  MarkingParity marking_parity_;
+
+  bool was_marked_incrementally_;
+
+  bool evacuation_;
+
+  // True if we are collecting slots to perform evacuation from evacuation
+  // candidates.
+  bool compacting_;
+
+  bool black_allocation_;
+
+  bool have_code_to_deoptimize_;
+
   base::VirtualMemory* marking_deque_memory_;
   size_t marking_deque_memory_committed_;
   MarkingDeque marking_deque_;
@@ -859,17 +870,9 @@
 
   EmbedderHeapTracer* embedder_heap_tracer_;
 
-  bool have_code_to_deoptimize_;
-
   List<Page*> evacuation_candidates_;
   List<Page*> newspace_evacuation_candidates_;
 
-  // True if we are collecting slots to perform evacuation from evacuation
-  // candidates.
-  bool compacting_;
-
-  bool black_allocation_;
-
   Sweeper sweeper_;
 
   friend class Heap;
diff --git a/src/heap/page-parallel-job.h b/src/heap/page-parallel-job.h
index e78e0e2..440c440 100644
--- a/src/heap/page-parallel-job.h
+++ b/src/heap/page-parallel-job.h
@@ -33,14 +33,20 @@
 template <typename JobTraits>
 class PageParallelJob {
  public:
-  PageParallelJob(Heap* heap, CancelableTaskManager* cancelable_task_manager)
+  // PageParallelJob cannot dynamically create a semaphore because of a bug in
+  // glibc. See http://crbug.com/609249 and
+  // https://sourceware.org/bugzilla/show_bug.cgi?id=12674.
+  // The caller must provide a semaphore with value 0 and ensure that
+  // the lifetime of the semaphore is the same as the lifetime of the Isolate.
+  // It is guaranteed that the semaphore value will be 0 after Run() call.
+  PageParallelJob(Heap* heap, CancelableTaskManager* cancelable_task_manager,
+                  base::Semaphore* semaphore)
       : heap_(heap),
         cancelable_task_manager_(cancelable_task_manager),
         items_(nullptr),
         num_items_(0),
         num_tasks_(0),
-        pending_tasks_(new base::Semaphore(0)),
-        finished_tasks_(new base::AtomicNumber<int>(0)) {}
+        pending_tasks_(semaphore) {}
 
   ~PageParallelJob() {
     Item* item = items_;
@@ -49,8 +55,6 @@
       delete item;
       item = next;
     }
-    delete pending_tasks_;
-    delete finished_tasks_;
   }
 
   void AddPage(MemoryChunk* chunk, typename JobTraits::PerPageData data) {
@@ -85,7 +89,7 @@
         start_index -= num_items_;
       }
       Task* task = new Task(heap_, items_, num_items_, start_index,
-                            pending_tasks_, per_task_data_callback(i), this);
+                            pending_tasks_, per_task_data_callback(i));
       task_ids[i] = task->id();
       if (i > 0) {
         V8::GetCurrentPlatform()->CallOnBackgroundThread(
@@ -97,18 +101,12 @@
     // Contribute on main thread.
     main_task->Run();
     delete main_task;
-    int aborted_tasks = 0;
     // Wait for background tasks.
     for (int i = 0; i < num_tasks_; i++) {
       if (!cancelable_task_manager_->TryAbort(task_ids[i])) {
         pending_tasks_->Wait();
-      } else {
-        ++aborted_tasks;
       }
     }
-    int finished_tasks = finished_tasks_->Value();
-    // TODO(ulan): Remove this check after investigation of crbug.com/609249.
-    CHECK_EQ(aborted_tasks + finished_tasks, num_tasks_);
     if (JobTraits::NeedSequentialFinalization) {
       Item* item = items_;
       while (item != nullptr) {
@@ -120,8 +118,6 @@
     }
   }
 
-  void NotifyFinishedTask() { finished_tasks_->Increment(1); }
-
  private:
   static const int kMaxNumberOfTasks = 10;
 
@@ -139,16 +135,14 @@
   class Task : public CancelableTask {
    public:
     Task(Heap* heap, Item* items, int num_items, int start_index,
-         base::Semaphore* on_finish, typename JobTraits::PerTaskData data,
-         PageParallelJob<JobTraits>* job)
+         base::Semaphore* on_finish, typename JobTraits::PerTaskData data)
         : CancelableTask(heap->isolate()),
           heap_(heap),
           items_(items),
           num_items_(num_items),
           start_index_(start_index),
           on_finish_(on_finish),
-          data_(data),
-          job_(job) {}
+          data_(data) {}
 
     virtual ~Task() {}
 
@@ -173,8 +167,7 @@
           current = items_;
         }
       }
-      job_->NotifyFinishedTask();
-      on_finish_->Signal("PageParallelJob::Task::RunInternal");
+      on_finish_->Signal();
     }
 
     Heap* heap_;
@@ -183,7 +176,6 @@
     int start_index_;
     base::Semaphore* on_finish_;
     typename JobTraits::PerTaskData data_;
-    PageParallelJob<JobTraits>* job_;
     DISALLOW_COPY_AND_ASSIGN(Task);
   };
 
@@ -193,7 +185,6 @@
   int num_items_;
   int num_tasks_;
   base::Semaphore* pending_tasks_;
-  base::AtomicNumber<int>* finished_tasks_;
   DISALLOW_COPY_AND_ASSIGN(PageParallelJob);
 };
 
diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc
index 13622d6..e517c45 100644
--- a/src/heap/spaces.cc
+++ b/src/heap/spaces.cc
@@ -356,8 +356,7 @@
   // v8::Task overrides.
   void Run() override {
     unmapper_->PerformFreeMemoryOnQueuedChunks();
-    unmapper_->pending_unmapping_tasks_semaphore_.Signal(
-        "Unmapper::UnmapFreeMemoryTask::Run");
+    unmapper_->pending_unmapping_tasks_semaphore_.Signal();
   }
 
   Unmapper* unmapper_;
diff --git a/src/log.cc b/src/log.cc
index 886dded..97acea9 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -560,7 +560,7 @@
     } else {
       buffer_[head_] = *sample;
       head_ = Succ(head_);
-      buffer_semaphore_.Signal("Profiler::Insert");  // Tell we have an element.
+      buffer_semaphore_.Signal();  // Tell we have an element.
     }
   }