--- old/src/share/vm/gc/parallel/psPromotionManager.cpp 2016-06-09 15:26:26.191525587 +0300 +++ new/src/share/vm/gc/parallel/psPromotionManager.cpp 2016-06-09 15:26:26.075525591 +0300 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "gc/parallel/gcTaskManager.hpp" #include "gc/parallel/mutableSpace.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" #include "gc/parallel/psOldGen.hpp" @@ -237,8 +238,53 @@ _preserved_marks = preserved_marks; } +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){ + _preserved_marks_set->get(_id)->restore_and_increment(_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) { } +}; + +class PSRestorePreservedMarksTaskExecutor : public RestorePreservedMarksTaskExecutor { +private: + GCTaskManager* _gc_task_manager; + +public: + PSRestorePreservedMarksTaskExecutor(GCTaskManager* gc_task_manager) + : _gc_task_manager(gc_task_manager) { } + + void restore(PreservedMarksSet* preserved_marks_set, + volatile size_t* total_size_addr) { + // GCTask / GCTaskQueue are ResourceObjs + ResourceMark rm; + + GCTaskQueue* q = GCTaskQueue::create(); + for (uint i = 0; i < preserved_marks_set->num(); i += 1) { + q->enqueue(new ParRestoreGCTask(i, preserved_marks_set, total_size_addr)); + } + _gc_task_manager->execute_and_wait(q); + } +}; + void PSPromotionManager::restore_preserved_marks() { - _preserved_marks_set->restore(PSScavenge::gc_task_manager()); + PSRestorePreservedMarksTaskExecutor task_executor(PSScavenge::gc_task_manager()); + _preserved_marks_set->restore(&task_executor); } void PSPromotionManager::drain_stacks_depth(bool totally_drain) {