8154153: PS: Restore preserved marks in parallel
authortonyp
Tue, 26 Apr 2016 10:19:57 +0200
changeset 38080 bb02a3ad3b0a
parent 38079 fd24ad51113a
child 38081 a3bcb7197d45
8154153: PS: Restore preserved marks in parallel Summary: Restore preserved marks after evacuation failure in parallel using the PreservedMark infrastructure. Reviewed-by: tschatzl
hotspot/src/share/vm/gc/parallel/psPromotionManager.cpp
hotspot/src/share/vm/gc/parallel/psPromotionManager.hpp
hotspot/src/share/vm/gc/parallel/psScavenge.cpp
hotspot/src/share/vm/gc/shared/preservedMarks.cpp
hotspot/src/share/vm/gc/shared/preservedMarks.hpp
--- a/hotspot/src/share/vm/gc/parallel/psPromotionManager.cpp	Mon Apr 25 12:11:58 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psPromotionManager.cpp	Tue Apr 26 10:19:57 2016 +0200
@@ -237,6 +237,10 @@
   _preserved_marks = preserved_marks;
 }
 
+void PSPromotionManager::restore_preserved_marks() {
+  _preserved_marks_set->restore(PSScavenge::gc_task_manager());
+}
+
 void PSPromotionManager::drain_stacks_depth(bool totally_drain) {
   totally_drain = totally_drain || _totally_drain;
 
--- a/hotspot/src/share/vm/gc/parallel/psPromotionManager.hpp	Mon Apr 25 12:11:58 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psPromotionManager.hpp	Tue Apr 26 10:19:57 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -180,7 +180,7 @@
 
   void reset();
   void register_preserved_marks(PreservedMarks* preserved_marks);
-  static void restore_preserved_marks() { _preserved_marks_set->restore(); }
+  static void restore_preserved_marks();
 
   void flush_labs();
   void drain_stacks(bool totally_drain) {
--- a/hotspot/src/share/vm/gc/parallel/psScavenge.cpp	Mon Apr 25 12:11:58 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psScavenge.cpp	Tue Apr 26 10:19:57 2016 +0200
@@ -443,7 +443,7 @@
     promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer);
     if (promotion_failure_occurred) {
       clean_up_failed_promotion();
-      log_info(gc)("Promotion failed");
+      log_info(gc, promotion)("Promotion failed");
     }
 
     _gc_tracer.report_tenuring_threshold(tenuring_threshold());
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.cpp	Mon Apr 25 12:11:58 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/preservedMarks.cpp	Tue Apr 26 10:19:57 2016 +0200
@@ -23,9 +23,11 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/parallel/gcTaskManager.hpp"
 #include "gc/shared/preservedMarks.inline.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 
 void PreservedMarks::restore() {
   while (!_stack.is_empty()) {
@@ -106,9 +108,43 @@
   workers->run_task(&task);
 }
 
-// temporary, used by PS
-void PreservedMarksSet::restore() {
-  restore<WorkGang>(NULL);
+class ParRestoreGCTask : public GCTask {
+private:
+  const uint _id;
+  PreservedMarksSet* const _preserved_marks_set;
+  volatile size_t* const _total_size_addr;
+
+public:
+  virtual char* name() { return (char*) "preserved mark restoration task"; }
+
+  virtual void do_it(GCTaskManager* manager, uint which) {
+    PreservedMarks* const preserved_marks = _preserved_marks_set->get(_id);
+    const size_t size = preserved_marks->size();
+    preserved_marks->restore();
+    // Only do the atomic add if the size is > 0.
+    if (size > 0) {
+      Atomic::add(size, _total_size_addr);
+    }
+  }
+
+  ParRestoreGCTask(uint id,
+                   PreservedMarksSet* preserved_marks_set,
+                   volatile size_t* total_size_addr)
+    : _id(id),
+      _preserved_marks_set(preserved_marks_set),
+      _total_size_addr(total_size_addr) { }
+};
+
+void PreservedMarksSet::restore_internal(GCTaskManager* gc_task_manager,
+                                         volatile size_t* total_size_addr) {
+  // GCTask / GCTaskQueue are ResourceObjs
+  ResourceMark rm;
+
+  GCTaskQueue* q = GCTaskQueue::create();
+  for (uint i = 0; i < num(); i += 1) {
+    q->enqueue(new ParRestoreGCTask(i, this, total_size_addr));
+  }
+  gc_task_manager->execute_and_wait(q);
 }
 
 void PreservedMarksSet::reclaim() {
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.hpp	Mon Apr 25 12:11:58 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/preservedMarks.hpp	Tue Apr 26 10:19:57 2016 +0200
@@ -44,6 +44,7 @@
 };
 typedef Stack<OopAndMarkOop, mtGC> OopAndMarkOopStack;
 
+class GCTaskManager;
 class WorkGang;
 
 class PreservedMarks VALUE_OBJ_CLASS_SPEC {
@@ -93,6 +94,10 @@
   // Internal version of restore() that uses a WorkGang for parallelism.
   void restore_internal(WorkGang* workers, volatile size_t* total_size_addr);
 
+  // Internal version of restore() that uses a GCTaskManager for parallelism.
+  void restore_internal(GCTaskManager* gc_task_manager,
+                        volatile size_t* total_size_addr);
+
 public:
   uint num() const { return _num; }
 
@@ -110,14 +115,11 @@
   // the memory taken up by the stack segments. If the executor is
   // NULL, restoration will be done serially. If the executor is not
   // NULL, restoration could be done in parallel (when it makes
-  // sense). Supported executors: WorkGang (Serial, CMS, G1)
+  // sense). Supported executors: WorkGang (Serial, CMS, G1),
+  // GCTaskManager (PS).
   template <class E>
   inline void restore(E* executor);
 
-  // Do the restoration serially. Temporary, to be used by PS until we
-  // can support GCTaskManager in restore(E*).
-  void restore();
-
   // Reclaim stack array.
   void reclaim();