Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
e3e92002
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看板
提交
e3e92002
编写于
2月 22, 2013
作者:
V
vlivanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8006439: Improve MethodHandles coverage
Reviewed-by: jrose, twisti
上级
e06c9d77
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
62 addition
and
38 deletion
+62
-38
src/share/classes/java/lang/invoke/MethodHandleImpl.java
src/share/classes/java/lang/invoke/MethodHandleImpl.java
+3
-21
src/share/classes/java/lang/invoke/MethodHandleNatives.java
src/share/classes/java/lang/invoke/MethodHandleNatives.java
+14
-2
src/share/classes/java/lang/invoke/MethodHandles.java
src/share/classes/java/lang/invoke/MethodHandles.java
+45
-15
未找到文件。
src/share/classes/java/lang/invoke/MethodHandleImpl.java
浏览文件 @
e3e92002
...
@@ -801,12 +801,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -801,12 +801,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static
static
MethodHandle
bindCaller
(
MethodHandle
mh
,
Class
<?>
hostClass
)
{
MethodHandle
bindCaller
(
MethodHandle
mh
,
Class
<?>
hostClass
)
{
// Do not use this function to inject calls into system classes.
// Do not use this function to inject calls into system classes.
if
(
hostClass
==
null
)
{
if
(
hostClass
==
null
hostClass
=
C_Trampoline
;
||
(
hostClass
.
isArray
()
||
}
else
if
(
hostClass
.
isArray
()
||
hostClass
.
isPrimitive
()
||
hostClass
.
isPrimitive
()
||
hostClass
.
getName
().
startsWith
(
"java."
)
||
hostClass
.
getName
().
startsWith
(
"java."
)
||
hostClass
.
getName
().
startsWith
(
"sun."
))
{
hostClass
.
getName
().
startsWith
(
"sun."
))
)
{
throw
new
InternalError
();
// does not happen, and should not anyway
throw
new
InternalError
();
// does not happen, and should not anyway
}
}
// For simplicity, convert mh to a varargs-like method.
// For simplicity, convert mh to a varargs-like method.
...
@@ -816,23 +815,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -816,23 +815,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return
restoreToType
(
bccInvoker
.
bindTo
(
vamh
),
mh
.
type
());
return
restoreToType
(
bccInvoker
.
bindTo
(
vamh
),
mh
.
type
());
}
}
// This class ("Trampoline") is known to be inside a dead-end class loader.
// Inject all doubtful calls into this class.
private
static
Class
<?>
C_Trampoline
;
static
{
Class
<?>
tramp
=
null
;
try
{
final
int
FRAME_COUNT_ARG
=
1
;
// [0] Reflection [1] Trampoline
java
.
lang
.
reflect
.
Method
gcc
=
sun
.
reflect
.
Reflection
.
class
.
getMethod
(
"getCallerClass"
,
int
.
class
);
tramp
=
(
Class
<?>)
sun
.
reflect
.
misc
.
MethodUtil
.
invoke
(
gcc
,
null
,
new
Object
[]{
FRAME_COUNT_ARG
});
if
(
tramp
.
getClassLoader
()
==
BindCaller
.
class
.
getClassLoader
())
throw
new
RuntimeException
(
tramp
.
getName
()+
" class loader"
);
}
catch
(
Throwable
ex
)
{
throw
new
InternalError
(
ex
);
}
C_Trampoline
=
tramp
;
}
private
static
MethodHandle
makeInjectedInvoker
(
Class
<?>
hostClass
)
{
private
static
MethodHandle
makeInjectedInvoker
(
Class
<?>
hostClass
)
{
Class
<?>
bcc
=
UNSAFE
.
defineAnonymousClass
(
hostClass
,
T_BYTES
,
null
);
Class
<?>
bcc
=
UNSAFE
.
defineAnonymousClass
(
hostClass
,
T_BYTES
,
null
);
if
(
hostClass
.
getClassLoader
()
!=
bcc
.
getClassLoader
())
if
(
hostClass
.
getClassLoader
()
!=
bcc
.
getClassLoader
())
...
...
src/share/classes/java/lang/invoke/MethodHandleNatives.java
浏览文件 @
e3e92002
...
@@ -393,11 +393,14 @@ class MethodHandleNatives {
...
@@ -393,11 +393,14 @@ class MethodHandleNatives {
*/
*/
// FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive.
// FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive.
static
boolean
isCallerSensitive
(
MemberName
mem
)
{
static
boolean
isCallerSensitive
(
MemberName
mem
)
{
assert
(
mem
.
isInvocable
());
if
(!
mem
.
isInvocable
())
return
false
;
// fields are not caller sensitive
Class
<?>
defc
=
mem
.
getDeclaringClass
();
Class
<?>
defc
=
mem
.
getDeclaringClass
();
switch
(
mem
.
getName
())
{
switch
(
mem
.
getName
())
{
case
"doPrivileged"
:
case
"doPrivileged"
:
case
"doPrivilegedWithCombiner"
:
return
defc
==
java
.
security
.
AccessController
.
class
;
return
defc
==
java
.
security
.
AccessController
.
class
;
case
"checkMemberAccess"
:
return
canBeCalledVirtual
(
mem
,
java
.
lang
.
SecurityManager
.
class
);
case
"getUnsafe"
:
case
"getUnsafe"
:
return
defc
==
sun
.
misc
.
Unsafe
.
class
;
return
defc
==
sun
.
misc
.
Unsafe
.
class
;
case
"lookup"
:
case
"lookup"
:
...
@@ -455,7 +458,7 @@ class MethodHandleNatives {
...
@@ -455,7 +458,7 @@ class MethodHandleNatives {
if
(
defc
==
java
.
util
.
concurrent
.
atomic
.
AtomicReferenceFieldUpdater
.
class
)
return
true
;
if
(
defc
==
java
.
util
.
concurrent
.
atomic
.
AtomicReferenceFieldUpdater
.
class
)
return
true
;
break
;
break
;
case
"getContextClassLoader"
:
case
"getContextClassLoader"
:
return
defc
==
java
.
lang
.
Thread
.
class
;
return
canBeCalledVirtual
(
mem
,
java
.
lang
.
Thread
.
class
)
;
case
"getPackage"
:
case
"getPackage"
:
case
"getPackages"
:
case
"getPackages"
:
return
defc
==
java
.
lang
.
Package
.
class
;
return
defc
==
java
.
lang
.
Package
.
class
;
...
@@ -473,6 +476,8 @@ class MethodHandleNatives {
...
@@ -473,6 +476,8 @@ class MethodHandleNatives {
break
;
break
;
case
"getCallerClassLoader"
:
case
"getCallerClassLoader"
:
return
defc
==
java
.
lang
.
ClassLoader
.
class
;
return
defc
==
java
.
lang
.
ClassLoader
.
class
;
case
"registerAsParallelCapable"
:
return
canBeCalledVirtual
(
mem
,
java
.
lang
.
ClassLoader
.
class
);
case
"getProxyClass"
:
case
"getProxyClass"
:
case
"newProxyInstance"
:
case
"newProxyInstance"
:
return
defc
==
java
.
lang
.
reflect
.
Proxy
.
class
;
return
defc
==
java
.
lang
.
reflect
.
Proxy
.
class
;
...
@@ -494,4 +499,11 @@ class MethodHandleNatives {
...
@@ -494,4 +499,11 @@ class MethodHandleNatives {
throw
new
InternalError
(
e
);
throw
new
InternalError
(
e
);
}
}
}
}
static
boolean
canBeCalledVirtual
(
MemberName
symbolicRef
,
Class
<?>
definingClass
)
{
Class
<?>
symbolicRefClass
=
symbolicRef
.
getDeclaringClass
();
if
(
symbolicRefClass
==
definingClass
)
return
true
;
if
(
symbolicRef
.
isStatic
()
||
symbolicRef
.
isPrivate
())
return
false
;
return
(
definingClass
.
isAssignableFrom
(
symbolicRefClass
)
||
// Msym overrides Mdef
symbolicRefClass
.
isInterface
());
// Mdef implements Msym
}
}
}
src/share/classes/java/lang/invoke/MethodHandles.java
浏览文件 @
e3e92002
...
@@ -598,7 +598,8 @@ public class MethodHandles {
...
@@ -598,7 +598,8 @@ public class MethodHandles {
MethodHandle
findStatic
(
Class
<?>
refc
,
String
name
,
MethodType
type
)
throws
NoSuchMethodException
,
IllegalAccessException
{
MethodHandle
findStatic
(
Class
<?>
refc
,
String
name
,
MethodType
type
)
throws
NoSuchMethodException
,
IllegalAccessException
{
MemberName
method
=
resolveOrFail
(
REF_invokeStatic
,
refc
,
name
,
type
);
MemberName
method
=
resolveOrFail
(
REF_invokeStatic
,
refc
,
name
,
type
);
checkSecurityManager
(
refc
,
method
);
// stack walk magic: do not refactor
checkSecurityManager
(
refc
,
method
);
// stack walk magic: do not refactor
return
getDirectMethod
(
REF_invokeStatic
,
refc
,
method
);
Class
<?>
callerClass
=
findBoundCallerClass
(
method
);
// stack walk magic: do not refactor
return
getDirectMethod
(
REF_invokeStatic
,
refc
,
method
,
callerClass
);
}
}
/**
/**
...
@@ -652,7 +653,8 @@ public class MethodHandles {
...
@@ -652,7 +653,8 @@ public class MethodHandles {
byte
refKind
=
(
refc
.
isInterface
()
?
REF_invokeInterface
:
REF_invokeVirtual
);
byte
refKind
=
(
refc
.
isInterface
()
?
REF_invokeInterface
:
REF_invokeVirtual
);
MemberName
method
=
resolveOrFail
(
refKind
,
refc
,
name
,
type
);
MemberName
method
=
resolveOrFail
(
refKind
,
refc
,
name
,
type
);
checkSecurityManager
(
refc
,
method
);
// stack walk magic: do not refactor
checkSecurityManager
(
refc
,
method
);
// stack walk magic: do not refactor
return
getDirectMethod
(
refKind
,
refc
,
method
);
Class
<?>
callerClass
=
findBoundCallerClass
(
method
);
return
getDirectMethod
(
refKind
,
refc
,
method
,
callerClass
);
}
}
private
MethodHandle
findVirtualForMH
(
String
name
,
MethodType
type
)
{
private
MethodHandle
findVirtualForMH
(
String
name
,
MethodType
type
)
{
// these names require special lookups because of the implicit MethodType argument
// these names require special lookups because of the implicit MethodType argument
...
@@ -736,7 +738,8 @@ public class MethodHandles {
...
@@ -736,7 +738,8 @@ public class MethodHandles {
Lookup
specialLookup
=
this
.
in
(
specialCaller
);
Lookup
specialLookup
=
this
.
in
(
specialCaller
);
MemberName
method
=
specialLookup
.
resolveOrFail
(
REF_invokeSpecial
,
refc
,
name
,
type
);
MemberName
method
=
specialLookup
.
resolveOrFail
(
REF_invokeSpecial
,
refc
,
name
,
type
);
checkSecurityManager
(
refc
,
method
);
// stack walk magic: do not refactor
checkSecurityManager
(
refc
,
method
);
// stack walk magic: do not refactor
return
specialLookup
.
getDirectMethod
(
REF_invokeSpecial
,
refc
,
method
);
Class
<?>
callerClass
=
findBoundCallerClass
(
method
);
return
specialLookup
.
getDirectMethod
(
REF_invokeSpecial
,
refc
,
method
,
callerClass
);
}
}
/**
/**
...
@@ -879,7 +882,8 @@ return mh1;
...
@@ -879,7 +882,8 @@ return mh1;
Class
<?
extends
Object
>
refc
=
receiver
.
getClass
();
// may get NPE
Class
<?
extends
Object
>
refc
=
receiver
.
getClass
();
// may get NPE
MemberName
method
=
resolveOrFail
(
REF_invokeSpecial
,
refc
,
name
,
type
);
MemberName
method
=
resolveOrFail
(
REF_invokeSpecial
,
refc
,
name
,
type
);
checkSecurityManager
(
refc
,
method
);
// stack walk magic: do not refactor
checkSecurityManager
(
refc
,
method
);
// stack walk magic: do not refactor
MethodHandle
mh
=
getDirectMethodNoRestrict
(
REF_invokeSpecial
,
refc
,
method
);
Class
<?>
callerClass
=
findBoundCallerClass
(
method
);
// stack walk magic: do not refactor
MethodHandle
mh
=
getDirectMethodNoRestrict
(
REF_invokeSpecial
,
refc
,
method
,
callerClass
);
return
mh
.
bindReceiver
(
receiver
).
setVarargs
(
method
);
return
mh
.
bindReceiver
(
receiver
).
setVarargs
(
method
);
}
}
...
@@ -910,8 +914,9 @@ return mh1;
...
@@ -910,8 +914,9 @@ return mh1;
if
(
refKind
==
REF_invokeSpecial
)
if
(
refKind
==
REF_invokeSpecial
)
refKind
=
REF_invokeVirtual
;
refKind
=
REF_invokeVirtual
;
assert
(
method
.
isMethod
());
assert
(
method
.
isMethod
());
Class
<?>
callerClass
=
findBoundCallerClass
(
method
);
// stack walk magic: do not refactor
Lookup
lookup
=
m
.
isAccessible
()
?
IMPL_LOOKUP
:
this
;
Lookup
lookup
=
m
.
isAccessible
()
?
IMPL_LOOKUP
:
this
;
return
lookup
.
getDirectMethod
(
refKind
,
method
.
getDeclaringClass
(),
method
);
return
lookup
.
getDirectMethod
(
refKind
,
method
.
getDeclaringClass
(),
method
,
callerClass
);
}
}
/**
/**
...
@@ -940,8 +945,9 @@ return mh1;
...
@@ -940,8 +945,9 @@ return mh1;
Lookup
specialLookup
=
this
.
in
(
specialCaller
);
Lookup
specialLookup
=
this
.
in
(
specialCaller
);
MemberName
method
=
new
MemberName
(
m
,
true
);
MemberName
method
=
new
MemberName
(
m
,
true
);
assert
(
method
.
isMethod
());
assert
(
method
.
isMethod
());
Class
<?>
callerClass
=
findBoundCallerClass
(
method
);
// stack walk magic: do not refactor
// ignore m.isAccessible: this is a new kind of access
// ignore m.isAccessible: this is a new kind of access
return
specialLookup
.
getDirectMethod
(
REF_invokeSpecial
,
method
.
getDeclaringClass
(),
method
);
return
specialLookup
.
getDirectMethod
(
REF_invokeSpecial
,
method
.
getDeclaringClass
(),
method
,
callerClass
);
}
}
/**
/**
...
@@ -1039,8 +1045,30 @@ return mh1;
...
@@ -1039,8 +1045,30 @@ return mh1;
throw
new
MemberName
(
refc
).
makeAccessException
(
"symbolic reference class is not public"
,
this
);
throw
new
MemberName
(
refc
).
makeAccessException
(
"symbolic reference class is not public"
,
this
);
}
}
/**
* Find my trustable caller class if m is a caller sensitive method.
* If this lookup object has private access, then the caller class is the lookupClass.
* Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
* This is the same caller class as is used by checkSecurityManager.
* This function performs stack walk magic: do not refactor it.
*/
Class
<?>
findBoundCallerClass
(
MemberName
m
)
{
Class
<?>
callerClass
=
null
;
if
(
MethodHandleNatives
.
isCallerSensitive
(
m
))
{
// Do not refactor this to a more "logical" place, since it is stack walk magic.
// Note that this is the same expression as in Step 2 below in checkSecurityManager.
callerClass
=
((
allowedModes
&
PRIVATE
)
!=
0
?
lookupClass
// for strong access modes, no extra check
// next line does stack walk magic; do not refactor:
:
getCallerClassAtEntryPoint
(
true
));
}
return
callerClass
;
}
/**
/**
* Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
* Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
* Determines a trustable caller class to compare with refc, the symbolic reference class.
* If this lookup object has private access, then the caller class is the lookupClass.
* Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
* This function performs stack walk magic: do not refactor it.
* This function performs stack walk magic: do not refactor it.
*/
*/
void
checkSecurityManager
(
Class
<?>
refc
,
MemberName
m
)
{
void
checkSecurityManager
(
Class
<?>
refc
,
MemberName
m
)
{
...
@@ -1195,22 +1223,22 @@ return mh1;
...
@@ -1195,22 +1223,22 @@ return mh1;
return
mh
.
viewAsType
(
narrowType
);
return
mh
.
viewAsType
(
narrowType
);
}
}
private
MethodHandle
getDirectMethod
(
byte
refKind
,
Class
<?>
refc
,
MemberName
method
)
throws
IllegalAccessException
{
private
MethodHandle
getDirectMethod
(
byte
refKind
,
Class
<?>
refc
,
MemberName
method
,
Class
<?>
callerClass
)
throws
IllegalAccessException
{
return
getDirectMethodCommon
(
refKind
,
refc
,
method
,
return
getDirectMethodCommon
(
refKind
,
refc
,
method
,
(
refKind
==
REF_invokeSpecial
||
(
refKind
==
REF_invokeSpecial
||
(
MethodHandleNatives
.
refKindHasReceiver
(
refKind
)
&&
(
MethodHandleNatives
.
refKindHasReceiver
(
refKind
)
&&
restrictProtectedReceiver
(
method
))));
restrictProtectedReceiver
(
method
)))
,
callerClass
);
}
}
private
MethodHandle
getDirectMethodNoRestrict
(
byte
refKind
,
Class
<?>
refc
,
MemberName
method
)
throws
IllegalAccessException
{
private
MethodHandle
getDirectMethodNoRestrict
(
byte
refKind
,
Class
<?>
refc
,
MemberName
method
,
Class
<?>
callerClass
)
throws
IllegalAccessException
{
return
getDirectMethodCommon
(
refKind
,
refc
,
method
,
false
);
return
getDirectMethodCommon
(
refKind
,
refc
,
method
,
false
,
callerClass
);
}
}
private
MethodHandle
getDirectMethodCommon
(
byte
refKind
,
Class
<?>
refc
,
MemberName
method
,
private
MethodHandle
getDirectMethodCommon
(
byte
refKind
,
Class
<?>
refc
,
MemberName
method
,
boolean
doRestrict
)
throws
IllegalAccessException
{
boolean
doRestrict
,
Class
<?>
callerClass
)
throws
IllegalAccessException
{
checkMethod
(
refKind
,
refc
,
method
);
checkMethod
(
refKind
,
refc
,
method
);
if
(
method
.
isMethodHandleInvoke
())
if
(
method
.
isMethodHandleInvoke
())
return
fakeMethodHandleInvoke
(
method
);
return
fakeMethodHandleInvoke
(
method
);
MethodHandle
mh
=
DirectMethodHandle
.
make
(
refc
,
method
);
MethodHandle
mh
=
DirectMethodHandle
.
make
(
refc
,
method
);
mh
=
maybeBindCaller
(
method
,
mh
);
mh
=
maybeBindCaller
(
method
,
mh
,
callerClass
);
mh
=
mh
.
setVarargs
(
method
);
mh
=
mh
.
setVarargs
(
method
);
if
(
doRestrict
)
if
(
doRestrict
)
mh
=
restrictReceiver
(
method
,
mh
,
lookupClass
());
mh
=
restrictReceiver
(
method
,
mh
,
lookupClass
());
...
@@ -1219,12 +1247,14 @@ return mh1;
...
@@ -1219,12 +1247,14 @@ return mh1;
private
MethodHandle
fakeMethodHandleInvoke
(
MemberName
method
)
{
private
MethodHandle
fakeMethodHandleInvoke
(
MemberName
method
)
{
return
throwException
(
method
.
getReturnType
(),
UnsupportedOperationException
.
class
);
return
throwException
(
method
.
getReturnType
(),
UnsupportedOperationException
.
class
);
}
}
private
MethodHandle
maybeBindCaller
(
MemberName
method
,
MethodHandle
mh
)
throws
IllegalAccessException
{
private
MethodHandle
maybeBindCaller
(
MemberName
method
,
MethodHandle
mh
,
Class
<?>
callerClass
)
throws
IllegalAccessException
{
if
(
allowedModes
==
TRUSTED
||
!
MethodHandleNatives
.
isCallerSensitive
(
method
))
if
(
allowedModes
==
TRUSTED
||
!
MethodHandleNatives
.
isCallerSensitive
(
method
))
return
mh
;
return
mh
;
Class
<?>
hostClass
=
lookupClass
;
Class
<?>
hostClass
=
lookupClass
;
if
((
allowedModes
&
PRIVATE
)
==
0
)
// caller must use full-power lookup
if
((
allowedModes
&
PRIVATE
)
==
0
)
// caller must use full-power lookup
hostClass
=
null
;
hostClass
=
callerClass
;
// callerClass came from a security manager style stack walk
MethodHandle
cbmh
=
MethodHandleImpl
.
bindCaller
(
mh
,
hostClass
);
MethodHandle
cbmh
=
MethodHandleImpl
.
bindCaller
(
mh
,
hostClass
);
// Note: caller will apply varargs after this step happens.
// Note: caller will apply varargs after this step happens.
return
cbmh
;
return
cbmh
;
...
@@ -1262,7 +1292,7 @@ return mh1;
...
@@ -1262,7 +1292,7 @@ return mh1;
}
else
if
(
MethodHandleNatives
.
refKindIsMethod
(
refKind
))
{
}
else
if
(
MethodHandleNatives
.
refKindIsMethod
(
refKind
))
{
MemberName
method
=
(
resolved
!=
null
)
?
resolved
MemberName
method
=
(
resolved
!=
null
)
?
resolved
:
resolveOrFail
(
refKind
,
defc
,
name
,
(
MethodType
)
type
);
:
resolveOrFail
(
refKind
,
defc
,
name
,
(
MethodType
)
type
);
return
getDirectMethod
(
refKind
,
defc
,
method
);
return
getDirectMethod
(
refKind
,
defc
,
method
,
lookupClass
);
}
else
if
(
refKind
==
REF_newInvokeSpecial
)
{
}
else
if
(
refKind
==
REF_newInvokeSpecial
)
{
assert
(
name
==
null
||
name
.
equals
(
"<init>"
));
assert
(
name
==
null
||
name
.
equals
(
"<init>"
));
MemberName
ctor
=
(
resolved
!=
null
)
?
resolved
MemberName
ctor
=
(
resolved
!=
null
)
?
resolved
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录