Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
86e077f0
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,发现更多精彩内容 >>
提交
86e077f0
编写于
4月 10, 2015
作者:
H
hannesw
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8067215: Disable dual fields when not using optimistic types
Reviewed-by: attila, lagergren
上级
ffaedbb3
变更
30
显示空白变更内容
内联
并排
Showing
30 changed file
with
534 addition
and
264 deletion
+534
-264
nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java
...jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java
+0
-2
nashorn/docs/DEVELOPER_README
nashorn/docs/DEVELOPER_README
+13
-10
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java
...e/classes/jdk/nashorn/internal/codegen/CodeGenerator.java
+11
-4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilerConstants.java
...asses/jdk/nashorn/internal/codegen/CompilerConstants.java
+5
-2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java
...sses/jdk/nashorn/internal/codegen/FieldObjectCreator.java
+4
-4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FindScopeDepths.java
...classes/jdk/nashorn/internal/codegen/FindScopeDepths.java
+1
-1
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MapCreator.java
...hare/classes/jdk/nashorn/internal/codegen/MapCreator.java
+11
-7
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MapTuple.java
.../share/classes/jdk/nashorn/internal/codegen/MapTuple.java
+2
-4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
...es/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
+48
-54
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectCreator.java
...e/classes/jdk/nashorn/internal/codegen/ObjectCreator.java
+1
-1
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java
...sses/jdk/nashorn/internal/codegen/SpillObjectCreator.java
+31
-22
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java
...rn/share/classes/jdk/nashorn/internal/objects/Global.java
+10
-4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java
...classes/jdk/nashorn/internal/objects/NativeJSAdapter.java
+1
-1
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/JSONParser.java
...share/classes/jdk/nashorn/internal/parser/JSONParser.java
+21
-11
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java
...lasses/jdk/nashorn/internal/runtime/AccessorProperty.java
+18
-19
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AllocationStrategy.java
...sses/jdk/nashorn/internal/runtime/AllocationStrategy.java
+7
-2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java
...n/share/classes/jdk/nashorn/internal/runtime/Context.java
+34
-1
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSONFunctions.java
...e/classes/jdk/nashorn/internal/runtime/JSONFunctions.java
+2
-1
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java
...rn/share/classes/jdk/nashorn/internal/runtime/JSType.java
+0
-5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java
.../share/classes/jdk/nashorn/internal/runtime/Property.java
+17
-26
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
...are/classes/jdk/nashorn/internal/runtime/PropertyMap.java
+10
-1
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java
...re/classes/jdk/nashorn/internal/runtime/ScriptObject.java
+33
-47
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java
...lasses/jdk/nashorn/internal/runtime/SetMethodCreator.java
+6
-2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SpillProperty.java
...e/classes/jdk/nashorn/internal/runtime/SpillProperty.java
+8
-10
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java
...classes/jdk/nashorn/internal/runtime/StructureLoader.java
+34
-7
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java
...lasses/jdk/nashorn/internal/runtime/linker/Bootstrap.java
+6
-7
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornGuards.java
...es/jdk/nashorn/internal/runtime/linker/NashornGuards.java
+1
-2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/scripts/JD.java
...ashorn/share/classes/jdk/nashorn/internal/scripts/JD.java
+88
-0
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/scripts/JO.java
...ashorn/share/classes/jdk/nashorn/internal/scripts/JO.java
+7
-7
nashorn/test/script/nosecurity/JDK-8067215.js
nashorn/test/script/nosecurity/JDK-8067215.js
+104
-0
未找到文件。
nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java
浏览文件 @
86e077f0
...
@@ -124,8 +124,6 @@ public class PrototypeGenerator extends ClassGenerator {
...
@@ -124,8 +124,6 @@ public class PrototypeGenerator extends ClassGenerator {
if
(
memberCount
>
0
)
{
if
(
memberCount
>
0
)
{
// call "super(map$)"
// call "super(map$)"
mi
.
getStatic
(
className
,
PROPERTYMAP_FIELD_NAME
,
PROPERTYMAP_DESC
);
mi
.
getStatic
(
className
,
PROPERTYMAP_FIELD_NAME
,
PROPERTYMAP_DESC
);
// make sure we use duplicated PropertyMap so that original map
// stays intact and so can be used for many global.
mi
.
invokeSpecial
(
PROTOTYPEOBJECT_TYPE
,
INIT
,
SCRIPTOBJECT_INIT_DESC
);
mi
.
invokeSpecial
(
PROTOTYPEOBJECT_TYPE
,
INIT
,
SCRIPTOBJECT_INIT_DESC
);
// initialize Function type fields
// initialize Function type fields
initFunctionFields
(
mi
);
initFunctionFields
(
mi
);
...
...
nashorn/docs/DEVELOPER_README
浏览文件 @
86e077f0
...
@@ -63,16 +63,19 @@ SYSTEM PROPERTY: -Dnashorn.codegen.debug.trace=<x>
...
@@ -63,16 +63,19 @@ SYSTEM PROPERTY: -Dnashorn.codegen.debug.trace=<x>
See the description of the codegen logger below.
See the description of the codegen logger below.
SYSTEM PROPERTY: -Dnashorn.fields.objects
SYSTEM PROPERTY: -Dnashorn.fields.objects, -Dnashorn.fields.dual
When this property is true, Nashorn will only use object fields for
When the nashorn.fields.objects property is true, Nashorn will always
AccessorProperties. This means that primitive values must be boxed
use object fields for AccessorProperties, requiring boxing for all
when stored in a field, which is significantly slower than using
primitive property values. When nashorn.fields.dual is set, Nashorn
primitive fields.
will always use dual long/object fields, which allows primitives to be
stored without boxing. When neither system property is set, Nashorn
By default, Nashorn uses dual object and long fields. Ints are
chooses a setting depending on the optimistic types setting (dual
represented as the 32 low bits of the long fields. Doubles are
fields when optimistic types are enabled, object-only fields otherwise).
represented as the doubleToLongBits of their value. This way a
With dual fields, Nashorn uses long fields to store primitive values.
Ints are represented as the 32 low bits of the long fields. Doubles
are represented as the doubleToLongBits of their value. This way a
single field can be used for all primitive types. Packing and
single field can be used for all primitive types. Packing and
unpacking doubles to their bit representation is intrinsified by
unpacking doubles to their bit representation is intrinsified by
the JVM and extremely fast.
the JVM and extremely fast.
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java
浏览文件 @
86e077f0
...
@@ -43,7 +43,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
...
@@ -43,7 +43,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
staticCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
staticCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
typeDescriptor
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
typeDescriptor
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
virtualCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
virtualCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
;
import
static
jdk
.
nashorn
.
internal
.
ir
.
Symbol
.
HAS_SLOT
;
import
static
jdk
.
nashorn
.
internal
.
ir
.
Symbol
.
HAS_SLOT
;
import
static
jdk
.
nashorn
.
internal
.
ir
.
Symbol
.
IS_INTERNAL
;
import
static
jdk
.
nashorn
.
internal
.
ir
.
Symbol
.
IS_INTERNAL
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
UnwarrantedOptimismException
.
INVALID_PROGRAM_POINT
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
UnwarrantedOptimismException
.
INVALID_PROGRAM_POINT
;
...
@@ -305,6 +304,14 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
...
@@ -305,6 +304,14 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
return
evalCode
;
return
evalCode
;
}
}
/**
* Are we using dual primitive/object field representation?
* @return true if using dual field representation, false for object-only fields
*/
boolean
useDualFields
()
{
return
compiler
.
getContext
().
useDualFields
();
}
/**
/**
* Load an identity node
* Load an identity node
*
*
...
@@ -1896,10 +1903,10 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
...
@@ -1896,10 +1903,10 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
//this symbol will be put fielded, we can't initialize it as undefined with a known type
//this symbol will be put fielded, we can't initialize it as undefined with a known type
@Override
@Override
public
Class
<?>
getValueType
()
{
public
Class
<?>
getValueType
()
{
if
(
OBJECT_FIELDS_ONLY
||
value
==
null
||
paramType
==
null
)
{
if
(
!
useDualFields
()
||
value
==
null
||
paramType
==
null
||
paramType
.
isBoolean
()
)
{
return
Object
.
class
;
return
Object
.
class
;
}
}
return
paramType
.
isBoolean
()
?
Object
.
class
:
paramType
.
getTypeClass
();
return
paramType
.
getTypeClass
();
}
}
});
});
}
}
...
@@ -2555,7 +2562,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
...
@@ -2555,7 +2562,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
//for literals, a value of null means object type, i.e. the value null or getter setter function
//for literals, a value of null means object type, i.e. the value null or getter setter function
//(I think)
//(I think)
final
Class
<?>
valueType
=
(
OBJECT_FIELDS_ONLY
||
value
==
null
||
value
.
getType
().
isBoolean
())
?
Object
.
class
:
value
.
getType
().
getTypeClass
();
final
Class
<?>
valueType
=
(
!
useDualFields
()
||
value
==
null
||
value
.
getType
().
isBoolean
())
?
Object
.
class
:
value
.
getType
().
getTypeClass
();
tuples
.
add
(
new
MapTuple
<
Expression
>(
key
,
symbol
,
Type
.
typeFor
(
valueType
),
value
)
{
tuples
.
add
(
new
MapTuple
<
Expression
>(
key
,
symbol
,
Type
.
typeFor
(
valueType
),
value
)
{
@Override
@Override
public
Class
<?>
getValueType
()
{
public
Class
<?>
getValueType
()
{
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilerConstants.java
浏览文件 @
86e077f0
...
@@ -149,8 +149,11 @@ public enum CompilerConstants {
...
@@ -149,8 +149,11 @@ public enum CompilerConstants {
/** Arguments parameter in scope object constructors; in slot 3 when present */
/** Arguments parameter in scope object constructors; in slot 3 when present */
INIT_ARGUMENTS
(
null
,
3
),
INIT_ARGUMENTS
(
null
,
3
),
/** prefix for all ScriptObject subclasses with fields, @see ObjectGenerator */
/** prefix for all ScriptObject subclasses with dual object/primitive fields, see {@link ObjectClassGenerator} */
JS_OBJECT_PREFIX
(
"JO"
),
JS_OBJECT_DUAL_FIELD_PREFIX
(
"JD"
),
/** prefix for all ScriptObject subclasses with object fields only, see {@link ObjectClassGenerator} */
JS_OBJECT_SINGLE_FIELD_PREFIX
(
"JO"
),
/** name for allocate method in JO objects */
/** name for allocate method in JO objects */
ALLOCATE
(
"allocate"
),
ALLOCATE
(
"allocate"
),
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java
浏览文件 @
86e077f0
...
@@ -151,7 +151,7 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
...
@@ -151,7 +151,7 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
@Override
@Override
protected
PropertyMap
makeMap
()
{
protected
PropertyMap
makeMap
()
{
assert
propertyMap
==
null
:
"property map already initialized"
;
assert
propertyMap
==
null
:
"property map already initialized"
;
propertyMap
=
newMapCreator
(
fieldObjectClass
).
makeFieldMap
(
hasArguments
(),
fieldCount
,
paddedFieldCount
,
evalCode
);
propertyMap
=
newMapCreator
(
fieldObjectClass
).
makeFieldMap
(
hasArguments
(),
codegen
.
useDualFields
(),
fieldCount
,
paddedFieldCount
,
evalCode
);
return
propertyMap
;
return
propertyMap
;
}
}
...
@@ -166,7 +166,7 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
...
@@ -166,7 +166,7 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
private
void
putField
(
final
MethodEmitter
method
,
final
String
key
,
final
int
fieldIndex
,
final
MapTuple
<
T
>
tuple
)
{
private
void
putField
(
final
MethodEmitter
method
,
final
String
key
,
final
int
fieldIndex
,
final
MapTuple
<
T
>
tuple
)
{
method
.
dup
();
method
.
dup
();
final
Type
fieldType
=
tuple
.
isPrimitive
()
?
PRIMITIVE_FIELD_TYPE
:
Type
.
OBJECT
;
final
Type
fieldType
=
codegen
.
useDualFields
()
&&
tuple
.
isPrimitive
()
?
PRIMITIVE_FIELD_TYPE
:
Type
.
OBJECT
;
final
String
fieldClass
=
getClassName
();
final
String
fieldClass
=
getClassName
();
final
String
fieldName
=
getFieldName
(
fieldIndex
,
fieldType
);
final
String
fieldName
=
getFieldName
(
fieldIndex
,
fieldType
);
final
String
fieldDesc
=
typeDescriptor
(
fieldType
.
getTypeClass
());
final
String
fieldDesc
=
typeDescriptor
(
fieldType
.
getTypeClass
());
...
@@ -202,8 +202,8 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
...
@@ -202,8 +202,8 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
*/
*/
private
void
findClass
()
{
private
void
findClass
()
{
fieldObjectClassName
=
isScope
()
?
fieldObjectClassName
=
isScope
()
?
ObjectClassGenerator
.
getClassName
(
fieldCount
,
paramCount
)
:
ObjectClassGenerator
.
getClassName
(
fieldCount
,
paramCount
,
codegen
.
useDualFields
()
)
:
ObjectClassGenerator
.
getClassName
(
paddedFieldCount
);
ObjectClassGenerator
.
getClassName
(
paddedFieldCount
,
codegen
.
useDualFields
()
);
try
{
try
{
this
.
fieldObjectClass
=
Context
.
forStructureClass
(
Compiler
.
binaryName
(
fieldObjectClassName
));
this
.
fieldObjectClass
=
Context
.
forStructureClass
(
Compiler
.
binaryName
(
fieldObjectClassName
));
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FindScopeDepths.java
浏览文件 @
86e077f0
...
@@ -207,7 +207,7 @@ final class FindScopeDepths extends NodeVisitor<LexicalContext> implements Logga
...
@@ -207,7 +207,7 @@ final class FindScopeDepths extends NodeVisitor<LexicalContext> implements Logga
final
RecompilableScriptFunctionData
data
=
new
RecompilableScriptFunctionData
(
final
RecompilableScriptFunctionData
data
=
new
RecompilableScriptFunctionData
(
newFunctionNode
,
newFunctionNode
,
compiler
.
getCodeInstaller
(),
compiler
.
getCodeInstaller
(),
ObjectClassGenerator
.
createAllocationStrategy
(
newFunctionNode
.
getThisProperties
()),
ObjectClassGenerator
.
createAllocationStrategy
(
newFunctionNode
.
getThisProperties
()
,
compiler
.
getContext
().
useDualFields
()
),
nestedFunctions
,
nestedFunctions
,
externalSymbolDepths
.
get
(
fnId
),
externalSymbolDepths
.
get
(
fnId
),
internalSymbols
.
get
(
fnId
),
internalSymbols
.
get
(
fnId
),
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MapCreator.java
浏览文件 @
86e077f0
...
@@ -68,17 +68,17 @@ public class MapCreator<T> {
...
@@ -68,17 +68,17 @@ public class MapCreator<T> {
* @param evalCode is this property map created for 'eval' code?
* @param evalCode is this property map created for 'eval' code?
* @return New map populated with accessor properties.
* @return New map populated with accessor properties.
*/
*/
PropertyMap
makeFieldMap
(
final
boolean
hasArguments
,
final
int
fieldCount
,
final
int
fieldMaximum
,
final
boolean
evalCode
)
{
PropertyMap
makeFieldMap
(
final
boolean
hasArguments
,
final
boolean
dualFields
,
final
int
fieldCount
,
final
int
fieldMaximum
,
final
boolean
evalCode
)
{
final
List
<
Property
>
properties
=
new
ArrayList
<>();
final
List
<
Property
>
properties
=
new
ArrayList
<>();
assert
tuples
!=
null
;
assert
tuples
!=
null
;
for
(
final
MapTuple
<
T
>
tuple
:
tuples
)
{
for
(
final
MapTuple
<
T
>
tuple
:
tuples
)
{
final
String
key
=
tuple
.
key
;
final
String
key
=
tuple
.
key
;
final
Symbol
symbol
=
tuple
.
symbol
;
final
Symbol
symbol
=
tuple
.
symbol
;
final
Class
<?>
initialType
=
tuple
.
getValueType
()
;
final
Class
<?>
initialType
=
dualFields
?
tuple
.
getValueType
()
:
Object
.
class
;
if
(
symbol
!=
null
&&
!
isValidArrayIndex
(
getArrayIndex
(
key
)))
{
if
(
symbol
!=
null
&&
!
isValidArrayIndex
(
getArrayIndex
(
key
)))
{
final
int
flags
=
getPropertyFlags
(
symbol
,
hasArguments
,
evalCode
);
final
int
flags
=
getPropertyFlags
(
symbol
,
hasArguments
,
evalCode
,
dualFields
);
final
Property
property
=
new
AccessorProperty
(
final
Property
property
=
new
AccessorProperty
(
key
,
key
,
flags
,
flags
,
...
@@ -92,7 +92,7 @@ public class MapCreator<T> {
...
@@ -92,7 +92,7 @@ public class MapCreator<T> {
return
PropertyMap
.
newMap
(
properties
,
structure
.
getName
(),
fieldCount
,
fieldMaximum
,
0
);
return
PropertyMap
.
newMap
(
properties
,
structure
.
getName
(),
fieldCount
,
fieldMaximum
,
0
);
}
}
PropertyMap
makeSpillMap
(
final
boolean
hasArguments
)
{
PropertyMap
makeSpillMap
(
final
boolean
hasArguments
,
final
boolean
dualFields
)
{
final
List
<
Property
>
properties
=
new
ArrayList
<>();
final
List
<
Property
>
properties
=
new
ArrayList
<>();
int
spillIndex
=
0
;
int
spillIndex
=
0
;
assert
tuples
!=
null
;
assert
tuples
!=
null
;
...
@@ -100,10 +100,10 @@ public class MapCreator<T> {
...
@@ -100,10 +100,10 @@ public class MapCreator<T> {
for
(
final
MapTuple
<
T
>
tuple
:
tuples
)
{
for
(
final
MapTuple
<
T
>
tuple
:
tuples
)
{
final
String
key
=
tuple
.
key
;
final
String
key
=
tuple
.
key
;
final
Symbol
symbol
=
tuple
.
symbol
;
final
Symbol
symbol
=
tuple
.
symbol
;
final
Class
<?>
initialType
=
tuple
.
getValueType
()
;
final
Class
<?>
initialType
=
dualFields
?
tuple
.
getValueType
()
:
Object
.
class
;
if
(
symbol
!=
null
&&
!
isValidArrayIndex
(
getArrayIndex
(
key
)))
{
if
(
symbol
!=
null
&&
!
isValidArrayIndex
(
getArrayIndex
(
key
)))
{
final
int
flags
=
getPropertyFlags
(
symbol
,
hasArguments
,
false
);
final
int
flags
=
getPropertyFlags
(
symbol
,
hasArguments
,
false
,
dualFields
);
properties
.
add
(
properties
.
add
(
new
SpillProperty
(
new
SpillProperty
(
key
,
key
,
...
@@ -124,7 +124,7 @@ public class MapCreator<T> {
...
@@ -124,7 +124,7 @@ public class MapCreator<T> {
*
*
* @return flags to use for fields
* @return flags to use for fields
*/
*/
static
int
getPropertyFlags
(
final
Symbol
symbol
,
final
boolean
hasArguments
,
final
boolean
evalCode
)
{
static
int
getPropertyFlags
(
final
Symbol
symbol
,
final
boolean
hasArguments
,
final
boolean
evalCode
,
final
boolean
dualFields
)
{
int
flags
=
0
;
int
flags
=
0
;
if
(
symbol
.
isParam
())
{
if
(
symbol
.
isParam
())
{
...
@@ -162,6 +162,10 @@ public class MapCreator<T> {
...
@@ -162,6 +162,10 @@ public class MapCreator<T> {
flags
|=
Property
.
NEEDS_DECLARATION
;
flags
|=
Property
.
NEEDS_DECLARATION
;
}
}
if
(
dualFields
)
{
flags
|=
Property
.
DUAL_FIELDS
;
}
return
flags
;
return
flags
;
}
}
}
}
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MapTuple.java
浏览文件 @
86e077f0
...
@@ -25,8 +25,6 @@
...
@@ -25,8 +25,6 @@
package
jdk.nashorn.internal.codegen
;
package
jdk.nashorn.internal.codegen
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
;
import
jdk.nashorn.internal.codegen.types.Type
;
import
jdk.nashorn.internal.codegen.types.Type
;
import
jdk.nashorn.internal.ir.Symbol
;
import
jdk.nashorn.internal.ir.Symbol
;
...
@@ -52,11 +50,11 @@ class MapTuple<T> {
...
@@ -52,11 +50,11 @@ class MapTuple<T> {
}
}
public
Class
<?>
getValueType
()
{
public
Class
<?>
getValueType
()
{
return
OBJECT_FIELDS_ONLY
?
Object
.
class
:
null
;
//until proven otherwise we are undefined, see NASHORN-592 int.class;
return
null
;
//until proven otherwise we are undefined, see NASHORN-592 int.class;
}
}
boolean
isPrimitive
()
{
boolean
isPrimitive
()
{
return
!
OBJECT_FIELDS_ONLY
&&
getValueType
().
isPrimitive
()
&&
getValueType
()
!=
boolean
.
class
;
return
getValueType
()
!=
null
&&
getValueType
().
isPrimitive
()
&&
getValueType
()
!=
boolean
.
class
;
}
}
@Override
@Override
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
浏览文件 @
86e077f0
...
@@ -31,7 +31,8 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_ARGUMENTS;
...
@@ -31,7 +31,8 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_ARGUMENTS;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
INIT_MAP
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
INIT_MAP
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
INIT_SCOPE
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
INIT_SCOPE
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
JAVA_THIS
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
JAVA_THIS
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
JS_OBJECT_PREFIX
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
JS_OBJECT_DUAL_FIELD_PREFIX
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
JS_OBJECT_SINGLE_FIELD_PREFIX
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
className
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
className
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
constructorNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
constructorNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
lookup
.
Lookup
.
MH
;
import
static
jdk
.
nashorn
.
internal
.
lookup
.
Lookup
.
MH
;
...
@@ -99,18 +100,10 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -99,18 +100,10 @@ public final class ObjectClassGenerator implements Loggable {
*/
*/
private
final
DebugLogger
log
;
private
final
DebugLogger
log
;
/**
/** Field types for object-only fields */
* Should the runtime only use java.lang.Object slots for fields? If this is false, the representation
private
static
final
Type
[]
FIELD_TYPES_OBJECT
=
new
Type
[]
{
Type
.
OBJECT
};
* will be a primitive 64-bit long value used for all primitives and a java.lang.Object for references.
/** Field types for dual primitive/object fields */
* This introduces a larger number of method handles in the system, as we need to have different getters
private
static
final
Type
[]
FIELD_TYPES_DUAL
=
new
Type
[]
{
Type
.
LONG
,
Type
.
OBJECT
};
* and setters for the different fields.
*
* This is engineered to plug into the TaggedArray implementation, when it's done.
*/
public
static
final
boolean
OBJECT_FIELDS_ONLY
=
Options
.
getBooleanProperty
(
"nashorn.fields.objects"
);
/** The field types in the system */
private
static
final
List
<
Type
>
FIELD_TYPES
=
new
LinkedList
<>();
/** What type is the primitive type in dual representation */
/** What type is the primitive type in dual representation */
public
static
final
Type
PRIMITIVE_FIELD_TYPE
=
Type
.
LONG
;
public
static
final
Type
PRIMITIVE_FIELD_TYPE
=
Type
.
LONG
;
...
@@ -118,33 +111,27 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -118,33 +111,27 @@ public final class ObjectClassGenerator implements Loggable {
private
static
final
MethodHandle
GET_DIFFERENT
=
findOwnMH
(
"getDifferent"
,
Object
.
class
,
Object
.
class
,
Class
.
class
,
MethodHandle
.
class
,
MethodHandle
.
class
,
int
.
class
);
private
static
final
MethodHandle
GET_DIFFERENT
=
findOwnMH
(
"getDifferent"
,
Object
.
class
,
Object
.
class
,
Class
.
class
,
MethodHandle
.
class
,
MethodHandle
.
class
,
int
.
class
);
private
static
final
MethodHandle
GET_DIFFERENT_UNDEFINED
=
findOwnMH
(
"getDifferentUndefined"
,
Object
.
class
,
int
.
class
);
private
static
final
MethodHandle
GET_DIFFERENT_UNDEFINED
=
findOwnMH
(
"getDifferentUndefined"
,
Object
.
class
,
int
.
class
);
/**
* The list of field types that we support - one type creates one field. This is currently either
* LONG + OBJECT or just OBJECT for classic mode.
*/
static
{
if
(!
OBJECT_FIELDS_ONLY
)
{
FIELD_TYPES
.
add
(
PRIMITIVE_FIELD_TYPE
);
}
FIELD_TYPES
.
add
(
Type
.
OBJECT
);
}
private
static
boolean
initialized
=
false
;
private
static
boolean
initialized
=
false
;
/** The context */
/** The context */
private
final
Context
context
;
private
final
Context
context
;
private
final
boolean
dualFields
;
/**
/**
* Constructor
* Constructor
*
*
* @param context a context
* @param context a context
* @param dualFields whether to use dual fields representation
*/
*/
public
ObjectClassGenerator
(
final
Context
context
)
{
public
ObjectClassGenerator
(
final
Context
context
,
final
boolean
dualFields
)
{
this
.
context
=
context
;
this
.
context
=
context
;
this
.
dualFields
=
dualFields
;
assert
context
!=
null
;
assert
context
!=
null
;
this
.
log
=
initLogger
(
context
);
this
.
log
=
initLogger
(
context
);
if
(!
initialized
)
{
if
(!
initialized
)
{
initialized
=
true
;
initialized
=
true
;
if
(
OBJECT_FIELDS_ONLY
)
{
if
(
!
dualFields
)
{
log
.
warning
(
"Running with object fields only - this is a deprecated configuration."
);
log
.
warning
(
"Running with object fields only - this is a deprecated configuration."
);
}
}
}
}
...
@@ -176,16 +163,30 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -176,16 +163,30 @@ public final class ObjectClassGenerator implements Loggable {
throw
new
AssertionError
(
"cannot pack"
+
n
);
throw
new
AssertionError
(
"cannot pack"
+
n
);
}
}
private
static
String
getPrefixName
(
final
boolean
dualFields
)
{
return
dualFields
?
JS_OBJECT_DUAL_FIELD_PREFIX
.
symbolName
()
:
JS_OBJECT_SINGLE_FIELD_PREFIX
.
symbolName
();
}
private
static
String
getPrefixName
(
final
String
className
)
{
if
(
className
.
startsWith
(
JS_OBJECT_DUAL_FIELD_PREFIX
.
symbolName
()))
{
return
getPrefixName
(
true
);
}
else
if
(
className
.
startsWith
(
JS_OBJECT_SINGLE_FIELD_PREFIX
.
symbolName
()))
{
return
getPrefixName
(
false
);
}
throw
new
AssertionError
(
"Not a structure class: "
+
className
);
}
/**
/**
* Returns the class name for JavaScript objects with fieldCount fields.
* Returns the class name for JavaScript objects with fieldCount fields.
*
*
* @param fieldCount Number of fields to allocate.
* @param fieldCount Number of fields to allocate.
*
*
@param dualFields whether to use dual fields representation
* @return The class name.
* @return The class name.
*/
*/
public
static
String
getClassName
(
final
int
fieldCount
)
{
public
static
String
getClassName
(
final
int
fieldCount
,
final
boolean
dualFields
)
{
return
fieldCount
!=
0
?
SCRIPTS_PACKAGE
+
'/'
+
JS_OBJECT_PREFIX
.
symbolName
()
+
fieldCount
:
final
String
prefix
=
getPrefixName
(
dualFields
);
SCRIPTS_PACKAGE
+
'/'
+
JS_OBJECT_PREFIX
.
symbolName
();
return
fieldCount
!=
0
?
SCRIPTS_PACKAGE
+
'/'
+
prefix
+
fieldCount
:
SCRIPTS_PACKAGE
+
'/'
+
prefix
;
}
}
/**
/**
...
@@ -194,22 +195,23 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -194,22 +195,23 @@ public final class ObjectClassGenerator implements Loggable {
*
*
* @param fieldCount Number of fields to allocate.
* @param fieldCount Number of fields to allocate.
* @param paramCount Number of parameters to allocate
* @param paramCount Number of parameters to allocate
*
*
@param dualFields whether to use dual fields representation
* @return The class name.
* @return The class name.
*/
*/
public
static
String
getClassName
(
final
int
fieldCount
,
final
int
paramCount
)
{
public
static
String
getClassName
(
final
int
fieldCount
,
final
int
paramCount
,
final
boolean
dualFields
)
{
return
SCRIPTS_PACKAGE
+
'/'
+
JS_OBJECT_PREFIX
.
symbolName
(
)
+
fieldCount
+
SCOPE_MARKER
+
paramCount
;
return
SCRIPTS_PACKAGE
+
'/'
+
getPrefixName
(
dualFields
)
+
fieldCount
+
SCOPE_MARKER
+
paramCount
;
}
}
/**
/**
* Returns the number of fields in the JavaScript scope class. Its name had to be generated using either
* Returns the number of fields in the JavaScript scope class. Its name had to be generated using either
* {@link #getClassName(int
)} or {@link #getClassName(int, int
)}.
* {@link #getClassName(int
, boolean)} or {@link #getClassName(int, int, boolean
)}.
* @param clazz the JavaScript scope class.
* @param clazz the JavaScript scope class.
* @return the number of fields in the scope class.
* @return the number of fields in the scope class.
*/
*/
public
static
int
getFieldCount
(
final
Class
<?>
clazz
)
{
public
static
int
getFieldCount
(
final
Class
<?>
clazz
)
{
final
String
name
=
clazz
.
getSimpleName
();
final
String
name
=
clazz
.
getSimpleName
();
final
String
prefix
=
JS_OBJECT_PREFIX
.
symbolName
();
final
String
prefix
=
getPrefixName
(
name
);
if
(
prefix
.
equals
(
name
))
{
if
(
prefix
.
equals
(
name
))
{
return
0
;
return
0
;
}
}
...
@@ -238,8 +240,8 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -238,8 +240,8 @@ public final class ObjectClassGenerator implements Loggable {
* @param className name of class
* @param className name of class
* @param fieldNames fields to initialize to undefined, where applicable
* @param fieldNames fields to initialize to undefined, where applicable
*/
*/
private
static
void
initializeToUndefined
(
final
MethodEmitter
init
,
final
String
className
,
final
List
<
String
>
fieldNames
)
{
private
void
initializeToUndefined
(
final
MethodEmitter
init
,
final
String
className
,
final
List
<
String
>
fieldNames
)
{
if
(
!
OBJECT_FIELDS_ONLY
)
{
if
(
dualFields
)
{
// no need to initialize anything to undefined in the dual field world
// no need to initialize anything to undefined in the dual field world
// - then we have a constant getter for undefined for any unknown type
// - then we have a constant getter for undefined for any unknown type
return
;
return
;
...
@@ -292,7 +294,7 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -292,7 +294,7 @@ public final class ObjectClassGenerator implements Loggable {
* @return Byte codes for generated class.
* @return Byte codes for generated class.
*/
*/
public
byte
[]
generate
(
final
int
fieldCount
)
{
public
byte
[]
generate
(
final
int
fieldCount
)
{
final
String
className
=
getClassName
(
fieldCount
);
final
String
className
=
getClassName
(
fieldCount
,
dualFields
);
final
String
superName
=
className
(
ScriptObject
.
class
);
final
String
superName
=
className
(
ScriptObject
.
class
);
final
ClassEmitter
classEmitter
=
newClassEmitter
(
className
,
superName
);
final
ClassEmitter
classEmitter
=
newClassEmitter
(
className
,
superName
);
...
@@ -322,7 +324,7 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -322,7 +324,7 @@ public final class ObjectClassGenerator implements Loggable {
* @return Byte codes for generated class.
* @return Byte codes for generated class.
*/
*/
public
byte
[]
generate
(
final
int
fieldCount
,
final
int
paramCount
)
{
public
byte
[]
generate
(
final
int
fieldCount
,
final
int
paramCount
)
{
final
String
className
=
getClassName
(
fieldCount
,
paramCount
);
final
String
className
=
getClassName
(
fieldCount
,
paramCount
,
dualFields
);
final
String
superName
=
className
(
FunctionScope
.
class
);
final
String
superName
=
className
(
FunctionScope
.
class
);
final
ClassEmitter
classEmitter
=
newClassEmitter
(
className
,
superName
);
final
ClassEmitter
classEmitter
=
newClassEmitter
(
className
,
superName
);
final
List
<
String
>
initFields
=
addFields
(
classEmitter
,
fieldCount
);
final
List
<
String
>
initFields
=
addFields
(
classEmitter
,
fieldCount
);
...
@@ -353,11 +355,11 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -353,11 +355,11 @@ public final class ObjectClassGenerator implements Loggable {
*
*
* @return List fields that need to be initialized.
* @return List fields that need to be initialized.
*/
*/
private
static
List
<
String
>
addFields
(
final
ClassEmitter
classEmitter
,
final
int
fieldCount
)
{
private
List
<
String
>
addFields
(
final
ClassEmitter
classEmitter
,
final
int
fieldCount
)
{
final
List
<
String
>
initFields
=
new
LinkedList
<>();
final
List
<
String
>
initFields
=
new
LinkedList
<>();
final
Type
[]
fieldTypes
=
dualFields
?
FIELD_TYPES_DUAL
:
FIELD_TYPES_OBJECT
;
for
(
int
i
=
0
;
i
<
fieldCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
fieldCount
;
i
++)
{
for
(
final
Type
type
:
FIELD_TYPES
)
{
for
(
final
Type
type
:
fieldTypes
)
{
final
String
fieldName
=
getFieldName
(
i
,
type
);
final
String
fieldName
=
getFieldName
(
i
,
type
);
classEmitter
.
field
(
fieldName
,
type
.
getTypeClass
());
classEmitter
.
field
(
fieldName
,
type
.
getTypeClass
());
...
@@ -533,13 +535,10 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -533,13 +535,10 @@ public final class ObjectClassGenerator implements Loggable {
private
static
MethodHandle
getterForType
(
final
Class
<?>
forType
,
final
MethodHandle
primitiveGetter
,
final
MethodHandle
objectGetter
)
{
private
static
MethodHandle
getterForType
(
final
Class
<?>
forType
,
final
MethodHandle
primitiveGetter
,
final
MethodHandle
objectGetter
)
{
switch
(
getAccessorTypeIndex
(
forType
))
{
switch
(
getAccessorTypeIndex
(
forType
))
{
case
TYPE_INT_INDEX:
case
TYPE_INT_INDEX:
assert
!
OBJECT_FIELDS_ONLY
:
"this can only happen with dual fields"
;
return
MH
.
explicitCastArguments
(
primitiveGetter
,
primitiveGetter
.
type
().
changeReturnType
(
int
.
class
));
return
MH
.
explicitCastArguments
(
primitiveGetter
,
primitiveGetter
.
type
().
changeReturnType
(
int
.
class
));
case
TYPE_LONG_INDEX:
case
TYPE_LONG_INDEX:
assert
!
OBJECT_FIELDS_ONLY
:
"this can only happen with dual fields"
;
return
primitiveGetter
;
return
primitiveGetter
;
case
TYPE_DOUBLE_INDEX:
case
TYPE_DOUBLE_INDEX:
assert
!
OBJECT_FIELDS_ONLY
:
"this can only happen with dual fields"
;
return
MH
.
filterReturnValue
(
primitiveGetter
,
UNPACK_DOUBLE
);
return
MH
.
filterReturnValue
(
primitiveGetter
,
UNPACK_DOUBLE
);
case
TYPE_OBJECT_INDEX:
case
TYPE_OBJECT_INDEX:
return
objectGetter
;
return
objectGetter
;
...
@@ -557,7 +556,7 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -557,7 +556,7 @@ public final class ObjectClassGenerator implements Loggable {
final
boolean
isPrimitiveStorage
=
forType
!=
null
&&
forType
.
isPrimitive
();
final
boolean
isPrimitiveStorage
=
forType
!=
null
&&
forType
.
isPrimitive
();
//which is the primordial getter
//which is the primordial getter
final
MethodHandle
getter
=
OBJECT_FIELDS_ONLY
?
objectGetter
:
isPrimitiveStorage
?
primitiveGetter
:
objectGetter
;
final
MethodHandle
getter
=
primitiveGetter
==
null
?
objectGetter
:
isPrimitiveStorage
?
primitiveGetter
:
objectGetter
;
if
(
forType
==
null
)
{
if
(
forType
==
null
)
{
if
(
isOptimistic
)
{
if
(
isOptimistic
)
{
...
@@ -580,8 +579,7 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -580,8 +579,7 @@ public final class ObjectClassGenerator implements Loggable {
return
MH
.
dropArguments
(
GET_UNDEFINED
.
get
(
ti
),
0
,
Object
.
class
);
return
MH
.
dropArguments
(
GET_UNDEFINED
.
get
(
ti
),
0
,
Object
.
class
);
}
}
assert
forType
!=
null
;
assert
primitiveGetter
!=
null
||
forType
==
Object
.
class
:
forType
;
assert
!
OBJECT_FIELDS_ONLY
||
forType
==
Object
.
class
:
forType
;
if
(
isOptimistic
)
{
if
(
isOptimistic
)
{
if
(
fti
<
ti
)
{
if
(
fti
<
ti
)
{
...
@@ -635,8 +633,6 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -635,8 +633,6 @@ public final class ObjectClassGenerator implements Loggable {
return
tgetter
;
return
tgetter
;
}
}
assert
!
OBJECT_FIELDS_ONLY
;
//final MethodType pmt = primitiveGetter.type();
assert
primitiveGetter
!=
null
;
assert
primitiveGetter
!=
null
;
final
MethodType
tgetterType
=
tgetter
.
type
();
final
MethodType
tgetterType
=
tgetter
.
type
();
switch
(
fti
)
{
switch
(
fti
)
{
...
@@ -727,7 +723,7 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -727,7 +723,7 @@ public final class ObjectClassGenerator implements Loggable {
final
int
fti
=
getAccessorTypeIndex
(
forType
);
final
int
fti
=
getAccessorTypeIndex
(
forType
);
final
int
ti
=
getAccessorTypeIndex
(
type
);
final
int
ti
=
getAccessorTypeIndex
(
type
);
if
(
fti
==
TYPE_OBJECT_INDEX
||
OBJECT_FIELDS_ONLY
)
{
if
(
fti
==
TYPE_OBJECT_INDEX
||
primitiveSetter
==
null
)
{
if
(
ti
==
TYPE_OBJECT_INDEX
)
{
if
(
ti
==
TYPE_OBJECT_INDEX
)
{
return
objectSetter
;
return
objectSetter
;
}
}
...
@@ -735,8 +731,6 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -735,8 +731,6 @@ public final class ObjectClassGenerator implements Loggable {
return
MH
.
asType
(
objectSetter
,
objectSetter
.
type
().
changeParameterType
(
1
,
type
));
return
MH
.
asType
(
objectSetter
,
objectSetter
.
type
().
changeParameterType
(
1
,
type
));
}
}
assert
!
OBJECT_FIELDS_ONLY
;
final
MethodType
pmt
=
primitiveSetter
.
type
();
final
MethodType
pmt
=
primitiveSetter
.
type
();
switch
(
fti
)
{
switch
(
fti
)
{
...
@@ -832,8 +826,8 @@ public final class ObjectClassGenerator implements Loggable {
...
@@ -832,8 +826,8 @@ public final class ObjectClassGenerator implements Loggable {
* @param thisProperties number of properties assigned to "this"
* @param thisProperties number of properties assigned to "this"
* @return the allocation strategy
* @return the allocation strategy
*/
*/
static
AllocationStrategy
createAllocationStrategy
(
final
int
thisProperties
)
{
static
AllocationStrategy
createAllocationStrategy
(
final
int
thisProperties
,
final
boolean
dualFields
)
{
final
int
paddedFieldCount
=
getPaddedFieldCount
(
thisProperties
);
final
int
paddedFieldCount
=
getPaddedFieldCount
(
thisProperties
);
return
new
AllocationStrategy
(
paddedFieldCount
);
return
new
AllocationStrategy
(
paddedFieldCount
,
dualFields
);
}
}
}
}
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectCreator.java
浏览文件 @
86e077f0
...
@@ -134,7 +134,7 @@ public abstract class ObjectCreator<T> {
...
@@ -134,7 +134,7 @@ public abstract class ObjectCreator<T> {
MethodEmitter
loadTuple
(
final
MethodEmitter
method
,
final
MapTuple
<
T
>
tuple
,
final
boolean
pack
)
{
MethodEmitter
loadTuple
(
final
MethodEmitter
method
,
final
MapTuple
<
T
>
tuple
,
final
boolean
pack
)
{
loadValue
(
tuple
.
value
,
tuple
.
type
);
loadValue
(
tuple
.
value
,
tuple
.
type
);
if
(
pack
&&
tuple
.
isPrimitive
())
{
if
(
pack
&&
codegen
.
useDualFields
()
&&
tuple
.
isPrimitive
())
{
method
.
pack
();
method
.
pack
();
}
else
{
}
else
{
method
.
convert
(
Type
.
OBJECT
);
method
.
convert
(
Type
.
OBJECT
);
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java
浏览文件 @
86e077f0
...
@@ -27,7 +27,6 @@ package jdk.nashorn.internal.codegen;
...
@@ -27,7 +27,6 @@ package jdk.nashorn.internal.codegen;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
constructorNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
constructorNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
virtualCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
virtualCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
;
import
java.util.LinkedHashSet
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.List
;
...
@@ -42,6 +41,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
...
@@ -42,6 +41,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
import
jdk.nashorn.internal.runtime.ScriptRuntime
;
import
jdk.nashorn.internal.runtime.ScriptRuntime
;
import
jdk.nashorn.internal.runtime.arrays.ArrayData
;
import
jdk.nashorn.internal.runtime.arrays.ArrayData
;
import
jdk.nashorn.internal.runtime.arrays.ArrayIndex
;
import
jdk.nashorn.internal.runtime.arrays.ArrayIndex
;
import
jdk.nashorn.internal.scripts.JD
;
import
jdk.nashorn.internal.scripts.JO
;
import
jdk.nashorn.internal.scripts.JO
;
/**
/**
...
@@ -65,10 +65,13 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
...
@@ -65,10 +65,13 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
assert
!
isScope
()
:
"spill scope objects are not currently supported"
;
assert
!
isScope
()
:
"spill scope objects are not currently supported"
;
final
int
length
=
tuples
.
size
();
final
int
length
=
tuples
.
size
();
final
long
[]
jpresetValues
=
new
long
[
ScriptObject
.
spillAllocationLength
(
length
)];
final
boolean
dualFields
=
codegen
.
useDualFields
();
final
Object
[]
opresetValues
=
new
Object
[
ScriptObject
.
spillAllocationLength
(
length
)];
final
int
spillLength
=
ScriptObject
.
spillAllocationLength
(
length
);
final
long
[]
jpresetValues
=
dualFields
?
new
long
[
spillLength
]
:
null
;
final
Object
[]
opresetValues
=
new
Object
[
spillLength
];
final
Set
<
Integer
>
postsetValues
=
new
LinkedHashSet
<>();
final
Set
<
Integer
>
postsetValues
=
new
LinkedHashSet
<>();
final
int
callSiteFlags
=
codegen
.
getCallSiteFlags
();
final
int
callSiteFlags
=
codegen
.
getCallSiteFlags
();
final
Class
<?>
objectClass
=
dualFields
?
JD
.
class
:
JO
.
class
;
ArrayData
arrayData
=
ArrayData
.
allocate
(
ScriptRuntime
.
EMPTY_ARRAY
);
ArrayData
arrayData
=
ArrayData
.
allocate
(
ScriptRuntime
.
EMPTY_ARRAY
);
// Compute constant property values
// Compute constant property values
...
@@ -88,9 +91,9 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
...
@@ -88,9 +91,9 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
final
Property
property
=
propertyMap
.
findProperty
(
key
);
final
Property
property
=
propertyMap
.
findProperty
(
key
);
if
(
property
!=
null
)
{
if
(
property
!=
null
)
{
// normal property key
// normal property key
property
.
setType
(
JSType
.
unboxedFieldType
(
constantValue
)
);
property
.
setType
(
dualFields
?
JSType
.
unboxedFieldType
(
constantValue
)
:
Object
.
class
);
final
int
slot
=
property
.
getSlot
();
final
int
slot
=
property
.
getSlot
();
if
(
!
OBJECT_FIELDS_ONLY
&&
constantValue
instanceof
Number
)
{
if
(
dualFields
&&
constantValue
instanceof
Number
)
{
jpresetValues
[
slot
]
=
ObjectClassGenerator
.
pack
((
Number
)
constantValue
);
jpresetValues
[
slot
]
=
ObjectClassGenerator
.
pack
((
Number
)
constantValue
);
}
else
{
}
else
{
opresetValues
[
slot
]
=
constantValue
;
opresetValues
[
slot
]
=
constantValue
;
...
@@ -130,10 +133,11 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
...
@@ -130,10 +133,11 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
//assert postsetValues.isEmpty() : "test me " + postsetValues;
//assert postsetValues.isEmpty() : "test me " + postsetValues;
// create object and invoke constructor
// create object and invoke constructor
method
.
_new
(
JO
.
c
lass
).
dup
();
method
.
_new
(
objectC
lass
).
dup
();
codegen
.
loadConstant
(
propertyMap
);
codegen
.
loadConstant
(
propertyMap
);
//load primitive values to j spill array
//load primitive values to j spill array
if
(
dualFields
)
{
codegen
.
loadConstant
(
jpresetValues
);
codegen
.
loadConstant
(
jpresetValues
);
for
(
final
int
i
:
postsetValues
)
{
for
(
final
int
i
:
postsetValues
)
{
final
MapTuple
<
Expression
>
tuple
=
tuples
.
get
(
i
);
final
MapTuple
<
Expression
>
tuple
=
tuples
.
get
(
i
);
...
@@ -145,13 +149,16 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
...
@@ -145,13 +149,16 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
method
.
arraystore
();
method
.
arraystore
();
}
}
}
}
}
else
{
method
.
loadNull
();
}
//load object values to o spill array
//load object values to o spill array
codegen
.
loadConstant
(
opresetValues
);
codegen
.
loadConstant
(
opresetValues
);
for
(
final
int
i
:
postsetValues
)
{
for
(
final
int
i
:
postsetValues
)
{
final
MapTuple
<
Expression
>
tuple
=
tuples
.
get
(
i
);
final
MapTuple
<
Expression
>
tuple
=
tuples
.
get
(
i
);
final
Property
property
=
propertyMap
.
findProperty
(
tuple
.
key
);
final
Property
property
=
propertyMap
.
findProperty
(
tuple
.
key
);
if
(
property
!=
null
&&
!
tuple
.
isPrimitive
(
))
{
if
(
property
!=
null
&&
(!
dualFields
||
!
tuple
.
isPrimitive
()
))
{
method
.
dup
();
method
.
dup
();
method
.
load
(
property
.
getSlot
());
method
.
load
(
property
.
getSlot
());
loadTuple
(
method
,
tuple
);
loadTuple
(
method
,
tuple
);
...
@@ -160,7 +167,7 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
...
@@ -160,7 +167,7 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
}
}
//instantiate the script object with spill objects
//instantiate the script object with spill objects
method
.
invoke
(
constructorNoLookup
(
JO
.
c
lass
,
PropertyMap
.
class
,
long
[].
class
,
Object
[].
class
));
method
.
invoke
(
constructorNoLookup
(
objectC
lass
,
PropertyMap
.
class
,
long
[].
class
,
Object
[].
class
));
// Set prefix array data if any
// Set prefix array data if any
if
(
arrayData
.
length
()
>
0
)
{
if
(
arrayData
.
length
()
>
0
)
{
...
@@ -188,7 +195,9 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
...
@@ -188,7 +195,9 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
@Override
@Override
protected
PropertyMap
makeMap
()
{
protected
PropertyMap
makeMap
()
{
assert
propertyMap
==
null
:
"property map already initialized"
;
assert
propertyMap
==
null
:
"property map already initialized"
;
propertyMap
=
new
MapCreator
<>(
JO
.
class
,
tuples
).
makeSpillMap
(
false
);
final
boolean
dualFields
=
codegen
.
useDualFields
();
final
Class
<?
extends
ScriptObject
>
clazz
=
dualFields
?
JD
.
class
:
JO
.
class
;
propertyMap
=
new
MapCreator
<>(
clazz
,
tuples
).
makeSpillMap
(
false
,
codegen
.
useDualFields
());
return
propertyMap
;
return
propertyMap
;
}
}
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java
浏览文件 @
86e077f0
...
@@ -79,6 +79,7 @@ import jdk.nashorn.internal.runtime.linker.Bootstrap;
...
@@ -79,6 +79,7 @@ import jdk.nashorn.internal.runtime.linker.Bootstrap;
import
jdk.nashorn.internal.runtime.linker.InvokeByName
;
import
jdk.nashorn.internal.runtime.linker.InvokeByName
;
import
jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor
;
import
jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor
;
import
jdk.nashorn.internal.runtime.regexp.RegExpResult
;
import
jdk.nashorn.internal.runtime.regexp.RegExpResult
;
import
jdk.nashorn.internal.scripts.JD
;
import
jdk.nashorn.internal.scripts.JO
;
import
jdk.nashorn.internal.scripts.JO
;
import
jdk.nashorn.tools.ShellFunctions
;
import
jdk.nashorn.tools.ShellFunctions
;
...
@@ -750,6 +751,11 @@ public final class Global extends ScriptObject implements Scope {
...
@@ -750,6 +751,11 @@ public final class Global extends ScriptObject implements Scope {
return
context
;
return
context
;
}
}
@Override
protected
boolean
useDualFields
()
{
return
context
.
useDualFields
();
}
// performs initialization checks for Global constructor and returns the
// performs initialization checks for Global constructor and returns the
// PropertyMap, if everything is fine.
// PropertyMap, if everything is fine.
private
static
PropertyMap
checkAndGetMap
(
final
Context
context
)
{
private
static
PropertyMap
checkAndGetMap
(
final
Context
context
)
{
...
@@ -933,7 +939,7 @@ public final class Global extends ScriptObject implements Scope {
...
@@ -933,7 +939,7 @@ public final class Global extends ScriptObject implements Scope {
* @return the new ScriptObject
* @return the new ScriptObject
*/
*/
public
ScriptObject
newObject
()
{
public
ScriptObject
newObject
()
{
return
new
JO
(
getObjectPrototype
(),
JO
.
getInitialMap
());
return
useDualFields
()
?
new
JD
(
getObjectPrototype
())
:
new
JO
(
getObjectPrototype
());
}
}
/**
/**
...
@@ -2744,8 +2750,8 @@ public final class Global extends ScriptObject implements Scope {
...
@@ -2744,8 +2750,8 @@ public final class Global extends ScriptObject implements Scope {
*/
*/
private
static
class
LexicalScope
extends
ScriptObject
{
private
static
class
LexicalScope
extends
ScriptObject
{
LexicalScope
(
final
ScriptObject
proto
)
{
LexicalScope
(
final
Global
global
)
{
super
(
proto
,
PropertyMap
.
newMap
());
super
(
global
,
PropertyMap
.
newMap
());
}
}
@Override
@Override
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java
浏览文件 @
86e077f0
...
@@ -160,7 +160,7 @@ public final class NativeJSAdapter extends ScriptObject {
...
@@ -160,7 +160,7 @@ public final class NativeJSAdapter extends ScriptObject {
}
}
private
static
ScriptObject
wrapAdaptee
(
final
ScriptObject
adaptee
)
{
private
static
ScriptObject
wrapAdaptee
(
final
ScriptObject
adaptee
)
{
return
new
JO
(
adaptee
,
JO
.
getInitialMap
()
);
return
new
JO
(
adaptee
);
}
}
@Override
@Override
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/JSONParser.java
浏览文件 @
86e077f0
...
@@ -41,6 +41,7 @@ import jdk.nashorn.internal.runtime.Source;
...
@@ -41,6 +41,7 @@ import jdk.nashorn.internal.runtime.Source;
import
jdk.nashorn.internal.runtime.SpillProperty
;
import
jdk.nashorn.internal.runtime.SpillProperty
;
import
jdk.nashorn.internal.runtime.arrays.ArrayData
;
import
jdk.nashorn.internal.runtime.arrays.ArrayData
;
import
jdk.nashorn.internal.runtime.arrays.ArrayIndex
;
import
jdk.nashorn.internal.runtime.arrays.ArrayIndex
;
import
jdk.nashorn.internal.scripts.JD
;
import
jdk.nashorn.internal.scripts.JO
;
import
jdk.nashorn.internal.scripts.JO
;
import
static
jdk
.
nashorn
.
internal
.
parser
.
TokenType
.
STRING
;
import
static
jdk
.
nashorn
.
internal
.
parser
.
TokenType
.
STRING
;
...
@@ -54,11 +55,10 @@ public class JSONParser {
...
@@ -54,11 +55,10 @@ public class JSONParser {
final
private
String
source
;
final
private
String
source
;
final
private
Global
global
;
final
private
Global
global
;
final
private
boolean
dualFields
;
final
int
length
;
final
int
length
;
int
pos
=
0
;
int
pos
=
0
;
private
static
PropertyMap
EMPTY_MAP
=
PropertyMap
.
newMap
();
private
static
final
int
EOF
=
-
1
;
private
static
final
int
EOF
=
-
1
;
private
static
final
String
TRUE
=
"true"
;
private
static
final
String
TRUE
=
"true"
;
...
@@ -74,10 +74,11 @@ public class JSONParser {
...
@@ -74,10 +74,11 @@ public class JSONParser {
* @param source the source
* @param source the source
* @param global the global object
* @param global the global object
*/
*/
public
JSONParser
(
final
String
source
,
final
Global
global
)
{
public
JSONParser
(
final
String
source
,
final
Global
global
,
final
boolean
dualFields
)
{
this
.
source
=
source
;
this
.
source
=
source
;
this
.
global
=
global
;
this
.
global
=
global
;
this
.
length
=
source
.
length
();
this
.
length
=
source
.
length
();
this
.
dualFields
=
dualFields
;
}
}
/**
/**
...
@@ -180,7 +181,7 @@ public class JSONParser {
...
@@ -180,7 +181,7 @@ public class JSONParser {
}
}
private
Object
parseObject
()
{
private
Object
parseObject
()
{
PropertyMap
propertyMap
=
EMPTY_MAP
;
PropertyMap
propertyMap
=
dualFields
?
JD
.
getInitialMap
()
:
JO
.
getInitialMap
()
;
ArrayData
arrayData
=
ArrayData
.
EMPTY_ARRAY
;
ArrayData
arrayData
=
ArrayData
.
EMPTY_ARRAY
;
final
ArrayList
<
Object
>
values
=
new
ArrayList
<>();
final
ArrayList
<
Object
>
values
=
new
ArrayList
<>();
int
state
=
STATE_EMPTY
;
int
state
=
STATE_EMPTY
;
...
@@ -241,36 +242,45 @@ public class JSONParser {
...
@@ -241,36 +242,45 @@ public class JSONParser {
return
newArrayData
.
set
(
index
,
value
,
false
);
return
newArrayData
.
set
(
index
,
value
,
false
);
}
}
private
static
PropertyMap
addObjectProperty
(
final
PropertyMap
propertyMap
,
final
List
<
Object
>
values
,
private
PropertyMap
addObjectProperty
(
final
PropertyMap
propertyMap
,
final
List
<
Object
>
values
,
final
String
id
,
final
Object
value
)
{
final
String
id
,
final
Object
value
)
{
final
Property
oldProperty
=
propertyMap
.
findProperty
(
id
);
final
Property
oldProperty
=
propertyMap
.
findProperty
(
id
);
final
PropertyMap
newMap
;
final
PropertyMap
newMap
;
final
Class
<?>
type
=
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
?
Object
.
class
:
getType
(
value
);
final
Class
<?>
type
;
final
int
flags
;
if
(
dualFields
)
{
type
=
getType
(
value
);
flags
=
Property
.
DUAL_FIELDS
;
}
else
{
type
=
Object
.
class
;
flags
=
0
;
}
if
(
oldProperty
!=
null
)
{
if
(
oldProperty
!=
null
)
{
values
.
set
(
oldProperty
.
getSlot
(),
value
);
values
.
set
(
oldProperty
.
getSlot
(),
value
);
newMap
=
propertyMap
.
replaceProperty
(
oldProperty
,
new
SpillProperty
(
id
,
0
,
oldProperty
.
getSlot
(),
type
));;
newMap
=
propertyMap
.
replaceProperty
(
oldProperty
,
new
SpillProperty
(
id
,
flags
,
oldProperty
.
getSlot
(),
type
));;
}
else
{
}
else
{
values
.
add
(
value
);
values
.
add
(
value
);
newMap
=
propertyMap
.
addProperty
(
new
SpillProperty
(
id
,
0
,
propertyMap
.
size
(),
type
));
newMap
=
propertyMap
.
addProperty
(
new
SpillProperty
(
id
,
flags
,
propertyMap
.
size
(),
type
));
}
}
return
newMap
;
return
newMap
;
}
}
private
Object
createObject
(
final
PropertyMap
propertyMap
,
final
List
<
Object
>
values
,
final
ArrayData
arrayData
)
{
private
Object
createObject
(
final
PropertyMap
propertyMap
,
final
List
<
Object
>
values
,
final
ArrayData
arrayData
)
{
final
long
[]
primitiveSpill
=
new
long
[
values
.
size
()]
;
final
long
[]
primitiveSpill
=
dualFields
?
new
long
[
values
.
size
()]
:
null
;
final
Object
[]
objectSpill
=
new
Object
[
values
.
size
()];
final
Object
[]
objectSpill
=
new
Object
[
values
.
size
()];
for
(
final
Property
property
:
propertyMap
.
getProperties
())
{
for
(
final
Property
property
:
propertyMap
.
getProperties
())
{
if
(
property
.
getType
()
==
Object
.
class
)
{
if
(
!
dualFields
||
property
.
getType
()
==
Object
.
class
)
{
objectSpill
[
property
.
getSlot
()]
=
values
.
get
(
property
.
getSlot
());
objectSpill
[
property
.
getSlot
()]
=
values
.
get
(
property
.
getSlot
());
}
else
{
}
else
{
primitiveSpill
[
property
.
getSlot
()]
=
ObjectClassGenerator
.
pack
((
Number
)
values
.
get
(
property
.
getSlot
()));
primitiveSpill
[
property
.
getSlot
()]
=
ObjectClassGenerator
.
pack
((
Number
)
values
.
get
(
property
.
getSlot
()));
}
}
}
}
final
ScriptObject
object
=
new
JO
(
propertyMap
,
primitiveSpill
,
objectSpill
);
final
ScriptObject
object
=
dualFields
?
new
JD
(
propertyMap
,
primitiveSpill
,
objectSpill
)
:
new
JO
(
propertyMap
,
null
,
objectSpill
);
object
.
setInitialProto
(
global
.
getObjectPrototype
());
object
.
setInitialProto
(
global
.
getObjectPrototype
());
object
.
setArray
(
arrayData
);
object
.
setArray
(
arrayData
);
return
object
;
return
object
;
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java
浏览文件 @
86e077f0
...
@@ -25,7 +25,6 @@
...
@@ -25,7 +25,6 @@
package
jdk.nashorn.internal.runtime
;
package
jdk.nashorn.internal.runtime
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
PRIMITIVE_FIELD_TYPE
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
PRIMITIVE_FIELD_TYPE
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
createGetter
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
createGetter
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
createSetter
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
createSetter
;
...
@@ -98,7 +97,7 @@ public class AccessorProperty extends Property {
...
@@ -98,7 +97,7 @@ public class AccessorProperty extends Property {
objectSetters
[
i
]
=
MH
.
asType
(
MH
.
setter
(
LOOKUP
,
structure
,
fieldName
,
typeClass
),
Lookup
.
SET_OBJECT_TYPE
);
objectSetters
[
i
]
=
MH
.
asType
(
MH
.
setter
(
LOOKUP
,
structure
,
fieldName
,
typeClass
),
Lookup
.
SET_OBJECT_TYPE
);
}
}
if
(!
OBJECT_FIELDS_ONLY
)
{
if
(!
StructureLoader
.
isSingleFieldStructure
(
structure
.
getName
())
)
{
for
(
int
i
=
0
;
i
<
fieldCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
fieldCount
;
i
++)
{
final
String
fieldNamePrimitive
=
getFieldName
(
i
,
PRIMITIVE_FIELD_TYPE
);
final
String
fieldNamePrimitive
=
getFieldName
(
i
,
PRIMITIVE_FIELD_TYPE
);
final
Class
<?>
typeClass
=
PRIMITIVE_FIELD_TYPE
.
getTypeClass
();
final
Class
<?>
typeClass
=
PRIMITIVE_FIELD_TYPE
.
getTypeClass
();
...
@@ -211,7 +210,7 @@ public class AccessorProperty extends Property {
...
@@ -211,7 +210,7 @@ public class AccessorProperty extends Property {
* @param setter the property setter or null if non writable, non configurable
* @param setter the property setter or null if non writable, non configurable
*/
*/
private
AccessorProperty
(
final
String
key
,
final
int
flags
,
final
int
slot
,
final
MethodHandle
getter
,
final
MethodHandle
setter
)
{
private
AccessorProperty
(
final
String
key
,
final
int
flags
,
final
int
slot
,
final
MethodHandle
getter
,
final
MethodHandle
setter
)
{
super
(
key
,
flags
|
IS_BUILTIN
|
(
getter
.
type
().
returnType
().
isPrimitive
()
?
IS_NASGEN_PRIMITIVE
:
0
),
slot
);
super
(
key
,
flags
|
IS_BUILTIN
|
DUAL_FIELDS
|
(
getter
.
type
().
returnType
().
isPrimitive
()
?
IS_NASGEN_PRIMITIVE
:
0
),
slot
);
assert
!
isSpill
();
assert
!
isSpill
();
// we don't need to prep the setters these will never be invalidated as this is a nasgen
// we don't need to prep the setters these will never be invalidated as this is a nasgen
...
@@ -221,9 +220,7 @@ public class AccessorProperty extends Property {
...
@@ -221,9 +220,7 @@ public class AccessorProperty extends Property {
final
Class
<?>
setterType
=
setter
==
null
?
null
:
setter
.
type
().
parameterType
(
1
);
final
Class
<?>
setterType
=
setter
==
null
?
null
:
setter
.
type
().
parameterType
(
1
);
assert
setterType
==
null
||
setterType
==
getterType
;
assert
setterType
==
null
||
setterType
==
getterType
;
if
(
OBJECT_FIELDS_ONLY
)
{
primitiveGetter
=
primitiveSetter
=
null
;
}
else
{
if
(
getterType
==
int
.
class
||
getterType
==
long
.
class
)
{
if
(
getterType
==
int
.
class
||
getterType
==
long
.
class
)
{
primitiveGetter
=
MH
.
asType
(
getter
,
Lookup
.
GET_PRIMITIVE_TYPE
);
primitiveGetter
=
MH
.
asType
(
getter
,
Lookup
.
GET_PRIMITIVE_TYPE
);
primitiveSetter
=
setter
==
null
?
null
:
MH
.
asType
(
setter
,
Lookup
.
SET_PRIMITIVE_TYPE
);
primitiveSetter
=
setter
==
null
?
null
:
MH
.
asType
(
setter
,
Lookup
.
SET_PRIMITIVE_TYPE
);
...
@@ -233,7 +230,6 @@ public class AccessorProperty extends Property {
...
@@ -233,7 +230,6 @@ public class AccessorProperty extends Property {
}
else
{
}
else
{
primitiveGetter
=
primitiveSetter
=
null
;
primitiveGetter
=
primitiveSetter
=
null
;
}
}
}
assert
primitiveGetter
==
null
||
primitiveGetter
.
type
()
==
Lookup
.
GET_PRIMITIVE_TYPE
:
primitiveGetter
+
"!="
+
Lookup
.
GET_PRIMITIVE_TYPE
;
assert
primitiveGetter
==
null
||
primitiveGetter
.
type
()
==
Lookup
.
GET_PRIMITIVE_TYPE
:
primitiveGetter
+
"!="
+
Lookup
.
GET_PRIMITIVE_TYPE
;
assert
primitiveSetter
==
null
||
primitiveSetter
.
type
()
==
Lookup
.
SET_PRIMITIVE_TYPE
:
primitiveSetter
;
assert
primitiveSetter
==
null
||
primitiveSetter
.
type
()
==
Lookup
.
SET_PRIMITIVE_TYPE
:
primitiveSetter
;
...
@@ -241,7 +237,7 @@ public class AccessorProperty extends Property {
...
@@ -241,7 +237,7 @@ public class AccessorProperty extends Property {
objectGetter
=
getter
.
type
()
!=
Lookup
.
GET_OBJECT_TYPE
?
MH
.
asType
(
getter
,
Lookup
.
GET_OBJECT_TYPE
)
:
getter
;
objectGetter
=
getter
.
type
()
!=
Lookup
.
GET_OBJECT_TYPE
?
MH
.
asType
(
getter
,
Lookup
.
GET_OBJECT_TYPE
)
:
getter
;
objectSetter
=
setter
!=
null
&&
setter
.
type
()
!=
Lookup
.
SET_OBJECT_TYPE
?
MH
.
asType
(
setter
,
Lookup
.
SET_OBJECT_TYPE
)
:
setter
;
objectSetter
=
setter
!=
null
&&
setter
.
type
()
!=
Lookup
.
SET_OBJECT_TYPE
?
MH
.
asType
(
setter
,
Lookup
.
SET_OBJECT_TYPE
)
:
setter
;
setType
(
OBJECT_FIELDS_ONLY
?
Object
.
class
:
getterType
);
setType
(
getterType
);
}
}
/**
/**
...
@@ -282,6 +278,9 @@ public class AccessorProperty extends Property {
...
@@ -282,6 +278,9 @@ public class AccessorProperty extends Property {
objectSetter
=
gs
.
objectSetters
[
slot
];
objectSetter
=
gs
.
objectSetters
[
slot
];
primitiveSetter
=
gs
.
primitiveSetters
[
slot
];
primitiveSetter
=
gs
.
primitiveSetters
[
slot
];
}
}
// Always use dual fields except for single field structures
assert
hasDualFields
()
!=
StructureLoader
.
isSingleFieldStructure
(
structure
.
getName
());
}
}
/**
/**
...
@@ -310,7 +309,7 @@ public class AccessorProperty extends Property {
...
@@ -310,7 +309,7 @@ public class AccessorProperty extends Property {
*/
*/
public
AccessorProperty
(
final
String
key
,
final
int
flags
,
final
Class
<?>
structure
,
final
int
slot
,
final
Class
<?>
initialType
)
{
public
AccessorProperty
(
final
String
key
,
final
int
flags
,
final
Class
<?>
structure
,
final
int
slot
,
final
Class
<?>
initialType
)
{
this
(
key
,
flags
,
structure
,
slot
);
this
(
key
,
flags
,
structure
,
slot
);
setType
(
OBJECT_FIELDS_ONLY
?
Object
.
class
:
initialType
);
setType
(
hasDualFields
()
?
initialType
:
Object
.
class
);
}
}
/**
/**
...
@@ -347,7 +346,7 @@ public class AccessorProperty extends Property {
...
@@ -347,7 +346,7 @@ public class AccessorProperty extends Property {
* @param initialValue initial value
* @param initialValue initial value
*/
*/
protected
final
void
setInitialValue
(
final
ScriptObject
owner
,
final
Object
initialValue
)
{
protected
final
void
setInitialValue
(
final
ScriptObject
owner
,
final
Object
initialValue
)
{
setType
(
JSType
.
unboxedFieldType
(
initialValue
)
);
setType
(
hasDualFields
()
?
JSType
.
unboxedFieldType
(
initialValue
)
:
Object
.
class
);
if
(
initialValue
instanceof
Integer
)
{
if
(
initialValue
instanceof
Integer
)
{
invokeSetter
(
owner
,
((
Integer
)
initialValue
).
intValue
());
invokeSetter
(
owner
,
((
Integer
)
initialValue
).
intValue
());
}
else
if
(
initialValue
instanceof
Long
)
{
}
else
if
(
initialValue
instanceof
Long
)
{
...
@@ -363,7 +362,7 @@ public class AccessorProperty extends Property {
...
@@ -363,7 +362,7 @@ public class AccessorProperty extends Property {
* Initialize the type of a property
* Initialize the type of a property
*/
*/
protected
final
void
initializeType
()
{
protected
final
void
initializeType
()
{
setType
(
OBJECT_FIELDS_ONLY
?
Object
.
class
:
null
);
setType
(
!
hasDualFields
()
?
Object
.
class
:
null
);
}
}
private
void
readObject
(
final
ObjectInputStream
s
)
throws
IOException
,
ClassNotFoundException
{
private
void
readObject
(
final
ObjectInputStream
s
)
throws
IOException
,
ClassNotFoundException
{
...
@@ -670,7 +669,7 @@ public class AccessorProperty extends Property {
...
@@ -670,7 +669,7 @@ public class AccessorProperty extends Property {
@Override
@Override
public
final
boolean
canChangeType
()
{
public
final
boolean
canChangeType
()
{
if
(
OBJECT_FIELDS_ONLY
)
{
if
(
!
hasDualFields
()
)
{
return
false
;
return
false
;
}
}
// Return true for currently undefined even if non-writable/configurable to allow initialization of ES6 CONST.
// Return true for currently undefined even if non-writable/configurable to allow initialization of ES6 CONST.
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AllocationStrategy.java
浏览文件 @
86e077f0
...
@@ -44,6 +44,9 @@ final public class AllocationStrategy implements Serializable {
...
@@ -44,6 +44,9 @@ final public class AllocationStrategy implements Serializable {
/** Number of fields in the allocated object */
/** Number of fields in the allocated object */
private
final
int
fieldCount
;
private
final
int
fieldCount
;
/** Whether to use dual field representation */
private
final
boolean
dualFields
;
/** Name of class where allocator function resides */
/** Name of class where allocator function resides */
private
transient
String
allocatorClassName
;
private
transient
String
allocatorClassName
;
...
@@ -53,15 +56,17 @@ final public class AllocationStrategy implements Serializable {
...
@@ -53,15 +56,17 @@ final public class AllocationStrategy implements Serializable {
/**
/**
* 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
* @param dualFields whether to use dual field representation
*/
*/
public
AllocationStrategy
(
final
int
fieldCount
)
{
public
AllocationStrategy
(
final
int
fieldCount
,
final
boolean
dualFields
)
{
this
.
fieldCount
=
fieldCount
;
this
.
fieldCount
=
fieldCount
;
this
.
dualFields
=
dualFields
;
}
}
private
String
getAllocatorClassName
()
{
private
String
getAllocatorClassName
()
{
if
(
allocatorClassName
==
null
)
{
if
(
allocatorClassName
==
null
)
{
// These classes get loaded, so an interned variant of their name is most likely around anyway.
// These classes get loaded, so an interned variant of their name is most likely around anyway.
allocatorClassName
=
Compiler
.
binaryName
(
ObjectClassGenerator
.
getClassName
(
fieldCount
)).
intern
();
allocatorClassName
=
Compiler
.
binaryName
(
ObjectClassGenerator
.
getClassName
(
fieldCount
,
dualFields
)).
intern
();
}
}
return
allocatorClassName
;
return
allocatorClassName
;
}
}
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java
浏览文件 @
86e077f0
...
@@ -130,6 +130,23 @@ public final class Context {
...
@@ -130,6 +130,23 @@ public final class Context {
private
static
MethodHandles
.
Lookup
LOOKUP
=
MethodHandles
.
lookup
();
private
static
MethodHandles
.
Lookup
LOOKUP
=
MethodHandles
.
lookup
();
private
static
MethodType
CREATE_PROGRAM_FUNCTION_TYPE
=
MethodType
.
methodType
(
ScriptFunction
.
class
,
ScriptObject
.
class
);
private
static
MethodType
CREATE_PROGRAM_FUNCTION_TYPE
=
MethodType
.
methodType
(
ScriptFunction
.
class
,
ScriptObject
.
class
);
/**
* Should scripts use only object slots for fields, or dual long/object slots? The default
* behaviour is to couple this to optimistic types, using dual representation if optimistic types are enabled
* and single field representation otherwise. This can be overridden by setting either the "nashorn.fields.objects"
* or "nashorn.fields.dual" system property.
*/
private
final
FieldMode
fieldMode
;
private
static
enum
FieldMode
{
/** Value for automatic field representation depending on optimistic types setting */
AUTO
,
/** Value for object field representation regardless of optimistic types setting */
OBJECTS
,
/** Value for dual primitive/object field representation regardless of optimistic types setting */
DUAL
}
/**
/**
* Keeps track of which builtin prototypes and properties have been relinked
* Keeps track of which builtin prototypes and properties have been relinked
* Currently we are conservative and associate the name of a builtin class with all
* Currently we are conservative and associate the name of a builtin class with all
...
@@ -434,7 +451,7 @@ public final class Context {
...
@@ -434,7 +451,7 @@ public final class Context {
* @param appLoader application class loader
* @param appLoader application class loader
*/
*/
public
Context
(
final
Options
options
,
final
ErrorManager
errors
,
final
ClassLoader
appLoader
)
{
public
Context
(
final
Options
options
,
final
ErrorManager
errors
,
final
ClassLoader
appLoader
)
{
this
(
options
,
errors
,
appLoader
,
(
ClassFilter
)
null
);
this
(
options
,
errors
,
appLoader
,
null
);
}
}
/**
/**
...
@@ -522,6 +539,14 @@ public final class Context {
...
@@ -522,6 +539,14 @@ public final class Context {
getErr
().
println
(
"nashorn full version "
+
Version
.
fullVersion
());
getErr
().
println
(
"nashorn full version "
+
Version
.
fullVersion
());
}
}
if
(
Options
.
getBooleanProperty
(
"nashorn.fields.dual"
))
{
fieldMode
=
FieldMode
.
DUAL
;
}
else
if
(
Options
.
getBooleanProperty
(
"nashorn.fields.objects"
))
{
fieldMode
=
FieldMode
.
OBJECTS
;
}
else
{
fieldMode
=
FieldMode
.
AUTO
;
}
initLoggers
();
initLoggers
();
}
}
...
@@ -575,6 +600,14 @@ public final class Context {
...
@@ -575,6 +600,14 @@ public final class Context {
return
env
.
getErr
();
return
env
.
getErr
();
}
}
/**
* Should scripts compiled by this context use dual field representation?
* @return true if using dual fields, false for object-only fields
*/
public
boolean
useDualFields
()
{
return
fieldMode
==
FieldMode
.
DUAL
||
(
fieldMode
==
FieldMode
.
AUTO
&&
env
.
_optimistic_types
);
}
/**
/**
* Get the PropertyMap of the current global scope
* Get the PropertyMap of the current global scope
* @return the property map of the current global scope
* @return the property map of the current global scope
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSONFunctions.java
浏览文件 @
86e077f0
...
@@ -72,7 +72,8 @@ public final class JSONFunctions {
...
@@ -72,7 +72,8 @@ public final class JSONFunctions {
public
static
Object
parse
(
final
Object
text
,
final
Object
reviver
)
{
public
static
Object
parse
(
final
Object
text
,
final
Object
reviver
)
{
final
String
str
=
JSType
.
toString
(
text
);
final
String
str
=
JSType
.
toString
(
text
);
final
Global
global
=
Context
.
getGlobal
();
final
Global
global
=
Context
.
getGlobal
();
final
JSONParser
parser
=
new
JSONParser
(
str
,
global
);
final
boolean
dualFields
=
((
ScriptObject
)
global
).
useDualFields
();
final
JSONParser
parser
=
new
JSONParser
(
str
,
global
,
dualFields
);
final
Object
value
;
final
Object
value
;
try
{
try
{
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java
浏览文件 @
86e077f0
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
package
jdk.nashorn.internal.runtime
;
package
jdk.nashorn.internal.runtime
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
staticCall
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
staticCall
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
;
import
static
jdk
.
nashorn
.
internal
.
lookup
.
Lookup
.
MH
;
import
static
jdk
.
nashorn
.
internal
.
lookup
.
Lookup
.
MH
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
ECMAErrors
.
typeError
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
ECMAErrors
.
typeError
;
...
@@ -1972,10 +1971,6 @@ public enum JSType {
...
@@ -1972,10 +1971,6 @@ public enum JSType {
* @return primive type or Object.class if not primitive
* @return primive type or Object.class if not primitive
*/
*/
public
static
Class
<?>
unboxedFieldType
(
final
Object
o
)
{
public
static
Class
<?>
unboxedFieldType
(
final
Object
o
)
{
if
(
OBJECT_FIELDS_ONLY
)
{
return
Object
.
class
;
}
if
(
o
==
null
)
{
if
(
o
==
null
)
{
return
Object
.
class
;
return
Object
.
class
;
}
else
if
(
o
.
getClass
()
==
Integer
.
class
)
{
}
else
if
(
o
.
getClass
()
==
Integer
.
class
)
{
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java
浏览文件 @
86e077f0
...
@@ -96,6 +96,9 @@ public abstract class Property implements Serializable {
...
@@ -96,6 +96,9 @@ public abstract class Property implements Serializable {
/** Is this property an ES6 lexical binding? */
/** Is this property an ES6 lexical binding? */
public
static
final
int
IS_LEXICAL_BINDING
=
1
<<
10
;
public
static
final
int
IS_LEXICAL_BINDING
=
1
<<
10
;
/** Does this property support dual field representation? */
public
static
final
int
DUAL_FIELDS
=
1
<<
11
;
/** Property key. */
/** Property key. */
private
final
String
key
;
private
final
String
key
;
...
@@ -286,7 +289,7 @@ public abstract class Property implements Serializable {
...
@@ -286,7 +289,7 @@ public abstract class Property implements Serializable {
* @return true if parameter
* @return true if parameter
*/
*/
public
boolean
isParameter
()
{
public
boolean
isParameter
()
{
return
(
flags
&
IS_PARAMETER
)
==
IS_PARAMETER
;
return
(
flags
&
IS_PARAMETER
)
!=
0
;
}
}
/**
/**
...
@@ -294,7 +297,7 @@ public abstract class Property implements Serializable {
...
@@ -294,7 +297,7 @@ public abstract class Property implements Serializable {
* @return true if has arguments
* @return true if has arguments
*/
*/
public
boolean
hasArguments
()
{
public
boolean
hasArguments
()
{
return
(
flags
&
HAS_ARGUMENTS
)
==
HAS_ARGUMENTS
;
return
(
flags
&
HAS_ARGUMENTS
)
!=
0
;
}
}
/**
/**
...
@@ -316,7 +319,7 @@ public abstract class Property implements Serializable {
...
@@ -316,7 +319,7 @@ public abstract class Property implements Serializable {
* @return true if this is a bound property
* @return true if this is a bound property
*/
*/
public
boolean
isBound
()
{
public
boolean
isBound
()
{
return
(
flags
&
IS_BOUND
)
==
IS_BOUND
;
return
(
flags
&
IS_BOUND
)
!=
0
;
}
}
/**
/**
...
@@ -325,7 +328,7 @@ public abstract class Property implements Serializable {
...
@@ -325,7 +328,7 @@ public abstract class Property implements Serializable {
* @return true if this is a block-scoped variable
* @return true if this is a block-scoped variable
*/
*/
public
boolean
needsDeclaration
()
{
public
boolean
needsDeclaration
()
{
return
(
flags
&
NEEDS_DECLARATION
)
==
NEEDS_DECLARATION
;
return
(
flags
&
NEEDS_DECLARATION
)
!=
0
;
}
}
/**
/**
...
@@ -345,16 +348,6 @@ public abstract class Property implements Serializable {
...
@@ -345,16 +348,6 @@ public abstract class Property implements Serializable {
return
this
;
return
this
;
}
}
/**
* Check if a flag is set for a property
* @param property property
* @param flag flag to check
* @return true if flag is set
*/
public
static
boolean
checkFlag
(
final
Property
property
,
final
int
flag
)
{
return
(
property
.
getFlags
()
&
flag
)
==
flag
;
}
/**
/**
* Get the flags for this property
* Get the flags for this property
* @return property flags
* @return property flags
...
@@ -363,16 +356,6 @@ public abstract class Property implements Serializable {
...
@@ -363,16 +356,6 @@ public abstract class Property implements Serializable {
return
flags
;
return
flags
;
}
}
/**
* Get the modify flags for this property. The modify flags are the ECMA 8.6.1
* flags that decide if the Property is writable, configurable and/or enumerable.
*
* @return modify flags for property
*/
public
int
getModifyFlags
()
{
return
flags
&
MODIFY_MASK
;
}
/**
/**
* Remove property flags from the property. Properties are immutable here,
* Remove property flags from the property. Properties are immutable here,
* so any property change that results in a smaller flag set results in the
* so any property change that results in a smaller flag set results in the
...
@@ -715,7 +698,7 @@ public abstract class Property implements Serializable {
...
@@ -715,7 +698,7 @@ public abstract class Property implements Serializable {
* @return whether this property is a function declaration or not.
* @return whether this property is a function declaration or not.
*/
*/
public
boolean
isFunctionDeclaration
()
{
public
boolean
isFunctionDeclaration
()
{
return
(
flags
&
IS_FUNCTION_DECLARATION
)
==
IS_FUNCTION_DECLARATION
;
return
(
flags
&
IS_FUNCTION_DECLARATION
)
!=
0
;
}
}
/**
/**
...
@@ -723,6 +706,14 @@ public abstract class Property implements Serializable {
...
@@ -723,6 +706,14 @@ public abstract class Property implements Serializable {
* @return true if this property represents a lexical binding.
* @return true if this property represents a lexical binding.
*/
*/
public
boolean
isLexicalBinding
()
{
public
boolean
isLexicalBinding
()
{
return
(
flags
&
IS_LEXICAL_BINDING
)
==
IS_LEXICAL_BINDING
;
return
(
flags
&
IS_LEXICAL_BINDING
)
!=
0
;
}
/**
* Does this property support dual fields for both primitive and object values?
* @return true if supports dual fields
*/
public
boolean
hasDualFields
()
{
return
(
flags
&
DUAL_FIELDS
)
!=
0
;
}
}
}
}
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
浏览文件 @
86e077f0
...
@@ -198,13 +198,22 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
...
@@ -198,13 +198,22 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
return
properties
==
null
||
properties
.
isEmpty
()?
newMap
()
:
newMap
(
properties
,
JO
.
class
.
getName
(),
0
,
0
,
0
);
return
properties
==
null
||
properties
.
isEmpty
()?
newMap
()
:
newMap
(
properties
,
JO
.
class
.
getName
(),
0
,
0
,
0
);
}
}
/**
* Return a sharable empty map for the given object class.
* @param clazz the base object class
* @return New empty {@link PropertyMap}.
*/
public
static
PropertyMap
newMap
(
final
Class
<?
extends
ScriptObject
>
clazz
)
{
return
new
PropertyMap
(
EMPTY_HASHMAP
,
clazz
.
getName
(),
0
,
0
,
0
,
false
);
}
/**
/**
* Return a sharable empty map.
* Return a sharable empty map.
*
*
* @return New empty {@link PropertyMap}.
* @return New empty {@link PropertyMap}.
*/
*/
public
static
PropertyMap
newMap
()
{
public
static
PropertyMap
newMap
()
{
return
new
PropertyMap
(
EMPTY_HASHMAP
,
JO
.
class
.
getName
(),
0
,
0
,
0
,
false
);
return
new
Map
(
JO
.
class
);
}
}
/**
/**
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java
浏览文件 @
86e077f0
...
@@ -28,7 +28,6 @@ package jdk.nashorn.internal.runtime;
...
@@ -28,7 +28,6 @@ package jdk.nashorn.internal.runtime;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
staticCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
staticCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
virtualCall
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
virtualCall
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
virtualCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
virtualCallNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
;
import
static
jdk
.
nashorn
.
internal
.
lookup
.
Lookup
.
MH
;
import
static
jdk
.
nashorn
.
internal
.
lookup
.
Lookup
.
MH
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
ECMAErrors
.
referenceError
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
ECMAErrors
.
referenceError
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
ECMAErrors
.
typeError
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
ECMAErrors
.
typeError
;
...
@@ -146,12 +145,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -146,12 +145,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
/** Area for reference properties added to object after instantiation, see {@link AccessorProperty} */
/** Area for reference properties added to object after instantiation, see {@link AccessorProperty} */
protected
Object
[]
objectSpill
;
protected
Object
[]
objectSpill
;
/**
* Number of elements in the spill. This may be less than the spill array lengths, if not all of
* the allocated memory is in use
*/
private
int
spillLength
;
/** Indexed array data. */
/** Indexed array data. */
private
ArrayData
arrayData
;
private
ArrayData
arrayData
;
...
@@ -171,12 +164,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -171,12 +164,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
/** Method handle for getting the array data */
/** Method handle for getting the array data */
public
static
final
Call
GET_ARRAY
=
virtualCall
(
MethodHandles
.
lookup
(),
ScriptObject
.
class
,
"getArray"
,
ArrayData
.
class
);
public
static
final
Call
GET_ARRAY
=
virtualCall
(
MethodHandles
.
lookup
(),
ScriptObject
.
class
,
"getArray"
,
ArrayData
.
class
);
/** Method handle for getting the property map - debugging purposes */
public
static
final
Call
GET_MAP
=
virtualCall
(
MethodHandles
.
lookup
(),
ScriptObject
.
class
,
"getMap"
,
PropertyMap
.
class
);
/** Method handle for setting the array data */
public
static
final
Call
SET_ARRAY
=
virtualCall
(
MethodHandles
.
lookup
(),
ScriptObject
.
class
,
"setArray"
,
void
.
class
,
ArrayData
.
class
);
/** Method handle for getting a function argument at a given index. Used from MapCreator */
/** Method handle for getting a function argument at a given index. Used from MapCreator */
public
static
final
Call
GET_ARGUMENT
=
virtualCall
(
MethodHandles
.
lookup
(),
ScriptObject
.
class
,
"getArgument"
,
Object
.
class
,
int
.
class
);
public
static
final
Call
GET_ARGUMENT
=
virtualCall
(
MethodHandles
.
lookup
(),
ScriptObject
.
class
,
"getArgument"
,
Object
.
class
,
int
.
class
);
...
@@ -259,8 +246,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -259,8 +246,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
this
(
map
);
this
(
map
);
this
.
primitiveSpill
=
primitiveSpill
;
this
.
primitiveSpill
=
primitiveSpill
;
this
.
objectSpill
=
objectSpill
;
this
.
objectSpill
=
objectSpill
;
assert
primitiveSpill
.
length
==
objectSpill
.
length
:
" primitive spill pool size is not the same length as object spill pool size"
;
assert
primitiveSpill
==
null
||
primitiveSpill
.
length
==
objectSpill
.
length
:
" primitive spill pool size is not the same length as object spill pool size"
;
this
.
spillLength
=
spillAllocationLength
(
primitiveSpill
.
length
);
}
}
/**
/**
...
@@ -727,7 +713,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -727,7 +713,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
setArray
(
getArray
().
ensure
(
longIndex
));
setArray
(
getArray
().
ensure
(
longIndex
));
doesNotHaveEnsureDelete
(
longIndex
,
oldLength
,
false
);
doesNotHaveEnsureDelete
(
longIndex
,
oldLength
,
false
);
}
}
setArray
(
getArray
().
set
(
index
,
value
,
false
));
setArray
(
getArray
().
set
(
index
,
value
,
false
));
}
}
private
void
checkIntegerKey
(
final
String
key
)
{
private
void
checkIntegerKey
(
final
String
key
)
{
...
@@ -976,10 +962,10 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -976,10 +962,10 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
* @param setter setter for {@link UserAccessorProperty}, null if not present or N/A
* @param setter setter for {@link UserAccessorProperty}, null if not present or N/A
*/
*/
protected
final
void
initUserAccessors
(
final
String
key
,
final
int
propertyFlags
,
final
ScriptFunction
getter
,
final
ScriptFunction
setter
)
{
protected
final
void
initUserAccessors
(
final
String
key
,
final
int
propertyFlags
,
final
ScriptFunction
getter
,
final
ScriptFunction
setter
)
{
final
int
slot
=
spillLength
;
ensureSpillSize
(
spillLength
);
//arguments=slot0, caller=slot0
objectSpill
[
slot
]
=
new
UserAccessorProperty
.
Accessors
(
getter
,
setter
);
final
PropertyMap
oldMap
=
getMap
();
final
PropertyMap
oldMap
=
getMap
();
final
int
slot
=
oldMap
.
getFreeSpillSlot
();
ensureSpillSize
(
slot
);
objectSpill
[
slot
]
=
new
UserAccessorProperty
.
Accessors
(
getter
,
setter
);
Property
newProperty
;
Property
newProperty
;
PropertyMap
newMap
;
PropertyMap
newMap
;
do
{
do
{
...
@@ -1006,20 +992,13 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -1006,20 +992,13 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
final
int
slot
=
uc
.
getSlot
();
final
int
slot
=
uc
.
getSlot
();
assert
uc
.
getLocalType
()
==
Object
.
class
;
assert
uc
.
getLocalType
()
==
Object
.
class
;
if
(
slot
>=
spillLength
)
{
uc
.
setAccessors
(
this
,
getMap
(),
new
UserAccessorProperty
.
Accessors
(
getter
,
setter
));
}
else
{
final
UserAccessorProperty
.
Accessors
gs
=
uc
.
getAccessors
(
this
);
//this crashes
final
UserAccessorProperty
.
Accessors
gs
=
uc
.
getAccessors
(
this
);
//this crashes
if
(
gs
==
null
)
{
assert
gs
!=
null
;
uc
.
setAccessors
(
this
,
getMap
(),
new
UserAccessorProperty
.
Accessors
(
getter
,
setter
));
}
else
{
//reuse existing getter setter for speed
//reuse existing getter setter for speed
gs
.
set
(
getter
,
setter
);
gs
.
set
(
getter
,
setter
);
if
(
uc
.
getFlags
()
==
propertyFlags
)
{
if
(
uc
.
getFlags
()
==
propertyFlags
)
{
return
oldProperty
;
return
oldProperty
;
}
}
}
}
newProperty
=
new
UserAccessorProperty
(
uc
.
getKey
(),
propertyFlags
,
slot
);
newProperty
=
new
UserAccessorProperty
(
uc
.
getKey
(),
propertyFlags
,
slot
);
}
else
{
}
else
{
// erase old property value and create new user accessor property
// erase old property value and create new user accessor property
...
@@ -2053,8 +2032,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2053,8 +2032,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
protoSwitchPoint
=
null
;
protoSwitchPoint
=
null
;
}
}
assert
OBJECT_FIELDS_ONLY
||
guard
!=
null
:
"we always need a map guard here"
;
final
GuardedInvocation
inv
=
new
GuardedInvocation
(
mh
,
guard
,
protoSwitchPoint
,
exception
);
final
GuardedInvocation
inv
=
new
GuardedInvocation
(
mh
,
guard
,
protoSwitchPoint
,
exception
);
return
inv
.
addSwitchPoint
(
findBuiltinSwitchPoint
(
name
));
return
inv
.
addSwitchPoint
(
findBuiltinSwitchPoint
(
name
));
}
}
...
@@ -2532,12 +2509,13 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2532,12 +2509,13 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
/**
/**
* Add a spill property for the given key.
* Add a spill property for the given key.
* @param key Property key.
* @param key Property key.
* @param
propertyFlags
Property flags.
* @param
flags
Property flags.
* @return Added property.
* @return Added property.
*/
*/
private
Property
addSpillProperty
(
final
String
key
,
final
int
propertyF
lags
,
final
Object
value
,
final
boolean
hasInitialValue
)
{
private
Property
addSpillProperty
(
final
String
key
,
final
int
f
lags
,
final
Object
value
,
final
boolean
hasInitialValue
)
{
final
PropertyMap
propertyMap
=
getMap
();
final
PropertyMap
propertyMap
=
getMap
();
final
int
fieldSlot
=
propertyMap
.
getFreeFieldSlot
();
final
int
fieldSlot
=
propertyMap
.
getFreeFieldSlot
();
final
int
propertyFlags
=
flags
|
(
useDualFields
()
?
Property
.
DUAL_FIELDS
:
0
);
Property
property
;
Property
property
;
if
(
fieldSlot
>
-
1
)
{
if
(
fieldSlot
>
-
1
)
{
...
@@ -2562,7 +2540,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -2562,7 +2540,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
* @return Setter method handle.
* @return Setter method handle.
*/
*/
MethodHandle
addSpill
(
final
Class
<?>
type
,
final
String
key
)
{
MethodHandle
addSpill
(
final
Class
<?>
type
,
final
String
key
)
{
return
addSpillProperty
(
key
,
0
,
null
,
false
).
getSetter
(
OBJECT_FIELDS_ONLY
?
Object
.
class
:
type
,
getMap
());
return
addSpillProperty
(
key
,
0
,
null
,
false
).
getSetter
(
type
,
getMap
());
}
}
/**
/**
...
@@ -3739,24 +3717,32 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
...
@@ -3739,24 +3717,32 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return
uc
;
return
uc
;
}
}
/**
* Returns {@code true} if properties for this object should use dual field mode, {@code false} otherwise.
* @return {@code true} if dual fields should be used.
*/
protected
boolean
useDualFields
()
{
return
!
StructureLoader
.
isSingleFieldStructure
(
getClass
().
getName
());
}
Object
ensureSpillSize
(
final
int
slot
)
{
Object
ensureSpillSize
(
final
int
slot
)
{
if
(
slot
<
spillLength
)
{
final
int
oldLength
=
objectSpill
==
null
?
0
:
objectSpill
.
length
;
if
(
slot
<
oldLength
)
{
return
this
;
return
this
;
}
}
final
int
newLength
=
alignUp
(
slot
+
1
,
SPILL_RATE
);
final
int
newLength
=
alignUp
(
slot
+
1
,
SPILL_RATE
);
final
Object
[]
newObjectSpill
=
new
Object
[
newLength
];
final
Object
[]
newObjectSpill
=
new
Object
[
newLength
];
final
long
[]
newPrimitiveSpill
=
OBJECT_FIELDS_ONLY
?
null
:
new
long
[
newLength
]
;
final
long
[]
newPrimitiveSpill
=
useDualFields
()
?
new
long
[
newLength
]
:
null
;
if
(
objectSpill
!=
null
)
{
if
(
objectSpill
!=
null
)
{
System
.
arraycopy
(
objectSpill
,
0
,
newObjectSpill
,
0
,
spill
Length
);
System
.
arraycopy
(
objectSpill
,
0
,
newObjectSpill
,
0
,
old
Length
);
if
(
!
OBJECT_FIELDS_ONLY
)
{
if
(
primitiveSpill
!=
null
&&
newPrimitiveSpill
!=
null
)
{
System
.
arraycopy
(
primitiveSpill
,
0
,
newPrimitiveSpill
,
0
,
spill
Length
);
System
.
arraycopy
(
primitiveSpill
,
0
,
newPrimitiveSpill
,
0
,
old
Length
);
}
}
}
}
this
.
primitiveSpill
=
newPrimitiveSpill
;
this
.
primitiveSpill
=
newPrimitiveSpill
;
this
.
objectSpill
=
newObjectSpill
;
this
.
objectSpill
=
newObjectSpill
;
this
.
spillLength
=
newLength
;
return
this
;
return
this
;
}
}
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java
浏览文件 @
86e077f0
...
@@ -232,14 +232,18 @@ final class SetMethodCreator {
...
@@ -232,14 +232,18 @@ final class SetMethodCreator {
}
}
private
SetMethod
createNewFieldSetter
(
final
SwitchPoint
builtinSwitchPoint
)
{
private
SetMethod
createNewFieldSetter
(
final
SwitchPoint
builtinSwitchPoint
)
{
return
createNewSetter
(
new
AccessorProperty
(
getName
(),
0
,
sobj
.
getClass
(),
getMap
().
getFreeFieldSlot
(),
type
),
builtinSwitchPoint
);
return
createNewSetter
(
new
AccessorProperty
(
getName
(),
getFlags
(
sobj
)
,
sobj
.
getClass
(),
getMap
().
getFreeFieldSlot
(),
type
),
builtinSwitchPoint
);
}
}
private
SetMethod
createNewSpillPropertySetter
(
final
SwitchPoint
builtinSwitchPoint
)
{
private
SetMethod
createNewSpillPropertySetter
(
final
SwitchPoint
builtinSwitchPoint
)
{
return
createNewSetter
(
new
SpillProperty
(
getName
(),
0
,
getMap
().
getFreeSpillSlot
(),
type
),
builtinSwitchPoint
);
return
createNewSetter
(
new
SpillProperty
(
getName
(),
getFlags
(
sobj
)
,
getMap
().
getFreeSpillSlot
(),
type
),
builtinSwitchPoint
);
}
}
private
PropertyMap
getNewMap
(
final
Property
property
)
{
private
PropertyMap
getNewMap
(
final
Property
property
)
{
return
getMap
().
addProperty
(
property
);
return
getMap
().
addProperty
(
property
);
}
}
private
static
int
getFlags
(
final
ScriptObject
scriptObject
)
{
return
scriptObject
.
useDualFields
()
?
Property
.
DUAL_FIELDS
:
0
;
}
}
}
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SpillProperty.java
浏览文件 @
86e077f0
...
@@ -25,7 +25,6 @@
...
@@ -25,7 +25,6 @@
package
jdk.nashorn.internal.runtime
;
package
jdk.nashorn.internal.runtime
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
;
import
static
jdk
.
nashorn
.
internal
.
lookup
.
Lookup
.
MH
;
import
static
jdk
.
nashorn
.
internal
.
lookup
.
Lookup
.
MH
;
import
java.lang.invoke.MethodHandle
;
import
java.lang.invoke.MethodHandle
;
...
@@ -139,11 +138,11 @@ public class SpillProperty extends AccessorProperty {
...
@@ -139,11 +138,11 @@ public class SpillProperty extends AccessorProperty {
}
}
}
}
private
static
MethodHandle
primitiveGetter
(
final
int
slot
)
{
private
static
MethodHandle
primitiveGetter
(
final
int
slot
,
final
int
flags
)
{
return
OBJECT_FIELDS_ONLY
?
null
:
Accessors
.
getCached
(
slot
,
true
,
true
)
;
return
(
flags
&
DUAL_FIELDS
)
==
DUAL_FIELDS
?
Accessors
.
getCached
(
slot
,
true
,
true
)
:
null
;
}
}
private
static
MethodHandle
primitiveSetter
(
final
int
slot
)
{
private
static
MethodHandle
primitiveSetter
(
final
int
slot
,
final
int
flags
)
{
return
OBJECT_FIELDS_ONLY
?
null
:
Accessors
.
getCached
(
slot
,
true
,
false
)
;
return
(
flags
&
DUAL_FIELDS
)
==
DUAL_FIELDS
?
Accessors
.
getCached
(
slot
,
true
,
false
)
:
null
;
}
}
private
static
MethodHandle
objectGetter
(
final
int
slot
)
{
private
static
MethodHandle
objectGetter
(
final
int
slot
)
{
return
Accessors
.
getCached
(
slot
,
false
,
true
);
return
Accessors
.
getCached
(
slot
,
false
,
true
);
...
@@ -160,8 +159,7 @@ public class SpillProperty extends AccessorProperty {
...
@@ -160,8 +159,7 @@ public class SpillProperty extends AccessorProperty {
* @param slot spill slot
* @param slot spill slot
*/
*/
public
SpillProperty
(
final
String
key
,
final
int
flags
,
final
int
slot
)
{
public
SpillProperty
(
final
String
key
,
final
int
flags
,
final
int
slot
)
{
super
(
key
,
flags
,
slot
,
primitiveGetter
(
slot
),
primitiveSetter
(
slot
),
objectGetter
(
slot
),
objectSetter
(
slot
));
super
(
key
,
flags
,
slot
,
primitiveGetter
(
slot
,
flags
),
primitiveSetter
(
slot
,
flags
),
objectGetter
(
slot
),
objectSetter
(
slot
));
assert
!
OBJECT_FIELDS_ONLY
||
getLocalType
()
==
Object
.
class
;
}
}
/**
/**
...
@@ -173,7 +171,7 @@ public class SpillProperty extends AccessorProperty {
...
@@ -173,7 +171,7 @@ public class SpillProperty extends AccessorProperty {
*/
*/
public
SpillProperty
(
final
String
key
,
final
int
flags
,
final
int
slot
,
final
Class
<?>
initialType
)
{
public
SpillProperty
(
final
String
key
,
final
int
flags
,
final
int
slot
,
final
Class
<?>
initialType
)
{
this
(
key
,
flags
,
slot
);
this
(
key
,
flags
,
slot
);
setType
(
OBJECT_FIELDS_ONLY
?
Object
.
class
:
initialType
);
setType
(
hasDualFields
()
?
initialType
:
Object
.
class
);
}
}
SpillProperty
(
final
String
key
,
final
int
flags
,
final
int
slot
,
final
ScriptObject
owner
,
final
Object
initialValue
)
{
SpillProperty
(
final
String
key
,
final
int
flags
,
final
int
slot
,
final
ScriptObject
owner
,
final
Object
initialValue
)
{
...
@@ -216,8 +214,8 @@ public class SpillProperty extends AccessorProperty {
...
@@ -216,8 +214,8 @@ public class SpillProperty extends AccessorProperty {
@Override
@Override
void
initMethodHandles
(
final
Class
<?>
structure
)
{
void
initMethodHandles
(
final
Class
<?>
structure
)
{
final
int
slot
=
getSlot
();
final
int
slot
=
getSlot
();
primitiveGetter
=
primitiveGetter
(
slot
);
primitiveGetter
=
primitiveGetter
(
slot
,
getFlags
()
);
primitiveSetter
=
primitiveSetter
(
slot
);
primitiveSetter
=
primitiveSetter
(
slot
,
getFlags
()
);
objectGetter
=
objectGetter
(
slot
);
objectGetter
=
objectGetter
(
slot
);
objectSetter
=
objectSetter
(
slot
);
objectSetter
=
objectSetter
(
slot
);
}
}
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java
浏览文件 @
86e077f0
...
@@ -27,7 +27,8 @@ package jdk.nashorn.internal.runtime;
...
@@ -27,7 +27,8 @@ package jdk.nashorn.internal.runtime;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
Compiler
.
SCRIPTS_PACKAGE
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
Compiler
.
SCRIPTS_PACKAGE
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
Compiler
.
binaryName
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
Compiler
.
binaryName
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
JS_OBJECT_PREFIX
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
JS_OBJECT_DUAL_FIELD_PREFIX
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
JS_OBJECT_SINGLE_FIELD_PREFIX
;
import
java.security.ProtectionDomain
;
import
java.security.ProtectionDomain
;
import
jdk.nashorn.internal.codegen.ObjectClassGenerator
;
import
jdk.nashorn.internal.codegen.ObjectClassGenerator
;
...
@@ -36,7 +37,8 @@ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
...
@@ -36,7 +37,8 @@ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
* Responsible for on the fly construction of structure classes.
* Responsible for on the fly construction of structure classes.
*/
*/
final
class
StructureLoader
extends
NashornLoader
{
final
class
StructureLoader
extends
NashornLoader
{
private
static
final
String
JS_OBJECT_PREFIX_EXTERNAL
=
binaryName
(
SCRIPTS_PACKAGE
)
+
'.'
+
JS_OBJECT_PREFIX
.
symbolName
();
private
static
final
String
SINGLE_FIELD_PREFIX
=
binaryName
(
SCRIPTS_PACKAGE
)
+
'.'
+
JS_OBJECT_SINGLE_FIELD_PREFIX
.
symbolName
();
private
static
final
String
DUAL_FIELD_PREFIX
=
binaryName
(
SCRIPTS_PACKAGE
)
+
'.'
+
JS_OBJECT_DUAL_FIELD_PREFIX
.
symbolName
();
/**
/**
* Constructor.
* Constructor.
...
@@ -45,14 +47,39 @@ final class StructureLoader extends NashornLoader {
...
@@ -45,14 +47,39 @@ final class StructureLoader extends NashornLoader {
super
(
parent
);
super
(
parent
);
}
}
/**
* Returns true if the class name represents a structure object with dual primitive/object fields.
* @param name a class name
* @return true if a dual field structure class
*/
private
static
boolean
isDualFieldStructure
(
final
String
name
)
{
return
name
.
startsWith
(
DUAL_FIELD_PREFIX
);
}
/**
* Returns true if the class name represents a structure object with single object-only fields.
* @param name a class name
* @return true if a single field structure class
*/
static
boolean
isSingleFieldStructure
(
final
String
name
)
{
return
name
.
startsWith
(
SINGLE_FIELD_PREFIX
);
}
/**
* Returns true if the class name represents a Nashorn structure object.
* @param name a class name
* @return true if a structure class
*/
static
boolean
isStructureClass
(
final
String
name
)
{
static
boolean
isStructureClass
(
final
String
name
)
{
return
name
.
startsWith
(
JS_OBJECT_PREFIX_EXTERNAL
);
return
isDualFieldStructure
(
name
)
||
isSingleFieldStructure
(
name
);
}
}
@Override
@Override
protected
Class
<?>
findClass
(
final
String
name
)
throws
ClassNotFoundException
{
protected
Class
<?>
findClass
(
final
String
name
)
throws
ClassNotFoundException
{
if
(
isStructureClass
(
name
))
{
if
(
isDualFieldStructure
(
name
))
{
return
generateClass
(
name
,
name
.
substring
(
JS_OBJECT_PREFIX_EXTERNAL
.
length
()));
return
generateClass
(
name
,
name
.
substring
(
DUAL_FIELD_PREFIX
.
length
()),
true
);
}
else
if
(
isSingleFieldStructure
(
name
))
{
return
generateClass
(
name
,
name
.
substring
(
SINGLE_FIELD_PREFIX
.
length
()),
false
);
}
}
return
super
.
findClass
(
name
);
return
super
.
findClass
(
name
);
}
}
...
@@ -63,10 +90,10 @@ final class StructureLoader extends NashornLoader {
...
@@ -63,10 +90,10 @@ final class StructureLoader extends NashornLoader {
* @param descriptor Layout descriptor.
* @param descriptor Layout descriptor.
* @return Generated class.
* @return Generated class.
*/
*/
private
Class
<?>
generateClass
(
final
String
name
,
final
String
descriptor
)
{
private
Class
<?>
generateClass
(
final
String
name
,
final
String
descriptor
,
final
boolean
dualFields
)
{
final
Context
context
=
Context
.
getContextTrusted
();
final
Context
context
=
Context
.
getContextTrusted
();
final
byte
[]
code
=
new
ObjectClassGenerator
(
context
).
generate
(
descriptor
);
final
byte
[]
code
=
new
ObjectClassGenerator
(
context
,
dualFields
).
generate
(
descriptor
);
return
defineClass
(
name
,
code
,
0
,
code
.
length
,
new
ProtectionDomain
(
null
,
getPermissions
(
null
)));
return
defineClass
(
name
,
code
,
0
,
code
.
length
,
new
ProtectionDomain
(
null
,
getPermissions
(
null
)));
}
}
}
}
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java
浏览文件 @
86e077f0
...
@@ -74,17 +74,16 @@ public final class Bootstrap {
...
@@ -74,17 +74,16 @@ public final class Bootstrap {
* of object fields only, it is fine. However, with dual fields, in order to get
* of object fields only, it is fine. However, with dual fields, in order to get
* performance on benchmarks with a lot of object instantiation and then field
* performance on benchmarks with a lot of object instantiation and then field
* reassignment, it can take slightly more relinks to become stable with type
* reassignment, it can take slightly more relinks to become stable with type
* changes swapping out an entire proprety map and making a map guard fail.
* changes swapping out an entire property map and making a map guard fail.
* Therefore the relink threshold is set to 16 for dual fields (now the default).
* Since we need to set this value statically it must work with possibly changing
* This doesn't seem to have any other negative performance implication.
* optimistic types and dual fields settings. A higher value does not seem to have
* any other negative performance implication when running with object-only fields,
* so we choose a higher value here.
*
*
* See for example octane.gbemu, run with --log=fields:warning to study
* See for example octane.gbemu, run with --log=fields:warning to study
* megamorphic behavior
* megamorphic behavior
*/
*/
private
static
final
int
NASHORN_DEFAULT_UNSTABLE_RELINK_THRESHOLD
=
private
static
final
int
NASHORN_DEFAULT_UNSTABLE_RELINK_THRESHOLD
=
16
;
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
?
8
:
16
;
// do not create me!!
// do not create me!!
private
Bootstrap
()
{
private
Bootstrap
()
{
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornGuards.java
浏览文件 @
86e077f0
...
@@ -33,7 +33,6 @@ import java.lang.ref.WeakReference;
...
@@ -33,7 +33,6 @@ import java.lang.ref.WeakReference;
import
jdk.internal.dynalink.CallSiteDescriptor
;
import
jdk.internal.dynalink.CallSiteDescriptor
;
import
jdk.internal.dynalink.linker.LinkRequest
;
import
jdk.internal.dynalink.linker.LinkRequest
;
import
jdk.nashorn.api.scripting.JSObject
;
import
jdk.nashorn.api.scripting.JSObject
;
import
jdk.nashorn.internal.codegen.ObjectClassGenerator
;
import
jdk.nashorn.internal.objects.Global
;
import
jdk.nashorn.internal.objects.Global
;
import
jdk.nashorn.internal.runtime.Property
;
import
jdk.nashorn.internal.runtime.Property
;
import
jdk.nashorn.internal.runtime.PropertyMap
;
import
jdk.nashorn.internal.runtime.PropertyMap
;
...
@@ -123,7 +122,7 @@ public final class NashornGuards {
...
@@ -123,7 +122,7 @@ public final class NashornGuards {
*/
*/
static
boolean
needsGuard
(
final
Property
property
,
final
CallSiteDescriptor
desc
)
{
static
boolean
needsGuard
(
final
Property
property
,
final
CallSiteDescriptor
desc
)
{
return
property
==
null
||
property
.
isConfigurable
()
return
property
==
null
||
property
.
isConfigurable
()
||
property
.
isBound
()
||
!
ObjectClassGenerator
.
OBJECT_FIELDS_ONLY
||
property
.
isBound
()
||
property
.
hasDualFields
()
||
!
NashornCallSiteDescriptor
.
isFastScope
(
desc
)
||
property
.
canChangeType
();
||
!
NashornCallSiteDescriptor
.
isFastScope
(
desc
)
||
property
.
canChangeType
();
}
}
...
...
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/scripts/JD.java
0 → 100644
浏览文件 @
86e077f0
/*
* 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.scripts
;
import
jdk.nashorn.internal.runtime.PropertyMap
;
import
jdk.nashorn.internal.runtime.ScriptObject
;
/**
* Empty object class for dual primitive-object fields.
*/
public
class
JD
extends
ScriptObject
{
private
static
final
PropertyMap
map
$
=
PropertyMap
.
newMap
(
JD
.
class
);
/**
* Returns the initial property map to be used.
* @return the initial property map.
*/
public
static
PropertyMap
getInitialMap
()
{
return
map
$
;
}
/**
* Constructor given an initial property map
*
* @param map the property map
*/
public
JD
(
final
PropertyMap
map
)
{
super
(
map
);
}
/**
* Constructor given an initial prototype and the default initial property map.
*
* @param proto the prototype object
*/
public
JD
(
final
ScriptObject
proto
)
{
super
(
proto
,
getInitialMap
());
}
/**
* Constructor that takes a pre-initialized spill pool. Used by
* {@link jdk.nashorn.internal.codegen.SpillObjectCreator} and
* {@link jdk.nashorn.internal.parser.JSONParser} for initializing object literals
*
* @param map property map
* @param primitiveSpill primitive spill pool
* @param objectSpill reference spill pool
*/
public
JD
(
final
PropertyMap
map
,
final
long
[]
primitiveSpill
,
final
Object
[]
objectSpill
)
{
super
(
map
,
primitiveSpill
,
objectSpill
);
}
/**
* A method handle of this method is passed to the ScriptFunction constructor.
*
* @param map the property map to use for allocatorMap
*
* @return newly allocated ScriptObject
*/
public
static
ScriptObject
allocate
(
final
PropertyMap
map
)
{
return
new
JD
(
map
);
}
}
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/scripts/JO.java
浏览文件 @
86e077f0
/*
/*
* Copyright (c) 2010, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 201
5
, 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
...
@@ -29,11 +29,11 @@ import jdk.nashorn.internal.runtime.PropertyMap;
...
@@ -29,11 +29,11 @@ import jdk.nashorn.internal.runtime.PropertyMap;
import
jdk.nashorn.internal.runtime.ScriptObject
;
import
jdk.nashorn.internal.runtime.ScriptObject
;
/**
/**
* Empty object class.
* Empty object class
for object-only fields
.
*/
*/
public
class
JO
extends
ScriptObject
{
public
class
JO
extends
ScriptObject
{
private
static
final
PropertyMap
map
$
=
PropertyMap
.
newMap
();
private
static
final
PropertyMap
map
$
=
PropertyMap
.
newMap
(
JO
.
class
);
/**
/**
* Returns the initial property map to be used.
* Returns the initial property map to be used.
...
@@ -53,13 +53,12 @@ public class JO extends ScriptObject {
...
@@ -53,13 +53,12 @@ public class JO extends ScriptObject {
}
}
/**
/**
* Constructor given an initial prototype and
an
initial property map.
* Constructor given an initial prototype and
the default
initial property map.
*
*
* @param proto the prototype object
* @param proto the prototype object
* @param map the property map
*/
*/
public
JO
(
final
ScriptObject
proto
,
final
PropertyMap
map
)
{
public
JO
(
final
ScriptObject
proto
)
{
super
(
proto
,
map
);
super
(
proto
,
getInitialMap
()
);
}
}
/**
/**
...
@@ -86,3 +85,4 @@ public class JO extends ScriptObject {
...
@@ -86,3 +85,4 @@ public class JO extends ScriptObject {
return
new
JO
(
map
);
return
new
JO
(
map
);
}
}
}
}
nashorn/test/script/nosecurity/JDK-8067215.js
0 → 100644
浏览文件 @
86e077f0
/*
* Copyright (c) 2010, 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-8067215: Disable dual fields when not using optimistic types
*
* @test
* @run
* @option -Dnashorn.debug=true
* @fork
*/
var
intType
=
Java
.
type
(
"
int
"
);
var
doubleType
=
Java
.
type
(
"
double
"
);
var
longType
=
Java
.
type
(
"
long
"
);
var
objectType
=
Java
.
type
(
"
java.lang.Object
"
);
var
Context
=
Java
.
type
(
"
jdk.nashorn.internal.runtime.Context
"
);
var
JSType
=
Java
.
type
(
"
jdk.nashorn.internal.runtime.JSType
"
);
var
context
=
Context
.
getContext
();
var
dualFields
=
context
.
useDualFields
();
var
optimisticTypes
=
context
.
getEnv
().
_optimistic_types
;
if
(
dualFields
!=
optimisticTypes
)
{
throw
new
Error
(
"
Wrong dual fields setting
"
);
}
function
testMap
(
obj
)
{
obj
.
x
=
"
foo
"
;
obj
[
"
y
"
]
=
0
;
Object
.
defineProperty
(
obj
,
"
z
"
,
{
value
:
0.5
});
var
map
=
Debug
.
map
(
obj
);
for
(
var
key
in
obj
)
{
var
prop
=
map
.
findProperty
(
key
);
if
(
prop
.
hasDualFields
()
!==
dualFields
)
{
throw
new
Error
(
"
Wrong property flags:
"
+
prop
);
}
if
(
prop
.
getType
()
!=
getExpectedType
(
obj
[
key
]))
{
throw
new
Error
(
"
Wrong property type:
"
+
prop
.
getType
()
+
"
//
"
+
getExpectedType
(
obj
[
key
]));
}
}
}
function
getExpectedType
(
value
)
{
if
(
!
dualFields
)
{
return
objectType
.
class
;
}
if
(
JSType
.
isRepresentableAsInt
(
value
))
{
return
intType
.
class
;
}
if
(
JSType
.
isRepresentableAsLong
(
value
))
{
return
longType
.
class
;
}
if
(
JSType
.
isNumber
(
value
))
{
return
doubleType
.
class
;
}
return
objectType
.
class
;
}
var
o
=
{
a
:
1
,
b
:
2.5
,
c
:
0x10000000000
,
d
:
true
};
function
C
()
{
this
.
a
=
1
;
this
.
b
=
2.5
;
this
.
c
=
0x10000000000
;
this
.
d
=
true
;
}
var
a
=
1
;
var
b
=
2.5
;
var
c
=
0x10000000000
;
var
d
=
true
;
testMap
(
o
);
testMap
(
new
C
());
testMap
(
JSON
.
parse
(
'
{ "a": 1, "b": 2.5, "c": 1099511627776, "d": true }
'
));
testMap
(
this
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录