Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
8b1dc5fb
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看板
提交
8b1dc5fb
编写于
1月 21, 2009
作者:
J
jcoomes
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
8bff602b
39040ebb
变更
9
显示空白变更内容
内联
并排
Showing
9 changed file
with
272 addition
and
87 deletion
+272
-87
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+168
-63
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+53
-0
src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
+5
-2
src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+1
-0
src/share/vm/gc_implementation/g1/g1OopClosures.hpp
src/share/vm/gc_implementation/g1/g1OopClosures.hpp
+30
-9
src/share/vm/gc_implementation/g1/g1_globals.hpp
src/share/vm/gc_implementation/g1/g1_globals.hpp
+1
-1
src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp
...e/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp
+4
-2
src/share/vm/gc_implementation/includeDB_gc_g1
src/share/vm/gc_implementation/includeDB_gc_g1
+9
-9
src/share/vm/gc_implementation/includeDB_gc_shared
src/share/vm/gc_implementation/includeDB_gc_shared
+1
-1
未找到文件。
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
浏览文件 @
8b1dc5fb
...
@@ -1285,7 +1285,9 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
...
@@ -1285,7 +1285,9 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
_unclean_regions_coming
(
false
),
_unclean_regions_coming
(
false
),
_young_list
(
new
YoungList
(
this
)),
_young_list
(
new
YoungList
(
this
)),
_gc_time_stamp
(
0
),
_gc_time_stamp
(
0
),
_surviving_young_words
(
NULL
)
_surviving_young_words
(
NULL
),
_in_cset_fast_test
(
NULL
),
_in_cset_fast_test_base
(
NULL
)
{
{
_g1h
=
this
;
// To catch bugs.
_g1h
=
this
;
// To catch bugs.
if
(
_process_strong_tasks
==
NULL
||
!
_process_strong_tasks
->
valid
())
{
if
(
_process_strong_tasks
==
NULL
||
!
_process_strong_tasks
->
valid
())
{
...
@@ -2485,6 +2487,19 @@ G1CollectedHeap::do_collection_pause_at_safepoint(HeapRegion* popular_region) {
...
@@ -2485,6 +2487,19 @@ G1CollectedHeap::do_collection_pause_at_safepoint(HeapRegion* popular_region) {
g1_policy
()
->
record_collection_pause_start
(
start_time_sec
,
g1_policy
()
->
record_collection_pause_start
(
start_time_sec
,
start_used_bytes
);
start_used_bytes
);
guarantee
(
_in_cset_fast_test
==
NULL
,
"invariant"
);
guarantee
(
_in_cset_fast_test_base
==
NULL
,
"invariant"
);
_in_cset_fast_test_length
=
n_regions
();
_in_cset_fast_test_base
=
NEW_C_HEAP_ARRAY
(
bool
,
_in_cset_fast_test_length
);
memset
(
_in_cset_fast_test_base
,
false
,
_in_cset_fast_test_length
*
sizeof
(
bool
));
// We're biasing _in_cset_fast_test to avoid subtracting the
// beginning of the heap every time we want to index; basically
// it's the same with what we do with the card table.
_in_cset_fast_test
=
_in_cset_fast_test_base
-
((
size_t
)
_g1_reserved
.
start
()
>>
HeapRegion
::
LogOfHRGrainBytes
);
#if SCAN_ONLY_VERBOSE
#if SCAN_ONLY_VERBOSE
_young_list
->
print
();
_young_list
->
print
();
#endif // SCAN_ONLY_VERBOSE
#endif // SCAN_ONLY_VERBOSE
...
@@ -2553,6 +2568,12 @@ G1CollectedHeap::do_collection_pause_at_safepoint(HeapRegion* popular_region) {
...
@@ -2553,6 +2568,12 @@ G1CollectedHeap::do_collection_pause_at_safepoint(HeapRegion* popular_region) {
free_collection_set
(
g1_policy
()
->
collection_set
());
free_collection_set
(
g1_policy
()
->
collection_set
());
g1_policy
()
->
clear_collection_set
();
g1_policy
()
->
clear_collection_set
();
FREE_C_HEAP_ARRAY
(
bool
,
_in_cset_fast_test_base
);
// this is more for peace of mind; we're nulling them here and
// we're expecting them to be null at the beginning of the next GC
_in_cset_fast_test
=
NULL
;
_in_cset_fast_test_base
=
NULL
;
if
(
popular_region
!=
NULL
)
{
if
(
popular_region
!=
NULL
)
{
// We have to wait until now, because we don't want the region to
// We have to wait until now, because we don't want the region to
// be rescheduled for pop-evac during RS update.
// be rescheduled for pop-evac during RS update.
...
@@ -3560,6 +3581,9 @@ public:
...
@@ -3560,6 +3581,9 @@ public:
size_t
undo_waste
()
{
return
_undo_waste
;
}
size_t
undo_waste
()
{
return
_undo_waste
;
}
void
push_on_queue
(
oop
*
ref
)
{
void
push_on_queue
(
oop
*
ref
)
{
assert
(
ref
!=
NULL
,
"invariant"
);
assert
(
has_partial_array_mask
(
ref
)
||
_g1h
->
obj_in_cs
(
*
ref
),
"invariant"
);
if
(
!
refs
()
->
push
(
ref
))
{
if
(
!
refs
()
->
push
(
ref
))
{
overflowed_refs
()
->
push
(
ref
);
overflowed_refs
()
->
push
(
ref
);
IF_G1_DETAILED_STATS
(
note_overflow_push
());
IF_G1_DETAILED_STATS
(
note_overflow_push
());
...
@@ -3572,6 +3596,10 @@ public:
...
@@ -3572,6 +3596,10 @@ public:
if
(
!
refs
()
->
pop_local
(
ref
))
{
if
(
!
refs
()
->
pop_local
(
ref
))
{
ref
=
NULL
;
ref
=
NULL
;
}
else
{
}
else
{
assert
(
ref
!=
NULL
,
"invariant"
);
assert
(
has_partial_array_mask
(
ref
)
||
_g1h
->
obj_in_cs
(
*
ref
),
"invariant"
);
IF_G1_DETAILED_STATS
(
note_pop
());
IF_G1_DETAILED_STATS
(
note_pop
());
}
}
}
}
...
@@ -3601,8 +3629,7 @@ public:
...
@@ -3601,8 +3629,7 @@ public:
obj
=
alloc_buf
->
allocate
(
word_sz
);
obj
=
alloc_buf
->
allocate
(
word_sz
);
assert
(
obj
!=
NULL
,
"buffer was definitely big enough..."
);
assert
(
obj
!=
NULL
,
"buffer was definitely big enough..."
);
}
}
else
{
else
{
obj
=
_g1h
->
par_allocate_during_gc
(
purpose
,
word_sz
);
obj
=
_g1h
->
par_allocate_during_gc
(
purpose
,
word_sz
);
}
}
return
obj
;
return
obj
;
...
@@ -3695,16 +3722,9 @@ public:
...
@@ -3695,16 +3722,9 @@ public:
}
}
}
}
void
trim_queue
()
{
private:
while
(
refs_to_scan
()
>
0
||
overflowed_refs_to_scan
()
>
0
)
{
void
deal_with_reference
(
oop
*
ref_to_scan
)
{
oop
*
ref_to_scan
=
NULL
;
if
(
has_partial_array_mask
(
ref_to_scan
))
{
if
(
overflowed_refs_to_scan
()
==
0
)
{
pop_from_queue
(
ref_to_scan
);
}
else
{
pop_from_overflow_queue
(
ref_to_scan
);
}
if
(
ref_to_scan
!=
NULL
)
{
if
((
intptr_t
)
ref_to_scan
&
G1_PARTIAL_ARRAY_MASK
)
{
_partial_scan_cl
->
do_oop_nv
(
ref_to_scan
);
_partial_scan_cl
->
do_oop_nv
(
ref_to_scan
);
}
else
{
}
else
{
// Note: we can use "raw" versions of "region_containing" because
// Note: we can use "raw" versions of "region_containing" because
...
@@ -3715,6 +3735,46 @@ public:
...
@@ -3715,6 +3735,46 @@ public:
_evac_cl
->
do_oop_nv
(
ref_to_scan
);
_evac_cl
->
do_oop_nv
(
ref_to_scan
);
}
}
}
}
public:
void
trim_queue
()
{
// I've replicated the loop twice, first to drain the overflow
// queue, second to drain the task queue. This is better than
// having a single loop, which checks both conditions and, inside
// it, either pops the overflow queue or the task queue, as each
// loop is tighter. Also, the decision to drain the overflow queue
// first is not arbitrary, as the overflow queue is not visible
// to the other workers, whereas the task queue is. So, we want to
// drain the "invisible" entries first, while allowing the other
// workers to potentially steal the "visible" entries.
while
(
refs_to_scan
()
>
0
||
overflowed_refs_to_scan
()
>
0
)
{
while
(
overflowed_refs_to_scan
()
>
0
)
{
oop
*
ref_to_scan
=
NULL
;
pop_from_overflow_queue
(
ref_to_scan
);
assert
(
ref_to_scan
!=
NULL
,
"invariant"
);
// We shouldn't have pushed it on the queue if it was not
// pointing into the CSet.
assert
(
ref_to_scan
!=
NULL
,
"sanity"
);
assert
(
has_partial_array_mask
(
ref_to_scan
)
||
_g1h
->
obj_in_cs
(
*
ref_to_scan
),
"sanity"
);
deal_with_reference
(
ref_to_scan
);
}
while
(
refs_to_scan
()
>
0
)
{
oop
*
ref_to_scan
=
NULL
;
pop_from_queue
(
ref_to_scan
);
if
(
ref_to_scan
!=
NULL
)
{
// We shouldn't have pushed it on the queue if it was not
// pointing into the CSet.
assert
(
has_partial_array_mask
(
ref_to_scan
)
||
_g1h
->
obj_in_cs
(
*
ref_to_scan
),
"sanity"
);
deal_with_reference
(
ref_to_scan
);
}
}
}
}
}
}
};
};
...
@@ -3728,17 +3788,26 @@ G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState*
...
@@ -3728,17 +3788,26 @@ G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState*
// Should probably be made inline and moved in g1OopClosures.inline.hpp.
// Should probably be made inline and moved in g1OopClosures.inline.hpp.
void
G1ParScanClosure
::
do_oop_nv
(
oop
*
p
)
{
void
G1ParScanClosure
::
do_oop_nv
(
oop
*
p
)
{
oop
obj
=
*
p
;
oop
obj
=
*
p
;
if
(
obj
!=
NULL
)
{
if
(
obj
!=
NULL
)
{
if
(
_g1
->
obj_in_cs
(
obj
))
{
if
(
_g1
->
in_cset_fast_test
(
obj
))
{
if
(
obj
->
is_forwarded
())
{
// We're not going to even bother checking whether the object is
*
p
=
obj
->
forwardee
();
// already forwarded or not, as this usually causes an immediate
}
else
{
// stall. We'll try to prefetch the object (for write, given that
// we might need to install the forwarding reference) and we'll
// get back to it when pop it from the queue
Prefetch
::
write
(
obj
->
mark_addr
(),
0
);
Prefetch
::
read
(
obj
->
mark_addr
(),
(
HeapWordSize
*
2
));
// slightly paranoid test; I'm trying to catch potential
// problems before we go into push_on_queue to know where the
// problem is coming from
assert
(
obj
==
*
p
,
"the value of *p should not have changed"
);
_par_scan_state
->
push_on_queue
(
p
);
_par_scan_state
->
push_on_queue
(
p
);
return
;
}
else
{
}
}
_g1_rem
->
par_write_ref
(
_from
,
p
,
_par_scan_state
->
queue_num
());
_g1_rem
->
par_write_ref
(
_from
,
p
,
_par_scan_state
->
queue_num
());
}
}
}
}
}
void
G1ParCopyHelper
::
mark_forwardee
(
oop
*
p
)
{
void
G1ParCopyHelper
::
mark_forwardee
(
oop
*
p
)
{
...
@@ -3777,13 +3846,36 @@ oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
...
@@ -3777,13 +3846,36 @@ oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
return
_g1
->
handle_evacuation_failure_par
(
cl
,
old
);
return
_g1
->
handle_evacuation_failure_par
(
cl
,
old
);
}
}
// We're going to allocate linearly, so might as well prefetch ahead.
Prefetch
::
write
(
obj_ptr
,
PrefetchCopyIntervalInBytes
);
oop
forward_ptr
=
old
->
forward_to_atomic
(
obj
);
oop
forward_ptr
=
old
->
forward_to_atomic
(
obj
);
if
(
forward_ptr
==
NULL
)
{
if
(
forward_ptr
==
NULL
)
{
Copy
::
aligned_disjoint_words
((
HeapWord
*
)
old
,
obj_ptr
,
word_sz
);
Copy
::
aligned_disjoint_words
((
HeapWord
*
)
old
,
obj_ptr
,
word_sz
);
obj
->
set_mark
(
m
);
if
(
g1p
->
track_object_age
(
alloc_purpose
))
{
if
(
g1p
->
track_object_age
(
alloc_purpose
))
{
// We could simply do obj->incr_age(). However, this causes a
// performance issue. obj->incr_age() will first check whether
// the object has a displaced mark by checking its mark word;
// getting the mark word from the new location of the object
// stalls. So, given that we already have the mark word and we
// are about to install it anyway, it's better to increase the
// age on the mark word, when the object does not have a
// displaced mark word. We're not expecting many objects to have
// a displaced marked word, so that case is not optimized
// further (it could be...) and we simply call obj->incr_age().
if
(
m
->
has_displaced_mark_helper
())
{
// in this case, we have to install the mark word first,
// otherwise obj looks to be forwarded (the old mark word,
// which contains the forward pointer, was copied)
obj
->
set_mark
(
m
);
obj
->
incr_age
();
obj
->
incr_age
();
}
else
{
m
=
m
->
incr_age
();
}
}
}
obj
->
set_mark
(
m
);
// preserve "next" mark bit
// preserve "next" mark bit
if
(
_g1
->
mark_in_progress
()
&&
!
_g1
->
is_obj_ill
(
old
))
{
if
(
_g1
->
mark_in_progress
()
&&
!
_g1
->
is_obj_ill
(
old
))
{
if
(
!
use_local_bitmaps
||
if
(
!
use_local_bitmaps
||
...
@@ -3805,9 +3897,11 @@ oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
...
@@ -3805,9 +3897,11 @@ oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
if
(
obj
->
is_objArray
()
&&
arrayOop
(
obj
)
->
length
()
>=
ParGCArrayScanChunk
)
{
if
(
obj
->
is_objArray
()
&&
arrayOop
(
obj
)
->
length
()
>=
ParGCArrayScanChunk
)
{
arrayOop
(
old
)
->
set_length
(
0
);
arrayOop
(
old
)
->
set_length
(
0
);
_par_scan_state
->
push_on_queue
(
(
oop
*
)
((
intptr_t
)
old
|
G1_PARTIAL_ARRAY_MASK
));
_par_scan_state
->
push_on_queue
(
set_partial_array_mask
(
old
));
}
else
{
}
else
{
_scanner
->
set_region
(
_g1
->
heap_region_containing
(
obj
));
// No point in using the slower heap_region_containing() method,
// given that we know obj is in the heap.
_scanner
->
set_region
(
_g1
->
heap_region_containing_raw
(
obj
));
obj
->
oop_iterate_backwards
(
_scanner
);
obj
->
oop_iterate_backwards
(
_scanner
);
}
}
}
else
{
}
else
{
...
@@ -3817,17 +3911,25 @@ oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
...
@@ -3817,17 +3911,25 @@ oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
return
obj
;
return
obj
;
}
}
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_forwardee
>
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
void
G1ParCopyClosure
<
do_gen_barrier
,
barrier
,
do_mark_forwardee
>::
do_oop_work
(
oop
*
p
)
{
bool
do_mark_forwardee
,
bool
skip_cset_test
>
void
G1ParCopyClosure
<
do_gen_barrier
,
barrier
,
do_mark_forwardee
,
skip_cset_test
>::
do_oop_work
(
oop
*
p
)
{
oop
obj
=
*
p
;
oop
obj
=
*
p
;
assert
(
barrier
!=
G1BarrierRS
||
obj
!=
NULL
,
assert
(
barrier
!=
G1BarrierRS
||
obj
!=
NULL
,
"Precondition: G1BarrierRS implies obj is nonNull"
);
"Precondition: G1BarrierRS implies obj is nonNull"
);
if
(
obj
!=
NULL
)
{
// The only time we skip the cset test is when we're scanning
if
(
_g1
->
obj_in_cs
(
obj
))
{
// references popped from the queue. And we only push on the queue
// references that we know point into the cset, so no point in
// checking again. But we'll leave an assert here for peace of mind.
assert
(
!
skip_cset_test
||
_g1
->
obj_in_cs
(
obj
),
"invariant"
);
// here the null check is implicit in the cset_fast_test() test
if
(
skip_cset_test
||
_g1
->
in_cset_fast_test
(
obj
))
{
#if G1_REM_SET_LOGGING
#if G1_REM_SET_LOGGING
gclog_or_tty
->
print_cr
(
"Loc "
PTR_FORMAT
" contains pointer "
PTR_FORMAT
" into CS."
,
gclog_or_tty
->
print_cr
(
"Loc "
PTR_FORMAT
" contains pointer "
PTR_FORMAT
" "
p
,
(
void
*
)
obj
);
"into CS."
,
p
,
(
void
*
)
obj
);
#endif
#endif
if
(
obj
->
is_forwarded
())
{
if
(
obj
->
is_forwarded
())
{
*
p
=
obj
->
forwardee
();
*
p
=
obj
->
forwardee
();
...
@@ -3839,25 +3941,25 @@ void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_forwardee>::do_oop_work(o
...
@@ -3839,25 +3941,25 @@ void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_forwardee>::do_oop_work(o
_g1_rem
->
par_write_ref
(
_from
,
p
,
_par_scan_state
->
queue_num
());
_g1_rem
->
par_write_ref
(
_from
,
p
,
_par_scan_state
->
queue_num
());
}
}
}
}
// When scanning moved objs, must look at all oops.
// When scanning moved objs, must look at all oops.
if
(
barrier
==
G1BarrierEvac
)
{
if
(
barrier
==
G1BarrierEvac
&&
obj
!=
NULL
)
{
_g1_rem
->
par_write_ref
(
_from
,
p
,
_par_scan_state
->
queue_num
());
_g1_rem
->
par_write_ref
(
_from
,
p
,
_par_scan_state
->
queue_num
());
}
}
if
(
do_gen_barrier
)
{
if
(
do_gen_barrier
&&
obj
!=
NULL
)
{
par_do_barrier
(
p
);
par_do_barrier
(
p
);
}
}
}
}
}
template
void
G1ParCopyClosure
<
false
,
G1BarrierEvac
,
false
>
::
do_oop_work
(
oop
*
p
);
template
void
G1ParCopyClosure
<
false
,
G1BarrierEvac
,
false
,
true
>
::
do_oop_work
(
oop
*
p
);
template
<
class
T
>
void
G1ParScanPartialArrayClosure
::
process_array_chunk
(
template
<
class
T
>
void
G1ParScanPartialArrayClosure
::
process_array_chunk
(
oop
obj
,
int
start
,
int
end
)
{
oop
obj
,
int
start
,
int
end
)
{
// process our set of indices (include header in first chunk)
// process our set of indices (include header in first chunk)
assert
(
start
<
end
,
"invariant"
);
assert
(
start
<
end
,
"invariant"
);
T
*
const
base
=
(
T
*
)
objArrayOop
(
obj
)
->
base
();
T
*
const
base
=
(
T
*
)
objArrayOop
(
obj
)
->
base
();
T
*
const
start_addr
=
base
+
start
;
T
*
const
start_addr
=
(
start
==
0
)
?
(
T
*
)
obj
:
base
+
start
;
T
*
const
end_addr
=
base
+
end
;
T
*
const
end_addr
=
base
+
end
;
MemRegion
mr
((
HeapWord
*
)
start_addr
,
(
HeapWord
*
)
end_addr
);
MemRegion
mr
((
HeapWord
*
)
start_addr
,
(
HeapWord
*
)
end_addr
);
_scanner
.
set_region
(
_g1
->
heap_region_containing
(
obj
));
_scanner
.
set_region
(
_g1
->
heap_region_containing
(
obj
));
...
@@ -3866,7 +3968,8 @@ template <class T> void G1ParScanPartialArrayClosure::process_array_chunk(
...
@@ -3866,7 +3968,8 @@ template <class T> void G1ParScanPartialArrayClosure::process_array_chunk(
void
G1ParScanPartialArrayClosure
::
do_oop_nv
(
oop
*
p
)
{
void
G1ParScanPartialArrayClosure
::
do_oop_nv
(
oop
*
p
)
{
assert
(
!
UseCompressedOops
,
"Needs to be fixed to work with compressed oops"
);
assert
(
!
UseCompressedOops
,
"Needs to be fixed to work with compressed oops"
);
oop
old
=
oop
((
intptr_t
)
p
&
~
G1_PARTIAL_ARRAY_MASK
);
assert
(
has_partial_array_mask
(
p
),
"invariant"
);
oop
old
=
clear_partial_array_mask
(
p
);
assert
(
old
->
is_objArray
(),
"must be obj array"
);
assert
(
old
->
is_objArray
(),
"must be obj array"
);
assert
(
old
->
is_forwarded
(),
"must be forwarded"
);
assert
(
old
->
is_forwarded
(),
"must be forwarded"
);
assert
(
Universe
::
heap
()
->
is_in_reserved
(
old
),
"must be in heap."
);
assert
(
Universe
::
heap
()
->
is_in_reserved
(
old
),
"must be in heap."
);
...
@@ -3884,7 +3987,7 @@ void G1ParScanPartialArrayClosure::do_oop_nv(oop* p) {
...
@@ -3884,7 +3987,7 @@ void G1ParScanPartialArrayClosure::do_oop_nv(oop* p) {
end
=
start
+
ParGCArrayScanChunk
;
end
=
start
+
ParGCArrayScanChunk
;
arrayOop
(
old
)
->
set_length
(
end
);
arrayOop
(
old
)
->
set_length
(
end
);
// Push remainder.
// Push remainder.
_par_scan_state
->
push_on_queue
(
(
oop
*
)
((
intptr_t
)
old
|
G1_PARTIAL_ARRAY_MASK
));
_par_scan_state
->
push_on_queue
(
set_partial_array_mask
(
old
));
}
else
{
}
else
{
// Restore length so that the heap remains parsable in
// Restore length so that the heap remains parsable in
// case of evacuation failure.
// case of evacuation failure.
...
@@ -3893,11 +3996,6 @@ void G1ParScanPartialArrayClosure::do_oop_nv(oop* p) {
...
@@ -3893,11 +3996,6 @@ void G1ParScanPartialArrayClosure::do_oop_nv(oop* p) {
// process our set of indices (include header in first chunk)
// process our set of indices (include header in first chunk)
process_array_chunk
<
oop
>
(
obj
,
start
,
end
);
process_array_chunk
<
oop
>
(
obj
,
start
,
end
);
oop
*
start_addr
=
start
==
0
?
(
oop
*
)
obj
:
obj
->
obj_at_addr
<
oop
>
(
start
);
oop
*
end_addr
=
(
oop
*
)(
obj
->
base
())
+
end
;
// obj_at_addr(end) asserts end < length
MemRegion
mr
((
HeapWord
*
)
start_addr
,
(
HeapWord
*
)
end_addr
);
_scanner
.
set_region
(
_g1
->
heap_region_containing
(
obj
));
obj
->
oop_iterate
(
&
_scanner
,
mr
);
}
}
int
G1ScanAndBalanceClosure
::
_nq
=
0
;
int
G1ScanAndBalanceClosure
::
_nq
=
0
;
...
@@ -3931,6 +4029,13 @@ public:
...
@@ -3931,6 +4029,13 @@ public:
pss
->
hash_seed
(),
pss
->
hash_seed
(),
ref_to_scan
))
{
ref_to_scan
))
{
IF_G1_DETAILED_STATS
(
pss
->
note_steal
());
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
assert
(
ref_to_scan
!=
NULL
,
"invariant"
);
assert
(
has_partial_array_mask
(
ref_to_scan
)
||
_g1h
->
obj_in_cs
(
*
ref_to_scan
),
"invariant"
);
pss
->
push_on_queue
(
ref_to_scan
);
pss
->
push_on_queue
(
ref_to_scan
);
continue
;
continue
;
}
}
...
@@ -3978,7 +4083,7 @@ public:
...
@@ -3978,7 +4083,7 @@ public:
G1ParScanThreadState
pss
(
_g1h
,
i
);
G1ParScanThreadState
pss
(
_g1h
,
i
);
G1ParScanHeapEvacClosure
scan_evac_cl
(
_g1h
,
&
pss
);
G1ParScanHeapEvacClosure
scan_evac_cl
(
_g1h
,
&
pss
);
G1ParScanHeapEvac
Closure
evac_failure_cl
(
_g1h
,
&
pss
);
G1ParScanHeapEvac
FailureClosure
evac_failure_cl
(
_g1h
,
&
pss
);
G1ParScanPartialArrayClosure
partial_scan_cl
(
_g1h
,
&
pss
);
G1ParScanPartialArrayClosure
partial_scan_cl
(
_g1h
,
&
pss
);
pss
.
set_evac_closure
(
&
scan_evac_cl
);
pss
.
set_evac_closure
(
&
scan_evac_cl
);
...
...
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
浏览文件 @
8b1dc5fb
...
@@ -247,6 +247,27 @@ private:
...
@@ -247,6 +247,27 @@ private:
NumberSeq
_pop_obj_rc_at_copy
;
NumberSeq
_pop_obj_rc_at_copy
;
void
print_popularity_summary_info
()
const
;
void
print_popularity_summary_info
()
const
;
// This is used for a quick test on whether a reference points into
// the collection set or not. Basically, we have an array, with one
// byte per region, and that byte denotes whether the corresponding
// region is in the collection set or not. The entry corresponding
// the bottom of the heap, i.e., region 0, is pointed to by
// _in_cset_fast_test_base. The _in_cset_fast_test field has been
// biased so that it actually points to address 0 of the address
// space, to make the test as fast as possible (we can simply shift
// the address to address into it, instead of having to subtract the
// bottom of the heap from the address before shifting it; basically
// it works in the same way the card table works).
bool
*
_in_cset_fast_test
;
// The allocated array used for the fast test on whether a reference
// points into the collection set or not. This field is also used to
// free the array.
bool
*
_in_cset_fast_test_base
;
// The length of the _in_cset_fast_test_base array.
size_t
_in_cset_fast_test_length
;
volatile
unsigned
_gc_time_stamp
;
volatile
unsigned
_gc_time_stamp
;
size_t
*
_surviving_young_words
;
size_t
*
_surviving_young_words
;
...
@@ -368,6 +389,38 @@ public:
...
@@ -368,6 +389,38 @@ public:
virtual
void
gc_prologue
(
bool
full
);
virtual
void
gc_prologue
(
bool
full
);
virtual
void
gc_epilogue
(
bool
full
);
virtual
void
gc_epilogue
(
bool
full
);
// We register a region with the fast "in collection set" test. We
// simply set to true the array slot corresponding to this region.
void
register_region_with_in_cset_fast_test
(
HeapRegion
*
r
)
{
assert
(
_in_cset_fast_test_base
!=
NULL
,
"sanity"
);
assert
(
r
->
in_collection_set
(),
"invariant"
);
int
index
=
r
->
hrs_index
();
assert
(
0
<=
(
size_t
)
index
&&
(
size_t
)
index
<
_in_cset_fast_test_length
,
"invariant"
);
assert
(
!
_in_cset_fast_test_base
[
index
],
"invariant"
);
_in_cset_fast_test_base
[
index
]
=
true
;
}
// This is a fast test on whether a reference points into the
// collection set or not. It does not assume that the reference
// points into the heap; if it doesn't, it will return false.
bool
in_cset_fast_test
(
oop
obj
)
{
assert
(
_in_cset_fast_test
!=
NULL
,
"sanity"
);
if
(
_g1_committed
.
contains
((
HeapWord
*
)
obj
))
{
// no need to subtract the bottom of the heap from obj,
// _in_cset_fast_test is biased
size_t
index
=
((
size_t
)
obj
)
>>
HeapRegion
::
LogOfHRGrainBytes
;
bool
ret
=
_in_cset_fast_test
[
index
];
// let's make sure the result is consistent with what the slower
// test returns
assert
(
ret
||
!
obj_in_cs
(
obj
),
"sanity"
);
assert
(
!
ret
||
obj_in_cs
(
obj
),
"sanity"
);
return
ret
;
}
else
{
return
false
;
}
}
protected:
protected:
// Shrink the garbage-first heap by at most the given size (in bytes!).
// Shrink the garbage-first heap by at most the given size (in bytes!).
...
...
src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
浏览文件 @
8b1dc5fb
...
@@ -36,8 +36,11 @@ G1CollectedHeap::heap_region_containing(const void* addr) const {
...
@@ -36,8 +36,11 @@ G1CollectedHeap::heap_region_containing(const void* addr) const {
inline
HeapRegion
*
inline
HeapRegion
*
G1CollectedHeap
::
heap_region_containing_raw
(
const
void
*
addr
)
const
{
G1CollectedHeap
::
heap_region_containing_raw
(
const
void
*
addr
)
const
{
HeapRegion
*
res
=
_hrs
->
addr_to_region
(
addr
);
assert
(
_g1_reserved
.
contains
(
addr
),
"invariant"
);
assert
(
res
!=
NULL
,
"addr outside of heap?"
);
size_t
index
=
((
intptr_t
)
addr
-
(
intptr_t
)
_g1_reserved
.
start
())
>>
HeapRegion
::
LogOfHRGrainBytes
;
HeapRegion
*
res
=
_hrs
->
at
(
index
);
assert
(
res
==
_hrs
->
addr_to_region
(
addr
),
"sanity"
);
return
res
;
return
res
;
}
}
...
...
src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
浏览文件 @
8b1dc5fb
...
@@ -2985,6 +2985,7 @@ add_to_collection_set(HeapRegion* hr) {
...
@@ -2985,6 +2985,7 @@ add_to_collection_set(HeapRegion* hr) {
_collection_set
=
hr
;
_collection_set
=
hr
;
_collection_set_size
++
;
_collection_set_size
++
;
_collection_set_bytes_used_before
+=
hr
->
used
();
_collection_set_bytes_used_before
+=
hr
->
used
();
_g1
->
register_region_with_in_cset_fast_test
(
hr
);
}
}
void
void
...
...
src/share/vm/gc_implementation/g1/g1OopClosures.hpp
浏览文件 @
8b1dc5fb
...
@@ -77,6 +77,18 @@ public:
...
@@ -77,6 +77,18 @@ public:
#define G1_PARTIAL_ARRAY_MASK 1
#define G1_PARTIAL_ARRAY_MASK 1
inline
bool
has_partial_array_mask
(
oop
*
ref
)
{
return
(
intptr_t
)
ref
&
G1_PARTIAL_ARRAY_MASK
;
}
inline
oop
*
set_partial_array_mask
(
oop
obj
)
{
return
(
oop
*
)
((
intptr_t
)
obj
|
G1_PARTIAL_ARRAY_MASK
);
}
inline
oop
clear_partial_array_mask
(
oop
*
ref
)
{
return
oop
((
intptr_t
)
ref
&
~
G1_PARTIAL_ARRAY_MASK
);
}
class
G1ParScanPartialArrayClosure
:
public
G1ParClosureSuper
{
class
G1ParScanPartialArrayClosure
:
public
G1ParClosureSuper
{
G1ParScanClosure
_scanner
;
G1ParScanClosure
_scanner
;
template
<
class
T
>
void
process_array_chunk
(
oop
obj
,
int
start
,
int
end
);
template
<
class
T
>
void
process_array_chunk
(
oop
obj
,
int
start
,
int
end
);
...
@@ -101,7 +113,8 @@ public:
...
@@ -101,7 +113,8 @@ public:
G1ParClosureSuper
(
g1
,
par_scan_state
),
_scanner
(
scanner
)
{
}
G1ParClosureSuper
(
g1
,
par_scan_state
),
_scanner
(
scanner
)
{
}
};
};
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_forwardee
>
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_forwardee
,
bool
skip_cset_test
>
class
G1ParCopyClosure
:
public
G1ParCopyHelper
{
class
G1ParCopyClosure
:
public
G1ParCopyHelper
{
G1ParScanClosure
_scanner
;
G1ParScanClosure
_scanner
;
void
do_oop_work
(
oop
*
p
);
void
do_oop_work
(
oop
*
p
);
...
@@ -119,14 +132,22 @@ public:
...
@@ -119,14 +132,22 @@ public:
virtual
void
do_oop
(
narrowOop
*
p
)
{
do_oop_nv
(
p
);
}
virtual
void
do_oop
(
narrowOop
*
p
)
{
do_oop_nv
(
p
);
}
};
};
typedef
G1ParCopyClosure
<
false
,
G1BarrierNone
,
false
>
G1ParScanExtRootClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierNone
,
false
,
false
>
G1ParScanExtRootClosure
;
typedef
G1ParCopyClosure
<
true
,
G1BarrierNone
,
false
>
G1ParScanPermClosure
;
typedef
G1ParCopyClosure
<
true
,
G1BarrierNone
,
false
,
false
>
G1ParScanPermClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierNone
,
true
>
G1ParScanAndMarkExtRootClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierNone
,
true
,
false
>
G1ParScanAndMarkExtRootClosure
;
typedef
G1ParCopyClosure
<
true
,
G1BarrierNone
,
true
>
G1ParScanAndMarkPermClosure
;
typedef
G1ParCopyClosure
<
true
,
G1BarrierNone
,
true
,
false
>
G1ParScanAndMarkPermClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierRS
,
false
>
G1ParScanHeapRSClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierRS
,
false
,
false
>
G1ParScanHeapRSClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierRS
,
true
>
G1ParScanAndMarkHeapRSClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierRS
,
true
,
false
>
G1ParScanAndMarkHeapRSClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierEvac
,
false
>
G1ParScanHeapEvacClosure
;
// This is the only case when we set skip_cset_test. Basically, this
// closure is (should?) only be called directly while we're draining
// the overflow and task queues. In that case we know that the
// reference in question points into the collection set, otherwise we
// would not have pushed it on the queue.
typedef
G1ParCopyClosure
<
false
,
G1BarrierEvac
,
false
,
true
>
G1ParScanHeapEvacClosure
;
// We need a separate closure to handle references during evacuation
// failure processing, as it cannot asume that the reference already
// points to the collection set (like G1ParScanHeapEvacClosure does).
typedef
G1ParCopyClosure
<
false
,
G1BarrierEvac
,
false
,
false
>
G1ParScanHeapEvacFailureClosure
;
class
FilterIntoCSClosure
:
public
OopClosure
{
class
FilterIntoCSClosure
:
public
OopClosure
{
G1CollectedHeap
*
_g1
;
G1CollectedHeap
*
_g1
;
...
...
src/share/vm/gc_implementation/g1/g1_globals.hpp
浏览文件 @
8b1dc5fb
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
#define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw) \
#define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw) \
\
\
product(intx, ParallelGCG1AllocBufferSize,
4
*K, \
product(intx, ParallelGCG1AllocBufferSize,
8
*K, \
"Size of parallel G1 allocation buffers in to-space.") \
"Size of parallel G1 allocation buffers in to-space.") \
\
\
product(intx, G1TimeSliceMS, 500, \
product(intx, G1TimeSliceMS, 500, \
...
...
src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp
浏览文件 @
8b1dc5fb
...
@@ -32,11 +32,13 @@ enum G1Barrier {
...
@@ -32,11 +32,13 @@ enum G1Barrier {
G1BarrierNone
,
G1BarrierRS
,
G1BarrierEvac
G1BarrierNone
,
G1BarrierRS
,
G1BarrierEvac
};
};
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_forwardee
>
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_forwardee
,
bool
skip_cset_test
>
class
G1ParCopyClosure
;
class
G1ParCopyClosure
;
class
G1ParScanClosure
;
class
G1ParScanClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierEvac
,
false
>
G1ParScanHeapEvacClosure
;
typedef
G1ParCopyClosure
<
false
,
G1BarrierEvac
,
false
,
true
>
G1ParScanHeapEvacClosure
;
class
FilterIntoCSClosure
;
class
FilterIntoCSClosure
;
class
FilterOutOfRegionClosure
;
class
FilterOutOfRegionClosure
;
...
...
src/share/vm/gc_implementation/includeDB_gc_g1
浏览文件 @
8b1dc5fb
...
@@ -31,7 +31,7 @@ bufferingOopClosure.hpp os.hpp
...
@@ -31,7 +31,7 @@ bufferingOopClosure.hpp os.hpp
cardTableRS.cpp concurrentMark.hpp
cardTableRS.cpp concurrentMark.hpp
cardTableRS.cpp g1SATBCardTableModRefBS.hpp
cardTableRS.cpp g1SATBCardTableModRefBS.hpp
collectionSetChooser.cpp g1CollectedHeap.hpp
collectionSetChooser.cpp g1CollectedHeap.
inline.
hpp
collectionSetChooser.cpp g1CollectorPolicy.hpp
collectionSetChooser.cpp g1CollectorPolicy.hpp
collectionSetChooser.cpp collectionSetChooser.hpp
collectionSetChooser.cpp collectionSetChooser.hpp
...
@@ -42,14 +42,14 @@ concurrentG1Refine.cpp atomic.hpp
...
@@ -42,14 +42,14 @@ concurrentG1Refine.cpp atomic.hpp
concurrentG1Refine.cpp concurrentG1Refine.hpp
concurrentG1Refine.cpp concurrentG1Refine.hpp
concurrentG1Refine.cpp concurrentG1RefineThread.hpp
concurrentG1Refine.cpp concurrentG1RefineThread.hpp
concurrentG1Refine.cpp copy.hpp
concurrentG1Refine.cpp copy.hpp
concurrentG1Refine.cpp g1CollectedHeap.hpp
concurrentG1Refine.cpp g1CollectedHeap.
inline.
hpp
concurrentG1Refine.cpp g1RemSet.hpp
concurrentG1Refine.cpp g1RemSet.hpp
concurrentG1Refine.hpp globalDefinitions.hpp
concurrentG1Refine.hpp globalDefinitions.hpp
concurrentG1RefineThread.cpp concurrentG1Refine.hpp
concurrentG1RefineThread.cpp concurrentG1Refine.hpp
concurrentG1RefineThread.cpp concurrentG1RefineThread.hpp
concurrentG1RefineThread.cpp concurrentG1RefineThread.hpp
concurrentG1RefineThread.cpp g1CollectedHeap.hpp
concurrentG1RefineThread.cpp g1CollectedHeap.
inline.
hpp
concurrentG1RefineThread.cpp g1CollectorPolicy.hpp
concurrentG1RefineThread.cpp g1CollectorPolicy.hpp
concurrentG1RefineThread.cpp handles.inline.hpp
concurrentG1RefineThread.cpp handles.inline.hpp
concurrentG1RefineThread.cpp mutexLocker.hpp
concurrentG1RefineThread.cpp mutexLocker.hpp
...
@@ -166,7 +166,7 @@ g1CollectorPolicy.cpp concurrentMark.hpp
...
@@ -166,7 +166,7 @@ g1CollectorPolicy.cpp concurrentMark.hpp
g1CollectorPolicy.cpp concurrentMarkThread.inline.hpp
g1CollectorPolicy.cpp concurrentMarkThread.inline.hpp
g1CollectorPolicy.cpp debug.hpp
g1CollectorPolicy.cpp debug.hpp
g1CollectorPolicy.cpp java.hpp
g1CollectorPolicy.cpp java.hpp
g1CollectorPolicy.cpp g1CollectedHeap.hpp
g1CollectorPolicy.cpp g1CollectedHeap.
inline.
hpp
g1CollectorPolicy.cpp g1CollectorPolicy.hpp
g1CollectorPolicy.cpp g1CollectorPolicy.hpp
g1CollectorPolicy.cpp heapRegionRemSet.hpp
g1CollectorPolicy.cpp heapRegionRemSet.hpp
g1CollectorPolicy.cpp mutexLocker.hpp
g1CollectorPolicy.cpp mutexLocker.hpp
...
@@ -187,7 +187,7 @@ g1MarkSweep.cpp biasedLocking.hpp
...
@@ -187,7 +187,7 @@ g1MarkSweep.cpp biasedLocking.hpp
g1MarkSweep.cpp codeCache.hpp
g1MarkSweep.cpp codeCache.hpp
g1MarkSweep.cpp events.hpp
g1MarkSweep.cpp events.hpp
g1MarkSweep.cpp fprofiler.hpp
g1MarkSweep.cpp fprofiler.hpp
g1MarkSweep.hpp g1CollectedHeap.hpp
g1MarkSweep.hpp g1CollectedHeap.
inline.
hpp
g1MarkSweep.cpp g1MarkSweep.hpp
g1MarkSweep.cpp g1MarkSweep.hpp
g1MarkSweep.cpp gcLocker.hpp
g1MarkSweep.cpp gcLocker.hpp
g1MarkSweep.cpp genCollectedHeap.hpp
g1MarkSweep.cpp genCollectedHeap.hpp
...
@@ -283,7 +283,7 @@ heapRegionRemSet.cpp globalDefinitions.hpp
...
@@ -283,7 +283,7 @@ heapRegionRemSet.cpp globalDefinitions.hpp
heapRegionRemSet.cpp space.inline.hpp
heapRegionRemSet.cpp space.inline.hpp
heapRegionSeq.cpp allocation.hpp
heapRegionSeq.cpp allocation.hpp
heapRegionSeq.cpp g1CollectedHeap.hpp
heapRegionSeq.cpp g1CollectedHeap.
inline.
hpp
heapRegionSeq.cpp heapRegionSeq.hpp
heapRegionSeq.cpp heapRegionSeq.hpp
heapRegionSeq.hpp growableArray.hpp
heapRegionSeq.hpp growableArray.hpp
...
@@ -334,18 +334,18 @@ specialized_oop_closures.hpp g1_specialized_oop_closures.hpp
...
@@ -334,18 +334,18 @@ specialized_oop_closures.hpp g1_specialized_oop_closures.hpp
survRateGroup.hpp numberSeq.hpp
survRateGroup.hpp numberSeq.hpp
survRateGroup.cpp allocation.hpp
survRateGroup.cpp allocation.hpp
survRateGroup.cpp g1CollectedHeap.hpp
survRateGroup.cpp g1CollectedHeap.
inline.
hpp
survRateGroup.cpp g1CollectorPolicy.hpp
survRateGroup.cpp g1CollectorPolicy.hpp
survRateGroup.cpp heapRegion.hpp
survRateGroup.cpp heapRegion.hpp
survRateGroup.cpp survRateGroup.hpp
survRateGroup.cpp survRateGroup.hpp
thread.cpp concurrentMarkThread.inline.hpp
thread.cpp concurrentMarkThread.inline.hpp
universe.cpp g1CollectedHeap.hpp
universe.cpp g1CollectedHeap.
inline.
hpp
universe.cpp g1CollectorPolicy.hpp
universe.cpp g1CollectorPolicy.hpp
vm_operations_g1.hpp vmGCOperations.hpp
vm_operations_g1.hpp vmGCOperations.hpp
vm_operations_g1.cpp vm_operations_g1.hpp
vm_operations_g1.cpp vm_operations_g1.hpp
vm_operations_g1.cpp g1CollectedHeap.hpp
vm_operations_g1.cpp g1CollectedHeap.
inline.
hpp
vm_operations_g1.cpp isGCActiveMark.hpp
vm_operations_g1.cpp isGCActiveMark.hpp
src/share/vm/gc_implementation/includeDB_gc_shared
浏览文件 @
8b1dc5fb
...
@@ -100,4 +100,4 @@ spaceCounters.hpp mutableSpace.hpp
...
@@ -100,4 +100,4 @@ spaceCounters.hpp mutableSpace.hpp
spaceCounters.hpp perfData.hpp
spaceCounters.hpp perfData.hpp
spaceCounters.hpp generationCounters.hpp
spaceCounters.hpp generationCounters.hpp
vmGCOperations.cpp g1CollectedHeap.hpp
vmGCOperations.cpp g1CollectedHeap.
inline.
hpp
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录