Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
de548700
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
de548700
编写于
3月 04, 2016
作者:
I
igerasim
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8149330: Capacity of StringBuilder should not get close to Integer.MAX_VALUE unless necessary
Reviewed-by: martin
上级
63bedc40
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
292 addition
and
19 deletion
+292
-19
src/share/classes/java/lang/AbstractStringBuilder.java
src/share/classes/java/lang/AbstractStringBuilder.java
+43
-16
src/share/classes/java/lang/StringBuffer.java
src/share/classes/java/lang/StringBuffer.java
+1
-3
test/java/lang/StringBuilder/Capacity.java
test/java/lang/StringBuilder/Capacity.java
+182
-0
test/java/lang/StringBuilder/HugeCapacity.java
test/java/lang/StringBuilder/HugeCapacity.java
+66
-0
未找到文件。
src/share/classes/java/lang/AbstractStringBuilder.java
浏览文件 @
de548700
/*
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -112,29 +112,56 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
}
/**
* This method has the same contract as ensureCapacity, but is
* never synchronized.
* For positive values of {@code minimumCapacity}, this method
* behaves like {@code ensureCapacity}, however it is never
* synchronized.
* If {@code minimumCapacity} is non positive due to numeric
* overflow, this method throws {@code OutOfMemoryError}.
*/
private
void
ensureCapacityInternal
(
int
minimumCapacity
)
{
// overflow-conscious code
if
(
minimumCapacity
-
value
.
length
>
0
)
expandCapacity
(
minimumCapacity
);
if
(
minimumCapacity
-
value
.
length
>
0
)
{
value
=
Arrays
.
copyOf
(
value
,
newCapacity
(
minimumCapacity
));
}
}
/**
* This implements the expansion semantics of ensureCapacity with no
* size check or synchronization.
* The maximum size of array to allocate (unless necessary).
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private
static
final
int
MAX_ARRAY_SIZE
=
Integer
.
MAX_VALUE
-
8
;
/**
* Returns a capacity at least as large as the given minimum capacity.
* Returns the current capacity increased by the same amount + 2 if
* that suffices.
* Will not return a capacity greater than {@code MAX_ARRAY_SIZE}
* unless the given minimum capacity is greater than that.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero or
* greater than Integer.MAX_VALUE
*/
void
expandCapacity
(
int
minimumCapacity
)
{
int
newCapacity
=
value
.
length
*
2
+
2
;
if
(
newCapacity
-
minimumCapacity
<
0
)
newCapacity
=
minimumCapacity
;
if
(
newCapacity
<
0
)
{
if
(
minimumCapacity
<
0
)
// overflow
throw
new
OutOfMemoryError
();
newCapacity
=
Integer
.
MAX_VALUE
;
private
int
newCapacity
(
int
minCapacity
)
{
// overflow-conscious code
int
newCapacity
=
(
value
.
length
<<
1
)
+
2
;
if
(
newCapacity
-
minCapacity
<
0
)
{
newCapacity
=
minCapacity
;
}
return
(
newCapacity
<=
0
||
MAX_ARRAY_SIZE
-
newCapacity
<
0
)
?
hugeCapacity
(
minCapacity
)
:
newCapacity
;
}
private
int
hugeCapacity
(
int
minCapacity
)
{
if
(
Integer
.
MAX_VALUE
-
minCapacity
<
0
)
{
// overflow
throw
new
OutOfMemoryError
();
}
value
=
Arrays
.
copyOf
(
value
,
newCapacity
);
return
(
minCapacity
>
MAX_ARRAY_SIZE
)
?
minCapacity
:
MAX_ARRAY_SIZE
;
}
/**
...
...
src/share/classes/java/lang/StringBuffer.java
浏览文件 @
de548700
...
...
@@ -171,9 +171,7 @@ import java.util.Arrays;
@Override
public
synchronized
void
ensureCapacity
(
int
minimumCapacity
)
{
if
(
minimumCapacity
>
value
.
length
)
{
expandCapacity
(
minimumCapacity
);
}
super
.
ensureCapacity
(
minimumCapacity
);
}
/**
...
...
test/java/lang/StringBuilder/Capacity.java
0 → 100644
浏览文件 @
de548700
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8149330
* @summary Basic set of tests of capacity management
* @run testng Capacity
*/
import
java.lang.reflect.Field
;
import
java.util.AbstractList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.SplittableRandom
;
import
org.testng.annotations.Test
;
import
org.testng.annotations.DataProvider
;
import
static
org
.
testng
.
Assert
.*;
public
class
Capacity
{
static
final
int
DEFAULT_CAPACITY
=
16
;
private
static
int
newCapacity
(
int
oldCapacity
,
int
desiredCapacity
)
{
return
Math
.
max
(
oldCapacity
*
2
+
2
,
desiredCapacity
);
}
private
static
int
nextNewCapacity
(
int
oldCapacity
)
{
return
newCapacity
(
oldCapacity
,
oldCapacity
+
1
);
}
@Test
(
dataProvider
=
"singleChar"
)
public
void
defaultCapacity
(
Character
ch
)
{
StringBuilder
sb
=
new
StringBuilder
();
assertEquals
(
sb
.
capacity
(),
DEFAULT_CAPACITY
);
for
(
int
i
=
0
;
i
<
DEFAULT_CAPACITY
;
i
++)
{
sb
.
append
(
ch
);
assertEquals
(
sb
.
capacity
(),
DEFAULT_CAPACITY
);
}
sb
.
append
(
ch
);
assertEquals
(
sb
.
capacity
(),
nextNewCapacity
(
DEFAULT_CAPACITY
));
}
@Test
(
dataProvider
=
"charCapacity"
)
public
void
explicitCapacity
(
Character
ch
,
int
initCapacity
)
{
StringBuilder
sb
=
new
StringBuilder
(
initCapacity
);
assertEquals
(
sb
.
capacity
(),
initCapacity
);
for
(
int
i
=
0
;
i
<
initCapacity
;
i
++)
{
sb
.
append
(
ch
);
assertEquals
(
sb
.
capacity
(),
initCapacity
);
}
sb
.
append
(
ch
);
assertEquals
(
sb
.
capacity
(),
nextNewCapacity
(
initCapacity
));
}
@Test
(
dataProvider
=
"singleChar"
)
public
void
sbFromString
(
Character
ch
)
{
String
s
=
"string "
+
ch
;
int
expectedCapacity
=
s
.
length
()
+
DEFAULT_CAPACITY
;
StringBuilder
sb
=
new
StringBuilder
(
s
);
assertEquals
(
sb
.
capacity
(),
expectedCapacity
);
for
(
int
i
=
0
;
i
<
DEFAULT_CAPACITY
;
i
++)
{
sb
.
append
(
ch
);
assertEquals
(
sb
.
capacity
(),
expectedCapacity
);
}
sb
.
append
(
ch
);
assertEquals
(
sb
.
capacity
(),
nextNewCapacity
(
expectedCapacity
));
}
@Test
(
dataProvider
=
"singleChar"
)
public
void
sbFromCharSeq
(
Character
ch
)
{
CharSequence
cs
=
new
MyCharSeq
(
"char seq "
+
ch
);
int
expectedCapacity
=
cs
.
length
()
+
DEFAULT_CAPACITY
;
StringBuilder
sb
=
new
StringBuilder
(
cs
);
assertEquals
(
sb
.
capacity
(),
expectedCapacity
);
for
(
int
i
=
0
;
i
<
DEFAULT_CAPACITY
;
i
++)
{
sb
.
append
(
ch
);
assertEquals
(
sb
.
capacity
(),
expectedCapacity
);
}
sb
.
append
(
ch
);
assertEquals
(
sb
.
capacity
(),
nextNewCapacity
(
expectedCapacity
));
}
@Test
(
dataProvider
=
"charCapacity"
)
public
void
ensureCapacity
(
Character
ch
,
int
cap
)
{
StringBuilder
sb
=
new
StringBuilder
(
0
);
assertEquals
(
sb
.
capacity
(),
0
);
sb
.
ensureCapacity
(
cap
);
// only has effect if cap > 0
int
newCap
=
(
cap
==
0
)
?
0
:
newCapacity
(
0
,
cap
);
assertEquals
(
sb
.
capacity
(),
newCap
);
sb
.
ensureCapacity
(
newCap
+
1
);
assertEquals
(
sb
.
capacity
(),
nextNewCapacity
(
newCap
));
sb
.
append
(
ch
);
assertEquals
(
sb
.
capacity
(),
nextNewCapacity
(
newCap
));
}
@Test
(
dataProvider
=
"negativeCapacity"
,
expectedExceptions
=
NegativeArraySizeException
.
class
)
public
void
negativeInitialCapacity
(
int
negCap
)
{
StringBuilder
sb
=
new
StringBuilder
(
negCap
);
}
@Test
(
dataProvider
=
"negativeCapacity"
)
public
void
ensureNegativeCapacity
(
int
negCap
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
ensureCapacity
(
negCap
);
assertEquals
(
sb
.
capacity
(),
DEFAULT_CAPACITY
);
}
@Test
(
dataProvider
=
"charCapacity"
)
public
void
trimToSize
(
Character
ch
,
int
cap
)
{
StringBuilder
sb
=
new
StringBuilder
(
cap
);
int
halfOfCap
=
cap
/
2
;
for
(
int
i
=
0
;
i
<
halfOfCap
;
i
++)
{
sb
.
append
(
ch
);
}
sb
.
trimToSize
();
// according to the spec, capacity doesn't have to
// become exactly the size
assertTrue
(
sb
.
capacity
()
>=
halfOfCap
);
}
@DataProvider
public
Object
[][]
singleChar
()
{
return
new
Object
[][]
{
{
'J'
},
{
'\u042b'
}
};
}
@DataProvider
public
Object
[][]
charCapacity
()
{
return
new
Object
[][]
{
{
'J'
,
0
},
{
'J'
,
1
},
{
'J'
,
15
},
{
'J'
,
DEFAULT_CAPACITY
},
{
'J'
,
1024
},
{
'\u042b'
,
0
},
{
'\u042b'
,
1
},
{
'\u042b'
,
15
},
{
'\u042b'
,
DEFAULT_CAPACITY
},
{
'\u042b'
,
1024
},
};
}
@DataProvider
public
Object
[][]
negativeCapacity
()
{
return
new
Object
[][]
{
{-
1
},
{
Integer
.
MIN_VALUE
}
};
}
private
static
class
MyCharSeq
implements
CharSequence
{
private
CharSequence
s
;
public
MyCharSeq
(
CharSequence
s
)
{
this
.
s
=
s
;
}
public
char
charAt
(
int
i
)
{
return
s
.
charAt
(
i
);
}
public
int
length
()
{
return
s
.
length
();
}
public
CharSequence
subSequence
(
int
st
,
int
e
)
{
return
s
.
subSequence
(
st
,
e
);
}
public
String
toString
()
{
return
s
.
toString
();
}
}
}
test/java/lang/StringBuilder/HugeCapacity.java
0 → 100644
浏览文件 @
de548700
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8149330
* @summary Capacity should not get close to Integer.MAX_VALUE unless
* necessary
* @run main/othervm -Xmx10G HugeCapacity
* @ignore This test has huge memory requirements
*/
public
class
HugeCapacity
{
private
static
int
failures
=
0
;
public
static
void
main
(
String
[]
args
)
{
testLatin1
();
testUtf16
();
if
(
failures
>
0
)
{
throw
new
RuntimeException
(
failures
+
" tests failed"
);
}
}
private
static
void
testLatin1
()
{
try
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
ensureCapacity
(
Integer
.
MAX_VALUE
/
2
);
sb
.
ensureCapacity
(
Integer
.
MAX_VALUE
/
2
+
1
);
}
catch
(
OutOfMemoryError
oom
)
{
oom
.
printStackTrace
();
failures
++;
}
}
private
static
void
testUtf16
()
{
try
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
'\u042b'
);
sb
.
ensureCapacity
(
Integer
.
MAX_VALUE
/
4
);
sb
.
ensureCapacity
(
Integer
.
MAX_VALUE
/
4
+
1
);
}
catch
(
OutOfMemoryError
oom
)
{
oom
.
printStackTrace
();
failures
++;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录