Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
e9fbebe0
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看板
提交
e9fbebe0
编写于
6月 19, 2010
作者:
J
jrose
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
06416474
6c9f76c4
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
195 addition
and
33 deletion
+195
-33
src/share/classes/java/dyn/MethodHandles.java
src/share/classes/java/dyn/MethodHandles.java
+42
-15
src/share/classes/sun/dyn/MethodHandleNatives.java
src/share/classes/sun/dyn/MethodHandleNatives.java
+34
-0
src/share/javavm/export/classfile_constants.h
src/share/javavm/export/classfile_constants.h
+16
-1
src/share/native/common/check_code.c
src/share/native/common/check_code.c
+26
-0
test/java/dyn/MethodHandlesTest.java
test/java/dyn/MethodHandlesTest.java
+77
-17
未找到文件。
src/share/classes/java/dyn/MethodHandles.java
浏览文件 @
e9fbebe0
...
...
@@ -411,41 +411,68 @@ public class MethodHandles {
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle giving read access to a field.
* Produce a method handle giving read access to a
non-static
field.
* The type of the method handle will have a return type of the field's
* value type.
* If the field is static, the method handle will take no arguments.
* Otherwise, its single argument will be the instance containing
* The method handle's single argument will be the instance containing
* the field.
* Access checking is performed immediately on behalf of the lookup class.
* @param name the field's name
* @param type the field's type
* @param isStatic true if and only if the field is static
* @return a method handle which can load values from the field
* @exception NoAccessException if access checking fails
*/
public
MethodHandle
findGetter
(
Class
<?>
refc
,
String
name
,
Class
<?>
type
,
boolean
isStatic
)
throws
NoAccessException
{
return
makeAccessor
(
refc
,
name
,
type
,
isStatic
,
false
);
public
MethodHandle
findGetter
(
Class
<?>
refc
,
String
name
,
Class
<?>
type
)
throws
NoAccessException
{
return
makeAccessor
(
refc
,
name
,
type
,
false
,
false
);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle giving write access to a
reflected
field.
* Produce a method handle giving write access to a
non-static
field.
* The type of the method handle will have a void return type.
* If the field is static, the method handle will take a single
* argument, of the field's value type, the value to be stored.
* Otherwise, the two arguments will be the instance containing
* The method handle will take two arguments, the instance containing
* the field, and the value to be stored.
* The second argument will be of the field's value type.
* Access checking is performed immediately on behalf of the lookup class.
* @param name the field's name
* @param type the field's type
* @param isStatic true if and only if the field is static
* @return a method handle which can store values into the reflected field
* @return a method handle which can store values into the field
* @exception NoAccessException if access checking fails
*/
public
MethodHandle
findSetter
(
Class
<?>
refc
,
String
name
,
Class
<?>
type
)
throws
NoAccessException
{
return
makeAccessor
(
refc
,
name
,
type
,
false
,
true
);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle giving read access to a static field.
* The type of the method handle will have a return type of the field's
* value type.
* The method handle will take no arguments.
* Access checking is performed immediately on behalf of the lookup class.
* @param name the field's name
* @param type the field's type
* @return a method handle which can load values from the field
* @exception NoAccessException if access checking fails
*/
public
MethodHandle
findStaticGetter
(
Class
<?>
refc
,
String
name
,
Class
<?>
type
)
throws
NoAccessException
{
return
makeAccessor
(
refc
,
name
,
type
,
true
,
false
);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle giving write access to a static field.
* The type of the method handle will have a void return type.
* The method handle will take a single
* argument, of the field's value type, the value to be stored.
* Access checking is performed immediately on behalf of the lookup class.
* @param name the field's name
* @param type the field's type
* @return a method handle which can store values into the field
* @exception NoAccessException if access checking fails
*/
public
MethodHandle
findSetter
(
Class
<?>
refc
,
String
name
,
Class
<?>
type
,
boolean
isStatic
)
throws
NoAccessException
{
return
makeAccessor
(
refc
,
name
,
type
,
isStatic
,
true
);
public
MethodHandle
findStaticSetter
(
Class
<?>
refc
,
String
name
,
Class
<?>
type
)
throws
NoAccessException
{
return
makeAccessor
(
refc
,
name
,
type
,
true
,
true
);
}
/**
...
...
src/share/classes/sun/dyn/MethodHandleNatives.java
浏览文件 @
e9fbebe0
...
...
@@ -258,6 +258,20 @@ class MethodHandleNatives {
//T_ARRAY = 13
T_VOID
=
14
;
//T_ADDRESS = 15
/**
* Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
*/
static
final
int
REF_getField
=
1
,
REF_getStatic
=
2
,
REF_putField
=
3
,
REF_putStatic
=
4
,
REF_invokeVirtual
=
5
,
REF_invokeStatic
=
6
,
REF_invokeSpecial
=
7
,
REF_newInvokeSpecial
=
8
,
REF_invokeInterface
=
9
;
}
private
static
native
int
getNamedCon
(
int
which
,
Object
[]
name
);
...
...
@@ -304,4 +318,24 @@ class MethodHandleNatives {
return
MethodTypeImpl
.
makeImpl
(
Access
.
TOKEN
,
rtype
,
ptypes
,
true
);
}
/**
* The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
* It will make an up-call to this method. (Do not change the name or signature.)
*/
static
MethodHandle
linkMethodHandleConstant
(
Class
<?>
callerClass
,
int
refKind
,
Class
<?>
defc
,
String
name
,
Object
type
)
{
Lookup
lookup
=
IMPL_LOOKUP
.
in
(
callerClass
);
switch
(
refKind
)
{
case
REF_getField:
return
lookup
.
findGetter
(
defc
,
name
,
(
Class
<?>)
type
);
case
REF_getStatic:
return
lookup
.
findStaticGetter
(
defc
,
name
,
(
Class
<?>)
type
);
case
REF_putField:
return
lookup
.
findSetter
(
defc
,
name
,
(
Class
<?>)
type
);
case
REF_putStatic:
return
lookup
.
findStaticSetter
(
defc
,
name
,
(
Class
<?>)
type
);
case
REF_invokeVirtual:
return
lookup
.
findVirtual
(
defc
,
name
,
(
MethodType
)
type
);
case
REF_invokeStatic:
return
lookup
.
findStatic
(
defc
,
name
,
(
MethodType
)
type
);
case
REF_invokeSpecial:
return
lookup
.
findSpecial
(
defc
,
name
,
(
MethodType
)
type
,
callerClass
);
case
REF_newInvokeSpecial:
return
lookup
.
findConstructor
(
defc
,
(
MethodType
)
type
);
case
REF_invokeInterface:
return
lookup
.
findVirtual
(
defc
,
name
,
(
MethodType
)
type
);
}
throw
new
IllegalArgumentException
(
"bad MethodHandle constant "
+
name
+
" : "
+
type
);
}
}
src/share/javavm/export/classfile_constants.h
浏览文件 @
e9fbebe0
...
...
@@ -84,7 +84,22 @@ enum {
JVM_CONSTANT_Fieldref
=
9
,
JVM_CONSTANT_Methodref
=
10
,
JVM_CONSTANT_InterfaceMethodref
=
11
,
JVM_CONSTANT_NameAndType
=
12
JVM_CONSTANT_NameAndType
=
12
,
JVM_CONSTANT_MethodHandle
=
15
,
// JSR 292
JVM_CONSTANT_MethodType
=
16
// JSR 292
};
/* JVM_CONSTANT_MethodHandle subtypes */
enum
{
JVM_REF_getField
=
1
,
JVM_REF_getStatic
=
2
,
JVM_REF_putField
=
3
,
JVM_REF_putStatic
=
4
,
JVM_REF_invokeVirtual
=
5
,
JVM_REF_invokeStatic
=
6
,
JVM_REF_invokeSpecial
=
7
,
JVM_REF_newInvokeSpecial
=
8
,
JVM_REF_invokeInterface
=
9
};
/* StackMapTable type item numbers */
...
...
src/share/native/common/check_code.c
浏览文件 @
e9fbebe0
...
...
@@ -204,6 +204,8 @@ enum {
#define LDC_CLASS_MAJOR_VERSION 49
#define LDC_METHOD_HANDLE_MAJOR_VERSION 51
#define ALLOC_STACK_SIZE 16
/* big enough */
typedef
struct
alloc_stack_type
{
...
...
@@ -1181,6 +1183,10 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
if
(
context
->
major_version
>=
LDC_CLASS_MAJOR_VERSION
)
{
types
|=
1
<<
JVM_CONSTANT_Class
;
}
if
(
context
->
major_version
>=
LDC_METHOD_HANDLE_MAJOR_VERSION
)
{
types
|=
(
1
<<
JVM_CONSTANT_MethodHandle
)
|
(
1
<<
JVM_CONSTANT_MethodType
);
}
this_idata
->
operand
.
i
=
key
;
verify_constant_pool_type
(
context
,
key
,
types
);
break
;
...
...
@@ -1194,6 +1200,10 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
if
(
context
->
major_version
>=
LDC_CLASS_MAJOR_VERSION
)
{
types
|=
1
<<
JVM_CONSTANT_Class
;
}
if
(
context
->
major_version
>=
LDC_METHOD_HANDLE_MAJOR_VERSION
)
{
types
|=
(
1
<<
JVM_CONSTANT_MethodHandle
)
|
(
1
<<
JVM_CONSTANT_MethodType
);
}
this_idata
->
operand
.
i
=
key
;
verify_constant_pool_type
(
context
,
key
,
types
);
break
;
...
...
@@ -2667,6 +2677,22 @@ push_stack(context_type *context, unsigned int inumber, stack_info_type *new_sta
full_info
=
make_class_info_from_name
(
context
,
"java/lang/Class"
);
break
;
case
JVM_CONSTANT_MethodHandle
:
case
JVM_CONSTANT_MethodType
:
if
(
context
->
major_version
<
LDC_METHOD_HANDLE_MAJOR_VERSION
)
CCerror
(
context
,
"Internal error #3"
);
stack_results
=
"A"
;
switch
(
type_table
[
operand
])
{
case
JVM_CONSTANT_MethodType
:
full_info
=
make_class_info_from_name
(
context
,
"java/dyn/MethodType"
);
break
;
default:
//JVM_CONSTANT_MethodHandle
full_info
=
make_class_info_from_name
(
context
,
"java/dyn/MethodHandle"
);
break
;
}
break
;
default:
CCerror
(
context
,
"Internal error #3"
);
stack_results
=
""
;
/* Never reached: keep lint happy */
...
...
test/java/dyn/MethodHandlesTest.java
浏览文件 @
e9fbebe0
...
...
@@ -47,6 +47,10 @@ import static org.junit.Assume.*;
public
class
MethodHandlesTest
{
// How much output?
static
int
verbosity
=
0
;
static
{
String
vstr
=
System
.
getProperty
(
"test.java.dyn.MethodHandlesTest.verbosity"
);
if
(
vstr
!=
null
)
verbosity
=
Integer
.
parseInt
(
vstr
);
}
// Set this true during development if you want to fast-forward to
// a particular new, non-working test. Tests which are known to
...
...
@@ -109,7 +113,7 @@ public class MethodHandlesTest {
String
vers
=
properties
.
getProperty
(
"java.vm.version"
);
String
name
=
properties
.
getProperty
(
"java.vm.name"
);
String
arch
=
properties
.
getProperty
(
"os.arch"
);
if
((
arch
.
equals
(
"
i386"
)
||
arch
.
equals
(
"amd64
"
)
||
if
((
arch
.
equals
(
"
amd64"
)
||
arch
.
equals
(
"i386"
)
||
arch
.
equals
(
"x86
"
)
||
arch
.
equals
(
"sparc"
)
||
arch
.
equals
(
"sparcv9"
))
&&
(
name
.
contains
(
"Client"
)
||
name
.
contains
(
"Server"
))
)
{
...
...
@@ -121,6 +125,7 @@ public class MethodHandlesTest {
}
String
testName
;
static
int
allPosTests
,
allNegTests
;
int
posTests
,
negTests
;
@After
public
void
printCounts
()
{
...
...
@@ -128,6 +133,8 @@ public class MethodHandlesTest {
System
.
out
.
println
();
if
(
posTests
!=
0
)
System
.
out
.
println
(
"=== "
+
testName
+
": "
+
posTests
+
" positive test cases run"
);
if
(
negTests
!=
0
)
System
.
out
.
println
(
"=== "
+
testName
+
": "
+
negTests
+
" negative test cases run"
);
allPosTests
+=
posTests
;
allNegTests
+=
negTests
;
posTests
=
negTests
=
0
;
}
}
...
...
@@ -153,6 +160,12 @@ public class MethodHandlesTest {
@AfterClass
public
static
void
tearDownClass
()
throws
Exception
{
int
posTests
=
allPosTests
,
negTests
=
allNegTests
;
if
(
verbosity
>=
2
&&
(
posTests
|
negTests
)
!=
0
)
{
System
.
out
.
println
();
if
(
posTests
!=
0
)
System
.
out
.
println
(
"=== "
+
posTests
+
" total positive test cases"
);
if
(
negTests
!=
0
)
System
.
out
.
println
(
"=== "
+
negTests
+
" total negative test cases"
);
}
}
static
List
<
Object
>
calledLog
=
new
ArrayList
<
Object
>();
...
...
@@ -811,28 +824,52 @@ public class MethodHandlesTest {
}
}
static
final
int
TEST_UNREFLECT
=
1
,
TEST_FIND_FIELD
=
2
,
TEST_FIND_STATIC_FIELD
=
3
;
static
boolean
testModeMatches
(
int
testMode
,
boolean
isStatic
)
{
switch
(
testMode
)
{
case
TEST_FIND_STATIC_FIELD:
return
isStatic
;
case
TEST_FIND_FIELD:
return
!
isStatic
;
default
:
return
true
;
// unreflect matches both
}
}
@Test
public
void
testUnreflectGetter
()
throws
Throwable
{
Lookup
lookup
=
PRIVATE
;
// FIXME: test more lookups than this one
startTest
(
"unreflectGetter"
);
testGetter
(
TEST_UNREFLECT
);
}
@Test
public
void
testFindGetter
()
throws
Throwable
{
startTest
(
"findGetter"
);
testGetter
(
TEST_FIND_FIELD
);
}
@Test
public
void
testFindStaticGetter
()
throws
Throwable
{
startTest
(
"findStaticGetter"
);
testGetter
(
TEST_FIND_STATIC_FIELD
);
}
public
void
testGetter
(
int
testMode
)
throws
Throwable
{
Lookup
lookup
=
PRIVATE
;
// FIXME: test more lookups than this one
for
(
Object
[]
c
:
HasFields
.
CASES
)
{
Field
f
=
(
Field
)
c
[
0
];
Object
value
=
c
[
1
];
Class
<?>
type
=
f
.
getType
();
if
(
type
.
isPrimitive
()
&&
type
!=
int
.
class
)
continue
;
//FIXME
testUnreflectGetter
(
lookup
,
f
,
type
,
value
);
testGetter
(
lookup
,
f
,
type
,
value
,
testMode
);
}
}
public
void
testUnreflectGetter
(
MethodHandles
.
Lookup
lookup
,
Field
f
,
Class
<?>
type
,
Object
value
)
throws
Throwable
{
countTest
(
true
);
public
void
testGetter
(
MethodHandles
.
Lookup
lookup
,
Field
f
,
Class
<?>
type
,
Object
value
,
int
testMode
)
throws
Throwable
{
boolean
isStatic
=
Modifier
.
isStatic
(
f
.
getModifiers
());
Class
<?>
fclass
=
f
.
getDeclaringClass
();
String
fname
=
f
.
getName
();
Class
<?>
ftype
=
f
.
getType
();
if
(!
testModeMatches
(
testMode
,
isStatic
))
return
;
countTest
(
true
);
MethodType
expType
=
MethodType
.
methodType
(
type
,
HasFields
.
class
);
if
(
isStatic
)
expType
=
expType
.
dropParameterTypes
(
0
,
1
);
MethodHandle
mh
=
lookup
.
unreflectGetter
(
f
);
assertSame
(
mh
.
type
(),
expType
);
assertEquals
(
mh
.
toString
(),
f
.
getName
()
);
assertEquals
(
mh
.
toString
(),
f
name
);
HasFields
fields
=
new
HasFields
();
Object
sawValue
;
Class
<?>
rtype
=
type
;
...
...
@@ -862,26 +899,49 @@ public class MethodHandlesTest {
@Test
public
void
testUnreflectSetter
()
throws
Throwable
{
startTest
(
"unreflectSetter"
);
testSetter
(
TEST_UNREFLECT
);
}
@Test
public
void
testFindSetter
()
throws
Throwable
{
startTest
(
"findSetter"
);
testSetter
(
TEST_FIND_FIELD
);
}
@Test
public
void
testFindStaticSetter
()
throws
Throwable
{
startTest
(
"findStaticSetter"
);
testSetter
(
TEST_FIND_STATIC_FIELD
);
}
public
void
testSetter
(
int
testMode
)
throws
Throwable
{
Lookup
lookup
=
PRIVATE
;
// FIXME: test more lookups than this one
startTest
(
"unreflectSetter"
);
for
(
Object
[]
c
:
HasFields
.
CASES
)
{
Field
f
=
(
Field
)
c
[
0
];
Object
value
=
c
[
1
];
Class
<?>
type
=
f
.
getType
();
if
(
type
.
isPrimitive
()
&&
type
!=
int
.
class
)
continue
;
//FIXME
testUnreflectSetter
(
lookup
,
f
,
type
,
value
);
testSetter
(
lookup
,
f
,
type
,
value
,
testMode
);
}
}
public
void
testUnreflectSetter
(
MethodHandles
.
Lookup
lookup
,
Field
f
,
Class
<?>
type
,
Object
value
)
throws
Throwable
{
countTest
(
true
);
public
void
testSetter
(
MethodHandles
.
Lookup
lookup
,
Field
f
,
Class
<?>
type
,
Object
value
,
int
testMode
)
throws
Throwable
{
boolean
isStatic
=
Modifier
.
isStatic
(
f
.
getModifiers
());
Class
<?>
fclass
=
f
.
getDeclaringClass
();
String
fname
=
f
.
getName
();
Class
<?>
ftype
=
f
.
getType
();
if
(!
testModeMatches
(
testMode
,
isStatic
))
return
;
countTest
(
true
);
MethodType
expType
=
MethodType
.
methodType
(
void
.
class
,
HasFields
.
class
,
type
);
if
(
isStatic
)
expType
=
expType
.
dropParameterTypes
(
0
,
1
);
MethodHandle
mh
=
lookup
.
unreflectSetter
(
f
);
MethodHandle
mh
;
if
(
testMode
==
TEST_UNREFLECT
)
mh
=
lookup
.
unreflectSetter
(
f
);
else
if
(
testMode
==
TEST_FIND_FIELD
)
mh
=
lookup
.
findSetter
(
fclass
,
fname
,
ftype
);
else
if
(
testMode
==
TEST_FIND_STATIC_FIELD
)
mh
=
lookup
.
findStaticSetter
(
fclass
,
fname
,
ftype
);
else
throw
new
InternalError
();
assertSame
(
mh
.
type
(),
expType
);
assertEquals
(
mh
.
toString
(),
f
.
getName
()
);
assertEquals
(
mh
.
toString
(),
f
name
);
HasFields
fields
=
new
HasFields
();
Object
sawValue
;
Class
<?>
vtype
=
type
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录