Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
0e330311
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,发现更多精彩内容 >>
提交
0e330311
编写于
7月 05, 2013
作者:
H
hannesw
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8017084: Use spill properties for large object literals
Reviewed-by: lagergren, sundar
上级
874a8be8
变更
23
展开全部
隐藏空白更改
内联
并排
Showing
23 changed file
with
18050 addition
and
232 deletion
+18050
-232
nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
...src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
+2
-2
nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java
...rc/jdk/nashorn/internal/tools/nasgen/StringConstants.java
+1
-3
nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
+66
-71
nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
.../src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
+61
-8
nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
+8
-0
nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
+26
-12
nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
...rc/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
+9
-6
nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java
nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java
+13
-61
nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java
.../src/jdk/nashorn/internal/codegen/SpillObjectCreator.java
+134
-0
nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
+24
-0
nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
+27
-23
nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
+1
-1
nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
...orn/src/jdk/nashorn/internal/objects/NativeArguments.java
+1
-1
nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
...c/jdk/nashorn/internal/objects/NativeStrictArguments.java
+1
-1
nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
...orn/src/jdk/nashorn/internal/objects/PrototypeObject.java
+1
-1
nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
.../src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
+2
-2
nashorn/src/jdk/nashorn/internal/parser/Parser.java
nashorn/src/jdk/nashorn/internal/parser/Parser.java
+1
-1
nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
...rn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
+19
-7
nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
+12
-29
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
+2
-2
nashorn/src/jdk/nashorn/internal/scripts/JO.java
nashorn/src/jdk/nashorn/internal/scripts/JO.java
+1
-1
nashorn/test/script/basic/JDK-8017084.js
nashorn/test/script/basic/JDK-8017084.js
+17625
-0
nashorn/test/script/basic/JDK-8017084.js.EXPECTED
nashorn/test/script/basic/JDK-8017084.js.EXPECTED
+13
-0
未找到文件。
nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
浏览文件 @
0e330311
...
...
@@ -25,6 +25,7 @@
package
jdk.nashorn.internal.tools.nasgen
;
import
static
jdk
.
internal
.
org
.
objectweb
.
asm
.
Opcodes
.
ACC_FINAL
;
import
static
jdk
.
internal
.
org
.
objectweb
.
asm
.
Opcodes
.
ACC_PRIVATE
;
import
static
jdk
.
internal
.
org
.
objectweb
.
asm
.
Opcodes
.
ACC_PUBLIC
;
import
static
jdk
.
internal
.
org
.
objectweb
.
asm
.
Opcodes
.
ACC_STATIC
;
...
...
@@ -164,7 +165,6 @@ public class ClassGenerator {
mi
.
visitCode
();
mi
.
pushNull
();
mi
.
putStatic
(
className
,
MAP_FIELD_NAME
,
MAP_DESC
);
mi
.
loadClass
(
className
);
mi
.
invokeStatic
(
MAP_TYPE
,
MAP_NEWMAP
,
MAP_NEWMAP_DESC
);
// stack: PropertyMap
}
...
...
@@ -236,7 +236,7 @@ public class ClassGenerator {
static
void
addMapField
(
final
ClassVisitor
cv
)
{
// add a MAP static field
final
FieldVisitor
fv
=
cv
.
visitField
(
ACC_PRIVATE
|
ACC_STATIC
,
final
FieldVisitor
fv
=
cv
.
visitField
(
ACC_PRIVATE
|
ACC_STATIC
|
ACC_FINAL
,
MAP_FIELD_NAME
,
MAP_DESC
,
null
,
null
);
if
(
fv
!=
null
)
{
fv
.
visitEnd
();
...
...
nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java
浏览文件 @
0e330311
...
...
@@ -96,12 +96,10 @@ public interface StringConstants {
static
final
String
MAP_TYPE
=
TYPE_PROPERTYMAP
.
getInternalName
();
static
final
String
MAP_DESC
=
TYPE_PROPERTYMAP
.
getDescriptor
();
static
final
String
MAP_NEWMAP
=
"newMap"
;
static
final
String
MAP_NEWMAP_DESC
=
Type
.
getMethodDescriptor
(
TYPE_PROPERTYMAP
,
TYPE_CLASS
);
static
final
String
MAP_NEWMAP_DESC
=
Type
.
getMethodDescriptor
(
TYPE_PROPERTYMAP
);
static
final
String
MAP_DUPLICATE
=
"duplicate"
;
static
final
String
MAP_DUPLICATE_DESC
=
Type
.
getMethodDescriptor
(
TYPE_PROPERTYMAP
);
static
final
String
MAP_SETFLAGS
=
"setFlags"
;
static
final
String
LOOKUP_TYPE
=
TYPE_LOOKUP
.
getInternalName
();
static
final
String
LOOKUP_GETMETHOD
=
"getMethod"
;
static
final
String
LOOKUP_NEWPROPERTY
=
"newProperty"
;
static
final
String
LOOKUP_NEWPROPERTY_DESC
=
Type
.
getMethodDescriptor
(
TYPE_PROPERTYMAP
,
TYPE_PROPERTYMAP
,
TYPE_STRING
,
Type
.
INT_TYPE
,
TYPE_METHODHANDLE
,
TYPE_METHODHANDLE
);
...
...
nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
浏览文件 @
0e330311
...
...
@@ -179,6 +179,8 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
private
static
final
DebugLogger
LOG
=
new
DebugLogger
(
"codegen"
,
"nashorn.codegen.debug"
);
/** From what size should we use spill instead of fields for JavaScript objects? */
private
static
final
int
OBJECT_SPILL_THRESHOLD
=
300
;
/**
* Constructor.
...
...
@@ -942,7 +944,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
* Create a new object based on the symbols and values, generate
* bootstrap code for object
*/
final
FieldObjectCreator
<
Symbol
>
foc
=
new
FieldObjectCreator
<
Symbol
>(
this
,
nameList
,
newSymbols
,
values
,
true
,
hasArguments
)
{
new
FieldObjectCreator
<
Symbol
>(
this
,
nameList
,
newSymbols
,
values
,
true
,
hasArguments
)
{
@Override
protected
void
loadValue
(
final
Symbol
value
)
{
method
.
load
(
value
);
...
...
@@ -956,8 +958,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
m
.
loadNull
();
}
}
};
foc
.
makeObject
(
method
);
}.
makeObject
(
method
);
// runScript(): merge scope into global
if
(
isFunctionBody
&&
function
.
isProgram
())
{
...
...
@@ -1320,7 +1321,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
return
method
;
}
@SuppressWarnings
(
"rawtypes"
)
@Override
public
boolean
enterLiteralNode
(
final
LiteralNode
literalNode
)
{
assert
literalNode
.
getSymbol
()
!=
null
:
literalNode
+
" has no symbol"
;
...
...
@@ -1352,73 +1352,71 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
values
.
add
(
value
);
}
new
FieldObjectCreator
<
Node
>(
this
,
keys
,
symbols
,
values
)
{
@Override
protected
void
loadValue
(
final
Node
node
)
{
load
(
node
);
}
if
(
elements
.
size
()
>
OBJECT_SPILL_THRESHOLD
)
{
new
SpillObjectCreator
(
this
,
keys
,
symbols
,
values
).
makeObject
(
method
);
}
else
{
new
FieldObjectCreator
<
Node
>(
this
,
keys
,
symbols
,
values
)
{
@Override
protected
void
loadValue
(
final
Node
node
)
{
load
(
node
);
}
/**
* Ensure that the properties start out as object types so that
* we can do putfield initializations instead of dynamicSetIndex
* which would be the case to determine initial property type
* otherwise.
*
* Use case, it's very expensive to do a million var x = {a:obj, b:obj}
* just to have to invalidate them immediately on initialization
*
* see NASHORN-594
*/
@Override
protected
MapCreator
newMapCreator
(
final
Class
<?>
fieldObjectClass
)
{
return
new
MapCreator
(
fieldObjectClass
,
keys
,
symbols
)
{
@Override
protected
int
getPropertyFlags
(
final
Symbol
symbol
,
final
boolean
isVarArg
)
{
return
super
.
getPropertyFlags
(
symbol
,
isVarArg
)
|
Property
.
IS_ALWAYS_OBJECT
;
}
};
}
/**
* Ensure that the properties start out as object types so that
* we can do putfield initializations instead of dynamicSetIndex
* which would be the case to determine initial property type
* otherwise.
*
* Use case, it's very expensive to do a million var x = {a:obj, b:obj}
* just to have to invalidate them immediately on initialization
*
* see NASHORN-594
*/
@Override
protected
MapCreator
newMapCreator
(
final
Class
<?>
fieldObjectClass
)
{
return
new
MapCreator
(
fieldObjectClass
,
keys
,
symbols
)
{
@Override
protected
int
getPropertyFlags
(
final
Symbol
symbol
,
final
boolean
hasArguments
)
{
return
super
.
getPropertyFlags
(
symbol
,
hasArguments
)
|
Property
.
IS_ALWAYS_OBJECT
;
}
};
}
}.
makeObject
(
method
);
}.
makeObject
(
method
);
}
method
.
dup
();
globalObjectPrototype
();
method
.
invoke
(
ScriptObject
.
SET_PROTO
);
if
(
!
hasGettersSetters
)
{
method
.
store
(
objectNode
.
getSymbol
());
return
false
;
}
if
(
hasGettersSetters
)
{
for
(
final
PropertyNode
propertyNode
:
elements
)
{
final
FunctionNode
getter
=
propertyNode
.
getGetter
()
;
final
FunctionNode
setter
=
propertyNode
.
getSetter
();
for
(
final
Node
element
:
elements
)
{
final
PropertyNode
propertyNode
=
(
PropertyNode
)
element
;
final
Object
key
=
propertyNode
.
getKey
();
final
FunctionNode
getter
=
propertyNode
.
getGetter
();
final
FunctionNode
setter
=
propertyNode
.
getSetter
();
if
(
getter
==
null
&&
setter
==
null
)
{
continue
;
}
if
(
getter
==
null
&&
setter
==
null
)
{
continue
;
}
method
.
dup
().
loadKey
(
propertyNode
.
getKey
());
method
.
dup
().
loadKey
(
key
);
if
(
getter
==
null
)
{
method
.
loadNull
();
}
else
{
getter
.
accept
(
this
);
}
if
(
g
etter
==
null
)
{
method
.
loadNull
();
}
else
{
g
etter
.
accept
(
this
);
}
if
(
s
etter
==
null
)
{
method
.
loadNull
();
}
else
{
s
etter
.
accept
(
this
);
}
if
(
setter
==
null
)
{
method
.
loadNull
();
}
else
{
setter
.
accept
(
this
);
method
.
invoke
(
ScriptObject
.
SET_USER_ACCESSORS
);
}
method
.
invoke
(
ScriptObject
.
SET_USER_ACCESSORS
);
}
method
.
store
(
objectNode
.
getSymbol
());
return
false
;
}
...
...
@@ -3183,24 +3181,21 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
return
;
}
final
boolean
isLazy
=
functionNode
.
isLazy
();
new
ObjectCreator
(
this
,
new
ArrayList
<
String
>(),
new
ArrayList
<
Symbol
>(),
false
,
false
)
{
@Override
protected
void
makeObject
(
final
MethodEmitter
m
)
{
final
String
className
=
SCRIPTFUNCTION_IMPL_OBJECT
;
// Generate the object class and property map in case this function is ever used as constructor
final
String
className
=
SCRIPTFUNCTION_IMPL_OBJECT
;
final
int
fieldCount
=
ObjectClassGenerator
.
getPaddedFieldCount
(
functionNode
.
countThisProperties
());
final
String
allocatorClassName
=
Compiler
.
binaryName
(
ObjectClassGenerator
.
getClassName
(
fieldCount
));
final
PropertyMap
allocatorMap
=
PropertyMap
.
newMap
(
null
,
0
,
fieldCount
,
0
);
m
.
_new
(
className
).
dup
();
loadConstant
(
new
RecompilableScriptFunctionData
(
functionNode
,
compiler
.
getCodeInstaller
(),
Compiler
.
binaryName
(
getClassName
()),
makeMap
()
));
method
.
_new
(
className
).
dup
();
loadConstant
(
new
RecompilableScriptFunctionData
(
functionNode
,
compiler
.
getCodeInstaller
(),
allocatorClassName
,
allocatorMap
));
if
(
isLazy
||
functionNode
.
needsParentScope
())
{
m
.
loadCompilerConstant
(
SCOPE
);
}
else
{
m
.
loadNull
();
}
m
.
invoke
(
constructorNoLookup
(
className
,
RecompilableScriptFunctionData
.
class
,
ScriptObject
.
class
));
}
}.
makeObject
(
method
);
if
(
functionNode
.
isLazy
()
||
functionNode
.
needsParentScope
())
{
method
.
loadCompilerConstant
(
SCOPE
);
}
else
{
method
.
loadNull
();
}
method
.
invoke
(
constructorNoLookup
(
className
,
RecompilableScriptFunctionData
.
class
,
ScriptObject
.
class
));
}
// calls on Global class.
...
...
nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
浏览文件 @
0e330311
...
...
@@ -26,15 +26,16 @@
package
jdk.nashorn.internal.codegen
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
ARGUMENTS
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
SCOPE
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
constructorNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
typeDescriptor
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
getPaddedFieldCount
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
types
.
Type
.
OBJECT
;
import
java.util.Iterator
;
import
java.util.List
;
import
jdk.nashorn.internal.codegen.types.Type
;
import
jdk.nashorn.internal.ir.Symbol
;
import
jdk.nashorn.internal.runtime.Context
;
import
jdk.nashorn.internal.runtime.PropertyMap
;
import
jdk.nashorn.internal.runtime.ScriptObject
;
import
jdk.nashorn.internal.runtime.arrays.ArrayIndex
;
...
...
@@ -48,6 +49,13 @@ import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
* @see jdk.nashorn.internal.ir.Node
*/
public
abstract
class
FieldObjectCreator
<
T
>
extends
ObjectCreator
{
private
String
fieldObjectClassName
;
private
Class
<?>
fieldObjectClass
;
private
int
fieldCount
;
private
int
paddedFieldCount
;
private
int
paramCount
;
/** array of corresponding values to symbols (null for no values) */
private
final
List
<
T
>
values
;
...
...
@@ -80,14 +88,9 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator {
super
(
codegen
,
keys
,
symbols
,
isScope
,
hasArguments
);
this
.
values
=
values
;
this
.
callSiteFlags
=
codegen
.
getCallSiteFlags
();
}
/**
* Loads the scope on the stack through the passed method emitter.
* @param method the method emitter to use
*/
protected
void
loadScope
(
final
MethodEmitter
method
)
{
method
.
loadCompilerConstant
(
SCOPE
);
countFields
();
findClass
();
}
/**
...
...
@@ -137,6 +140,13 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator {
}
}
@Override
protected
PropertyMap
makeMap
()
{
assert
propertyMap
==
null
:
"property map already initialized"
;
propertyMap
=
newMapCreator
(
fieldObjectClass
).
makeFieldMap
(
hasArguments
(),
fieldCount
,
paddedFieldCount
);
return
propertyMap
;
}
/**
* Technique for loading an initial value. Defined by anonymous subclasses in code gen.
*
...
...
@@ -173,4 +183,47 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator {
loadValue
(
value
);
method
.
dynamicSetIndex
(
callSiteFlags
);
}
/**
* Locate (or indirectly create) the object container class.
*/
private
void
findClass
()
{
fieldObjectClassName
=
isScope
()
?
ObjectClassGenerator
.
getClassName
(
fieldCount
,
paramCount
)
:
ObjectClassGenerator
.
getClassName
(
paddedFieldCount
);
try
{
this
.
fieldObjectClass
=
Context
.
forStructureClass
(
Compiler
.
binaryName
(
fieldObjectClassName
));
}
catch
(
final
ClassNotFoundException
e
)
{
throw
new
AssertionError
(
"Nashorn has encountered an internal error. Structure can not be created."
);
}
}
/**
* Get the class name for the object class,
* e.g. {@code com.nashorn.oracle.scripts.JO2P0}
*
* @return script class name
*/
String
getClassName
()
{
return
fieldObjectClassName
;
}
/**
* Tally the number of fields and parameters.
*/
private
void
countFields
()
{
for
(
final
Symbol
symbol
:
this
.
symbols
)
{
if
(
symbol
!=
null
)
{
if
(
hasArguments
()
&&
symbol
.
isParam
())
{
symbol
.
setFieldIndex
(
paramCount
++);
}
else
{
symbol
.
setFieldIndex
(
fieldCount
++);
}
}
}
paddedFieldCount
=
getPaddedFieldCount
(
fieldCount
);
}
}
nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
浏览文件 @
0e330311
...
...
@@ -175,6 +175,14 @@ final class FinalizeTypes extends NodeOperatorVisitor<LexicalContext> {
if
(
destType
==
null
)
{
destType
=
specBinaryNode
.
getType
();
}
// Register assignments to this object in case this is used as constructor
if
(
binaryNode
.
lhs
()
instanceof
AccessNode
)
{
AccessNode
accessNode
=
(
AccessNode
)
binaryNode
.
lhs
();
if
(
accessNode
.
getBase
().
getSymbol
().
isThis
())
{
lc
.
getCurrentFunction
().
addThisProperty
(
accessNode
.
getProperty
().
getName
());
}
}
return
specBinaryNode
.
setRHS
(
convert
(
specBinaryNode
.
rhs
(),
destType
));
}
...
...
nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
浏览文件 @
0e330311
...
...
@@ -41,10 +41,10 @@ public class MapCreator {
private
final
Class
<?>
structure
;
/** key set for object map */
private
final
String
[]
keys
;
final
List
<
String
>
keys
;
/** corresponding symbol set for object map */
private
final
Symbol
[]
symbols
;
final
List
<
Symbol
>
symbols
;
/**
* Constructor
...
...
@@ -54,11 +54,9 @@ public class MapCreator {
* @param symbols list of symbols for map
*/
MapCreator
(
final
Class
<?>
structure
,
final
List
<
String
>
keys
,
final
List
<
Symbol
>
symbols
)
{
final
int
size
=
keys
.
size
();
this
.
structure
=
structure
;
this
.
keys
=
keys
.
toArray
(
new
String
[
size
])
;
this
.
symbols
=
symbols
.
toArray
(
new
Symbol
[
size
])
;
this
.
keys
=
keys
;
this
.
symbols
=
symbols
;
}
/**
...
...
@@ -70,21 +68,37 @@ public class MapCreator {
*
* @return New map populated with accessor properties.
*/
PropertyMap
makeMap
(
final
boolean
hasArguments
,
final
int
fieldCount
,
final
int
fieldMaximum
)
{
PropertyMap
make
Field
Map
(
final
boolean
hasArguments
,
final
int
fieldCount
,
final
int
fieldMaximum
)
{
final
List
<
Property
>
properties
=
new
ArrayList
<>();
assert
keys
!=
null
;
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
final
String
key
=
keys
[
i
]
;
final
Symbol
symbol
=
symbols
[
i
]
;
for
(
int
i
=
0
,
length
=
keys
.
size
();
i
<
length
;
i
++)
{
final
String
key
=
keys
.
get
(
i
)
;
final
Symbol
symbol
=
symbols
.
get
(
i
)
;
if
(
symbol
!=
null
&&
!
ArrayIndex
.
isIntArrayIndex
(
key
))
{
properties
.
add
(
new
AccessorProperty
(
key
,
getPropertyFlags
(
symbol
,
hasArguments
),
structure
,
symbol
.
getFieldIndex
()));
}
}
return
PropertyMap
.
newMap
(
structure
,
properties
,
fieldCount
,
fieldMaximum
);
return
PropertyMap
.
newMap
(
properties
,
fieldCount
,
fieldMaximum
,
0
);
}
PropertyMap
makeSpillMap
(
final
boolean
hasArguments
)
{
final
List
<
Property
>
properties
=
new
ArrayList
<>();
int
spillIndex
=
0
;
assert
keys
!=
null
;
for
(
int
i
=
0
,
length
=
keys
.
size
();
i
<
length
;
i
++)
{
final
String
key
=
keys
.
get
(
i
);
final
Symbol
symbol
=
symbols
.
get
(
i
);
if
(
symbol
!=
null
&&
!
ArrayIndex
.
isIntArrayIndex
(
key
))
{
properties
.
add
(
new
AccessorProperty
(
key
,
getPropertyFlags
(
symbol
,
hasArguments
),
spillIndex
++));
}
}
return
PropertyMap
.
newMap
(
properties
,
0
,
0
,
spillIndex
);
}
/**
...
...
nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
浏览文件 @
0e330311
...
...
@@ -73,11 +73,6 @@ public final class ObjectClassGenerator {
*/
static
final
int
FIELD_PADDING
=
4
;
/**
* Rounding when calculating the number of fields.
*/
static
final
int
FIELD_ROUNDING
=
4
;
/**
* Debug field logger
* Should we print debugging information for fields when they are generated and getters/setters are called?
...
...
@@ -325,7 +320,6 @@ public final class ObjectClassGenerator {
final
List
<
String
>
initFields
=
addFields
(
classEmitter
,
fieldCount
);
final
MethodEmitter
init
=
newInitMethod
(
classEmitter
);
initializeToUndefined
(
init
,
className
,
initFields
);
init
.
returnVoid
();
init
.
end
();
...
...
@@ -709,6 +703,15 @@ public final class ObjectClassGenerator {
}
}
/**
* Add padding to field count to avoid creating too many classes and have some spare fields
* @param count the field count
* @return the padded field count
*/
static
int
getPaddedFieldCount
(
final
int
count
)
{
return
count
/
FIELD_PADDING
*
FIELD_PADDING
+
FIELD_PADDING
;
}
//
// Provide generic getters and setters for undefined types. If a type is undefined, all
// and marshals the set to the correct setter depending on the type of the value being set.
...
...
nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java
浏览文件 @
0e330311
...
...
@@ -25,10 +25,10 @@
package
jdk.nashorn.internal.codegen
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
SCOPE
;
import
java.util.List
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
ObjectClassGenerator
.
FIELD_PADDING
;
import
jdk.nashorn.internal.ir.Symbol
;
import
jdk.nashorn.internal.runtime.Context
;
import
jdk.nashorn.internal.runtime.PropertyMap
;
/**
...
...
@@ -36,9 +36,6 @@ import jdk.nashorn.internal.runtime.PropertyMap;
*/
public
abstract
class
ObjectCreator
{
/** Compile unit for this ObjectCreator, see CompileUnit */
//protected final CompileUnit compileUnit;
/** List of keys to initiate in this ObjectCreator */
protected
final
List
<
String
>
keys
;
...
...
@@ -50,12 +47,7 @@ public abstract class ObjectCreator {
private
final
boolean
isScope
;
private
final
boolean
hasArguments
;
private
int
fieldCount
;
private
int
paddedFieldCount
;
private
int
paramCount
;
private
String
fieldObjectClassName
;
private
Class
<?>
fieldObjectClass
;
private
PropertyMap
propertyMap
;
protected
PropertyMap
propertyMap
;
/**
* Constructor
...
...
@@ -72,41 +64,6 @@ public abstract class ObjectCreator {
this
.
symbols
=
symbols
;
this
.
isScope
=
isScope
;
this
.
hasArguments
=
hasArguments
;
countFields
();
findClass
();
}
/**
* Tally the number of fields and parameters.
*/
private
void
countFields
()
{
for
(
final
Symbol
symbol
:
this
.
symbols
)
{
if
(
symbol
!=
null
)
{
if
(
hasArguments
()
&&
symbol
.
isParam
())
{
symbol
.
setFieldIndex
(
paramCount
++);
}
else
{
symbol
.
setFieldIndex
(
fieldCount
++);
}
}
}
paddedFieldCount
=
fieldCount
+
FIELD_PADDING
;
}
/**
* Locate (or indirectly create) the object container class.
*/
private
void
findClass
()
{
fieldObjectClassName
=
isScope
()
?
ObjectClassGenerator
.
getClassName
(
fieldCount
,
paramCount
)
:
ObjectClassGenerator
.
getClassName
(
paddedFieldCount
);
try
{
this
.
fieldObjectClass
=
Context
.
forStructureClass
(
Compiler
.
binaryName
(
fieldObjectClassName
));
}
catch
(
final
ClassNotFoundException
e
)
{
throw
new
AssertionError
(
"Nashorn has encountered an internal error. Structure can not be created."
);
}
}
/**
...
...
@@ -115,6 +72,12 @@ public abstract class ObjectCreator {
*/
protected
abstract
void
makeObject
(
final
MethodEmitter
method
);
/**
* Construct the property map appropriate for the object.
* @return the newly created property map
*/
protected
abstract
PropertyMap
makeMap
();
/**
* Create a new MapCreator
* @param clazz type of MapCreator
...
...
@@ -125,12 +88,11 @@ public abstract class ObjectCreator {
}
/**
*
Construct the property map appropriate for the object
.
* @
return the newly created property map
*
Loads the scope on the stack through the passed method emitter
.
* @
param method the method emitter to use
*/
protected
PropertyMap
makeMap
()
{
propertyMap
=
newMapCreator
(
fieldObjectClass
).
makeMap
(
hasArguments
(),
fieldCount
,
paddedFieldCount
);
return
propertyMap
;
protected
void
loadScope
(
final
MethodEmitter
method
)
{
method
.
loadCompilerConstant
(
SCOPE
);
}
/**
...
...
@@ -143,16 +105,6 @@ public abstract class ObjectCreator {
return
method
;
}
/**
* Get the class name for the object class,
* e.g. {@code com.nashorn.oracle.scripts.JO2P0}
*
* @return script class name
*/
String
getClassName
()
{
return
fieldObjectClassName
;
}
/**
* Is this a scope object
* @return true if scope
...
...
nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java
0 → 100644
浏览文件 @
0e330311
/*
* Copyright (c) 2010-2013, 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.codegen
;
import
jdk.nashorn.internal.codegen.types.Type
;
import
jdk.nashorn.internal.ir.LiteralNode
;
import
jdk.nashorn.internal.ir.Node
;
import
jdk.nashorn.internal.ir.Symbol
;
import
jdk.nashorn.internal.runtime.Property
;
import
jdk.nashorn.internal.runtime.PropertyMap
;
import
jdk.nashorn.internal.runtime.ScriptObject
;
import
jdk.nashorn.internal.scripts.JO
;
import
java.util.List
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
CompilerConstants
.
constructorNoLookup
;
import
static
jdk
.
nashorn
.
internal
.
codegen
.
types
.
Type
.
OBJECT
;
/**
* An object creator that uses spill properties.
*/
public
class
SpillObjectCreator
extends
ObjectCreator
{
private
final
List
<
Node
>
values
;
/**
* Constructor
*
* @param codegen code generator
* @param keys keys for fields in object
* @param symbols symbols for fields in object
* @param values list of values corresponding to keys
*/
protected
SpillObjectCreator
(
final
CodeGenerator
codegen
,
final
List
<
String
>
keys
,
final
List
<
Symbol
>
symbols
,
final
List
<
Node
>
values
)
{
super
(
codegen
,
keys
,
symbols
,
false
,
false
);
this
.
values
=
values
;
makeMap
();
}
@Override
protected
void
makeObject
(
final
MethodEmitter
method
)
{
assert
!
isScope
()
:
"spill scope objects are not currently supported"
;
final
int
length
=
keys
.
size
();
final
Object
[]
presetValues
=
new
Object
[
propertyMap
.
size
()];
final
Class
clazz
=
JO
.
class
;
// Compute constant values
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
final
String
key
=
keys
.
get
(
i
);
final
Property
property
=
propertyMap
.
findProperty
(
key
);
if
(
property
!=
null
)
{
presetValues
[
property
.
getSlot
()]
=
LiteralNode
.
objectAsConstant
(
values
.
get
(
i
));
}
}
method
.
_new
(
clazz
).
dup
();
codegen
.
loadConstant
(
propertyMap
);
method
.
invoke
(
constructorNoLookup
(
JO
.
class
,
PropertyMap
.
class
));
method
.
dup
();
codegen
.
loadConstant
(
presetValues
);
// Create properties with non-constant values
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
final
String
key
=
keys
.
get
(
i
);
final
Property
property
=
propertyMap
.
findProperty
(
key
);
if
(
property
!=
null
&&
presetValues
[
property
.
getSlot
()]
==
LiteralNode
.
POSTSET_MARKER
)
{
method
.
dup
();
method
.
load
(
property
.
getSlot
());
codegen
.
load
(
values
.
get
(
i
)).
convert
(
OBJECT
);
method
.
arraystore
();
presetValues
[
property
.
getSlot
()]
=
null
;
}
}
method
.
putField
(
Type
.
typeFor
(
ScriptObject
.
class
).
getInternalName
(),
"spill"
,
Type
.
OBJECT_ARRAY
.
getDescriptor
());
final
int
callSiteFlags
=
codegen
.
getCallSiteFlags
();
// Assign properties with valid array index keys
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
final
String
key
=
keys
.
get
(
i
);
final
Property
property
=
propertyMap
.
findProperty
(
key
);
final
Node
value
=
values
.
get
(
i
);
if
(
property
==
null
&&
value
!=
null
)
{
method
.
dup
();
method
.
load
(
keys
.
get
(
i
));
codegen
.
load
(
value
);
method
.
dynamicSetIndex
(
callSiteFlags
);
}
}
}
@Override
protected
PropertyMap
makeMap
()
{
assert
propertyMap
==
null
:
"property map already initialized"
;
propertyMap
=
new
MapCreator
(
JO
.
class
,
keys
,
symbols
)
{
@Override
protected
int
getPropertyFlags
(
Symbol
symbol
,
boolean
hasArguments
)
{
return
super
.
getPropertyFlags
(
symbol
,
hasArguments
)
|
Property
.
IS_SPILL
|
Property
.
IS_ALWAYS_OBJECT
;
}
}.
makeSpillMap
(
false
);
return
propertyMap
;
}
}
nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
浏览文件 @
0e330311
...
...
@@ -131,6 +131,10 @@ public final class FunctionNode extends LexicalContextNode implements Flags<Func
@Ignore
private
final
Compiler
.
Hints
hints
;
/** Properties of this object assigned in this function */
@Ignore
private
HashSet
<
String
>
thisProperties
;
/** Function flags. */
private
final
int
flags
;
...
...
@@ -277,6 +281,7 @@ public final class FunctionNode extends LexicalContextNode implements Flags<Func
this
.
declaredSymbols
=
functionNode
.
declaredSymbols
;
this
.
kind
=
functionNode
.
kind
;
this
.
firstToken
=
functionNode
.
firstToken
;
this
.
thisProperties
=
functionNode
.
thisProperties
;
}
@Override
...
...
@@ -613,6 +618,25 @@ public final class FunctionNode extends LexicalContextNode implements Flags<Func
return
getFlag
(
NEEDS_PARENT_SCOPE
)
||
isProgram
();
}
/**
* Register a property assigned to the this object in this function.
* @param key the property name
*/
public
void
addThisProperty
(
final
String
key
)
{
if
(
thisProperties
==
null
)
{
thisProperties
=
new
HashSet
<>();
}
thisProperties
.
add
(
key
);
}
/**
* Get the number of properties assigned to the this object in this function.
* @return number of properties
*/
public
int
countThisProperties
()
{
return
thisProperties
==
null
?
0
:
thisProperties
.
size
();
}
/**
* Return the kind of this function
* @see FunctionNode.Kind
...
...
nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
浏览文件 @
0e330311
...
...
@@ -49,6 +49,9 @@ public abstract class LiteralNode<T> extends Node implements PropertyKey {
/** Literal value */
protected
final
T
value
;
/** Marker for values that must be computed at runtime */
public
static
final
Object
POSTSET_MARKER
=
new
Object
();
/**
* Constructor
*
...
...
@@ -495,6 +498,30 @@ public abstract class LiteralNode<T> extends Node implements PropertyKey {
return
new
LexerTokenLiteralNode
(
parent
.
getToken
(),
parent
.
getFinish
(),
value
);
}
/**
* Get the constant value for an object, or {@link #POSTSET_MARKER} if the value can't be statically computed.
*
* @param object a node or value object
* @return the constant value or {@code POSTSET_MARKER}
*/
public
static
Object
objectAsConstant
(
final
Object
object
)
{
if
(
object
==
null
)
{
return
null
;
}
else
if
(
object
instanceof
Number
||
object
instanceof
String
||
object
instanceof
Boolean
)
{
return
object
;
}
else
if
(
object
instanceof
LiteralNode
)
{
return
objectAsConstant
(((
LiteralNode
<?>)
object
).
getValue
());
}
else
if
(
object
instanceof
UnaryNode
)
{
final
UnaryNode
unaryNode
=
(
UnaryNode
)
object
;
if
(
unaryNode
.
isTokenType
(
TokenType
.
CONVERT
)
&&
unaryNode
.
getType
().
isObject
())
{
return
objectAsConstant
(
unaryNode
.
rhs
());
}
}
return
POSTSET_MARKER
;
}
private
static
final
class
NullLiteralNode
extends
LiteralNode
<
Object
>
{
private
NullLiteralNode
(
final
long
token
,
final
int
finish
)
{
...
...
@@ -525,11 +552,6 @@ public abstract class LiteralNode<T> extends Node implements PropertyKey {
* Array literal node class.
*/
public
static
final
class
ArrayLiteralNode
extends
LiteralNode
<
Node
[]>
{
private
static
class
PostsetMarker
{
//empty
}
private
static
PostsetMarker
POSTSET_MARKER
=
new
PostsetMarker
();
/** Array element type. */
private
Type
elementType
;
...
...
@@ -740,24 +762,6 @@ public abstract class LiteralNode<T> extends Node implements PropertyKey {
}
}
private
Object
objectAsConstant
(
final
Object
object
)
{
if
(
object
==
null
)
{
return
null
;
}
else
if
(
object
instanceof
Number
||
object
instanceof
String
||
object
instanceof
Boolean
)
{
return
object
;
}
else
if
(
object
instanceof
LiteralNode
)
{
return
objectAsConstant
(((
LiteralNode
<?>)
object
).
getValue
());
}
else
if
(
object
instanceof
UnaryNode
)
{
final
UnaryNode
unaryNode
=
(
UnaryNode
)
object
;
if
(
unaryNode
.
isTokenType
(
TokenType
.
CONVERT
)
&&
unaryNode
.
getType
().
isObject
())
{
return
objectAsConstant
(
unaryNode
.
rhs
());
}
}
return
POSTSET_MARKER
;
}
@Override
public
Node
[]
getArray
()
{
return
value
;
...
...
nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
浏览文件 @
0e330311
...
...
@@ -514,7 +514,7 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
type
(
"ArrayExpression"
);
comma
();
final
Node
[]
value
=
(
Node
[])
literalNode
.
getValue
();
final
Node
[]
value
=
literalNode
.
getArray
();
array
(
"elements"
,
Arrays
.
asList
(
value
));
}
else
{
type
(
"Literal"
);
...
...
nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
浏览文件 @
0e330311
...
...
@@ -64,7 +64,7 @@ public final class NativeArguments extends ScriptObject {
private
static
final
PropertyMap
map
$
;
static
{
PropertyMap
map
=
PropertyMap
.
newMap
(
NativeArguments
.
class
);
PropertyMap
map
=
PropertyMap
.
newMap
();
map
=
Lookup
.
newProperty
(
map
,
"length"
,
Property
.
NOT_ENUMERABLE
,
G
$LENGTH
,
S
$LENGTH
);
map
=
Lookup
.
newProperty
(
map
,
"callee"
,
Property
.
NOT_ENUMERABLE
,
G
$CALLEE
,
S
$CALLEE
);
map
$
=
map
;
...
...
nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
浏览文件 @
0e330311
...
...
@@ -54,7 +54,7 @@ public final class NativeStrictArguments extends ScriptObject {
private
static
final
PropertyMap
map
$
;
static
{
PropertyMap
map
=
PropertyMap
.
newMap
(
NativeStrictArguments
.
class
);
PropertyMap
map
=
PropertyMap
.
newMap
();
map
=
Lookup
.
newProperty
(
map
,
"length"
,
Property
.
NOT_ENUMERABLE
,
G
$LENGTH
,
S
$LENGTH
);
// In strict mode, the caller and callee properties should throw TypeError
// Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
...
...
nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
浏览文件 @
0e330311
...
...
@@ -52,7 +52,7 @@ public class PrototypeObject extends ScriptObject {
private
static
final
MethodHandle
SET_CONSTRUCTOR
=
findOwnMH
(
"setConstructor"
,
void
.
class
,
Object
.
class
,
Object
.
class
);
static
{
PropertyMap
map
=
PropertyMap
.
newMap
(
PrototypeObject
.
class
);
PropertyMap
map
=
PropertyMap
.
newMap
();
map
=
Lookup
.
newProperty
(
map
,
"constructor"
,
Property
.
NOT_ENUMERABLE
,
GET_CONSTRUCTOR
,
SET_CONSTRUCTOR
);
map
$
=
map
;
}
...
...
nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
浏览文件 @
0e330311
...
...
@@ -149,7 +149,7 @@ public class ScriptFunctionImpl extends ScriptFunction {
}
static
{
PropertyMap
map
=
PropertyMap
.
newMap
(
ScriptFunctionImpl
.
class
);
PropertyMap
map
=
PropertyMap
.
newMap
();
map
=
Lookup
.
newProperty
(
map
,
"prototype"
,
Property
.
NOT_ENUMERABLE
|
Property
.
NOT_CONFIGURABLE
,
G
$PROTOTYPE
,
S
$PROTOTYPE
);
map
=
Lookup
.
newProperty
(
map
,
"length"
,
Property
.
NOT_ENUMERABLE
|
Property
.
NOT_CONFIGURABLE
|
Property
.
NOT_WRITABLE
,
G
$LENGTH
,
null
);
map
=
Lookup
.
newProperty
(
map
,
"name"
,
Property
.
NOT_ENUMERABLE
|
Property
.
NOT_CONFIGURABLE
|
Property
.
NOT_WRITABLE
,
G
$NAME
,
null
);
...
...
@@ -201,7 +201,7 @@ public class ScriptFunctionImpl extends ScriptFunction {
// Instance of this class is used as global anonymous function which
// serves as Function.prototype object.
private
static
class
AnonymousFunction
extends
ScriptFunctionImpl
{
private
static
final
PropertyMap
nasgenmap
$$
=
PropertyMap
.
newMap
(
AnonymousFunction
.
class
);
private
static
final
PropertyMap
nasgenmap
$$
=
PropertyMap
.
newMap
();
AnonymousFunction
()
{
super
(
""
,
GlobalFunctions
.
ANONYMOUS
,
nasgenmap
$$
,
null
);
...
...
nashorn/src/jdk/nashorn/internal/parser/Parser.java
浏览文件 @
0e330311
...
...
@@ -2009,7 +2009,7 @@ loop:
}
if
(!
redefinitionOk
)
{
throw
error
(
AbstractParser
.
message
(
"property.redefinition"
,
key
.
toString
()
),
property
.
getToken
());
throw
error
(
AbstractParser
.
message
(
"property.redefinition"
,
key
),
property
.
getToken
());
}
PropertyNode
newProperty
=
existingProperty
;
...
...
nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
浏览文件 @
0e330311
...
...
@@ -140,8 +140,8 @@ public class AccessorProperty extends Property {
this
.
primitiveGetter
=
bindTo
(
property
.
primitiveGetter
,
delegate
);
this
.
primitiveSetter
=
bindTo
(
property
.
primitiveSetter
,
delegate
);
this
.
objectGetter
=
bindTo
(
property
.
objectGetter
,
delegate
);
this
.
objectSetter
=
bindTo
(
property
.
objectSetter
,
delegate
);
this
.
objectGetter
=
bindTo
(
property
.
ensureObjectGetter
()
,
delegate
);
this
.
objectSetter
=
bindTo
(
property
.
ensureObjectSetter
()
,
delegate
);
setCurrentType
(
property
.
getCurrentType
());
}
...
...
@@ -331,12 +331,26 @@ public class AccessorProperty extends Property {
}
}
@Override
p
ublic
MethodHandle
getGetter
(
final
Class
<?>
type
)
{
// Spill getters and setters are lazily initialized, see JDK-8011630
p
rivate
MethodHandle
ensureObjectGetter
(
)
{
if
(
isSpill
()
&&
objectGetter
==
null
)
{
objectGetter
=
getSpillGetter
();
}
return
objectGetter
;
}
private
MethodHandle
ensureObjectSetter
()
{
if
(
isSpill
()
&&
objectSetter
==
null
)
{
objectSetter
=
getSpillSetter
();
}
return
objectSetter
;
}
@Override
public
MethodHandle
getGetter
(
final
Class
<?>
type
)
{
final
int
i
=
getAccessorTypeIndex
(
type
);
ensureObjectGetter
();
if
(
getters
[
i
]
==
null
)
{
getters
[
i
]
=
debug
(
createGetter
(
currentType
,
type
,
primitiveGetter
,
objectGetter
),
...
...
@@ -372,9 +386,7 @@ public class AccessorProperty extends Property {
}
private
MethodHandle
generateSetter
(
final
Class
<?>
forType
,
final
Class
<?>
type
)
{
if
(
isSpill
()
&&
objectSetter
==
null
)
{
objectSetter
=
getSpillSetter
();
}
ensureObjectSetter
();
MethodHandle
mh
=
createSetter
(
forType
,
type
,
primitiveSetter
,
objectSetter
);
mh
=
debug
(
mh
,
currentType
,
type
,
"set"
);
return
mh
;
...
...
nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
浏览文件 @
0e330311
...
...
@@ -91,14 +91,16 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
/**
* Constructor.
*
* @param properties
A {@link PropertyHashMap} with initial contents.
* @param fieldCount
Number of fields in use.
* @param properties A {@link PropertyHashMap} with initial contents.
* @param fieldCount Number of fields in use.
* @param fieldMaximum Number of fields available.
* @param spillLength Number of spill slots used.
*/
private
PropertyMap
(
final
PropertyHashMap
properties
,
final
int
fieldCount
,
final
int
fieldMaximum
)
{
private
PropertyMap
(
final
PropertyHashMap
properties
,
final
int
fieldCount
,
final
int
fieldMaximum
,
final
int
spillLength
)
{
this
.
properties
=
properties
;
this
.
fieldCount
=
fieldCount
;
this
.
fieldMaximum
=
fieldMaximum
;
this
.
spillLength
=
spillLength
;
if
(
Context
.
DEBUG
)
{
count
++;
...
...
@@ -111,7 +113,7 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
* @param properties A {@link PropertyHashMap} with initial contents.
*/
private
PropertyMap
(
final
PropertyHashMap
properties
)
{
this
(
properties
,
0
,
0
);
this
(
properties
,
0
,
0
,
0
);
}
/**
...
...
@@ -159,42 +161,23 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
/**
* Public property map allocator.
*
* @param structure Class the map's {@link AccessorProperty}s apply to.
* @param properties Collection of initial properties.
* @param fieldCount Number of fields in use.
* @param properties Collection of initial properties.
* @param fieldCount Number of fields in use.
* @param fieldMaximum Number of fields available.
*
*
@param spillLength Number of used spill slots.
* @return New {@link PropertyMap}.
*/
public
static
PropertyMap
newMap
(
final
Class
<?>
structure
,
final
Collection
<
Property
>
properties
,
final
int
fieldCount
,
final
int
fieldMaximum
)
{
// Reduce the number of empty maps in the context.
if
(
structure
==
JO
.
class
)
{
return
EMPTY_MAP
;
}
public
static
PropertyMap
newMap
(
final
Collection
<
Property
>
properties
,
final
int
fieldCount
,
final
int
fieldMaximum
,
final
int
spillLength
)
{
PropertyHashMap
newProperties
=
EMPTY_HASHMAP
.
immutableAdd
(
properties
);
return
new
PropertyMap
(
newProperties
,
fieldCount
,
fieldMaximum
);
}
/**
* Public property map factory allocator
*
* @param structure Class the map's {@link AccessorProperty}s apply to.
*
* @return New {@link PropertyMap}.
*/
public
static
PropertyMap
newMap
(
final
Class
<?>
structure
)
{
return
newMap
(
structure
,
null
,
0
,
0
);
return
new
PropertyMap
(
newProperties
,
fieldCount
,
fieldMaximum
,
spillLength
);
}
/**
* Return a sharable empty map.
*
* @param context the context
* @return New empty {@link PropertyMap}.
*/
public
static
PropertyMap
new
EmptyMap
(
final
Context
context
)
{
public
static
PropertyMap
new
Map
(
)
{
return
new
PropertyMap
(
EMPTY_HASHMAP
);
}
...
...
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
浏览文件 @
0e330311
...
...
@@ -170,7 +170,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
this
.
arrayData
=
ArrayData
.
EMPTY_ARRAY
;
this
.
setMap
(
map
==
null
?
PropertyMap
.
newMap
(
getClass
()
)
:
map
);
this
.
setMap
(
map
==
null
?
PropertyMap
.
newMap
()
:
map
);
}
/**
...
...
@@ -188,7 +188,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
this
.
arrayData
=
ArrayData
.
EMPTY_ARRAY
;
this
.
setMap
(
map
==
null
?
PropertyMap
.
newMap
(
getClass
()
)
:
map
);
this
.
setMap
(
map
==
null
?
PropertyMap
.
newMap
()
:
map
);
this
.
proto
=
proto
;
if
(
proto
!=
null
)
{
...
...
nashorn/src/jdk/nashorn/internal/scripts/JO.java
浏览文件 @
0e330311
...
...
@@ -33,7 +33,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
*/
public
class
JO
extends
ScriptObject
{
private
static
final
PropertyMap
map
$
=
PropertyMap
.
newMap
(
JO
.
class
);
private
static
final
PropertyMap
map
$
=
PropertyMap
.
newMap
();
/**
* Returns the initial property map to be used.
...
...
nashorn/test/script/basic/JDK-8017084.js
0 → 100644
浏览文件 @
0e330311
此差异已折叠。
点击以展开。
nashorn/test/script/basic/JDK-8017084.js.EXPECTED
0 → 100644
浏览文件 @
0e330311
703
5624
17575
111
getting X
X
setting X
17577
111
aaa
hhh
yyy
X
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录