Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
2c61150c
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看板
提交
2c61150c
编写于
4月 25, 2012
作者:
J
jmasa
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
7b83234d
72a17806
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
620 addition
and
620 deletion
+620
-620
src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
...entation/concurrentMarkSweep/compactibleFreeListSpace.cpp
+147
-147
src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
...entation/concurrentMarkSweep/compactibleFreeListSpace.hpp
+2
-2
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
...ion/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+27
-27
src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp
...re/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp
+12
-12
src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp
...m/gc_implementation/concurrentMarkSweep/promotionInfo.cpp
+1
-1
src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp
...m/gc_implementation/concurrentMarkSweep/promotionInfo.hpp
+9
-9
src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
...m/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
+1
-1
src/share/vm/gc_implementation/shared/allocationStats.hpp
src/share/vm/gc_implementation/shared/allocationStats.hpp
+45
-45
src/share/vm/memory/binaryTreeDictionary.cpp
src/share/vm/memory/binaryTreeDictionary.cpp
+195
-195
src/share/vm/memory/binaryTreeDictionary.hpp
src/share/vm/memory/binaryTreeDictionary.hpp
+68
-68
src/share/vm/memory/freeBlockDictionary.cpp
src/share/vm/memory/freeBlockDictionary.cpp
+2
-2
src/share/vm/memory/freeBlockDictionary.hpp
src/share/vm/memory/freeBlockDictionary.hpp
+19
-19
src/share/vm/memory/freeList.cpp
src/share/vm/memory/freeList.cpp
+38
-38
src/share/vm/memory/freeList.hpp
src/share/vm/memory/freeList.hpp
+54
-54
未找到文件。
src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
浏览文件 @
2c61150c
...
@@ -119,7 +119,7 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
...
@@ -119,7 +119,7 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
// moved to its new location before the klass is moved.
// moved to its new location before the klass is moved.
// Set the _refillSize for the linear allocation blocks
// Set the _refillSize for the linear allocation blocks
if
(
!
use_adaptive_freelists
)
{
if
(
!
use_adaptive_freelists
)
{
FreeChunk
*
fc
=
_dictionary
->
get
C
hunk
(
mr
.
word_size
());
FreeChunk
*
fc
=
_dictionary
->
get
_c
hunk
(
mr
.
word_size
());
// The small linAB initially has all the space and will allocate
// The small linAB initially has all the space and will allocate
// a chunk of any size.
// a chunk of any size.
HeapWord
*
addr
=
(
HeapWord
*
)
fc
;
HeapWord
*
addr
=
(
HeapWord
*
)
fc
;
...
@@ -275,12 +275,12 @@ void CompactibleFreeListSpace::reset(MemRegion mr) {
...
@@ -275,12 +275,12 @@ void CompactibleFreeListSpace::reset(MemRegion mr) {
assert
(
mr
.
word_size
()
>=
MinChunkSize
,
"Chunk size is too small"
);
assert
(
mr
.
word_size
()
>=
MinChunkSize
,
"Chunk size is too small"
);
_bt
.
single_block
(
mr
.
start
(),
mr
.
word_size
());
_bt
.
single_block
(
mr
.
start
(),
mr
.
word_size
());
FreeChunk
*
fc
=
(
FreeChunk
*
)
mr
.
start
();
FreeChunk
*
fc
=
(
FreeChunk
*
)
mr
.
start
();
fc
->
set
S
ize
(
mr
.
word_size
());
fc
->
set
_s
ize
(
mr
.
word_size
());
if
(
mr
.
word_size
()
>=
IndexSetSize
)
{
if
(
mr
.
word_size
()
>=
IndexSetSize
)
{
returnChunkToDictionary
(
fc
);
returnChunkToDictionary
(
fc
);
}
else
{
}
else
{
_bt
.
verify_not_unallocated
((
HeapWord
*
)
fc
,
fc
->
size
());
_bt
.
verify_not_unallocated
((
HeapWord
*
)
fc
,
fc
->
size
());
_indexedFreeList
[
mr
.
word_size
()].
return
ChunkAtH
ead
(
fc
);
_indexedFreeList
[
mr
.
word_size
()].
return
_chunk_at_h
ead
(
fc
);
}
}
}
}
_promoInfo
.
reset
();
_promoInfo
.
reset
();
...
@@ -298,7 +298,7 @@ void CompactibleFreeListSpace::reset_after_compaction() {
...
@@ -298,7 +298,7 @@ void CompactibleFreeListSpace::reset_after_compaction() {
}
else
{
}
else
{
// Place as much of mr in the linAB as we can get,
// Place as much of mr in the linAB as we can get,
// provided it was big enough to go into the dictionary.
// provided it was big enough to go into the dictionary.
FreeChunk
*
fc
=
dictionary
()
->
find
LargestD
ict
();
FreeChunk
*
fc
=
dictionary
()
->
find
_largest_d
ict
();
if
(
fc
!=
NULL
)
{
if
(
fc
!=
NULL
)
{
assert
(
fc
->
size
()
==
mr
.
word_size
(),
assert
(
fc
->
size
()
==
mr
.
word_size
(),
"Why was the chunk broken up?"
);
"Why was the chunk broken up?"
);
...
@@ -325,14 +325,14 @@ FreeChunk* CompactibleFreeListSpace::find_chunk_at_end() {
...
@@ -325,14 +325,14 @@ FreeChunk* CompactibleFreeListSpace::find_chunk_at_end() {
#ifndef PRODUCT
#ifndef PRODUCT
void
CompactibleFreeListSpace
::
initializeIndexedFreeListArrayReturnedBytes
()
{
void
CompactibleFreeListSpace
::
initializeIndexedFreeListArrayReturnedBytes
()
{
for
(
size_t
i
=
IndexSetStart
;
i
<
IndexSetSize
;
i
+=
IndexSetStride
)
{
for
(
size_t
i
=
IndexSetStart
;
i
<
IndexSetSize
;
i
+=
IndexSetStride
)
{
_indexedFreeList
[
i
].
allocation_stats
()
->
set_returned
B
ytes
(
0
);
_indexedFreeList
[
i
].
allocation_stats
()
->
set_returned
_b
ytes
(
0
);
}
}
}
}
size_t
CompactibleFreeListSpace
::
sumIndexedFreeListArrayReturnedBytes
()
{
size_t
CompactibleFreeListSpace
::
sumIndexedFreeListArrayReturnedBytes
()
{
size_t
sum
=
0
;
size_t
sum
=
0
;
for
(
size_t
i
=
IndexSetStart
;
i
<
IndexSetSize
;
i
+=
IndexSetStride
)
{
for
(
size_t
i
=
IndexSetStart
;
i
<
IndexSetSize
;
i
+=
IndexSetStride
)
{
sum
+=
_indexedFreeList
[
i
].
allocation_stats
()
->
returned
B
ytes
();
sum
+=
_indexedFreeList
[
i
].
allocation_stats
()
->
returned
_b
ytes
();
}
}
return
sum
;
return
sum
;
}
}
...
@@ -356,7 +356,7 @@ size_t CompactibleFreeListSpace::totalCountInIndexedFreeLists() const {
...
@@ -356,7 +356,7 @@ size_t CompactibleFreeListSpace::totalCountInIndexedFreeLists() const {
size_t
CompactibleFreeListSpace
::
totalCount
()
{
size_t
CompactibleFreeListSpace
::
totalCount
()
{
size_t
num
=
totalCountInIndexedFreeLists
();
size_t
num
=
totalCountInIndexedFreeLists
();
num
+=
dictionary
()
->
total
C
ount
();
num
+=
dictionary
()
->
total
_c
ount
();
if
(
_smallLinearAllocBlock
.
_word_size
!=
0
)
{
if
(
_smallLinearAllocBlock
.
_word_size
!=
0
)
{
num
++
;
num
++
;
}
}
...
@@ -366,7 +366,7 @@ size_t CompactibleFreeListSpace::totalCount() {
...
@@ -366,7 +366,7 @@ size_t CompactibleFreeListSpace::totalCount() {
bool
CompactibleFreeListSpace
::
is_free_block
(
const
HeapWord
*
p
)
const
{
bool
CompactibleFreeListSpace
::
is_free_block
(
const
HeapWord
*
p
)
const
{
FreeChunk
*
fc
=
(
FreeChunk
*
)
p
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
p
;
return
fc
->
is
F
ree
();
return
fc
->
is
_f
ree
();
}
}
size_t
CompactibleFreeListSpace
::
used
()
const
{
size_t
CompactibleFreeListSpace
::
used
()
const
{
...
@@ -393,7 +393,7 @@ size_t CompactibleFreeListSpace::free() const {
...
@@ -393,7 +393,7 @@ size_t CompactibleFreeListSpace::free() const {
// that supports jvmstat, and you are apt to see the values
// that supports jvmstat, and you are apt to see the values
// flicker in such cases.
// flicker in such cases.
assert
(
_dictionary
!=
NULL
,
"No _dictionary?"
);
assert
(
_dictionary
!=
NULL
,
"No _dictionary?"
);
return
(
_dictionary
->
total
ChunkS
ize
(
DEBUG_ONLY
(
freelistLock
()))
+
return
(
_dictionary
->
total
_chunk_s
ize
(
DEBUG_ONLY
(
freelistLock
()))
+
totalSizeInIndexedFreeLists
()
+
totalSizeInIndexedFreeLists
()
+
_smallLinearAllocBlock
.
_word_size
)
*
HeapWordSize
;
_smallLinearAllocBlock
.
_word_size
)
*
HeapWordSize
;
}
}
...
@@ -401,7 +401,7 @@ size_t CompactibleFreeListSpace::free() const {
...
@@ -401,7 +401,7 @@ size_t CompactibleFreeListSpace::free() const {
size_t
CompactibleFreeListSpace
::
max_alloc_in_words
()
const
{
size_t
CompactibleFreeListSpace
::
max_alloc_in_words
()
const
{
assert
(
_dictionary
!=
NULL
,
"No _dictionary?"
);
assert
(
_dictionary
!=
NULL
,
"No _dictionary?"
);
assert_locked
();
assert_locked
();
size_t
res
=
_dictionary
->
max
ChunkS
ize
();
size_t
res
=
_dictionary
->
max
_chunk_s
ize
();
res
=
MAX2
(
res
,
MIN2
(
_smallLinearAllocBlock
.
_word_size
,
res
=
MAX2
(
res
,
MIN2
(
_smallLinearAllocBlock
.
_word_size
,
(
size_t
)
SmallForLinearAlloc
-
1
));
(
size_t
)
SmallForLinearAlloc
-
1
));
// XXX the following could potentially be pretty slow;
// XXX the following could potentially be pretty slow;
...
@@ -469,7 +469,7 @@ const {
...
@@ -469,7 +469,7 @@ const {
void
CompactibleFreeListSpace
::
print_dictionary_free_lists
(
outputStream
*
st
)
void
CompactibleFreeListSpace
::
print_dictionary_free_lists
(
outputStream
*
st
)
const
{
const
{
_dictionary
->
report
S
tatistics
();
_dictionary
->
report
_s
tatistics
();
st
->
print_cr
(
"Layout of Freelists in Tree"
);
st
->
print_cr
(
"Layout of Freelists in Tree"
);
st
->
print_cr
(
"---------------------------"
);
st
->
print_cr
(
"---------------------------"
);
_dictionary
->
print_free_lists
(
st
);
_dictionary
->
print_free_lists
(
st
);
...
@@ -547,12 +547,12 @@ void CompactibleFreeListSpace::dump_at_safepoint_with_locks(CMSCollector* c,
...
@@ -547,12 +547,12 @@ void CompactibleFreeListSpace::dump_at_safepoint_with_locks(CMSCollector* c,
void
CompactibleFreeListSpace
::
reportFreeListStatistics
()
const
{
void
CompactibleFreeListSpace
::
reportFreeListStatistics
()
const
{
assert_lock_strong
(
&
_freelistLock
);
assert_lock_strong
(
&
_freelistLock
);
assert
(
PrintFLSStatistics
!=
0
,
"Reporting error"
);
assert
(
PrintFLSStatistics
!=
0
,
"Reporting error"
);
_dictionary
->
report
S
tatistics
();
_dictionary
->
report
_s
tatistics
();
if
(
PrintFLSStatistics
>
1
)
{
if
(
PrintFLSStatistics
>
1
)
{
reportIndexedFreeListStatistics
();
reportIndexedFreeListStatistics
();
size_t
total
S
ize
=
totalSizeInIndexedFreeLists
()
+
size_t
total
_s
ize
=
totalSizeInIndexedFreeLists
()
+
_dictionary
->
total
ChunkS
ize
(
DEBUG_ONLY
(
freelistLock
()));
_dictionary
->
total
_chunk_s
ize
(
DEBUG_ONLY
(
freelistLock
()));
gclog_or_tty
->
print
(
" free=%ld frag=%1.4f
\n
"
,
total
S
ize
,
flsFrag
());
gclog_or_tty
->
print
(
" free=%ld frag=%1.4f
\n
"
,
total
_s
ize
,
flsFrag
());
}
}
}
}
...
@@ -560,13 +560,13 @@ void CompactibleFreeListSpace::reportIndexedFreeListStatistics() const {
...
@@ -560,13 +560,13 @@ void CompactibleFreeListSpace::reportIndexedFreeListStatistics() const {
assert_lock_strong
(
&
_freelistLock
);
assert_lock_strong
(
&
_freelistLock
);
gclog_or_tty
->
print
(
"Statistics for IndexedFreeLists:
\n
"
gclog_or_tty
->
print
(
"Statistics for IndexedFreeLists:
\n
"
"--------------------------------
\n
"
);
"--------------------------------
\n
"
);
size_t
total
S
ize
=
totalSizeInIndexedFreeLists
();
size_t
total
_s
ize
=
totalSizeInIndexedFreeLists
();
size_t
free
B
locks
=
numFreeBlocksInIndexedFreeLists
();
size_t
free
_b
locks
=
numFreeBlocksInIndexedFreeLists
();
gclog_or_tty
->
print
(
"Total Free Space: %d
\n
"
,
total
S
ize
);
gclog_or_tty
->
print
(
"Total Free Space: %d
\n
"
,
total
_s
ize
);
gclog_or_tty
->
print
(
"Max Chunk Size: %d
\n
"
,
maxChunkSizeInIndexedFreeLists
());
gclog_or_tty
->
print
(
"Max Chunk Size: %d
\n
"
,
maxChunkSizeInIndexedFreeLists
());
gclog_or_tty
->
print
(
"Number of Blocks: %d
\n
"
,
free
B
locks
);
gclog_or_tty
->
print
(
"Number of Blocks: %d
\n
"
,
free
_b
locks
);
if
(
free
B
locks
!=
0
)
{
if
(
free
_b
locks
!=
0
)
{
gclog_or_tty
->
print
(
"Av. Block Size: %d
\n
"
,
total
Size
/
freeB
locks
);
gclog_or_tty
->
print
(
"Av. Block Size: %d
\n
"
,
total
_size
/
free_b
locks
);
}
}
}
}
...
@@ -913,7 +913,7 @@ CompactibleFreeListSpace::object_iterate_careful(ObjectClosureCareful* cl) {
...
@@ -913,7 +913,7 @@ CompactibleFreeListSpace::object_iterate_careful(ObjectClosureCareful* cl) {
for
(
addr
=
bottom
(),
last
=
end
();
for
(
addr
=
bottom
(),
last
=
end
();
addr
<
last
;
addr
+=
size
)
{
addr
<
last
;
addr
+=
size
)
{
FreeChunk
*
fc
=
(
FreeChunk
*
)
addr
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
addr
;
if
(
fc
->
is
F
ree
())
{
if
(
fc
->
is
_f
ree
())
{
// Since we hold the free list lock, which protects direct
// Since we hold the free list lock, which protects direct
// allocation in this generation by mutators, a free object
// allocation in this generation by mutators, a free object
// will remain free throughout this iteration code.
// will remain free throughout this iteration code.
...
@@ -955,7 +955,7 @@ CompactibleFreeListSpace::object_iterate_careful_m(MemRegion mr,
...
@@ -955,7 +955,7 @@ CompactibleFreeListSpace::object_iterate_careful_m(MemRegion mr,
for
(
addr
=
block_start_careful
(
mr
.
start
()),
end
=
mr
.
end
();
for
(
addr
=
block_start_careful
(
mr
.
start
()),
end
=
mr
.
end
();
addr
<
end
;
addr
+=
size
)
{
addr
<
end
;
addr
+=
size
)
{
FreeChunk
*
fc
=
(
FreeChunk
*
)
addr
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
addr
;
if
(
fc
->
is
F
ree
())
{
if
(
fc
->
is
_f
ree
())
{
// Since we hold the free list lock, which protects direct
// Since we hold the free list lock, which protects direct
// allocation in this generation by mutators, a free object
// allocation in this generation by mutators, a free object
// will remain free throughout this iteration code.
// will remain free throughout this iteration code.
...
@@ -1071,7 +1071,7 @@ size_t CompactibleFreeListSpace::block_size_nopar(const HeapWord* p) const {
...
@@ -1071,7 +1071,7 @@ size_t CompactibleFreeListSpace::block_size_nopar(const HeapWord* p) const {
NOT_PRODUCT
(
verify_objects_initialized
());
NOT_PRODUCT
(
verify_objects_initialized
());
assert
(
MemRegion
(
bottom
(),
end
()).
contains
(
p
),
"p not in space"
);
assert
(
MemRegion
(
bottom
(),
end
()).
contains
(
p
),
"p not in space"
);
FreeChunk
*
fc
=
(
FreeChunk
*
)
p
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
p
;
if
(
fc
->
is
F
ree
())
{
if
(
fc
->
is
_f
ree
())
{
return
fc
->
size
();
return
fc
->
size
();
}
else
{
}
else
{
// Ignore mark word because this may be a recently promoted
// Ignore mark word because this may be a recently promoted
...
@@ -1162,7 +1162,7 @@ bool CompactibleFreeListSpace::block_is_obj_nopar(const HeapWord* p) const {
...
@@ -1162,7 +1162,7 @@ bool CompactibleFreeListSpace::block_is_obj_nopar(const HeapWord* p) const {
FreeChunk
*
fc
=
(
FreeChunk
*
)
p
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
p
;
assert
(
is_in_reserved
(
p
),
"Should be in space"
);
assert
(
is_in_reserved
(
p
),
"Should be in space"
);
assert
(
_bt
.
block_start
(
p
)
==
p
,
"Should be a block boundary"
);
assert
(
_bt
.
block_start
(
p
)
==
p
,
"Should be a block boundary"
);
if
(
!
fc
->
is
F
ree
())
{
if
(
!
fc
->
is
_f
ree
())
{
// Ignore mark word because it may have been used to
// Ignore mark word because it may have been used to
// chain together promoted objects (the last one
// chain together promoted objects (the last one
// would have a null value).
// would have a null value).
...
@@ -1224,7 +1224,7 @@ HeapWord* CompactibleFreeListSpace::allocate(size_t size) {
...
@@ -1224,7 +1224,7 @@ HeapWord* CompactibleFreeListSpace::allocate(size_t size) {
FreeChunk
*
fc
=
(
FreeChunk
*
)
res
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
res
;
fc
->
markNotFree
();
fc
->
markNotFree
();
assert
(
!
fc
->
is
F
ree
(),
"shouldn't be marked free"
);
assert
(
!
fc
->
is
_f
ree
(),
"shouldn't be marked free"
);
assert
(
oop
(
fc
)
->
klass_or_null
()
==
NULL
,
"should look uninitialized"
);
assert
(
oop
(
fc
)
->
klass_or_null
()
==
NULL
,
"should look uninitialized"
);
// Verify that the block offset table shows this to
// Verify that the block offset table shows this to
// be a single block, but not one which is unallocated.
// be a single block, but not one which is unallocated.
...
@@ -1336,7 +1336,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) {
...
@@ -1336,7 +1336,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) {
FreeList
<
FreeChunk
>*
fl
=
&
_indexedFreeList
[
i
];
FreeList
<
FreeChunk
>*
fl
=
&
_indexedFreeList
[
i
];
if
(
fl
->
head
())
{
if
(
fl
->
head
())
{
ret
=
getFromListGreater
(
fl
,
numWords
);
ret
=
getFromListGreater
(
fl
,
numWords
);
assert
(
ret
==
NULL
||
ret
->
is
F
ree
(),
"Should be returning a free chunk"
);
assert
(
ret
==
NULL
||
ret
->
is
_f
ree
(),
"Should be returning a free chunk"
);
return
ret
;
return
ret
;
}
}
}
}
...
@@ -1347,7 +1347,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) {
...
@@ -1347,7 +1347,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) {
/* Try to get a chunk that satisfies request, while avoiding
/* Try to get a chunk that satisfies request, while avoiding
fragmentation that can't be handled. */
fragmentation that can't be handled. */
{
{
ret
=
dictionary
()
->
get
C
hunk
(
currSize
);
ret
=
dictionary
()
->
get
_c
hunk
(
currSize
);
if
(
ret
!=
NULL
)
{
if
(
ret
!=
NULL
)
{
assert
(
ret
->
size
()
-
numWords
>=
MinChunkSize
,
assert
(
ret
->
size
()
-
numWords
>=
MinChunkSize
,
"Chunk is too small"
);
"Chunk is too small"
);
...
@@ -1355,10 +1355,10 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) {
...
@@ -1355,10 +1355,10 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) {
/* Carve returned chunk. */
/* Carve returned chunk. */
(
void
)
splitChunkAndReturnRemainder
(
ret
,
numWords
);
(
void
)
splitChunkAndReturnRemainder
(
ret
,
numWords
);
/* Label this as no longer a free chunk. */
/* Label this as no longer a free chunk. */
assert
(
ret
->
is
F
ree
(),
"This chunk should be free"
);
assert
(
ret
->
is
_f
ree
(),
"This chunk should be free"
);
ret
->
link
P
rev
(
NULL
);
ret
->
link
_p
rev
(
NULL
);
}
}
assert
(
ret
==
NULL
||
ret
->
is
F
ree
(),
"Should be returning a free chunk"
);
assert
(
ret
==
NULL
||
ret
->
is
_f
ree
(),
"Should be returning a free chunk"
);
return
ret
;
return
ret
;
}
}
ShouldNotReachHere
();
ShouldNotReachHere
();
...
@@ -1366,7 +1366,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) {
...
@@ -1366,7 +1366,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) {
bool
CompactibleFreeListSpace
::
verifyChunkInIndexedFreeLists
(
FreeChunk
*
fc
)
const
{
bool
CompactibleFreeListSpace
::
verifyChunkInIndexedFreeLists
(
FreeChunk
*
fc
)
const
{
assert
(
fc
->
size
()
<
IndexSetSize
,
"Size of chunk is too large"
);
assert
(
fc
->
size
()
<
IndexSetSize
,
"Size of chunk is too large"
);
return
_indexedFreeList
[
fc
->
size
()].
verify
ChunkInFreeLists
(
fc
);
return
_indexedFreeList
[
fc
->
size
()].
verify
_chunk_in_free_list
(
fc
);
}
}
bool
CompactibleFreeListSpace
::
verify_chunk_is_linear_alloc_block
(
FreeChunk
*
fc
)
const
{
bool
CompactibleFreeListSpace
::
verify_chunk_is_linear_alloc_block
(
FreeChunk
*
fc
)
const
{
...
@@ -1380,13 +1380,13 @@ bool CompactibleFreeListSpace::verify_chunk_is_linear_alloc_block(FreeChunk* fc)
...
@@ -1380,13 +1380,13 @@ bool CompactibleFreeListSpace::verify_chunk_is_linear_alloc_block(FreeChunk* fc)
// Check if the purported free chunk is present either as a linear
// Check if the purported free chunk is present either as a linear
// allocation block, the size-indexed table of (smaller) free blocks,
// allocation block, the size-indexed table of (smaller) free blocks,
// or the larger free blocks kept in the binary tree dictionary.
// or the larger free blocks kept in the binary tree dictionary.
bool
CompactibleFreeListSpace
::
verify
ChunkInFreeLists
(
FreeChunk
*
fc
)
const
{
bool
CompactibleFreeListSpace
::
verify
_chunk_in_free_list
(
FreeChunk
*
fc
)
const
{
if
(
verify_chunk_is_linear_alloc_block
(
fc
))
{
if
(
verify_chunk_is_linear_alloc_block
(
fc
))
{
return
true
;
return
true
;
}
else
if
(
fc
->
size
()
<
IndexSetSize
)
{
}
else
if
(
fc
->
size
()
<
IndexSetSize
)
{
return
verifyChunkInIndexedFreeLists
(
fc
);
return
verifyChunkInIndexedFreeLists
(
fc
);
}
else
{
}
else
{
return
dictionary
()
->
verify
ChunkInFreeLists
(
fc
);
return
dictionary
()
->
verify
_chunk_in_free_list
(
fc
);
}
}
}
}
...
@@ -1414,7 +1414,7 @@ FreeChunk* CompactibleFreeListSpace::allocateScratch(size_t size) {
...
@@ -1414,7 +1414,7 @@ FreeChunk* CompactibleFreeListSpace::allocateScratch(size_t size) {
}
}
if
(
fc
!=
NULL
)
{
if
(
fc
!=
NULL
)
{
fc
->
dontCoalesce
();
fc
->
dontCoalesce
();
assert
(
fc
->
is
F
ree
(),
"Should be free, but not coalescable"
);
assert
(
fc
->
is
_f
ree
(),
"Should be free, but not coalescable"
);
// Verify that the block offset table shows this to
// Verify that the block offset table shows this to
// be a single block, but not one which is unallocated.
// be a single block, but not one which is unallocated.
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc
->
size
());
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc
->
size
());
...
@@ -1494,7 +1494,7 @@ CompactibleFreeListSpace::getChunkFromLinearAllocBlock(LinearAllocBlock *blk,
...
@@ -1494,7 +1494,7 @@ CompactibleFreeListSpace::getChunkFromLinearAllocBlock(LinearAllocBlock *blk,
}
}
// Return the chunk that isn't big enough, and then refill below.
// Return the chunk that isn't big enough, and then refill below.
addChunkToFreeLists
(
blk
->
_ptr
,
sz
);
addChunkToFreeLists
(
blk
->
_ptr
,
sz
);
split
B
irth
(
sz
);
split
_b
irth
(
sz
);
// Don't keep statistics on adding back chunk from a LinAB.
// Don't keep statistics on adding back chunk from a LinAB.
}
else
{
}
else
{
// A refilled block would not satisfy the request.
// A refilled block would not satisfy the request.
...
@@ -1506,14 +1506,14 @@ CompactibleFreeListSpace::getChunkFromLinearAllocBlock(LinearAllocBlock *blk,
...
@@ -1506,14 +1506,14 @@ CompactibleFreeListSpace::getChunkFromLinearAllocBlock(LinearAllocBlock *blk,
assert
(
blk
->
_ptr
==
NULL
||
blk
->
_word_size
>=
size
+
MinChunkSize
,
assert
(
blk
->
_ptr
==
NULL
||
blk
->
_word_size
>=
size
+
MinChunkSize
,
"block was replenished"
);
"block was replenished"
);
if
(
res
!=
NULL
)
{
if
(
res
!=
NULL
)
{
split
B
irth
(
size
);
split
_b
irth
(
size
);
repairLinearAllocBlock
(
blk
);
repairLinearAllocBlock
(
blk
);
}
else
if
(
blk
->
_ptr
!=
NULL
)
{
}
else
if
(
blk
->
_ptr
!=
NULL
)
{
res
=
blk
->
_ptr
;
res
=
blk
->
_ptr
;
size_t
blk_size
=
blk
->
_word_size
;
size_t
blk_size
=
blk
->
_word_size
;
blk
->
_word_size
-=
size
;
blk
->
_word_size
-=
size
;
blk
->
_ptr
+=
size
;
blk
->
_ptr
+=
size
;
split
B
irth
(
size
);
split
_b
irth
(
size
);
repairLinearAllocBlock
(
blk
);
repairLinearAllocBlock
(
blk
);
// Update BOT last so that other (parallel) GC threads see a consistent
// Update BOT last so that other (parallel) GC threads see a consistent
// view of the BOT and free blocks.
// view of the BOT and free blocks.
...
@@ -1542,7 +1542,7 @@ HeapWord* CompactibleFreeListSpace::getChunkFromLinearAllocBlockRemainder(
...
@@ -1542,7 +1542,7 @@ HeapWord* CompactibleFreeListSpace::getChunkFromLinearAllocBlockRemainder(
size_t
blk_size
=
blk
->
_word_size
;
size_t
blk_size
=
blk
->
_word_size
;
blk
->
_word_size
-=
size
;
blk
->
_word_size
-=
size
;
blk
->
_ptr
+=
size
;
blk
->
_ptr
+=
size
;
split
B
irth
(
size
);
split
_b
irth
(
size
);
repairLinearAllocBlock
(
blk
);
repairLinearAllocBlock
(
blk
);
// Update BOT last so that other (parallel) GC threads see a consistent
// Update BOT last so that other (parallel) GC threads see a consistent
// view of the BOT and free blocks.
// view of the BOT and free blocks.
...
@@ -1559,7 +1559,7 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeList(size_t size) {
...
@@ -1559,7 +1559,7 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeList(size_t size) {
assert_locked
();
assert_locked
();
assert
(
size
<
SmallForDictionary
,
"just checking"
);
assert
(
size
<
SmallForDictionary
,
"just checking"
);
FreeChunk
*
res
;
FreeChunk
*
res
;
res
=
_indexedFreeList
[
size
].
get
ChunkAtH
ead
();
res
=
_indexedFreeList
[
size
].
get
_chunk_at_h
ead
();
if
(
res
==
NULL
)
{
if
(
res
==
NULL
)
{
res
=
getChunkFromIndexedFreeListHelper
(
size
);
res
=
getChunkFromIndexedFreeListHelper
(
size
);
}
}
...
@@ -1593,7 +1593,7 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
...
@@ -1593,7 +1593,7 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
// Do not replenish from an underpopulated size.
// Do not replenish from an underpopulated size.
if
(
_indexedFreeList
[
replenish_size
].
surplus
()
>
0
&&
if
(
_indexedFreeList
[
replenish_size
].
surplus
()
>
0
&&
_indexedFreeList
[
replenish_size
].
head
()
!=
NULL
)
{
_indexedFreeList
[
replenish_size
].
head
()
!=
NULL
)
{
newFc
=
_indexedFreeList
[
replenish_size
].
get
ChunkAtH
ead
();
newFc
=
_indexedFreeList
[
replenish_size
].
get
_chunk_at_h
ead
();
}
else
if
(
bestFitFirst
())
{
}
else
if
(
bestFitFirst
())
{
newFc
=
bestFitSmall
(
replenish_size
);
newFc
=
bestFitSmall
(
replenish_size
);
}
}
...
@@ -1626,13 +1626,13 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
...
@@ -1626,13 +1626,13 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
i
<
(
num_blk
-
1
);
i
<
(
num_blk
-
1
);
curFc
=
nextFc
,
nextFc
=
(
FreeChunk
*
)((
HeapWord
*
)
nextFc
+
size
),
curFc
=
nextFc
,
nextFc
=
(
FreeChunk
*
)((
HeapWord
*
)
nextFc
+
size
),
i
++
)
{
i
++
)
{
curFc
->
set
S
ize
(
size
);
curFc
->
set
_s
ize
(
size
);
// Don't record this as a return in order to try and
// Don't record this as a return in order to try and
// determine the "returns" from a GC.
// determine the "returns" from a GC.
_bt
.
verify_not_unallocated
((
HeapWord
*
)
fc
,
size
);
_bt
.
verify_not_unallocated
((
HeapWord
*
)
fc
,
size
);
_indexedFreeList
[
size
].
return
ChunkAtT
ail
(
curFc
,
false
);
_indexedFreeList
[
size
].
return
_chunk_at_t
ail
(
curFc
,
false
);
_bt
.
mark_block
((
HeapWord
*
)
curFc
,
size
);
_bt
.
mark_block
((
HeapWord
*
)
curFc
,
size
);
split
B
irth
(
size
);
split
_b
irth
(
size
);
// Don't record the initial population of the indexed list
// Don't record the initial population of the indexed list
// as a split birth.
// as a split birth.
}
}
...
@@ -1640,9 +1640,9 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
...
@@ -1640,9 +1640,9 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
// check that the arithmetic was OK above
// check that the arithmetic was OK above
assert
((
HeapWord
*
)
nextFc
==
(
HeapWord
*
)
newFc
+
num_blk
*
size
,
assert
((
HeapWord
*
)
nextFc
==
(
HeapWord
*
)
newFc
+
num_blk
*
size
,
"inconsistency in carving newFc"
);
"inconsistency in carving newFc"
);
curFc
->
set
S
ize
(
size
);
curFc
->
set
_s
ize
(
size
);
_bt
.
mark_block
((
HeapWord
*
)
curFc
,
size
);
_bt
.
mark_block
((
HeapWord
*
)
curFc
,
size
);
split
B
irth
(
size
);
split
_b
irth
(
size
);
fc
=
curFc
;
fc
=
curFc
;
}
else
{
}
else
{
// Return entire block to caller
// Return entire block to caller
...
@@ -1655,14 +1655,14 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
...
@@ -1655,14 +1655,14 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
// replenish the indexed free list.
// replenish the indexed free list.
fc
=
getChunkFromDictionaryExact
(
size
);
fc
=
getChunkFromDictionaryExact
(
size
);
}
}
// assert(fc == NULL || fc->is
F
ree(), "Should be returning a free chunk");
// assert(fc == NULL || fc->is
_f
ree(), "Should be returning a free chunk");
return
fc
;
return
fc
;
}
}
FreeChunk
*
FreeChunk
*
CompactibleFreeListSpace
::
getChunkFromDictionary
(
size_t
size
)
{
CompactibleFreeListSpace
::
getChunkFromDictionary
(
size_t
size
)
{
assert_locked
();
assert_locked
();
FreeChunk
*
fc
=
_dictionary
->
get
C
hunk
(
size
);
FreeChunk
*
fc
=
_dictionary
->
get
_c
hunk
(
size
);
if
(
fc
==
NULL
)
{
if
(
fc
==
NULL
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -1679,7 +1679,7 @@ CompactibleFreeListSpace::getChunkFromDictionary(size_t size) {
...
@@ -1679,7 +1679,7 @@ CompactibleFreeListSpace::getChunkFromDictionary(size_t size) {
FreeChunk
*
FreeChunk
*
CompactibleFreeListSpace
::
getChunkFromDictionaryExact
(
size_t
size
)
{
CompactibleFreeListSpace
::
getChunkFromDictionaryExact
(
size_t
size
)
{
assert_locked
();
assert_locked
();
FreeChunk
*
fc
=
_dictionary
->
get
C
hunk
(
size
);
FreeChunk
*
fc
=
_dictionary
->
get
_c
hunk
(
size
);
if
(
fc
==
NULL
)
{
if
(
fc
==
NULL
)
{
return
fc
;
return
fc
;
}
}
...
@@ -1688,11 +1688,11 @@ CompactibleFreeListSpace::getChunkFromDictionaryExact(size_t size) {
...
@@ -1688,11 +1688,11 @@ CompactibleFreeListSpace::getChunkFromDictionaryExact(size_t size) {
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
size
);
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
size
);
return
fc
;
return
fc
;
}
}
assert
(
fc
->
size
()
>
size
,
"get
C
hunk() guarantee"
);
assert
(
fc
->
size
()
>
size
,
"get
_c
hunk() guarantee"
);
if
(
fc
->
size
()
<
size
+
MinChunkSize
)
{
if
(
fc
->
size
()
<
size
+
MinChunkSize
)
{
// Return the chunk to the dictionary and go get a bigger one.
// Return the chunk to the dictionary and go get a bigger one.
returnChunkToDictionary
(
fc
);
returnChunkToDictionary
(
fc
);
fc
=
_dictionary
->
get
C
hunk
(
size
+
MinChunkSize
);
fc
=
_dictionary
->
get
_c
hunk
(
size
+
MinChunkSize
);
if
(
fc
==
NULL
)
{
if
(
fc
==
NULL
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -1713,7 +1713,7 @@ CompactibleFreeListSpace::returnChunkToDictionary(FreeChunk* chunk) {
...
@@ -1713,7 +1713,7 @@ CompactibleFreeListSpace::returnChunkToDictionary(FreeChunk* chunk) {
_bt
.
verify_single_block
((
HeapWord
*
)
chunk
,
size
);
_bt
.
verify_single_block
((
HeapWord
*
)
chunk
,
size
);
// adjust _unallocated_block downward, as necessary
// adjust _unallocated_block downward, as necessary
_bt
.
freed
((
HeapWord
*
)
chunk
,
size
);
_bt
.
freed
((
HeapWord
*
)
chunk
,
size
);
_dictionary
->
return
C
hunk
(
chunk
);
_dictionary
->
return
_c
hunk
(
chunk
);
#ifndef PRODUCT
#ifndef PRODUCT
if
(
CMSCollector
::
abstract_state
()
!=
CMSCollector
::
Sweeping
)
{
if
(
CMSCollector
::
abstract_state
()
!=
CMSCollector
::
Sweeping
)
{
TreeChunk
<
FreeChunk
>::
as_TreeChunk
(
chunk
)
->
list
()
->
verify_stats
();
TreeChunk
<
FreeChunk
>::
as_TreeChunk
(
chunk
)
->
list
()
->
verify_stats
();
...
@@ -1728,9 +1728,9 @@ CompactibleFreeListSpace::returnChunkToFreeList(FreeChunk* fc) {
...
@@ -1728,9 +1728,9 @@ CompactibleFreeListSpace::returnChunkToFreeList(FreeChunk* fc) {
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
size
);
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
size
);
_bt
.
verify_not_unallocated
((
HeapWord
*
)
fc
,
size
);
_bt
.
verify_not_unallocated
((
HeapWord
*
)
fc
,
size
);
if
(
_adaptive_freelists
)
{
if
(
_adaptive_freelists
)
{
_indexedFreeList
[
size
].
return
ChunkAtT
ail
(
fc
);
_indexedFreeList
[
size
].
return
_chunk_at_t
ail
(
fc
);
}
else
{
}
else
{
_indexedFreeList
[
size
].
return
ChunkAtH
ead
(
fc
);
_indexedFreeList
[
size
].
return
_chunk_at_h
ead
(
fc
);
}
}
#ifndef PRODUCT
#ifndef PRODUCT
if
(
CMSCollector
::
abstract_state
()
!=
CMSCollector
::
Sweeping
)
{
if
(
CMSCollector
::
abstract_state
()
!=
CMSCollector
::
Sweeping
)
{
...
@@ -1758,7 +1758,7 @@ CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats(
...
@@ -1758,7 +1758,7 @@ CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats(
FreeChunk
*
ec
;
FreeChunk
*
ec
;
{
{
MutexLockerEx
x
(
lock
,
Mutex
::
_no_safepoint_check_flag
);
MutexLockerEx
x
(
lock
,
Mutex
::
_no_safepoint_check_flag
);
ec
=
dictionary
()
->
find
LargestD
ict
();
// get largest block
ec
=
dictionary
()
->
find
_largest_d
ict
();
// get largest block
if
(
ec
!=
NULL
&&
ec
->
end
()
==
chunk
)
{
if
(
ec
!=
NULL
&&
ec
->
end
()
==
chunk
)
{
// It's a coterminal block - we can coalesce.
// It's a coterminal block - we can coalesce.
size_t
old_size
=
ec
->
size
();
size_t
old_size
=
ec
->
size
();
...
@@ -1769,7 +1769,7 @@ CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats(
...
@@ -1769,7 +1769,7 @@ CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats(
ec
=
(
FreeChunk
*
)
chunk
;
ec
=
(
FreeChunk
*
)
chunk
;
}
}
}
}
ec
->
set
S
ize
(
size
);
ec
->
set
_s
ize
(
size
);
debug_only
(
ec
->
mangleFreed
(
size
));
debug_only
(
ec
->
mangleFreed
(
size
));
if
(
size
<
SmallForDictionary
)
{
if
(
size
<
SmallForDictionary
)
{
lock
=
_indexedFreeListParLocks
[
size
];
lock
=
_indexedFreeListParLocks
[
size
];
...
@@ -1792,7 +1792,7 @@ CompactibleFreeListSpace::addChunkToFreeLists(HeapWord* chunk,
...
@@ -1792,7 +1792,7 @@ CompactibleFreeListSpace::addChunkToFreeLists(HeapWord* chunk,
_bt
.
verify_single_block
(
chunk
,
size
);
_bt
.
verify_single_block
(
chunk
,
size
);
FreeChunk
*
fc
=
(
FreeChunk
*
)
chunk
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
chunk
;
fc
->
set
S
ize
(
size
);
fc
->
set
_s
ize
(
size
);
debug_only
(
fc
->
mangleFreed
(
size
));
debug_only
(
fc
->
mangleFreed
(
size
));
if
(
size
<
SmallForDictionary
)
{
if
(
size
<
SmallForDictionary
)
{
returnChunkToFreeList
(
fc
);
returnChunkToFreeList
(
fc
);
...
@@ -1835,7 +1835,7 @@ CompactibleFreeListSpace::removeChunkFromDictionary(FreeChunk* fc) {
...
@@ -1835,7 +1835,7 @@ CompactibleFreeListSpace::removeChunkFromDictionary(FreeChunk* fc) {
assert_locked
();
assert_locked
();
assert
(
fc
!=
NULL
,
"null chunk"
);
assert
(
fc
!=
NULL
,
"null chunk"
);
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
size
);
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
size
);
_dictionary
->
remove
C
hunk
(
fc
);
_dictionary
->
remove
_c
hunk
(
fc
);
// adjust _unallocated_block upward, as necessary
// adjust _unallocated_block upward, as necessary
_bt
.
allocated
((
HeapWord
*
)
fc
,
size
);
_bt
.
allocated
((
HeapWord
*
)
fc
,
size
);
}
}
...
@@ -1850,7 +1850,7 @@ CompactibleFreeListSpace::removeChunkFromIndexedFreeList(FreeChunk* fc) {
...
@@ -1850,7 +1850,7 @@ CompactibleFreeListSpace::removeChunkFromIndexedFreeList(FreeChunk* fc) {
verifyIndexedFreeList
(
size
);
verifyIndexedFreeList
(
size
);
}
}
)
)
_indexedFreeList
[
size
].
remove
C
hunk
(
fc
);
_indexedFreeList
[
size
].
remove
_c
hunk
(
fc
);
NOT_PRODUCT
(
NOT_PRODUCT
(
if
(
FLSVerifyIndexTable
)
{
if
(
FLSVerifyIndexTable
)
{
verifyIndexedFreeList
(
size
);
verifyIndexedFreeList
(
size
);
...
@@ -1874,7 +1874,7 @@ FreeChunk* CompactibleFreeListSpace::bestFitSmall(size_t numWords) {
...
@@ -1874,7 +1874,7 @@ FreeChunk* CompactibleFreeListSpace::bestFitSmall(size_t numWords) {
// and split out a free chunk which is returned.
// and split out a free chunk which is returned.
_indexedFreeList
[
start
].
set_hint
(
hint
);
_indexedFreeList
[
start
].
set_hint
(
hint
);
FreeChunk
*
res
=
getFromListGreater
(
fl
,
numWords
);
FreeChunk
*
res
=
getFromListGreater
(
fl
,
numWords
);
assert
(
res
==
NULL
||
res
->
is
F
ree
(),
assert
(
res
==
NULL
||
res
->
is
_f
ree
(),
"Should be returning a free chunk"
);
"Should be returning a free chunk"
);
return
res
;
return
res
;
}
}
...
@@ -1896,13 +1896,13 @@ FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList<FreeChunk>* fl,
...
@@ -1896,13 +1896,13 @@ FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList<FreeChunk>* fl,
assert
(
oldNumWords
>=
numWords
+
MinChunkSize
,
assert
(
oldNumWords
>=
numWords
+
MinChunkSize
,
"Size of chunks in the list is too small"
);
"Size of chunks in the list is too small"
);
fl
->
remove
C
hunk
(
curr
);
fl
->
remove
_c
hunk
(
curr
);
// recorded indirectly by splitChunkAndReturnRemainder -
// recorded indirectly by splitChunkAndReturnRemainder -
// smallSplit(oldNumWords, numWords);
// smallSplit(oldNumWords, numWords);
FreeChunk
*
new_chunk
=
splitChunkAndReturnRemainder
(
curr
,
numWords
);
FreeChunk
*
new_chunk
=
splitChunkAndReturnRemainder
(
curr
,
numWords
);
// Does anything have to be done for the remainder in terms of
// Does anything have to be done for the remainder in terms of
// fixing the card table?
// fixing the card table?
assert
(
new_chunk
==
NULL
||
new_chunk
->
is
F
ree
(),
assert
(
new_chunk
==
NULL
||
new_chunk
->
is
_f
ree
(),
"Should be returning a free chunk"
);
"Should be returning a free chunk"
);
return
new_chunk
;
return
new_chunk
;
}
}
...
@@ -1920,13 +1920,13 @@ CompactibleFreeListSpace::splitChunkAndReturnRemainder(FreeChunk* chunk,
...
@@ -1920,13 +1920,13 @@ CompactibleFreeListSpace::splitChunkAndReturnRemainder(FreeChunk* chunk,
assert
(
rem_size
>=
MinChunkSize
,
"Free chunk smaller than minimum"
);
assert
(
rem_size
>=
MinChunkSize
,
"Free chunk smaller than minimum"
);
FreeChunk
*
ffc
=
(
FreeChunk
*
)((
HeapWord
*
)
chunk
+
new_size
);
FreeChunk
*
ffc
=
(
FreeChunk
*
)((
HeapWord
*
)
chunk
+
new_size
);
assert
(
is_aligned
(
ffc
),
"alignment problem"
);
assert
(
is_aligned
(
ffc
),
"alignment problem"
);
ffc
->
set
S
ize
(
rem_size
);
ffc
->
set
_s
ize
(
rem_size
);
ffc
->
link
N
ext
(
NULL
);
ffc
->
link
_n
ext
(
NULL
);
ffc
->
link
P
rev
(
NULL
);
// Mark as a free block for other (parallel) GC threads.
ffc
->
link
_p
rev
(
NULL
);
// Mark as a free block for other (parallel) GC threads.
// Above must occur before BOT is updated below.
// Above must occur before BOT is updated below.
// adjust block offset table
// adjust block offset table
OrderAccess
::
storestore
();
OrderAccess
::
storestore
();
assert
(
chunk
->
is
Free
()
&&
ffc
->
isF
ree
(),
"Error"
);
assert
(
chunk
->
is
_free
()
&&
ffc
->
is_f
ree
(),
"Error"
);
_bt
.
split_block
((
HeapWord
*
)
chunk
,
chunk
->
size
(),
new_size
);
_bt
.
split_block
((
HeapWord
*
)
chunk
,
chunk
->
size
(),
new_size
);
if
(
rem_size
<
SmallForDictionary
)
{
if
(
rem_size
<
SmallForDictionary
)
{
bool
is_par
=
(
SharedHeap
::
heap
()
->
n_par_threads
()
>
0
);
bool
is_par
=
(
SharedHeap
::
heap
()
->
n_par_threads
()
>
0
);
...
@@ -1941,7 +1941,7 @@ CompactibleFreeListSpace::splitChunkAndReturnRemainder(FreeChunk* chunk,
...
@@ -1941,7 +1941,7 @@ CompactibleFreeListSpace::splitChunkAndReturnRemainder(FreeChunk* chunk,
returnChunkToDictionary
(
ffc
);
returnChunkToDictionary
(
ffc
);
split
(
size
,
rem_size
);
split
(
size
,
rem_size
);
}
}
chunk
->
set
S
ize
(
new_size
);
chunk
->
set
_s
ize
(
new_size
);
return
chunk
;
return
chunk
;
}
}
...
@@ -2048,10 +2048,10 @@ void CompactibleFreeListSpace::repairLinearAllocBlock(LinearAllocBlock* blk) {
...
@@ -2048,10 +2048,10 @@ void CompactibleFreeListSpace::repairLinearAllocBlock(LinearAllocBlock* blk) {
assert
(
blk
->
_word_size
!=
0
&&
blk
->
_word_size
>=
MinChunkSize
,
assert
(
blk
->
_word_size
!=
0
&&
blk
->
_word_size
>=
MinChunkSize
,
"Minimum block size requirement"
);
"Minimum block size requirement"
);
FreeChunk
*
fc
=
(
FreeChunk
*
)(
blk
->
_ptr
);
FreeChunk
*
fc
=
(
FreeChunk
*
)(
blk
->
_ptr
);
fc
->
set
S
ize
(
blk
->
_word_size
);
fc
->
set
_s
ize
(
blk
->
_word_size
);
fc
->
link
P
rev
(
NULL
);
// mark as free
fc
->
link
_p
rev
(
NULL
);
// mark as free
fc
->
dontCoalesce
();
fc
->
dontCoalesce
();
assert
(
fc
->
is
F
ree
(),
"just marked it free"
);
assert
(
fc
->
is
_f
ree
(),
"just marked it free"
);
assert
(
fc
->
cantCoalesce
(),
"just marked it uncoalescable"
);
assert
(
fc
->
cantCoalesce
(),
"just marked it uncoalescable"
);
}
}
}
}
...
@@ -2151,7 +2151,7 @@ double CompactibleFreeListSpace::flsFrag() const {
...
@@ -2151,7 +2151,7 @@ double CompactibleFreeListSpace::flsFrag() const {
}
}
double
totFree
=
itabFree
+
double
totFree
=
itabFree
+
_dictionary
->
total
ChunkS
ize
(
DEBUG_ONLY
(
freelistLock
()));
_dictionary
->
total
_chunk_s
ize
(
DEBUG_ONLY
(
freelistLock
()));
if
(
totFree
>
0
)
{
if
(
totFree
>
0
)
{
frag
=
((
frag
+
_dictionary
->
sum_of_squared_block_sizes
())
/
frag
=
((
frag
+
_dictionary
->
sum_of_squared_block_sizes
())
/
(
totFree
*
totFree
));
(
totFree
*
totFree
));
...
@@ -2174,11 +2174,11 @@ void CompactibleFreeListSpace::beginSweepFLCensus(
...
@@ -2174,11 +2174,11 @@ void CompactibleFreeListSpace::beginSweepFLCensus(
gclog_or_tty
->
print
(
"size[%d] : "
,
i
);
gclog_or_tty
->
print
(
"size[%d] : "
,
i
);
}
}
fl
->
compute_desired
(
inter_sweep_current
,
inter_sweep_estimate
,
intra_sweep_estimate
);
fl
->
compute_desired
(
inter_sweep_current
,
inter_sweep_estimate
,
intra_sweep_estimate
);
fl
->
set_coal
D
esired
((
ssize_t
)((
double
)
fl
->
desired
()
*
CMSSmallCoalSurplusPercent
));
fl
->
set_coal
_d
esired
((
ssize_t
)((
double
)
fl
->
desired
()
*
CMSSmallCoalSurplusPercent
));
fl
->
set_before
S
weep
(
fl
->
count
());
fl
->
set_before
_s
weep
(
fl
->
count
());
fl
->
set_bfr
S
urp
(
fl
->
surplus
());
fl
->
set_bfr
_s
urp
(
fl
->
surplus
());
}
}
_dictionary
->
begin
SweepDictC
ensus
(
CMSLargeCoalSurplusPercent
,
_dictionary
->
begin
_sweep_dict_c
ensus
(
CMSLargeCoalSurplusPercent
,
inter_sweep_current
,
inter_sweep_current
,
inter_sweep_estimate
,
inter_sweep_estimate
,
intra_sweep_estimate
);
intra_sweep_estimate
);
...
@@ -2212,17 +2212,17 @@ void CompactibleFreeListSpace::clearFLCensus() {
...
@@ -2212,17 +2212,17 @@ void CompactibleFreeListSpace::clearFLCensus() {
size_t
i
;
size_t
i
;
for
(
i
=
IndexSetStart
;
i
<
IndexSetSize
;
i
+=
IndexSetStride
)
{
for
(
i
=
IndexSetStart
;
i
<
IndexSetSize
;
i
+=
IndexSetStride
)
{
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
i
];
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
i
];
fl
->
set_prev
S
weep
(
fl
->
count
());
fl
->
set_prev
_s
weep
(
fl
->
count
());
fl
->
set_coal
B
irths
(
0
);
fl
->
set_coal
_b
irths
(
0
);
fl
->
set_coal
D
eaths
(
0
);
fl
->
set_coal
_d
eaths
(
0
);
fl
->
set_split
B
irths
(
0
);
fl
->
set_split
_b
irths
(
0
);
fl
->
set_split
D
eaths
(
0
);
fl
->
set_split
_d
eaths
(
0
);
}
}
}
}
void
CompactibleFreeListSpace
::
endSweepFLCensus
(
size_t
sweep_count
)
{
void
CompactibleFreeListSpace
::
endSweepFLCensus
(
size_t
sweep_count
)
{
if
(
PrintFLSStatistics
>
0
)
{
if
(
PrintFLSStatistics
>
0
)
{
HeapWord
*
largestAddr
=
(
HeapWord
*
)
dictionary
()
->
find
LargestD
ict
();
HeapWord
*
largestAddr
=
(
HeapWord
*
)
dictionary
()
->
find
_largest_d
ict
();
gclog_or_tty
->
print_cr
(
"CMS: Large block "
PTR_FORMAT
,
gclog_or_tty
->
print_cr
(
"CMS: Large block "
PTR_FORMAT
,
largestAddr
);
largestAddr
);
}
}
...
@@ -2233,30 +2233,30 @@ void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) {
...
@@ -2233,30 +2233,30 @@ void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) {
}
}
clearFLCensus
();
clearFLCensus
();
assert_locked
();
assert_locked
();
_dictionary
->
end
SweepDictC
ensus
(
CMSLargeSplitSurplusPercent
);
_dictionary
->
end
_sweep_dict_c
ensus
(
CMSLargeSplitSurplusPercent
);
}
}
bool
CompactibleFreeListSpace
::
coalOverPopulated
(
size_t
size
)
{
bool
CompactibleFreeListSpace
::
coalOverPopulated
(
size_t
size
)
{
if
(
size
<
SmallForDictionary
)
{
if
(
size
<
SmallForDictionary
)
{
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
return
(
fl
->
coal
D
esired
()
<
0
)
||
return
(
fl
->
coal
_d
esired
()
<
0
)
||
((
int
)
fl
->
count
()
>
fl
->
coal
D
esired
());
((
int
)
fl
->
count
()
>
fl
->
coal
_d
esired
());
}
else
{
}
else
{
return
dictionary
()
->
coal
DictOverP
opulated
(
size
);
return
dictionary
()
->
coal
_dict_over_p
opulated
(
size
);
}
}
}
}
void
CompactibleFreeListSpace
::
smallCoalBirth
(
size_t
size
)
{
void
CompactibleFreeListSpace
::
smallCoalBirth
(
size_t
size
)
{
assert
(
size
<
SmallForDictionary
,
"Size too large for indexed list"
);
assert
(
size
<
SmallForDictionary
,
"Size too large for indexed list"
);
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
fl
->
increment_coal
B
irths
();
fl
->
increment_coal
_b
irths
();
fl
->
increment_surplus
();
fl
->
increment_surplus
();
}
}
void
CompactibleFreeListSpace
::
smallCoalDeath
(
size_t
size
)
{
void
CompactibleFreeListSpace
::
smallCoalDeath
(
size_t
size
)
{
assert
(
size
<
SmallForDictionary
,
"Size too large for indexed list"
);
assert
(
size
<
SmallForDictionary
,
"Size too large for indexed list"
);
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
fl
->
increment_coal
D
eaths
();
fl
->
increment_coal
_d
eaths
();
fl
->
decrement_surplus
();
fl
->
decrement_surplus
();
}
}
...
@@ -2264,7 +2264,7 @@ void CompactibleFreeListSpace::coalBirth(size_t size) {
...
@@ -2264,7 +2264,7 @@ void CompactibleFreeListSpace::coalBirth(size_t size) {
if
(
size
<
SmallForDictionary
)
{
if
(
size
<
SmallForDictionary
)
{
smallCoalBirth
(
size
);
smallCoalBirth
(
size
);
}
else
{
}
else
{
dictionary
()
->
dict
CensusUpd
ate
(
size
,
dictionary
()
->
dict
_census_udp
ate
(
size
,
false
/* split */
,
false
/* split */
,
true
/* birth */
);
true
/* birth */
);
}
}
...
@@ -2274,7 +2274,7 @@ void CompactibleFreeListSpace::coalDeath(size_t size) {
...
@@ -2274,7 +2274,7 @@ void CompactibleFreeListSpace::coalDeath(size_t size) {
if
(
size
<
SmallForDictionary
)
{
if
(
size
<
SmallForDictionary
)
{
smallCoalDeath
(
size
);
smallCoalDeath
(
size
);
}
else
{
}
else
{
dictionary
()
->
dict
CensusUpd
ate
(
size
,
dictionary
()
->
dict
_census_udp
ate
(
size
,
false
/* split */
,
false
/* split */
,
false
/* birth */
);
false
/* birth */
);
}
}
...
@@ -2283,22 +2283,22 @@ void CompactibleFreeListSpace::coalDeath(size_t size) {
...
@@ -2283,22 +2283,22 @@ void CompactibleFreeListSpace::coalDeath(size_t size) {
void
CompactibleFreeListSpace
::
smallSplitBirth
(
size_t
size
)
{
void
CompactibleFreeListSpace
::
smallSplitBirth
(
size_t
size
)
{
assert
(
size
<
SmallForDictionary
,
"Size too large for indexed list"
);
assert
(
size
<
SmallForDictionary
,
"Size too large for indexed list"
);
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
fl
->
increment_split
B
irths
();
fl
->
increment_split
_b
irths
();
fl
->
increment_surplus
();
fl
->
increment_surplus
();
}
}
void
CompactibleFreeListSpace
::
smallSplitDeath
(
size_t
size
)
{
void
CompactibleFreeListSpace
::
smallSplitDeath
(
size_t
size
)
{
assert
(
size
<
SmallForDictionary
,
"Size too large for indexed list"
);
assert
(
size
<
SmallForDictionary
,
"Size too large for indexed list"
);
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
size
];
fl
->
increment_split
D
eaths
();
fl
->
increment_split
_d
eaths
();
fl
->
decrement_surplus
();
fl
->
decrement_surplus
();
}
}
void
CompactibleFreeListSpace
::
split
B
irth
(
size_t
size
)
{
void
CompactibleFreeListSpace
::
split
_b
irth
(
size_t
size
)
{
if
(
size
<
SmallForDictionary
)
{
if
(
size
<
SmallForDictionary
)
{
smallSplitBirth
(
size
);
smallSplitBirth
(
size
);
}
else
{
}
else
{
dictionary
()
->
dict
CensusUpd
ate
(
size
,
dictionary
()
->
dict
_census_udp
ate
(
size
,
true
/* split */
,
true
/* split */
,
true
/* birth */
);
true
/* birth */
);
}
}
...
@@ -2308,7 +2308,7 @@ void CompactibleFreeListSpace::splitDeath(size_t size) {
...
@@ -2308,7 +2308,7 @@ void CompactibleFreeListSpace::splitDeath(size_t size) {
if
(
size
<
SmallForDictionary
)
{
if
(
size
<
SmallForDictionary
)
{
smallSplitDeath
(
size
);
smallSplitDeath
(
size
);
}
else
{
}
else
{
dictionary
()
->
dict
CensusUpd
ate
(
size
,
dictionary
()
->
dict
_census_udp
ate
(
size
,
true
/* split */
,
true
/* split */
,
false
/* birth */
);
false
/* birth */
);
}
}
...
@@ -2317,8 +2317,8 @@ void CompactibleFreeListSpace::splitDeath(size_t size) {
...
@@ -2317,8 +2317,8 @@ void CompactibleFreeListSpace::splitDeath(size_t size) {
void
CompactibleFreeListSpace
::
split
(
size_t
from
,
size_t
to1
)
{
void
CompactibleFreeListSpace
::
split
(
size_t
from
,
size_t
to1
)
{
size_t
to2
=
from
-
to1
;
size_t
to2
=
from
-
to1
;
splitDeath
(
from
);
splitDeath
(
from
);
split
B
irth
(
to1
);
split
_b
irth
(
to1
);
split
B
irth
(
to2
);
split
_b
irth
(
to2
);
}
}
void
CompactibleFreeListSpace
::
print
()
const
{
void
CompactibleFreeListSpace
::
print
()
const
{
...
@@ -2364,7 +2364,7 @@ class VerifyAllBlksClosure: public BlkClosure {
...
@@ -2364,7 +2364,7 @@ class VerifyAllBlksClosure: public BlkClosure {
FreeChunk
*
fc
=
(
FreeChunk
*
)
addr
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
addr
;
res
=
fc
->
size
();
res
=
fc
->
size
();
if
(
FLSVerifyLists
&&
!
fc
->
cantCoalesce
())
{
if
(
FLSVerifyLists
&&
!
fc
->
cantCoalesce
())
{
guarantee
(
_sp
->
verify
ChunkInFreeLists
(
fc
),
guarantee
(
_sp
->
verify
_chunk_in_free_list
(
fc
),
"Chunk should be on a free list"
);
"Chunk should be on a free list"
);
}
}
}
}
...
@@ -2520,7 +2520,7 @@ void CompactibleFreeListSpace::verifyIndexedFreeList(size_t size) const {
...
@@ -2520,7 +2520,7 @@ void CompactibleFreeListSpace::verifyIndexedFreeList(size_t size) const {
"Slot should have been empty"
);
"Slot should have been empty"
);
for
(;
fc
!=
NULL
;
fc
=
fc
->
next
(),
n
++
)
{
for
(;
fc
!=
NULL
;
fc
=
fc
->
next
(),
n
++
)
{
guarantee
(
fc
->
size
()
==
size
,
"Size inconsistency"
);
guarantee
(
fc
->
size
()
==
size
,
"Size inconsistency"
);
guarantee
(
fc
->
is
F
ree
(),
"!free?"
);
guarantee
(
fc
->
is
_f
ree
(),
"!free?"
);
guarantee
(
fc
->
next
()
==
NULL
||
fc
->
next
()
->
prev
()
==
fc
,
"Broken list"
);
guarantee
(
fc
->
next
()
==
NULL
||
fc
->
next
()
->
prev
()
==
fc
,
"Broken list"
);
guarantee
((
fc
->
next
()
==
NULL
)
==
(
fc
==
tail
),
"Incorrect tail"
);
guarantee
((
fc
->
next
()
==
NULL
)
==
(
fc
==
tail
),
"Incorrect tail"
);
}
}
...
@@ -2529,7 +2529,7 @@ void CompactibleFreeListSpace::verifyIndexedFreeList(size_t size) const {
...
@@ -2529,7 +2529,7 @@ void CompactibleFreeListSpace::verifyIndexedFreeList(size_t size) const {
#ifndef PRODUCT
#ifndef PRODUCT
void
CompactibleFreeListSpace
::
check_free_list_consistency
()
const
{
void
CompactibleFreeListSpace
::
check_free_list_consistency
()
const
{
assert
(
_dictionary
->
min
S
ize
()
<=
IndexSetSize
,
assert
(
_dictionary
->
min
_s
ize
()
<=
IndexSetSize
,
"Some sizes can't be allocated without recourse to"
"Some sizes can't be allocated without recourse to"
" linear allocation buffers"
);
" linear allocation buffers"
);
assert
(
BinaryTreeDictionary
<
FreeChunk
>::
min_tree_chunk_size
*
HeapWordSize
==
sizeof
(
TreeChunk
<
FreeChunk
>
),
assert
(
BinaryTreeDictionary
<
FreeChunk
>::
min_tree_chunk_size
*
HeapWordSize
==
sizeof
(
TreeChunk
<
FreeChunk
>
),
...
@@ -2548,33 +2548,33 @@ void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
...
@@ -2548,33 +2548,33 @@ void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
FreeList
<
FreeChunk
>
total
;
FreeList
<
FreeChunk
>
total
;
gclog_or_tty
->
print
(
"end sweep# "
SIZE_FORMAT
"
\n
"
,
sweep_count
);
gclog_or_tty
->
print
(
"end sweep# "
SIZE_FORMAT
"
\n
"
,
sweep_count
);
FreeList
<
FreeChunk
>::
print_labels_on
(
gclog_or_tty
,
"size"
);
FreeList
<
FreeChunk
>::
print_labels_on
(
gclog_or_tty
,
"size"
);
size_t
total
F
ree
=
0
;
size_t
total
_f
ree
=
0
;
for
(
size_t
i
=
IndexSetStart
;
i
<
IndexSetSize
;
i
+=
IndexSetStride
)
{
for
(
size_t
i
=
IndexSetStart
;
i
<
IndexSetSize
;
i
+=
IndexSetStride
)
{
const
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
i
];
const
FreeList
<
FreeChunk
>
*
fl
=
&
_indexedFreeList
[
i
];
total
F
ree
+=
fl
->
count
()
*
fl
->
size
();
total
_f
ree
+=
fl
->
count
()
*
fl
->
size
();
if
(
i
%
(
40
*
IndexSetStride
)
==
0
)
{
if
(
i
%
(
40
*
IndexSetStride
)
==
0
)
{
FreeList
<
FreeChunk
>::
print_labels_on
(
gclog_or_tty
,
"size"
);
FreeList
<
FreeChunk
>::
print_labels_on
(
gclog_or_tty
,
"size"
);
}
}
fl
->
print_on
(
gclog_or_tty
);
fl
->
print_on
(
gclog_or_tty
);
total
.
set_bfr
Surp
(
total
.
bfrSurp
()
+
fl
->
bfrS
urp
()
);
total
.
set_bfr
_surp
(
total
.
bfr_surp
()
+
fl
->
bfr_s
urp
()
);
total
.
set_surplus
(
total
.
surplus
()
+
fl
->
surplus
()
);
total
.
set_surplus
(
total
.
surplus
()
+
fl
->
surplus
()
);
total
.
set_desired
(
total
.
desired
()
+
fl
->
desired
()
);
total
.
set_desired
(
total
.
desired
()
+
fl
->
desired
()
);
total
.
set_prev
Sweep
(
total
.
prevSweep
()
+
fl
->
prevS
weep
()
);
total
.
set_prev
_sweep
(
total
.
prev_sweep
()
+
fl
->
prev_s
weep
()
);
total
.
set_before
Sweep
(
total
.
beforeSweep
()
+
fl
->
beforeS
weep
());
total
.
set_before
_sweep
(
total
.
before_sweep
()
+
fl
->
before_s
weep
());
total
.
set_count
(
total
.
count
()
+
fl
->
count
()
);
total
.
set_count
(
total
.
count
()
+
fl
->
count
()
);
total
.
set_coal
Births
(
total
.
coalBirths
()
+
fl
->
coalB
irths
()
);
total
.
set_coal
_births
(
total
.
coal_births
()
+
fl
->
coal_b
irths
()
);
total
.
set_coal
Deaths
(
total
.
coalDeaths
()
+
fl
->
coalD
eaths
()
);
total
.
set_coal
_deaths
(
total
.
coal_deaths
()
+
fl
->
coal_d
eaths
()
);
total
.
set_split
Births
(
total
.
splitBirths
()
+
fl
->
splitB
irths
());
total
.
set_split
_births
(
total
.
split_births
()
+
fl
->
split_b
irths
());
total
.
set_split
Deaths
(
total
.
splitDeaths
()
+
fl
->
splitD
eaths
());
total
.
set_split
_deaths
(
total
.
split_deaths
()
+
fl
->
split_d
eaths
());
}
}
total
.
print_on
(
gclog_or_tty
,
"TOTAL"
);
total
.
print_on
(
gclog_or_tty
,
"TOTAL"
);
gclog_or_tty
->
print_cr
(
"Total free in indexed lists "
gclog_or_tty
->
print_cr
(
"Total free in indexed lists "
SIZE_FORMAT
" words"
,
total
F
ree
);
SIZE_FORMAT
" words"
,
total
_f
ree
);
gclog_or_tty
->
print
(
"growth: %8.5f deficit: %8.5f
\n
"
,
gclog_or_tty
->
print
(
"growth: %8.5f deficit: %8.5f
\n
"
,
(
double
)(
total
.
split
Births
()
+
total
.
coalBirths
()
-
total
.
splitDeaths
()
-
total
.
coalD
eaths
())
/
(
double
)(
total
.
split
_births
()
+
total
.
coal_births
()
-
total
.
split_deaths
()
-
total
.
coal_d
eaths
())
/
(
total
.
prev
Sweep
()
!=
0
?
(
double
)
total
.
prevS
weep
()
:
1.0
),
(
total
.
prev
_sweep
()
!=
0
?
(
double
)
total
.
prev_s
weep
()
:
1.0
),
(
double
)(
total
.
desired
()
-
total
.
count
())
/
(
total
.
desired
()
!=
0
?
(
double
)
total
.
desired
()
:
1.0
));
(
double
)(
total
.
desired
()
-
total
.
count
())
/
(
total
.
desired
()
!=
0
?
(
double
)
total
.
desired
()
:
1.0
));
_dictionary
->
print
DictC
ensus
();
_dictionary
->
print
_dict_c
ensus
();
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
...
@@ -2643,11 +2643,11 @@ HeapWord* CFLS_LAB::alloc(size_t word_sz) {
...
@@ -2643,11 +2643,11 @@ HeapWord* CFLS_LAB::alloc(size_t word_sz) {
// If it didn't work, give up.
// If it didn't work, give up.
if
(
fl
->
count
()
==
0
)
return
NULL
;
if
(
fl
->
count
()
==
0
)
return
NULL
;
}
}
res
=
fl
->
get
ChunkAtH
ead
();
res
=
fl
->
get
_chunk_at_h
ead
();
assert
(
res
!=
NULL
,
"Why was count non-zero?"
);
assert
(
res
!=
NULL
,
"Why was count non-zero?"
);
}
}
res
->
markNotFree
();
res
->
markNotFree
();
assert
(
!
res
->
is
F
ree
(),
"shouldn't be marked free"
);
assert
(
!
res
->
is
_f
ree
(),
"shouldn't be marked free"
);
assert
(
oop
(
res
)
->
klass_or_null
()
==
NULL
,
"should look uninitialized"
);
assert
(
oop
(
res
)
->
klass_or_null
()
==
NULL
,
"should look uninitialized"
);
// mangle a just allocated object with a distinct pattern.
// mangle a just allocated object with a distinct pattern.
debug_only
(
res
->
mangleAllocated
(
word_sz
));
debug_only
(
res
->
mangleAllocated
(
word_sz
));
...
@@ -2786,9 +2786,9 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2786,9 +2786,9 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
// we increment the split death count by the number of blocks
// we increment the split death count by the number of blocks
// we just took from the cur_sz-size blocks list and which
// we just took from the cur_sz-size blocks list and which
// we will be splitting below.
// we will be splitting below.
ssize_t
deaths
=
gfl
->
split
D
eaths
()
+
ssize_t
deaths
=
gfl
->
split
_d
eaths
()
+
fl_for_cur_sz
.
count
();
fl_for_cur_sz
.
count
();
gfl
->
set_split
D
eaths
(
deaths
);
gfl
->
set_split
_d
eaths
(
deaths
);
}
}
}
}
}
}
...
@@ -2799,21 +2799,21 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2799,21 +2799,21 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
}
else
{
}
else
{
// Divide each block on fl_for_cur_sz up k ways.
// Divide each block on fl_for_cur_sz up k ways.
FreeChunk
*
fc
;
FreeChunk
*
fc
;
while
((
fc
=
fl_for_cur_sz
.
get
ChunkAtH
ead
())
!=
NULL
)
{
while
((
fc
=
fl_for_cur_sz
.
get
_chunk_at_h
ead
())
!=
NULL
)
{
// Must do this in reverse order, so that anybody attempting to
// Must do this in reverse order, so that anybody attempting to
// access the main chunk sees it as a single free block until we
// access the main chunk sees it as a single free block until we
// change it.
// change it.
size_t
fc_size
=
fc
->
size
();
size_t
fc_size
=
fc
->
size
();
assert
(
fc
->
is
F
ree
(),
"Error"
);
assert
(
fc
->
is
_f
ree
(),
"Error"
);
for
(
int
i
=
k
-
1
;
i
>=
0
;
i
--
)
{
for
(
int
i
=
k
-
1
;
i
>=
0
;
i
--
)
{
FreeChunk
*
ffc
=
(
FreeChunk
*
)((
HeapWord
*
)
fc
+
i
*
word_sz
);
FreeChunk
*
ffc
=
(
FreeChunk
*
)((
HeapWord
*
)
fc
+
i
*
word_sz
);
assert
((
i
!=
0
)
||
assert
((
i
!=
0
)
||
((
fc
==
ffc
)
&&
ffc
->
is
F
ree
()
&&
((
fc
==
ffc
)
&&
ffc
->
is
_f
ree
()
&&
(
ffc
->
size
()
==
k
*
word_sz
)
&&
(
fc_size
==
word_sz
)),
(
ffc
->
size
()
==
k
*
word_sz
)
&&
(
fc_size
==
word_sz
)),
"Counting error"
);
"Counting error"
);
ffc
->
set
S
ize
(
word_sz
);
ffc
->
set
_s
ize
(
word_sz
);
ffc
->
link
P
rev
(
NULL
);
// Mark as a free block for other (parallel) GC threads.
ffc
->
link
_p
rev
(
NULL
);
// Mark as a free block for other (parallel) GC threads.
ffc
->
link
N
ext
(
NULL
);
ffc
->
link
_n
ext
(
NULL
);
// Above must occur before BOT is updated below.
// Above must occur before BOT is updated below.
OrderAccess
::
storestore
();
OrderAccess
::
storestore
();
// splitting from the right, fc_size == i * word_sz
// splitting from the right, fc_size == i * word_sz
...
@@ -2824,7 +2824,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2824,7 +2824,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc_size
);
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc_size
);
_bt
.
verify_single_block
((
HeapWord
*
)
ffc
,
word_sz
);
_bt
.
verify_single_block
((
HeapWord
*
)
ffc
,
word_sz
);
// Push this on "fl".
// Push this on "fl".
fl
->
return
ChunkAtH
ead
(
ffc
);
fl
->
return
_chunk_at_h
ead
(
ffc
);
}
}
// TRAP
// TRAP
assert
(
fl
->
tail
()
->
next
()
==
NULL
,
"List invariant."
);
assert
(
fl
->
tail
()
->
next
()
==
NULL
,
"List invariant."
);
...
@@ -2834,8 +2834,8 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2834,8 +2834,8 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
size_t
num
=
fl
->
count
();
size_t
num
=
fl
->
count
();
MutexLockerEx
x
(
_indexedFreeListParLocks
[
word_sz
],
MutexLockerEx
x
(
_indexedFreeListParLocks
[
word_sz
],
Mutex
::
_no_safepoint_check_flag
);
Mutex
::
_no_safepoint_check_flag
);
ssize_t
births
=
_indexedFreeList
[
word_sz
].
split
B
irths
()
+
num
;
ssize_t
births
=
_indexedFreeList
[
word_sz
].
split
_b
irths
()
+
num
;
_indexedFreeList
[
word_sz
].
set_split
B
irths
(
births
);
_indexedFreeList
[
word_sz
].
set_split
_b
irths
(
births
);
return
;
return
;
}
}
}
}
...
@@ -2848,12 +2848,12 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2848,12 +2848,12 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
MutexLockerEx
x
(
parDictionaryAllocLock
(),
MutexLockerEx
x
(
parDictionaryAllocLock
(),
Mutex
::
_no_safepoint_check_flag
);
Mutex
::
_no_safepoint_check_flag
);
while
(
n
>
0
)
{
while
(
n
>
0
)
{
fc
=
dictionary
()
->
get
C
hunk
(
MAX2
(
n
*
word_sz
,
fc
=
dictionary
()
->
get
_c
hunk
(
MAX2
(
n
*
word_sz
,
_dictionary
->
min
S
ize
()),
_dictionary
->
min
_s
ize
()),
FreeBlockDictionary
<
FreeChunk
>::
atLeast
);
FreeBlockDictionary
<
FreeChunk
>::
atLeast
);
if
(
fc
!=
NULL
)
{
if
(
fc
!=
NULL
)
{
_bt
.
allocated
((
HeapWord
*
)
fc
,
fc
->
size
(),
true
/* reducing */
);
// update _unallocated_blk
_bt
.
allocated
((
HeapWord
*
)
fc
,
fc
->
size
(),
true
/* reducing */
);
// update _unallocated_blk
dictionary
()
->
dict
CensusUpd
ate
(
fc
->
size
(),
dictionary
()
->
dict
_census_udp
ate
(
fc
->
size
(),
true
/*split*/
,
true
/*split*/
,
false
/*birth*/
);
false
/*birth*/
);
break
;
break
;
...
@@ -2864,7 +2864,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2864,7 +2864,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
if
(
fc
==
NULL
)
return
;
if
(
fc
==
NULL
)
return
;
// Otherwise, split up that block.
// Otherwise, split up that block.
assert
((
ssize_t
)
n
>=
1
,
"Control point invariant"
);
assert
((
ssize_t
)
n
>=
1
,
"Control point invariant"
);
assert
(
fc
->
is
F
ree
(),
"Error: should be a free block"
);
assert
(
fc
->
is
_f
ree
(),
"Error: should be a free block"
);
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc
->
size
());
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc
->
size
());
const
size_t
nn
=
fc
->
size
()
/
word_sz
;
const
size_t
nn
=
fc
->
size
()
/
word_sz
;
n
=
MIN2
(
nn
,
n
);
n
=
MIN2
(
nn
,
n
);
...
@@ -2895,18 +2895,18 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2895,18 +2895,18 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
if
(
rem
>
0
)
{
if
(
rem
>
0
)
{
size_t
prefix_size
=
n
*
word_sz
;
size_t
prefix_size
=
n
*
word_sz
;
rem_fc
=
(
FreeChunk
*
)((
HeapWord
*
)
fc
+
prefix_size
);
rem_fc
=
(
FreeChunk
*
)((
HeapWord
*
)
fc
+
prefix_size
);
rem_fc
->
set
S
ize
(
rem
);
rem_fc
->
set
_s
ize
(
rem
);
rem_fc
->
link
P
rev
(
NULL
);
// Mark as a free block for other (parallel) GC threads.
rem_fc
->
link
_p
rev
(
NULL
);
// Mark as a free block for other (parallel) GC threads.
rem_fc
->
link
N
ext
(
NULL
);
rem_fc
->
link
_n
ext
(
NULL
);
// Above must occur before BOT is updated below.
// Above must occur before BOT is updated below.
assert
((
ssize_t
)
n
>
0
&&
prefix_size
>
0
&&
rem_fc
>
fc
,
"Error"
);
assert
((
ssize_t
)
n
>
0
&&
prefix_size
>
0
&&
rem_fc
>
fc
,
"Error"
);
OrderAccess
::
storestore
();
OrderAccess
::
storestore
();
_bt
.
split_block
((
HeapWord
*
)
fc
,
fc
->
size
(),
prefix_size
);
_bt
.
split_block
((
HeapWord
*
)
fc
,
fc
->
size
(),
prefix_size
);
assert
(
fc
->
is
F
ree
(),
"Error"
);
assert
(
fc
->
is
_f
ree
(),
"Error"
);
fc
->
set
S
ize
(
prefix_size
);
fc
->
set
_s
ize
(
prefix_size
);
if
(
rem
>=
IndexSetSize
)
{
if
(
rem
>=
IndexSetSize
)
{
returnChunkToDictionary
(
rem_fc
);
returnChunkToDictionary
(
rem_fc
);
dictionary
()
->
dict
CensusUpd
ate
(
rem
,
true
/*split*/
,
true
/*birth*/
);
dictionary
()
->
dict
_census_udp
ate
(
rem
,
true
/*split*/
,
true
/*birth*/
);
rem_fc
=
NULL
;
rem_fc
=
NULL
;
}
}
// Otherwise, return it to the small list below.
// Otherwise, return it to the small list below.
...
@@ -2916,7 +2916,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2916,7 +2916,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
MutexLockerEx
x
(
_indexedFreeListParLocks
[
rem
],
MutexLockerEx
x
(
_indexedFreeListParLocks
[
rem
],
Mutex
::
_no_safepoint_check_flag
);
Mutex
::
_no_safepoint_check_flag
);
_bt
.
verify_not_unallocated
((
HeapWord
*
)
rem_fc
,
rem_fc
->
size
());
_bt
.
verify_not_unallocated
((
HeapWord
*
)
rem_fc
,
rem_fc
->
size
());
_indexedFreeList
[
rem
].
return
ChunkAtH
ead
(
rem_fc
);
_indexedFreeList
[
rem
].
return
_chunk_at_h
ead
(
rem_fc
);
smallSplitBirth
(
rem
);
smallSplitBirth
(
rem
);
}
}
assert
((
ssize_t
)
n
>
0
&&
fc
!=
NULL
,
"Consistency"
);
assert
((
ssize_t
)
n
>
0
&&
fc
!=
NULL
,
"Consistency"
);
...
@@ -2928,9 +2928,9 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2928,9 +2928,9 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
// All but first chunk in this loop
// All but first chunk in this loop
for
(
ssize_t
i
=
n
-
1
;
i
>
0
;
i
--
)
{
for
(
ssize_t
i
=
n
-
1
;
i
>
0
;
i
--
)
{
FreeChunk
*
ffc
=
(
FreeChunk
*
)((
HeapWord
*
)
fc
+
i
*
word_sz
);
FreeChunk
*
ffc
=
(
FreeChunk
*
)((
HeapWord
*
)
fc
+
i
*
word_sz
);
ffc
->
set
S
ize
(
word_sz
);
ffc
->
set
_s
ize
(
word_sz
);
ffc
->
link
P
rev
(
NULL
);
// Mark as a free block for other (parallel) GC threads.
ffc
->
link
_p
rev
(
NULL
);
// Mark as a free block for other (parallel) GC threads.
ffc
->
link
N
ext
(
NULL
);
ffc
->
link
_n
ext
(
NULL
);
// Above must occur before BOT is updated below.
// Above must occur before BOT is updated below.
OrderAccess
::
storestore
();
OrderAccess
::
storestore
();
// splitting from the right, fc_size == (n - i + 1) * wordsize
// splitting from the right, fc_size == (n - i + 1) * wordsize
...
@@ -2940,25 +2940,25 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
...
@@ -2940,25 +2940,25 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
_bt
.
verify_single_block
((
HeapWord
*
)
ffc
,
ffc
->
size
());
_bt
.
verify_single_block
((
HeapWord
*
)
ffc
,
ffc
->
size
());
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc_size
);
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc_size
);
// Push this on "fl".
// Push this on "fl".
fl
->
return
ChunkAtH
ead
(
ffc
);
fl
->
return
_chunk_at_h
ead
(
ffc
);
}
}
// First chunk
// First chunk
assert
(
fc
->
is
F
ree
()
&&
fc
->
size
()
==
n
*
word_sz
,
"Error: should still be a free block"
);
assert
(
fc
->
is
_f
ree
()
&&
fc
->
size
()
==
n
*
word_sz
,
"Error: should still be a free block"
);
// The blocks above should show their new sizes before the first block below
// The blocks above should show their new sizes before the first block below
fc
->
set
S
ize
(
word_sz
);
fc
->
set
_s
ize
(
word_sz
);
fc
->
link
P
rev
(
NULL
);
// idempotent wrt free-ness, see assert above
fc
->
link
_p
rev
(
NULL
);
// idempotent wrt free-ness, see assert above
fc
->
link
N
ext
(
NULL
);
fc
->
link
_n
ext
(
NULL
);
_bt
.
verify_not_unallocated
((
HeapWord
*
)
fc
,
fc
->
size
());
_bt
.
verify_not_unallocated
((
HeapWord
*
)
fc
,
fc
->
size
());
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc
->
size
());
_bt
.
verify_single_block
((
HeapWord
*
)
fc
,
fc
->
size
());
fl
->
return
ChunkAtH
ead
(
fc
);
fl
->
return
_chunk_at_h
ead
(
fc
);
assert
((
ssize_t
)
n
>
0
&&
(
ssize_t
)
n
==
fl
->
count
(),
"Incorrect number of blocks"
);
assert
((
ssize_t
)
n
>
0
&&
(
ssize_t
)
n
==
fl
->
count
(),
"Incorrect number of blocks"
);
{
{
// Update the stats for this block size.
// Update the stats for this block size.
MutexLockerEx
x
(
_indexedFreeListParLocks
[
word_sz
],
MutexLockerEx
x
(
_indexedFreeListParLocks
[
word_sz
],
Mutex
::
_no_safepoint_check_flag
);
Mutex
::
_no_safepoint_check_flag
);
const
ssize_t
births
=
_indexedFreeList
[
word_sz
].
split
B
irths
()
+
n
;
const
ssize_t
births
=
_indexedFreeList
[
word_sz
].
split
_b
irths
()
+
n
;
_indexedFreeList
[
word_sz
].
set_split
B
irths
(
births
);
_indexedFreeList
[
word_sz
].
set_split
_b
irths
(
births
);
// ssize_t new_surplus = _indexedFreeList[word_sz].surplus() + n;
// ssize_t new_surplus = _indexedFreeList[word_sz].surplus() + n;
// _indexedFreeList[word_sz].set_surplus(new_surplus);
// _indexedFreeList[word_sz].set_surplus(new_surplus);
}
}
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
浏览文件 @
2c61150c
...
@@ -499,7 +499,7 @@ class CompactibleFreeListSpace: public CompactibleSpace {
...
@@ -499,7 +499,7 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// Verify that the given chunk is in the free lists:
// Verify that the given chunk is in the free lists:
// i.e. either the binary tree dictionary, the indexed free lists
// i.e. either the binary tree dictionary, the indexed free lists
// or the linear allocation block.
// or the linear allocation block.
bool
verify
ChunkInFreeLists
(
FreeChunk
*
fc
)
const
;
bool
verify
_chunk_in_free_list
(
FreeChunk
*
fc
)
const
;
// Verify that the given chunk is the linear allocation block
// Verify that the given chunk is the linear allocation block
bool
verify_chunk_is_linear_alloc_block
(
FreeChunk
*
fc
)
const
;
bool
verify_chunk_is_linear_alloc_block
(
FreeChunk
*
fc
)
const
;
// Do some basic checks on the the free lists.
// Do some basic checks on the the free lists.
...
@@ -608,7 +608,7 @@ class CompactibleFreeListSpace: public CompactibleSpace {
...
@@ -608,7 +608,7 @@ class CompactibleFreeListSpace: public CompactibleSpace {
void
coalDeath
(
size_t
size
);
void
coalDeath
(
size_t
size
);
void
smallSplitBirth
(
size_t
size
);
void
smallSplitBirth
(
size_t
size
);
void
smallSplitDeath
(
size_t
size
);
void
smallSplitDeath
(
size_t
size
);
void
split
B
irth
(
size_t
size
);
void
split
_b
irth
(
size_t
size
);
void
splitDeath
(
size_t
size
);
void
splitDeath
(
size_t
size
);
void
split
(
size_t
from
,
size_t
to1
);
void
split
(
size_t
from
,
size_t
to1
);
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
浏览文件 @
2c61150c
...
@@ -1026,7 +1026,7 @@ HeapWord* ConcurrentMarkSweepGeneration::have_lock_and_allocate(size_t size,
...
@@ -1026,7 +1026,7 @@ HeapWord* ConcurrentMarkSweepGeneration::have_lock_and_allocate(size_t size,
// its mark-bit or P-bits not yet set. Such objects need
// its mark-bit or P-bits not yet set. Such objects need
// to be safely navigable by block_start().
// to be safely navigable by block_start().
assert
(
oop
(
res
)
->
klass_or_null
()
==
NULL
,
"Object should be uninitialized here."
);
assert
(
oop
(
res
)
->
klass_or_null
()
==
NULL
,
"Object should be uninitialized here."
);
assert
(
!
((
FreeChunk
*
)
res
)
->
is
F
ree
(),
"Error, block will look free but show wrong size"
);
assert
(
!
((
FreeChunk
*
)
res
)
->
is
_f
ree
(),
"Error, block will look free but show wrong size"
);
collector
()
->
direct_allocated
(
res
,
adjustedSize
);
collector
()
->
direct_allocated
(
res
,
adjustedSize
);
_direct_allocated_words
+=
adjustedSize
;
_direct_allocated_words
+=
adjustedSize
;
// allocation counters
// allocation counters
...
@@ -1391,7 +1391,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
...
@@ -1391,7 +1391,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
oop
obj
=
oop
(
obj_ptr
);
oop
obj
=
oop
(
obj_ptr
);
OrderAccess
::
storestore
();
OrderAccess
::
storestore
();
assert
(
obj
->
klass_or_null
()
==
NULL
,
"Object should be uninitialized here."
);
assert
(
obj
->
klass_or_null
()
==
NULL
,
"Object should be uninitialized here."
);
assert
(
!
((
FreeChunk
*
)
obj_ptr
)
->
is
F
ree
(),
"Error, block will look free but show wrong size"
);
assert
(
!
((
FreeChunk
*
)
obj_ptr
)
->
is
_f
ree
(),
"Error, block will look free but show wrong size"
);
// IMPORTANT: See note on object initialization for CMS above.
// IMPORTANT: See note on object initialization for CMS above.
// Otherwise, copy the object. Here we must be careful to insert the
// Otherwise, copy the object. Here we must be careful to insert the
// klass pointer last, since this marks the block as an allocated object.
// klass pointer last, since this marks the block as an allocated object.
...
@@ -1400,7 +1400,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
...
@@ -1400,7 +1400,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
// Restore the mark word copied above.
// Restore the mark word copied above.
obj
->
set_mark
(
m
);
obj
->
set_mark
(
m
);
assert
(
obj
->
klass_or_null
()
==
NULL
,
"Object should be uninitialized here."
);
assert
(
obj
->
klass_or_null
()
==
NULL
,
"Object should be uninitialized here."
);
assert
(
!
((
FreeChunk
*
)
obj_ptr
)
->
is
F
ree
(),
"Error, block will look free but show wrong size"
);
assert
(
!
((
FreeChunk
*
)
obj_ptr
)
->
is
_f
ree
(),
"Error, block will look free but show wrong size"
);
OrderAccess
::
storestore
();
OrderAccess
::
storestore
();
if
(
UseCompressedOops
)
{
if
(
UseCompressedOops
)
{
...
@@ -1421,7 +1421,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
...
@@ -1421,7 +1421,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
promoInfo
->
track
((
PromotedObject
*
)
obj
,
old
->
klass
());
promoInfo
->
track
((
PromotedObject
*
)
obj
,
old
->
klass
());
}
}
assert
(
obj
->
klass_or_null
()
==
NULL
,
"Object should be uninitialized here."
);
assert
(
obj
->
klass_or_null
()
==
NULL
,
"Object should be uninitialized here."
);
assert
(
!
((
FreeChunk
*
)
obj_ptr
)
->
is
F
ree
(),
"Error, block will look free but show wrong size"
);
assert
(
!
((
FreeChunk
*
)
obj_ptr
)
->
is
_f
ree
(),
"Error, block will look free but show wrong size"
);
assert
(
old
->
is_oop
(),
"Will use and dereference old klass ptr below"
);
assert
(
old
->
is_oop
(),
"Will use and dereference old klass ptr below"
);
// Finally, install the klass pointer (this should be volatile).
// Finally, install the klass pointer (this should be volatile).
...
@@ -2034,7 +2034,7 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
...
@@ -2034,7 +2034,7 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
pointer_delta
(
cms_space
->
end
(),
cms_space
->
compaction_top
())
pointer_delta
(
cms_space
->
end
(),
cms_space
->
compaction_top
())
*
HeapWordSize
,
*
HeapWordSize
,
"All the free space should be compacted into one chunk at top"
);
"All the free space should be compacted into one chunk at top"
);
assert
(
cms_space
->
dictionary
()
->
total
ChunkS
ize
(
assert
(
cms_space
->
dictionary
()
->
total
_chunk_s
ize
(
debug_only
(
cms_space
->
freelistLock
()))
==
0
||
debug_only
(
cms_space
->
freelistLock
()))
==
0
||
cms_space
->
totalSizeInIndexedFreeLists
()
==
0
,
cms_space
->
totalSizeInIndexedFreeLists
()
==
0
,
"All the free space should be in a single chunk"
);
"All the free space should be in a single chunk"
);
...
@@ -6131,7 +6131,7 @@ void ConcurrentMarkSweepGeneration::setNearLargestChunk() {
...
@@ -6131,7 +6131,7 @@ void ConcurrentMarkSweepGeneration::setNearLargestChunk() {
double
nearLargestPercent
=
FLSLargestBlockCoalesceProximity
;
double
nearLargestPercent
=
FLSLargestBlockCoalesceProximity
;
HeapWord
*
minAddr
=
_cmsSpace
->
bottom
();
HeapWord
*
minAddr
=
_cmsSpace
->
bottom
();
HeapWord
*
largestAddr
=
HeapWord
*
largestAddr
=
(
HeapWord
*
)
_cmsSpace
->
dictionary
()
->
find
LargestD
ict
();
(
HeapWord
*
)
_cmsSpace
->
dictionary
()
->
find
_largest_d
ict
();
if
(
largestAddr
==
NULL
)
{
if
(
largestAddr
==
NULL
)
{
// The dictionary appears to be empty. In this case
// The dictionary appears to be empty. In this case
// try to coalesce at the end of the heap.
// try to coalesce at the end of the heap.
...
@@ -7906,7 +7906,7 @@ SweepClosure::SweepClosure(CMSCollector* collector,
...
@@ -7906,7 +7906,7 @@ SweepClosure::SweepClosure(CMSCollector* collector,
_last_fc
=
NULL
;
_last_fc
=
NULL
;
_sp
->
initializeIndexedFreeListArrayReturnedBytes
();
_sp
->
initializeIndexedFreeListArrayReturnedBytes
();
_sp
->
dictionary
()
->
initialize
DictReturnedB
ytes
();
_sp
->
dictionary
()
->
initialize
_dict_returned_b
ytes
();
)
)
assert
(
_limit
>=
_sp
->
bottom
()
&&
_limit
<=
_sp
->
end
(),
assert
(
_limit
>=
_sp
->
bottom
()
&&
_limit
<=
_sp
->
end
(),
"sweep _limit out of bounds"
);
"sweep _limit out of bounds"
);
...
@@ -7954,13 +7954,13 @@ SweepClosure::~SweepClosure() {
...
@@ -7954,13 +7954,13 @@ SweepClosure::~SweepClosure() {
if
(
PrintCMSStatistics
&&
CMSVerifyReturnedBytes
)
{
if
(
PrintCMSStatistics
&&
CMSVerifyReturnedBytes
)
{
size_t
indexListReturnedBytes
=
_sp
->
sumIndexedFreeListArrayReturnedBytes
();
size_t
indexListReturnedBytes
=
_sp
->
sumIndexedFreeListArrayReturnedBytes
();
size_t
dict
ReturnedBytes
=
_sp
->
dictionary
()
->
sumDictReturnedB
ytes
();
size_t
dict
_returned_bytes
=
_sp
->
dictionary
()
->
sum_dict_returned_b
ytes
();
size_t
returned
Bytes
=
indexListReturnedBytes
+
dictReturnedB
ytes
;
size_t
returned
_bytes
=
indexListReturnedBytes
+
dict_returned_b
ytes
;
gclog_or_tty
->
print
(
"Returned "
SIZE_FORMAT
" bytes"
,
returned
B
ytes
);
gclog_or_tty
->
print
(
"Returned "
SIZE_FORMAT
" bytes"
,
returned
_b
ytes
);
gclog_or_tty
->
print
(
" Indexed List Returned "
SIZE_FORMAT
" bytes"
,
gclog_or_tty
->
print
(
" Indexed List Returned "
SIZE_FORMAT
" bytes"
,
indexListReturnedBytes
);
indexListReturnedBytes
);
gclog_or_tty
->
print_cr
(
" Dictionary Returned "
SIZE_FORMAT
" bytes"
,
gclog_or_tty
->
print_cr
(
" Dictionary Returned "
SIZE_FORMAT
" bytes"
,
dict
ReturnedB
ytes
);
dict
_returned_b
ytes
);
}
}
}
}
if
(
CMSTraceSweeper
)
{
if
(
CMSTraceSweeper
)
{
...
@@ -7985,9 +7985,9 @@ void SweepClosure::initialize_free_range(HeapWord* freeFinger,
...
@@ -7985,9 +7985,9 @@ void SweepClosure::initialize_free_range(HeapWord* freeFinger,
if
(
CMSTestInFreeList
)
{
if
(
CMSTestInFreeList
)
{
if
(
freeRangeInFreeLists
)
{
if
(
freeRangeInFreeLists
)
{
FreeChunk
*
fc
=
(
FreeChunk
*
)
freeFinger
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
freeFinger
;
assert
(
fc
->
is
F
ree
(),
"A chunk on the free list should be free."
);
assert
(
fc
->
is
_f
ree
(),
"A chunk on the free list should be free."
);
assert
(
fc
->
size
()
>
0
,
"Free range should have a size"
);
assert
(
fc
->
size
()
>
0
,
"Free range should have a size"
);
assert
(
_sp
->
verify
ChunkInFreeLists
(
fc
),
"Chunk is not in free lists"
);
assert
(
_sp
->
verify
_chunk_in_free_list
(
fc
),
"Chunk is not in free lists"
);
}
}
}
}
}
}
...
@@ -8057,7 +8057,7 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
...
@@ -8057,7 +8057,7 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
assert
(
addr
<
_limit
,
"sweep invariant"
);
assert
(
addr
<
_limit
,
"sweep invariant"
);
// check if we should yield
// check if we should yield
do_yield_check
(
addr
);
do_yield_check
(
addr
);
if
(
fc
->
is
F
ree
())
{
if
(
fc
->
is
_f
ree
())
{
// Chunk that is already free
// Chunk that is already free
res
=
fc
->
size
();
res
=
fc
->
size
();
do_already_free_chunk
(
fc
);
do_already_free_chunk
(
fc
);
...
@@ -8145,7 +8145,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
...
@@ -8145,7 +8145,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
// 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
())
{
assert
(
_sp
->
verify
ChunkInFreeLists
(
fc
),
assert
(
_sp
->
verify
_chunk_in_free_list
(
fc
),
"free chunk should be in free lists"
);
"free chunk should be in free lists"
);
}
}
// a chunk that is already free, should not have been
// a chunk that is already free, should not have been
...
@@ -8171,7 +8171,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
...
@@ -8171,7 +8171,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
FreeChunk
*
nextChunk
=
(
FreeChunk
*
)(
addr
+
size
);
FreeChunk
*
nextChunk
=
(
FreeChunk
*
)(
addr
+
size
);
assert
((
HeapWord
*
)
nextChunk
<=
_sp
->
end
(),
"Chunk size out of bounds?"
);
assert
((
HeapWord
*
)
nextChunk
<=
_sp
->
end
(),
"Chunk size out of bounds?"
);
if
((
HeapWord
*
)
nextChunk
<
_sp
->
end
()
&&
// There is another free chunk to the right ...
if
((
HeapWord
*
)
nextChunk
<
_sp
->
end
()
&&
// There is another free chunk to the right ...
nextChunk
->
is
F
ree
()
&&
// ... which is free...
nextChunk
->
is
_f
ree
()
&&
// ... which is free...
nextChunk
->
cantCoalesce
())
{
// ... but can't be coalesced
nextChunk
->
cantCoalesce
())
{
// ... but can't be coalesced
// nothing to do
// nothing to do
}
else
{
}
else
{
...
@@ -8203,7 +8203,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
...
@@ -8203,7 +8203,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
assert
(
ffc
->
size
()
==
pointer_delta
(
addr
,
freeFinger
()),
assert
(
ffc
->
size
()
==
pointer_delta
(
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
->
verify
ChunkInFreeLists
(
ffc
),
assert
(
_sp
->
verify
_chunk_in_free_list
(
ffc
),
"free range is not in free lists"
);
"free range is not in free lists"
);
}
}
_sp
->
removeFreeChunkFromFreeLists
(
ffc
);
_sp
->
removeFreeChunkFromFreeLists
(
ffc
);
...
@@ -8262,7 +8262,7 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
...
@@ -8262,7 +8262,7 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
assert
(
ffc
->
size
()
==
pointer_delta
(
addr
,
freeFinger
()),
assert
(
ffc
->
size
()
==
pointer_delta
(
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
->
verify
ChunkInFreeLists
(
ffc
),
assert
(
_sp
->
verify
_chunk_in_free_list
(
ffc
),
"free range is not in free lists"
);
"free range is not in free lists"
);
}
}
_sp
->
removeFreeChunkFromFreeLists
(
ffc
);
_sp
->
removeFreeChunkFromFreeLists
(
ffc
);
...
@@ -8351,11 +8351,11 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
...
@@ -8351,11 +8351,11 @@ 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.
const
bool
fcInFreeLists
=
fc
->
is
F
ree
();
const
bool
fcInFreeLists
=
fc
->
is
_f
ree
();
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
)
{
assert
(
_sp
->
verify
ChunkInFreeLists
(
fc
),
"free chunk is not in free lists"
);
assert
(
_sp
->
verify
_chunk_in_free_list
(
fc
),
"free chunk is not in free lists"
);
}
}
if
(
CMSTraceSweeper
)
{
if
(
CMSTraceSweeper
)
{
...
@@ -8410,7 +8410,7 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
...
@@ -8410,7 +8410,7 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
assert
(
ffc
->
size
()
==
pointer_delta
(
fc_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
->
verify
ChunkInFreeLists
(
ffc
),
assert
(
_sp
->
verify
_chunk_in_free_list
(
ffc
),
"Chunk is not in free lists"
);
"Chunk is not in free lists"
);
}
}
_sp
->
coalDeath
(
ffc
->
size
());
_sp
->
coalDeath
(
ffc
->
size
());
...
@@ -8459,7 +8459,7 @@ void SweepClosure::lookahead_and_flush(FreeChunk* fc, size_t chunk_size) {
...
@@ -8459,7 +8459,7 @@ void SweepClosure::lookahead_and_flush(FreeChunk* fc, size_t chunk_size) {
" when examining fc = "
PTR_FORMAT
"("
SIZE_FORMAT
")"
,
" when examining fc = "
PTR_FORMAT
"("
SIZE_FORMAT
")"
,
_limit
,
_sp
->
bottom
(),
_sp
->
end
(),
fc
,
chunk_size
));
_limit
,
_sp
->
bottom
(),
_sp
->
end
(),
fc
,
chunk_size
));
if
(
eob
>=
_limit
)
{
if
(
eob
>=
_limit
)
{
assert
(
eob
==
_limit
||
fc
->
is
F
ree
(),
"Only a free chunk should allow us to cross over the limit"
);
assert
(
eob
==
_limit
||
fc
->
is
_f
ree
(),
"Only a free chunk should allow us to cross over the limit"
);
if
(
CMSTraceSweeper
)
{
if
(
CMSTraceSweeper
)
{
gclog_or_tty
->
print_cr
(
"_limit "
PTR_FORMAT
" reached or crossed by block "
gclog_or_tty
->
print_cr
(
"_limit "
PTR_FORMAT
" reached or crossed by block "
"["
PTR_FORMAT
","
PTR_FORMAT
") in space "
"["
PTR_FORMAT
","
PTR_FORMAT
") in space "
...
@@ -8482,8 +8482,8 @@ void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) {
...
@@ -8482,8 +8482,8 @@ void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) {
if
(
!
freeRangeInFreeLists
())
{
if
(
!
freeRangeInFreeLists
())
{
if
(
CMSTestInFreeList
)
{
if
(
CMSTestInFreeList
)
{
FreeChunk
*
fc
=
(
FreeChunk
*
)
chunk
;
FreeChunk
*
fc
=
(
FreeChunk
*
)
chunk
;
fc
->
set
S
ize
(
size
);
fc
->
set
_s
ize
(
size
);
assert
(
!
_sp
->
verify
ChunkInFreeLists
(
fc
),
assert
(
!
_sp
->
verify
_chunk_in_free_list
(
fc
),
"chunk should not be in free lists yet"
);
"chunk should not be in free lists yet"
);
}
}
if
(
CMSTraceSweeper
)
{
if
(
CMSTraceSweeper
)
{
...
@@ -8557,8 +8557,8 @@ void SweepClosure::do_yield_work(HeapWord* addr) {
...
@@ -8557,8 +8557,8 @@ void SweepClosure::do_yield_work(HeapWord* addr) {
// This is actually very useful in a product build if it can
// This is actually very useful in a product build if it can
// be called from the debugger. Compile it into the product
// be called from the debugger. Compile it into the product
// as needed.
// as needed.
bool
debug_verify
ChunkInFreeLists
(
FreeChunk
*
fc
)
{
bool
debug_verify
_chunk_in_free_list
(
FreeChunk
*
fc
)
{
return
debug_cms_space
->
verify
ChunkInFreeLists
(
fc
);
return
debug_cms_space
->
verify
_chunk_in_free_list
(
fc
);
}
}
#endif
#endif
...
@@ -9255,7 +9255,7 @@ void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) {
...
@@ -9255,7 +9255,7 @@ void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) {
size_t
chunk_at_end_old_size
=
chunk_at_end
->
size
();
size_t
chunk_at_end_old_size
=
chunk_at_end
->
size
();
assert
(
chunk_at_end_old_size
>=
word_size_change
,
assert
(
chunk_at_end_old_size
>=
word_size_change
,
"Shrink is too large"
);
"Shrink is too large"
);
chunk_at_end
->
set
S
ize
(
chunk_at_end_old_size
-
chunk_at_end
->
set
_s
ize
(
chunk_at_end_old_size
-
word_size_change
);
word_size_change
);
_cmsSpace
->
freed
((
HeapWord
*
)
chunk_at_end
->
end
(),
_cmsSpace
->
freed
((
HeapWord
*
)
chunk_at_end
->
end
(),
word_size_change
);
word_size_change
);
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp
浏览文件 @
2c61150c
...
@@ -75,20 +75,20 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC {
...
@@ -75,20 +75,20 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC {
// calls. We really want the read of _mark and _prev from this pointer
// calls. We really want the read of _mark and _prev from this pointer
// to be volatile but making the fields volatile causes all sorts of
// to be volatile but making the fields volatile causes all sorts of
// compilation errors.
// compilation errors.
return
((
volatile
FreeChunk
*
)
addr
)
->
is
F
ree
();
return
((
volatile
FreeChunk
*
)
addr
)
->
is
_f
ree
();
}
}
bool
is
F
ree
()
const
volatile
{
bool
is
_f
ree
()
const
volatile
{
LP64_ONLY
(
if
(
UseCompressedOops
)
return
mark
()
->
is_cms_free_chunk
();
else
)
LP64_ONLY
(
if
(
UseCompressedOops
)
return
mark
()
->
is_cms_free_chunk
();
else
)
return
(((
intptr_t
)
_prev
)
&
0x1
)
==
0x1
;
return
(((
intptr_t
)
_prev
)
&
0x1
)
==
0x1
;
}
}
bool
cantCoalesce
()
const
{
bool
cantCoalesce
()
const
{
assert
(
is
F
ree
(),
"can't get coalesce bit on not free"
);
assert
(
is
_f
ree
(),
"can't get coalesce bit on not free"
);
return
(((
intptr_t
)
_prev
)
&
0x2
)
==
0x2
;
return
(((
intptr_t
)
_prev
)
&
0x2
)
==
0x2
;
}
}
void
dontCoalesce
()
{
void
dontCoalesce
()
{
// the block should be free
// the block should be free
assert
(
is
F
ree
(),
"Should look like a free block"
);
assert
(
is
_f
ree
(),
"Should look like a free block"
);
_prev
=
(
FreeChunk
*
)(((
intptr_t
)
_prev
)
|
0x2
);
_prev
=
(
FreeChunk
*
)(((
intptr_t
)
_prev
)
|
0x2
);
}
}
FreeChunk
*
prev
()
const
{
FreeChunk
*
prev
()
const
{
...
@@ -103,23 +103,23 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC {
...
@@ -103,23 +103,23 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC {
LP64_ONLY
(
if
(
UseCompressedOops
)
return
mark
()
->
get_size
();
else
)
LP64_ONLY
(
if
(
UseCompressedOops
)
return
mark
()
->
get_size
();
else
)
return
_size
;
return
_size
;
}
}
void
set
S
ize
(
size_t
sz
)
{
void
set
_s
ize
(
size_t
sz
)
{
LP64_ONLY
(
if
(
UseCompressedOops
)
set_mark
(
markOopDesc
::
set_size_and_free
(
sz
));
else
)
LP64_ONLY
(
if
(
UseCompressedOops
)
set_mark
(
markOopDesc
::
set_size_and_free
(
sz
));
else
)
_size
=
sz
;
_size
=
sz
;
}
}
FreeChunk
*
next
()
const
{
return
_next
;
}
FreeChunk
*
next
()
const
{
return
_next
;
}
void
link
A
fter
(
FreeChunk
*
ptr
)
{
void
link
_a
fter
(
FreeChunk
*
ptr
)
{
link
N
ext
(
ptr
);
link
_n
ext
(
ptr
);
if
(
ptr
!=
NULL
)
ptr
->
link
P
rev
(
this
);
if
(
ptr
!=
NULL
)
ptr
->
link
_p
rev
(
this
);
}
}
void
link
N
ext
(
FreeChunk
*
ptr
)
{
_next
=
ptr
;
}
void
link
_n
ext
(
FreeChunk
*
ptr
)
{
_next
=
ptr
;
}
void
link
P
rev
(
FreeChunk
*
ptr
)
{
void
link
_p
rev
(
FreeChunk
*
ptr
)
{
LP64_ONLY
(
if
(
UseCompressedOops
)
_prev
=
ptr
;
else
)
LP64_ONLY
(
if
(
UseCompressedOops
)
_prev
=
ptr
;
else
)
_prev
=
(
FreeChunk
*
)((
intptr_t
)
ptr
|
0x1
);
_prev
=
(
FreeChunk
*
)((
intptr_t
)
ptr
|
0x1
);
}
}
void
clear
N
ext
()
{
_next
=
NULL
;
}
void
clear
_n
ext
()
{
_next
=
NULL
;
}
void
markNotFree
()
{
void
markNotFree
()
{
// Set _prev (klass) to null before (if) clearing the mark word below
// Set _prev (klass) to null before (if) clearing the mark word below
_prev
=
NULL
;
_prev
=
NULL
;
...
@@ -129,7 +129,7 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC {
...
@@ -129,7 +129,7 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC {
set_mark
(
markOopDesc
::
prototype
());
set_mark
(
markOopDesc
::
prototype
());
}
}
#endif
#endif
assert
(
!
is
F
ree
(),
"Error"
);
assert
(
!
is
_f
ree
(),
"Error"
);
}
}
// Return the address past the end of this chunk
// Return the address past the end of this chunk
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp
浏览文件 @
2c61150c
...
@@ -121,7 +121,7 @@ void PromotionInfo::track(PromotedObject* trackOop) {
...
@@ -121,7 +121,7 @@ void PromotionInfo::track(PromotedObject* trackOop) {
void
PromotionInfo
::
track
(
PromotedObject
*
trackOop
,
klassOop
klassOfOop
)
{
void
PromotionInfo
::
track
(
PromotedObject
*
trackOop
,
klassOop
klassOfOop
)
{
// make a copy of header as it may need to be spooled
// make a copy of header as it may need to be spooled
markOop
mark
=
oop
(
trackOop
)
->
mark
();
markOop
mark
=
oop
(
trackOop
)
->
mark
();
trackOop
->
clear
N
ext
();
trackOop
->
clear
_n
ext
();
if
(
mark
->
must_be_preserved_for_cms_scavenge
(
klassOfOop
))
{
if
(
mark
->
must_be_preserved_for_cms_scavenge
(
klassOfOop
))
{
// save non-prototypical header, and mark oop
// save non-prototypical header, and mark oop
saveDisplacedHeader
(
mark
);
saveDisplacedHeader
(
mark
);
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp
浏览文件 @
2c61150c
...
@@ -43,7 +43,7 @@ class PromotedObject VALUE_OBJ_CLASS_SPEC {
...
@@ -43,7 +43,7 @@ class PromotedObject VALUE_OBJ_CLASS_SPEC {
// whose position will depend on endian-ness of the platform.
// whose position will depend on endian-ness of the platform.
// This is so that there is no interference with the
// This is so that there is no interference with the
// cms_free_bit occupying bit position 7 (lsb == 0)
// cms_free_bit occupying bit position 7 (lsb == 0)
// when we are using compressed oops; see FreeChunk::is
F
ree().
// when we are using compressed oops; see FreeChunk::is
_f
ree().
// We cannot move the cms_free_bit down because currently
// We cannot move the cms_free_bit down because currently
// biased locking code assumes that age bits are contiguous
// biased locking code assumes that age bits are contiguous
// with the lock bits. Even if that assumption were relaxed,
// with the lock bits. Even if that assumption were relaxed,
...
@@ -65,7 +65,7 @@ class PromotedObject VALUE_OBJ_CLASS_SPEC {
...
@@ -65,7 +65,7 @@ class PromotedObject VALUE_OBJ_CLASS_SPEC {
};
};
public:
public:
inline
PromotedObject
*
next
()
const
{
inline
PromotedObject
*
next
()
const
{
assert
(
!
((
FreeChunk
*
)
this
)
->
is
F
ree
(),
"Error"
);
assert
(
!
((
FreeChunk
*
)
this
)
->
is
_f
ree
(),
"Error"
);
PromotedObject
*
res
;
PromotedObject
*
res
;
if
(
UseCompressedOops
)
{
if
(
UseCompressedOops
)
{
// The next pointer is a compressed oop stored in the top 32 bits
// The next pointer is a compressed oop stored in the top 32 bits
...
@@ -85,27 +85,27 @@ class PromotedObject VALUE_OBJ_CLASS_SPEC {
...
@@ -85,27 +85,27 @@ class PromotedObject VALUE_OBJ_CLASS_SPEC {
}
else
{
}
else
{
_next
|=
(
intptr_t
)
x
;
_next
|=
(
intptr_t
)
x
;
}
}
assert
(
!
((
FreeChunk
*
)
this
)
->
is
F
ree
(),
"Error"
);
assert
(
!
((
FreeChunk
*
)
this
)
->
is
_f
ree
(),
"Error"
);
}
}
inline
void
setPromotedMark
()
{
inline
void
setPromotedMark
()
{
_next
|=
promoted_mask
;
_next
|=
promoted_mask
;
assert
(
!
((
FreeChunk
*
)
this
)
->
is
F
ree
(),
"Error"
);
assert
(
!
((
FreeChunk
*
)
this
)
->
is
_f
ree
(),
"Error"
);
}
}
inline
bool
hasPromotedMark
()
const
{
inline
bool
hasPromotedMark
()
const
{
assert
(
!
((
FreeChunk
*
)
this
)
->
is
F
ree
(),
"Error"
);
assert
(
!
((
FreeChunk
*
)
this
)
->
is
_f
ree
(),
"Error"
);
return
(
_next
&
promoted_mask
)
==
promoted_mask
;
return
(
_next
&
promoted_mask
)
==
promoted_mask
;
}
}
inline
void
setDisplacedMark
()
{
inline
void
setDisplacedMark
()
{
_next
|=
displaced_mark
;
_next
|=
displaced_mark
;
assert
(
!
((
FreeChunk
*
)
this
)
->
is
F
ree
(),
"Error"
);
assert
(
!
((
FreeChunk
*
)
this
)
->
is
_f
ree
(),
"Error"
);
}
}
inline
bool
hasDisplacedMark
()
const
{
inline
bool
hasDisplacedMark
()
const
{
assert
(
!
((
FreeChunk
*
)
this
)
->
is
F
ree
(),
"Error"
);
assert
(
!
((
FreeChunk
*
)
this
)
->
is
_f
ree
(),
"Error"
);
return
(
_next
&
displaced_mark
)
!=
0
;
return
(
_next
&
displaced_mark
)
!=
0
;
}
}
inline
void
clear
N
ext
()
{
inline
void
clear
_n
ext
()
{
_next
=
0
;
_next
=
0
;
assert
(
!
((
FreeChunk
*
)
this
)
->
is
F
ree
(),
"Error"
);
assert
(
!
((
FreeChunk
*
)
this
)
->
is
_f
ree
(),
"Error"
);
}
}
debug_only
(
void
*
next_addr
()
{
return
(
void
*
)
&
_next
;
})
debug_only
(
void
*
next_addr
()
{
return
(
void
*
)
&
_next
;
})
};
};
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
浏览文件 @
2c61150c
...
@@ -46,7 +46,7 @@
...
@@ -46,7 +46,7 @@
nonstatic_field(LinearAllocBlock, _word_size, size_t) \
nonstatic_field(LinearAllocBlock, _word_size, size_t) \
nonstatic_field(FreeList<FreeChunk>, _size, size_t) \
nonstatic_field(FreeList<FreeChunk>, _size, size_t) \
nonstatic_field(FreeList<FreeChunk>, _count, ssize_t) \
nonstatic_field(FreeList<FreeChunk>, _count, ssize_t) \
nonstatic_field(BinaryTreeDictionary<FreeChunk>,_total
S
ize, size_t) \
nonstatic_field(BinaryTreeDictionary<FreeChunk>,_total
_s
ize, size_t) \
nonstatic_field(CompactibleFreeListSpace, _dictionary, FreeBlockDictionary<FreeChunk>*) \
nonstatic_field(CompactibleFreeListSpace, _dictionary, FreeBlockDictionary<FreeChunk>*) \
nonstatic_field(CompactibleFreeListSpace, _indexedFreeList[0], FreeList<FreeChunk>) \
nonstatic_field(CompactibleFreeListSpace, _indexedFreeList[0], FreeList<FreeChunk>) \
nonstatic_field(CompactibleFreeListSpace, _smallLinearAllocBlock, LinearAllocBlock)
nonstatic_field(CompactibleFreeListSpace, _smallLinearAllocBlock, LinearAllocBlock)
...
...
src/share/vm/gc_implementation/shared/allocationStats.hpp
浏览文件 @
2c61150c
...
@@ -39,7 +39,7 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
...
@@ -39,7 +39,7 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
// We measure the demand between the end of the previous sweep and
// We measure the demand between the end of the previous sweep and
// beginning of this sweep:
// beginning of this sweep:
// Count(end_last_sweep) - Count(start_this_sweep)
// Count(end_last_sweep) - Count(start_this_sweep)
// + split
Births(between) - splitD
eaths(between)
// + split
_births(between) - split_d
eaths(between)
// The above number divided by the time since the end of the
// The above number divided by the time since the end of the
// previous sweep gives us a time rate of demand for blocks
// previous sweep gives us a time rate of demand for blocks
// of this size. We compute a padded average of this rate as
// of this size. We compute a padded average of this rate as
...
@@ -51,34 +51,34 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
...
@@ -51,34 +51,34 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
AdaptivePaddedAverage
_demand_rate_estimate
;
AdaptivePaddedAverage
_demand_rate_estimate
;
ssize_t
_desired
;
// Demand stimate computed as described above
ssize_t
_desired
;
// Demand stimate computed as described above
ssize_t
_coal
D
esired
;
// desired +/- small-percent for tuning coalescing
ssize_t
_coal
_d
esired
;
// desired +/- small-percent for tuning coalescing
ssize_t
_surplus
;
// count - (desired +/- small-percent),
ssize_t
_surplus
;
// count - (desired +/- small-percent),
// used to tune splitting in best fit
// used to tune splitting in best fit
ssize_t
_bfr
S
urp
;
// surplus at start of current sweep
ssize_t
_bfr
_s
urp
;
// surplus at start of current sweep
ssize_t
_prev
S
weep
;
// count from end of previous sweep
ssize_t
_prev
_s
weep
;
// count from end of previous sweep
ssize_t
_before
S
weep
;
// count from before current sweep
ssize_t
_before
_s
weep
;
// count from before current sweep
ssize_t
_coal
B
irths
;
// additional chunks from coalescing
ssize_t
_coal
_b
irths
;
// additional chunks from coalescing
ssize_t
_coal
D
eaths
;
// loss from coalescing
ssize_t
_coal
_d
eaths
;
// loss from coalescing
ssize_t
_split
B
irths
;
// additional chunks from splitting
ssize_t
_split
_b
irths
;
// additional chunks from splitting
ssize_t
_split
D
eaths
;
// loss from splitting
ssize_t
_split
_d
eaths
;
// loss from splitting
size_t
_returned
B
ytes
;
// number of bytes returned to list.
size_t
_returned
_b
ytes
;
// number of bytes returned to list.
public:
public:
void
initialize
(
bool
split_birth
=
false
)
{
void
initialize
(
bool
split_birth
=
false
)
{
AdaptivePaddedAverage
*
dummy
=
AdaptivePaddedAverage
*
dummy
=
new
(
&
_demand_rate_estimate
)
AdaptivePaddedAverage
(
CMS_FLSWeight
,
new
(
&
_demand_rate_estimate
)
AdaptivePaddedAverage
(
CMS_FLSWeight
,
CMS_FLSPadding
);
CMS_FLSPadding
);
_desired
=
0
;
_desired
=
0
;
_coal
D
esired
=
0
;
_coal
_d
esired
=
0
;
_surplus
=
0
;
_surplus
=
0
;
_bfr
S
urp
=
0
;
_bfr
_s
urp
=
0
;
_prev
S
weep
=
0
;
_prev
_s
weep
=
0
;
_before
S
weep
=
0
;
_before
_s
weep
=
0
;
_coal
B
irths
=
0
;
_coal
_b
irths
=
0
;
_coal
D
eaths
=
0
;
_coal
_d
eaths
=
0
;
_split
B
irths
=
(
split_birth
?
1
:
0
);
_split
_b
irths
=
(
split_birth
?
1
:
0
);
_split
D
eaths
=
0
;
_split
_d
eaths
=
0
;
_returned
B
ytes
=
0
;
_returned
_b
ytes
=
0
;
}
}
AllocationStats
()
{
AllocationStats
()
{
...
@@ -99,12 +99,12 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
...
@@ -99,12 +99,12 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
// vulnerable to noisy glitches. In such cases, we
// vulnerable to noisy glitches. In such cases, we
// ignore the current sample and use currently available
// ignore the current sample and use currently available
// historical estimates.
// historical estimates.
assert
(
prev
Sweep
()
+
splitBirths
()
+
coalB
irths
()
// "Total Production Stock"
assert
(
prev
_sweep
()
+
split_births
()
+
coal_b
irths
()
// "Total Production Stock"
>=
split
Deaths
()
+
coalD
eaths
()
+
(
ssize_t
)
count
,
// "Current stock + depletion"
>=
split
_deaths
()
+
coal_d
eaths
()
+
(
ssize_t
)
count
,
// "Current stock + depletion"
"Conservation Principle"
);
"Conservation Principle"
);
if
(
inter_sweep_current
>
_threshold
)
{
if
(
inter_sweep_current
>
_threshold
)
{
ssize_t
demand
=
prev
Sweep
()
-
(
ssize_t
)
count
+
splitBirths
()
+
coalB
irths
()
ssize_t
demand
=
prev
_sweep
()
-
(
ssize_t
)
count
+
split_births
()
+
coal_b
irths
()
-
split
Deaths
()
-
coalD
eaths
();
-
split
_deaths
()
-
coal_d
eaths
();
assert
(
demand
>=
0
,
assert
(
demand
>=
0
,
err_msg
(
"Demand ("
SSIZE_FORMAT
") should be non-negative for "
err_msg
(
"Demand ("
SSIZE_FORMAT
") should be non-negative for "
PTR_FORMAT
" (size="
SIZE_FORMAT
")"
,
PTR_FORMAT
" (size="
SIZE_FORMAT
")"
,
...
@@ -130,40 +130,40 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
...
@@ -130,40 +130,40 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
ssize_t
desired
()
const
{
return
_desired
;
}
ssize_t
desired
()
const
{
return
_desired
;
}
void
set_desired
(
ssize_t
v
)
{
_desired
=
v
;
}
void
set_desired
(
ssize_t
v
)
{
_desired
=
v
;
}
ssize_t
coal
Desired
()
const
{
return
_coalD
esired
;
}
ssize_t
coal
_desired
()
const
{
return
_coal_d
esired
;
}
void
set_coal
Desired
(
ssize_t
v
)
{
_coalD
esired
=
v
;
}
void
set_coal
_desired
(
ssize_t
v
)
{
_coal_d
esired
=
v
;
}
ssize_t
surplus
()
const
{
return
_surplus
;
}
ssize_t
surplus
()
const
{
return
_surplus
;
}
void
set_surplus
(
ssize_t
v
)
{
_surplus
=
v
;
}
void
set_surplus
(
ssize_t
v
)
{
_surplus
=
v
;
}
void
increment_surplus
()
{
_surplus
++
;
}
void
increment_surplus
()
{
_surplus
++
;
}
void
decrement_surplus
()
{
_surplus
--
;
}
void
decrement_surplus
()
{
_surplus
--
;
}
ssize_t
bfr
Surp
()
const
{
return
_bfrS
urp
;
}
ssize_t
bfr
_surp
()
const
{
return
_bfr_s
urp
;
}
void
set_bfr
Surp
(
ssize_t
v
)
{
_bfrS
urp
=
v
;
}
void
set_bfr
_surp
(
ssize_t
v
)
{
_bfr_s
urp
=
v
;
}
ssize_t
prev
Sweep
()
const
{
return
_prevS
weep
;
}
ssize_t
prev
_sweep
()
const
{
return
_prev_s
weep
;
}
void
set_prev
Sweep
(
ssize_t
v
)
{
_prevS
weep
=
v
;
}
void
set_prev
_sweep
(
ssize_t
v
)
{
_prev_s
weep
=
v
;
}
ssize_t
before
Sweep
()
const
{
return
_beforeS
weep
;
}
ssize_t
before
_sweep
()
const
{
return
_before_s
weep
;
}
void
set_before
Sweep
(
ssize_t
v
)
{
_beforeS
weep
=
v
;
}
void
set_before
_sweep
(
ssize_t
v
)
{
_before_s
weep
=
v
;
}
ssize_t
coal
Births
()
const
{
return
_coalB
irths
;
}
ssize_t
coal
_births
()
const
{
return
_coal_b
irths
;
}
void
set_coal
Births
(
ssize_t
v
)
{
_coalB
irths
=
v
;
}
void
set_coal
_births
(
ssize_t
v
)
{
_coal_b
irths
=
v
;
}
void
increment_coal
Births
()
{
_coalB
irths
++
;
}
void
increment_coal
_births
()
{
_coal_b
irths
++
;
}
ssize_t
coal
Deaths
()
const
{
return
_coalD
eaths
;
}
ssize_t
coal
_deaths
()
const
{
return
_coal_d
eaths
;
}
void
set_coal
Deaths
(
ssize_t
v
)
{
_coalD
eaths
=
v
;
}
void
set_coal
_deaths
(
ssize_t
v
)
{
_coal_d
eaths
=
v
;
}
void
increment_coal
Deaths
()
{
_coalD
eaths
++
;
}
void
increment_coal
_deaths
()
{
_coal_d
eaths
++
;
}
ssize_t
split
Births
()
const
{
return
_splitB
irths
;
}
ssize_t
split
_births
()
const
{
return
_split_b
irths
;
}
void
set_split
Births
(
ssize_t
v
)
{
_splitB
irths
=
v
;
}
void
set_split
_births
(
ssize_t
v
)
{
_split_b
irths
=
v
;
}
void
increment_split
Births
()
{
_splitB
irths
++
;
}
void
increment_split
_births
()
{
_split_b
irths
++
;
}
ssize_t
split
Deaths
()
const
{
return
_splitD
eaths
;
}
ssize_t
split
_deaths
()
const
{
return
_split_d
eaths
;
}
void
set_split
Deaths
(
ssize_t
v
)
{
_splitD
eaths
=
v
;
}
void
set_split
_deaths
(
ssize_t
v
)
{
_split_d
eaths
=
v
;
}
void
increment_split
Deaths
()
{
_splitD
eaths
++
;
}
void
increment_split
_deaths
()
{
_split_d
eaths
++
;
}
NOT_PRODUCT
(
NOT_PRODUCT
(
size_t
returned
Bytes
()
const
{
return
_returnedB
ytes
;
}
size_t
returned
_bytes
()
const
{
return
_returned_b
ytes
;
}
void
set_returned
Bytes
(
size_t
v
)
{
_returnedB
ytes
=
v
;
}
void
set_returned
_bytes
(
size_t
v
)
{
_returned_b
ytes
=
v
;
}
)
)
};
};
...
...
src/share/vm/memory/binaryTreeDictionary.cpp
浏览文件 @
2c61150c
...
@@ -44,7 +44,7 @@ TreeChunk<Chunk>* TreeChunk<Chunk>::as_TreeChunk(Chunk* fc) {
...
@@ -44,7 +44,7 @@ TreeChunk<Chunk>* TreeChunk<Chunk>::as_TreeChunk(Chunk* fc) {
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
TreeChunk
<
Chunk
>::
verify
TreeChunkL
ist
()
const
{
void
TreeChunk
<
Chunk
>::
verify
_tree_chunk_l
ist
()
const
{
TreeChunk
<
Chunk
>*
nextTC
=
(
TreeChunk
<
Chunk
>*
)
next
();
TreeChunk
<
Chunk
>*
nextTC
=
(
TreeChunk
<
Chunk
>*
)
next
();
if
(
prev
()
!=
NULL
)
{
// interior list node shouldn'r have tree fields
if
(
prev
()
!=
NULL
)
{
// interior list node shouldn'r have tree fields
guarantee
(
embedded_list
()
->
parent
()
==
NULL
&&
embedded_list
()
->
left
()
==
NULL
&&
guarantee
(
embedded_list
()
->
parent
()
==
NULL
&&
embedded_list
()
->
left
()
==
NULL
&&
...
@@ -53,7 +53,7 @@ void TreeChunk<Chunk>::verifyTreeChunkList() const {
...
@@ -53,7 +53,7 @@ void TreeChunk<Chunk>::verifyTreeChunkList() const {
if
(
nextTC
!=
NULL
)
{
if
(
nextTC
!=
NULL
)
{
guarantee
(
as_TreeChunk
(
nextTC
->
prev
())
==
this
,
"broken chain"
);
guarantee
(
as_TreeChunk
(
nextTC
->
prev
())
==
this
,
"broken chain"
);
guarantee
(
nextTC
->
size
()
==
size
(),
"wrong size"
);
guarantee
(
nextTC
->
size
()
==
size
(),
"wrong size"
);
nextTC
->
verify
TreeChunkL
ist
();
nextTC
->
verify
_tree_chunk_l
ist
();
}
}
}
}
...
@@ -73,9 +73,9 @@ TreeList<Chunk>* TreeList<Chunk>::as_TreeList(TreeChunk<Chunk>* tc) {
...
@@ -73,9 +73,9 @@ TreeList<Chunk>* TreeList<Chunk>::as_TreeList(TreeChunk<Chunk>* tc) {
tl
->
link_tail
(
tc
);
tl
->
link_tail
(
tc
);
tl
->
set_count
(
1
);
tl
->
set_count
(
1
);
tl
->
init_statistics
(
true
/* split_birth */
);
tl
->
init_statistics
(
true
/* split_birth */
);
tl
->
set
P
arent
(
NULL
);
tl
->
set
_p
arent
(
NULL
);
tl
->
set
L
eft
(
NULL
);
tl
->
set
_l
eft
(
NULL
);
tl
->
set
R
ight
(
NULL
);
tl
->
set
_r
ight
(
NULL
);
return
tl
;
return
tl
;
}
}
...
@@ -92,15 +92,15 @@ TreeList<Chunk>* TreeList<Chunk>::as_TreeList(HeapWord* addr, size_t size) {
...
@@ -92,15 +92,15 @@ TreeList<Chunk>* TreeList<Chunk>::as_TreeList(HeapWord* addr, size_t size) {
SpaceMangler
::
is_mangled
((
HeapWord
*
)
tc
->
next_addr
()))
||
SpaceMangler
::
is_mangled
((
HeapWord
*
)
tc
->
next_addr
()))
||
(
tc
->
size
()
==
0
&&
tc
->
prev
()
==
NULL
&&
tc
->
next
()
==
NULL
),
(
tc
->
size
()
==
0
&&
tc
->
prev
()
==
NULL
&&
tc
->
next
()
==
NULL
),
"Space should be clear or mangled"
);
"Space should be clear or mangled"
);
tc
->
set
S
ize
(
size
);
tc
->
set
_s
ize
(
size
);
tc
->
link
P
rev
(
NULL
);
tc
->
link
_p
rev
(
NULL
);
tc
->
link
N
ext
(
NULL
);
tc
->
link
_n
ext
(
NULL
);
TreeList
<
Chunk
>*
tl
=
TreeList
<
Chunk
>::
as_TreeList
(
tc
);
TreeList
<
Chunk
>*
tl
=
TreeList
<
Chunk
>::
as_TreeList
(
tc
);
return
tl
;
return
tl
;
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
TreeList
<
Chunk
>*
TreeList
<
Chunk
>::
remove
ChunkReplaceIfN
eeded
(
TreeChunk
<
Chunk
>*
tc
)
{
TreeList
<
Chunk
>*
TreeList
<
Chunk
>::
remove
_chunk_replace_if_n
eeded
(
TreeChunk
<
Chunk
>*
tc
)
{
TreeList
<
Chunk
>*
retTL
=
this
;
TreeList
<
Chunk
>*
retTL
=
this
;
Chunk
*
list
=
head
();
Chunk
*
list
=
head
();
...
@@ -108,7 +108,7 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
...
@@ -108,7 +108,7 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
assert
(
tc
!=
NULL
,
"Chunk being removed is NULL"
);
assert
(
tc
!=
NULL
,
"Chunk being removed is NULL"
);
assert
(
parent
()
==
NULL
||
this
==
parent
()
->
left
()
||
assert
(
parent
()
==
NULL
||
this
==
parent
()
->
left
()
||
this
==
parent
()
->
right
(),
"list is inconsistent"
);
this
==
parent
()
->
right
(),
"list is inconsistent"
);
assert
(
tc
->
is
F
ree
(),
"Header is not marked correctly"
);
assert
(
tc
->
is
_f
ree
(),
"Header is not marked correctly"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
...
@@ -148,24 +148,24 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
...
@@ -148,24 +148,24 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
// Fix the parent to point to the new TreeList<Chunk>.
// Fix the parent to point to the new TreeList<Chunk>.
if
(
retTL
->
parent
()
!=
NULL
)
{
if
(
retTL
->
parent
()
!=
NULL
)
{
if
(
this
==
retTL
->
parent
()
->
left
())
{
if
(
this
==
retTL
->
parent
()
->
left
())
{
retTL
->
parent
()
->
set
L
eft
(
retTL
);
retTL
->
parent
()
->
set
_l
eft
(
retTL
);
}
else
{
}
else
{
assert
(
this
==
retTL
->
parent
()
->
right
(),
"Parent is incorrect"
);
assert
(
this
==
retTL
->
parent
()
->
right
(),
"Parent is incorrect"
);
retTL
->
parent
()
->
set
R
ight
(
retTL
);
retTL
->
parent
()
->
set
_r
ight
(
retTL
);
}
}
}
}
// Fix the children's parent pointers to point to the
// Fix the children's parent pointers to point to the
// new list.
// new list.
assert
(
right
()
==
retTL
->
right
(),
"Should have been copied"
);
assert
(
right
()
==
retTL
->
right
(),
"Should have been copied"
);
if
(
retTL
->
right
()
!=
NULL
)
{
if
(
retTL
->
right
()
!=
NULL
)
{
retTL
->
right
()
->
set
P
arent
(
retTL
);
retTL
->
right
()
->
set
_p
arent
(
retTL
);
}
}
assert
(
left
()
==
retTL
->
left
(),
"Should have been copied"
);
assert
(
left
()
==
retTL
->
left
(),
"Should have been copied"
);
if
(
retTL
->
left
()
!=
NULL
)
{
if
(
retTL
->
left
()
!=
NULL
)
{
retTL
->
left
()
->
set
P
arent
(
retTL
);
retTL
->
left
()
->
set
_p
arent
(
retTL
);
}
}
retTL
->
link_head
(
nextTC
);
retTL
->
link_head
(
nextTC
);
assert
(
nextTC
->
is
F
ree
(),
"Should be a free chunk"
);
assert
(
nextTC
->
is
_f
ree
(),
"Should be a free chunk"
);
}
}
}
else
{
}
else
{
if
(
nextTC
==
NULL
)
{
if
(
nextTC
==
NULL
)
{
...
@@ -173,7 +173,7 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
...
@@ -173,7 +173,7 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
link_tail
(
prevFC
);
link_tail
(
prevFC
);
}
}
// Chunk is interior to the list
// Chunk is interior to the list
prevFC
->
link
A
fter
(
nextTC
);
prevFC
->
link
_a
fter
(
nextTC
);
}
}
// Below this point the embeded TreeList<Chunk> being used for the
// Below this point the embeded TreeList<Chunk> being used for the
...
@@ -183,8 +183,8 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
...
@@ -183,8 +183,8 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
assert
(
!
retTL
->
head
()
||
retTL
->
size
()
==
retTL
->
head
()
->
size
(),
assert
(
!
retTL
->
head
()
||
retTL
->
size
()
==
retTL
->
head
()
->
size
(),
"Wrong sized chunk in list"
);
"Wrong sized chunk in list"
);
debug_only
(
debug_only
(
tc
->
link
P
rev
(
NULL
);
tc
->
link
_p
rev
(
NULL
);
tc
->
link
N
ext
(
NULL
);
tc
->
link
_n
ext
(
NULL
);
tc
->
set_list
(
NULL
);
tc
->
set_list
(
NULL
);
bool
prev_found
=
false
;
bool
prev_found
=
false
;
bool
next_found
=
false
;
bool
next_found
=
false
;
...
@@ -207,7 +207,7 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
...
@@ -207,7 +207,7 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
)
)
retTL
->
decrement_count
();
retTL
->
decrement_count
();
assert
(
tc
->
is
F
ree
(),
"Should still be a free chunk"
);
assert
(
tc
->
is
_f
ree
(),
"Should still be a free chunk"
);
assert
(
retTL
->
head
()
==
NULL
||
retTL
->
head
()
->
prev
()
==
NULL
,
assert
(
retTL
->
head
()
==
NULL
||
retTL
->
head
()
->
prev
()
==
NULL
,
"list invariant"
);
"list invariant"
);
assert
(
retTL
->
tail
()
==
NULL
||
retTL
->
tail
()
->
next
()
==
NULL
,
assert
(
retTL
->
tail
()
==
NULL
||
retTL
->
tail
()
->
next
()
==
NULL
,
...
@@ -216,22 +216,22 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
...
@@ -216,22 +216,22 @@ TreeList<Chunk>* TreeList<Chunk>::removeChunkReplaceIfNeeded(TreeChunk<Chunk>* t
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
TreeList
<
Chunk
>::
return
ChunkAtT
ail
(
TreeChunk
<
Chunk
>*
chunk
)
{
void
TreeList
<
Chunk
>::
return
_chunk_at_t
ail
(
TreeChunk
<
Chunk
>*
chunk
)
{
assert
(
chunk
!=
NULL
,
"returning NULL chunk"
);
assert
(
chunk
!=
NULL
,
"returning NULL chunk"
);
assert
(
chunk
->
list
()
==
this
,
"list should be set for chunk"
);
assert
(
chunk
->
list
()
==
this
,
"list should be set for chunk"
);
assert
(
tail
()
!=
NULL
,
"The tree list is embedded in the first chunk"
);
assert
(
tail
()
!=
NULL
,
"The tree list is embedded in the first chunk"
);
// which means that the list can never be empty.
// which means that the list can never be empty.
assert
(
!
verify
ChunkInFreeLists
(
chunk
),
"Double entry"
);
assert
(
!
verify
_chunk_in_free_list
(
chunk
),
"Double entry"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
Chunk
*
fc
=
tail
();
Chunk
*
fc
=
tail
();
fc
->
link
A
fter
(
chunk
);
fc
->
link
_a
fter
(
chunk
);
link_tail
(
chunk
);
link_tail
(
chunk
);
assert
(
!
tail
()
||
size
()
==
tail
()
->
size
(),
"Wrong sized chunk in list"
);
assert
(
!
tail
()
||
size
()
==
tail
()
->
size
(),
"Wrong sized chunk in list"
);
FreeList
<
Chunk
>::
increment_count
();
FreeList
<
Chunk
>::
increment_count
();
debug_only
(
increment_returned
B
ytes_by
(
chunk
->
size
()
*
sizeof
(
HeapWord
));)
debug_only
(
increment_returned
_b
ytes_by
(
chunk
->
size
()
*
sizeof
(
HeapWord
));)
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
}
}
...
@@ -241,25 +241,25 @@ void TreeList<Chunk>::returnChunkAtTail(TreeChunk<Chunk>* chunk) {
...
@@ -241,25 +241,25 @@ void TreeList<Chunk>::returnChunkAtTail(TreeChunk<Chunk>* chunk) {
// because the TreeList<Chunk> is embedded in the first TreeChunk<Chunk> in the
// because the TreeList<Chunk> is embedded in the first TreeChunk<Chunk> in the
// list. See the definition of TreeChunk<Chunk>.
// list. See the definition of TreeChunk<Chunk>.
template
<
class
Chunk
>
template
<
class
Chunk
>
void
TreeList
<
Chunk
>::
return
ChunkAtH
ead
(
TreeChunk
<
Chunk
>*
chunk
)
{
void
TreeList
<
Chunk
>::
return
_chunk_at_h
ead
(
TreeChunk
<
Chunk
>*
chunk
)
{
assert
(
chunk
->
list
()
==
this
,
"list should be set for chunk"
);
assert
(
chunk
->
list
()
==
this
,
"list should be set for chunk"
);
assert
(
head
()
!=
NULL
,
"The tree list is embedded in the first chunk"
);
assert
(
head
()
!=
NULL
,
"The tree list is embedded in the first chunk"
);
assert
(
chunk
!=
NULL
,
"returning NULL chunk"
);
assert
(
chunk
!=
NULL
,
"returning NULL chunk"
);
assert
(
!
verify
ChunkInFreeLists
(
chunk
),
"Double entry"
);
assert
(
!
verify
_chunk_in_free_list
(
chunk
),
"Double entry"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
Chunk
*
fc
=
head
()
->
next
();
Chunk
*
fc
=
head
()
->
next
();
if
(
fc
!=
NULL
)
{
if
(
fc
!=
NULL
)
{
chunk
->
link
A
fter
(
fc
);
chunk
->
link
_a
fter
(
fc
);
}
else
{
}
else
{
assert
(
tail
()
==
NULL
,
"List is inconsistent"
);
assert
(
tail
()
==
NULL
,
"List is inconsistent"
);
link_tail
(
chunk
);
link_tail
(
chunk
);
}
}
head
()
->
link
A
fter
(
chunk
);
head
()
->
link
_a
fter
(
chunk
);
assert
(
!
head
()
||
size
()
==
head
()
->
size
(),
"Wrong sized chunk in list"
);
assert
(
!
head
()
||
size
()
==
head
()
->
size
(),
"Wrong sized chunk in list"
);
FreeList
<
Chunk
>::
increment_count
();
FreeList
<
Chunk
>::
increment_count
();
debug_only
(
increment_returned
B
ytes_by
(
chunk
->
size
()
*
sizeof
(
HeapWord
));)
debug_only
(
increment_returned
_b
ytes_by
(
chunk
->
size
()
*
sizeof
(
HeapWord
));)
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
}
}
...
@@ -314,7 +314,7 @@ TreeChunk<Chunk>* TreeList<Chunk>::largest_address() {
...
@@ -314,7 +314,7 @@ TreeChunk<Chunk>* TreeList<Chunk>::largest_address() {
template
<
class
Chunk
>
template
<
class
Chunk
>
BinaryTreeDictionary
<
Chunk
>::
BinaryTreeDictionary
(
bool
adaptive_freelists
,
bool
splay
)
:
BinaryTreeDictionary
<
Chunk
>::
BinaryTreeDictionary
(
bool
adaptive_freelists
,
bool
splay
)
:
_splay
(
splay
),
_adaptive_freelists
(
adaptive_freelists
),
_splay
(
splay
),
_adaptive_freelists
(
adaptive_freelists
),
_total
Size
(
0
),
_totalFreeB
locks
(
0
),
_root
(
0
)
{}
_total
_size
(
0
),
_total_free_b
locks
(
0
),
_root
(
0
)
{}
template
<
class
Chunk
>
template
<
class
Chunk
>
BinaryTreeDictionary
<
Chunk
>::
BinaryTreeDictionary
(
MemRegion
mr
,
BinaryTreeDictionary
<
Chunk
>::
BinaryTreeDictionary
(
MemRegion
mr
,
...
@@ -329,26 +329,26 @@ BinaryTreeDictionary<Chunk>::BinaryTreeDictionary(MemRegion mr,
...
@@ -329,26 +329,26 @@ BinaryTreeDictionary<Chunk>::BinaryTreeDictionary(MemRegion mr,
assert
(
root
()
->
right
()
==
NULL
,
"reset check failed"
);
assert
(
root
()
->
right
()
==
NULL
,
"reset check failed"
);
assert
(
root
()
->
head
()
->
next
()
==
NULL
,
"reset check failed"
);
assert
(
root
()
->
head
()
->
next
()
==
NULL
,
"reset check failed"
);
assert
(
root
()
->
head
()
->
prev
()
==
NULL
,
"reset check failed"
);
assert
(
root
()
->
head
()
->
prev
()
==
NULL
,
"reset check failed"
);
assert
(
total
S
ize
()
==
root
()
->
size
(),
"reset check failed"
);
assert
(
total
_s
ize
()
==
root
()
->
size
(),
"reset check failed"
);
assert
(
total
FreeB
locks
()
==
1
,
"reset check failed"
);
assert
(
total
_free_b
locks
()
==
1
,
"reset check failed"
);
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
inc_total
S
ize
(
size_t
inc
)
{
void
BinaryTreeDictionary
<
Chunk
>::
inc_total
_s
ize
(
size_t
inc
)
{
_total
Size
=
_totalS
ize
+
inc
;
_total
_size
=
_total_s
ize
+
inc
;
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
dec_total
S
ize
(
size_t
dec
)
{
void
BinaryTreeDictionary
<
Chunk
>::
dec_total
_s
ize
(
size_t
dec
)
{
_total
Size
=
_totalS
ize
-
dec
;
_total
_size
=
_total_s
ize
-
dec
;
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
reset
(
MemRegion
mr
)
{
void
BinaryTreeDictionary
<
Chunk
>::
reset
(
MemRegion
mr
)
{
assert
(
mr
.
word_size
()
>=
BinaryTreeDictionary
<
Chunk
>::
min_tree_chunk_size
,
"minimum chunk size"
);
assert
(
mr
.
word_size
()
>=
BinaryTreeDictionary
<
Chunk
>::
min_tree_chunk_size
,
"minimum chunk size"
);
set_root
(
TreeList
<
Chunk
>::
as_TreeList
(
mr
.
start
(),
mr
.
word_size
()));
set_root
(
TreeList
<
Chunk
>::
as_TreeList
(
mr
.
start
(),
mr
.
word_size
()));
set_total
S
ize
(
mr
.
word_size
());
set_total
_s
ize
(
mr
.
word_size
());
set_total
FreeB
locks
(
1
);
set_total
_free_b
locks
(
1
);
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
...
@@ -360,8 +360,8 @@ void BinaryTreeDictionary<Chunk>::reset(HeapWord* addr, size_t byte_size) {
...
@@ -360,8 +360,8 @@ void BinaryTreeDictionary<Chunk>::reset(HeapWord* addr, size_t byte_size) {
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
reset
()
{
void
BinaryTreeDictionary
<
Chunk
>::
reset
()
{
set_root
(
NULL
);
set_root
(
NULL
);
set_total
S
ize
(
0
);
set_total
_s
ize
(
0
);
set_total
FreeB
locks
(
0
);
set_total
_free_b
locks
(
0
);
}
}
// Get a free block of size at least size from tree, or NULL.
// Get a free block of size at least size from tree, or NULL.
...
@@ -374,13 +374,13 @@ void BinaryTreeDictionary<Chunk>::reset() {
...
@@ -374,13 +374,13 @@ void BinaryTreeDictionary<Chunk>::reset() {
// node is replaced in place by its tree successor.
// node is replaced in place by its tree successor.
template
<
class
Chunk
>
template
<
class
Chunk
>
TreeChunk
<
Chunk
>*
TreeChunk
<
Chunk
>*
BinaryTreeDictionary
<
Chunk
>::
get
ChunkFromT
ree
(
size_t
size
,
enum
FreeBlockDictionary
<
Chunk
>::
Dither
dither
,
bool
splay
)
BinaryTreeDictionary
<
Chunk
>::
get
_chunk_from_t
ree
(
size_t
size
,
enum
FreeBlockDictionary
<
Chunk
>::
Dither
dither
,
bool
splay
)
{
{
TreeList
<
Chunk
>
*
curTL
,
*
prevTL
;
TreeList
<
Chunk
>
*
curTL
,
*
prevTL
;
TreeChunk
<
Chunk
>*
retTC
=
NULL
;
TreeChunk
<
Chunk
>*
retTC
=
NULL
;
assert
(
size
>=
BinaryTreeDictionary
<
Chunk
>::
min_tree_chunk_size
,
"minimum chunk size"
);
assert
(
size
>=
BinaryTreeDictionary
<
Chunk
>::
min_tree_chunk_size
,
"minimum chunk size"
);
if
(
FLSVerifyDictionary
)
{
if
(
FLSVerifyDictionary
)
{
verify
T
ree
();
verify
_t
ree
();
}
}
// starting at the root, work downwards trying to find match.
// starting at the root, work downwards trying to find match.
// Remember the last node of size too great or too small.
// Remember the last node of size too great or too small.
...
@@ -421,7 +421,7 @@ BinaryTreeDictionary<Chunk>::getChunkFromTree(size_t size, enum FreeBlockDiction
...
@@ -421,7 +421,7 @@ BinaryTreeDictionary<Chunk>::getChunkFromTree(size_t size, enum FreeBlockDiction
while
(
hintTL
->
hint
()
!=
0
)
{
while
(
hintTL
->
hint
()
!=
0
)
{
assert
(
hintTL
->
hint
()
==
0
||
hintTL
->
hint
()
>
hintTL
->
size
(),
assert
(
hintTL
->
hint
()
==
0
||
hintTL
->
hint
()
>
hintTL
->
size
(),
"hint points in the wrong direction"
);
"hint points in the wrong direction"
);
hintTL
=
find
L
ist
(
hintTL
->
hint
());
hintTL
=
find
_l
ist
(
hintTL
->
hint
());
assert
(
curTL
!=
hintTL
,
"Infinite loop"
);
assert
(
curTL
!=
hintTL
,
"Infinite loop"
);
if
(
hintTL
==
NULL
||
if
(
hintTL
==
NULL
||
hintTL
==
curTL
/* Should not happen but protect against it */
)
{
hintTL
==
curTL
/* Should not happen but protect against it */
)
{
...
@@ -448,15 +448,15 @@ BinaryTreeDictionary<Chunk>::getChunkFromTree(size_t size, enum FreeBlockDiction
...
@@ -448,15 +448,15 @@ BinaryTreeDictionary<Chunk>::getChunkFromTree(size_t size, enum FreeBlockDiction
}
}
// don't waste time splaying if chunk's singleton
// don't waste time splaying if chunk's singleton
if
(
splay
&&
curTL
->
head
()
->
next
()
!=
NULL
)
{
if
(
splay
&&
curTL
->
head
()
->
next
()
!=
NULL
)
{
semi
SplayS
tep
(
curTL
);
semi
_splay_s
tep
(
curTL
);
}
}
retTC
=
curTL
->
first_available
();
retTC
=
curTL
->
first_available
();
assert
((
retTC
!=
NULL
)
&&
(
curTL
->
count
()
>
0
),
assert
((
retTC
!=
NULL
)
&&
(
curTL
->
count
()
>
0
),
"A list in the binary tree should not be NULL"
);
"A list in the binary tree should not be NULL"
);
assert
(
retTC
->
size
()
>=
size
,
assert
(
retTC
->
size
()
>=
size
,
"A chunk of the wrong size was found"
);
"A chunk of the wrong size was found"
);
remove
ChunkFromT
ree
(
retTC
);
remove
_chunk_from_t
ree
(
retTC
);
assert
(
retTC
->
is
F
ree
(),
"Header is not marked correctly"
);
assert
(
retTC
->
is
_f
ree
(),
"Header is not marked correctly"
);
}
}
if
(
FLSVerifyDictionary
)
{
if
(
FLSVerifyDictionary
)
{
...
@@ -466,7 +466,7 @@ BinaryTreeDictionary<Chunk>::getChunkFromTree(size_t size, enum FreeBlockDiction
...
@@ -466,7 +466,7 @@ BinaryTreeDictionary<Chunk>::getChunkFromTree(size_t size, enum FreeBlockDiction
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
TreeList
<
Chunk
>*
BinaryTreeDictionary
<
Chunk
>::
find
L
ist
(
size_t
size
)
const
{
TreeList
<
Chunk
>*
BinaryTreeDictionary
<
Chunk
>::
find
_l
ist
(
size_t
size
)
const
{
TreeList
<
Chunk
>*
curTL
;
TreeList
<
Chunk
>*
curTL
;
for
(
curTL
=
root
();
curTL
!=
NULL
;)
{
for
(
curTL
=
root
();
curTL
!=
NULL
;)
{
if
(
curTL
->
size
()
==
size
)
{
// exact match
if
(
curTL
->
size
()
==
size
)
{
// exact match
...
@@ -485,18 +485,18 @@ TreeList<Chunk>* BinaryTreeDictionary<Chunk>::findList(size_t size) const {
...
@@ -485,18 +485,18 @@ TreeList<Chunk>* BinaryTreeDictionary<Chunk>::findList(size_t size) const {
template
<
class
Chunk
>
template
<
class
Chunk
>
bool
BinaryTreeDictionary
<
Chunk
>::
verify
ChunkInFreeLists
(
Chunk
*
tc
)
const
{
bool
BinaryTreeDictionary
<
Chunk
>::
verify
_chunk_in_free_list
(
Chunk
*
tc
)
const
{
size_t
size
=
tc
->
size
();
size_t
size
=
tc
->
size
();
TreeList
<
Chunk
>*
tl
=
find
L
ist
(
size
);
TreeList
<
Chunk
>*
tl
=
find
_l
ist
(
size
);
if
(
tl
==
NULL
)
{
if
(
tl
==
NULL
)
{
return
false
;
return
false
;
}
else
{
}
else
{
return
tl
->
verify
ChunkInFreeLists
(
tc
);
return
tl
->
verify
_chunk_in_free_list
(
tc
);
}
}
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
Chunk
*
BinaryTreeDictionary
<
Chunk
>::
find
LargestD
ict
()
const
{
Chunk
*
BinaryTreeDictionary
<
Chunk
>::
find
_largest_d
ict
()
const
{
TreeList
<
Chunk
>
*
curTL
=
root
();
TreeList
<
Chunk
>
*
curTL
=
root
();
if
(
curTL
!=
NULL
)
{
if
(
curTL
!=
NULL
)
{
while
(
curTL
->
right
()
!=
NULL
)
curTL
=
curTL
->
right
();
while
(
curTL
->
right
()
!=
NULL
)
curTL
=
curTL
->
right
();
...
@@ -512,9 +512,9 @@ Chunk* BinaryTreeDictionary<Chunk>::findLargestDict() const {
...
@@ -512,9 +512,9 @@ Chunk* BinaryTreeDictionary<Chunk>::findLargestDict() const {
// remove the node and repair the tree.
// remove the node and repair the tree.
template
<
class
Chunk
>
template
<
class
Chunk
>
TreeChunk
<
Chunk
>*
TreeChunk
<
Chunk
>*
BinaryTreeDictionary
<
Chunk
>::
remove
ChunkFromT
ree
(
TreeChunk
<
Chunk
>*
tc
)
{
BinaryTreeDictionary
<
Chunk
>::
remove
_chunk_from_t
ree
(
TreeChunk
<
Chunk
>*
tc
)
{
assert
(
tc
!=
NULL
,
"Should not call with a NULL chunk"
);
assert
(
tc
!=
NULL
,
"Should not call with a NULL chunk"
);
assert
(
tc
->
is
F
ree
(),
"Header is not marked correctly"
);
assert
(
tc
->
is
_f
ree
(),
"Header is not marked correctly"
);
TreeList
<
Chunk
>
*
newTL
,
*
parentTL
;
TreeList
<
Chunk
>
*
newTL
,
*
parentTL
;
TreeChunk
<
Chunk
>*
retTC
;
TreeChunk
<
Chunk
>*
retTC
;
...
@@ -534,13 +534,13 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
...
@@ -534,13 +534,13 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
assert
(
tl
->
parent
()
==
NULL
||
tl
==
tl
->
parent
()
->
left
()
||
assert
(
tl
->
parent
()
==
NULL
||
tl
==
tl
->
parent
()
->
left
()
||
tl
==
tl
->
parent
()
->
right
(),
"list is inconsistent"
);
tl
==
tl
->
parent
()
->
right
(),
"list is inconsistent"
);
bool
complicated
S
plice
=
false
;
bool
complicated
_s
plice
=
false
;
retTC
=
tc
;
retTC
=
tc
;
// Removing this chunk can have the side effect of changing the node
// Removing this chunk can have the side effect of changing the node
// (TreeList<Chunk>*) in the tree. If the node is the root, update it.
// (TreeList<Chunk>*) in the tree. If the node is the root, update it.
TreeList
<
Chunk
>*
replacementTL
=
tl
->
remove
ChunkReplaceIfN
eeded
(
tc
);
TreeList
<
Chunk
>*
replacementTL
=
tl
->
remove
_chunk_replace_if_n
eeded
(
tc
);
assert
(
tc
->
is
F
ree
(),
"Chunk should still be free"
);
assert
(
tc
->
is
_f
ree
(),
"Chunk should still be free"
);
assert
(
replacementTL
->
parent
()
==
NULL
||
assert
(
replacementTL
->
parent
()
==
NULL
||
replacementTL
==
replacementTL
->
parent
()
->
left
()
||
replacementTL
==
replacementTL
->
parent
()
->
left
()
||
replacementTL
==
replacementTL
->
parent
()
->
right
(),
replacementTL
==
replacementTL
->
parent
()
->
right
(),
...
@@ -570,15 +570,15 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
...
@@ -570,15 +570,15 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
if
(
replacementTL
->
left
()
==
NULL
)
{
if
(
replacementTL
->
left
()
==
NULL
)
{
// left is NULL so pick right. right may also be NULL.
// left is NULL so pick right. right may also be NULL.
newTL
=
replacementTL
->
right
();
newTL
=
replacementTL
->
right
();
debug_only
(
replacementTL
->
clear
R
ight
();)
debug_only
(
replacementTL
->
clear
_r
ight
();)
}
else
if
(
replacementTL
->
right
()
==
NULL
)
{
}
else
if
(
replacementTL
->
right
()
==
NULL
)
{
// right is NULL
// right is NULL
newTL
=
replacementTL
->
left
();
newTL
=
replacementTL
->
left
();
debug_only
(
replacementTL
->
clearLeft
();)
debug_only
(
replacementTL
->
clearLeft
();)
}
else
{
// we have both children, so, by patriarchal convention,
}
else
{
// we have both children, so, by patriarchal convention,
// my replacement is least node in right sub-tree
// my replacement is least node in right sub-tree
complicated
S
plice
=
true
;
complicated
_s
plice
=
true
;
newTL
=
remove
TreeM
inimum
(
replacementTL
->
right
());
newTL
=
remove
_tree_m
inimum
(
replacementTL
->
right
());
assert
(
newTL
!=
NULL
&&
newTL
->
left
()
==
NULL
&&
assert
(
newTL
!=
NULL
&&
newTL
->
left
()
==
NULL
&&
newTL
->
right
()
==
NULL
,
"sub-tree minimum exists"
);
newTL
->
right
()
==
NULL
,
"sub-tree minimum exists"
);
}
}
...
@@ -586,7 +586,7 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
...
@@ -586,7 +586,7 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
// newTL may be NULL.
// newTL may be NULL.
// should verify; we just cleanly excised our replacement
// should verify; we just cleanly excised our replacement
if
(
FLSVerifyDictionary
)
{
if
(
FLSVerifyDictionary
)
{
verify
T
ree
();
verify
_t
ree
();
}
}
// first make newTL my parent's child
// first make newTL my parent's child
if
((
parentTL
=
replacementTL
->
parent
())
==
NULL
)
{
if
((
parentTL
=
replacementTL
->
parent
())
==
NULL
)
{
...
@@ -594,35 +594,35 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
...
@@ -594,35 +594,35 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
assert
(
tl
==
root
(),
"Incorrectly replacing root"
);
assert
(
tl
==
root
(),
"Incorrectly replacing root"
);
set_root
(
newTL
);
set_root
(
newTL
);
if
(
newTL
!=
NULL
)
{
if
(
newTL
!=
NULL
)
{
newTL
->
clear
P
arent
();
newTL
->
clear
_p
arent
();
}
}
}
else
if
(
parentTL
->
right
()
==
replacementTL
)
{
}
else
if
(
parentTL
->
right
()
==
replacementTL
)
{
// replacementTL is a right child
// replacementTL is a right child
parentTL
->
set
R
ight
(
newTL
);
parentTL
->
set
_r
ight
(
newTL
);
}
else
{
// replacementTL is a left child
}
else
{
// replacementTL is a left child
assert
(
parentTL
->
left
()
==
replacementTL
,
"should be left child"
);
assert
(
parentTL
->
left
()
==
replacementTL
,
"should be left child"
);
parentTL
->
set
L
eft
(
newTL
);
parentTL
->
set
_l
eft
(
newTL
);
}
}
debug_only
(
replacementTL
->
clear
P
arent
();)
debug_only
(
replacementTL
->
clear
_p
arent
();)
if
(
complicated
S
plice
)
{
// we need newTL to get replacementTL's
if
(
complicated
_s
plice
)
{
// we need newTL to get replacementTL's
// two children
// two children
assert
(
newTL
!=
NULL
&&
assert
(
newTL
!=
NULL
&&
newTL
->
left
()
==
NULL
&&
newTL
->
right
()
==
NULL
,
newTL
->
left
()
==
NULL
&&
newTL
->
right
()
==
NULL
,
"newTL should not have encumbrances from the past"
);
"newTL should not have encumbrances from the past"
);
// we'd like to assert as below:
// we'd like to assert as below:
// assert(replacementTL->left() != NULL && replacementTL->right() != NULL,
// assert(replacementTL->left() != NULL && replacementTL->right() != NULL,
// "else !complicated
S
plice");
// "else !complicated
_s
plice");
// ... however, the above assertion is too strong because we aren't
// ... however, the above assertion is too strong because we aren't
// guaranteed that replacementTL->right() is still NULL.
// guaranteed that replacementTL->right() is still NULL.
// Recall that we removed
// Recall that we removed
// the right sub-tree minimum from replacementTL.
// the right sub-tree minimum from replacementTL.
// That may well have been its right
// That may well have been its right
// child! So we'll just assert half of the above:
// child! So we'll just assert half of the above:
assert
(
replacementTL
->
left
()
!=
NULL
,
"else !complicated
S
plice"
);
assert
(
replacementTL
->
left
()
!=
NULL
,
"else !complicated
_s
plice"
);
newTL
->
set
L
eft
(
replacementTL
->
left
());
newTL
->
set
_l
eft
(
replacementTL
->
left
());
newTL
->
set
R
ight
(
replacementTL
->
right
());
newTL
->
set
_r
ight
(
replacementTL
->
right
());
debug_only
(
debug_only
(
replacementTL
->
clear
R
ight
();
replacementTL
->
clear
_r
ight
();
replacementTL
->
clearLeft
();
replacementTL
->
clearLeft
();
)
)
}
}
...
@@ -632,16 +632,16 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
...
@@ -632,16 +632,16 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
"delete without encumbrances"
);
"delete without encumbrances"
);
}
}
assert
(
total
S
ize
()
>=
retTC
->
size
(),
"Incorrect total size"
);
assert
(
total
_s
ize
()
>=
retTC
->
size
(),
"Incorrect total size"
);
dec_total
S
ize
(
retTC
->
size
());
// size book-keeping
dec_total
_s
ize
(
retTC
->
size
());
// size book-keeping
assert
(
total
FreeB
locks
()
>
0
,
"Incorrect total count"
);
assert
(
total
_free_b
locks
()
>
0
,
"Incorrect total count"
);
set_total
FreeBlocks
(
totalFreeB
locks
()
-
1
);
set_total
_free_blocks
(
total_free_b
locks
()
-
1
);
assert
(
retTC
!=
NULL
,
"null chunk?"
);
assert
(
retTC
!=
NULL
,
"null chunk?"
);
assert
(
retTC
->
prev
()
==
NULL
&&
retTC
->
next
()
==
NULL
,
assert
(
retTC
->
prev
()
==
NULL
&&
retTC
->
next
()
==
NULL
,
"should return without encumbrances"
);
"should return without encumbrances"
);
if
(
FLSVerifyDictionary
)
{
if
(
FLSVerifyDictionary
)
{
verify
T
ree
();
verify
_t
ree
();
}
}
assert
(
!
removing_only_chunk
||
_root
==
NULL
,
"root should be NULL"
);
assert
(
!
removing_only_chunk
||
_root
==
NULL
,
"root should be NULL"
);
return
TreeChunk
<
Chunk
>::
as_TreeChunk
(
retTC
);
return
TreeChunk
<
Chunk
>::
as_TreeChunk
(
retTC
);
...
@@ -651,7 +651,7 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
...
@@ -651,7 +651,7 @@ BinaryTreeDictionary<Chunk>::removeChunkFromTree(TreeChunk<Chunk>* tc) {
// If lm has a right child, link it to the left node of
// If lm has a right child, link it to the left node of
// the parent of lm.
// the parent of lm.
template
<
class
Chunk
>
template
<
class
Chunk
>
TreeList
<
Chunk
>*
BinaryTreeDictionary
<
Chunk
>::
remove
TreeM
inimum
(
TreeList
<
Chunk
>*
tl
)
{
TreeList
<
Chunk
>*
BinaryTreeDictionary
<
Chunk
>::
remove
_tree_m
inimum
(
TreeList
<
Chunk
>*
tl
)
{
assert
(
tl
!=
NULL
&&
tl
->
parent
()
!=
NULL
,
"really need a proper sub-tree"
);
assert
(
tl
!=
NULL
&&
tl
->
parent
()
!=
NULL
,
"really need a proper sub-tree"
);
// locate the subtree minimum by walking down left branches
// locate the subtree minimum by walking down left branches
TreeList
<
Chunk
>*
curTL
=
tl
;
TreeList
<
Chunk
>*
curTL
=
tl
;
...
@@ -660,12 +660,12 @@ TreeList<Chunk>* BinaryTreeDictionary<Chunk>::removeTreeMinimum(TreeList<Chunk>*
...
@@ -660,12 +660,12 @@ TreeList<Chunk>* BinaryTreeDictionary<Chunk>::removeTreeMinimum(TreeList<Chunk>*
if
(
curTL
!=
root
())
{
// Should this test just be removed?
if
(
curTL
!=
root
())
{
// Should this test just be removed?
TreeList
<
Chunk
>*
parentTL
=
curTL
->
parent
();
TreeList
<
Chunk
>*
parentTL
=
curTL
->
parent
();
if
(
parentTL
->
left
()
==
curTL
)
{
// curTL is a left child
if
(
parentTL
->
left
()
==
curTL
)
{
// curTL is a left child
parentTL
->
set
L
eft
(
curTL
->
right
());
parentTL
->
set
_l
eft
(
curTL
->
right
());
}
else
{
}
else
{
// If the list tl has no left child, then curTL may be
// If the list tl has no left child, then curTL may be
// the right child of parentTL.
// the right child of parentTL.
assert
(
parentTL
->
right
()
==
curTL
,
"should be a right child"
);
assert
(
parentTL
->
right
()
==
curTL
,
"should be a right child"
);
parentTL
->
set
R
ight
(
curTL
->
right
());
parentTL
->
set
_r
ight
(
curTL
->
right
());
}
}
}
else
{
}
else
{
// The only use of this method would not pass the root of the
// The only use of this method would not pass the root of the
...
@@ -675,12 +675,12 @@ TreeList<Chunk>* BinaryTreeDictionary<Chunk>::removeTreeMinimum(TreeList<Chunk>*
...
@@ -675,12 +675,12 @@ TreeList<Chunk>* BinaryTreeDictionary<Chunk>::removeTreeMinimum(TreeList<Chunk>*
set_root
(
NULL
);
set_root
(
NULL
);
}
}
debug_only
(
debug_only
(
curTL
->
clear
P
arent
();
// Test if this needs to be cleared
curTL
->
clear
_p
arent
();
// Test if this needs to be cleared
curTL
->
clear
R
ight
();
// recall, above, left child is already null
curTL
->
clear
_r
ight
();
// recall, above, left child is already null
)
)
// we just excised a (non-root) node, we should still verify all tree invariants
// we just excised a (non-root) node, we should still verify all tree invariants
if
(
FLSVerifyDictionary
)
{
if
(
FLSVerifyDictionary
)
{
verify
T
ree
();
verify
_t
ree
();
}
}
return
curTL
;
return
curTL
;
}
}
...
@@ -694,7 +694,7 @@ TreeList<Chunk>* BinaryTreeDictionary<Chunk>::removeTreeMinimum(TreeList<Chunk>*
...
@@ -694,7 +694,7 @@ TreeList<Chunk>* BinaryTreeDictionary<Chunk>::removeTreeMinimum(TreeList<Chunk>*
// [Measurements will be needed to (in)validate this expectation.]
// [Measurements will be needed to (in)validate this expectation.]
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
semi
SplayS
tep
(
TreeList
<
Chunk
>*
tc
)
{
void
BinaryTreeDictionary
<
Chunk
>::
semi
_splay_s
tep
(
TreeList
<
Chunk
>*
tc
)
{
// apply a semi-splay step at the given node:
// apply a semi-splay step at the given node:
// . if root, norting needs to be done
// . if root, norting needs to be done
// . if child of root, splay once
// . if child of root, splay once
...
@@ -705,17 +705,17 @@ void BinaryTreeDictionary<Chunk>::semiSplayStep(TreeList<Chunk>* tc) {
...
@@ -705,17 +705,17 @@ void BinaryTreeDictionary<Chunk>::semiSplayStep(TreeList<Chunk>* tc) {
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
insert
ChunkInT
ree
(
Chunk
*
fc
)
{
void
BinaryTreeDictionary
<
Chunk
>::
insert
_chunk_in_t
ree
(
Chunk
*
fc
)
{
TreeList
<
Chunk
>
*
curTL
,
*
prevTL
;
TreeList
<
Chunk
>
*
curTL
,
*
prevTL
;
size_t
size
=
fc
->
size
();
size_t
size
=
fc
->
size
();
assert
(
size
>=
BinaryTreeDictionary
<
Chunk
>::
min_tree_chunk_size
,
"too small to be a TreeList<Chunk>"
);
assert
(
size
>=
BinaryTreeDictionary
<
Chunk
>::
min_tree_chunk_size
,
"too small to be a TreeList<Chunk>"
);
if
(
FLSVerifyDictionary
)
{
if
(
FLSVerifyDictionary
)
{
verify
T
ree
();
verify
_t
ree
();
}
}
fc
->
clear
N
ext
();
fc
->
clear
_n
ext
();
fc
->
link
P
rev
(
NULL
);
fc
->
link
_p
rev
(
NULL
);
// work down from the _root, looking for insertion point
// work down from the _root, looking for insertion point
for
(
prevTL
=
curTL
=
root
();
curTL
!=
NULL
;)
{
for
(
prevTL
=
curTL
=
root
();
curTL
!=
NULL
;)
{
...
@@ -735,10 +735,10 @@ void BinaryTreeDictionary<Chunk>::insertChunkInTree(Chunk* fc) {
...
@@ -735,10 +735,10 @@ void BinaryTreeDictionary<Chunk>::insertChunkInTree(Chunk* fc) {
tc
->
initialize
();
tc
->
initialize
();
if
(
curTL
!=
NULL
)
{
// exact match
if
(
curTL
!=
NULL
)
{
// exact match
tc
->
set_list
(
curTL
);
tc
->
set_list
(
curTL
);
curTL
->
return
ChunkAtT
ail
(
tc
);
curTL
->
return
_chunk_at_t
ail
(
tc
);
}
else
{
// need a new node in tree
}
else
{
// need a new node in tree
tc
->
clear
N
ext
();
tc
->
clear
_n
ext
();
tc
->
link
P
rev
(
NULL
);
tc
->
link
_p
rev
(
NULL
);
TreeList
<
Chunk
>*
newTL
=
TreeList
<
Chunk
>::
as_TreeList
(
tc
);
TreeList
<
Chunk
>*
newTL
=
TreeList
<
Chunk
>::
as_TreeList
(
tc
);
assert
(((
TreeChunk
<
Chunk
>*
)
tc
)
->
list
()
==
newTL
,
assert
(((
TreeChunk
<
Chunk
>*
)
tc
)
->
list
()
==
newTL
,
"List was not initialized correctly"
);
"List was not initialized correctly"
);
...
@@ -748,28 +748,28 @@ void BinaryTreeDictionary<Chunk>::insertChunkInTree(Chunk* fc) {
...
@@ -748,28 +748,28 @@ void BinaryTreeDictionary<Chunk>::insertChunkInTree(Chunk* fc) {
}
else
{
// insert under prevTL ...
}
else
{
// insert under prevTL ...
if
(
prevTL
->
size
()
<
size
)
{
// am right child
if
(
prevTL
->
size
()
<
size
)
{
// am right child
assert
(
prevTL
->
right
()
==
NULL
,
"control point invariant"
);
assert
(
prevTL
->
right
()
==
NULL
,
"control point invariant"
);
prevTL
->
set
R
ight
(
newTL
);
prevTL
->
set
_r
ight
(
newTL
);
}
else
{
// am left child
}
else
{
// am left child
assert
(
prevTL
->
size
()
>
size
&&
prevTL
->
left
()
==
NULL
,
"cpt pt inv"
);
assert
(
prevTL
->
size
()
>
size
&&
prevTL
->
left
()
==
NULL
,
"cpt pt inv"
);
prevTL
->
set
L
eft
(
newTL
);
prevTL
->
set
_l
eft
(
newTL
);
}
}
}
}
}
}
assert
(
tc
->
list
()
!=
NULL
,
"Tree list should be set"
);
assert
(
tc
->
list
()
!=
NULL
,
"Tree list should be set"
);
inc_total
S
ize
(
size
);
inc_total
_s
ize
(
size
);
// Method 'total
SizeInT
ree' walks through the every block in the
// Method 'total
_size_in_t
ree' walks through the every block in the
// tree, so it can cause significant performance loss if there are
// tree, so it can cause significant performance loss if there are
// many blocks in the tree
// many blocks in the tree
assert
(
!
FLSVerifyDictionary
||
total
SizeInTree
(
root
())
==
totalSize
(),
"_totalS
ize inconsistency"
);
assert
(
!
FLSVerifyDictionary
||
total
_size_in_tree
(
root
())
==
total_size
(),
"_total_s
ize inconsistency"
);
set_total
FreeBlocks
(
totalFreeB
locks
()
+
1
);
set_total
_free_blocks
(
total_free_b
locks
()
+
1
);
if
(
FLSVerifyDictionary
)
{
if
(
FLSVerifyDictionary
)
{
verify
T
ree
();
verify
_t
ree
();
}
}
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
max
ChunkS
ize
()
const
{
size_t
BinaryTreeDictionary
<
Chunk
>::
max
_chunk_s
ize
()
const
{
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
TreeList
<
Chunk
>*
tc
=
root
();
TreeList
<
Chunk
>*
tc
=
root
();
if
(
tc
==
NULL
)
return
0
;
if
(
tc
==
NULL
)
return
0
;
...
@@ -778,7 +778,7 @@ size_t BinaryTreeDictionary<Chunk>::maxChunkSize() const {
...
@@ -778,7 +778,7 @@ size_t BinaryTreeDictionary<Chunk>::maxChunkSize() const {
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
total
ListL
ength
(
TreeList
<
Chunk
>*
tl
)
const
{
size_t
BinaryTreeDictionary
<
Chunk
>::
total
_list_l
ength
(
TreeList
<
Chunk
>*
tl
)
const
{
size_t
res
;
size_t
res
;
res
=
tl
->
count
();
res
=
tl
->
count
();
#ifdef ASSERT
#ifdef ASSERT
...
@@ -791,12 +791,12 @@ size_t BinaryTreeDictionary<Chunk>::totalListLength(TreeList<Chunk>* tl) const {
...
@@ -791,12 +791,12 @@ size_t BinaryTreeDictionary<Chunk>::totalListLength(TreeList<Chunk>* tl) const {
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
total
SizeInT
ree
(
TreeList
<
Chunk
>*
tl
)
const
{
size_t
BinaryTreeDictionary
<
Chunk
>::
total
_size_in_t
ree
(
TreeList
<
Chunk
>*
tl
)
const
{
if
(
tl
==
NULL
)
if
(
tl
==
NULL
)
return
0
;
return
0
;
return
(
tl
->
size
()
*
total
ListL
ength
(
tl
))
+
return
(
tl
->
size
()
*
total
_list_l
ength
(
tl
))
+
total
SizeInT
ree
(
tl
->
left
())
+
total
_size_in_t
ree
(
tl
->
left
())
+
total
SizeInT
ree
(
tl
->
right
());
total
_size_in_t
ree
(
tl
->
right
());
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
...
@@ -805,73 +805,73 @@ double BinaryTreeDictionary<Chunk>::sum_of_squared_block_sizes(TreeList<Chunk>*
...
@@ -805,73 +805,73 @@ double BinaryTreeDictionary<Chunk>::sum_of_squared_block_sizes(TreeList<Chunk>*
return
0.0
;
return
0.0
;
}
}
double
size
=
(
double
)(
tl
->
size
());
double
size
=
(
double
)(
tl
->
size
());
double
curr
=
size
*
size
*
total
ListL
ength
(
tl
);
double
curr
=
size
*
size
*
total
_list_l
ength
(
tl
);
curr
+=
sum_of_squared_block_sizes
(
tl
->
left
());
curr
+=
sum_of_squared_block_sizes
(
tl
->
left
());
curr
+=
sum_of_squared_block_sizes
(
tl
->
right
());
curr
+=
sum_of_squared_block_sizes
(
tl
->
right
());
return
curr
;
return
curr
;
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
total
FreeBlocksInT
ree
(
TreeList
<
Chunk
>*
tl
)
const
{
size_t
BinaryTreeDictionary
<
Chunk
>::
total
_free_blocks_in_t
ree
(
TreeList
<
Chunk
>*
tl
)
const
{
if
(
tl
==
NULL
)
if
(
tl
==
NULL
)
return
0
;
return
0
;
return
total
ListL
ength
(
tl
)
+
return
total
_list_l
ength
(
tl
)
+
total
FreeBlocksInT
ree
(
tl
->
left
())
+
total
_free_blocks_in_t
ree
(
tl
->
left
())
+
total
FreeBlocksInT
ree
(
tl
->
right
());
total
_free_blocks_in_t
ree
(
tl
->
right
());
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
num
FreeB
locks
()
const
{
size_t
BinaryTreeDictionary
<
Chunk
>::
num
_free_b
locks
()
const
{
assert
(
total
FreeBlocksInTree
(
root
())
==
totalFreeB
locks
(),
assert
(
total
_free_blocks_in_tree
(
root
())
==
total_free_b
locks
(),
"_total
FreeB
locks inconsistency"
);
"_total
_free_b
locks inconsistency"
);
return
total
FreeB
locks
();
return
total
_free_b
locks
();
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
tree
HeightH
elper
(
TreeList
<
Chunk
>*
tl
)
const
{
size_t
BinaryTreeDictionary
<
Chunk
>::
tree
_height_h
elper
(
TreeList
<
Chunk
>*
tl
)
const
{
if
(
tl
==
NULL
)
if
(
tl
==
NULL
)
return
0
;
return
0
;
return
1
+
MAX2
(
tree
HeightH
elper
(
tl
->
left
()),
return
1
+
MAX2
(
tree
_height_h
elper
(
tl
->
left
()),
tree
HeightH
elper
(
tl
->
right
()));
tree
_height_h
elper
(
tl
->
right
()));
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
treeHeight
()
const
{
size_t
BinaryTreeDictionary
<
Chunk
>::
treeHeight
()
const
{
return
tree
HeightH
elper
(
root
());
return
tree
_height_h
elper
(
root
());
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
total
NodesH
elper
(
TreeList
<
Chunk
>*
tl
)
const
{
size_t
BinaryTreeDictionary
<
Chunk
>::
total
_nodes_h
elper
(
TreeList
<
Chunk
>*
tl
)
const
{
if
(
tl
==
NULL
)
{
if
(
tl
==
NULL
)
{
return
0
;
return
0
;
}
}
return
1
+
total
NodesH
elper
(
tl
->
left
())
+
return
1
+
total
_nodes_h
elper
(
tl
->
left
())
+
total
NodesH
elper
(
tl
->
right
());
total
_nodes_h
elper
(
tl
->
right
());
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
total
NodesInT
ree
(
TreeList
<
Chunk
>*
tl
)
const
{
size_t
BinaryTreeDictionary
<
Chunk
>::
total
_nodes_in_t
ree
(
TreeList
<
Chunk
>*
tl
)
const
{
return
total
NodesH
elper
(
root
());
return
total
_nodes_h
elper
(
root
());
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
dict
CensusUpd
ate
(
size_t
size
,
bool
split
,
bool
birth
){
void
BinaryTreeDictionary
<
Chunk
>::
dict
_census_udp
ate
(
size_t
size
,
bool
split
,
bool
birth
){
TreeList
<
Chunk
>*
nd
=
find
L
ist
(
size
);
TreeList
<
Chunk
>*
nd
=
find
_l
ist
(
size
);
if
(
nd
)
{
if
(
nd
)
{
if
(
split
)
{
if
(
split
)
{
if
(
birth
)
{
if
(
birth
)
{
nd
->
increment_split
B
irths
();
nd
->
increment_split
_b
irths
();
nd
->
increment_surplus
();
nd
->
increment_surplus
();
}
else
{
}
else
{
nd
->
increment_split
D
eaths
();
nd
->
increment_split
_d
eaths
();
nd
->
decrement_surplus
();
nd
->
decrement_surplus
();
}
}
}
else
{
}
else
{
if
(
birth
)
{
if
(
birth
)
{
nd
->
increment_coal
B
irths
();
nd
->
increment_coal
_b
irths
();
nd
->
increment_surplus
();
nd
->
increment_surplus
();
}
else
{
}
else
{
nd
->
increment_coal
D
eaths
();
nd
->
increment_coal
_d
eaths
();
nd
->
decrement_surplus
();
nd
->
decrement_surplus
();
}
}
}
}
...
@@ -884,13 +884,13 @@ void BinaryTreeDictionary<Chunk>::dictCensusUpdate(size_t size, bool split, bool
...
@@ -884,13 +884,13 @@ void BinaryTreeDictionary<Chunk>::dictCensusUpdate(size_t size, bool split, bool
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
bool
BinaryTreeDictionary
<
Chunk
>::
coal
DictOverP
opulated
(
size_t
size
)
{
bool
BinaryTreeDictionary
<
Chunk
>::
coal
_dict_over_p
opulated
(
size_t
size
)
{
if
(
FLSAlwaysCoalesceLarge
)
return
true
;
if
(
FLSAlwaysCoalesceLarge
)
return
true
;
TreeList
<
Chunk
>*
list_of_size
=
find
L
ist
(
size
);
TreeList
<
Chunk
>*
list_of_size
=
find
_l
ist
(
size
);
// None of requested size implies overpopulated.
// None of requested size implies overpopulated.
return
list_of_size
==
NULL
||
list_of_size
->
coal
D
esired
()
<=
0
||
return
list_of_size
==
NULL
||
list_of_size
->
coal
_d
esired
()
<=
0
||
list_of_size
->
count
()
>
list_of_size
->
coal
D
esired
();
list_of_size
->
count
()
>
list_of_size
->
coal
_d
esired
();
}
}
// Closures for walking the binary tree.
// Closures for walking the binary tree.
...
@@ -952,9 +952,9 @@ class BeginSweepClosure : public AscendTreeCensusClosure<Chunk> {
...
@@ -952,9 +952,9 @@ class BeginSweepClosure : public AscendTreeCensusClosure<Chunk> {
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
double
coalSurplusPercent
=
_percentage
;
double
coalSurplusPercent
=
_percentage
;
fl
->
compute_desired
(
_inter_sweep_current
,
_inter_sweep_estimate
,
_intra_sweep_estimate
);
fl
->
compute_desired
(
_inter_sweep_current
,
_inter_sweep_estimate
,
_intra_sweep_estimate
);
fl
->
set_coal
D
esired
((
ssize_t
)((
double
)
fl
->
desired
()
*
coalSurplusPercent
));
fl
->
set_coal
_d
esired
((
ssize_t
)((
double
)
fl
->
desired
()
*
coalSurplusPercent
));
fl
->
set_before
S
weep
(
fl
->
count
());
fl
->
set_before
_s
weep
(
fl
->
count
());
fl
->
set_bfr
S
urp
(
fl
->
surplus
());
fl
->
set_bfr
_s
urp
(
fl
->
surplus
());
}
}
};
};
...
@@ -1031,7 +1031,7 @@ Chunk* BinaryTreeDictionary<Chunk>::find_chunk_ends_at(HeapWord* target) const {
...
@@ -1031,7 +1031,7 @@ Chunk* BinaryTreeDictionary<Chunk>::find_chunk_ends_at(HeapWord* target) const {
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
begin
SweepDictC
ensus
(
double
coalSurplusPercent
,
void
BinaryTreeDictionary
<
Chunk
>::
begin
_sweep_dict_c
ensus
(
double
coalSurplusPercent
,
float
inter_sweep_current
,
float
inter_sweep_estimate
,
float
intra_sweep_estimate
)
{
float
inter_sweep_current
,
float
inter_sweep_estimate
,
float
intra_sweep_estimate
)
{
BeginSweepClosure
<
Chunk
>
bsc
(
coalSurplusPercent
,
inter_sweep_current
,
BeginSweepClosure
<
Chunk
>
bsc
(
coalSurplusPercent
,
inter_sweep_current
,
inter_sweep_estimate
,
inter_sweep_estimate
,
...
@@ -1046,33 +1046,33 @@ template <class Chunk>
...
@@ -1046,33 +1046,33 @@ template <class Chunk>
class
InitializeDictReturnedBytesClosure
:
public
AscendTreeCensusClosure
<
Chunk
>
{
class
InitializeDictReturnedBytesClosure
:
public
AscendTreeCensusClosure
<
Chunk
>
{
public:
public:
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
fl
->
set_returned
B
ytes
(
0
);
fl
->
set_returned
_b
ytes
(
0
);
}
}
};
};
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
initialize
DictReturnedB
ytes
()
{
void
BinaryTreeDictionary
<
Chunk
>::
initialize
_dict_returned_b
ytes
()
{
InitializeDictReturnedBytesClosure
<
Chunk
>
idrb
;
InitializeDictReturnedBytesClosure
<
Chunk
>
idrb
;
idrb
.
do_tree
(
root
());
idrb
.
do_tree
(
root
());
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
class
ReturnedBytesClosure
:
public
AscendTreeCensusClosure
<
Chunk
>
{
class
ReturnedBytesClosure
:
public
AscendTreeCensusClosure
<
Chunk
>
{
size_t
_dict
ReturnedB
ytes
;
size_t
_dict
_returned_b
ytes
;
public:
public:
ReturnedBytesClosure
()
{
_dict
ReturnedB
ytes
=
0
;
}
ReturnedBytesClosure
()
{
_dict
_returned_b
ytes
=
0
;
}
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
_dict
ReturnedBytes
+=
fl
->
returnedB
ytes
();
_dict
_returned_bytes
+=
fl
->
returned_b
ytes
();
}
}
size_t
dict
ReturnedBytes
()
{
return
_dictReturnedB
ytes
;
}
size_t
dict
_returned_bytes
()
{
return
_dict_returned_b
ytes
;
}
};
};
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
sum
DictReturnedB
ytes
()
{
size_t
BinaryTreeDictionary
<
Chunk
>::
sum
_dict_returned_b
ytes
()
{
ReturnedBytesClosure
<
Chunk
>
rbc
;
ReturnedBytesClosure
<
Chunk
>
rbc
;
rbc
.
do_tree
(
root
());
rbc
.
do_tree
(
root
());
return
rbc
.
dict
ReturnedB
ytes
();
return
rbc
.
dict
_returned_b
ytes
();
}
}
// Count the number of entries in the tree.
// Count the number of entries in the tree.
...
@@ -1087,7 +1087,7 @@ class treeCountClosure : public DescendTreeCensusClosure<Chunk> {
...
@@ -1087,7 +1087,7 @@ class treeCountClosure : public DescendTreeCensusClosure<Chunk> {
};
};
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
total
C
ount
()
{
size_t
BinaryTreeDictionary
<
Chunk
>::
total
_c
ount
()
{
treeCountClosure
<
Chunk
>
ctc
(
0
);
treeCountClosure
<
Chunk
>
ctc
(
0
);
ctc
.
do_tree
(
root
());
ctc
.
do_tree
(
root
());
return
ctc
.
count
;
return
ctc
.
count
;
...
@@ -1108,7 +1108,7 @@ class setTreeSurplusClosure : public AscendTreeCensusClosure<Chunk> {
...
@@ -1108,7 +1108,7 @@ class setTreeSurplusClosure : public AscendTreeCensusClosure<Chunk> {
};
};
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
set
TreeS
urplus
(
double
splitSurplusPercent
)
{
void
BinaryTreeDictionary
<
Chunk
>::
set
_tree_s
urplus
(
double
splitSurplusPercent
)
{
setTreeSurplusClosure
<
Chunk
>
sts
(
splitSurplusPercent
);
setTreeSurplusClosure
<
Chunk
>
sts
(
splitSurplusPercent
);
sts
.
do_tree
(
root
());
sts
.
do_tree
(
root
());
}
}
...
@@ -1130,7 +1130,7 @@ class setTreeHintsClosure : public DescendTreeCensusClosure<Chunk> {
...
@@ -1130,7 +1130,7 @@ class setTreeHintsClosure : public DescendTreeCensusClosure<Chunk> {
};
};
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
set
TreeH
ints
(
void
)
{
void
BinaryTreeDictionary
<
Chunk
>::
set
_tree_h
ints
(
void
)
{
setTreeHintsClosure
<
Chunk
>
sth
(
0
);
setTreeHintsClosure
<
Chunk
>
sth
(
0
);
sth
.
do_tree
(
root
());
sth
.
do_tree
(
root
());
}
}
...
@@ -1139,45 +1139,45 @@ void BinaryTreeDictionary<Chunk>::setTreeHints(void) {
...
@@ -1139,45 +1139,45 @@ void BinaryTreeDictionary<Chunk>::setTreeHints(void) {
template
<
class
Chunk
>
template
<
class
Chunk
>
class
clearTreeCensusClosure
:
public
AscendTreeCensusClosure
<
Chunk
>
{
class
clearTreeCensusClosure
:
public
AscendTreeCensusClosure
<
Chunk
>
{
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
fl
->
set_prev
S
weep
(
fl
->
count
());
fl
->
set_prev
_s
weep
(
fl
->
count
());
fl
->
set_coal
B
irths
(
0
);
fl
->
set_coal
_b
irths
(
0
);
fl
->
set_coal
D
eaths
(
0
);
fl
->
set_coal
_d
eaths
(
0
);
fl
->
set_split
B
irths
(
0
);
fl
->
set_split
_b
irths
(
0
);
fl
->
set_split
D
eaths
(
0
);
fl
->
set_split
_d
eaths
(
0
);
}
}
};
};
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
clear
TreeC
ensus
(
void
)
{
void
BinaryTreeDictionary
<
Chunk
>::
clear
_tree_c
ensus
(
void
)
{
clearTreeCensusClosure
<
Chunk
>
ctc
;
clearTreeCensusClosure
<
Chunk
>
ctc
;
ctc
.
do_tree
(
root
());
ctc
.
do_tree
(
root
());
}
}
// Do reporting and post sweep clean up.
// Do reporting and post sweep clean up.
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
end
SweepDictC
ensus
(
double
splitSurplusPercent
)
{
void
BinaryTreeDictionary
<
Chunk
>::
end
_sweep_dict_c
ensus
(
double
splitSurplusPercent
)
{
// Does walking the tree 3 times hurt?
// Does walking the tree 3 times hurt?
set
TreeS
urplus
(
splitSurplusPercent
);
set
_tree_s
urplus
(
splitSurplusPercent
);
set
TreeH
ints
();
set
_tree_h
ints
();
if
(
PrintGC
&&
Verbose
)
{
if
(
PrintGC
&&
Verbose
)
{
report
S
tatistics
();
report
_s
tatistics
();
}
}
clear
TreeC
ensus
();
clear
_tree_c
ensus
();
}
}
// Print summary statistics
// Print summary statistics
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
report
S
tatistics
()
const
{
void
BinaryTreeDictionary
<
Chunk
>::
report
_s
tatistics
()
const
{
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
gclog_or_tty
->
print
(
"Statistics for BinaryTreeDictionary:
\n
"
gclog_or_tty
->
print
(
"Statistics for BinaryTreeDictionary:
\n
"
"------------------------------------
\n
"
);
"------------------------------------
\n
"
);
size_t
total
Size
=
totalChunkS
ize
(
debug_only
(
NULL
));
size_t
total
_size
=
total_chunk_s
ize
(
debug_only
(
NULL
));
size_t
free
Blocks
=
numFreeB
locks
();
size_t
free
_blocks
=
num_free_b
locks
();
gclog_or_tty
->
print
(
"Total Free Space: %d
\n
"
,
total
S
ize
);
gclog_or_tty
->
print
(
"Total Free Space: %d
\n
"
,
total
_s
ize
);
gclog_or_tty
->
print
(
"Max Chunk Size: %d
\n
"
,
max
ChunkS
ize
());
gclog_or_tty
->
print
(
"Max Chunk Size: %d
\n
"
,
max
_chunk_s
ize
());
gclog_or_tty
->
print
(
"Number of Blocks: %d
\n
"
,
free
B
locks
);
gclog_or_tty
->
print
(
"Number of Blocks: %d
\n
"
,
free
_b
locks
);
if
(
free
B
locks
>
0
)
{
if
(
free
_b
locks
>
0
)
{
gclog_or_tty
->
print
(
"Av. Block Size: %d
\n
"
,
total
Size
/
freeB
locks
);
gclog_or_tty
->
print
(
"Av. Block Size: %d
\n
"
,
total
_size
/
free_b
locks
);
}
}
gclog_or_tty
->
print
(
"Tree Height: %d
\n
"
,
treeHeight
());
gclog_or_tty
->
print
(
"Tree Height: %d
\n
"
,
treeHeight
());
}
}
...
@@ -1188,38 +1188,38 @@ void BinaryTreeDictionary<Chunk>::reportStatistics() const {
...
@@ -1188,38 +1188,38 @@ void BinaryTreeDictionary<Chunk>::reportStatistics() const {
template
<
class
Chunk
>
template
<
class
Chunk
>
class
PrintTreeCensusClosure
:
public
AscendTreeCensusClosure
<
Chunk
>
{
class
PrintTreeCensusClosure
:
public
AscendTreeCensusClosure
<
Chunk
>
{
int
_print_line
;
int
_print_line
;
size_t
_total
F
ree
;
size_t
_total
_f
ree
;
FreeList
<
Chunk
>
_total
;
FreeList
<
Chunk
>
_total
;
public:
public:
PrintTreeCensusClosure
()
{
PrintTreeCensusClosure
()
{
_print_line
=
0
;
_print_line
=
0
;
_total
F
ree
=
0
;
_total
_f
ree
=
0
;
}
}
FreeList
<
Chunk
>*
total
()
{
return
&
_total
;
}
FreeList
<
Chunk
>*
total
()
{
return
&
_total
;
}
size_t
total
Free
()
{
return
_totalF
ree
;
}
size_t
total
_free
()
{
return
_total_f
ree
;
}
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
void
do_list
(
FreeList
<
Chunk
>*
fl
)
{
if
(
++
_print_line
>=
40
)
{
if
(
++
_print_line
>=
40
)
{
FreeList
<
Chunk
>::
print_labels_on
(
gclog_or_tty
,
"size"
);
FreeList
<
Chunk
>::
print_labels_on
(
gclog_or_tty
,
"size"
);
_print_line
=
0
;
_print_line
=
0
;
}
}
fl
->
print_on
(
gclog_or_tty
);
fl
->
print_on
(
gclog_or_tty
);
_total
F
ree
+=
fl
->
count
()
*
fl
->
size
()
;
_total
_f
ree
+=
fl
->
count
()
*
fl
->
size
()
;
total
()
->
set_count
(
total
()
->
count
()
+
fl
->
count
()
);
total
()
->
set_count
(
total
()
->
count
()
+
fl
->
count
()
);
total
()
->
set_bfr
Surp
(
total
()
->
bfrSurp
()
+
fl
->
bfrS
urp
()
);
total
()
->
set_bfr
_surp
(
total
()
->
bfr_surp
()
+
fl
->
bfr_s
urp
()
);
total
()
->
set_surplus
(
total
()
->
split
D
eaths
()
+
fl
->
surplus
()
);
total
()
->
set_surplus
(
total
()
->
split
_d
eaths
()
+
fl
->
surplus
()
);
total
()
->
set_desired
(
total
()
->
desired
()
+
fl
->
desired
()
);
total
()
->
set_desired
(
total
()
->
desired
()
+
fl
->
desired
()
);
total
()
->
set_prev
Sweep
(
total
()
->
prevSweep
()
+
fl
->
prevS
weep
()
);
total
()
->
set_prev
_sweep
(
total
()
->
prev_sweep
()
+
fl
->
prev_s
weep
()
);
total
()
->
set_before
Sweep
(
total
()
->
beforeSweep
()
+
fl
->
beforeS
weep
());
total
()
->
set_before
_sweep
(
total
()
->
before_sweep
()
+
fl
->
before_s
weep
());
total
()
->
set_coal
Births
(
total
()
->
coalBirths
()
+
fl
->
coalB
irths
()
);
total
()
->
set_coal
_births
(
total
()
->
coal_births
()
+
fl
->
coal_b
irths
()
);
total
()
->
set_coal
Deaths
(
total
()
->
coalDeaths
()
+
fl
->
coalD
eaths
()
);
total
()
->
set_coal
_deaths
(
total
()
->
coal_deaths
()
+
fl
->
coal_d
eaths
()
);
total
()
->
set_split
Births
(
total
()
->
splitBirths
()
+
fl
->
splitB
irths
());
total
()
->
set_split
_births
(
total
()
->
split_births
()
+
fl
->
split_b
irths
());
total
()
->
set_split
Deaths
(
total
()
->
splitDeaths
()
+
fl
->
splitD
eaths
());
total
()
->
set_split
_deaths
(
total
()
->
split_deaths
()
+
fl
->
split_d
eaths
());
}
}
};
};
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
print
DictC
ensus
(
void
)
const
{
void
BinaryTreeDictionary
<
Chunk
>::
print
_dict_c
ensus
(
void
)
const
{
gclog_or_tty
->
print
(
"
\n
BinaryTree
\n
"
);
gclog_or_tty
->
print
(
"
\n
BinaryTree
\n
"
);
FreeList
<
Chunk
>::
print_labels_on
(
gclog_or_tty
,
"size"
);
FreeList
<
Chunk
>::
print_labels_on
(
gclog_or_tty
,
"size"
);
...
@@ -1230,12 +1230,12 @@ void BinaryTreeDictionary<Chunk>::printDictCensus(void) const {
...
@@ -1230,12 +1230,12 @@ void BinaryTreeDictionary<Chunk>::printDictCensus(void) const {
FreeList
<
Chunk
>::
print_labels_on
(
gclog_or_tty
,
" "
);
FreeList
<
Chunk
>::
print_labels_on
(
gclog_or_tty
,
" "
);
total
->
print_on
(
gclog_or_tty
,
"TOTAL
\t
"
);
total
->
print_on
(
gclog_or_tty
,
"TOTAL
\t
"
);
gclog_or_tty
->
print
(
gclog_or_tty
->
print
(
"total
F
ree(words): "
SIZE_FORMAT_W
(
16
)
"total
_f
ree(words): "
SIZE_FORMAT_W
(
16
)
" growth: %8.5f deficit: %8.5f
\n
"
,
" growth: %8.5f deficit: %8.5f
\n
"
,
ptc
.
total
F
ree
(),
ptc
.
total
_f
ree
(),
(
double
)(
total
->
split
Births
()
+
total
->
coalB
irths
()
(
double
)(
total
->
split
_births
()
+
total
->
coal_b
irths
()
-
total
->
split
Deaths
()
-
total
->
coalD
eaths
())
-
total
->
split
_deaths
()
-
total
->
coal_d
eaths
())
/
(
total
->
prev
Sweep
()
!=
0
?
(
double
)
total
->
prevS
weep
()
:
1.0
),
/
(
total
->
prev
_sweep
()
!=
0
?
(
double
)
total
->
prev_s
weep
()
:
1.0
),
(
double
)(
total
->
desired
()
-
total
->
count
())
(
double
)(
total
->
desired
()
-
total
->
count
())
/
(
total
->
desired
()
!=
0
?
(
double
)
total
->
desired
()
:
1.0
));
/
(
total
->
desired
()
!=
0
?
(
double
)
total
->
desired
()
:
1.0
));
}
}
...
@@ -1279,19 +1279,19 @@ void BinaryTreeDictionary<Chunk>::print_free_lists(outputStream* st) const {
...
@@ -1279,19 +1279,19 @@ void BinaryTreeDictionary<Chunk>::print_free_lists(outputStream* st) const {
// . parent and child point to each other
// . parent and child point to each other
// . each node's key correctly related to that of its child(ren)
// . each node's key correctly related to that of its child(ren)
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
verify
T
ree
()
const
{
void
BinaryTreeDictionary
<
Chunk
>::
verify
_t
ree
()
const
{
guarantee
(
root
()
==
NULL
||
total
FreeB
locks
()
==
0
||
guarantee
(
root
()
==
NULL
||
total
_free_b
locks
()
==
0
||
total
Size
()
!=
0
,
"_totalS
ize should't be 0?"
);
total
_size
()
!=
0
,
"_total_s
ize should't be 0?"
);
guarantee
(
root
()
==
NULL
||
root
()
->
parent
()
==
NULL
,
"_root shouldn't have parent"
);
guarantee
(
root
()
==
NULL
||
root
()
->
parent
()
==
NULL
,
"_root shouldn't have parent"
);
verify
TreeH
elper
(
root
());
verify
_tree_h
elper
(
root
());
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
size_t
BinaryTreeDictionary
<
Chunk
>::
verify
PrevFreeP
trs
(
TreeList
<
Chunk
>*
tl
)
{
size_t
BinaryTreeDictionary
<
Chunk
>::
verify
_prev_free_p
trs
(
TreeList
<
Chunk
>*
tl
)
{
size_t
ct
=
0
;
size_t
ct
=
0
;
for
(
Chunk
*
curFC
=
tl
->
head
();
curFC
!=
NULL
;
curFC
=
curFC
->
next
())
{
for
(
Chunk
*
curFC
=
tl
->
head
();
curFC
!=
NULL
;
curFC
=
curFC
->
next
())
{
ct
++
;
ct
++
;
assert
(
curFC
->
prev
()
==
NULL
||
curFC
->
prev
()
->
is
F
ree
(),
assert
(
curFC
->
prev
()
==
NULL
||
curFC
->
prev
()
->
is
_f
ree
(),
"Chunk should be free"
);
"Chunk should be free"
);
}
}
return
ct
;
return
ct
;
...
@@ -1301,7 +1301,7 @@ size_t BinaryTreeDictionary<Chunk>::verifyPrevFreePtrs(TreeList<Chunk>* tl) {
...
@@ -1301,7 +1301,7 @@ size_t BinaryTreeDictionary<Chunk>::verifyPrevFreePtrs(TreeList<Chunk>* tl) {
// caution on very deep trees; and watch out for stack overflow errors;
// caution on very deep trees; and watch out for stack overflow errors;
// In general, to be used only for debugging.
// In general, to be used only for debugging.
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
verify
TreeH
elper
(
TreeList
<
Chunk
>*
tl
)
const
{
void
BinaryTreeDictionary
<
Chunk
>::
verify
_tree_h
elper
(
TreeList
<
Chunk
>*
tl
)
const
{
if
(
tl
==
NULL
)
if
(
tl
==
NULL
)
return
;
return
;
guarantee
(
tl
->
size
()
!=
0
,
"A list must has a size"
);
guarantee
(
tl
->
size
()
!=
0
,
"A list must has a size"
);
...
@@ -1313,26 +1313,26 @@ void BinaryTreeDictionary<Chunk>::verifyTreeHelper(TreeList<Chunk>* tl) const {
...
@@ -1313,26 +1313,26 @@ void BinaryTreeDictionary<Chunk>::verifyTreeHelper(TreeList<Chunk>* tl) const {
"parent !> left"
);
"parent !> left"
);
guarantee
(
tl
->
right
()
==
NULL
||
tl
->
right
()
->
size
()
>
tl
->
size
(),
guarantee
(
tl
->
right
()
==
NULL
||
tl
->
right
()
->
size
()
>
tl
->
size
(),
"parent !< left"
);
"parent !< left"
);
guarantee
(
tl
->
head
()
==
NULL
||
tl
->
head
()
->
is
F
ree
(),
"!Free"
);
guarantee
(
tl
->
head
()
==
NULL
||
tl
->
head
()
->
is
_f
ree
(),
"!Free"
);
guarantee
(
tl
->
head
()
==
NULL
||
tl
->
head_as_TreeChunk
()
->
list
()
==
tl
,
guarantee
(
tl
->
head
()
==
NULL
||
tl
->
head_as_TreeChunk
()
->
list
()
==
tl
,
"list inconsistency"
);
"list inconsistency"
);
guarantee
(
tl
->
count
()
>
0
||
(
tl
->
head
()
==
NULL
&&
tl
->
tail
()
==
NULL
),
guarantee
(
tl
->
count
()
>
0
||
(
tl
->
head
()
==
NULL
&&
tl
->
tail
()
==
NULL
),
"list count is inconsistent"
);
"list count is inconsistent"
);
guarantee
(
tl
->
count
()
>
1
||
tl
->
head
()
==
tl
->
tail
(),
guarantee
(
tl
->
count
()
>
1
||
tl
->
head
()
==
tl
->
tail
(),
"list is incorrectly constructed"
);
"list is incorrectly constructed"
);
size_t
count
=
verify
PrevFreeP
trs
(
tl
);
size_t
count
=
verify
_prev_free_p
trs
(
tl
);
guarantee
(
count
==
(
size_t
)
tl
->
count
(),
"Node count is incorrect"
);
guarantee
(
count
==
(
size_t
)
tl
->
count
(),
"Node count is incorrect"
);
if
(
tl
->
head
()
!=
NULL
)
{
if
(
tl
->
head
()
!=
NULL
)
{
tl
->
head_as_TreeChunk
()
->
verify
TreeChunkL
ist
();
tl
->
head_as_TreeChunk
()
->
verify
_tree_chunk_l
ist
();
}
}
verify
TreeH
elper
(
tl
->
left
());
verify
_tree_h
elper
(
tl
->
left
());
verify
TreeH
elper
(
tl
->
right
());
verify
_tree_h
elper
(
tl
->
right
());
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
BinaryTreeDictionary
<
Chunk
>::
verify
()
const
{
void
BinaryTreeDictionary
<
Chunk
>::
verify
()
const
{
verify
T
ree
();
verify
_t
ree
();
guarantee
(
total
Size
()
==
totalSizeInT
ree
(
root
()),
"Total Size inconsistency"
);
guarantee
(
total
_size
()
==
total_size_in_t
ree
(
root
()),
"Total Size inconsistency"
);
}
}
#ifndef SERIALGC
#ifndef SERIALGC
...
...
src/share/vm/memory/binaryTreeDictionary.hpp
浏览文件 @
2c61150c
...
@@ -70,22 +70,22 @@ class TreeList: public FreeList<Chunk> {
...
@@ -70,22 +70,22 @@ class TreeList: public FreeList<Chunk> {
// Accessors for links in tree.
// Accessors for links in tree.
void
set
L
eft
(
TreeList
<
Chunk
>*
tl
)
{
void
set
_l
eft
(
TreeList
<
Chunk
>*
tl
)
{
_left
=
tl
;
_left
=
tl
;
if
(
tl
!=
NULL
)
if
(
tl
!=
NULL
)
tl
->
set
P
arent
(
this
);
tl
->
set
_p
arent
(
this
);
}
}
void
set
R
ight
(
TreeList
<
Chunk
>*
tl
)
{
void
set
_r
ight
(
TreeList
<
Chunk
>*
tl
)
{
_right
=
tl
;
_right
=
tl
;
if
(
tl
!=
NULL
)
if
(
tl
!=
NULL
)
tl
->
set
P
arent
(
this
);
tl
->
set
_p
arent
(
this
);
}
}
void
set
P
arent
(
TreeList
<
Chunk
>*
tl
)
{
_parent
=
tl
;
}
void
set
_p
arent
(
TreeList
<
Chunk
>*
tl
)
{
_parent
=
tl
;
}
void
clearLeft
()
{
_left
=
NULL
;
}
void
clearLeft
()
{
_left
=
NULL
;
}
void
clear
R
ight
()
{
_right
=
NULL
;
}
void
clear
_r
ight
()
{
_right
=
NULL
;
}
void
clear
P
arent
()
{
_parent
=
NULL
;
}
void
clear
_p
arent
()
{
_parent
=
NULL
;
}
void
initialize
()
{
clearLeft
();
clear
Right
(),
clearP
arent
();
}
void
initialize
()
{
clearLeft
();
clear
_right
(),
clear_p
arent
();
}
// For constructing a TreeList from a Tree chunk or
// For constructing a TreeList from a Tree chunk or
// address and size.
// address and size.
...
@@ -104,16 +104,16 @@ class TreeList: public FreeList<Chunk> {
...
@@ -104,16 +104,16 @@ class TreeList: public FreeList<Chunk> {
// use with caution!
// use with caution!
TreeChunk
<
Chunk
>*
largest_address
();
TreeChunk
<
Chunk
>*
largest_address
();
// remove
ChunkReplaceIfN
eeded() removes the given "tc" from the TreeList.
// remove
_chunk_replace_if_n
eeded() removes the given "tc" from the TreeList.
// If "tc" is the first chunk in the list, it is also the
// If "tc" is the first chunk in the list, it is also the
// TreeList that is the node in the tree. remove
ChunkReplaceIfN
eeded()
// TreeList that is the node in the tree. remove
_chunk_replace_if_n
eeded()
// returns the possibly replaced TreeList* for the node in
// returns the possibly replaced TreeList* for the node in
// the tree. It also updates the parent of the original
// the tree. It also updates the parent of the original
// node to point to the new node.
// node to point to the new node.
TreeList
<
Chunk
>*
remove
ChunkReplaceIfN
eeded
(
TreeChunk
<
Chunk
>*
tc
);
TreeList
<
Chunk
>*
remove
_chunk_replace_if_n
eeded
(
TreeChunk
<
Chunk
>*
tc
);
// See FreeList.
// See FreeList.
void
return
ChunkAtH
ead
(
TreeChunk
<
Chunk
>*
tc
);
void
return
_chunk_at_h
ead
(
TreeChunk
<
Chunk
>*
tc
);
void
return
ChunkAtT
ail
(
TreeChunk
<
Chunk
>*
tc
);
void
return
_chunk_at_t
ail
(
TreeChunk
<
Chunk
>*
tc
);
};
};
// A TreeChunk is a subclass of a Chunk that additionally
// A TreeChunk is a subclass of a Chunk that additionally
...
@@ -151,7 +151,7 @@ class TreeChunk : public Chunk {
...
@@ -151,7 +151,7 @@ class TreeChunk : public Chunk {
size_t
size
()
const
volatile
{
return
Chunk
::
size
();
}
size_t
size
()
const
volatile
{
return
Chunk
::
size
();
}
// debugging
// debugging
void
verify
TreeChunkL
ist
()
const
;
void
verify
_tree_chunk_l
ist
()
const
;
};
};
...
@@ -159,19 +159,19 @@ template <class Chunk>
...
@@ -159,19 +159,19 @@ template <class Chunk>
class
BinaryTreeDictionary
:
public
FreeBlockDictionary
<
Chunk
>
{
class
BinaryTreeDictionary
:
public
FreeBlockDictionary
<
Chunk
>
{
friend
class
VMStructs
;
friend
class
VMStructs
;
bool
_splay
;
bool
_splay
;
size_t
_total
S
ize
;
size_t
_total
_s
ize
;
size_t
_total
FreeB
locks
;
size_t
_total
_free_b
locks
;
TreeList
<
Chunk
>*
_root
;
TreeList
<
Chunk
>*
_root
;
bool
_adaptive_freelists
;
bool
_adaptive_freelists
;
// private accessors
// private accessors
bool
splay
()
const
{
return
_splay
;
}
bool
splay
()
const
{
return
_splay
;
}
void
set_splay
(
bool
v
)
{
_splay
=
v
;
}
void
set_splay
(
bool
v
)
{
_splay
=
v
;
}
void
set_total
Size
(
size_t
v
)
{
_totalS
ize
=
v
;
}
void
set_total
_size
(
size_t
v
)
{
_total_s
ize
=
v
;
}
virtual
void
inc_total
S
ize
(
size_t
v
);
virtual
void
inc_total
_s
ize
(
size_t
v
);
virtual
void
dec_total
S
ize
(
size_t
v
);
virtual
void
dec_total
_s
ize
(
size_t
v
);
size_t
total
FreeBlocks
()
const
{
return
_totalFreeB
locks
;
}
size_t
total
_free_blocks
()
const
{
return
_total_free_b
locks
;
}
void
set_total
FreeBlocks
(
size_t
v
)
{
_totalFreeB
locks
=
v
;
}
void
set_total
_free_blocks
(
size_t
v
)
{
_total_free_b
locks
=
v
;
}
TreeList
<
Chunk
>*
root
()
const
{
return
_root
;
}
TreeList
<
Chunk
>*
root
()
const
{
return
_root
;
}
void
set_root
(
TreeList
<
Chunk
>*
v
)
{
_root
=
v
;
}
void
set_root
(
TreeList
<
Chunk
>*
v
)
{
_root
=
v
;
}
bool
adaptive_freelists
()
{
return
_adaptive_freelists
;
}
bool
adaptive_freelists
()
{
return
_adaptive_freelists
;
}
...
@@ -186,46 +186,46 @@ class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> {
...
@@ -186,46 +186,46 @@ class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> {
// return it. If the chunk
// return it. If the chunk
// is the last chunk of that size, remove the node for that size
// is the last chunk of that size, remove the node for that size
// from the tree.
// from the tree.
TreeChunk
<
Chunk
>*
get
ChunkFromT
ree
(
size_t
size
,
enum
FreeBlockDictionary
<
Chunk
>::
Dither
dither
,
bool
splay
);
TreeChunk
<
Chunk
>*
get
_chunk_from_t
ree
(
size_t
size
,
enum
FreeBlockDictionary
<
Chunk
>::
Dither
dither
,
bool
splay
);
// Return a list of the specified size or NULL from the tree.
// Return a list of the specified size or NULL from the tree.
// The list is not removed from the tree.
// The list is not removed from the tree.
TreeList
<
Chunk
>*
find
L
ist
(
size_t
size
)
const
;
TreeList
<
Chunk
>*
find
_l
ist
(
size_t
size
)
const
;
// Remove this chunk from the tree. If the removal results
// Remove this chunk from the tree. If the removal results
// in an empty list in the tree, remove the empty list.
// in an empty list in the tree, remove the empty list.
TreeChunk
<
Chunk
>*
remove
ChunkFromT
ree
(
TreeChunk
<
Chunk
>*
tc
);
TreeChunk
<
Chunk
>*
remove
_chunk_from_t
ree
(
TreeChunk
<
Chunk
>*
tc
);
// Remove the node in the trees starting at tl that has the
// Remove the node in the trees starting at tl that has the
// minimum value and return it. Repair the tree as needed.
// minimum value and return it. Repair the tree as needed.
TreeList
<
Chunk
>*
remove
TreeM
inimum
(
TreeList
<
Chunk
>*
tl
);
TreeList
<
Chunk
>*
remove
_tree_m
inimum
(
TreeList
<
Chunk
>*
tl
);
void
semi
SplayS
tep
(
TreeList
<
Chunk
>*
tl
);
void
semi
_splay_s
tep
(
TreeList
<
Chunk
>*
tl
);
// Add this free chunk to the tree.
// Add this free chunk to the tree.
void
insert
ChunkInT
ree
(
Chunk
*
freeChunk
);
void
insert
_chunk_in_t
ree
(
Chunk
*
freeChunk
);
public:
public:
static
const
size_t
min_tree_chunk_size
=
sizeof
(
TreeChunk
<
Chunk
>
)
/
HeapWordSize
;
static
const
size_t
min_tree_chunk_size
=
sizeof
(
TreeChunk
<
Chunk
>
)
/
HeapWordSize
;
void
verify
T
ree
()
const
;
void
verify
_t
ree
()
const
;
// verify that the given chunk is in the tree.
// verify that the given chunk is in the tree.
bool
verify
ChunkInFreeLists
(
Chunk
*
tc
)
const
;
bool
verify
_chunk_in_free_list
(
Chunk
*
tc
)
const
;
private:
private:
void
verify
TreeH
elper
(
TreeList
<
Chunk
>*
tl
)
const
;
void
verify
_tree_h
elper
(
TreeList
<
Chunk
>*
tl
)
const
;
static
size_t
verify
PrevFreeP
trs
(
TreeList
<
Chunk
>*
tl
);
static
size_t
verify
_prev_free_p
trs
(
TreeList
<
Chunk
>*
tl
);
// Returns the total number of chunks in the list.
// Returns the total number of chunks in the list.
size_t
total
ListL
ength
(
TreeList
<
Chunk
>*
tl
)
const
;
size_t
total
_list_l
ength
(
TreeList
<
Chunk
>*
tl
)
const
;
// Returns the total number of words in the chunks in the tree
// Returns the total number of words in the chunks in the tree
// starting at "tl".
// starting at "tl".
size_t
total
SizeInT
ree
(
TreeList
<
Chunk
>*
tl
)
const
;
size_t
total
_size_in_t
ree
(
TreeList
<
Chunk
>*
tl
)
const
;
// Returns the sum of the square of the size of each block
// Returns the sum of the square of the size of each block
// in the tree starting at "tl".
// in the tree starting at "tl".
double
sum_of_squared_block_sizes
(
TreeList
<
Chunk
>*
const
tl
)
const
;
double
sum_of_squared_block_sizes
(
TreeList
<
Chunk
>*
const
tl
)
const
;
// Returns the total number of free blocks in the tree starting
// Returns the total number of free blocks in the tree starting
// at "tl".
// at "tl".
size_t
total
FreeBlocksInT
ree
(
TreeList
<
Chunk
>*
tl
)
const
;
size_t
total
_free_blocks_in_t
ree
(
TreeList
<
Chunk
>*
tl
)
const
;
size_t
num
FreeB
locks
()
const
;
size_t
num
_free_b
locks
()
const
;
size_t
treeHeight
()
const
;
size_t
treeHeight
()
const
;
size_t
tree
HeightH
elper
(
TreeList
<
Chunk
>*
tl
)
const
;
size_t
tree
_height_h
elper
(
TreeList
<
Chunk
>*
tl
)
const
;
size_t
total
NodesInT
ree
(
TreeList
<
Chunk
>*
tl
)
const
;
size_t
total
_nodes_in_t
ree
(
TreeList
<
Chunk
>*
tl
)
const
;
size_t
total
NodesH
elper
(
TreeList
<
Chunk
>*
tl
)
const
;
size_t
total
_nodes_h
elper
(
TreeList
<
Chunk
>*
tl
)
const
;
public:
public:
// Constructor
// Constructor
...
@@ -233,7 +233,7 @@ class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> {
...
@@ -233,7 +233,7 @@ class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> {
BinaryTreeDictionary
(
MemRegion
mr
,
bool
adaptive_freelists
,
bool
splay
=
false
);
BinaryTreeDictionary
(
MemRegion
mr
,
bool
adaptive_freelists
,
bool
splay
=
false
);
// Public accessors
// Public accessors
size_t
total
Size
()
const
{
return
_totalS
ize
;
}
size_t
total
_size
()
const
{
return
_total_s
ize
;
}
// Reset the dictionary to the initial conditions with
// Reset the dictionary to the initial conditions with
// a single free chunk.
// a single free chunk.
...
@@ -245,37 +245,37 @@ class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> {
...
@@ -245,37 +245,37 @@ class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> {
// Return a chunk of size "size" or greater from
// Return a chunk of size "size" or greater from
// the tree.
// the tree.
// want a better dynamic splay strategy for the future.
// want a better dynamic splay strategy for the future.
Chunk
*
get
C
hunk
(
size_t
size
,
enum
FreeBlockDictionary
<
Chunk
>::
Dither
dither
)
{
Chunk
*
get
_c
hunk
(
size_t
size
,
enum
FreeBlockDictionary
<
Chunk
>::
Dither
dither
)
{
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
Chunk
*
res
=
get
ChunkFromT
ree
(
size
,
dither
,
splay
());
Chunk
*
res
=
get
_chunk_from_t
ree
(
size
,
dither
,
splay
());
assert
(
res
==
NULL
||
res
->
is
F
ree
(),
assert
(
res
==
NULL
||
res
->
is
_f
ree
(),
"Should be returning a free chunk"
);
"Should be returning a free chunk"
);
return
res
;
return
res
;
}
}
void
return
C
hunk
(
Chunk
*
chunk
)
{
void
return
_c
hunk
(
Chunk
*
chunk
)
{
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
insert
ChunkInT
ree
(
chunk
);
insert
_chunk_in_t
ree
(
chunk
);
}
}
void
remove
C
hunk
(
Chunk
*
chunk
)
{
void
remove
_c
hunk
(
Chunk
*
chunk
)
{
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
();
remove
ChunkFromT
ree
((
TreeChunk
<
Chunk
>*
)
chunk
);
remove
_chunk_from_t
ree
((
TreeChunk
<
Chunk
>*
)
chunk
);
assert
(
chunk
->
is
F
ree
(),
"Should still be a free chunk"
);
assert
(
chunk
->
is
_f
ree
(),
"Should still be a free chunk"
);
}
}
size_t
max
ChunkS
ize
()
const
;
size_t
max
_chunk_s
ize
()
const
;
size_t
total
ChunkS
ize
(
debug_only
(
const
Mutex
*
lock
))
const
{
size_t
total
_chunk_s
ize
(
debug_only
(
const
Mutex
*
lock
))
const
{
debug_only
(
debug_only
(
if
(
lock
!=
NULL
&&
lock
->
owned_by_self
())
{
if
(
lock
!=
NULL
&&
lock
->
owned_by_self
())
{
assert
(
total
SizeInTree
(
root
())
==
totalS
ize
(),
assert
(
total
_size_in_tree
(
root
())
==
total_s
ize
(),
"_total
S
ize inconsistency"
);
"_total
_s
ize inconsistency"
);
}
}
)
)
return
total
S
ize
();
return
total
_s
ize
();
}
}
size_t
min
S
ize
()
const
{
size_t
min
_s
ize
()
const
{
return
min_tree_chunk_size
;
return
min_tree_chunk_size
;
}
}
...
@@ -288,40 +288,40 @@ class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> {
...
@@ -288,40 +288,40 @@ class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> {
// Find the list with size "size" in the binary tree and update
// Find the list with size "size" in the binary tree and update
// the statistics in the list according to "split" (chunk was
// the statistics in the list according to "split" (chunk was
// split or coalesce) and "birth" (chunk was added or removed).
// split or coalesce) and "birth" (chunk was added or removed).
void
dict
CensusUpd
ate
(
size_t
size
,
bool
split
,
bool
birth
);
void
dict
_census_udp
ate
(
size_t
size
,
bool
split
,
bool
birth
);
// Return true if the dictionary is overpopulated (more chunks of
// Return true if the dictionary is overpopulated (more chunks of
// this size than desired) for size "size".
// this size than desired) for size "size".
bool
coal
DictOverP
opulated
(
size_t
size
);
bool
coal
_dict_over_p
opulated
(
size_t
size
);
// Methods called at the beginning of a sweep to prepare the
// Methods called at the beginning of a sweep to prepare the
// statistics for the sweep.
// statistics for the sweep.
void
begin
SweepDictC
ensus
(
double
coalSurplusPercent
,
void
begin
_sweep_dict_c
ensus
(
double
coalSurplusPercent
,
float
inter_sweep_current
,
float
inter_sweep_current
,
float
inter_sweep_estimate
,
float
inter_sweep_estimate
,
float
intra_sweep_estimate
);
float
intra_sweep_estimate
);
// Methods called after the end of a sweep to modify the
// Methods called after the end of a sweep to modify the
// statistics for the sweep.
// statistics for the sweep.
void
end
SweepDictC
ensus
(
double
splitSurplusPercent
);
void
end
_sweep_dict_c
ensus
(
double
splitSurplusPercent
);
// Return the largest free chunk in the tree.
// Return the largest free chunk in the tree.
Chunk
*
find
LargestD
ict
()
const
;
Chunk
*
find
_largest_d
ict
()
const
;
// Accessors for statistics
// Accessors for statistics
void
set
TreeS
urplus
(
double
splitSurplusPercent
);
void
set
_tree_s
urplus
(
double
splitSurplusPercent
);
void
set
TreeH
ints
(
void
);
void
set
_tree_h
ints
(
void
);
// Reset statistics for all the lists in the tree.
// Reset statistics for all the lists in the tree.
void
clear
TreeC
ensus
(
void
);
void
clear
_tree_c
ensus
(
void
);
// Print the statistcis for all the lists in the tree. Also may
// Print the statistcis for all the lists in the tree. Also may
// print out summaries.
// print out summaries.
void
print
DictC
ensus
(
void
)
const
;
void
print
_dict_c
ensus
(
void
)
const
;
void
print_free_lists
(
outputStream
*
st
)
const
;
void
print_free_lists
(
outputStream
*
st
)
const
;
// For debugging. Returns the sum of the _returned
B
ytes for
// For debugging. Returns the sum of the _returned
_b
ytes for
// all lists in the tree.
// all lists in the tree.
size_t
sum
DictReturnedB
ytes
()
PRODUCT_RETURN0
;
size_t
sum
_dict_returned_b
ytes
()
PRODUCT_RETURN0
;
// Sets the _returned
B
ytes for all the lists in the tree to zero.
// Sets the _returned
_b
ytes for all the lists in the tree to zero.
void
initialize
DictReturnedB
ytes
()
PRODUCT_RETURN
;
void
initialize
_dict_returned_b
ytes
()
PRODUCT_RETURN
;
// For debugging. Return the total number of chunks in the dictionary.
// For debugging. Return the total number of chunks in the dictionary.
size_t
total
C
ount
()
PRODUCT_RETURN0
;
size_t
total
_c
ount
()
PRODUCT_RETURN0
;
void
report
S
tatistics
()
const
;
void
report
_s
tatistics
()
const
;
void
verify
()
const
;
void
verify
()
const
;
};
};
...
...
src/share/vm/memory/freeBlockDictionary.cpp
浏览文件 @
2c61150c
...
@@ -52,8 +52,8 @@ template <class Chunk> void FreeBlockDictionary<Chunk>::set_par_lock(Mutex* lock
...
@@ -52,8 +52,8 @@ template <class Chunk> void FreeBlockDictionary<Chunk>::set_par_lock(Mutex* lock
template
<
class
Chunk
>
void
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
()
const
{
template
<
class
Chunk
>
void
FreeBlockDictionary
<
Chunk
>::
verify_par_locked
()
const
{
#ifdef ASSERT
#ifdef ASSERT
if
(
ParallelGCThreads
>
0
)
{
if
(
ParallelGCThreads
>
0
)
{
Thread
*
my
T
hread
=
Thread
::
current
();
Thread
*
my
_t
hread
=
Thread
::
current
();
if
(
my
T
hread
->
is_GC_task_thread
())
{
if
(
my
_t
hread
->
is_GC_task_thread
())
{
assert
(
par_lock
()
!=
NULL
,
"Should be using locking?"
);
assert
(
par_lock
()
!=
NULL
,
"Should be using locking?"
);
assert_lock_strong
(
par_lock
());
assert_lock_strong
(
par_lock
());
}
}
...
...
src/share/vm/memory/freeBlockDictionary.hpp
浏览文件 @
2c61150c
...
@@ -51,45 +51,45 @@ class FreeBlockDictionary: public CHeapObj {
...
@@ -51,45 +51,45 @@ class FreeBlockDictionary: public CHeapObj {
NOT_PRODUCT
(
Mutex
*
_lock
;)
NOT_PRODUCT
(
Mutex
*
_lock
;)
public:
public:
virtual
void
remove
C
hunk
(
Chunk
*
fc
)
=
0
;
virtual
void
remove
_c
hunk
(
Chunk
*
fc
)
=
0
;
virtual
Chunk
*
get
C
hunk
(
size_t
size
,
Dither
dither
=
atLeast
)
=
0
;
virtual
Chunk
*
get
_c
hunk
(
size_t
size
,
Dither
dither
=
atLeast
)
=
0
;
virtual
void
return
C
hunk
(
Chunk
*
chunk
)
=
0
;
virtual
void
return
_c
hunk
(
Chunk
*
chunk
)
=
0
;
virtual
size_t
total
ChunkS
ize
(
debug_only
(
const
Mutex
*
lock
))
const
=
0
;
virtual
size_t
total
_chunk_s
ize
(
debug_only
(
const
Mutex
*
lock
))
const
=
0
;
virtual
size_t
max
ChunkS
ize
()
const
=
0
;
virtual
size_t
max
_chunk_s
ize
()
const
=
0
;
virtual
size_t
min
S
ize
()
const
=
0
;
virtual
size_t
min
_s
ize
()
const
=
0
;
// Reset the dictionary to the initial conditions for a single
// Reset the dictionary to the initial conditions for a single
// block.
// block.
virtual
void
reset
(
HeapWord
*
addr
,
size_t
size
)
=
0
;
virtual
void
reset
(
HeapWord
*
addr
,
size_t
size
)
=
0
;
virtual
void
reset
()
=
0
;
virtual
void
reset
()
=
0
;
virtual
void
dict
CensusUpd
ate
(
size_t
size
,
bool
split
,
bool
birth
)
=
0
;
virtual
void
dict
_census_udp
ate
(
size_t
size
,
bool
split
,
bool
birth
)
=
0
;
virtual
bool
coal
DictOverP
opulated
(
size_t
size
)
=
0
;
virtual
bool
coal
_dict_over_p
opulated
(
size_t
size
)
=
0
;
virtual
void
begin
SweepDictC
ensus
(
double
coalSurplusPercent
,
virtual
void
begin
_sweep_dict_c
ensus
(
double
coalSurplusPercent
,
float
inter_sweep_current
,
float
inter_sweep_estimate
,
float
inter_sweep_current
,
float
inter_sweep_estimate
,
float
intra__sweep_current
)
=
0
;
float
intra__sweep_current
)
=
0
;
virtual
void
end
SweepDictC
ensus
(
double
splitSurplusPercent
)
=
0
;
virtual
void
end
_sweep_dict_c
ensus
(
double
splitSurplusPercent
)
=
0
;
virtual
Chunk
*
find
LargestD
ict
()
const
=
0
;
virtual
Chunk
*
find
_largest_d
ict
()
const
=
0
;
// verify that the given chunk is in the dictionary.
// verify that the given chunk is in the dictionary.
virtual
bool
verify
ChunkInFreeLists
(
Chunk
*
tc
)
const
=
0
;
virtual
bool
verify
_chunk_in_free_list
(
Chunk
*
tc
)
const
=
0
;
// Sigma_{all_free_blocks} (block_size^2)
// Sigma_{all_free_blocks} (block_size^2)
virtual
double
sum_of_squared_block_sizes
()
const
=
0
;
virtual
double
sum_of_squared_block_sizes
()
const
=
0
;
virtual
Chunk
*
find_chunk_ends_at
(
HeapWord
*
target
)
const
=
0
;
virtual
Chunk
*
find_chunk_ends_at
(
HeapWord
*
target
)
const
=
0
;
virtual
void
inc_total
S
ize
(
size_t
v
)
=
0
;
virtual
void
inc_total
_s
ize
(
size_t
v
)
=
0
;
virtual
void
dec_total
S
ize
(
size_t
v
)
=
0
;
virtual
void
dec_total
_s
ize
(
size_t
v
)
=
0
;
NOT_PRODUCT
(
NOT_PRODUCT
(
virtual
size_t
sum
DictReturnedB
ytes
()
=
0
;
virtual
size_t
sum
_dict_returned_b
ytes
()
=
0
;
virtual
void
initialize
DictReturnedB
ytes
()
=
0
;
virtual
void
initialize
_dict_returned_b
ytes
()
=
0
;
virtual
size_t
total
C
ount
()
=
0
;
virtual
size_t
total
_c
ount
()
=
0
;
)
)
virtual
void
report
S
tatistics
()
const
{
virtual
void
report
_s
tatistics
()
const
{
gclog_or_tty
->
print
(
"No statistics available"
);
gclog_or_tty
->
print
(
"No statistics available"
);
}
}
virtual
void
print
DictC
ensus
()
const
=
0
;
virtual
void
print
_dict_c
ensus
()
const
=
0
;
virtual
void
print_free_lists
(
outputStream
*
st
)
const
=
0
;
virtual
void
print_free_lists
(
outputStream
*
st
)
const
=
0
;
virtual
void
verify
()
const
=
0
;
virtual
void
verify
()
const
=
0
;
...
...
src/share/vm/memory/freeList.cpp
浏览文件 @
2c61150c
...
@@ -65,7 +65,7 @@ FreeList<Chunk>::FreeList(Chunk* fc) :
...
@@ -65,7 +65,7 @@ FreeList<Chunk>::FreeList(Chunk* fc) :
_hint
=
0
;
_hint
=
0
;
init_statistics
();
init_statistics
();
#ifndef PRODUCT
#ifndef PRODUCT
_allocation_stats
.
set_returned
B
ytes
(
size
()
*
HeapWordSize
);
_allocation_stats
.
set_returned
_b
ytes
(
size
()
*
HeapWordSize
);
#endif
#endif
}
}
...
@@ -83,7 +83,7 @@ void FreeList<Chunk>::init_statistics(bool split_birth) {
...
@@ -83,7 +83,7 @@ void FreeList<Chunk>::init_statistics(bool split_birth) {
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
Chunk
*
FreeList
<
Chunk
>::
get
ChunkAtH
ead
()
{
Chunk
*
FreeList
<
Chunk
>::
get
_chunk_at_h
ead
()
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
...
@@ -93,7 +93,7 @@ Chunk* FreeList<Chunk>::getChunkAtHead() {
...
@@ -93,7 +93,7 @@ Chunk* FreeList<Chunk>::getChunkAtHead() {
if
(
nextFC
!=
NULL
)
{
if
(
nextFC
!=
NULL
)
{
// The chunk fc being removed has a "next". Set the "next" to the
// The chunk fc being removed has a "next". Set the "next" to the
// "prev" of fc.
// "prev" of fc.
nextFC
->
link
P
rev
(
NULL
);
nextFC
->
link
_p
rev
(
NULL
);
}
else
{
// removed tail of list
}
else
{
// removed tail of list
link_tail
(
NULL
);
link_tail
(
NULL
);
}
}
...
@@ -126,10 +126,10 @@ void FreeList<Chunk>::getFirstNChunksFromList(size_t n, FreeList<Chunk>* fl) {
...
@@ -126,10 +126,10 @@ void FreeList<Chunk>::getFirstNChunksFromList(size_t n, FreeList<Chunk>* fl) {
if
(
new_head
==
NULL
)
{
if
(
new_head
==
NULL
)
{
set_tail
(
NULL
);
set_tail
(
NULL
);
}
else
{
}
else
{
new_head
->
link
P
rev
(
NULL
);
new_head
->
link
_p
rev
(
NULL
);
}
}
// Now we can fix up the tail.
// Now we can fix up the tail.
tl
->
link
N
ext
(
NULL
);
tl
->
link
_n
ext
(
NULL
);
// And return the result.
// And return the result.
fl
->
set_tail
(
tl
);
fl
->
set_tail
(
tl
);
fl
->
set_count
(
k
);
fl
->
set_count
(
k
);
...
@@ -138,7 +138,7 @@ void FreeList<Chunk>::getFirstNChunksFromList(size_t n, FreeList<Chunk>* fl) {
...
@@ -138,7 +138,7 @@ void FreeList<Chunk>::getFirstNChunksFromList(size_t n, FreeList<Chunk>* fl) {
// Remove this chunk from the list
// Remove this chunk from the list
template
<
class
Chunk
>
template
<
class
Chunk
>
void
FreeList
<
Chunk
>::
remove
C
hunk
(
Chunk
*
fc
)
{
void
FreeList
<
Chunk
>::
remove
_c
hunk
(
Chunk
*
fc
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
assert
(
head
()
!=
NULL
,
"Remove from empty list"
);
assert
(
head
()
!=
NULL
,
"Remove from empty list"
);
assert
(
fc
!=
NULL
,
"Remove a NULL chunk"
);
assert
(
fc
!=
NULL
,
"Remove a NULL chunk"
);
...
@@ -151,7 +151,7 @@ void FreeList<Chunk>::removeChunk(Chunk*fc) {
...
@@ -151,7 +151,7 @@ void FreeList<Chunk>::removeChunk(Chunk*fc) {
if
(
nextFC
!=
NULL
)
{
if
(
nextFC
!=
NULL
)
{
// The chunk fc being removed has a "next". Set the "next" to the
// The chunk fc being removed has a "next". Set the "next" to the
// "prev" of fc.
// "prev" of fc.
nextFC
->
link
P
rev
(
prevFC
);
nextFC
->
link
_p
rev
(
prevFC
);
}
else
{
// removed tail of list
}
else
{
// removed tail of list
link_tail
(
prevFC
);
link_tail
(
prevFC
);
}
}
...
@@ -160,7 +160,7 @@ void FreeList<Chunk>::removeChunk(Chunk*fc) {
...
@@ -160,7 +160,7 @@ void FreeList<Chunk>::removeChunk(Chunk*fc) {
assert
(
nextFC
==
NULL
||
nextFC
->
prev
()
==
NULL
,
assert
(
nextFC
==
NULL
||
nextFC
->
prev
()
==
NULL
,
"Prev of head should be NULL"
);
"Prev of head should be NULL"
);
}
else
{
}
else
{
prevFC
->
link
N
ext
(
nextFC
);
prevFC
->
link
_n
ext
(
nextFC
);
assert
(
tail
()
!=
prevFC
||
prevFC
->
next
()
==
NULL
,
assert
(
tail
()
!=
prevFC
||
prevFC
->
next
()
==
NULL
,
"Next of tail should be NULL"
);
"Next of tail should be NULL"
);
}
}
...
@@ -169,10 +169,10 @@ void FreeList<Chunk>::removeChunk(Chunk*fc) {
...
@@ -169,10 +169,10 @@ void FreeList<Chunk>::removeChunk(Chunk*fc) {
"H/T/C Inconsistency"
);
"H/T/C Inconsistency"
);
// clear next and prev fields of fc, debug only
// clear next and prev fields of fc, debug only
NOT_PRODUCT
(
NOT_PRODUCT
(
fc
->
link
P
rev
(
NULL
);
fc
->
link
_p
rev
(
NULL
);
fc
->
link
N
ext
(
NULL
);
fc
->
link
_n
ext
(
NULL
);
)
)
assert
(
fc
->
is
F
ree
(),
"Should still be a free chunk"
);
assert
(
fc
->
is
_f
ree
(),
"Should still be a free chunk"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
size
()
==
size
(),
"wrong item on list"
);
assert
(
head
()
==
NULL
||
head
()
->
size
()
==
size
(),
"wrong item on list"
);
...
@@ -181,7 +181,7 @@ void FreeList<Chunk>::removeChunk(Chunk*fc) {
...
@@ -181,7 +181,7 @@ void FreeList<Chunk>::removeChunk(Chunk*fc) {
// Add this chunk at the head of the list.
// Add this chunk at the head of the list.
template
<
class
Chunk
>
template
<
class
Chunk
>
void
FreeList
<
Chunk
>::
return
ChunkAtH
ead
(
Chunk
*
chunk
,
bool
record_return
)
{
void
FreeList
<
Chunk
>::
return
_chunk_at_h
ead
(
Chunk
*
chunk
,
bool
record_return
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
assert
(
chunk
!=
NULL
,
"insert a NULL chunk"
);
assert
(
chunk
!=
NULL
,
"insert a NULL chunk"
);
assert
(
size
()
==
chunk
->
size
(),
"Wrong size"
);
assert
(
size
()
==
chunk
->
size
(),
"Wrong size"
);
...
@@ -190,7 +190,7 @@ void FreeList<Chunk>::returnChunkAtHead(Chunk* chunk, bool record_return) {
...
@@ -190,7 +190,7 @@ void FreeList<Chunk>::returnChunkAtHead(Chunk* chunk, bool record_return) {
Chunk
*
oldHead
=
head
();
Chunk
*
oldHead
=
head
();
assert
(
chunk
!=
oldHead
,
"double insertion"
);
assert
(
chunk
!=
oldHead
,
"double insertion"
);
chunk
->
link
A
fter
(
oldHead
);
chunk
->
link
_a
fter
(
oldHead
);
link_head
(
chunk
);
link_head
(
chunk
);
if
(
oldHead
==
NULL
)
{
// only chunk in list
if
(
oldHead
==
NULL
)
{
// only chunk in list
assert
(
tail
()
==
NULL
,
"inconsistent FreeList"
);
assert
(
tail
()
==
NULL
,
"inconsistent FreeList"
);
...
@@ -199,7 +199,7 @@ void FreeList<Chunk>::returnChunkAtHead(Chunk* chunk, bool record_return) {
...
@@ -199,7 +199,7 @@ void FreeList<Chunk>::returnChunkAtHead(Chunk* chunk, bool record_return) {
increment_count
();
// of # of chunks in list
increment_count
();
// of # of chunks in list
DEBUG_ONLY
(
DEBUG_ONLY
(
if
(
record_return
)
{
if
(
record_return
)
{
increment_returned
B
ytes_by
(
size
()
*
HeapWordSize
);
increment_returned
_b
ytes_by
(
size
()
*
HeapWordSize
);
}
}
)
)
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
...
@@ -209,14 +209,14 @@ void FreeList<Chunk>::returnChunkAtHead(Chunk* chunk, bool record_return) {
...
@@ -209,14 +209,14 @@ void FreeList<Chunk>::returnChunkAtHead(Chunk* chunk, bool record_return) {
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
FreeList
<
Chunk
>::
return
ChunkAtH
ead
(
Chunk
*
chunk
)
{
void
FreeList
<
Chunk
>::
return
_chunk_at_h
ead
(
Chunk
*
chunk
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
return
ChunkAtH
ead
(
chunk
,
true
);
return
_chunk_at_h
ead
(
chunk
,
true
);
}
}
// Add this chunk at the tail of the list.
// Add this chunk at the tail of the list.
template
<
class
Chunk
>
template
<
class
Chunk
>
void
FreeList
<
Chunk
>::
return
ChunkAtT
ail
(
Chunk
*
chunk
,
bool
record_return
)
{
void
FreeList
<
Chunk
>::
return
_chunk_at_t
ail
(
Chunk
*
chunk
,
bool
record_return
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
assert
(
tail
()
==
NULL
||
tail
()
->
next
()
==
NULL
,
"list invariant"
);
...
@@ -226,7 +226,7 @@ void FreeList<Chunk>::returnChunkAtTail(Chunk* chunk, bool record_return) {
...
@@ -226,7 +226,7 @@ void FreeList<Chunk>::returnChunkAtTail(Chunk* chunk, bool record_return) {
Chunk
*
oldTail
=
tail
();
Chunk
*
oldTail
=
tail
();
assert
(
chunk
!=
oldTail
,
"double insertion"
);
assert
(
chunk
!=
oldTail
,
"double insertion"
);
if
(
oldTail
!=
NULL
)
{
if
(
oldTail
!=
NULL
)
{
oldTail
->
link
A
fter
(
chunk
);
oldTail
->
link
_a
fter
(
chunk
);
}
else
{
// only chunk in list
}
else
{
// only chunk in list
assert
(
head
()
==
NULL
,
"inconsistent FreeList"
);
assert
(
head
()
==
NULL
,
"inconsistent FreeList"
);
link_head
(
chunk
);
link_head
(
chunk
);
...
@@ -235,7 +235,7 @@ void FreeList<Chunk>::returnChunkAtTail(Chunk* chunk, bool record_return) {
...
@@ -235,7 +235,7 @@ void FreeList<Chunk>::returnChunkAtTail(Chunk* chunk, bool record_return) {
increment_count
();
// of # of chunks in list
increment_count
();
// of # of chunks in list
DEBUG_ONLY
(
DEBUG_ONLY
(
if
(
record_return
)
{
if
(
record_return
)
{
increment_returned
B
ytes_by
(
size
()
*
HeapWordSize
);
increment_returned
_b
ytes_by
(
size
()
*
HeapWordSize
);
}
}
)
)
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
assert
(
head
()
==
NULL
||
head
()
->
prev
()
==
NULL
,
"list invariant"
);
...
@@ -245,8 +245,8 @@ void FreeList<Chunk>::returnChunkAtTail(Chunk* chunk, bool record_return) {
...
@@ -245,8 +245,8 @@ void FreeList<Chunk>::returnChunkAtTail(Chunk* chunk, bool record_return) {
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
void
FreeList
<
Chunk
>::
return
ChunkAtT
ail
(
Chunk
*
chunk
)
{
void
FreeList
<
Chunk
>::
return
_chunk_at_t
ail
(
Chunk
*
chunk
)
{
return
ChunkAtT
ail
(
chunk
,
true
);
return
_chunk_at_t
ail
(
chunk
,
true
);
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
...
@@ -262,8 +262,8 @@ void FreeList<Chunk>::prepend(FreeList<Chunk>* fl) {
...
@@ -262,8 +262,8 @@ void FreeList<Chunk>::prepend(FreeList<Chunk>* fl) {
Chunk
*
fl_tail
=
fl
->
tail
();
Chunk
*
fl_tail
=
fl
->
tail
();
Chunk
*
this_head
=
head
();
Chunk
*
this_head
=
head
();
assert
(
fl_tail
->
next
()
==
NULL
,
"Well-formedness of fl"
);
assert
(
fl_tail
->
next
()
==
NULL
,
"Well-formedness of fl"
);
fl_tail
->
link
N
ext
(
this_head
);
fl_tail
->
link
_n
ext
(
this_head
);
this_head
->
link
P
rev
(
fl_tail
);
this_head
->
link
_p
rev
(
fl_tail
);
set_head
(
fl
->
head
());
set_head
(
fl
->
head
());
set_count
(
count
()
+
fl
->
count
());
set_count
(
count
()
+
fl
->
count
());
}
}
...
@@ -273,10 +273,10 @@ void FreeList<Chunk>::prepend(FreeList<Chunk>* fl) {
...
@@ -273,10 +273,10 @@ void FreeList<Chunk>::prepend(FreeList<Chunk>* fl) {
}
}
}
}
// verify
ChunkInFreeLists
() is used to verify that an item is in this free list.
// verify
_chunk_in_free_list
() is used to verify that an item is in this free list.
// It is used as a debugging aid.
// It is used as a debugging aid.
template
<
class
Chunk
>
template
<
class
Chunk
>
bool
FreeList
<
Chunk
>::
verify
ChunkInFreeLists
(
Chunk
*
fc
)
const
{
bool
FreeList
<
Chunk
>::
verify
_chunk_in_free_list
(
Chunk
*
fc
)
const
{
// This is an internal consistency check, not part of the check that the
// This is an internal consistency check, not part of the check that the
// chunk is in the free lists.
// chunk is in the free lists.
guarantee
(
fc
->
size
()
==
size
(),
"Wrong list is being searched"
);
guarantee
(
fc
->
size
()
==
size
(),
"Wrong list is being searched"
);
...
@@ -302,21 +302,21 @@ void FreeList<Chunk>::verify_stats() const {
...
@@ -302,21 +302,21 @@ void FreeList<Chunk>::verify_stats() const {
// dictionary for example, this might be the first block and
// dictionary for example, this might be the first block and
// in that case there would be no place that we could record
// in that case there would be no place that we could record
// the stats (which are kept in the block itself).
// the stats (which are kept in the block itself).
assert
((
_allocation_stats
.
prev
Sweep
()
+
_allocation_stats
.
splitB
irths
()
assert
((
_allocation_stats
.
prev
_sweep
()
+
_allocation_stats
.
split_b
irths
()
+
_allocation_stats
.
coal
B
irths
()
+
1
)
// Total Production Stock + 1
+
_allocation_stats
.
coal
_b
irths
()
+
1
)
// Total Production Stock + 1
>=
(
_allocation_stats
.
split
Deaths
()
+
_allocation_stats
.
coalD
eaths
()
>=
(
_allocation_stats
.
split
_deaths
()
+
_allocation_stats
.
coal_d
eaths
()
+
(
ssize_t
)
count
()),
// Total Current Stock + depletion
+
(
ssize_t
)
count
()),
// Total Current Stock + depletion
err_msg
(
"FreeList "
PTR_FORMAT
" of size "
SIZE_FORMAT
err_msg
(
"FreeList "
PTR_FORMAT
" of size "
SIZE_FORMAT
" violates Conservation Principle: "
" violates Conservation Principle: "
"prev
S
weep("
SIZE_FORMAT
")"
"prev
_s
weep("
SIZE_FORMAT
")"
" + split
B
irths("
SIZE_FORMAT
")"
" + split
_b
irths("
SIZE_FORMAT
")"
" + coal
B
irths("
SIZE_FORMAT
") + 1 >= "
" + coal
_b
irths("
SIZE_FORMAT
") + 1 >= "
" split
D
eaths("
SIZE_FORMAT
")"
" split
_d
eaths("
SIZE_FORMAT
")"
" coal
D
eaths("
SIZE_FORMAT
")"
" coal
_d
eaths("
SIZE_FORMAT
")"
" + count("
SSIZE_FORMAT
")"
,
" + count("
SSIZE_FORMAT
")"
,
this
,
_size
,
_allocation_stats
.
prev
Sweep
(),
_allocation_stats
.
splitB
irths
(),
this
,
_size
,
_allocation_stats
.
prev
_sweep
(),
_allocation_stats
.
split_b
irths
(),
_allocation_stats
.
split
Births
(),
_allocation_stats
.
splitD
eaths
(),
_allocation_stats
.
split
_births
(),
_allocation_stats
.
split_d
eaths
(),
_allocation_stats
.
coal
D
eaths
(),
count
()));
_allocation_stats
.
coal
_d
eaths
(),
count
()));
}
}
template
<
class
Chunk
>
template
<
class
Chunk
>
...
@@ -360,8 +360,8 @@ void FreeList<Chunk>::print_on(outputStream* st, const char* c) const {
...
@@ -360,8 +360,8 @@ void FreeList<Chunk>::print_on(outputStream* st, const char* c) const {
st
->
print
(
"
\t
"
st
->
print
(
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\n
"
,
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\t
"
SSIZE_FORMAT_W
(
14
)
"
\n
"
,
bfr
Surp
(),
surplus
(),
desired
(),
prevSweep
(),
beforeS
weep
(),
bfr
_surp
(),
surplus
(),
desired
(),
prev_sweep
(),
before_s
weep
(),
count
(),
coal
Births
(),
coalDeaths
(),
splitBirths
(),
splitD
eaths
());
count
(),
coal
_births
(),
coal_deaths
(),
split_births
(),
split_d
eaths
());
}
}
#ifndef SERIALGC
#ifndef SERIALGC
...
...
src/share/vm/memory/freeList.hpp
浏览文件 @
2c61150c
...
@@ -119,7 +119,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
...
@@ -119,7 +119,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
// If this method is not used (just set the head instead),
// If this method is not used (just set the head instead),
// this check can be avoided.
// this check can be avoided.
if
(
v
!=
NULL
)
{
if
(
v
!=
NULL
)
{
v
->
link
P
rev
(
NULL
);
v
->
link
_p
rev
(
NULL
);
}
}
}
}
...
@@ -138,7 +138,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
...
@@ -138,7 +138,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
assert_proper_lock_protection
();
assert_proper_lock_protection
();
set_tail
(
v
);
set_tail
(
v
);
if
(
v
!=
NULL
)
{
if
(
v
!=
NULL
)
{
v
->
clear
N
ext
();
v
->
clear
_n
ext
();
}
}
}
}
...
@@ -185,12 +185,12 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
...
@@ -185,12 +185,12 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
inter_sweep_estimate
,
inter_sweep_estimate
,
intra_sweep_estimate
);
intra_sweep_estimate
);
}
}
ssize_t
coal
D
esired
()
const
{
ssize_t
coal
_d
esired
()
const
{
return
_allocation_stats
.
coal
D
esired
();
return
_allocation_stats
.
coal
_d
esired
();
}
}
void
set_coal
D
esired
(
ssize_t
v
)
{
void
set_coal
_d
esired
(
ssize_t
v
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
set_coal
D
esired
(
v
);
_allocation_stats
.
set_coal
_d
esired
(
v
);
}
}
ssize_t
surplus
()
const
{
ssize_t
surplus
()
const
{
...
@@ -209,106 +209,106 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
...
@@ -209,106 +209,106 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
_allocation_stats
.
decrement_surplus
();
_allocation_stats
.
decrement_surplus
();
}
}
ssize_t
bfr
S
urp
()
const
{
ssize_t
bfr
_s
urp
()
const
{
return
_allocation_stats
.
bfr
S
urp
();
return
_allocation_stats
.
bfr
_s
urp
();
}
}
void
set_bfr
S
urp
(
ssize_t
v
)
{
void
set_bfr
_s
urp
(
ssize_t
v
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
set_bfr
S
urp
(
v
);
_allocation_stats
.
set_bfr
_s
urp
(
v
);
}
}
ssize_t
prev
S
weep
()
const
{
ssize_t
prev
_s
weep
()
const
{
return
_allocation_stats
.
prev
S
weep
();
return
_allocation_stats
.
prev
_s
weep
();
}
}
void
set_prev
S
weep
(
ssize_t
v
)
{
void
set_prev
_s
weep
(
ssize_t
v
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
set_prev
S
weep
(
v
);
_allocation_stats
.
set_prev
_s
weep
(
v
);
}
}
ssize_t
before
S
weep
()
const
{
ssize_t
before
_s
weep
()
const
{
return
_allocation_stats
.
before
S
weep
();
return
_allocation_stats
.
before
_s
weep
();
}
}
void
set_before
S
weep
(
ssize_t
v
)
{
void
set_before
_s
weep
(
ssize_t
v
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
set_before
S
weep
(
v
);
_allocation_stats
.
set_before
_s
weep
(
v
);
}
}
ssize_t
coal
B
irths
()
const
{
ssize_t
coal
_b
irths
()
const
{
return
_allocation_stats
.
coal
B
irths
();
return
_allocation_stats
.
coal
_b
irths
();
}
}
void
set_coal
B
irths
(
ssize_t
v
)
{
void
set_coal
_b
irths
(
ssize_t
v
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
set_coal
B
irths
(
v
);
_allocation_stats
.
set_coal
_b
irths
(
v
);
}
}
void
increment_coal
B
irths
()
{
void
increment_coal
_b
irths
()
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
increment_coal
B
irths
();
_allocation_stats
.
increment_coal
_b
irths
();
}
}
ssize_t
coal
D
eaths
()
const
{
ssize_t
coal
_d
eaths
()
const
{
return
_allocation_stats
.
coal
D
eaths
();
return
_allocation_stats
.
coal
_d
eaths
();
}
}
void
set_coal
D
eaths
(
ssize_t
v
)
{
void
set_coal
_d
eaths
(
ssize_t
v
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
set_coal
D
eaths
(
v
);
_allocation_stats
.
set_coal
_d
eaths
(
v
);
}
}
void
increment_coal
D
eaths
()
{
void
increment_coal
_d
eaths
()
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
increment_coal
D
eaths
();
_allocation_stats
.
increment_coal
_d
eaths
();
}
}
ssize_t
split
B
irths
()
const
{
ssize_t
split
_b
irths
()
const
{
return
_allocation_stats
.
split
B
irths
();
return
_allocation_stats
.
split
_b
irths
();
}
}
void
set_split
B
irths
(
ssize_t
v
)
{
void
set_split
_b
irths
(
ssize_t
v
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
set_split
B
irths
(
v
);
_allocation_stats
.
set_split
_b
irths
(
v
);
}
}
void
increment_split
B
irths
()
{
void
increment_split
_b
irths
()
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
increment_split
B
irths
();
_allocation_stats
.
increment_split
_b
irths
();
}
}
ssize_t
split
D
eaths
()
const
{
ssize_t
split
_d
eaths
()
const
{
return
_allocation_stats
.
split
D
eaths
();
return
_allocation_stats
.
split
_d
eaths
();
}
}
void
set_split
D
eaths
(
ssize_t
v
)
{
void
set_split
_d
eaths
(
ssize_t
v
)
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
set_split
D
eaths
(
v
);
_allocation_stats
.
set_split
_d
eaths
(
v
);
}
}
void
increment_split
D
eaths
()
{
void
increment_split
_d
eaths
()
{
assert_proper_lock_protection
();
assert_proper_lock_protection
();
_allocation_stats
.
increment_split
D
eaths
();
_allocation_stats
.
increment_split
_d
eaths
();
}
}
NOT_PRODUCT
(
NOT_PRODUCT
(
// For debugging. The "_returned
B
ytes" in all the lists are summed
// For debugging. The "_returned
_b
ytes" in all the lists are summed
// and compared with the total number of bytes swept during a
// and compared with the total number of bytes swept during a
// collection.
// collection.
size_t
returned
Bytes
()
const
{
return
_allocation_stats
.
returnedB
ytes
();
}
size_t
returned
_bytes
()
const
{
return
_allocation_stats
.
returned_b
ytes
();
}
void
set_returned
Bytes
(
size_t
v
)
{
_allocation_stats
.
set_returnedB
ytes
(
v
);
}
void
set_returned
_bytes
(
size_t
v
)
{
_allocation_stats
.
set_returned_b
ytes
(
v
);
}
void
increment_returned
B
ytes_by
(
size_t
v
)
{
void
increment_returned
_b
ytes_by
(
size_t
v
)
{
_allocation_stats
.
set_returned
Bytes
(
_allocation_stats
.
returnedB
ytes
()
+
v
);
_allocation_stats
.
set_returned
_bytes
(
_allocation_stats
.
returned_b
ytes
()
+
v
);
}
}
)
)
// Unlink head of list and return it. Returns NULL if
// Unlink head of list and return it. Returns NULL if
// the list is empty.
// the list is empty.
Chunk
*
get
ChunkAtH
ead
();
Chunk
*
get
_chunk_at_h
ead
();
// Remove the first "n" or "count", whichever is smaller, chunks from the
// Remove the first "n" or "count", whichever is smaller, chunks from the
// list, setting "fl", which is required to be empty, to point to them.
// list, setting "fl", which is required to be empty, to point to them.
void
getFirstNChunksFromList
(
size_t
n
,
FreeList
<
Chunk
>*
fl
);
void
getFirstNChunksFromList
(
size_t
n
,
FreeList
<
Chunk
>*
fl
);
// Unlink this chunk from it's free list
// Unlink this chunk from it's free list
void
remove
C
hunk
(
Chunk
*
fc
);
void
remove
_c
hunk
(
Chunk
*
fc
);
// Add this chunk to this free list.
// Add this chunk to this free list.
void
return
ChunkAtH
ead
(
Chunk
*
fc
);
void
return
_chunk_at_h
ead
(
Chunk
*
fc
);
void
return
ChunkAtT
ail
(
Chunk
*
fc
);
void
return
_chunk_at_t
ail
(
Chunk
*
fc
);
// Similar to returnChunk* but also records some diagnostic
// Similar to returnChunk* but also records some diagnostic
// information.
// information.
void
return
ChunkAtH
ead
(
Chunk
*
fc
,
bool
record_return
);
void
return
_chunk_at_h
ead
(
Chunk
*
fc
,
bool
record_return
);
void
return
ChunkAtT
ail
(
Chunk
*
fc
,
bool
record_return
);
void
return
_chunk_at_t
ail
(
Chunk
*
fc
,
bool
record_return
);
// Prepend "fl" (whose size is required to be the same as that of "this")
// Prepend "fl" (whose size is required to be the same as that of "this")
// to the front of "this" list.
// to the front of "this" list.
...
@@ -316,7 +316,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
...
@@ -316,7 +316,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
// Verify that the chunk is in the list.
// Verify that the chunk is in the list.
// found. Return NULL if "fc" is not found.
// found. Return NULL if "fc" is not found.
bool
verify
ChunkInFreeLists
(
Chunk
*
fc
)
const
;
bool
verify
_chunk_in_free_list
(
Chunk
*
fc
)
const
;
// Stats verification
// Stats verification
void
verify_stats
()
const
PRODUCT_RETURN
;
void
verify_stats
()
const
PRODUCT_RETURN
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录