# HG changeset patch # User tonyp # Date 1461658797 -7200 # Node ID bb02a3ad3b0a35ae5af87bc99261d035ddaec61e # Parent fd24ad51113ae7bb0a45d3acb96bc12876ce4bf8 8154153: PS: Restore preserved marks in parallel Summary: Restore preserved marks after evacuation failure in parallel using the PreservedMark infrastructure. Reviewed-by: tschatzl diff -r fd24ad51113a -r bb02a3ad3b0a hotspot/src/share/vm/gc/parallel/psPromotionManager.cpp --- 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; diff -r fd24ad51113a -r bb02a3ad3b0a hotspot/src/share/vm/gc/parallel/psPromotionManager.hpp --- 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) { diff -r fd24ad51113a -r bb02a3ad3b0a hotspot/src/share/vm/gc/parallel/psScavenge.cpp --- 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()); diff -r fd24ad51113a -r bb02a3ad3b0a hotspot/src/share/vm/gc/shared/preservedMarks.cpp --- 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(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() { diff -r fd24ad51113a -r bb02a3ad3b0a hotspot/src/share/vm/gc/shared/preservedMarks.hpp --- 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 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 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();