Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
7e35994f
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
7e35994f
编写于
9月 10, 2014
作者:
V
vlivanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8038261: JSR292: cache and reuse typed array accessors
Reviewed-by: vlivanov, psandoz Contributed-by: john.r.rose@oracle.com
上级
5cdd5a30
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
111 addition
and
40 deletion
+111
-40
src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
...re/classes/java/lang/invoke/InvokerBytecodeGenerator.java
+68
-0
src/share/classes/java/lang/invoke/MethodHandleImpl.java
src/share/classes/java/lang/invoke/MethodHandleImpl.java
+43
-40
未找到文件。
src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
浏览文件 @
7e35994f
...
@@ -35,6 +35,7 @@ import static java.lang.invoke.LambdaForm.*;
...
@@ -35,6 +35,7 @@ import static java.lang.invoke.LambdaForm.*;
import
static
java
.
lang
.
invoke
.
LambdaForm
.
BasicType
.*;
import
static
java
.
lang
.
invoke
.
LambdaForm
.
BasicType
.*;
import
static
java
.
lang
.
invoke
.
MethodHandleStatics
.*;
import
static
java
.
lang
.
invoke
.
MethodHandleStatics
.*;
import
static
java
.
lang
.
invoke
.
MethodHandleNatives
.
Constants
.*;
import
static
java
.
lang
.
invoke
.
MethodHandleNatives
.
Constants
.*;
import
java.lang.invoke.MethodHandleImpl.ArrayAccessor
;
import
sun.invoke.util.ValueConversions
;
import
sun.invoke.util.ValueConversions
;
import
sun.invoke.util.VerifyAccess
;
import
sun.invoke.util.VerifyAccess
;
import
sun.invoke.util.VerifyType
;
import
sun.invoke.util.VerifyType
;
...
@@ -427,6 +428,40 @@ class InvokerBytecodeGenerator {
...
@@ -427,6 +428,40 @@ class InvokerBytecodeGenerator {
emitStoreInsn
(
L_TYPE
,
index
);
emitStoreInsn
(
L_TYPE
,
index
);
}
}
private
byte
arrayTypeCode
(
Wrapper
elementType
)
{
switch
(
elementType
)
{
case
BOOLEAN:
return
Opcodes
.
T_BOOLEAN
;
case
BYTE:
return
Opcodes
.
T_BYTE
;
case
CHAR:
return
Opcodes
.
T_CHAR
;
case
SHORT:
return
Opcodes
.
T_SHORT
;
case
INT:
return
Opcodes
.
T_INT
;
case
LONG:
return
Opcodes
.
T_LONG
;
case
FLOAT:
return
Opcodes
.
T_FLOAT
;
case
DOUBLE:
return
Opcodes
.
T_DOUBLE
;
case
OBJECT:
return
0
;
// in place of Opcodes.T_OBJECT
default
:
throw
new
InternalError
();
}
}
private
int
arrayInsnOpcode
(
byte
tcode
,
int
aaop
)
throws
InternalError
{
assert
(
aaop
==
Opcodes
.
AASTORE
||
aaop
==
Opcodes
.
AALOAD
);
int
xas
;
switch
(
tcode
)
{
case
Opcodes
.
T_BOOLEAN
:
xas
=
Opcodes
.
BASTORE
;
break
;
case
Opcodes
.
T_BYTE
:
xas
=
Opcodes
.
BASTORE
;
break
;
case
Opcodes
.
T_CHAR
:
xas
=
Opcodes
.
CASTORE
;
break
;
case
Opcodes
.
T_SHORT
:
xas
=
Opcodes
.
SASTORE
;
break
;
case
Opcodes
.
T_INT
:
xas
=
Opcodes
.
IASTORE
;
break
;
case
Opcodes
.
T_LONG
:
xas
=
Opcodes
.
LASTORE
;
break
;
case
Opcodes
.
T_FLOAT
:
xas
=
Opcodes
.
FASTORE
;
break
;
case
Opcodes
.
T_DOUBLE
:
xas
=
Opcodes
.
DASTORE
;
break
;
case
0
:
xas
=
Opcodes
.
AASTORE
;
break
;
default
:
throw
new
InternalError
();
}
return
xas
-
Opcodes
.
AASTORE
+
aaop
;
}
private
void
freeFrameLocal
(
int
oldFrameLocal
)
{
private
void
freeFrameLocal
(
int
oldFrameLocal
)
{
int
i
=
indexForFrameLocal
(
oldFrameLocal
);
int
i
=
indexForFrameLocal
(
oldFrameLocal
);
if
(
i
<
0
)
return
;
if
(
i
<
0
)
return
;
...
@@ -616,6 +651,10 @@ class InvokerBytecodeGenerator {
...
@@ -616,6 +651,10 @@ class InvokerBytecodeGenerator {
i
=
i
+
2
;
// Jump to the end of GWC idiom
i
=
i
+
2
;
// Jump to the end of GWC idiom
}
else
if
(
isNewArray
(
rtype
,
name
))
{
}
else
if
(
isNewArray
(
rtype
,
name
))
{
emitNewArray
(
rtype
,
name
);
emitNewArray
(
rtype
,
name
);
}
else
if
(
isArrayLoad
(
member
))
{
emitArrayLoad
(
name
);
}
else
if
(
isArrayStore
(
member
))
{
emitArrayStore
(
name
);
}
else
if
(
isStaticallyInvocable
(
member
))
{
}
else
if
(
isStaticallyInvocable
(
member
))
{
emitStaticInvoke
(
name
);
emitStaticInvoke
(
name
);
}
else
{
}
else
{
...
@@ -634,6 +673,35 @@ class InvokerBytecodeGenerator {
...
@@ -634,6 +673,35 @@ class InvokerBytecodeGenerator {
return
classFile
;
return
classFile
;
}
}
boolean
isArrayLoad
(
MemberName
member
)
{
return
member
!=
null
&&
member
.
getDeclaringClass
()
==
ArrayAccessor
.
class
&&
member
.
getName
()
!=
null
&&
member
.
getName
().
startsWith
(
"getElement"
);
}
boolean
isArrayStore
(
MemberName
member
)
{
return
member
!=
null
&&
member
.
getDeclaringClass
()
==
ArrayAccessor
.
class
&&
member
.
getName
()
!=
null
&&
member
.
getName
().
startsWith
(
"setElement"
);
}
void
emitArrayLoad
(
Name
name
)
{
emitArrayOp
(
name
,
Opcodes
.
AALOAD
);
}
void
emitArrayStore
(
Name
name
)
{
emitArrayOp
(
name
,
Opcodes
.
AASTORE
);
}
void
emitArrayOp
(
Name
name
,
int
arrayOpcode
)
{
assert
arrayOpcode
==
Opcodes
.
AALOAD
||
arrayOpcode
==
Opcodes
.
AASTORE
;
Class
<?>
elementType
=
name
.
function
.
methodType
().
parameterType
(
0
).
getComponentType
();
assert
elementType
!=
null
;
emitPushArguments
(
name
);
if
(
elementType
.
isPrimitive
())
{
Wrapper
w
=
Wrapper
.
forPrimitiveType
(
elementType
);
arrayOpcode
=
arrayInsnOpcode
(
arrayTypeCode
(
w
),
arrayOpcode
);
}
mv
.
visitInsn
(
arrayOpcode
);
}
/**
/**
* Emit an invoke for the given name.
* Emit an invoke for the given name.
*/
*/
...
...
src/share/classes/java/lang/invoke/MethodHandleImpl.java
浏览文件 @
7e35994f
...
@@ -52,27 +52,54 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -52,27 +52,54 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
}
static
MethodHandle
makeArrayElementAccessor
(
Class
<?>
arrayClass
,
boolean
isSetter
)
{
static
MethodHandle
makeArrayElementAccessor
(
Class
<?>
arrayClass
,
boolean
isSetter
)
{
if
(
arrayClass
==
Object
[].
class
)
return
(
isSetter
?
ArrayAccessor
.
OBJECT_ARRAY_SETTER
:
ArrayAccessor
.
OBJECT_ARRAY_GETTER
);
if
(!
arrayClass
.
isArray
())
if
(!
arrayClass
.
isArray
())
throw
newIllegalArgumentException
(
"not an array: "
+
arrayClass
);
throw
newIllegalArgumentException
(
"not an array: "
+
arrayClass
);
MethodHandle
accessor
=
ArrayAccessor
.
getAccessor
(
arrayClass
,
isSetter
);
MethodHandle
[]
cache
=
ArrayAccessor
.
TYPED_ACCESSORS
.
get
(
arrayClass
);
MethodType
srcType
=
accessor
.
type
().
erase
();
int
cacheIndex
=
(
isSetter
?
ArrayAccessor
.
SETTER_INDEX
:
ArrayAccessor
.
GETTER_INDEX
);
MethodType
lambdaType
=
srcType
.
invokerType
();
MethodHandle
mh
=
cache
[
cacheIndex
];
Name
[]
names
=
arguments
(
1
,
lambdaType
);
if
(
mh
!=
null
)
return
mh
;
Name
[]
args
=
Arrays
.
copyOfRange
(
names
,
1
,
1
+
srcType
.
parameterCount
());
mh
=
ArrayAccessor
.
getAccessor
(
arrayClass
,
isSetter
);
names
[
names
.
length
-
1
]
=
new
Name
(
accessor
.
asType
(
srcType
),
(
Object
[])
args
);
MethodType
correctType
=
ArrayAccessor
.
correctType
(
arrayClass
,
isSetter
);
LambdaForm
form
=
new
LambdaForm
(
"getElement"
,
lambdaType
.
parameterCount
(),
names
);
if
(
mh
.
type
()
!=
correctType
)
{
MethodHandle
mh
=
SimpleMethodHandle
.
make
(
srcType
,
form
);
assert
(
mh
.
type
().
parameterType
(
0
)
==
Object
[].
class
);
if
(
ArrayAccessor
.
needCast
(
arrayClass
))
{
assert
((
isSetter
?
mh
.
type
().
parameterType
(
2
)
:
mh
.
type
().
returnType
())
==
Object
.
class
);
mh
=
mh
.
bindTo
(
arrayClass
);
assert
(
isSetter
||
correctType
.
parameterType
(
0
).
getComponentType
()
==
correctType
.
returnType
());
}
// safe to view non-strictly, because element type follows from array type
mh
=
mh
.
asType
(
ArrayAccessor
.
correctType
(
arrayClass
,
isSetter
));
mh
=
mh
.
viewAsType
(
correctType
);
}
// Atomically update accessor cache.
synchronized
(
cache
)
{
if
(
cache
[
cacheIndex
]
==
null
)
{
cache
[
cacheIndex
]
=
mh
;
}
else
{
// Throw away newly constructed accessor and use cached version.
mh
=
cache
[
cacheIndex
];
}
}
return
mh
;
return
mh
;
}
}
static
final
class
ArrayAccessor
{
static
final
class
ArrayAccessor
{
/// Support for array element access
/// Support for array element access
static
final
HashMap
<
Class
<?>,
MethodHandle
>
GETTER_CACHE
=
new
HashMap
<>();
// TODO use it
static
final
int
GETTER_INDEX
=
0
,
SETTER_INDEX
=
1
,
INDEX_LIMIT
=
2
;
static
final
HashMap
<
Class
<?>,
MethodHandle
>
SETTER_CACHE
=
new
HashMap
<>();
// TODO use it
static
final
ClassValue
<
MethodHandle
[]>
TYPED_ACCESSORS
=
new
ClassValue
<
MethodHandle
[]>()
{
@Override
protected
MethodHandle
[]
computeValue
(
Class
<?>
type
)
{
return
new
MethodHandle
[
INDEX_LIMIT
];
}
};
static
final
MethodHandle
OBJECT_ARRAY_GETTER
,
OBJECT_ARRAY_SETTER
;
static
{
MethodHandle
[]
cache
=
TYPED_ACCESSORS
.
get
(
Object
[].
class
);
cache
[
GETTER_INDEX
]
=
OBJECT_ARRAY_GETTER
=
getAccessor
(
Object
[].
class
,
false
);
cache
[
SETTER_INDEX
]
=
OBJECT_ARRAY_SETTER
=
getAccessor
(
Object
[].
class
,
true
);
assert
(
InvokerBytecodeGenerator
.
isStaticallyInvocable
(
ArrayAccessor
.
OBJECT_ARRAY_GETTER
.
internalMemberName
()));
assert
(
InvokerBytecodeGenerator
.
isStaticallyInvocable
(
ArrayAccessor
.
OBJECT_ARRAY_SETTER
.
internalMemberName
()));
}
static
int
getElementI
(
int
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
int
getElementI
(
int
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
long
getElementJ
(
long
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
long
getElementJ
(
long
[]
a
,
int
i
)
{
return
a
[
i
];
}
...
@@ -94,45 +121,21 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -94,45 +121,21 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static
void
setElementC
(
char
[]
a
,
int
i
,
char
x
)
{
a
[
i
]
=
x
;
}
static
void
setElementC
(
char
[]
a
,
int
i
,
char
x
)
{
a
[
i
]
=
x
;
}
static
void
setElementL
(
Object
[]
a
,
int
i
,
Object
x
)
{
a
[
i
]
=
x
;
}
static
void
setElementL
(
Object
[]
a
,
int
i
,
Object
x
)
{
a
[
i
]
=
x
;
}
static
Object
getElementL
(
Class
<?>
arrayClass
,
Object
[]
a
,
int
i
)
{
arrayClass
.
cast
(
a
);
return
a
[
i
];
}
static
void
setElementL
(
Class
<?>
arrayClass
,
Object
[]
a
,
int
i
,
Object
x
)
{
arrayClass
.
cast
(
a
);
a
[
i
]
=
x
;
}
// Weakly typed wrappers of Object[] accessors:
static
Object
getElementL
(
Object
a
,
int
i
)
{
return
getElementL
((
Object
[])
a
,
i
);
}
static
void
setElementL
(
Object
a
,
int
i
,
Object
x
)
{
setElementL
((
Object
[])
a
,
i
,
x
);
}
static
Object
getElementL
(
Object
arrayClass
,
Object
a
,
int
i
)
{
return
getElementL
((
Class
<?>)
arrayClass
,
(
Object
[])
a
,
i
);
}
static
void
setElementL
(
Object
arrayClass
,
Object
a
,
int
i
,
Object
x
)
{
setElementL
((
Class
<?>)
arrayClass
,
(
Object
[])
a
,
i
,
x
);
}
static
boolean
needCast
(
Class
<?>
arrayClass
)
{
Class
<?>
elemClass
=
arrayClass
.
getComponentType
();
return
!
elemClass
.
isPrimitive
()
&&
elemClass
!=
Object
.
class
;
}
static
String
name
(
Class
<?>
arrayClass
,
boolean
isSetter
)
{
static
String
name
(
Class
<?>
arrayClass
,
boolean
isSetter
)
{
Class
<?>
elemClass
=
arrayClass
.
getComponentType
();
Class
<?>
elemClass
=
arrayClass
.
getComponentType
();
if
(
elemClass
==
null
)
throw
newIllegalArgumentException
(
"not an array"
,
arrayClass
);
if
(
elemClass
==
null
)
throw
newIllegalArgumentException
(
"not an array"
,
arrayClass
);
return
(!
isSetter
?
"getElement"
:
"setElement"
)
+
Wrapper
.
basicTypeChar
(
elemClass
);
return
(!
isSetter
?
"getElement"
:
"setElement"
)
+
Wrapper
.
basicTypeChar
(
elemClass
);
}
}
static
final
boolean
USE_WEAKLY_TYPED_ARRAY_ACCESSORS
=
false
;
// FIXME: decide
static
MethodType
type
(
Class
<?>
arrayClass
,
boolean
isSetter
)
{
static
MethodType
type
(
Class
<?>
arrayClass
,
boolean
isSetter
)
{
Class
<?>
elemClass
=
arrayClass
.
getComponentType
();
Class
<?>
elemClass
=
arrayClass
.
getComponentType
();
Class
<?>
arrayArgClass
=
arrayClass
;
Class
<?>
arrayArgClass
=
arrayClass
;
if
(!
elemClass
.
isPrimitive
())
{
if
(!
elemClass
.
isPrimitive
())
{
arrayArgClass
=
Object
[].
class
;
arrayArgClass
=
Object
[].
class
;
if
(
USE_WEAKLY_TYPED_ARRAY_ACCESSORS
)
elemClass
=
Object
.
class
;
arrayArgClass
=
Object
.
class
;
}
}
if
(!
needCast
(
arrayClass
))
{
return
!
isSetter
?
return
!
isSetter
?
MethodType
.
methodType
(
elemClass
,
arrayArgClass
,
int
.
class
)
:
MethodType
.
methodType
(
elemClass
,
arrayArgClass
,
int
.
class
)
:
MethodType
.
methodType
(
void
.
class
,
arrayArgClass
,
int
.
class
,
elemClass
);
MethodType
.
methodType
(
void
.
class
,
arrayArgClass
,
int
.
class
,
elemClass
);
}
else
{
Class
<?>
classArgClass
=
Class
.
class
;
if
(
USE_WEAKLY_TYPED_ARRAY_ACCESSORS
)
classArgClass
=
Object
.
class
;
return
!
isSetter
?
MethodType
.
methodType
(
Object
.
class
,
classArgClass
,
arrayArgClass
,
int
.
class
)
:
MethodType
.
methodType
(
void
.
class
,
classArgClass
,
arrayArgClass
,
int
.
class
,
Object
.
class
);
}
}
}
static
MethodType
correctType
(
Class
<?>
arrayClass
,
boolean
isSetter
)
{
static
MethodType
correctType
(
Class
<?>
arrayClass
,
boolean
isSetter
)
{
Class
<?>
elemClass
=
arrayClass
.
getComponentType
();
Class
<?>
elemClass
=
arrayClass
.
getComponentType
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录