Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
544b659e
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
544b659e
编写于
9月 30, 2015
作者:
A
attila
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8137333: Boundless soft caching of property map histories causes high memory pressure
Reviewed-by: hannesw, sundar
上级
7736f263
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
41 addition
and
21 deletion
+41
-21
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
...are/classes/jdk/nashorn/internal/runtime/PropertyMap.java
+41
-21
未找到文件。
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
浏览文件 @
544b659e
...
...
@@ -34,7 +34,9 @@ import java.io.ObjectInputStream;
import
java.io.ObjectOutputStream
;
import
java.io.Serializable
;
import
java.lang.invoke.SwitchPoint
;
import
java.lang.ref.Reference
;
import
java.lang.ref.SoftReference
;
import
java.lang.ref.WeakReference
;
import
java.util.Arrays
;
import
java.util.BitSet
;
import
java.util.Collection
;
...
...
@@ -43,6 +45,7 @@ import java.util.Iterator;
import
java.util.NoSuchElementException
;
import
java.util.WeakHashMap
;
import
java.util.concurrent.atomic.LongAdder
;
import
jdk.nashorn.internal.runtime.options.Options
;
import
jdk.nashorn.internal.scripts.JO
;
/**
...
...
@@ -55,6 +58,9 @@ import jdk.nashorn.internal.scripts.JO;
* will return a new map.
*/
public
class
PropertyMap
implements
Iterable
<
Object
>,
Serializable
{
private
static
final
int
INITIAL_SOFT_REFERENCE_DERIVATION_LIMIT
=
Math
.
max
(
0
,
Options
.
getIntProperty
(
"nashorn.propertyMap.softReferenceDerivationLimit"
,
32
));
/** Used for non extensible PropertyMaps, negative logic as the normal case is extensible. See {@link ScriptObject#preventExtensions()} */
private
static
final
int
NOT_EXTENSIBLE
=
0b0000_0001
;
/** Does this map contain valid array keys? */
...
...
@@ -78,6 +84,13 @@ public class PropertyMap implements Iterable<Object>, Serializable {
/** Structure class name */
private
final
String
className
;
/**
* Countdown of number of times this property map has been derived from another property map. When it
* reaches zero, the property map will start using weak references instead of soft references to hold on
* to its history elements.
*/
private
final
int
softReferenceDerivationLimit
;
/** A reference to the expected shared prototype property map. If this is set this
* property map should only be used if it the same as the actual prototype map. */
private
transient
SharedPropertyMap
sharedProtoMap
;
...
...
@@ -86,7 +99,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
private
transient
HashMap
<
String
,
SwitchPoint
>
protoSwitches
;
/** History of maps, used to limit map duplication. */
private
transient
WeakHashMap
<
Property
,
Soft
Reference
<
PropertyMap
>>
history
;
private
transient
WeakHashMap
<
Property
,
Reference
<
PropertyMap
>>
history
;
/** History of prototypes, used to limit map duplication. */
private
transient
WeakHashMap
<
ScriptObject
,
SoftReference
<
PropertyMap
>>
protoHistory
;
...
...
@@ -114,6 +127,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
this
.
fieldMaximum
=
fieldMaximum
;
this
.
spillLength
=
spillLength
;
this
.
flags
=
flags
;
this
.
softReferenceDerivationLimit
=
INITIAL_SOFT_REFERENCE_DERIVATION_LIMIT
;
if
(
Context
.
DEBUG
)
{
count
.
increment
();
...
...
@@ -126,7 +140,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
* @param propertyMap Existing property map.
* @param properties A {@link PropertyHashMap} with a new set of properties.
*/
private
PropertyMap
(
final
PropertyMap
propertyMap
,
final
PropertyHashMap
properties
,
final
int
flags
,
final
int
fieldCount
,
final
int
spillLength
)
{
private
PropertyMap
(
final
PropertyMap
propertyMap
,
final
PropertyHashMap
properties
,
final
int
flags
,
final
int
fieldCount
,
final
int
spillLength
,
final
int
softReferenceDerivationLimit
)
{
this
.
properties
=
properties
;
this
.
flags
=
flags
;
this
.
spillLength
=
spillLength
;
...
...
@@ -137,6 +151,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
this
.
listeners
=
propertyMap
.
listeners
;
this
.
freeSlots
=
propertyMap
.
freeSlots
;
this
.
sharedProtoMap
=
propertyMap
.
sharedProtoMap
;
this
.
softReferenceDerivationLimit
=
softReferenceDerivationLimit
;
if
(
Context
.
DEBUG
)
{
count
.
increment
();
...
...
@@ -150,7 +165,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
* @param propertyMap Existing property map.
*/
protected
PropertyMap
(
final
PropertyMap
propertyMap
)
{
this
(
propertyMap
,
propertyMap
.
properties
,
propertyMap
.
flags
,
propertyMap
.
fieldCount
,
propertyMap
.
spillLength
);
this
(
propertyMap
,
propertyMap
.
properties
,
propertyMap
.
flags
,
propertyMap
.
fieldCount
,
propertyMap
.
spillLength
,
propertyMap
.
softReferenceDerivationLimit
);
}
private
void
writeObject
(
final
ObjectOutputStream
out
)
throws
IOException
{
...
...
@@ -438,11 +453,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
*/
public
final
PropertyMap
addPropertyNoHistory
(
final
Property
property
)
{
propertyAdded
(
property
,
true
);
final
PropertyHashMap
newProperties
=
properties
.
immutableAdd
(
property
);
final
PropertyMap
newMap
=
new
PropertyMap
(
this
,
newProperties
,
newFlags
(
property
),
newFieldCount
(
property
),
newSpillLength
(
property
));
newMap
.
updateFreeSlots
(
null
,
property
);
return
newMap
;
return
addPropertyInternal
(
property
);
}
/**
...
...
@@ -457,15 +468,24 @@ public class PropertyMap implements Iterable<Object>, Serializable {
PropertyMap
newMap
=
checkHistory
(
property
);
if
(
newMap
==
null
)
{
final
PropertyHashMap
newProperties
=
properties
.
immutableAdd
(
property
);
newMap
=
new
PropertyMap
(
this
,
newProperties
,
newFlags
(
property
),
newFieldCount
(
property
),
newSpillLength
(
property
));
newMap
.
updateFreeSlots
(
null
,
property
);
newMap
=
addPropertyInternal
(
property
);
addToHistory
(
property
,
newMap
);
}
return
newMap
;
}
private
PropertyMap
deriveMap
(
final
PropertyHashMap
newProperties
,
final
int
newFlags
,
final
int
newFieldCount
,
final
int
newSpillLength
)
{
return
new
PropertyMap
(
this
,
newProperties
,
newFlags
,
newFieldCount
,
newSpillLength
,
softReferenceDerivationLimit
==
0
?
0
:
softReferenceDerivationLimit
-
1
);
}
private
PropertyMap
addPropertyInternal
(
final
Property
property
)
{
final
PropertyHashMap
newProperties
=
properties
.
immutableAdd
(
property
);
final
PropertyMap
newMap
=
deriveMap
(
newProperties
,
newFlags
(
property
),
newFieldCount
(
property
),
newSpillLength
(
property
));
newMap
.
updateFreeSlots
(
null
,
property
);
return
newMap
;
}
/**
* Remove a property from a map. Cloning or using an existing map if available.
*
...
...
@@ -485,13 +505,13 @@ public class PropertyMap implements Iterable<Object>, Serializable {
// If deleted property was last field or spill slot we can make it reusable by reducing field/slot count.
// Otherwise mark it as free in free slots bitset.
if
(
isSpill
&&
slot
>=
0
&&
slot
==
spillLength
-
1
)
{
newMap
=
new
PropertyMap
(
this
,
newProperties
,
flags
,
fieldCount
,
spillLength
-
1
);
newMap
=
deriveMap
(
newProperties
,
flags
,
fieldCount
,
spillLength
-
1
);
newMap
.
freeSlots
=
freeSlots
;
}
else
if
(!
isSpill
&&
slot
>=
0
&&
slot
==
fieldCount
-
1
)
{
newMap
=
new
PropertyMap
(
this
,
newProperties
,
flags
,
fieldCount
-
1
,
spillLength
);
newMap
=
deriveMap
(
newProperties
,
flags
,
fieldCount
-
1
,
spillLength
);
newMap
.
freeSlots
=
freeSlots
;
}
else
{
newMap
=
new
PropertyMap
(
this
,
newProperties
,
flags
,
fieldCount
,
spillLength
);
newMap
=
deriveMap
(
newProperties
,
flags
,
fieldCount
,
spillLength
);
newMap
.
updateFreeSlots
(
property
,
null
);
}
addToHistory
(
property
,
newMap
);
...
...
@@ -539,7 +559,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
// Add replaces existing property.
final
PropertyHashMap
newProperties
=
properties
.
immutableReplace
(
oldProperty
,
newProperty
);
final
PropertyMap
newMap
=
new
PropertyMap
(
this
,
newProperties
,
flags
,
fieldCount
,
newSpillLength
);
final
PropertyMap
newMap
=
deriveMap
(
newProperties
,
flags
,
fieldCount
,
newSpillLength
);
if
(!
sameType
)
{
newMap
.
updateFreeSlots
(
oldProperty
,
newProperty
);
...
...
@@ -584,7 +604,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
final
Property
[]
otherProperties
=
other
.
properties
.
getProperties
();
final
PropertyHashMap
newProperties
=
properties
.
immutableAdd
(
otherProperties
);
final
PropertyMap
newMap
=
new
PropertyMap
(
this
,
newProperties
,
flags
,
fieldCount
,
spillLength
);
final
PropertyMap
newMap
=
deriveMap
(
newProperties
,
flags
,
fieldCount
,
spillLength
);
for
(
final
Property
property
:
otherProperties
)
{
// This method is only safe to use with non-slotted, native getter/setter properties
assert
property
.
getSlot
()
==
-
1
;
...
...
@@ -618,7 +638,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
* @return New map with {@link #NOT_EXTENSIBLE} flag set.
*/
PropertyMap
preventExtensions
()
{
return
new
PropertyMap
(
this
,
properties
,
flags
|
NOT_EXTENSIBLE
,
fieldCount
,
spillLength
);
return
deriveMap
(
properties
,
flags
|
NOT_EXTENSIBLE
,
fieldCount
,
spillLength
);
}
/**
...
...
@@ -634,7 +654,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
newProperties
=
newProperties
.
immutableAdd
(
oldProperty
.
addFlags
(
Property
.
NOT_CONFIGURABLE
));
}
return
new
PropertyMap
(
this
,
newProperties
,
flags
|
NOT_EXTENSIBLE
,
fieldCount
,
spillLength
);
return
deriveMap
(
newProperties
,
flags
|
NOT_EXTENSIBLE
,
fieldCount
,
spillLength
);
}
/**
...
...
@@ -656,7 +676,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
newProperties
=
newProperties
.
immutableAdd
(
oldProperty
.
addFlags
(
propertyFlags
));
}
return
new
PropertyMap
(
this
,
newProperties
,
flags
|
NOT_EXTENSIBLE
,
fieldCount
,
spillLength
);
return
deriveMap
(
newProperties
,
flags
|
NOT_EXTENSIBLE
,
fieldCount
,
spillLength
);
}
/**
...
...
@@ -743,7 +763,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
history
=
new
WeakHashMap
<>();
}
history
.
put
(
property
,
new
SoftReference
<>(
newMap
));
history
.
put
(
property
,
softReferenceDerivationLimit
==
0
?
new
WeakReference
<>(
newMap
)
:
new
SoftReference
<>(
newMap
));
}
/**
...
...
@@ -756,7 +776,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
private
PropertyMap
checkHistory
(
final
Property
property
)
{
if
(
history
!=
null
)
{
final
Soft
Reference
<
PropertyMap
>
ref
=
history
.
get
(
property
);
final
Reference
<
PropertyMap
>
ref
=
history
.
get
(
property
);
final
PropertyMap
historicMap
=
ref
==
null
?
null
:
ref
.
get
();
if
(
historicMap
!=
null
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录