Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
1e523264
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,发现更多精彩内容 >>
提交
1e523264
编写于
11月 08, 2017
作者:
H
hannesw
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8190427: Test for JDK-8165198 fails intermittently because of GC
Reviewed-by: jlaskey, sundar
上级
b219338b
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
309 addition
and
424 deletion
+309
-424
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeDebug.java
...are/classes/jdk/nashorn/internal/objects/NativeDebug.java
+5
-5
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyListeners.java
...asses/jdk/nashorn/internal/runtime/PropertyListeners.java
+0
-260
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
...are/classes/jdk/nashorn/internal/runtime/PropertyMap.java
+42
-117
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertySwitchPoints.java
...es/jdk/nashorn/internal/runtime/PropertySwitchPoints.java
+226
-0
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java
...re/classes/jdk/nashorn/internal/runtime/ScriptObject.java
+29
-17
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java
...lasses/jdk/nashorn/internal/runtime/SetMethodCreator.java
+2
-2
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SharedPropertyMap.java
...asses/jdk/nashorn/internal/runtime/SharedPropertyMap.java
+5
-23
未找到文件。
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeDebug.java
浏览文件 @
1e523264
/*
/*
* Copyright (c) 2010, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -36,7 +36,7 @@ import jdk.nashorn.internal.objects.annotations.ScriptClass;
...
@@ -36,7 +36,7 @@ import jdk.nashorn.internal.objects.annotations.ScriptClass;
import
jdk.nashorn.internal.objects.annotations.Where
;
import
jdk.nashorn.internal.objects.annotations.Where
;
import
jdk.nashorn.internal.runtime.Context
;
import
jdk.nashorn.internal.runtime.Context
;
import
jdk.nashorn.internal.runtime.JSType
;
import
jdk.nashorn.internal.runtime.JSType
;
import
jdk.nashorn.internal.runtime.Property
Listener
s
;
import
jdk.nashorn.internal.runtime.Property
SwitchPoint
s
;
import
jdk.nashorn.internal.runtime.PropertyMap
;
import
jdk.nashorn.internal.runtime.PropertyMap
;
import
jdk.nashorn.internal.runtime.Scope
;
import
jdk.nashorn.internal.runtime.Scope
;
import
jdk.nashorn.internal.runtime.ScriptFunction
;
import
jdk.nashorn.internal.runtime.ScriptFunction
;
...
@@ -244,7 +244,7 @@ public final class NativeDebug extends ScriptObject {
...
@@ -244,7 +244,7 @@ public final class NativeDebug extends ScriptObject {
*/
*/
@Function
(
attributes
=
Attribute
.
NOT_ENUMERABLE
,
where
=
Where
.
CONSTRUCTOR
)
@Function
(
attributes
=
Attribute
.
NOT_ENUMERABLE
,
where
=
Where
.
CONSTRUCTOR
)
public
static
int
getListenerCount
(
final
Object
self
,
final
Object
obj
)
{
public
static
int
getListenerCount
(
final
Object
self
,
final
Object
obj
)
{
return
(
obj
instanceof
ScriptObject
)
?
Property
Listeners
.
getListener
Count
((
ScriptObject
)
obj
)
:
0
;
return
(
obj
instanceof
ScriptObject
)
?
Property
SwitchPoints
.
getSwitchPoint
Count
((
ScriptObject
)
obj
)
:
0
;
}
}
/**
/**
...
@@ -260,8 +260,8 @@ public final class NativeDebug extends ScriptObject {
...
@@ -260,8 +260,8 @@ public final class NativeDebug extends ScriptObject {
out
.
println
(
"ScriptObject count "
+
ScriptObject
.
getCount
());
out
.
println
(
"ScriptObject count "
+
ScriptObject
.
getCount
());
out
.
println
(
"Scope count "
+
Scope
.
getScopeCount
());
out
.
println
(
"Scope count "
+
Scope
.
getScopeCount
());
out
.
println
(
"
ScriptObject listeners added "
+
PropertyListeners
.
getListener
sAdded
());
out
.
println
(
"
Property SwitchPoints added "
+
PropertySwitchPoints
.
getSwitchPoint
sAdded
());
out
.
println
(
"
ScriptObject listeners removed "
+
PropertyListeners
.
getListenersRemov
ed
());
out
.
println
(
"
Property SwitchPoints invalidated "
+
PropertySwitchPoints
.
getSwitchPointsInvalidat
ed
());
out
.
println
(
"ScriptFunction constructor calls "
+
ScriptFunction
.
getConstructorCount
());
out
.
println
(
"ScriptFunction constructor calls "
+
ScriptFunction
.
getConstructorCount
());
out
.
println
(
"ScriptFunction invokes "
+
ScriptFunction
.
getInvokes
());
out
.
println
(
"ScriptFunction invokes "
+
ScriptFunction
.
getInvokes
());
out
.
println
(
"ScriptFunction allocations "
+
ScriptFunction
.
getAllocations
());
out
.
println
(
"ScriptFunction allocations "
+
ScriptFunction
.
getAllocations
());
...
...
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyListeners.java
已删除
100644 → 0
浏览文件 @
b219338b
/*
* Copyright (c) 2010, 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
jdk.nashorn.internal.runtime
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.WeakHashMap
;
import
java.util.concurrent.atomic.LongAdder
;
/**
* Helper class to manage property listeners and notification.
*/
public
class
PropertyListeners
{
private
Map
<
Object
,
WeakPropertyMapSet
>
listeners
;
// These counters are updated in debug mode
private
static
LongAdder
listenersAdded
;
private
static
LongAdder
listenersRemoved
;
static
{
if
(
Context
.
DEBUG
)
{
listenersAdded
=
new
LongAdder
();
listenersRemoved
=
new
LongAdder
();
}
}
/**
* Copy constructor
* @param listener listener to copy
*/
PropertyListeners
(
final
PropertyListeners
listener
)
{
if
(
listener
!=
null
&&
listener
.
listeners
!=
null
)
{
this
.
listeners
=
new
WeakHashMap
<>();
// We need to copy the nested weak sets in order to avoid concurrent modification issues, see JDK-8146274
synchronized
(
listener
)
{
for
(
final
Map
.
Entry
<
Object
,
WeakPropertyMapSet
>
entry
:
listener
.
listeners
.
entrySet
())
{
this
.
listeners
.
put
(
entry
.
getKey
(),
new
WeakPropertyMapSet
(
entry
.
getValue
()));
}
}
}
}
/**
* Return aggregate listeners added to all PropertyListenerManagers
* @return the listenersAdded
*/
public
static
long
getListenersAdded
()
{
return
listenersAdded
.
longValue
();
}
/**
* Return aggregate listeners removed from all PropertyListenerManagers
* @return the listenersRemoved
*/
public
static
long
getListenersRemoved
()
{
return
listenersRemoved
.
longValue
();
}
/**
* Return number of listeners added to a ScriptObject.
* @param obj the object
* @return the listener count
*/
public
static
int
getListenerCount
(
final
ScriptObject
obj
)
{
return
obj
.
getMap
().
getListenerCount
();
}
/**
* Return the number of listeners added to this PropertyListeners instance.
* @return the listener count;
*/
public
int
getListenerCount
()
{
return
listeners
==
null
?
0
:
listeners
.
size
();
}
// Property listener management methods
/**
* Add {@code propertyMap} as property listener to {@code listeners} using key {@code key} by
* creating and returning a new {@code PropertyListeners} instance.
*
* @param listeners the original property listeners instance, may be null
* @param key the property key
* @param propertyMap the property map
* @return the new property map
*/
public
static
PropertyListeners
addListener
(
final
PropertyListeners
listeners
,
final
String
key
,
final
PropertyMap
propertyMap
)
{
final
PropertyListeners
newListeners
;
if
(
listeners
==
null
||
!
listeners
.
containsListener
(
key
,
propertyMap
))
{
newListeners
=
new
PropertyListeners
(
listeners
);
newListeners
.
addListener
(
key
,
propertyMap
);
return
newListeners
;
}
return
listeners
;
}
/**
* Checks whether {@code propertyMap} is registered as listener with {@code key}.
*
* @param key the property key
* @param propertyMap the property map
* @return true if property map is registered with property key
*/
synchronized
boolean
containsListener
(
final
String
key
,
final
PropertyMap
propertyMap
)
{
if
(
listeners
==
null
)
{
return
false
;
}
final
WeakPropertyMapSet
set
=
listeners
.
get
(
key
);
return
set
!=
null
&&
set
.
contains
(
propertyMap
);
}
/**
* Add a property listener to this object.
*
* @param propertyMap The property listener that is added.
*/
synchronized
final
void
addListener
(
final
String
key
,
final
PropertyMap
propertyMap
)
{
if
(
Context
.
DEBUG
)
{
listenersAdded
.
increment
();
}
if
(
listeners
==
null
)
{
listeners
=
new
WeakHashMap
<>();
}
WeakPropertyMapSet
set
=
listeners
.
get
(
key
);
if
(
set
==
null
)
{
set
=
new
WeakPropertyMapSet
();
listeners
.
put
(
key
,
set
);
}
if
(!
set
.
contains
(
propertyMap
))
{
set
.
add
(
propertyMap
);
}
}
/**
* A new property is being added.
*
* @param prop The new Property added.
*/
public
synchronized
void
propertyAdded
(
final
Property
prop
)
{
if
(
listeners
!=
null
)
{
final
WeakPropertyMapSet
set
=
listeners
.
get
(
prop
.
getKey
());
if
(
set
!=
null
)
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
propertyMap
.
propertyAdded
(
prop
,
false
);
}
listeners
.
remove
(
prop
.
getKey
());
if
(
Context
.
DEBUG
)
{
listenersRemoved
.
increment
();
}
}
}
}
/**
* An existing property is being deleted.
*
* @param prop The property being deleted.
*/
public
synchronized
void
propertyDeleted
(
final
Property
prop
)
{
if
(
listeners
!=
null
)
{
final
WeakPropertyMapSet
set
=
listeners
.
get
(
prop
.
getKey
());
if
(
set
!=
null
)
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
propertyMap
.
propertyDeleted
(
prop
,
false
);
}
listeners
.
remove
(
prop
.
getKey
());
if
(
Context
.
DEBUG
)
{
listenersRemoved
.
increment
();
}
}
}
}
/**
* An existing Property is being replaced with a new Property.
*
* @param oldProp The old property that is being replaced.
* @param newProp The new property that replaces the old property.
*
*/
public
synchronized
void
propertyModified
(
final
Property
oldProp
,
final
Property
newProp
)
{
if
(
listeners
!=
null
)
{
final
WeakPropertyMapSet
set
=
listeners
.
get
(
oldProp
.
getKey
());
if
(
set
!=
null
)
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
propertyMap
.
propertyModified
(
oldProp
,
newProp
,
false
);
}
listeners
.
remove
(
oldProp
.
getKey
());
if
(
Context
.
DEBUG
)
{
listenersRemoved
.
increment
();
}
}
}
}
/**
* Callback for when a proto is changed
*/
public
synchronized
void
protoChanged
()
{
if
(
listeners
!=
null
)
{
for
(
final
WeakPropertyMapSet
set
:
listeners
.
values
())
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
propertyMap
.
protoChanged
(
false
);
}
}
listeners
.
clear
();
}
}
private
static
class
WeakPropertyMapSet
{
private
final
WeakHashMap
<
PropertyMap
,
Boolean
>
map
;
WeakPropertyMapSet
()
{
this
.
map
=
new
WeakHashMap
<>();
}
WeakPropertyMapSet
(
final
WeakPropertyMapSet
set
)
{
this
.
map
=
new
WeakHashMap
<>(
set
.
map
);
}
void
add
(
final
PropertyMap
propertyMap
)
{
map
.
put
(
propertyMap
,
Boolean
.
TRUE
);
}
boolean
contains
(
final
PropertyMap
propertyMap
)
{
return
map
.
containsKey
(
propertyMap
);
}
Set
<
PropertyMap
>
elements
()
{
return
map
.
keySet
();
}
}
}
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
浏览文件 @
1e523264
/*
/*
* Copyright (c) 2010, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -40,9 +40,9 @@ import java.lang.ref.WeakReference;
...
@@ -40,9 +40,9 @@ import java.lang.ref.WeakReference;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.BitSet
;
import
java.util.BitSet
;
import
java.util.Collection
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.Iterator
;
import
java.util.NoSuchElementException
;
import
java.util.NoSuchElementException
;
import
java.util.Set
;
import
java.util.WeakHashMap
;
import
java.util.WeakHashMap
;
import
java.util.concurrent.atomic.LongAdder
;
import
java.util.concurrent.atomic.LongAdder
;
import
jdk.nashorn.internal.runtime.options.Options
;
import
jdk.nashorn.internal.runtime.options.Options
;
...
@@ -95,17 +95,14 @@ public class PropertyMap implements Iterable<Object>, Serializable {
...
@@ -95,17 +95,14 @@ public class PropertyMap implements Iterable<Object>, Serializable {
* property map should only be used if it the same as the actual prototype map. */
* property map should only be used if it the same as the actual prototype map. */
private
transient
SharedPropertyMap
sharedProtoMap
;
private
transient
SharedPropertyMap
sharedProtoMap
;
/** {@link SwitchPoint}s for gets on inherited properties. */
private
transient
HashMap
<
Object
,
SwitchPoint
>
protoSwitches
;
/** History of maps, used to limit map duplication. */
/** History of maps, used to limit map duplication. */
private
transient
WeakHashMap
<
Property
,
Reference
<
PropertyMap
>>
history
;
private
transient
WeakHashMap
<
Property
,
Reference
<
PropertyMap
>>
history
;
/** History of prototypes, used to limit map duplication. */
/** History of prototypes, used to limit map duplication. */
private
transient
WeakHashMap
<
ScriptObject
,
SoftReference
<
PropertyMap
>>
protoHistory
;
private
transient
WeakHashMap
<
ScriptObject
,
SoftReference
<
PropertyMap
>>
protoHistory
;
/**
property listeners
*/
/**
SwitchPoints for properties inherited form this map
*/
private
transient
Property
Listeners
listener
s
;
private
transient
Property
SwitchPoints
propertySwitchPoint
s
;
private
transient
BitSet
freeSlots
;
private
transient
BitSet
freeSlots
;
...
@@ -147,8 +144,8 @@ public class PropertyMap implements Iterable<Object>, Serializable {
...
@@ -147,8 +144,8 @@ public class PropertyMap implements Iterable<Object>, Serializable {
this
.
fieldCount
=
fieldCount
;
this
.
fieldCount
=
fieldCount
;
this
.
fieldMaximum
=
propertyMap
.
fieldMaximum
;
this
.
fieldMaximum
=
propertyMap
.
fieldMaximum
;
this
.
className
=
propertyMap
.
className
;
this
.
className
=
propertyMap
.
className
;
// We inherit the parent property
listener
s instance. It will be cloned when a new listener is added.
// We inherit the parent property
propertySwitchPoint
s instance. It will be cloned when a new listener is added.
this
.
listeners
=
propertyMap
.
listener
s
;
this
.
propertySwitchPoints
=
propertyMap
.
propertySwitchPoint
s
;
this
.
freeSlots
=
propertyMap
.
freeSlots
;
this
.
freeSlots
=
propertyMap
.
freeSlots
;
this
.
sharedProtoMap
=
propertyMap
.
sharedProtoMap
;
this
.
sharedProtoMap
=
propertyMap
.
sharedProtoMap
;
this
.
softReferenceDerivationLimit
=
softReferenceDerivationLimit
;
this
.
softReferenceDerivationLimit
=
softReferenceDerivationLimit
;
...
@@ -245,142 +242,70 @@ public class PropertyMap implements Iterable<Object>, Serializable {
...
@@ -245,142 +242,70 @@ public class PropertyMap implements Iterable<Object>, Serializable {
}
}
/**
/**
* Get the number of
listener
s of this map
* Get the number of
property SwitchPoint
s of this map
*
*
* @return the number of
listener
s
* @return the number of
property SwitchPoint
s
*/
*/
public
int
get
Listener
Count
()
{
public
int
get
SwitchPoint
Count
()
{
return
listeners
==
null
?
0
:
listeners
.
getListener
Count
();
return
propertySwitchPoints
==
null
?
0
:
propertySwitchPoints
.
getSwitchPoint
Count
();
}
}
/**
/**
* Add
{@code listenerMap} as a listener
to this property map for the given {@code key}.
* Add
a property switchpoint
to this property map for the given {@code key}.
*
*
* @param key the property name
* @param key the property name
* @param
listenerMap the listener map
* @param
switchPoint the switchpoint
*/
*/
public
void
addListener
(
final
String
key
,
final
PropertyMap
listenerMap
)
{
public
void
addSwitchPoint
(
final
String
key
,
final
SwitchPoint
switchPoint
)
{
if
(
listenerMap
!=
this
)
{
// We need to clone listener instance when adding a new listener since we share
// We need to clone listener instance when adding a new listener since we share
// the listeners instance with our parent maps that don't need to see the new listener.
// the propertySwitchPoints instance with our parent maps that don't need to see the new listener.
listeners
=
PropertyListeners
.
addListener
(
listeners
,
key
,
listenerMap
);
propertySwitchPoints
=
PropertySwitchPoints
.
addSwitchPoint
(
propertySwitchPoints
,
key
,
switchPoint
);
}
}
/**
* A new property is being added.
*
* @param property The new Property added.
* @param isSelf was the property added to this map?
*/
public
void
propertyAdded
(
final
Property
property
,
final
boolean
isSelf
)
{
if
(!
isSelf
)
{
invalidateProtoSwitchPoint
(
property
.
getKey
());
}
if
(
listeners
!=
null
)
{
listeners
.
propertyAdded
(
property
);
}
}
}
/**
/**
* An existing property is being deleted.
* Method called when a property of an object using this property map is being created,
* modified, or deleted. If a switchpoint for the property exists it will be invalidated.
*
*
* @param property The property being deleted.
* @param property The changed property.
* @param isSelf was the property deleted from this map?
*/
*/
public
void
propertyDeleted
(
final
Property
property
,
final
boolean
isSelf
)
{
public
void
propertyChanged
(
final
Property
property
)
{
if
(!
isSelf
)
{
if
(
propertySwitchPoints
!=
null
)
{
invalidateProtoSwitchPoint
(
property
.
getKey
());
propertySwitchPoints
.
invalidateProperty
(
property
);
}
if
(
listeners
!=
null
)
{
listeners
.
propertyDeleted
(
property
);
}
}
}
}
/**
/**
* An existing property is being redefined.
* Method called when the prototype of an object using this property map is changed.
*
* @param oldProperty The old property
* @param newProperty The new property
* @param isSelf was the property modified on this map?
*/
public
void
propertyModified
(
final
Property
oldProperty
,
final
Property
newProperty
,
final
boolean
isSelf
)
{
if
(!
isSelf
)
{
invalidateProtoSwitchPoint
(
oldProperty
.
getKey
());
}
if
(
listeners
!=
null
)
{
listeners
.
propertyModified
(
oldProperty
,
newProperty
);
}
}
/**
* The prototype of an object associated with this {@link PropertyMap} is changed.
*
* @param isSelf was the prototype changed on the object using this map?
*/
*/
public
void
protoChanged
(
final
boolean
isSelf
)
{
void
protoChanged
()
{
if
(!
isSelf
)
{
if
(
sharedProtoMap
!=
null
)
{
invalidateAllProtoSwitchPoints
();
}
else
if
(
sharedProtoMap
!=
null
)
{
sharedProtoMap
.
invalidateSwitchPoint
();
sharedProtoMap
.
invalidateSwitchPoint
();
}
}
if
(
listener
s
!=
null
)
{
if
(
propertySwitchPoint
s
!=
null
)
{
listeners
.
protoChanged
(
);
propertySwitchPoints
.
invalidateInheritedProperties
(
this
);
}
}
}
}
/**
/**
* Return a SwitchPoint used to track changes of a property in a prototype.
* Returns a SwitchPoint for use with a property inherited from this or a parent map.
* If such a switchpoint exists, it will be invalidated when the property is modified
* in an object using this map. This method returns {@code null} if no swichpoint exists
* for the property.
*
*
* @param key Property key.
* @param key Property key.
* @return A
shared {@link SwitchPoint} for the property
.
* @return A
{@link SwitchPoint} for the property, or null
.
*/
*/
public
synchronized
SwitchPoint
getSwitchPoint
(
final
String
key
)
{
public
synchronized
SwitchPoint
getSwitchPoint
(
final
String
key
)
{
if
(
protoSwitches
==
null
)
{
if
(
propertySwitchPoints
!=
null
)
{
protoSwitches
=
new
HashMap
<>();
final
Set
<
SwitchPoint
>
existingSwitchPoints
=
propertySwitchPoints
.
getSwitchPoints
(
key
);
}
for
(
final
SwitchPoint
switchPoint
:
existingSwitchPoints
)
{
if
(
switchPoint
!=
null
&&
!
switchPoint
.
hasBeenInvalidated
())
{
SwitchPoint
switchPoint
=
protoSwitches
.
get
(
key
);
if
(
switchPoint
==
null
)
{
switchPoint
=
new
SwitchPoint
();
protoSwitches
.
put
(
key
,
switchPoint
);
}
return
switchPoint
;
return
switchPoint
;
}
}
/**
* Indicate that a prototype property has changed.
*
* @param key {@link Property} key to invalidate.
*/
synchronized
void
invalidateProtoSwitchPoint
(
final
Object
key
)
{
if
(
protoSwitches
!=
null
)
{
final
SwitchPoint
sp
=
protoSwitches
.
get
(
key
);
if
(
sp
!=
null
)
{
protoSwitches
.
remove
(
key
);
if
(
Context
.
DEBUG
)
{
protoInvalidations
.
increment
();
}
SwitchPoint
.
invalidateAll
(
new
SwitchPoint
[]{
sp
});
}
}
}
}
}
/**
return
null
;
* Indicate that proto itself has changed in hierarchy somewhere.
*/
synchronized
void
invalidateAllProtoSwitchPoints
()
{
if
(
protoSwitches
!=
null
)
{
final
int
size
=
protoSwitches
.
size
();
if
(
size
>
0
)
{
if
(
Context
.
DEBUG
)
{
protoInvalidations
.
add
(
size
);
}
SwitchPoint
.
invalidateAll
(
protoSwitches
.
values
().
toArray
(
new
SwitchPoint
[
0
]));
protoSwitches
.
clear
();
}
}
}
}
/**
/**
...
@@ -452,7 +377,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
...
@@ -452,7 +377,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
* @return New {@link PropertyMap} with {@link Property} added.
* @return New {@link PropertyMap} with {@link Property} added.
*/
*/
public
final
PropertyMap
addPropertyNoHistory
(
final
Property
property
)
{
public
final
PropertyMap
addPropertyNoHistory
(
final
Property
property
)
{
property
Added
(
property
,
true
);
property
Changed
(
property
);
return
addPropertyInternal
(
property
);
return
addPropertyInternal
(
property
);
}
}
...
@@ -464,7 +389,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
...
@@ -464,7 +389,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
* @return New {@link PropertyMap} with {@link Property} added.
* @return New {@link PropertyMap} with {@link Property} added.
*/
*/
public
final
synchronized
PropertyMap
addProperty
(
final
Property
property
)
{
public
final
synchronized
PropertyMap
addProperty
(
final
Property
property
)
{
property
Added
(
property
,
true
);
property
Changed
(
property
);
PropertyMap
newMap
=
checkHistory
(
property
);
PropertyMap
newMap
=
checkHistory
(
property
);
if
(
newMap
==
null
)
{
if
(
newMap
==
null
)
{
...
@@ -494,7 +419,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
...
@@ -494,7 +419,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
* @return New {@link PropertyMap} with {@link Property} removed or {@code null} if not found.
* @return New {@link PropertyMap} with {@link Property} removed or {@code null} if not found.
*/
*/
public
final
synchronized
PropertyMap
deleteProperty
(
final
Property
property
)
{
public
final
synchronized
PropertyMap
deleteProperty
(
final
Property
property
)
{
property
Deleted
(
property
,
true
);
property
Changed
(
property
);
PropertyMap
newMap
=
checkHistory
(
property
);
PropertyMap
newMap
=
checkHistory
(
property
);
final
Object
key
=
property
.
getKey
();
final
Object
key
=
property
.
getKey
();
...
@@ -529,7 +454,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
...
@@ -529,7 +454,7 @@ public class PropertyMap implements Iterable<Object>, Serializable {
* @return New {@link PropertyMap} with {@link Property} replaced.
* @return New {@link PropertyMap} with {@link Property} replaced.
*/
*/
public
final
PropertyMap
replaceProperty
(
final
Property
oldProperty
,
final
Property
newProperty
)
{
public
final
PropertyMap
replaceProperty
(
final
Property
oldProperty
,
final
Property
newProperty
)
{
property
Modified
(
oldProperty
,
newProperty
,
true
);
property
Changed
(
oldProperty
);
/*
/*
* See ScriptObject.modifyProperty and ScriptObject.setUserAccessors methods.
* See ScriptObject.modifyProperty and ScriptObject.setUserAccessors methods.
*
*
...
...
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertySwitchPoints.java
0 → 100644
浏览文件 @
1e523264
/*
* Copyright (c) 2010, 2017, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
jdk.nashorn.internal.runtime
;
import
java.lang.invoke.SwitchPoint
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.WeakHashMap
;
import
java.util.concurrent.atomic.LongAdder
;
/**
* Helper class for tracking and invalidation of switchpoints for inherited properties.
*/
public
class
PropertySwitchPoints
{
private
final
Map
<
Object
,
WeakSwitchPointSet
>
switchPointMap
=
new
HashMap
<>();
private
final
static
SwitchPoint
[]
EMPTY_SWITCHPOINT_ARRAY
=
new
SwitchPoint
[
0
];
// These counters are updated in debug mode
private
static
LongAdder
switchPointsAdded
;
private
static
LongAdder
switchPointsInvalidated
;
static
{
if
(
Context
.
DEBUG
)
{
switchPointsAdded
=
new
LongAdder
();
switchPointsInvalidated
=
new
LongAdder
();
}
}
/**
* Copy constructor
*
* @param switchPoints Proto switchpoints to copy
*/
private
PropertySwitchPoints
(
final
PropertySwitchPoints
switchPoints
)
{
if
(
switchPoints
!=
null
)
{
// We need to copy the nested weak sets in order to avoid concurrent modification issues, see JDK-8146274
synchronized
(
switchPoints
)
{
for
(
final
Map
.
Entry
<
Object
,
WeakSwitchPointSet
>
entry
:
switchPoints
.
switchPointMap
.
entrySet
())
{
this
.
switchPointMap
.
put
(
entry
.
getKey
(),
new
WeakSwitchPointSet
(
entry
.
getValue
()));
}
}
}
}
/**
* Return aggregate switchpoints added to all ProtoSwitchPoints
* @return the number of switchpoints added
*/
public
static
long
getSwitchPointsAdded
()
{
return
switchPointsAdded
.
longValue
();
}
/**
* Return aggregate switchPointMap invalidated in all ProtoSwitchPoints
* @return the number of switchpoints invalidated
*/
public
static
long
getSwitchPointsInvalidated
()
{
return
switchPointsInvalidated
.
longValue
();
}
/**
* Return number of property switchPoints added to a ScriptObject.
* @param obj the object
* @return the switchpoint count
*/
public
static
int
getSwitchPointCount
(
final
ScriptObject
obj
)
{
return
obj
.
getMap
().
getSwitchPointCount
();
}
/**
* Return the number of switchpoints added to this ProtoSwitchPoints instance.
* @return the switchpoint count;
*/
int
getSwitchPointCount
()
{
return
switchPointMap
.
size
();
}
/**
* Add {@code switchPoint} to the switchpoints for for property {@code key}, creating
* and returning a new {@code ProtoSwitchPoints} instance if the switchpoint was not already contained
*
* @param oldSwitchPoints the original PropertySwitchPoints instance. May be null
* @param key the property key
* @param switchPoint the switchpoint to be added
* @return the new PropertySwitchPoints instance, or this instance if switchpoint was already contained
*/
static
PropertySwitchPoints
addSwitchPoint
(
final
PropertySwitchPoints
oldSwitchPoints
,
final
String
key
,
final
SwitchPoint
switchPoint
)
{
if
(
oldSwitchPoints
==
null
||
!
oldSwitchPoints
.
contains
(
key
,
switchPoint
))
{
final
PropertySwitchPoints
newSwitchPoints
=
new
PropertySwitchPoints
(
oldSwitchPoints
);
newSwitchPoints
.
add
(
key
,
switchPoint
);
return
newSwitchPoints
;
}
return
oldSwitchPoints
;
}
/**
* Checks whether {@code switchPoint} is contained in {@code key}'s set.
*
* @param key the property key
* @param switchPoint the switchPoint
* @return true if switchpoint is already contained for key
*/
private
synchronized
boolean
contains
(
final
String
key
,
final
SwitchPoint
switchPoint
)
{
final
WeakSwitchPointSet
set
=
this
.
switchPointMap
.
get
(
key
);
return
set
!=
null
&&
set
.
contains
(
switchPoint
);
}
private
synchronized
void
add
(
final
String
key
,
final
SwitchPoint
switchPoint
)
{
if
(
Context
.
DEBUG
)
{
switchPointsAdded
.
increment
();
}
WeakSwitchPointSet
set
=
this
.
switchPointMap
.
get
(
key
);
if
(
set
==
null
)
{
set
=
new
WeakSwitchPointSet
();
this
.
switchPointMap
.
put
(
key
,
set
);
}
set
.
add
(
switchPoint
);
}
Set
<
SwitchPoint
>
getSwitchPoints
(
final
Object
key
)
{
WeakSwitchPointSet
switchPointSet
=
switchPointMap
.
get
(
key
);
if
(
switchPointSet
!=
null
)
{
return
switchPointSet
.
elements
();
}
return
Collections
.
emptySet
();
}
/**
* Invalidate all switchpoints for the given property. This is called when that
* property is created, deleted, or modified in a script object.
*
* @param prop The property to invalidate.
*/
synchronized
void
invalidateProperty
(
final
Property
prop
)
{
final
WeakSwitchPointSet
set
=
switchPointMap
.
get
(
prop
.
getKey
());
if
(
set
!=
null
)
{
if
(
Context
.
DEBUG
)
{
switchPointsInvalidated
.
add
(
set
.
size
());
}
final
SwitchPoint
[]
switchPoints
=
set
.
elements
().
toArray
(
EMPTY_SWITCHPOINT_ARRAY
);
SwitchPoint
.
invalidateAll
(
switchPoints
);
this
.
switchPointMap
.
remove
(
prop
.
getKey
());
}
}
/**
* Invalidate all switchpoints except those defined in {@code map}. This is called
* when the prototype of a script object is changed.
*
* @param map map of properties to exclude from invalidation
*/
synchronized
void
invalidateInheritedProperties
(
final
PropertyMap
map
)
{
for
(
final
Map
.
Entry
<
Object
,
WeakSwitchPointSet
>
entry
:
switchPointMap
.
entrySet
())
{
if
(
map
.
findProperty
(
entry
.
getKey
())
!=
null
)
{
continue
;
}
if
(
Context
.
DEBUG
)
{
switchPointsInvalidated
.
add
(
entry
.
getValue
().
size
());
}
final
SwitchPoint
[]
switchPoints
=
entry
.
getValue
().
elements
().
toArray
(
EMPTY_SWITCHPOINT_ARRAY
);
SwitchPoint
.
invalidateAll
(
switchPoints
);
}
switchPointMap
.
clear
();
}
private
static
class
WeakSwitchPointSet
{
private
final
WeakHashMap
<
SwitchPoint
,
Void
>
map
;
WeakSwitchPointSet
()
{
map
=
new
WeakHashMap
<>();
}
WeakSwitchPointSet
(
final
WeakSwitchPointSet
set
)
{
map
=
new
WeakHashMap
<>(
set
.
map
);
}
void
add
(
final
SwitchPoint
switchPoint
)
{
map
.
put
(
switchPoint
,
null
);
}
boolean
contains
(
final
SwitchPoint
switchPoint
)
{
return
map
.
containsKey
(
switchPoint
);
}
Set
<
SwitchPoint
>
elements
()
{
return
map
.
keySet
();
}
int
size
()
{
return
map
.
size
();
}
}
}
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java
浏览文件 @
1e523264
/*
/*
* Copyright (c) 2010, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -1248,7 +1248,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -1248,7 +1248,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
proto
=
newProto
;
proto
=
newProto
;
// Let current listeners know that the prototype has changed
// Let current listeners know that the prototype has changed
getMap
().
protoChanged
(
true
);
getMap
().
protoChanged
();
// Replace our current allocator map with one that is associated with the new prototype.
// Replace our current allocator map with one that is associated with the new prototype.
setMap
(
getMap
().
changeProto
(
newProto
));
setMap
(
getMap
().
changeProto
(
newProto
));
}
}
...
@@ -2107,30 +2107,38 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2107,30 +2107,38 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
}
}
/**
/**
* Get a
switch point for a property with the given {@code name} that will be invalidated when
* Get a
n array of switch points for a property with the given {@code name} that will be
*
the property definition is changed in this object's prototype chain. Returns {@code null} if
*
invalidated when the property definition is changed in this object's prototype chain.
* the property is defined in this object itself.
*
Returns {@code null} if
the property is defined in this object itself.
*
*
* @param name the property name
* @param name the property name
* @param owner the property owner, null if property is not defined
* @param owner the property owner, null if property is not defined
* @return a
SwitchPoint
or null
* @return a
n array of SwitchPoints
or null
*/
*/
public
final
SwitchPoint
[]
getProtoSwitchPoints
(
final
String
name
,
final
ScriptObject
owner
)
{
public
final
SwitchPoint
[]
getProtoSwitchPoints
(
final
String
name
,
final
ScriptObject
owner
)
{
if
(
owner
==
this
||
getProto
()
==
null
)
{
if
(
owner
==
this
||
getProto
()
==
null
)
{
return
null
;
return
null
;
}
}
final
List
<
SwitchPoint
>
switchPoints
=
new
ArrayList
<>();
final
Set
<
SwitchPoint
>
switchPoints
=
new
HashSet
<>();
SwitchPoint
switchPoint
=
getProto
().
getMap
().
getSwitchPoint
(
name
);
if
(
switchPoint
==
null
)
{
switchPoint
=
new
SwitchPoint
();
for
(
ScriptObject
obj
=
this
;
obj
!=
owner
&&
obj
.
getProto
()
!=
null
;
obj
=
obj
.
getProto
())
{
for
(
ScriptObject
obj
=
this
;
obj
!=
owner
&&
obj
.
getProto
()
!=
null
;
obj
=
obj
.
getProto
())
{
final
ScriptObject
parent
=
obj
.
getProto
();
obj
.
getProto
().
getMap
().
addSwitchPoint
(
name
,
switchPoint
);
parent
.
getMap
().
addListener
(
name
,
obj
.
getMap
());
}
final
SwitchPoint
sp
=
parent
.
getMap
().
getSharedProtoSwitchPoint
();
}
if
(
sp
!=
null
&&
!
sp
.
hasBeenInvalidated
())
{
switchPoints
.
add
(
sp
);
switchPoints
.
add
(
switchPoint
);
for
(
ScriptObject
obj
=
this
;
obj
!=
owner
&&
obj
.
getProto
()
!=
null
;
obj
=
obj
.
getProto
())
{
final
SwitchPoint
sharedProtoSwitchPoint
=
obj
.
getProto
().
getMap
().
getSharedProtoSwitchPoint
();
if
(
sharedProtoSwitchPoint
!=
null
&&
!
sharedProtoSwitchPoint
.
hasBeenInvalidated
())
{
switchPoints
.
add
(
sharedProtoSwitchPoint
);
}
}
}
}
switchPoints
.
add
(
getMap
().
getSwitchPoint
(
name
));
return
switchPoints
.
toArray
(
new
SwitchPoint
[
0
]);
return
switchPoints
.
toArray
(
new
SwitchPoint
[
0
]);
}
}
...
@@ -2141,12 +2149,16 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2141,12 +2149,16 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return
null
;
return
null
;
}
}
SwitchPoint
switchPoint
=
getProto
().
getMap
().
getSwitchPoint
(
name
);
if
(
switchPoint
==
null
)
{
switchPoint
=
new
SwitchPoint
();
for
(
ScriptObject
obj
=
this
;
obj
.
getProto
()
!=
null
;
obj
=
obj
.
getProto
())
{
for
(
ScriptObject
obj
=
this
;
obj
.
getProto
()
!=
null
;
obj
=
obj
.
getProto
())
{
final
ScriptObject
parent
=
obj
.
getProto
(
);
obj
.
getProto
().
getMap
().
addSwitchPoint
(
name
,
switchPoint
);
parent
.
getMap
().
addListener
(
name
,
obj
.
getMap
());
}
}
}
return
getMap
().
getSwitchPoint
(
name
)
;
return
switchPoint
;
}
}
private
void
checkSharedProtoMap
()
{
private
void
checkSharedProtoMap
()
{
...
...
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java
浏览文件 @
1e523264
/*
/*
* Copyright (c) 2010, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -185,7 +185,7 @@ final class SetMethodCreator {
...
@@ -185,7 +185,7 @@ final class SetMethodCreator {
private
SetMethod
createNewPropertySetter
(
final
SwitchPoint
builtinSwitchPoint
)
{
private
SetMethod
createNewPropertySetter
(
final
SwitchPoint
builtinSwitchPoint
)
{
final
SetMethod
sm
=
map
.
getFreeFieldSlot
()
>
-
1
?
createNewFieldSetter
(
builtinSwitchPoint
)
:
createNewSpillPropertySetter
(
builtinSwitchPoint
);
final
SetMethod
sm
=
map
.
getFreeFieldSlot
()
>
-
1
?
createNewFieldSetter
(
builtinSwitchPoint
)
:
createNewSpillPropertySetter
(
builtinSwitchPoint
);
map
.
property
Added
(
sm
.
property
,
true
);
map
.
property
Changed
(
sm
.
property
);
return
sm
;
return
sm
;
}
}
...
...
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SharedPropertyMap.java
浏览文件 @
1e523264
/*
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015,
2017,
Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -48,33 +48,15 @@ public final class SharedPropertyMap extends PropertyMap {
...
@@ -48,33 +48,15 @@ public final class SharedPropertyMap extends PropertyMap {
* Create a new shared property map from the given {@code map}.
* Create a new shared property map from the given {@code map}.
* @param map property map to copy
* @param map property map to copy
*/
*/
public
SharedPropertyMap
(
final
PropertyMap
map
)
{
SharedPropertyMap
(
final
PropertyMap
map
)
{
super
(
map
);
super
(
map
);
this
.
switchPoint
=
new
SwitchPoint
();
this
.
switchPoint
=
new
SwitchPoint
();
}
}
@Override
@Override
public
void
propertyAdded
(
final
Property
property
,
final
boolean
isSelf
)
{
public
void
propertyChanged
(
final
Property
property
)
{
if
(
isSelf
)
{
invalidateSwitchPoint
();
invalidateSwitchPoint
();
}
super
.
propertyChanged
(
property
);
super
.
propertyAdded
(
property
,
isSelf
);
}
@Override
public
void
propertyDeleted
(
final
Property
property
,
final
boolean
isSelf
)
{
if
(
isSelf
)
{
invalidateSwitchPoint
();
}
super
.
propertyDeleted
(
property
,
isSelf
);
}
@Override
public
void
propertyModified
(
final
Property
oldProperty
,
final
Property
newProperty
,
final
boolean
isSelf
)
{
if
(
isSelf
)
{
invalidateSwitchPoint
();
}
super
.
propertyModified
(
oldProperty
,
newProperty
,
isSelf
);
}
}
@Override
@Override
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录