Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
c4091c5a
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看板
提交
c4091c5a
编写于
6月 07, 2011
作者:
J
jcoomes
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
9afeef74
4a132bd6
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
155 addition
and
79 deletion
+155
-79
src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
...entation/concurrentMarkSweep/compactibleFreeListSpace.hpp
+6
-1
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
...ion/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+127
-66
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
...ion/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
+11
-7
src/share/vm/memory/blockOffsetTable.cpp
src/share/vm/memory/blockOffsetTable.cpp
+11
-5
未找到文件。
src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
浏览文件 @
c4091c5a
/*
/*
* Copyright (c) 2001, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
1
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -407,6 +407,11 @@ class CompactibleFreeListSpace: public CompactibleSpace {
...
@@ -407,6 +407,11 @@ class CompactibleFreeListSpace: public CompactibleSpace {
void
save_sweep_limit
()
{
void
save_sweep_limit
()
{
_sweep_limit
=
BlockOffsetArrayUseUnallocatedBlock
?
_sweep_limit
=
BlockOffsetArrayUseUnallocatedBlock
?
unallocated_block
()
:
end
();
unallocated_block
()
:
end
();
if
(
CMSTraceSweeper
)
{
gclog_or_tty
->
print_cr
(
">>>>> Saving sweep limit "
PTR_FORMAT
" for space ["
PTR_FORMAT
","
PTR_FORMAT
") <<<<<<"
,
_sweep_limit
,
bottom
(),
end
());
}
}
}
NOT_PRODUCT
(
NOT_PRODUCT
(
void
clear_sweep_limit
()
{
_sweep_limit
=
NULL
;
}
void
clear_sweep_limit
()
{
_sweep_limit
=
NULL
;
}
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
浏览文件 @
c4091c5a
...
@@ -7888,40 +7888,45 @@ SweepClosure::SweepClosure(CMSCollector* collector,
...
@@ -7888,40 +7888,45 @@ SweepClosure::SweepClosure(CMSCollector* collector,
assert
(
_limit
>=
_sp
->
bottom
()
&&
_limit
<=
_sp
->
end
(),
assert
(
_limit
>=
_sp
->
bottom
()
&&
_limit
<=
_sp
->
end
(),
"sweep _limit out of bounds"
);
"sweep _limit out of bounds"
);
if
(
CMSTraceSweeper
)
{
if
(
CMSTraceSweeper
)
{
gclog_or_tty
->
print
(
"
\n
====================
\n
Starting new sweep
\n
"
);
gclog_or_tty
->
print_cr
(
"
\n
====================
\n
Starting new sweep with limit "
PTR_FORMAT
,
_limit
);
}
}
}
}
// We need this destructor to reclaim any space at the end
void
SweepClosure
::
print_on
(
outputStream
*
st
)
const
{
// of the space, which do_blk below may not yet have added back to
tty
->
print_cr
(
"_sp = ["
PTR_FORMAT
","
PTR_FORMAT
")"
,
// the free lists.
_sp
->
bottom
(),
_sp
->
end
());
tty
->
print_cr
(
"_limit = "
PTR_FORMAT
,
_limit
);
tty
->
print_cr
(
"_freeFinger = "
PTR_FORMAT
,
_freeFinger
);
NOT_PRODUCT
(
tty
->
print_cr
(
"_last_fc = "
PTR_FORMAT
,
_last_fc
);)
tty
->
print_cr
(
"_inFreeRange = %d, _freeRangeInFreeLists = %d, _lastFreeRangeCoalesced = %d"
,
_inFreeRange
,
_freeRangeInFreeLists
,
_lastFreeRangeCoalesced
);
}
#ifndef PRODUCT
// Assertion checking only: no useful work in product mode --
// however, if any of the flags below become product flags,
// you may need to review this code to see if it needs to be
// enabled in product mode.
SweepClosure
::~
SweepClosure
()
{
SweepClosure
::~
SweepClosure
()
{
assert_lock_strong
(
_freelistLock
);
assert_lock_strong
(
_freelistLock
);
assert
(
_limit
>=
_sp
->
bottom
()
&&
_limit
<=
_sp
->
end
(),
assert
(
_limit
>=
_sp
->
bottom
()
&&
_limit
<=
_sp
->
end
(),
"sweep _limit out of bounds"
);
"sweep _limit out of bounds"
);
// Flush any remaining coterminal free run as a single
// coalesced chunk to the appropriate free list.
if
(
inFreeRange
())
{
if
(
inFreeRange
())
{
assert
(
freeFinger
()
<
_limit
,
"freeFinger points too high"
);
warning
(
"inFreeRange() should have been reset; dumping state of SweepClosure"
);
flush_cur_free_chunk
(
freeFinger
(),
pointer_delta
(
_limit
,
freeFinger
()));
print
();
if
(
CMSTraceSweeper
)
{
ShouldNotReachHere
();
gclog_or_tty
->
print
(
"Sweep: last chunk: "
);
gclog_or_tty
->
print
(
"put_free_blk 0x%x ("
SIZE_FORMAT
") [coalesced:"
SIZE_FORMAT
"]
\n
"
,
freeFinger
(),
pointer_delta
(
_limit
,
freeFinger
()),
lastFreeRangeCoalesced
());
}
}
}
// else nothing to flush
NOT_PRODUCT
(
if
(
Verbose
&&
PrintGC
)
{
if
(
Verbose
&&
PrintGC
)
{
gclog_or_tty
->
print
(
"Collected "
SIZE_FORMAT
" objects, "
gclog_or_tty
->
print
(
"Collected "
SIZE_FORMAT
" objects, "
SIZE_FORMAT
" bytes"
,
SIZE_FORMAT
" bytes"
,
_numObjectsFreed
,
_numWordsFreed
*
sizeof
(
HeapWord
));
_numObjectsFreed
,
_numWordsFreed
*
sizeof
(
HeapWord
));
gclog_or_tty
->
print_cr
(
"
\n
Live "
SIZE_FORMAT
" objects, "
gclog_or_tty
->
print_cr
(
"
\n
Live "
SIZE_FORMAT
" objects, "
SIZE_FORMAT
" bytes "
SIZE_FORMAT
" bytes "
"Already free "
SIZE_FORMAT
" objects, "
SIZE_FORMAT
" bytes"
,
"Already free "
SIZE_FORMAT
" objects, "
SIZE_FORMAT
" bytes"
,
_numObjectsLive
,
_numWordsLive
*
sizeof
(
HeapWord
),
_numObjectsLive
,
_numWordsLive
*
sizeof
(
HeapWord
),
_numObjectsAlreadyFree
,
_numWordsAlreadyFree
*
sizeof
(
HeapWord
));
_numObjectsAlreadyFree
,
_numWordsAlreadyFree
*
sizeof
(
HeapWord
));
size_t
totalBytes
=
(
_numWordsFreed
+
_numWordsLive
+
_numWordsAlreadyFree
)
*
size_t
totalBytes
=
(
_numWordsFreed
+
_numWordsLive
+
_numWordsAlreadyFree
)
sizeof
(
HeapWord
);
*
sizeof
(
HeapWord
);
gclog_or_tty
->
print_cr
(
"Total sweep: "
SIZE_FORMAT
" bytes"
,
totalBytes
);
gclog_or_tty
->
print_cr
(
"Total sweep: "
SIZE_FORMAT
" bytes"
,
totalBytes
);
if
(
PrintCMSStatistics
&&
CMSVerifyReturnedBytes
)
{
if
(
PrintCMSStatistics
&&
CMSVerifyReturnedBytes
)
{
...
@@ -7935,13 +7940,12 @@ SweepClosure::~SweepClosure() {
...
@@ -7935,13 +7940,12 @@ SweepClosure::~SweepClosure() {
dictReturnedBytes
);
dictReturnedBytes
);
}
}
}
}
)
// Now, in debug mode, just null out the sweep_limit
NOT_PRODUCT
(
_sp
->
clear_sweep_limit
();)
if
(
CMSTraceSweeper
)
{
if
(
CMSTraceSweeper
)
{
gclog_or_tty
->
print
(
"end of sweep
\n
================
\n
"
);
gclog_or_tty
->
print_cr
(
"end of sweep with _limit = "
PTR_FORMAT
"
\n
================"
,
_limit
);
}
}
}
}
#endif // PRODUCT
void
SweepClosure
::
initialize_free_range
(
HeapWord
*
freeFinger
,
void
SweepClosure
::
initialize_free_range
(
HeapWord
*
freeFinger
,
bool
freeRangeInFreeLists
)
{
bool
freeRangeInFreeLists
)
{
...
@@ -8001,15 +8005,17 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
...
@@ -8001,15 +8005,17 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
// we started the sweep, it may no longer be one because heap expansion
// we started the sweep, it may no longer be one because heap expansion
// may have caused us to coalesce the block ending at the address _limit
// may have caused us to coalesce the block ending at the address _limit
// with a newly expanded chunk (this happens when _limit was set to the
// with a newly expanded chunk (this happens when _limit was set to the
// previous _end of the space), so we may have stepped past _limit; see CR 6977970.
// previous _end of the space), so we may have stepped past _limit:
// see the following Zeno-like trail of CRs 6977970, 7008136, 7042740.
if
(
addr
>=
_limit
)
{
// we have swept up to or past the limit: finish up
if
(
addr
>=
_limit
)
{
// we have swept up to or past the limit: finish up
assert
(
_limit
>=
_sp
->
bottom
()
&&
_limit
<=
_sp
->
end
(),
assert
(
_limit
>=
_sp
->
bottom
()
&&
_limit
<=
_sp
->
end
(),
"sweep _limit out of bounds"
);
"sweep _limit out of bounds"
);
assert
(
addr
<
_sp
->
end
(),
"addr out of bounds"
);
assert
(
addr
<
_sp
->
end
(),
"addr out of bounds"
);
// Flush any
remaining coterminal free run
as a single
// Flush any
free range we might be holding
as a single
// coalesced chunk to the appropriate free list.
// coalesced chunk to the appropriate free list.
if
(
inFreeRange
())
{
if
(
inFreeRange
())
{
assert
(
freeFinger
()
<
_limit
,
"finger points too high"
);
assert
(
freeFinger
()
>=
_sp
->
bottom
()
&&
freeFinger
()
<
_limit
,
err_msg
(
"freeFinger() "
PTR_FORMAT
" is out-of-bounds"
,
freeFinger
()));
flush_cur_free_chunk
(
freeFinger
(),
flush_cur_free_chunk
(
freeFinger
(),
pointer_delta
(
addr
,
freeFinger
()));
pointer_delta
(
addr
,
freeFinger
()));
if
(
CMSTraceSweeper
)
{
if
(
CMSTraceSweeper
)
{
...
@@ -8033,7 +8039,16 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
...
@@ -8033,7 +8039,16 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
res
=
fc
->
size
();
res
=
fc
->
size
();
do_already_free_chunk
(
fc
);
do_already_free_chunk
(
fc
);
debug_only
(
_sp
->
verifyFreeLists
());
debug_only
(
_sp
->
verifyFreeLists
());
assert
(
res
==
fc
->
size
(),
"Don't expect the size to change"
);
// If we flush the chunk at hand in lookahead_and_flush()
// and it's coalesced with a preceding chunk, then the
// process of "mangling" the payload of the coalesced block
// will cause erasure of the size information from the
// (erstwhile) header of all the coalesced blocks but the
// first, so the first disjunct in the assert will not hold
// in that specific case (in which case the second disjunct
// will hold).
assert
(
res
==
fc
->
size
()
||
((
HeapWord
*
)
fc
)
+
res
>=
_limit
,
"Otherwise the size info doesn't change at this step"
);
NOT_PRODUCT
(
NOT_PRODUCT
(
_numObjectsAlreadyFree
++
;
_numObjectsAlreadyFree
++
;
_numWordsAlreadyFree
+=
res
;
_numWordsAlreadyFree
+=
res
;
...
@@ -8103,7 +8118,7 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
...
@@ -8103,7 +8118,7 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
//
//
void
SweepClosure
::
do_already_free_chunk
(
FreeChunk
*
fc
)
{
void
SweepClosure
::
do_already_free_chunk
(
FreeChunk
*
fc
)
{
size_t
size
=
fc
->
size
();
const
size_t
size
=
fc
->
size
();
// Chunks that cannot be coalesced are not in the
// Chunks that cannot be coalesced are not in the
// free lists.
// free lists.
if
(
CMSTestInFreeList
&&
!
fc
->
cantCoalesce
())
{
if
(
CMSTestInFreeList
&&
!
fc
->
cantCoalesce
())
{
...
@@ -8112,7 +8127,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
...
@@ -8112,7 +8127,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
}
}
// a chunk that is already free, should not have been
// a chunk that is already free, should not have been
// marked in the bit map
// marked in the bit map
HeapWord
*
addr
=
(
HeapWord
*
)
fc
;
HeapWord
*
const
addr
=
(
HeapWord
*
)
fc
;
assert
(
!
_bitMap
->
isMarked
(
addr
),
"free chunk should be unmarked"
);
assert
(
!
_bitMap
->
isMarked
(
addr
),
"free chunk should be unmarked"
);
// Verify that the bit map has no bits marked between
// Verify that the bit map has no bits marked between
// addr and purported end of this block.
// addr and purported end of this block.
...
@@ -8149,7 +8164,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
...
@@ -8149,7 +8164,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
}
}
}
else
{
}
else
{
// the midst of a free range, we are coalescing
// the midst of a free range, we are coalescing
debug_only
(
record_free_block_coalesced
(
fc
);)
print_free_block_coalesced
(
fc
);
if
(
CMSTraceSweeper
)
{
if
(
CMSTraceSweeper
)
{
gclog_or_tty
->
print
(
" -- pick up free block 0x%x (%d)
\n
"
,
fc
,
size
);
gclog_or_tty
->
print
(
" -- pick up free block 0x%x (%d)
\n
"
,
fc
,
size
);
}
}
...
@@ -8173,6 +8188,10 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
...
@@ -8173,6 +8188,10 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
}
}
}
}
}
}
// Note that if the chunk is not coalescable (the else arm
// below), we unconditionally flush, without needing to do
// a "lookahead," as we do below.
if
(
inFreeRange
())
lookahead_and_flush
(
fc
,
size
);
}
else
{
}
else
{
// Code path common to both original and adaptive free lists.
// Code path common to both original and adaptive free lists.
...
@@ -8191,8 +8210,8 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
...
@@ -8191,8 +8210,8 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
// This is a chunk of garbage. It is not in any free list.
// This is a chunk of garbage. It is not in any free list.
// Add it to a free list or let it possibly be coalesced into
// Add it to a free list or let it possibly be coalesced into
// a larger chunk.
// a larger chunk.
HeapWord
*
addr
=
(
HeapWord
*
)
fc
;
HeapWord
*
const
addr
=
(
HeapWord
*
)
fc
;
size_t
size
=
CompactibleFreeListSpace
::
adjustObjectSize
(
oop
(
addr
)
->
size
());
const
size_t
size
=
CompactibleFreeListSpace
::
adjustObjectSize
(
oop
(
addr
)
->
size
());
if
(
_sp
->
adaptive_freelists
())
{
if
(
_sp
->
adaptive_freelists
())
{
// Verify that the bit map has no bits marked between
// Verify that the bit map has no bits marked between
...
@@ -8205,7 +8224,6 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
...
@@ -8205,7 +8224,6 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
// start of a new free range
// start of a new free range
assert
(
size
>
0
,
"A free range should have a size"
);
assert
(
size
>
0
,
"A free range should have a size"
);
initialize_free_range
(
addr
,
false
);
initialize_free_range
(
addr
,
false
);
}
else
{
}
else
{
// this will be swept up when we hit the end of the
// this will be swept up when we hit the end of the
// free range
// free range
...
@@ -8235,6 +8253,9 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
...
@@ -8235,6 +8253,9 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
// addr and purported end of just dead object.
// addr and purported end of just dead object.
_bitMap
->
verifyNoOneBitsInRange
(
addr
+
1
,
addr
+
size
);
_bitMap
->
verifyNoOneBitsInRange
(
addr
+
1
,
addr
+
size
);
}
}
assert
(
_limit
>=
addr
+
size
,
"A freshly garbage chunk can't possibly straddle over _limit"
);
if
(
inFreeRange
())
lookahead_and_flush
(
fc
,
size
);
return
size
;
return
size
;
}
}
...
@@ -8284,8 +8305,8 @@ size_t SweepClosure::do_live_chunk(FreeChunk* fc) {
...
@@ -8284,8 +8305,8 @@ size_t SweepClosure::do_live_chunk(FreeChunk* fc) {
(
!
_collector
->
should_unload_classes
()
(
!
_collector
->
should_unload_classes
()
||
oop
(
addr
)
->
is_parsable
()),
||
oop
(
addr
)
->
is_parsable
()),
"Should be an initialized object"
);
"Should be an initialized object"
);
// Note that there are objects used during class redefinition
// Note that there are objects used during class redefinition
,
//
(e.g., merge_cp in VM_RedefineClasses::merge_cp_and_rewrite()
//
e.g. merge_cp in VM_RedefineClasses::merge_cp_and_rewrite(),
// which are discarded with their is_conc_safe state still
// which are discarded with their is_conc_safe state still
// false. These object may be floating garbage so may be
// false. These object may be floating garbage so may be
// seen here. If they are floating garbage their size
// seen here. If they are floating garbage their size
...
@@ -8307,7 +8328,7 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
...
@@ -8307,7 +8328,7 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
size_t
chunkSize
)
{
size_t
chunkSize
)
{
// do_post_free_or_garbage_chunk() should only be called in the case
// do_post_free_or_garbage_chunk() should only be called in the case
// of the adaptive free list allocator.
// of the adaptive free list allocator.
bool
fcInFreeLists
=
fc
->
isFree
();
const
bool
fcInFreeLists
=
fc
->
isFree
();
assert
(
_sp
->
adaptive_freelists
(),
"Should only be used in this case."
);
assert
(
_sp
->
adaptive_freelists
(),
"Should only be used in this case."
);
assert
((
HeapWord
*
)
fc
<=
_limit
,
"sweep invariant"
);
assert
((
HeapWord
*
)
fc
<=
_limit
,
"sweep invariant"
);
if
(
CMSTestInFreeList
&&
fcInFreeLists
)
{
if
(
CMSTestInFreeList
&&
fcInFreeLists
)
{
...
@@ -8318,11 +8339,11 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
...
@@ -8318,11 +8339,11 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
gclog_or_tty
->
print_cr
(
" -- pick up another chunk at 0x%x (%d)"
,
fc
,
chunkSize
);
gclog_or_tty
->
print_cr
(
" -- pick up another chunk at 0x%x (%d)"
,
fc
,
chunkSize
);
}
}
HeapWord
*
addr
=
(
HeapWord
*
)
fc
;
HeapWord
*
const
fc_
addr
=
(
HeapWord
*
)
fc
;
bool
coalesce
;
bool
coalesce
;
size_t
left
=
pointer_delta
(
addr
,
freeFinger
());
const
size_t
left
=
pointer_delta
(
fc_
addr
,
freeFinger
());
size_t
right
=
chunkSize
;
const
size_t
right
=
chunkSize
;
switch
(
FLSCoalescePolicy
)
{
switch
(
FLSCoalescePolicy
)
{
// numeric value forms a coalition aggressiveness metric
// numeric value forms a coalition aggressiveness metric
case
0
:
{
// never coalesce
case
0
:
{
// never coalesce
...
@@ -8355,15 +8376,15 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
...
@@ -8355,15 +8376,15 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
// If the chunk is in a free range and either we decided to coalesce above
// If the chunk is in a free range and either we decided to coalesce above
// or the chunk is near the large block at the end of the heap
// or the chunk is near the large block at the end of the heap
// (isNearLargestChunk() returns true), then coalesce this chunk.
// (isNearLargestChunk() returns true), then coalesce this chunk.
bool
doCoalesce
=
inFreeRange
()
&&
const
bool
doCoalesce
=
inFreeRange
()
(
coalesce
||
_g
->
isNearLargestChunk
((
HeapWord
*
)
fc
));
&&
(
coalesce
||
_g
->
isNearLargestChunk
(
fc_addr
));
if
(
doCoalesce
)
{
if
(
doCoalesce
)
{
// Coalesce the current free range on the left with the new
// Coalesce the current free range on the left with the new
// chunk on the right. If either is on a free list,
// chunk on the right. If either is on a free list,
// it must be removed from the list and stashed in the closure.
// it must be removed from the list and stashed in the closure.
if
(
freeRangeInFreeLists
())
{
if
(
freeRangeInFreeLists
())
{
FreeChunk
*
ffc
=
(
FreeChunk
*
)
freeFinger
();
FreeChunk
*
const
ffc
=
(
FreeChunk
*
)
freeFinger
();
assert
(
ffc
->
size
()
==
pointer_delta
(
addr
,
freeFinger
()),
assert
(
ffc
->
size
()
==
pointer_delta
(
fc_
addr
,
freeFinger
()),
"Size of free range is inconsistent with chunk size."
);
"Size of free range is inconsistent with chunk size."
);
if
(
CMSTestInFreeList
)
{
if
(
CMSTestInFreeList
)
{
assert
(
_sp
->
verifyChunkInFreeLists
(
ffc
),
assert
(
_sp
->
verifyChunkInFreeLists
(
ffc
),
...
@@ -8380,13 +8401,14 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
...
@@ -8380,13 +8401,14 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
_sp
->
removeFreeChunkFromFreeLists
(
fc
);
_sp
->
removeFreeChunkFromFreeLists
(
fc
);
}
}
set_lastFreeRangeCoalesced
(
true
);
set_lastFreeRangeCoalesced
(
true
);
print_free_block_coalesced
(
fc
);
}
else
{
// not in a free range and/or should not coalesce
}
else
{
// not in a free range and/or should not coalesce
// Return the current free range and start a new one.
// Return the current free range and start a new one.
if
(
inFreeRange
())
{
if
(
inFreeRange
())
{
// In a free range but cannot coalesce with the right hand chunk.
// In a free range but cannot coalesce with the right hand chunk.
// Put the current free range into the free lists.
// Put the current free range into the free lists.
flush_cur_free_chunk
(
freeFinger
(),
flush_cur_free_chunk
(
freeFinger
(),
pointer_delta
(
addr
,
freeFinger
()));
pointer_delta
(
fc_
addr
,
freeFinger
()));
}
}
// Set up for new free range. Pass along whether the right hand
// Set up for new free range. Pass along whether the right hand
// chunk is in the free lists.
// chunk is in the free lists.
...
@@ -8394,6 +8416,42 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
...
@@ -8394,6 +8416,42 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
}
}
}
}
// Lookahead flush:
// If we are tracking a free range, and this is the last chunk that
// we'll look at because its end crosses past _limit, we'll preemptively
// flush it along with any free range we may be holding on to. Note that
// this can be the case only for an already free or freshly garbage
// chunk. If this block is an object, it can never straddle
// over _limit. The "straddling" occurs when _limit is set at
// the previous end of the space when this cycle started, and
// a subsequent heap expansion caused the previously co-terminal
// free block to be coalesced with the newly expanded portion,
// thus rendering _limit a non-block-boundary making it dangerous
// for the sweeper to step over and examine.
void
SweepClosure
::
lookahead_and_flush
(
FreeChunk
*
fc
,
size_t
chunk_size
)
{
assert
(
inFreeRange
(),
"Should only be called if currently in a free range."
);
HeapWord
*
const
eob
=
((
HeapWord
*
)
fc
)
+
chunk_size
;
assert
(
_sp
->
used_region
().
contains
(
eob
-
1
),
err_msg
(
"eob = "
PTR_FORMAT
" out of bounds wrt _sp = ["
PTR_FORMAT
","
PTR_FORMAT
")"
" when examining fc = "
PTR_FORMAT
"("
SIZE_FORMAT
")"
,
_limit
,
_sp
->
bottom
(),
_sp
->
end
(),
fc
,
chunk_size
));
if
(
eob
>=
_limit
)
{
assert
(
eob
==
_limit
||
fc
->
isFree
(),
"Only a free chunk should allow us to cross over the limit"
);
if
(
CMSTraceSweeper
)
{
gclog_or_tty
->
print_cr
(
"_limit "
PTR_FORMAT
" reached or crossed by block "
"["
PTR_FORMAT
","
PTR_FORMAT
") in space "
"["
PTR_FORMAT
","
PTR_FORMAT
")"
,
_limit
,
fc
,
eob
,
_sp
->
bottom
(),
_sp
->
end
());
}
// Return the storage we are tracking back into the free lists.
if
(
CMSTraceSweeper
)
{
gclog_or_tty
->
print_cr
(
"Flushing ... "
);
}
assert
(
freeFinger
()
<
eob
,
"Error"
);
flush_cur_free_chunk
(
freeFinger
(),
pointer_delta
(
eob
,
freeFinger
()));
}
}
void
SweepClosure
::
flush_cur_free_chunk
(
HeapWord
*
chunk
,
size_t
size
)
{
void
SweepClosure
::
flush_cur_free_chunk
(
HeapWord
*
chunk
,
size_t
size
)
{
assert
(
inFreeRange
(),
"Should only be called if currently in a free range."
);
assert
(
inFreeRange
(),
"Should only be called if currently in a free range."
);
assert
(
size
>
0
,
assert
(
size
>
0
,
...
@@ -8419,6 +8477,8 @@ void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) {
...
@@ -8419,6 +8477,8 @@ void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) {
}
}
_sp
->
addChunkAndRepairOffsetTable
(
chunk
,
size
,
_sp
->
addChunkAndRepairOffsetTable
(
chunk
,
size
,
lastFreeRangeCoalesced
());
lastFreeRangeCoalesced
());
}
else
if
(
CMSTraceSweeper
)
{
gclog_or_tty
->
print_cr
(
"Already in free list: nothing to flush"
);
}
}
set_inFreeRange
(
false
);
set_inFreeRange
(
false
);
set_freeRangeInFreeLists
(
false
);
set_freeRangeInFreeLists
(
false
);
...
@@ -8477,13 +8537,14 @@ void SweepClosure::do_yield_work(HeapWord* addr) {
...
@@ -8477,13 +8537,14 @@ void SweepClosure::do_yield_work(HeapWord* addr) {
bool
debug_verifyChunkInFreeLists
(
FreeChunk
*
fc
)
{
bool
debug_verifyChunkInFreeLists
(
FreeChunk
*
fc
)
{
return
debug_cms_space
->
verifyChunkInFreeLists
(
fc
);
return
debug_cms_space
->
verifyChunkInFreeLists
(
fc
);
}
}
#endif
void
SweepClosure
::
record
_free_block_coalesced
(
FreeChunk
*
fc
)
const
{
void
SweepClosure
::
print
_free_block_coalesced
(
FreeChunk
*
fc
)
const
{
if
(
CMSTraceSweeper
)
{
if
(
CMSTraceSweeper
)
{
gclog_or_tty
->
print
(
"Sweep:coal_free_blk 0x%x (%d)
\n
"
,
fc
,
fc
->
size
());
gclog_or_tty
->
print_cr
(
"Sweep:coal_free_blk "
PTR_FORMAT
" ("
SIZE_FORMAT
")"
,
fc
,
fc
->
size
());
}
}
}
}
#endif
// CMSIsAliveClosure
// CMSIsAliveClosure
bool
CMSIsAliveClosure
::
do_object_b
(
oop
obj
)
{
bool
CMSIsAliveClosure
::
do_object_b
(
oop
obj
)
{
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
浏览文件 @
c4091c5a
...
@@ -1701,9 +1701,9 @@ class SweepClosure: public BlkClosureCareful {
...
@@ -1701,9 +1701,9 @@ class SweepClosure: public BlkClosureCareful {
CMSCollector
*
_collector
;
// collector doing the work
CMSCollector
*
_collector
;
// collector doing the work
ConcurrentMarkSweepGeneration
*
_g
;
// Generation being swept
ConcurrentMarkSweepGeneration
*
_g
;
// Generation being swept
CompactibleFreeListSpace
*
_sp
;
// Space being swept
CompactibleFreeListSpace
*
_sp
;
// Space being swept
HeapWord
*
_limit
;
// the address at
which the sweep should stop because
HeapWord
*
_limit
;
// the address at
or above which the sweep should stop
//
we do not expect blocks eligible for sweeping past
//
because we do not expect newly garbage blocks
// that address.
//
eligible for sweeping past
that address.
Mutex
*
_freelistLock
;
// Free list lock (in space)
Mutex
*
_freelistLock
;
// Free list lock (in space)
CMSBitMap
*
_bitMap
;
// Marking bit map (in
CMSBitMap
*
_bitMap
;
// Marking bit map (in
// generation)
// generation)
...
@@ -1750,6 +1750,10 @@ class SweepClosure: public BlkClosureCareful {
...
@@ -1750,6 +1750,10 @@ class SweepClosure: public BlkClosureCareful {
void
do_post_free_or_garbage_chunk
(
FreeChunk
*
fc
,
size_t
chunkSize
);
void
do_post_free_or_garbage_chunk
(
FreeChunk
*
fc
,
size_t
chunkSize
);
// Process a free chunk during sweeping.
// Process a free chunk during sweeping.
void
do_already_free_chunk
(
FreeChunk
*
fc
);
void
do_already_free_chunk
(
FreeChunk
*
fc
);
// Work method called when processing an already free or a
// freshly garbage chunk to do a lookahead and possibly a
// premptive flush if crossing over _limit.
void
lookahead_and_flush
(
FreeChunk
*
fc
,
size_t
chunkSize
);
// Process a garbage chunk during sweeping.
// Process a garbage chunk during sweeping.
size_t
do_garbage_chunk
(
FreeChunk
*
fc
);
size_t
do_garbage_chunk
(
FreeChunk
*
fc
);
// Process a live chunk during sweeping.
// Process a live chunk during sweeping.
...
@@ -1758,8 +1762,6 @@ class SweepClosure: public BlkClosureCareful {
...
@@ -1758,8 +1762,6 @@ class SweepClosure: public BlkClosureCareful {
// Accessors.
// Accessors.
HeapWord
*
freeFinger
()
const
{
return
_freeFinger
;
}
HeapWord
*
freeFinger
()
const
{
return
_freeFinger
;
}
void
set_freeFinger
(
HeapWord
*
v
)
{
_freeFinger
=
v
;
}
void
set_freeFinger
(
HeapWord
*
v
)
{
_freeFinger
=
v
;
}
size_t
freeRangeSize
()
const
{
return
_freeRangeSize
;
}
void
set_freeRangeSize
(
size_t
v
)
{
_freeRangeSize
=
v
;
}
bool
inFreeRange
()
const
{
return
_inFreeRange
;
}
bool
inFreeRange
()
const
{
return
_inFreeRange
;
}
void
set_inFreeRange
(
bool
v
)
{
_inFreeRange
=
v
;
}
void
set_inFreeRange
(
bool
v
)
{
_inFreeRange
=
v
;
}
bool
lastFreeRangeCoalesced
()
const
{
return
_lastFreeRangeCoalesced
;
}
bool
lastFreeRangeCoalesced
()
const
{
return
_lastFreeRangeCoalesced
;
}
...
@@ -1779,14 +1781,16 @@ class SweepClosure: public BlkClosureCareful {
...
@@ -1779,14 +1781,16 @@ class SweepClosure: public BlkClosureCareful {
void
do_yield_work
(
HeapWord
*
addr
);
void
do_yield_work
(
HeapWord
*
addr
);
// Debugging/Printing
// Debugging/Printing
void
record_free_block_coalesced
(
FreeChunk
*
fc
)
const
PRODUCT_RETURN
;
void
print_free_block_coalesced
(
FreeChunk
*
fc
)
const
;
public:
public:
SweepClosure
(
CMSCollector
*
collector
,
ConcurrentMarkSweepGeneration
*
g
,
SweepClosure
(
CMSCollector
*
collector
,
ConcurrentMarkSweepGeneration
*
g
,
CMSBitMap
*
bitMap
,
bool
should_yield
);
CMSBitMap
*
bitMap
,
bool
should_yield
);
~
SweepClosure
();
~
SweepClosure
()
PRODUCT_RETURN
;
size_t
do_blk_careful
(
HeapWord
*
addr
);
size_t
do_blk_careful
(
HeapWord
*
addr
);
void
print
()
const
{
print_on
(
tty
);
}
void
print_on
(
outputStream
*
st
)
const
;
};
};
// Closures related to weak references processing
// Closures related to weak references processing
...
...
src/share/vm/memory/blockOffsetTable.cpp
浏览文件 @
c4091c5a
/*
/*
* Copyright (c) 2000, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
1
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -566,11 +566,17 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe(
...
@@ -566,11 +566,17 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe(
q
=
n
;
q
=
n
;
n
+=
_sp
->
block_size
(
n
);
n
+=
_sp
->
block_size
(
n
);
assert
(
n
>
q
,
assert
(
n
>
q
,
err_msg
(
"Looping at n = "
PTR_FORMAT
" with last = "
PTR_FORMAT
" _sp = ["
PTR_FORMAT
","
PTR_FORMAT
")"
,
err_msg
(
"Looping at n = "
PTR_FORMAT
" with last = "
PTR_FORMAT
","
n
,
last
,
_sp
->
bottom
(),
_sp
->
end
()));
" while querying blk_start("
PTR_FORMAT
")"
}
" on _sp = ["
PTR_FORMAT
","
PTR_FORMAT
")"
,
assert
(
q
<=
addr
,
err_msg
(
"wrong order for current ("
INTPTR_FORMAT
") <= arg ("
INTPTR_FORMAT
")"
,
q
,
addr
));
n
,
last
,
addr
,
_sp
->
bottom
(),
_sp
->
end
()));
assert
(
addr
<=
n
,
err_msg
(
"wrong order for arg ("
INTPTR_FORMAT
") <= next ("
INTPTR_FORMAT
")"
,
addr
,
n
));
}
assert
(
q
<=
addr
,
err_msg
(
"wrong order for current ("
INTPTR_FORMAT
")"
" <= arg ("
INTPTR_FORMAT
")"
,
q
,
addr
));
assert
(
addr
<=
n
,
err_msg
(
"wrong order for arg ("
INTPTR_FORMAT
") <= next ("
INTPTR_FORMAT
")"
,
addr
,
n
));
return
q
;
return
q
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录