Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
b642e31e
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,发现更多精彩内容 >>
提交
b642e31e
编写于
9月 16, 2015
作者:
H
hannesw
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8134609: Allow constructors with same prototoype map to share the allocator map
Reviewed-by: attila, sundar
上级
92853b17
变更
15
展开全部
显示空白变更内容
内联
并排
Showing
15 changed file
with
655 addition
and
187 deletion
+655
-187
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java
...classes/jdk/nashorn/internal/objects/NativeJSAdapter.java
+3
-3
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AllocationStrategy.java
...sses/jdk/nashorn/internal/runtime/AllocationStrategy.java
+84
-3
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Debug.java
...orn/share/classes/jdk/nashorn/internal/runtime/Debug.java
+11
-0
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyListeners.java
...asses/jdk/nashorn/internal/runtime/PropertyListeners.java
+14
-10
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
...are/classes/jdk/nashorn/internal/runtime/PropertyMap.java
+170
-119
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
...horn/internal/runtime/RecompilableScriptFunctionData.java
+2
-2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java
.../classes/jdk/nashorn/internal/runtime/ScriptFunction.java
+23
-19
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java
...sses/jdk/nashorn/internal/runtime/ScriptFunctionData.java
+2
-1
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java
...re/classes/jdk/nashorn/internal/runtime/ScriptObject.java
+34
-20
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java
...lasses/jdk/nashorn/internal/runtime/SetMethodCreator.java
+2
-5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SharedPropertyMap.java
...asses/jdk/nashorn/internal/runtime/SharedPropertyMap.java
+100
-0
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/WithObject.java
...hare/classes/jdk/nashorn/internal/runtime/WithObject.java
+15
-4
nashorn/test/script/basic/JDK-8134569.js
nashorn/test/script/basic/JDK-8134569.js
+80
-1
nashorn/test/script/basic/JDK-8134569.js.EXPECTED
nashorn/test/script/basic/JDK-8134569.js.EXPECTED
+20
-0
nashorn/test/script/basic/JDK-8134609.js
nashorn/test/script/basic/JDK-8134609.js
+95
-0
未找到文件。
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java
浏览文件 @
b642e31e
...
@@ -627,7 +627,7 @@ public final class NativeJSAdapter extends ScriptObject {
...
@@ -627,7 +627,7 @@ public final class NativeJSAdapter extends ScriptObject {
return
new
GuardedInvocation
(
MH
.
dropArguments
(
MH
.
constant
(
Object
.
class
,
return
new
GuardedInvocation
(
MH
.
dropArguments
(
MH
.
constant
(
Object
.
class
,
func
.
createBound
(
this
,
new
Object
[]
{
name
})),
0
,
Object
.
class
),
func
.
createBound
(
this
,
new
Object
[]
{
name
})),
0
,
Object
.
class
),
testJSAdaptor
(
adaptee
,
null
,
null
,
null
),
testJSAdaptor
(
adaptee
,
null
,
null
,
null
),
adaptee
.
getProtoSwitchPoint
(
__call__
,
find
.
getOwner
())
);
adaptee
.
getProtoSwitchPoint
s
(
__call__
,
find
.
getOwner
()),
null
);
}
}
}
}
throw
typeError
(
"no.such.function"
,
desc
.
getNameToken
(
2
),
ScriptRuntime
.
safeToString
(
this
));
throw
typeError
(
"no.such.function"
,
desc
.
getNameToken
(
2
),
ScriptRuntime
.
safeToString
(
this
));
...
@@ -698,7 +698,7 @@ public final class NativeJSAdapter extends ScriptObject {
...
@@ -698,7 +698,7 @@ public final class NativeJSAdapter extends ScriptObject {
return
new
GuardedInvocation
(
return
new
GuardedInvocation
(
methodHandle
,
methodHandle
,
testJSAdaptor
(
adaptee
,
findData
.
getGetter
(
Object
.
class
,
INVALID_PROGRAM_POINT
,
null
),
findData
.
getOwner
(),
func
),
testJSAdaptor
(
adaptee
,
findData
.
getGetter
(
Object
.
class
,
INVALID_PROGRAM_POINT
,
null
),
findData
.
getOwner
(),
func
),
adaptee
.
getProtoSwitchPoint
(
hook
,
findData
.
getOwner
())
);
adaptee
.
getProtoSwitchPoint
s
(
hook
,
findData
.
getOwner
()),
null
);
}
}
}
}
}
}
...
@@ -710,7 +710,7 @@ public final class NativeJSAdapter extends ScriptObject {
...
@@ -710,7 +710,7 @@ public final class NativeJSAdapter extends ScriptObject {
final
MethodHandle
methodHandle
=
hook
.
equals
(
__put__
)
?
final
MethodHandle
methodHandle
=
hook
.
equals
(
__put__
)
?
MH
.
asType
(
Lookup
.
EMPTY_SETTER
,
type
)
:
MH
.
asType
(
Lookup
.
EMPTY_SETTER
,
type
)
:
Lookup
.
emptyGetter
(
type
.
returnType
());
Lookup
.
emptyGetter
(
type
.
returnType
());
return
new
GuardedInvocation
(
methodHandle
,
testJSAdaptor
(
adaptee
,
null
,
null
,
null
),
adaptee
.
getProtoSwitchPoint
(
hook
,
null
)
);
return
new
GuardedInvocation
(
methodHandle
,
testJSAdaptor
(
adaptee
,
null
,
null
,
null
),
adaptee
.
getProtoSwitchPoint
s
(
hook
,
null
),
null
);
}
}
}
}
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AllocationStrategy.java
浏览文件 @
b642e31e
...
@@ -29,6 +29,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
...
@@ -29,6 +29,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
import
java.io.Serializable
;
import
java.io.Serializable
;
import
java.lang.invoke.MethodHandle
;
import
java.lang.invoke.MethodHandle
;
import
java.lang.invoke.MethodHandles
;
import
java.lang.invoke.MethodHandles
;
import
java.lang.ref.WeakReference
;
import
jdk.nashorn.internal.codegen.Compiler
;
import
jdk.nashorn.internal.codegen.Compiler
;
import
jdk.nashorn.internal.codegen.CompilerConstants
;
import
jdk.nashorn.internal.codegen.CompilerConstants
;
import
jdk.nashorn.internal.codegen.ObjectClassGenerator
;
import
jdk.nashorn.internal.codegen.ObjectClassGenerator
;
...
@@ -53,6 +54,9 @@ final public class AllocationStrategy implements Serializable {
...
@@ -53,6 +54,9 @@ final public class AllocationStrategy implements Serializable {
/** lazily generated allocator */
/** lazily generated allocator */
private
transient
MethodHandle
allocator
;
private
transient
MethodHandle
allocator
;
/** Last used allocator map */
private
transient
AllocatorMap
lastMap
;
/**
/**
* Construct an allocation strategy with the given map and class name.
* Construct an allocation strategy with the given map and class name.
* @param fieldCount number of fields in the allocated object
* @param fieldCount number of fields in the allocated object
...
@@ -71,11 +75,49 @@ final public class AllocationStrategy implements Serializable {
...
@@ -71,11 +75,49 @@ final public class AllocationStrategy implements Serializable {
return
allocatorClassName
;
return
allocatorClassName
;
}
}
PropertyMap
getAllocatorMap
()
{
/**
// Create a new map for each function instance
* Get the property map for the allocated object.
return
PropertyMap
.
newMap
(
null
,
getAllocatorClassName
(),
0
,
fieldCount
,
0
);
* @param prototype the prototype object
* @return the property map
*/
synchronized
PropertyMap
getAllocatorMap
(
final
ScriptObject
prototype
)
{
assert
prototype
!=
null
;
final
PropertyMap
protoMap
=
prototype
.
getMap
();
if
(
lastMap
!=
null
)
{
if
(!
lastMap
.
hasSharedProtoMap
())
{
if
(
lastMap
.
hasSamePrototype
(
prototype
))
{
return
lastMap
.
allocatorMap
;
}
if
(
lastMap
.
hasSameProtoMap
(
protoMap
)
&&
lastMap
.
hasUnchangedProtoMap
())
{
// Convert to shared prototype map. Allocated objects will use the same property map
// that can be used as long as none of the prototypes modify the shared proto map.
final
PropertyMap
allocatorMap
=
PropertyMap
.
newMap
(
null
,
getAllocatorClassName
(),
0
,
fieldCount
,
0
);
final
SharedPropertyMap
sharedProtoMap
=
new
SharedPropertyMap
(
protoMap
);
allocatorMap
.
setSharedProtoMap
(
sharedProtoMap
);
prototype
.
setMap
(
sharedProtoMap
);
lastMap
=
new
AllocatorMap
(
prototype
,
protoMap
,
allocatorMap
);
return
allocatorMap
;
}
}
if
(
lastMap
.
hasValidSharedProtoMap
()
&&
lastMap
.
hasSameProtoMap
(
protoMap
))
{
prototype
.
setMap
(
lastMap
.
getSharedProtoMap
());
return
lastMap
.
allocatorMap
;
}
}
final
PropertyMap
allocatorMap
=
PropertyMap
.
newMap
(
null
,
getAllocatorClassName
(),
0
,
fieldCount
,
0
);
lastMap
=
new
AllocatorMap
(
prototype
,
protoMap
,
allocatorMap
);
return
allocatorMap
;
}
}
/**
* Allocate an object with the given property map
* @param map the property map
* @return the allocated object
*/
ScriptObject
allocate
(
final
PropertyMap
map
)
{
ScriptObject
allocate
(
final
PropertyMap
map
)
{
try
{
try
{
if
(
allocator
==
null
)
{
if
(
allocator
==
null
)
{
...
@@ -94,4 +136,43 @@ final public class AllocationStrategy implements Serializable {
...
@@ -94,4 +136,43 @@ final public class AllocationStrategy implements Serializable {
public
String
toString
()
{
public
String
toString
()
{
return
"AllocationStrategy[fieldCount="
+
fieldCount
+
"]"
;
return
"AllocationStrategy[fieldCount="
+
fieldCount
+
"]"
;
}
}
static
class
AllocatorMap
{
final
private
WeakReference
<
ScriptObject
>
prototype
;
final
private
WeakReference
<
PropertyMap
>
prototypeMap
;
private
PropertyMap
allocatorMap
;
AllocatorMap
(
final
ScriptObject
prototype
,
final
PropertyMap
protoMap
,
final
PropertyMap
allocMap
)
{
this
.
prototype
=
new
WeakReference
<>(
prototype
);
this
.
prototypeMap
=
new
WeakReference
<>(
protoMap
);
this
.
allocatorMap
=
allocMap
;
}
boolean
hasSamePrototype
(
final
ScriptObject
proto
)
{
return
prototype
.
get
()
==
proto
;
}
boolean
hasSameProtoMap
(
final
PropertyMap
protoMap
)
{
return
prototypeMap
.
get
()
==
protoMap
||
allocatorMap
.
getSharedProtoMap
()
==
protoMap
;
}
boolean
hasUnchangedProtoMap
()
{
final
ScriptObject
proto
=
prototype
.
get
();
return
proto
!=
null
&&
proto
.
getMap
()
==
prototypeMap
.
get
();
}
boolean
hasSharedProtoMap
()
{
return
getSharedProtoMap
()
!=
null
;
}
boolean
hasValidSharedProtoMap
()
{
return
hasSharedProtoMap
()
&&
getSharedProtoMap
().
isValidSharedProtoMap
();
}
PropertyMap
getSharedProtoMap
()
{
return
allocatorMap
.
getSharedProtoMap
();
}
}
}
}
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Debug.java
浏览文件 @
b642e31e
...
@@ -26,6 +26,8 @@
...
@@ -26,6 +26,8 @@
package
jdk.nashorn.internal.runtime
;
package
jdk.nashorn.internal.runtime
;
import
static
jdk
.
nashorn
.
internal
.
parser
.
TokenType
.
EOF
;
import
static
jdk
.
nashorn
.
internal
.
parser
.
TokenType
.
EOF
;
import
jdk.nashorn.api.scripting.NashornException
;
import
jdk.nashorn.internal.parser.Lexer
;
import
jdk.nashorn.internal.parser.Lexer
;
import
jdk.nashorn.internal.parser.Token
;
import
jdk.nashorn.internal.parser.Token
;
import
jdk.nashorn.internal.parser.TokenStream
;
import
jdk.nashorn.internal.parser.TokenStream
;
...
@@ -62,6 +64,15 @@ public final class Debug {
...
@@ -62,6 +64,15 @@ public final class Debug {
return
firstJSFrame
(
new
Throwable
());
return
firstJSFrame
(
new
Throwable
());
}
}
/**
* Return a formatted script stack trace string with frames information separated by '\n'.
* This is a shortcut for {@code NashornException.getScriptStackString(new Throwable())}.
* @return formatted stack trace string
*/
public
static
String
scriptStack
()
{
return
NashornException
.
getScriptStackString
(
new
Throwable
());
}
/**
/**
* Return the system identity hashcode for an object as a human readable
* Return the system identity hashcode for an object as a human readable
* string
* string
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyListeners.java
浏览文件 @
b642e31e
...
@@ -75,16 +75,20 @@ public class PropertyListeners {
...
@@ -75,16 +75,20 @@ public class PropertyListeners {
}
}
/**
/**
* Return
listeners added to this
ScriptObject.
* Return
number of listeners added to a
ScriptObject.
* @param obj the object
* @param obj the object
* @return the listener count
* @return the listener count
*/
*/
public
static
int
getListenerCount
(
final
ScriptObject
obj
)
{
public
static
int
getListenerCount
(
final
ScriptObject
obj
)
{
final
PropertyListeners
propertyListeners
=
obj
.
getMap
().
getListeners
();
return
obj
.
getMap
().
getListenerCount
();
if
(
propertyListeners
!=
null
)
{
return
propertyListeners
.
listeners
==
null
?
0
:
propertyListeners
.
listeners
.
size
();
}
}
return
0
;
/**
* 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
// Property listener management methods
...
@@ -156,7 +160,7 @@ public class PropertyListeners {
...
@@ -156,7 +160,7 @@ public class PropertyListeners {
final
WeakPropertyMapSet
set
=
listeners
.
get
(
prop
.
getKey
());
final
WeakPropertyMapSet
set
=
listeners
.
get
(
prop
.
getKey
());
if
(
set
!=
null
)
{
if
(
set
!=
null
)
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
propertyMap
.
propertyAdded
(
prop
);
propertyMap
.
propertyAdded
(
prop
,
false
);
}
}
listeners
.
remove
(
prop
.
getKey
());
listeners
.
remove
(
prop
.
getKey
());
if
(
Context
.
DEBUG
)
{
if
(
Context
.
DEBUG
)
{
...
@@ -176,7 +180,7 @@ public class PropertyListeners {
...
@@ -176,7 +180,7 @@ public class PropertyListeners {
final
WeakPropertyMapSet
set
=
listeners
.
get
(
prop
.
getKey
());
final
WeakPropertyMapSet
set
=
listeners
.
get
(
prop
.
getKey
());
if
(
set
!=
null
)
{
if
(
set
!=
null
)
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
propertyMap
.
propertyDeleted
(
prop
);
propertyMap
.
propertyDeleted
(
prop
,
false
);
}
}
listeners
.
remove
(
prop
.
getKey
());
listeners
.
remove
(
prop
.
getKey
());
if
(
Context
.
DEBUG
)
{
if
(
Context
.
DEBUG
)
{
...
@@ -198,7 +202,7 @@ public class PropertyListeners {
...
@@ -198,7 +202,7 @@ public class PropertyListeners {
final
WeakPropertyMapSet
set
=
listeners
.
get
(
oldProp
.
getKey
());
final
WeakPropertyMapSet
set
=
listeners
.
get
(
oldProp
.
getKey
());
if
(
set
!=
null
)
{
if
(
set
!=
null
)
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
propertyMap
.
propertyModified
(
oldProp
,
newProp
);
propertyMap
.
propertyModified
(
oldProp
,
newProp
,
false
);
}
}
listeners
.
remove
(
oldProp
.
getKey
());
listeners
.
remove
(
oldProp
.
getKey
());
if
(
Context
.
DEBUG
)
{
if
(
Context
.
DEBUG
)
{
...
@@ -215,7 +219,7 @@ public class PropertyListeners {
...
@@ -215,7 +219,7 @@ public class PropertyListeners {
if
(
listeners
!=
null
)
{
if
(
listeners
!=
null
)
{
for
(
final
WeakPropertyMapSet
set
:
listeners
.
values
())
{
for
(
final
WeakPropertyMapSet
set
:
listeners
.
values
())
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
for
(
final
PropertyMap
propertyMap
:
set
.
elements
())
{
propertyMap
.
protoChanged
();
propertyMap
.
protoChanged
(
false
);
}
}
}
}
listeners
.
clear
();
listeners
.
clear
();
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
浏览文件 @
b642e31e
此差异已折叠。
点击以展开。
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
浏览文件 @
b642e31e
...
@@ -368,8 +368,8 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
...
@@ -368,8 +368,8 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
}
}
@Override
@Override
PropertyMap
getAllocatorMap
()
{
PropertyMap
getAllocatorMap
(
final
ScriptObject
prototype
)
{
return
allocationStrategy
.
getAllocatorMap
();
return
allocationStrategy
.
getAllocatorMap
(
prototype
);
}
}
@Override
@Override
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java
浏览文件 @
b642e31e
...
@@ -521,35 +521,39 @@ public class ScriptFunction extends ScriptObject {
...
@@ -521,35 +521,39 @@ public class ScriptFunction extends ScriptObject {
assert
!
isBoundFunction
();
// allocate never invoked on bound functions
assert
!
isBoundFunction
();
// allocate never invoked on bound functions
final
ScriptObject
object
=
data
.
allocate
(
getAllocatorMap
());
final
ScriptObject
prototype
=
getAllocatorPrototype
();
final
ScriptObject
object
=
data
.
allocate
(
getAllocatorMap
(
prototype
));
if
(
object
!=
null
)
{
if
(
object
!=
null
)
{
final
Object
prototype
=
getPrototype
();
object
.
setInitialProto
(
prototype
);
if
(
prototype
instanceof
ScriptObject
)
{
object
.
setInitialProto
((
ScriptObject
)
prototype
);
}
if
(
object
.
getProto
()
==
null
)
{
object
.
setInitialProto
(
getObjectPrototype
());
}
}
}
return
object
;
return
object
;
}
}
private
PropertyMap
getAllocatorMap
()
{
/**
if
(
allocatorMap
==
null
)
{
* Get the property map used by "allocate"
allocatorMap
=
data
.
getAllocatorMap
();
* @param prototype actual prototype object
* @return property map
*/
private
synchronized
PropertyMap
getAllocatorMap
(
final
ScriptObject
prototype
)
{
if
(
allocatorMap
==
null
||
allocatorMap
.
isInvalidSharedMapFor
(
prototype
))
{
// The prototype map has changed since this function was last used as constructor.
// Get a new allocator map.
allocatorMap
=
data
.
getAllocatorMap
(
prototype
);
}
}
return
allocatorMap
;
return
allocatorMap
;
}
}
/**
/**
* Return Object.prototype - used by "allocate"
* Return the actual prototype used by "allocate"
*
* @return allocator prototype
* @return Object.prototype
*/
*/
protected
final
ScriptObject
getObjectPrototype
()
{
private
ScriptObject
getAllocatorPrototype
()
{
final
Object
prototype
=
getPrototype
();
if
(
prototype
instanceof
ScriptObject
)
{
return
(
ScriptObject
)
prototype
;
}
return
Global
.
objectPrototype
();
return
Global
.
objectPrototype
();
}
}
...
@@ -591,10 +595,10 @@ public class ScriptFunction extends ScriptObject {
...
@@ -591,10 +595,10 @@ public class ScriptFunction extends ScriptObject {
*
*
* @param newPrototype new prototype object
* @param newPrototype new prototype object
*/
*/
public
final
void
setPrototype
(
final
Object
newPrototype
)
{
public
synchronized
final
void
setPrototype
(
final
Object
newPrototype
)
{
if
(
newPrototype
instanceof
ScriptObject
&&
newPrototype
!=
this
.
prototype
&&
allocatorMap
!=
null
)
{
if
(
newPrototype
instanceof
ScriptObject
&&
newPrototype
!=
this
.
prototype
&&
allocatorMap
!=
null
)
{
//
Replace our current allocator map with one that is associated with
the new prototype.
//
Unset allocator map to be replaced with one matching
the new prototype.
allocatorMap
=
allocatorMap
.
changeProto
((
ScriptObject
)
newPrototype
)
;
allocatorMap
=
null
;
}
}
this
.
prototype
=
newPrototype
;
this
.
prototype
=
newPrototype
;
}
}
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java
浏览文件 @
b642e31e
...
@@ -389,9 +389,10 @@ public abstract class ScriptFunctionData implements Serializable {
...
@@ -389,9 +389,10 @@ public abstract class ScriptFunctionData implements Serializable {
/**
/**
* Get the property map to use for objects allocated by this function.
* Get the property map to use for objects allocated by this function.
*
*
* @param prototype the prototype of the allocated object
* @return the property map for allocated objects.
* @return the property map for allocated objects.
*/
*/
PropertyMap
getAllocatorMap
()
{
PropertyMap
getAllocatorMap
(
final
ScriptObject
prototype
)
{
return
null
;
return
null
;
}
}
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java
浏览文件 @
b642e31e
...
@@ -809,9 +809,11 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -809,9 +809,11 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
if
(
deep
)
{
if
(
deep
)
{
final
ScriptObject
myProto
=
getProto
();
final
ScriptObject
myProto
=
getProto
();
if
(
myProto
!=
null
)
{
final
FindProperty
find
=
myProto
==
null
?
null
:
myProto
.
findProperty
(
key
,
true
,
start
);
return
myProto
.
findProperty
(
key
,
deep
,
start
);
// checkSharedProtoMap must be invoked after myProto.checkSharedProtoMap to propagate
}
// shared proto invalidation up the prototype chain. It also must be invoked when prototype is null.
checkSharedProtoMap
();
return
find
;
}
}
return
null
;
return
null
;
...
@@ -832,7 +834,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -832,7 +834,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
if
(
deep
)
{
if
(
deep
)
{
final
ScriptObject
myProto
=
getProto
();
final
ScriptObject
myProto
=
getProto
();
if
(
myProto
!=
null
)
{
if
(
myProto
!=
null
)
{
return
myProto
.
hasProperty
(
key
,
deep
);
return
myProto
.
hasProperty
(
key
,
true
);
}
}
}
}
...
@@ -1258,11 +1260,8 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -1258,11 +1260,8 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
if
(
oldProto
!=
newProto
)
{
if
(
oldProto
!=
newProto
)
{
proto
=
newProto
;
proto
=
newProto
;
// Let current listeners know that the prototype has changed and set our map
// Let current listeners know that the prototype has changed
final
PropertyListeners
listeners
=
getMap
().
getListeners
();
getMap
().
protoChanged
(
true
);
if
(
listeners
!=
null
)
{
listeners
.
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
));
}
}
...
@@ -1314,7 +1313,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -1314,7 +1313,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
}
}
p
=
p
.
getProto
();
p
=
p
.
getProto
();
}
}
setProto
((
ScriptObject
)
newProto
);
setProto
((
ScriptObject
)
newProto
);
}
else
{
}
else
{
throw
typeError
(
"cant.set.proto.to.non.object"
,
ScriptRuntime
.
safeToString
(
this
),
ScriptRuntime
.
safeToString
(
newProto
));
throw
typeError
(
"cant.set.proto.to.non.object"
,
ScriptRuntime
.
safeToString
(
this
),
ScriptRuntime
.
safeToString
(
newProto
));
}
}
...
@@ -2012,11 +2011,11 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2012,11 +2011,11 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
final
ScriptObject
owner
=
find
.
getOwner
();
final
ScriptObject
owner
=
find
.
getOwner
();
final
Class
<
ClassCastException
>
exception
=
explicitInstanceOfCheck
?
null
:
ClassCastException
.
class
;
final
Class
<
ClassCastException
>
exception
=
explicitInstanceOfCheck
?
null
:
ClassCastException
.
class
;
final
SwitchPoint
protoSwitchPoint
;
final
SwitchPoint
[]
protoSwitchPoints
;
if
(
mh
==
null
)
{
if
(
mh
==
null
)
{
mh
=
Lookup
.
emptyGetter
(
returnType
);
mh
=
Lookup
.
emptyGetter
(
returnType
);
protoSwitchPoint
=
getProtoSwitchPoint
(
name
,
owner
);
protoSwitchPoint
s
=
getProtoSwitchPoints
(
name
,
owner
);
}
else
if
(!
find
.
isSelf
())
{
}
else
if
(!
find
.
isSelf
())
{
assert
mh
.
type
().
returnType
().
equals
(
returnType
)
:
assert
mh
.
type
().
returnType
().
equals
(
returnType
)
:
"return type mismatch for getter "
+
mh
.
type
().
returnType
()
+
" != "
+
returnType
;
"return type mismatch for getter "
+
mh
.
type
().
returnType
()
+
" != "
+
returnType
;
...
@@ -2024,12 +2023,12 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2024,12 +2023,12 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
// Add a filter that replaces the self object with the prototype owning the property.
// Add a filter that replaces the self object with the prototype owning the property.
mh
=
addProtoFilter
(
mh
,
find
.
getProtoChainLength
());
mh
=
addProtoFilter
(
mh
,
find
.
getProtoChainLength
());
}
}
protoSwitchPoint
=
getProtoSwitchPoint
(
name
,
owner
);
protoSwitchPoint
s
=
getProtoSwitchPoints
(
name
,
owner
);
}
else
{
}
else
{
protoSwitchPoint
=
null
;
protoSwitchPoint
s
=
null
;
}
}
final
GuardedInvocation
inv
=
new
GuardedInvocation
(
mh
,
guard
,
protoSwitchPoint
,
exception
);
final
GuardedInvocation
inv
=
new
GuardedInvocation
(
mh
,
guard
,
protoSwitchPoint
s
,
exception
);
return
inv
.
addSwitchPoint
(
findBuiltinSwitchPoint
(
name
));
return
inv
.
addSwitchPoint
(
findBuiltinSwitchPoint
(
name
));
}
}
...
@@ -2128,17 +2127,32 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2128,17 +2127,32 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
* @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 SwitchPoint or null
*/
*/
public
final
SwitchPoint
getProtoSwitchPoint
(
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
<>();
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
();
final
ScriptObject
parent
=
obj
.
getProto
();
parent
.
getMap
().
addListener
(
name
,
obj
.
getMap
());
parent
.
getMap
().
addListener
(
name
,
obj
.
getMap
());
final
SwitchPoint
sp
=
parent
.
getMap
().
getSharedProtoSwitchPoint
();
if
(
sp
!=
null
&&
!
sp
.
hasBeenInvalidated
())
{
switchPoints
.
add
(
sp
);
}
}
switchPoints
.
add
(
getMap
().
getSwitchPoint
(
name
));
return
switchPoints
.
toArray
(
new
SwitchPoint
[
switchPoints
.
size
()]);
}
}
return
getMap
().
getSwitchPoint
(
name
);
private
void
checkSharedProtoMap
()
{
// Check if our map has an expected shared prototype property map. If it has, make sure that
// the prototype map has not been invalidated, and that it does match the actual map of the prototype.
if
(
getMap
().
isInvalidSharedMapFor
(
getProto
()))
{
// Change our own map to one that does not assume a shared prototype map.
setMap
(
getMap
().
makeUnsharedCopy
());
}
}
}
/**
/**
...
@@ -2220,7 +2234,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2220,7 +2234,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return
new
GuardedInvocation
(
return
new
GuardedInvocation
(
Lookup
.
EMPTY_SETTER
,
Lookup
.
EMPTY_SETTER
,
NashornGuards
.
getMapGuard
(
getMap
(),
explicitInstanceOfCheck
),
NashornGuards
.
getMapGuard
(
getMap
(),
explicitInstanceOfCheck
),
getProtoSwitchPoint
(
name
,
null
),
getProtoSwitchPoint
s
(
name
,
null
),
explicitInstanceOfCheck
?
null
:
ClassCastException
.
class
);
explicitInstanceOfCheck
?
null
:
ClassCastException
.
class
);
}
}
...
@@ -2366,7 +2380,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2366,7 +2380,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
find
.
getGetter
(
Object
.
class
,
INVALID_PROGRAM_POINT
,
request
),
find
.
getGetter
(
Object
.
class
,
INVALID_PROGRAM_POINT
,
request
),
find
.
getProtoChainLength
(),
find
.
getProtoChainLength
(),
func
),
func
),
getProtoSwitchPoint
(
NO_SUCH_PROPERTY_NAME
,
find
.
getOwner
()),
getProtoSwitchPoint
s
(
NO_SUCH_PROPERTY_NAME
,
find
.
getOwner
()),
//TODO this doesn't need a ClassCastException as guard always checks script object
//TODO this doesn't need a ClassCastException as guard always checks script object
null
);
null
);
}
}
...
@@ -2438,7 +2452,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2438,7 +2452,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
}
}
return
new
GuardedInvocation
(
Lookup
.
emptyGetter
(
desc
.
getMethodType
().
returnType
()),
return
new
GuardedInvocation
(
Lookup
.
emptyGetter
(
desc
.
getMethodType
().
returnType
()),
NashornGuards
.
getMapGuard
(
getMap
(),
explicitInstanceOfCheck
),
getProtoSwitchPoint
(
name
,
null
),
NashornGuards
.
getMapGuard
(
getMap
(),
explicitInstanceOfCheck
),
getProtoSwitchPoint
s
(
name
,
null
),
explicitInstanceOfCheck
?
null
:
ClassCastException
.
class
);
explicitInstanceOfCheck
?
null
:
ClassCastException
.
class
);
}
}
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java
浏览文件 @
b642e31e
...
@@ -186,10 +186,7 @@ final class SetMethodCreator {
...
@@ -186,10 +186,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
);
final
PropertyListeners
listeners
=
map
.
getListeners
();
map
.
propertyAdded
(
sm
.
property
,
true
);
if
(
listeners
!=
null
)
{
listeners
.
propertyAdded
(
sm
.
property
);
}
return
sm
;
return
sm
;
}
}
...
@@ -204,7 +201,7 @@ final class SetMethodCreator {
...
@@ -204,7 +201,7 @@ final class SetMethodCreator {
//fast type specific setter
//fast type specific setter
final
MethodHandle
fastSetter
=
property
.
getSetter
(
type
,
newMap
);
//0 sobj, 1 value, slot folded for spill property already
final
MethodHandle
fastSetter
=
property
.
getSetter
(
type
,
newMap
);
//0 sobj, 1 value, slot folded for spill property already
//slow setter, that calls ScriptObject.set with appropr
ai
te type and key name
//slow setter, that calls ScriptObject.set with appropr
ia
te type and key name
MethodHandle
slowSetter
=
ScriptObject
.
SET_SLOW
[
getAccessorTypeIndex
(
type
)];
MethodHandle
slowSetter
=
ScriptObject
.
SET_SLOW
[
getAccessorTypeIndex
(
type
)];
slowSetter
=
MH
.
insertArguments
(
slowSetter
,
3
,
NashornCallSiteDescriptor
.
getFlags
(
desc
));
slowSetter
=
MH
.
insertArguments
(
slowSetter
,
3
,
NashornCallSiteDescriptor
.
getFlags
(
desc
));
slowSetter
=
MH
.
insertArguments
(
slowSetter
,
1
,
name
);
slowSetter
=
MH
.
insertArguments
(
slowSetter
,
1
,
name
);
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SharedPropertyMap.java
0 → 100644
浏览文件 @
b642e31e
/*
* Copyright (c) 2015, 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
;
/**
* This class represents a property map that can be shared among multiple prototype objects, allowing all inheriting
* top-level objects to also share one property map. This is class is only used for prototype objects, the
* top-level objects use ordinary {@link PropertyMap}s with the {@link PropertyMap#sharedProtoMap} field
* set to the expected shared prototype map.
*
* <p>When an instance of this class is evolved because a property is added, removed, or modified in an object
* using it, the {@link #invalidateSwitchPoint()} method is invoked to signal to all callsites and inheriting
* objects that the assumption of a single shared prototype map is no longer valid. The property map resulting
* from the modification will no longer be an instance of this class.</p>
*/
public
final
class
SharedPropertyMap
extends
PropertyMap
{
private
SwitchPoint
switchPoint
;
private
static
final
long
serialVersionUID
=
2166297719721778876L
;
/**
* Create a new shared property map from the given {@code map}.
* @param map property map to copy
*/
public
SharedPropertyMap
(
final
PropertyMap
map
)
{
super
(
map
);
this
.
switchPoint
=
new
SwitchPoint
();
}
@Override
public
void
propertyAdded
(
final
Property
property
,
final
boolean
isSelf
)
{
if
(
isSelf
)
{
invalidateSwitchPoint
();
}
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
synchronized
boolean
isValidSharedProtoMap
()
{
return
switchPoint
!=
null
;
}
@Override
synchronized
SwitchPoint
getSharedProtoSwitchPoint
()
{
return
switchPoint
;
}
/**
* Invalidate the shared prototype switch point if this is a shared prototype map.
*/
synchronized
void
invalidateSwitchPoint
()
{
if
(
switchPoint
!=
null
)
{
assert
!
switchPoint
.
hasBeenInvalidated
();
SwitchPoint
.
invalidateAll
(
new
SwitchPoint
[]{
switchPoint
});
switchPoint
=
null
;
}
}
}
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/WithObject.java
浏览文件 @
b642e31e
...
@@ -46,7 +46,7 @@ import jdk.nashorn.internal.runtime.linker.NashornGuards;
...
@@ -46,7 +46,7 @@ import jdk.nashorn.internal.runtime.linker.NashornGuards;
*
*
*/
*/
public
final
class
WithObject
extends
Scope
{
public
final
class
WithObject
extends
Scope
{
private
static
final
MethodHandle
WITHEXPRESSIONGUARD
=
findOwnMH
(
"withExpressionGuard"
,
boolean
.
class
,
Object
.
class
,
PropertyMap
.
class
,
SwitchPoint
.
class
);
private
static
final
MethodHandle
WITHEXPRESSIONGUARD
=
findOwnMH
(
"withExpressionGuard"
,
boolean
.
class
,
Object
.
class
,
PropertyMap
.
class
,
SwitchPoint
[]
.
class
);
private
static
final
MethodHandle
WITHEXPRESSIONFILTER
=
findOwnMH
(
"withFilterExpression"
,
Object
.
class
,
Object
.
class
);
private
static
final
MethodHandle
WITHEXPRESSIONFILTER
=
findOwnMH
(
"withFilterExpression"
,
Object
.
class
,
Object
.
class
);
private
static
final
MethodHandle
WITHSCOPEFILTER
=
findOwnMH
(
"withFilterScope"
,
Object
.
class
,
Object
.
class
);
private
static
final
MethodHandle
WITHSCOPEFILTER
=
findOwnMH
(
"withFilterScope"
,
Object
.
class
,
Object
.
class
);
private
static
final
MethodHandle
BIND_TO_EXPRESSION_OBJ
=
findOwnMH
(
"bindToExpression"
,
Object
.
class
,
Object
.
class
,
Object
.
class
);
private
static
final
MethodHandle
BIND_TO_EXPRESSION_OBJ
=
findOwnMH
(
"bindToExpression"
,
Object
.
class
,
Object
.
class
,
Object
.
class
);
...
@@ -360,13 +360,24 @@ public final class WithObject extends Scope {
...
@@ -360,13 +360,24 @@ public final class WithObject extends Scope {
private
MethodHandle
expressionGuard
(
final
String
name
,
final
ScriptObject
owner
)
{
private
MethodHandle
expressionGuard
(
final
String
name
,
final
ScriptObject
owner
)
{
final
PropertyMap
map
=
expression
.
getMap
();
final
PropertyMap
map
=
expression
.
getMap
();
final
SwitchPoint
sp
=
expression
.
getProtoSwitchPoint
(
name
,
owner
);
final
SwitchPoint
[]
sp
=
expression
.
getProtoSwitchPoints
(
name
,
owner
);
return
MH
.
insertArguments
(
WITHEXPRESSIONGUARD
,
1
,
map
,
sp
);
return
MH
.
insertArguments
(
WITHEXPRESSIONGUARD
,
1
,
map
,
sp
);
}
}
@SuppressWarnings
(
"unused"
)
@SuppressWarnings
(
"unused"
)
private
static
boolean
withExpressionGuard
(
final
Object
receiver
,
final
PropertyMap
map
,
final
SwitchPoint
sp
)
{
private
static
boolean
withExpressionGuard
(
final
Object
receiver
,
final
PropertyMap
map
,
final
SwitchPoint
[]
sp
)
{
return
((
WithObject
)
receiver
).
expression
.
getMap
()
==
map
&&
(
sp
==
null
||
!
sp
.
hasBeenInvalidated
());
return
((
WithObject
)
receiver
).
expression
.
getMap
()
==
map
&&
!
hasBeenInvalidated
(
sp
);
}
private
static
boolean
hasBeenInvalidated
(
final
SwitchPoint
[]
switchPoints
)
{
if
(
switchPoints
!=
null
)
{
for
(
final
SwitchPoint
switchPoint
:
switchPoints
)
{
if
(
switchPoint
.
hasBeenInvalidated
())
{
return
true
;
}
}
}
return
false
;
}
}
/**
/**
...
...
nashorn/test/script/basic/JDK-8134569.js
浏览文件 @
b642e31e
...
@@ -62,67 +62,146 @@ function createDeep() {
...
@@ -62,67 +62,146 @@ function createDeep() {
return
new
C
();
return
new
C
();
}
}
function
createDeeper
()
{
function
C
()
{
this
.
i1
=
1
;
this
.
i2
=
2
;
this
.
i3
=
3
;
return
this
;
}
function
D
()
{
this
.
p1
=
1
;
this
.
p2
=
2
;
this
.
p3
=
3
;
return
this
;
}
function
E
()
{
this
.
e1
=
1
;
this
.
e2
=
2
;
this
.
e3
=
3
;
return
this
;
}
D
.
prototype
=
new
E
();
C
.
prototype
=
new
D
();
return
new
C
();
}
function
createEval
()
{
function
createEval
()
{
return
eval
(
"
Object.create({})
"
);
return
eval
(
"
Object.create({})
"
);
}
}
function
p
(
o
)
{
print
(
o
.
x
)
}
function
p
(
o
)
{
print
(
o
.
x
)
}
var
a
,
b
;
function
e
(
o
)
{
print
(
o
.
e1
)
}
var
a
,
b
,
c
;
create
();
create
();
a
=
create
();
a
=
create
();
b
=
create
();
b
=
create
();
c
=
create
();
a
.
__proto__
.
x
=
123
;
a
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
a
);
p
(
b
);
p
(
b
);
p
(
c
);
a
=
create
();
a
=
create
();
b
=
create
();
b
=
create
();
c
=
create
();
b
.
__proto__
.
x
=
123
;
b
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
a
);
p
(
b
);
p
(
b
);
p
(
c
);
a
=
createEmpty
();
a
=
createEmpty
();
b
=
createEmpty
();
b
=
createEmpty
();
c
=
createEmpty
();
a
.
__proto__
.
x
=
123
;
a
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
a
);
p
(
b
);
p
(
b
);
p
(
c
);
a
=
createEmpty
();
a
=
createEmpty
();
b
=
createEmpty
();
b
=
createEmpty
();
c
=
createEmpty
();
b
.
__proto__
.
x
=
123
;
b
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
a
);
p
(
b
);
p
(
b
);
p
(
c
);
a
=
createDeep
();
a
=
createDeep
();
b
=
createDeep
();
b
=
createDeep
();
c
=
createDeep
();
a
.
__proto__
.
__proto__
.
x
=
123
;
a
.
__proto__
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
a
);
p
(
b
);
p
(
b
);
p
(
c
);
a
=
createDeep
();
a
=
createDeep
();
b
=
createDeep
();
b
=
createDeep
();
c
=
createDeep
();
b
.
__proto__
.
__proto__
.
x
=
123
;
b
.
__proto__
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
a
);
p
(
b
);
p
(
b
);
p
(
c
);
a
=
createDeeper
();
b
=
createDeeper
();
c
=
createDeeper
();
a
.
__proto__
.
__proto__
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
b
);
p
(
c
);
a
=
createDeeper
();
b
=
createDeeper
();
c
=
createDeeper
();
b
.
__proto__
.
__proto__
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
b
);
p
(
c
);
a
=
createDeeper
();
b
=
createDeeper
();
c
=
createDeeper
();
a
.
__proto__
.
__proto__
=
null
;
e
(
a
);
e
(
b
);
e
(
c
);
a
=
createDeeper
();
b
=
createDeeper
();
c
=
createDeeper
();
b
.
__proto__
.
__proto__
=
null
;
e
(
a
);
e
(
b
);
e
(
c
);
a
=
createEval
();
a
=
createEval
();
b
=
createEval
();
b
=
createEval
();
c
=
createEval
();
a
.
__proto__
.
x
=
123
;
a
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
a
);
p
(
b
);
p
(
b
);
p
(
c
);
a
=
createEval
();
a
=
createEval
();
b
=
createEval
();
b
=
createEval
();
c
=
createEval
();
b
.
__proto__
.
x
=
123
;
b
.
__proto__
.
x
=
123
;
p
(
a
);
p
(
a
);
p
(
b
);
p
(
b
);
p
(
c
);
nashorn/test/script/basic/JDK-8134569.js.EXPECTED
浏览文件 @
b642e31e
123
123
undefined
undefined
undefined
undefined
undefined
123
undefined
123
undefined
undefined
undefined
123
123
undefined
123
123
undefined
undefined
undefined
undefined
undefined
123
123
undefined
123
123
undefined
undefined
undefined
undefined
undefined
123
123
undefined
undefined
1
1
1
undefined
1
123
123
undefined
undefined
undefined
undefined
undefined
123
123
undefined
nashorn/test/script/basic/JDK-8134609.js
0 → 100644
浏览文件 @
b642e31e
/*
* Copyright (c) 2015, 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.
*/
/**
* JDK-8134609: Allow constructors with same prototoype map to share the allocator map
*
* @test
* @run
* @fork
* @option -Dnashorn.debug
*/
function
createProto
(
members
)
{
function
P
()
{
for
(
var
id
in
members
)
{
if
(
members
.
hasOwnProperty
(
id
))
{
this
[
id
]
=
members
[
id
];
}
}
return
this
;
}
return
new
P
();
}
function
createSubclass
(
prototype
,
members
)
{
function
C
()
{
for
(
var
id
in
members
)
{
if
(
members
.
hasOwnProperty
(
id
))
{
this
[
id
]
=
members
[
id
];
}
}
return
this
;
}
C
.
prototype
=
prototype
;
return
new
C
();
}
function
assertP1
(
object
,
value
)
{
Assert
.
assertTrue
(
object
.
p1
===
value
);
}
// First prototype will have non-shared proto-map. Second and third will be shared.
var
proto0
=
createProto
({
p1
:
0
,
p2
:
1
});
var
proto1
=
createProto
({
p1
:
1
,
p2
:
2
});
var
proto2
=
createProto
({
p1
:
2
,
p2
:
3
});
Assert
.
assertTrue
(
Debug
.
map
(
proto1
)
===
Debug
.
map
(
proto2
));
assertP1
(
proto1
,
1
);
assertP1
(
proto2
,
2
);
// First instantiation will have a non-shared prototype map, from the second one
// maps will be shared until a different proto map comes along.
var
child0
=
createSubclass
(
proto1
,
{
c1
:
1
,
c2
:
2
});
var
child1
=
createSubclass
(
proto2
,
{
c1
:
2
,
c2
:
3
});
var
child2
=
createSubclass
(
proto1
,
{
c1
:
3
,
c2
:
4
});
var
child3
=
createSubclass
(
proto2
,
{
c1
:
1
,
c2
:
2
});
var
child4
=
createSubclass
(
proto0
,
{
c1
:
3
,
c2
:
2
});
Assert
.
assertTrue
(
Debug
.
map
(
child1
)
===
Debug
.
map
(
child2
));
Assert
.
assertTrue
(
Debug
.
map
(
child1
)
===
Debug
.
map
(
child3
));
Assert
.
assertTrue
(
Debug
.
map
(
child3
)
!==
Debug
.
map
(
child4
));
assertP1
(
child1
,
2
);
assertP1
(
child2
,
1
);
assertP1
(
child3
,
2
);
assertP1
(
child4
,
0
);
Assert
.
assertTrue
(
delete
proto2
.
p1
);
assertP1
(
child3
,
undefined
);
assertP1
(
child2
,
1
);
Assert
.
assertTrue
(
Debug
.
map
(
child1
)
!==
Debug
.
map
(
child3
));
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录