Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
e6ad5bbe
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
e6ad5bbe
编写于
8月 09, 2010
作者:
J
jcoomes
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6966222: G1: simplify TaskQueue overflow handling
Reviewed-by: tonyp, ysr
上级
d0aa394b
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
127 addition
and
90 deletion
+127
-90
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+64
-37
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+25
-51
src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
+1
-2
src/share/vm/utilities/taskqueue.cpp
src/share/vm/utilities/taskqueue.cpp
+31
-0
src/share/vm/utilities/taskqueue.hpp
src/share/vm/utilities/taskqueue.hpp
+6
-0
未找到文件。
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
浏览文件 @
e6ad5bbe
...
...
@@ -2710,6 +2710,35 @@ struct PrepareForRSScanningClosure : public HeapRegionClosure {
}
};
#if TASKQUEUE_STATS
void
G1CollectedHeap
::
print_taskqueue_stats_hdr
(
outputStream
*
const
st
)
{
st
->
print_raw_cr
(
"GC Task Stats"
);
st
->
print_raw
(
"thr "
);
TaskQueueStats
::
print_header
(
1
,
st
);
st
->
cr
();
st
->
print_raw
(
"--- "
);
TaskQueueStats
::
print_header
(
2
,
st
);
st
->
cr
();
}
void
G1CollectedHeap
::
print_taskqueue_stats
(
outputStream
*
const
st
)
const
{
print_taskqueue_stats_hdr
(
st
);
TaskQueueStats
totals
;
const
int
n
=
MAX2
(
workers
()
->
total_workers
(),
1
);
for
(
int
i
=
0
;
i
<
n
;
++
i
)
{
st
->
print
(
"%3d "
,
i
);
task_queue
(
i
)
->
stats
.
print
(
st
);
st
->
cr
();
totals
+=
task_queue
(
i
)
->
stats
;
}
st
->
print_raw
(
"tot "
);
totals
.
print
(
st
);
st
->
cr
();
DEBUG_ONLY
(
totals
.
verify
());
}
void
G1CollectedHeap
::
reset_taskqueue_stats
()
{
const
int
n
=
MAX2
(
workers
()
->
total_workers
(),
1
);
for
(
int
i
=
0
;
i
<
n
;
++
i
)
{
task_queue
(
i
)
->
stats
.
reset
();
}
}
#endif // TASKQUEUE_STATS
void
G1CollectedHeap
::
do_collection_pause_at_safepoint
(
double
target_pause_time_ms
)
{
if
(
GC_locker
::
check_active_before_gc
())
{
...
...
@@ -2970,6 +2999,9 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
}
}
TASKQUEUE_STATS_ONLY
(
if
(
ParallelGCVerbose
)
print_taskqueue_stats
());
TASKQUEUE_STATS_ONLY
(
reset_taskqueue_stats
());
if
(
PrintHeapAtGC
)
{
Universe
::
print_heap_after_gc
();
}
...
...
@@ -3715,10 +3747,6 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num)
_surviving_alloc_buffer
(
g1h
->
desired_plab_sz
(
GCAllocForSurvived
)),
_tenured_alloc_buffer
(
g1h
->
desired_plab_sz
(
GCAllocForTenured
)),
_age_table
(
false
),
#if G1_DETAILED_STATS
_pushes
(
0
),
_pops
(
0
),
_steals
(
0
),
_steal_attempts
(
0
),
_overflow_pushes
(
0
),
#endif
_strong_roots_time
(
0
),
_term_time
(
0
),
_alloc_buffer_waste
(
0
),
_undo_waste
(
0
)
{
...
...
@@ -3738,14 +3766,41 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num)
_surviving_young_words
=
_surviving_young_words_base
+
PADDING_ELEM_NUM
;
memset
(
_surviving_young_words
,
0
,
real_length
*
sizeof
(
size_t
));
_overflowed_refs
=
new
OverflowQueue
(
10
);
_alloc_buffers
[
GCAllocForSurvived
]
=
&
_surviving_alloc_buffer
;
_alloc_buffers
[
GCAllocForTenured
]
=
&
_tenured_alloc_buffer
;
_start
=
os
::
elapsedTime
();
}
void
G1ParScanThreadState
::
print_termination_stats_hdr
(
outputStream
*
const
st
)
{
st
->
print_raw_cr
(
"GC Termination Stats"
);
st
->
print_raw_cr
(
" elapsed --strong roots-- -------termination-------"
" ------waste (KiB)------"
);
st
->
print_raw_cr
(
"thr ms ms % ms % attempts"
" total alloc undo"
);
st
->
print_raw_cr
(
"--- --------- --------- ------ --------- ------ --------"
" ------- ------- -------"
);
}
void
G1ParScanThreadState
::
print_termination_stats
(
int
i
,
outputStream
*
const
st
)
const
{
const
double
elapsed_ms
=
elapsed_time
()
*
1000.0
;
const
double
s_roots_ms
=
strong_roots_time
()
*
1000.0
;
const
double
term_ms
=
term_time
()
*
1000.0
;
st
->
print_cr
(
"%3d %9.2f %9.2f %6.2f "
"%9.2f %6.2f "
SIZE_FORMAT_W
(
8
)
" "
SIZE_FORMAT_W
(
7
)
" "
SIZE_FORMAT_W
(
7
)
" "
SIZE_FORMAT_W
(
7
),
i
,
elapsed_ms
,
s_roots_ms
,
s_roots_ms
*
100
/
elapsed_ms
,
term_ms
,
term_ms
*
100
/
elapsed_ms
,
term_attempts
(),
(
alloc_buffer_waste
()
+
undo_waste
())
*
HeapWordSize
/
K
,
alloc_buffer_waste
()
*
HeapWordSize
/
K
,
undo_waste
()
*
HeapWordSize
/
K
);
}
G1ParClosureSuper
::
G1ParClosureSuper
(
G1CollectedHeap
*
g1
,
G1ParScanThreadState
*
par_scan_state
)
:
_g1
(
g1
),
_g1_rem
(
_g1
->
g1_rem_set
()),
_cm
(
_g1
->
concurrent_mark
()),
_par_scan_state
(
par_scan_state
)
{
}
...
...
@@ -3952,12 +4007,9 @@ public:
G1ParScanThreadState
*
pss
=
par_scan_state
();
while
(
true
)
{
pss
->
trim_queue
();
IF_G1_DETAILED_STATS
(
pss
->
note_steal_attempt
());
StarTask
stolen_task
;
if
(
queues
()
->
steal
(
pss
->
queue_num
(),
pss
->
hash_seed
(),
stolen_task
))
{
IF_G1_DETAILED_STATS
(
pss
->
note_steal
());
// slightly paranoid tests; I'm trying to catch potential
// problems before we go into push_on_queue to know where the
// problem is coming from
...
...
@@ -4076,35 +4128,9 @@ public:
// Clean up any par-expanded rem sets.
HeapRegionRemSet
::
par_cleanup
();
MutexLocker
x
(
stats_lock
());
if
(
ParallelGCVerbose
)
{
gclog_or_tty
->
print
(
"Thread %d complete:
\n
"
,
i
);
#if G1_DETAILED_STATS
gclog_or_tty
->
print
(
" Pushes: %7d Pops: %7d Overflows: %7d Steals %7d (in %d attempts)
\n
"
,
pss
.
pushes
(),
pss
.
pops
(),
pss
.
overflow_pushes
(),
pss
.
steals
(),
pss
.
steal_attempts
());
#endif
double
elapsed
=
pss
.
elapsed
();
double
strong_roots
=
pss
.
strong_roots_time
();
double
term
=
pss
.
term_time
();
gclog_or_tty
->
print
(
" Elapsed: %7.2f ms.
\n
"
" Strong roots: %7.2f ms (%6.2f%%)
\n
"
" Termination: %7.2f ms (%6.2f%%) "
"(in "
SIZE_FORMAT
" entries)
\n
"
,
elapsed
*
1000.0
,
strong_roots
*
1000.0
,
(
strong_roots
*
100.0
/
elapsed
),
term
*
1000.0
,
(
term
*
100.0
/
elapsed
),
pss
.
term_attempts
());
size_t
total_waste
=
pss
.
alloc_buffer_waste
()
+
pss
.
undo_waste
();
gclog_or_tty
->
print
(
" Waste: %8dK
\n
"
" Alloc Buffer: %8dK
\n
"
" Undo: %8dK
\n
"
,
(
total_waste
*
HeapWordSize
)
/
K
,
(
pss
.
alloc_buffer_waste
()
*
HeapWordSize
)
/
K
,
(
pss
.
undo_waste
()
*
HeapWordSize
)
/
K
);
MutexLocker
x
(
stats_lock
());
pss
.
print_termination_stats
(
i
);
}
assert
(
pss
.
refs_to_scan
()
==
0
,
"Task queue should be empty"
);
...
...
@@ -4221,6 +4247,7 @@ void G1CollectedHeap::evacuate_collection_set() {
if
(
ParallelGCThreads
>
0
)
{
// The individual threads will set their evac-failure closures.
StrongRootsScope
srs
(
this
);
if
(
ParallelGCVerbose
)
G1ParScanThreadState
::
print_termination_stats_hdr
();
workers
()
->
run_task
(
&
g1_par_task
);
}
else
{
StrongRootsScope
srs
(
this
);
...
...
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
浏览文件 @
e6ad5bbe
...
...
@@ -46,17 +46,7 @@ class ConcurrentMarkThread;
class
ConcurrentG1Refine
;
class
ConcurrentZFThread
;
// If want to accumulate detailed statistics on work queues
// turn this on.
#define G1_DETAILED_STATS 0
#if G1_DETAILED_STATS
# define IF_G1_DETAILED_STATS(code) code
#else
# define IF_G1_DETAILED_STATS(code)
#endif
typedef
GenericTaskQueue
<
StarTask
>
RefToScanQueue
;
typedef
OverflowTaskQueue
<
StarTask
>
RefToScanQueue
;
typedef
GenericTaskQueueSet
<
RefToScanQueue
>
RefToScanQueueSet
;
typedef
int
RegionIdx_t
;
// needs to hold [ 0..max_regions() )
...
...
@@ -471,6 +461,12 @@ protected:
virtual
void
shrink
(
size_t
expand_bytes
);
void
shrink_helper
(
size_t
expand_bytes
);
#if TASKQUEUE_STATS
static
void
print_taskqueue_stats_hdr
(
outputStream
*
const
st
=
gclog_or_tty
);
void
print_taskqueue_stats
(
outputStream
*
const
st
=
gclog_or_tty
)
const
;
void
reset_taskqueue_stats
();
#endif // TASKQUEUE_STATS
// Do an incremental collection: identify a collection set, and evacuate
// its live objects elsewhere.
virtual
void
do_collection_pause
();
...
...
@@ -662,7 +658,7 @@ protected:
public:
void
set_refine_cte_cl_concurrency
(
bool
concurrent
);
RefToScanQueue
*
task_queue
(
int
i
);
RefToScanQueue
*
task_queue
(
int
i
)
const
;
// A set of cards where updates happened during the GC
DirtyCardQueueSet
&
dirty_card_queue_set
()
{
return
_dirty_card_queue_set
;
}
...
...
@@ -1579,9 +1575,6 @@ protected:
CardTableModRefBS
*
_ct_bs
;
G1RemSet
*
_g1_rem
;
typedef
GrowableArray
<
StarTask
>
OverflowQueue
;
OverflowQueue
*
_overflowed_refs
;
G1ParGCAllocBuffer
_surviving_alloc_buffer
;
G1ParGCAllocBuffer
_tenured_alloc_buffer
;
G1ParGCAllocBuffer
*
_alloc_buffers
[
GCAllocPurposeCount
];
...
...
@@ -1598,10 +1591,6 @@ protected:
int
_queue_num
;
size_t
_term_attempts
;
#if G1_DETAILED_STATS
int
_pushes
,
_pops
,
_steals
,
_steal_attempts
;
int
_overflow_pushes
;
#endif
double
_start
;
double
_start_strong_roots
;
...
...
@@ -1615,7 +1604,7 @@ protected:
// this points into the array, as we use the first few entries for padding
size_t
*
_surviving_young_words
;
#define PADDING_ELEM_NUM (
64
/ sizeof(size_t))
#define PADDING_ELEM_NUM (
DEFAULT_CACHE_LINE_SIZE
/ sizeof(size_t))
void
add_to_alloc_buffer_waste
(
size_t
waste
)
{
_alloc_buffer_waste
+=
waste
;
}
...
...
@@ -1650,15 +1639,14 @@ public:
}
RefToScanQueue
*
refs
()
{
return
_refs
;
}
OverflowQueue
*
overflowed_refs
()
{
return
_overflowed_refs
;
}
ageTable
*
age_table
()
{
return
&
_age_table
;
}
G1ParGCAllocBuffer
*
alloc_buffer
(
GCAllocPurpose
purpose
)
{
return
_alloc_buffers
[
purpose
];
}
size_t
alloc_buffer_waste
()
{
return
_alloc_buffer_waste
;
}
size_t
undo_waste
()
{
return
_undo_waste
;
}
size_t
alloc_buffer_waste
()
const
{
return
_alloc_buffer_waste
;
}
size_t
undo_waste
()
const
{
return
_undo_waste
;
}
template
<
class
T
>
void
push_on_queue
(
T
*
ref
)
{
assert
(
ref
!=
NULL
,
"invariant"
);
...
...
@@ -1671,12 +1659,7 @@ public:
assert
(
_g1h
->
obj_in_cs
(
p
),
"Should be in CS"
);
}
#endif
if
(
!
refs
()
->
push
(
ref
))
{
overflowed_refs
()
->
push
(
ref
);
IF_G1_DETAILED_STATS
(
note_overflow_push
());
}
else
{
IF_G1_DETAILED_STATS
(
note_push
());
}
refs
()
->
push
(
ref
);
}
void
pop_from_queue
(
StarTask
&
ref
)
{
...
...
@@ -1687,7 +1670,6 @@ public:
_g1h
->
is_in_g1_reserved
(
ref
.
is_narrow
()
?
oopDesc
::
load_decode_heap_oop
((
narrowOop
*
)
ref
)
:
oopDesc
::
load_decode_heap_oop
((
oop
*
)
ref
)),
"invariant"
);
IF_G1_DETAILED_STATS
(
note_pop
());
}
else
{
StarTask
null_task
;
ref
=
null_task
;
...
...
@@ -1695,7 +1677,8 @@ public:
}
void
pop_from_overflow_queue
(
StarTask
&
ref
)
{
StarTask
new_ref
=
overflowed_refs
()
->
pop
();
StarTask
new_ref
;
refs
()
->
pop_overflow
(
new_ref
);
assert
((
oop
*
)
new_ref
!=
NULL
,
"pop() from a local non-empty stack"
);
assert
(
UseCompressedOops
||
!
new_ref
.
is_narrow
(),
"Error"
);
assert
(
has_partial_array_mask
((
oop
*
)
new_ref
)
||
...
...
@@ -1706,7 +1689,7 @@ public:
}
int
refs_to_scan
()
{
return
refs
()
->
size
();
}
int
overflowed_refs_to_scan
()
{
return
overflowed_refs
()
->
length
();
}
int
overflowed_refs_to_scan
()
{
return
refs
()
->
overflow_stack
()
->
length
();
}
template
<
class
T
>
void
update_rs
(
HeapRegion
*
from
,
T
*
p
,
int
tid
)
{
if
(
G1DeferredRSUpdate
)
{
...
...
@@ -1775,30 +1758,16 @@ public:
int
*
hash_seed
()
{
return
&
_hash_seed
;
}
int
queue_num
()
{
return
_queue_num
;
}
size_t
term_attempts
()
{
return
_term_attempts
;
}
size_t
term_attempts
()
const
{
return
_term_attempts
;
}
void
note_term_attempt
()
{
_term_attempts
++
;
}
#if G1_DETAILED_STATS
int
pushes
()
{
return
_pushes
;
}
int
pops
()
{
return
_pops
;
}
int
steals
()
{
return
_steals
;
}
int
steal_attempts
()
{
return
_steal_attempts
;
}
int
overflow_pushes
()
{
return
_overflow_pushes
;
}
void
note_push
()
{
_pushes
++
;
}
void
note_pop
()
{
_pops
++
;
}
void
note_steal
()
{
_steals
++
;
}
void
note_steal_attempt
()
{
_steal_attempts
++
;
}
void
note_overflow_push
()
{
_overflow_pushes
++
;
}
#endif
void
start_strong_roots
()
{
_start_strong_roots
=
os
::
elapsedTime
();
}
void
end_strong_roots
()
{
_strong_roots_time
+=
(
os
::
elapsedTime
()
-
_start_strong_roots
);
}
double
strong_roots_time
()
{
return
_strong_roots_time
;
}
double
strong_roots_time
()
const
{
return
_strong_roots_time
;
}
void
start_term_time
()
{
note_term_attempt
();
...
...
@@ -1807,12 +1776,17 @@ public:
void
end_term_time
()
{
_term_time
+=
(
os
::
elapsedTime
()
-
_start_term
);
}
double
term_time
()
{
return
_term_time
;
}
double
term_time
()
const
{
return
_term_time
;
}
double
elapsed
()
{
double
elapsed
_time
()
const
{
return
os
::
elapsedTime
()
-
_start
;
}
static
void
print_termination_stats_hdr
(
outputStream
*
const
st
=
gclog_or_tty
);
void
print_termination_stats
(
int
i
,
outputStream
*
const
st
=
gclog_or_tty
)
const
;
size_t
*
surviving_young_words
()
{
// We add on to hide entry 0 which accumulates surviving words for
// age -1 regions (i.e. non-young ones)
...
...
src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
浏览文件 @
e6ad5bbe
...
...
@@ -81,11 +81,10 @@ inline HeapWord* G1CollectedHeap::attempt_allocation(size_t word_size,
return
attempt_allocation_slow
(
word_size
,
permit_collection_pause
);
}
inline
RefToScanQueue
*
G1CollectedHeap
::
task_queue
(
int
i
)
{
inline
RefToScanQueue
*
G1CollectedHeap
::
task_queue
(
int
i
)
const
{
return
_task_queues
->
queue
(
i
);
}
inline
bool
G1CollectedHeap
::
isMarkedPrev
(
oop
obj
)
const
{
return
_cm
->
prevMarkBitMap
()
->
isMarked
((
HeapWord
*
)
obj
);
}
...
...
src/share/vm/utilities/taskqueue.cpp
浏览文件 @
e6ad5bbe
...
...
@@ -36,6 +36,14 @@ const char * const TaskQueueStats::_names[last_stat_id] = {
"qpush"
,
"qpop"
,
"qpop-s"
,
"qattempt"
,
"qsteal"
,
"opush"
,
"omax"
};
TaskQueueStats
&
TaskQueueStats
::
operator
+=
(
const
TaskQueueStats
&
addend
)
{
for
(
unsigned
int
i
=
0
;
i
<
last_stat_id
;
++
i
)
{
_stats
[
i
]
+=
addend
.
_stats
[
i
];
}
return
*
this
;
}
void
TaskQueueStats
::
print_header
(
unsigned
int
line
,
outputStream
*
const
stream
,
unsigned
int
width
)
{
...
...
@@ -71,6 +79,29 @@ void TaskQueueStats::print(outputStream* stream, unsigned int width) const
}
#undef FMT
}
#ifdef ASSERT
// Invariants which should hold after a TaskQueue has been emptied and is
// quiescent; they do not hold at arbitrary times.
void
TaskQueueStats
::
verify
()
const
{
assert
(
get
(
push
)
==
get
(
pop
)
+
get
(
steal
),
err_msg
(
"push="
SIZE_FORMAT
" pop="
SIZE_FORMAT
" steal="
SIZE_FORMAT
,
get
(
push
),
get
(
pop
),
get
(
steal
)));
assert
(
get
(
pop_slow
)
<=
get
(
pop
),
err_msg
(
"pop_slow="
SIZE_FORMAT
" pop="
SIZE_FORMAT
,
get
(
pop_slow
),
get
(
pop
)));
assert
(
get
(
steal
)
<=
get
(
steal_attempt
),
err_msg
(
"steal="
SIZE_FORMAT
" steal_attempt="
SIZE_FORMAT
,
get
(
steal
),
get
(
steal_attempt
)));
assert
(
get
(
overflow
)
==
0
||
get
(
push
)
!=
0
,
err_msg
(
"overflow="
SIZE_FORMAT
" push="
SIZE_FORMAT
,
get
(
overflow
),
get
(
push
)));
assert
(
get
(
overflow_max_len
)
==
0
||
get
(
overflow
)
!=
0
,
err_msg
(
"overflow_max_len="
SIZE_FORMAT
" overflow="
SIZE_FORMAT
,
get
(
overflow_max_len
),
get
(
overflow
)));
}
#endif // ASSERT
#endif // TASKQUEUE_STATS
int
TaskQueueSetSuper
::
randomParkAndMiller
(
int
*
seed0
)
{
...
...
src/share/vm/utilities/taskqueue.hpp
浏览文件 @
e6ad5bbe
...
...
@@ -59,15 +59,21 @@ public:
inline
void
record_steal
(
bool
success
);
inline
void
record_overflow
(
size_t
new_length
);
TaskQueueStats
&
operator
+=
(
const
TaskQueueStats
&
addend
);
inline
size_t
get
(
StatId
id
)
const
{
return
_stats
[
id
];
}
inline
const
size_t
*
get
()
const
{
return
_stats
;
}
inline
void
reset
();
// Print the specified line of the header (does not include a line separator).
static
void
print_header
(
unsigned
int
line
,
outputStream
*
const
stream
=
tty
,
unsigned
int
width
=
10
);
// Print the statistics (does not include a line separator).
void
print
(
outputStream
*
const
stream
=
tty
,
unsigned
int
width
=
10
)
const
;
DEBUG_ONLY
(
void
verify
()
const
;)
private:
size_t
_stats
[
last_stat_id
];
static
const
char
*
const
_names
[
last_stat_id
];
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录