提交 a3afdf82 编写于 作者: J johnc

Merge

......@@ -353,6 +353,10 @@ class ConcurrentMark: public CHeapObj {
friend class CMConcurrentMarkingTask;
friend class G1ParNoteEndTask;
friend class CalcLiveObjectsClosure;
friend class G1RefProcTaskProxy;
friend class G1RefProcTaskExecutor;
friend class G1CMParKeepAliveAndDrainClosure;
friend class G1CMParDrainMarkingStackClosure;
protected:
ConcurrentMarkThread* _cmThread; // the thread doing the work
......@@ -936,7 +940,7 @@ private:
// if this is true, then the task has aborted for some reason
bool _has_aborted;
// set when the task aborts because it has met its time quota
bool _has_aborted_timed_out;
bool _has_timed_out;
// true when we're draining SATB buffers; this avoids the task
// aborting due to SATB buffers being available (as we're already
// dealing with them)
......@@ -1041,7 +1045,7 @@ public:
// trying not to exceed the given duration. However, it might exit
// prematurely, according to some conditions (i.e. SATB buffers are
// available for processing).
void do_marking_step(double target_ms);
void do_marking_step(double target_ms, bool do_stealing, bool do_termination);
// These two calls start and stop the timer
void record_start_time() {
......@@ -1063,7 +1067,8 @@ public:
bool has_aborted() { return _has_aborted; }
void set_has_aborted() { _has_aborted = true; }
void clear_has_aborted() { _has_aborted = false; }
bool claimed() { return _claimed; }
bool has_timed_out() { return _has_timed_out; }
bool claimed() { return _claimed; }
// Support routines for the partially scanned region that may be
// recorded as a result of aborting while draining the CMRegionStack
......
......@@ -251,7 +251,9 @@ void ConcurrentMarkThread::run() {
// Now do the remainder of the cleanup operation.
_cm->completeCleanup();
_sts.join();
g1_policy->record_concurrent_mark_cleanup_completed();
_sts.leave();
double cleanup_end_sec = os::elapsedTime();
if (PrintGC) {
......
......@@ -4925,10 +4925,11 @@ void G1CollectedHeap::evacuate_collection_set() {
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
}
void G1CollectedHeap::free_region_if_totally_empty(HeapRegion* hr,
void G1CollectedHeap::free_region_if_empty(HeapRegion* hr,
size_t* pre_used,
FreeRegionList* free_list,
HumongousRegionSet* humongous_proxy_set,
HRRSCleanupTask* hrrs_cleanup_task,
bool par) {
if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young()) {
if (hr->isHumongous()) {
......@@ -4937,6 +4938,8 @@ void G1CollectedHeap::free_region_if_totally_empty(HeapRegion* hr,
} else {
free_region(hr, pre_used, free_list, par);
}
} else {
hr->rem_set()->do_cleanup_work(hrrs_cleanup_task);
}
}
......
......@@ -40,6 +40,7 @@
class HeapRegion;
class HeapRegionSeq;
class HRRSCleanupTask;
class PermanentGenerationSpec;
class GenerationSpec;
class OopsInHeapRegionClosure;
......@@ -1099,11 +1100,12 @@ public:
// all dead. It calls either free_region() or
// free_humongous_region() depending on the type of the region that
// is passed to it.
void free_region_if_totally_empty(HeapRegion* hr,
size_t* pre_used,
FreeRegionList* free_list,
HumongousRegionSet* humongous_proxy_set,
bool par);
void free_region_if_empty(HeapRegion* hr,
size_t* pre_used,
FreeRegionList* free_list,
HumongousRegionSet* humongous_proxy_set,
HRRSCleanupTask* hrrs_cleanup_task,
bool par);
// It appends the free list to the master free list and updates the
// master humongous list according to the contents of the proxy
......
......@@ -81,6 +81,14 @@
product(intx, G1MarkRegionStackSize, 1024 * 1024, \
"Size of the region stack for concurrent marking.") \
\
product(double, G1ConcMarkStepDurationMillis, 10.0, \
"Target duration of individual concurrent marking steps " \
"in milliseconds.") \
\
product(intx, G1RefProcDrainInterval, 10, \
"The number of discovered reference objects to process before " \
"draining concurrent marking work queues.") \
\
develop(bool, G1SATBBarrierPrintNullPreVals, false, \
"If true, count frac of ptr writes with null pre-vals.") \
\
......
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2011, 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
......@@ -463,7 +463,6 @@ public:
}
static void par_contract_all();
};
void PosParPRT::par_contract_all() {
......@@ -1070,6 +1069,11 @@ bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const
}
void
OtherRegionsTable::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) {
_sparse_table.do_cleanup_work(hrrs_cleanup_task);
}
// Determines how many threads can add records to an rset in parallel.
// This can be done by either mutator threads together with the
// concurrent refinement threads or GC threads.
......@@ -1384,6 +1388,19 @@ void HeapRegionRemSet::print_recorded() {
}
}
void HeapRegionRemSet::reset_for_cleanup_tasks() {
SparsePRT::reset_for_cleanup_tasks();
}
void HeapRegionRemSet::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) {
_other_regions.do_cleanup_work(hrrs_cleanup_task);
}
void
HeapRegionRemSet::finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task) {
SparsePRT::finish_cleanup_task(hrrs_cleanup_task);
}
#ifndef PRODUCT
void HeapRegionRemSet::test() {
os::sleep(Thread::current(), (jlong)5000, false);
......
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2011, 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
......@@ -38,6 +38,10 @@ class HeapRegionRemSetIterator;
class PosParPRT;
class SparsePRT;
// Essentially a wrapper around SparsePRTCleanupTask. See
// sparsePRT.hpp for more details.
class HRRSCleanupTask : public SparsePRTCleanupTask {
};
// The "_coarse_map" is a bitmap with one bit for each region, where set
// bits indicate that the corresponding region may contain some pointer
......@@ -156,6 +160,8 @@ public:
// "from_hr" is being cleared; remove any entries from it.
void clear_incoming_entry(HeapRegion* from_hr);
void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task);
// Declare the heap size (in # of regions) to the OtherRegionsTable.
// (Uses it to initialize from_card_cache).
static void init_from_card_cache(size_t max_regions);
......@@ -165,10 +171,8 @@ public:
static void shrink_from_card_cache(size_t new_n_regs);
static void print_from_card_cache();
};
class HeapRegionRemSet : public CHeapObj {
friend class VMStructs;
friend class HeapRegionRemSetIterator;
......@@ -342,11 +346,16 @@ public:
static void print_recorded();
static void record_event(Event evnt);
// These are wrappers for the similarly-named methods on
// SparsePRT. Look at sparsePRT.hpp for more details.
static void reset_for_cleanup_tasks();
void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task);
static void finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task);
// Run unit tests.
#ifndef PRODUCT
static void test();
#endif
};
class HeapRegionRemSetIterator : public CHeapObj {
......
......@@ -195,10 +195,10 @@ int HeapRegionSeq::find_contiguous(size_t num) {
assert(0 <= res && res < _regions.length(),
err_msg("res: %d should be valid", res));
_alloc_search_start = res + (int) num;
assert(0 < _alloc_search_start && _alloc_search_start <= _regions.length(),
err_msg("_alloc_search_start: %d should be valid",
_alloc_search_start));
}
assert(0 < _alloc_search_start && _alloc_search_start <= _regions.length(),
err_msg("_alloc_search_start: %d should be valid",
_alloc_search_start));
return res;
}
......
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2011, 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
......@@ -415,6 +415,38 @@ SparsePRT* SparsePRT::get_from_expanded_list() {
return NULL;
}
void SparsePRT::reset_for_cleanup_tasks() {
_head_expanded_list = NULL;
}
void SparsePRT::do_cleanup_work(SparsePRTCleanupTask* sprt_cleanup_task) {
if (should_be_on_expanded_list()) {
sprt_cleanup_task->add(this);
}
}
void SparsePRT::finish_cleanup_task(SparsePRTCleanupTask* sprt_cleanup_task) {
assert(ParGCRareEvent_lock->owned_by_self(), "pre-condition");
SparsePRT* head = sprt_cleanup_task->head();
SparsePRT* tail = sprt_cleanup_task->tail();
if (head != NULL) {
assert(tail != NULL, "if head is not NULL, so should tail");
tail->set_next_expanded(_head_expanded_list);
_head_expanded_list = head;
} else {
assert(tail == NULL, "if head is NULL, so should tail");
}
}
bool SparsePRT::should_be_on_expanded_list() {
if (_expanded) {
assert(_cur != _next, "if _expanded is true, cur should be != _next");
} else {
assert(_cur == _next, "if _expanded is false, cur should be == _next");
}
return expanded();
}
void SparsePRT::cleanup_all() {
// First clean up all expanded tables so they agree on next and cur.
......@@ -484,6 +516,7 @@ void SparsePRT::clear() {
_cur->clear();
}
_next = _cur;
_expanded = false;
}
void SparsePRT::cleanup() {
......@@ -518,3 +551,15 @@ void SparsePRT::expand() {
}
add_to_expanded_list(this);
}
void SparsePRTCleanupTask::add(SparsePRT* sprt) {
assert(sprt->should_be_on_expanded_list(), "pre-condition");
sprt->set_next_expanded(NULL);
if (_tail != NULL) {
_tail->set_next_expanded(sprt);
} else {
_head = sprt;
}
_tail = sprt;
}
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2011, 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
......@@ -212,8 +212,11 @@ public:
// mutex.
class SparsePRTIter;
class SparsePRTCleanupTask;
class SparsePRT VALUE_OBJ_CLASS_SPEC {
friend class SparsePRTCleanupTask;
// Iterations are done on the _cur hash table, since they only need to
// see entries visible at the start of a collection pause.
// All other operations are done using the _next hash table.
......@@ -238,6 +241,8 @@ class SparsePRT VALUE_OBJ_CLASS_SPEC {
SparsePRT* next_expanded() { return _next_expanded; }
void set_next_expanded(SparsePRT* nxt) { _next_expanded = nxt; }
bool should_be_on_expanded_list();
static SparsePRT* _head_expanded_list;
public:
......@@ -284,12 +289,36 @@ public:
static void add_to_expanded_list(SparsePRT* sprt);
static SparsePRT* get_from_expanded_list();
// The purpose of these three methods is to help the GC workers
// during the cleanup pause to recreate the expanded list, purging
// any tables from it that belong to regions that are freed during
// cleanup (if we don't purge those tables, there is a race that
// causes various crashes; see CR 7014261).
//
// We chose to recreate the expanded list, instead of purging
// entries from it by iterating over it, to avoid this serial phase
// at the end of the cleanup pause.
//
// The three methods below work as follows:
// * reset_for_cleanup_tasks() : Nulls the expanded list head at the
// start of the cleanup pause.
// * do_cleanup_work() : Called by the cleanup workers for every
// region that is not free / is being freed by the cleanup
// pause. It creates a list of expanded tables whose head / tail
// are on the thread-local SparsePRTCleanupTask object.
// * finish_cleanup_task() : Called by the cleanup workers after
// they complete their cleanup task. It adds the local list into
// the global expanded list. It assumes that the
// ParGCRareEvent_lock is being held to ensure MT-safety.
static void reset_for_cleanup_tasks();
void do_cleanup_work(SparsePRTCleanupTask* sprt_cleanup_task);
static void finish_cleanup_task(SparsePRTCleanupTask* sprt_cleanup_task);
bool contains_card(RegionIdx_t region_id, CardIdx_t card_index) const {
return _next->contains_card(region_id, card_index);
}
};
class SparsePRTIter: public RSHashTableIter {
public:
void init(const SparsePRT* sprt) {
......@@ -300,4 +329,22 @@ public:
}
};
// This allows each worker during a cleanup pause to create a
// thread-local list of sparse tables that have been expanded and need
// to be processed at the beginning of the next GC pause. This lists
// are concatenated into the single expanded list at the end of the
// cleanup pause.
class SparsePRTCleanupTask VALUE_OBJ_CLASS_SPEC {
private:
SparsePRT* _head;
SparsePRT* _tail;
public:
SparsePRTCleanupTask() : _head(NULL), _tail(NULL) { }
void add(SparsePRT* sprt);
SparsePRT* head() { return _head; }
SparsePRT* tail() { return _tail; }
};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_SPARSEPRT_HPP
......@@ -1941,10 +1941,16 @@ bool Arguments::check_vm_args_consistency() {
status = false;
}
#ifndef SERIALGC
if (UseG1GC) {
status = status && verify_percentage(InitiatingHeapOccupancyPercent,
"InitiatingHeapOccupancyPercent");
status = status && verify_min_value(G1RefProcDrainInterval, 1,
"G1RefProcDrainInterval");
status = status && verify_min_value((intx)G1ConcMarkStepDurationMillis, 1,
"G1ConcMarkStepDurationMillis");
}
#endif
status = status && verify_interval(RefDiscoveryPolicy,
ReferenceProcessor::DiscoveryPolicyMin,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册