Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
fbfd2d29
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看板
提交
fbfd2d29
编写于
9月 10, 2014
作者:
V
vlivanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8050052: Small cleanups in java.lang.invoke code
Reviewed-by: vlivanov, psandoz Contributed-by: john.r.rose@oracle.com
上级
301e0094
变更
14
展开全部
显示空白变更内容
内联
并排
Showing
14 changed file
with
308 addition
and
324 deletion
+308
-324
src/share/classes/java/lang/invoke/BoundMethodHandle.java
src/share/classes/java/lang/invoke/BoundMethodHandle.java
+53
-35
src/share/classes/java/lang/invoke/CallSite.java
src/share/classes/java/lang/invoke/CallSite.java
+1
-1
src/share/classes/java/lang/invoke/DirectMethodHandle.java
src/share/classes/java/lang/invoke/DirectMethodHandle.java
+2
-1
src/share/classes/java/lang/invoke/Invokers.java
src/share/classes/java/lang/invoke/Invokers.java
+18
-20
src/share/classes/java/lang/invoke/LambdaForm.java
src/share/classes/java/lang/invoke/LambdaForm.java
+110
-162
src/share/classes/java/lang/invoke/MemberName.java
src/share/classes/java/lang/invoke/MemberName.java
+14
-17
src/share/classes/java/lang/invoke/MethodHandle.java
src/share/classes/java/lang/invoke/MethodHandle.java
+26
-13
src/share/classes/java/lang/invoke/MethodHandleImpl.java
src/share/classes/java/lang/invoke/MethodHandleImpl.java
+14
-19
src/share/classes/java/lang/invoke/MethodHandleProxies.java
src/share/classes/java/lang/invoke/MethodHandleProxies.java
+5
-4
src/share/classes/java/lang/invoke/MethodHandleStatics.java
src/share/classes/java/lang/invoke/MethodHandleStatics.java
+5
-2
src/share/classes/java/lang/invoke/MethodHandles.java
src/share/classes/java/lang/invoke/MethodHandles.java
+4
-2
src/share/classes/java/lang/invoke/MethodType.java
src/share/classes/java/lang/invoke/MethodType.java
+1
-1
src/share/classes/java/lang/invoke/MethodTypeForm.java
src/share/classes/java/lang/invoke/MethodTypeForm.java
+45
-45
test/java/lang/invoke/MethodHandlesTest.java
test/java/lang/invoke/MethodHandlesTest.java
+10
-2
未找到文件。
src/share/classes/java/lang/invoke/BoundMethodHandle.java
浏览文件 @
fbfd2d29
...
@@ -50,9 +50,9 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -50,9 +50,9 @@ import jdk.internal.org.objectweb.asm.Type;
*
*
* All bound arguments are encapsulated in dedicated species.
* All bound arguments are encapsulated in dedicated species.
*/
*/
/*
non-public
*/
abstract
class
BoundMethodHandle
extends
MethodHandle
{
/*
non-public
*/
abstract
class
BoundMethodHandle
extends
MethodHandle
{
/*
non-public
*/
BoundMethodHandle
(
MethodType
type
,
LambdaForm
form
)
{
/*
non-public
*/
BoundMethodHandle
(
MethodType
type
,
LambdaForm
form
)
{
super
(
type
,
form
);
super
(
type
,
form
);
}
}
...
@@ -66,15 +66,15 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -66,15 +66,15 @@ import jdk.internal.org.objectweb.asm.Type;
switch
(
xtype
)
{
switch
(
xtype
)
{
case
L_TYPE:
case
L_TYPE:
if
(
true
)
return
bindSingle
(
type
,
form
,
x
);
// Use known fast path.
if
(
true
)
return
bindSingle
(
type
,
form
,
x
);
// Use known fast path.
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
L_TYPE
).
constructor
[
0
]
.
invokeBasic
(
type
,
form
,
x
);
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
L_TYPE
).
constructor
()
.
invokeBasic
(
type
,
form
,
x
);
case
I_TYPE:
case
I_TYPE:
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
I_TYPE
).
constructor
[
0
]
.
invokeBasic
(
type
,
form
,
ValueConversions
.
widenSubword
(
x
));
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
I_TYPE
).
constructor
()
.
invokeBasic
(
type
,
form
,
ValueConversions
.
widenSubword
(
x
));
case
J_TYPE:
case
J_TYPE:
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
J_TYPE
).
constructor
[
0
]
.
invokeBasic
(
type
,
form
,
(
long
)
x
);
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
J_TYPE
).
constructor
()
.
invokeBasic
(
type
,
form
,
(
long
)
x
);
case
F_TYPE:
case
F_TYPE:
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
F_TYPE
).
constructor
[
0
]
.
invokeBasic
(
type
,
form
,
(
float
)
x
);
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
F_TYPE
).
constructor
()
.
invokeBasic
(
type
,
form
,
(
float
)
x
);
case
D_TYPE:
case
D_TYPE:
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
D_TYPE
).
constructor
[
0
]
.
invokeBasic
(
type
,
form
,
(
double
)
x
);
return
(
BoundMethodHandle
)
SpeciesData
.
EMPTY
.
extendWith
(
D_TYPE
).
constructor
()
.
invokeBasic
(
type
,
form
,
(
double
)
x
);
default
:
throw
newInternalError
(
"unexpected xtype: "
+
xtype
);
default
:
throw
newInternalError
(
"unexpected xtype: "
+
xtype
);
}
}
}
catch
(
Throwable
t
)
{
}
catch
(
Throwable
t
)
{
...
@@ -139,8 +139,8 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -139,8 +139,8 @@ import jdk.internal.org.objectweb.asm.Type;
/*non-public*/
abstract
int
fieldCount
();
/*non-public*/
abstract
int
fieldCount
();
@Override
@Override
final
Object
internalProperties
()
{
Object
internalProperties
()
{
return
"
/
BMH="
+
internalValues
();
return
"
\n&
BMH="
+
internalValues
();
}
}
@Override
@Override
...
@@ -219,7 +219,7 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -219,7 +219,7 @@ import jdk.internal.org.objectweb.asm.Type;
@Override
@Override
/*non-public*/
final
BoundMethodHandle
copyWithExtendL
(
MethodType
mt
,
LambdaForm
lf
,
Object
narg
)
{
/*non-public*/
final
BoundMethodHandle
copyWithExtendL
(
MethodType
mt
,
LambdaForm
lf
,
Object
narg
)
{
try
{
try
{
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
L_TYPE
).
constructor
[
0
]
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
L_TYPE
).
constructor
()
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
throw
uncaughtException
(
ex
);
throw
uncaughtException
(
ex
);
}
}
...
@@ -227,7 +227,7 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -227,7 +227,7 @@ import jdk.internal.org.objectweb.asm.Type;
@Override
@Override
/*non-public*/
final
BoundMethodHandle
copyWithExtendI
(
MethodType
mt
,
LambdaForm
lf
,
int
narg
)
{
/*non-public*/
final
BoundMethodHandle
copyWithExtendI
(
MethodType
mt
,
LambdaForm
lf
,
int
narg
)
{
try
{
try
{
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
I_TYPE
).
constructor
[
0
]
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
I_TYPE
).
constructor
()
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
throw
uncaughtException
(
ex
);
throw
uncaughtException
(
ex
);
}
}
...
@@ -235,7 +235,7 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -235,7 +235,7 @@ import jdk.internal.org.objectweb.asm.Type;
@Override
@Override
/*non-public*/
final
BoundMethodHandle
copyWithExtendJ
(
MethodType
mt
,
LambdaForm
lf
,
long
narg
)
{
/*non-public*/
final
BoundMethodHandle
copyWithExtendJ
(
MethodType
mt
,
LambdaForm
lf
,
long
narg
)
{
try
{
try
{
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
J_TYPE
).
constructor
[
0
]
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
J_TYPE
).
constructor
()
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
throw
uncaughtException
(
ex
);
throw
uncaughtException
(
ex
);
}
}
...
@@ -243,7 +243,7 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -243,7 +243,7 @@ import jdk.internal.org.objectweb.asm.Type;
@Override
@Override
/*non-public*/
final
BoundMethodHandle
copyWithExtendF
(
MethodType
mt
,
LambdaForm
lf
,
float
narg
)
{
/*non-public*/
final
BoundMethodHandle
copyWithExtendF
(
MethodType
mt
,
LambdaForm
lf
,
float
narg
)
{
try
{
try
{
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
F_TYPE
).
constructor
[
0
]
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
F_TYPE
).
constructor
()
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
throw
uncaughtException
(
ex
);
throw
uncaughtException
(
ex
);
}
}
...
@@ -251,7 +251,7 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -251,7 +251,7 @@ import jdk.internal.org.objectweb.asm.Type;
@Override
@Override
/*non-public*/
final
BoundMethodHandle
copyWithExtendD
(
MethodType
mt
,
LambdaForm
lf
,
double
narg
)
{
/*non-public*/
final
BoundMethodHandle
copyWithExtendD
(
MethodType
mt
,
LambdaForm
lf
,
double
narg
)
{
try
{
try
{
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
D_TYPE
).
constructor
[
0
]
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
return
(
BoundMethodHandle
)
SPECIES_DATA
.
extendWith
(
D_TYPE
).
constructor
()
.
invokeBasic
(
mt
,
lf
,
argL0
,
narg
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
throw
uncaughtException
(
ex
);
throw
uncaughtException
(
ex
);
}
}
...
@@ -268,18 +268,20 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -268,18 +268,20 @@ import jdk.internal.org.objectweb.asm.Type;
* The fields are immutable; their values are fully specified at object construction.
* The fields are immutable; their values are fully specified at object construction.
* Each BMH type supplies an array of getter functions which may be used in lambda forms.
* Each BMH type supplies an array of getter functions which may be used in lambda forms.
* A BMH is constructed by cloning a shorter BMH and adding one or more new field values.
* A BMH is constructed by cloning a shorter BMH and adding one or more new field values.
* As a degenerate and common case, the "shorter BMH" can be missing, and contributes zero prior fields.
* The shortest possible BMH has zero fields; its class is SimpleMethodHandle.
* BMH species are not interrelated by subtyping, even though it would appear that
* a shorter BMH could serve as a supertype of a longer one which extends it.
*/
*/
static
class
SpeciesData
{
static
class
SpeciesData
{
final
String
typeChars
;
private
final
String
typeChars
;
final
BasicType
[]
typeCodes
;
private
final
BasicType
[]
typeCodes
;
final
Class
<?
extends
BoundMethodHandle
>
clazz
;
private
final
Class
<?
extends
BoundMethodHandle
>
clazz
;
// Bootstrapping requires circular relations MH -> BMH -> SpeciesData -> MH
// Bootstrapping requires circular relations MH -> BMH -> SpeciesData -> MH
// Therefore, we need a non-final link in the chain. Use array elements.
// Therefore, we need a non-final link in the chain. Use array elements.
final
MethodHandle
[]
constructor
;
@Stable
private
final
MethodHandle
[]
constructor
;
final
MethodHandle
[]
getters
;
@Stable
private
final
MethodHandle
[]
getters
;
final
NamedFunction
[]
nominalGetters
;
@Stable
private
final
NamedFunction
[]
nominalGetters
;
final
SpeciesData
[]
extensions
;
@Stable
private
final
SpeciesData
[]
extensions
;
/*non-public*/
int
fieldCount
()
{
/*non-public*/
int
fieldCount
()
{
return
typeCodes
.
length
;
return
typeCodes
.
length
;
...
@@ -290,9 +292,14 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -290,9 +292,14 @@ import jdk.internal.org.objectweb.asm.Type;
/*non-public*/
char
fieldTypeChar
(
int
i
)
{
/*non-public*/
char
fieldTypeChar
(
int
i
)
{
return
typeChars
.
charAt
(
i
);
return
typeChars
.
charAt
(
i
);
}
}
Object
fieldSignature
()
{
return
typeChars
;
}
public
Class
<?
extends
BoundMethodHandle
>
fieldHolder
()
{
return
clazz
;
}
public
String
toString
()
{
public
String
toString
()
{
return
"SpeciesData
["
+(
isPlaceholder
()
?
"<placeholder>"
:
clazz
.
getSimpleName
())+
":"
+
typeChars
+
"]
"
;
return
"SpeciesData
<"
+
fieldSignature
()+
">
"
;
}
}
/**
/**
...
@@ -301,7 +308,20 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -301,7 +308,20 @@ import jdk.internal.org.objectweb.asm.Type;
* getter.
* getter.
*/
*/
NamedFunction
getterFunction
(
int
i
)
{
NamedFunction
getterFunction
(
int
i
)
{
return
nominalGetters
[
i
];
NamedFunction
nf
=
nominalGetters
[
i
];
assert
(
nf
.
memberDeclaringClassOrNull
()
==
fieldHolder
());
assert
(
nf
.
returnType
()
==
fieldType
(
i
));
return
nf
;
}
NamedFunction
[]
getterFunctions
()
{
return
nominalGetters
;
}
MethodHandle
[]
getterHandles
()
{
return
getters
;
}
MethodHandle
constructor
()
{
return
constructor
[
0
];
}
}
static
final
SpeciesData
EMPTY
=
new
SpeciesData
(
""
,
BoundMethodHandle
.
class
);
static
final
SpeciesData
EMPTY
=
new
SpeciesData
(
""
,
BoundMethodHandle
.
class
);
...
@@ -324,7 +344,7 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -324,7 +344,7 @@ import jdk.internal.org.objectweb.asm.Type;
private
void
initForBootstrap
()
{
private
void
initForBootstrap
()
{
assert
(!
INIT_DONE
);
assert
(!
INIT_DONE
);
if
(
constructor
[
0
]
==
null
)
{
if
(
constructor
()
==
null
)
{
String
types
=
typeChars
;
String
types
=
typeChars
;
Factory
.
makeCtors
(
clazz
,
types
,
this
.
constructor
);
Factory
.
makeCtors
(
clazz
,
types
,
this
.
constructor
);
Factory
.
makeGetters
(
clazz
,
types
,
this
.
getters
);
Factory
.
makeGetters
(
clazz
,
types
,
this
.
getters
);
...
@@ -508,19 +528,19 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -508,19 +528,19 @@ import jdk.internal.org.objectweb.asm.Type;
* return new Species_LLI(mt, lf, argL0, argL1, argI2);
* return new Species_LLI(mt, lf, argL0, argL1, argI2);
* }
* }
* final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
* final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
* return SPECIES_DATA.extendWith(L_TYPE).constructor
[0]
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* return SPECIES_DATA.extendWith(L_TYPE).constructor
()
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* }
* final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
* final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
* return SPECIES_DATA.extendWith(I_TYPE).constructor
[0]
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* return SPECIES_DATA.extendWith(I_TYPE).constructor
()
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* }
* final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
* final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
* return SPECIES_DATA.extendWith(J_TYPE).constructor
[0]
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* return SPECIES_DATA.extendWith(J_TYPE).constructor
()
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* }
* final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
* final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
* return SPECIES_DATA.extendWith(F_TYPE).constructor
[0]
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* return SPECIES_DATA.extendWith(F_TYPE).constructor
()
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* }
* public final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
* public final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
* return SPECIES_DATA.extendWith(D_TYPE).constructor
[0]
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* return SPECIES_DATA.extendWith(D_TYPE).constructor
()
.invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* }
* }
* }
* </pre>
* </pre>
...
@@ -653,16 +673,14 @@ import jdk.internal.org.objectweb.asm.Type;
...
@@ -653,16 +673,14 @@ import jdk.internal.org.objectweb.asm.Type;
char
btChar
=
type
.
basicTypeChar
();
char
btChar
=
type
.
basicTypeChar
();
mv
=
cw
.
visitMethod
(
NOT_ACC_PUBLIC
+
ACC_FINAL
,
"copyWithExtend"
+
btChar
,
makeSignature
(
String
.
valueOf
(
btChar
),
false
),
null
,
E_THROWABLE
);
mv
=
cw
.
visitMethod
(
NOT_ACC_PUBLIC
+
ACC_FINAL
,
"copyWithExtend"
+
btChar
,
makeSignature
(
String
.
valueOf
(
btChar
),
false
),
null
,
E_THROWABLE
);
mv
.
visitCode
();
mv
.
visitCode
();
// return SPECIES_DATA.extendWith(t).constructor
[0]
.invokeBasic(mt, lf, argL0, ..., narg)
// return SPECIES_DATA.extendWith(t).constructor
()
.invokeBasic(mt, lf, argL0, ..., narg)
// obtain constructor
// obtain constructor
mv
.
visitFieldInsn
(
GETSTATIC
,
className
,
"SPECIES_DATA"
,
SPECIES_DATA_SIG
);
mv
.
visitFieldInsn
(
GETSTATIC
,
className
,
"SPECIES_DATA"
,
SPECIES_DATA_SIG
);
int
iconstInsn
=
ICONST_0
+
ord
;
int
iconstInsn
=
ICONST_0
+
ord
;
assert
(
iconstInsn
<=
ICONST_5
);
assert
(
iconstInsn
<=
ICONST_5
);
mv
.
visitInsn
(
iconstInsn
);
mv
.
visitInsn
(
iconstInsn
);
mv
.
visitMethodInsn
(
INVOKEVIRTUAL
,
SPECIES_DATA
,
"extendWith"
,
BMHSPECIES_DATA_EWI_SIG
,
false
);
mv
.
visitMethodInsn
(
INVOKEVIRTUAL
,
SPECIES_DATA
,
"extendWith"
,
BMHSPECIES_DATA_EWI_SIG
,
false
);
mv
.
visitFieldInsn
(
GETFIELD
,
SPECIES_DATA
,
"constructor"
,
"["
+
MH_SIG
);
mv
.
visitMethodInsn
(
INVOKEVIRTUAL
,
SPECIES_DATA
,
"constructor"
,
"()"
+
MH_SIG
,
false
);
mv
.
visitInsn
(
ICONST_0
);
mv
.
visitInsn
(
AALOAD
);
// load mt, lf
// load mt, lf
mv
.
visitVarInsn
(
ALOAD
,
1
);
mv
.
visitVarInsn
(
ALOAD
,
1
);
mv
.
visitVarInsn
(
ALOAD
,
2
);
mv
.
visitVarInsn
(
ALOAD
,
2
);
...
...
src/share/classes/java/lang/invoke/CallSite.java
浏览文件 @
fbfd2d29
...
@@ -319,7 +319,7 @@ public class CallSite {
...
@@ -319,7 +319,7 @@ public class CallSite {
throw
new
ClassCastException
(
"bootstrap method failed to produce a CallSite"
);
throw
new
ClassCastException
(
"bootstrap method failed to produce a CallSite"
);
}
}
if
(!
site
.
getTarget
().
type
().
equals
(
type
))
if
(!
site
.
getTarget
().
type
().
equals
(
type
))
throw
new
WrongMethodTypeException
(
"wrong type: "
+
site
.
getTarget
()
);
throw
wrongTargetType
(
site
.
getTarget
(),
type
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
BootstrapMethodError
bex
;
BootstrapMethodError
bex
;
if
(
ex
instanceof
BootstrapMethodError
)
if
(
ex
instanceof
BootstrapMethodError
)
...
...
src/share/classes/java/lang/invoke/DirectMethodHandle.java
浏览文件 @
fbfd2d29
...
@@ -59,6 +59,7 @@ class DirectMethodHandle extends MethodHandle {
...
@@ -59,6 +59,7 @@ class DirectMethodHandle extends MethodHandle {
MemberName
m
=
new
MemberName
(
Object
.
class
,
member
.
getName
(),
member
.
getMethodType
(),
member
.
getReferenceKind
());
MemberName
m
=
new
MemberName
(
Object
.
class
,
member
.
getName
(),
member
.
getMethodType
(),
member
.
getReferenceKind
());
m
=
MemberName
.
getFactory
().
resolveOrNull
(
m
.
getReferenceKind
(),
m
,
null
);
m
=
MemberName
.
getFactory
().
resolveOrNull
(
m
.
getReferenceKind
(),
m
,
null
);
if
(
m
!=
null
&&
m
.
isPublic
())
{
if
(
m
!=
null
&&
m
.
isPublic
())
{
assert
(
member
.
getReferenceKind
()
==
m
.
getReferenceKind
());
// else this.form is wrong
member
=
m
;
member
=
m
;
}
}
}
}
...
@@ -127,7 +128,7 @@ class DirectMethodHandle extends MethodHandle {
...
@@ -127,7 +128,7 @@ class DirectMethodHandle extends MethodHandle {
@Override
@Override
String
internalProperties
()
{
String
internalProperties
()
{
return
"
/DMH="
+
member
.
toString
();
return
"
\n& DMH.MN="
+
internalMemberName
();
}
}
//// Implementation methods.
//// Implementation methods.
...
...
src/share/classes/java/lang/invoke/Invokers.java
浏览文件 @
fbfd2d29
...
@@ -308,7 +308,7 @@ class Invokers {
...
@@ -308,7 +308,7 @@ class Invokers {
:
Arrays
.
asList
(
mtype
,
customized
,
which
,
nameCursor
,
names
.
length
);
:
Arrays
.
asList
(
mtype
,
customized
,
which
,
nameCursor
,
names
.
length
);
if
(
MTYPE_ARG
>=
INARG_LIMIT
)
{
if
(
MTYPE_ARG
>=
INARG_LIMIT
)
{
assert
(
names
[
MTYPE_ARG
]
==
null
);
assert
(
names
[
MTYPE_ARG
]
==
null
);
NamedFunction
getter
=
BoundMethodHandle
.
getSpeciesData
(
"L"
).
getterFunction
(
0
);
NamedFunction
getter
=
BoundMethodHandle
.
speciesData_L
(
).
getterFunction
(
0
);
names
[
MTYPE_ARG
]
=
new
Name
(
getter
,
names
[
THIS_MH
]);
names
[
MTYPE_ARG
]
=
new
Name
(
getter
,
names
[
THIS_MH
]);
// else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
// else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
}
}
...
@@ -360,9 +360,6 @@ class Invokers {
...
@@ -360,9 +360,6 @@ class Invokers {
Object
checkGenericType
(
Object
mhObj
,
Object
expectedObj
)
{
Object
checkGenericType
(
Object
mhObj
,
Object
expectedObj
)
{
MethodHandle
mh
=
(
MethodHandle
)
mhObj
;
MethodHandle
mh
=
(
MethodHandle
)
mhObj
;
MethodType
expected
=
(
MethodType
)
expectedObj
;
MethodType
expected
=
(
MethodType
)
expectedObj
;
if
(
mh
.
type
()
==
expected
)
return
mh
;
MethodHandle
atc
=
mh
.
asTypeCache
;
if
(
atc
!=
null
&&
atc
.
type
()
==
expected
)
return
atc
;
return
mh
.
asType
(
expected
);
return
mh
.
asType
(
expected
);
/* Maybe add more paths here. Possible optimizations:
/* Maybe add more paths here. Possible optimizations:
* for (R)MH.invoke(a*),
* for (R)MH.invoke(a*),
...
@@ -436,24 +433,25 @@ class Invokers {
...
@@ -436,24 +433,25 @@ class Invokers {
}
}
// Local constant functions:
// Local constant functions:
private
static
final
NamedFunction
NF_checkExactType
;
private
static
final
NamedFunction
private
static
final
NamedFunction
NF_checkGenericType
;
NF_checkExactType
,
private
static
final
NamedFunction
NF_asType
;
NF_checkGenericType
,
private
static
final
NamedFunction
NF_getCallSiteTarget
;
NF_getCallSiteTarget
;
static
{
static
{
try
{
try
{
NamedFunction
nfs
[]
=
{
NF_checkExactType
=
new
NamedFunction
(
Invokers
.
class
NF_checkExactType
=
new
NamedFunction
(
Invokers
.
class
.
getDeclaredMethod
(
"checkExactType"
,
Object
.
class
,
Object
.
class
));
.
getDeclaredMethod
(
"checkExactType"
,
Object
.
class
,
Object
.
class
)),
NF_checkGenericType
=
new
NamedFunction
(
Invokers
.
class
NF_checkGenericType
=
new
NamedFunction
(
Invokers
.
class
.
getDeclaredMethod
(
"checkGenericType"
,
Object
.
class
,
Object
.
class
));
.
getDeclaredMethod
(
"checkGenericType"
,
Object
.
class
,
Object
.
class
)),
NF_asType
=
new
NamedFunction
(
MethodHandle
.
class
.
getDeclaredMethod
(
"asType"
,
MethodType
.
class
));
NF_getCallSiteTarget
=
new
NamedFunction
(
Invokers
.
class
NF_getCallSiteTarget
=
new
NamedFunction
(
Invokers
.
class
.
getDeclaredMethod
(
"getCallSiteTarget"
,
Object
.
class
));
.
getDeclaredMethod
(
"getCallSiteTarget"
,
Object
.
class
))
NF_checkExactType
.
resolve
();
};
NF_checkGenericType
.
resolve
();
for
(
NamedFunction
nf
:
nfs
)
{
NF_getCallSiteTarget
.
resolve
();
// Each nf must be statically invocable or we get tied up in our bootstraps.
// bound
assert
(
InvokerBytecodeGenerator
.
isStaticallyInvocable
(
nf
.
member
))
:
nf
;
nf
.
resolve
();
}
}
catch
(
ReflectiveOperationException
ex
)
{
}
catch
(
ReflectiveOperationException
ex
)
{
throw
newInternalError
(
ex
);
throw
newInternalError
(
ex
);
}
}
...
...
src/share/classes/java/lang/invoke/LambdaForm.java
浏览文件 @
fbfd2d29
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/MemberName.java
浏览文件 @
fbfd2d29
...
@@ -327,10 +327,6 @@ import java.util.Objects;
...
@@ -327,10 +327,6 @@ import java.util.Objects;
assert
(
getReferenceKind
()
==
oldKind
);
assert
(
getReferenceKind
()
==
oldKind
);
assert
(
MethodHandleNatives
.
refKindIsValid
(
refKind
));
assert
(
MethodHandleNatives
.
refKindIsValid
(
refKind
));
flags
+=
(((
int
)
refKind
-
oldKind
)
<<
MN_REFERENCE_KIND_SHIFT
);
flags
+=
(((
int
)
refKind
-
oldKind
)
<<
MN_REFERENCE_KIND_SHIFT
);
// if (isConstructor() && refKind != REF_newInvokeSpecial)
// flags += (IS_METHOD - IS_CONSTRUCTOR);
// else if (refKind == REF_newInvokeSpecial && isMethod())
// flags += (IS_CONSTRUCTOR - IS_METHOD);
return
this
;
return
this
;
}
}
...
@@ -344,9 +340,11 @@ import java.util.Objects;
...
@@ -344,9 +340,11 @@ import java.util.Objects;
return
!
testFlags
(
mask
,
0
);
return
!
testFlags
(
mask
,
0
);
}
}
/** Utility method to query if this member is a method handle invocation (invoke or invokeExact). */
/** Utility method to query if this member is a method handle invocation (invoke or invokeExact).
* Also returns true for the non-public MH.invokeBasic.
*/
public
boolean
isMethodHandleInvoke
()
{
public
boolean
isMethodHandleInvoke
()
{
final
int
bits
=
MH_INVOKE_MODS
;
final
int
bits
=
MH_INVOKE_MODS
&~
Modifier
.
PUBLIC
;
final
int
negs
=
Modifier
.
STATIC
;
final
int
negs
=
Modifier
.
STATIC
;
if
(
testFlags
(
bits
|
negs
,
bits
)
&&
if
(
testFlags
(
bits
|
negs
,
bits
)
&&
clazz
==
MethodHandle
.
class
)
{
clazz
==
MethodHandle
.
class
)
{
...
@@ -355,7 +353,14 @@ import java.util.Objects;
...
@@ -355,7 +353,14 @@ import java.util.Objects;
return
false
;
return
false
;
}
}
public
static
boolean
isMethodHandleInvokeName
(
String
name
)
{
public
static
boolean
isMethodHandleInvokeName
(
String
name
)
{
return
name
.
equals
(
"invoke"
)
||
name
.
equals
(
"invokeExact"
);
switch
(
name
)
{
case
"invoke"
:
case
"invokeExact"
:
case
"invokeBasic"
:
// internal sig-poly method
return
true
;
default
:
return
false
;
}
}
}
private
static
final
int
MH_INVOKE_MODS
=
Modifier
.
NATIVE
|
Modifier
.
FINAL
|
Modifier
.
PUBLIC
;
private
static
final
int
MH_INVOKE_MODS
=
Modifier
.
NATIVE
|
Modifier
.
FINAL
|
Modifier
.
PUBLIC
;
...
@@ -720,16 +725,8 @@ import java.util.Objects;
...
@@ -720,16 +725,8 @@ import java.util.Objects;
init
(
defClass
,
name
,
type
,
flagsMods
(
IS_FIELD
,
0
,
refKind
));
init
(
defClass
,
name
,
type
,
flagsMods
(
IS_FIELD
,
0
,
refKind
));
initResolved
(
false
);
initResolved
(
false
);
}
}
/** Create a field or type name from the given components: Declaring class, name, type.
/** Create a method or constructor name from the given components:
* The declaring class may be supplied as null if this is to be a bare name and type.
* Declaring class, name, type, reference kind.
* The modifier flags default to zero.
* The resulting name will in an unresolved state.
*/
public
MemberName
(
Class
<?>
defClass
,
String
name
,
Class
<?>
type
,
Void
unused
)
{
this
(
defClass
,
name
,
type
,
REF_NONE
);
initResolved
(
false
);
}
/** Create a method or constructor name from the given components: Declaring class, name, type, modifiers.
* It will be a constructor if and only if the name is {@code "<init>"}.
* It will be a constructor if and only if the name is {@code "<init>"}.
* The declaring class may be supplied as null if this is to be a bare name and type.
* The declaring class may be supplied as null if this is to be a bare name and type.
* The last argument is optional, a boolean which requests REF_invokeSpecial.
* The last argument is optional, a boolean which requests REF_invokeSpecial.
...
...
src/share/classes/java/lang/invoke/MethodHandle.java
浏览文件 @
fbfd2d29
...
@@ -762,11 +762,19 @@ public abstract class MethodHandle {
...
@@ -762,11 +762,19 @@ public abstract class MethodHandle {
return
this
;
return
this
;
}
}
// Return 'this.asTypeCache' if the conversion is already memoized.
// Return 'this.asTypeCache' if the conversion is already memoized.
MethodHandle
atc
=
asTypeCached
(
newType
);
if
(
atc
!=
null
)
{
return
atc
;
}
return
asTypeUncached
(
newType
);
}
private
MethodHandle
asTypeCached
(
MethodType
newType
)
{
MethodHandle
atc
=
asTypeCache
;
MethodHandle
atc
=
asTypeCache
;
if
(
atc
!=
null
&&
newType
==
atc
.
type
)
{
if
(
atc
!=
null
&&
newType
==
atc
.
type
)
{
return
atc
;
return
atc
;
}
}
return
asTypeUncached
(
newType
)
;
return
null
;
}
}
/** Override this to change asType behavior. */
/** Override this to change asType behavior. */
...
@@ -991,8 +999,11 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
...
@@ -991,8 +999,11 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
return
MethodHandles
.
collectArguments
(
target
,
collectArgPos
,
collector
);
return
MethodHandles
.
collectArguments
(
target
,
collectArgPos
,
collector
);
}
}
// private API: return true if last param exactly matches arrayType
/**
private
boolean
asCollectorChecks
(
Class
<?>
arrayType
,
int
arrayLength
)
{
* See if {@code asCollector} can be validly called with the given arguments.
* Return false if the last parameter is not an exact match to arrayType.
*/
/*non-public*/
boolean
asCollectorChecks
(
Class
<?>
arrayType
,
int
arrayLength
)
{
spreadArrayChecks
(
arrayType
,
arrayLength
);
spreadArrayChecks
(
arrayType
,
arrayLength
);
int
nargs
=
type
().
parameterCount
();
int
nargs
=
type
().
parameterCount
();
if
(
nargs
!=
0
)
{
if
(
nargs
!=
0
)
{
...
@@ -1154,7 +1165,7 @@ assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
...
@@ -1154,7 +1165,7 @@ assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
* @see #asFixedArity
* @see #asFixedArity
*/
*/
public
MethodHandle
asVarargsCollector
(
Class
<?>
arrayType
)
{
public
MethodHandle
asVarargsCollector
(
Class
<?>
arrayType
)
{
Class
<?>
arrayElement
=
arrayType
.
getComponentType
();
arrayType
.
getClass
();
// explicit NPE
boolean
lastMatch
=
asCollectorChecks
(
arrayType
,
0
);
boolean
lastMatch
=
asCollectorChecks
(
arrayType
,
0
);
if
(
isVarargsCollector
()
&&
lastMatch
)
if
(
isVarargsCollector
()
&&
lastMatch
)
return
this
;
return
this
;
...
@@ -1283,14 +1294,17 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
...
@@ -1283,14 +1294,17 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
*/
*/
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
if
(
DEBUG_METHOD_HANDLE_NAMES
)
return
debugString
();
if
(
DEBUG_METHOD_HANDLE_NAMES
)
return
"MethodHandle"
+
debugString
();
return
standardString
();
return
standardString
();
}
}
String
standardString
()
{
String
standardString
()
{
return
"MethodHandle"
+
type
;
return
"MethodHandle"
+
type
;
}
}
/** Return a string with a several lines describing the method handle structure.
* This string would be suitable for display in an IDE debugger.
*/
String
debugString
()
{
String
debugString
()
{
return
standardString
()+
"/LF=
"
+
internalForm
()+
internalProperties
();
return
type
+
" :
"
+
internalForm
()+
internalProperties
();
}
}
//// Implementation methods.
//// Implementation methods.
...
@@ -1302,15 +1316,13 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
...
@@ -1302,15 +1316,13 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
/*non-public*/
/*non-public*/
MethodHandle
setVarargs
(
MemberName
member
)
throws
IllegalAccessException
{
MethodHandle
setVarargs
(
MemberName
member
)
throws
IllegalAccessException
{
if
(!
member
.
isVarargs
())
return
this
;
if
(!
member
.
isVarargs
())
return
this
;
int
argc
=
type
().
parameterCount
();
Class
<?>
arrayType
=
type
().
lastParameterType
();
if
(
argc
!=
0
)
{
Class
<?>
arrayType
=
type
().
parameterType
(
argc
-
1
);
if
(
arrayType
.
isArray
())
{
if
(
arrayType
.
isArray
())
{
return
MethodHandleImpl
.
makeVarargsCollector
(
this
,
arrayType
);
return
MethodHandleImpl
.
makeVarargsCollector
(
this
,
arrayType
);
}
}
}
throw
member
.
makeAccessException
(
"cannot make variable arity"
,
null
);
throw
member
.
makeAccessException
(
"cannot make variable arity"
,
null
);
}
}
/*non-public*/
/*non-public*/
MethodHandle
viewAsType
(
MethodType
newType
)
{
MethodHandle
viewAsType
(
MethodType
newType
)
{
// No actual conversions, just a new view of the same method.
// No actual conversions, just a new view of the same method.
...
@@ -1361,7 +1373,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
...
@@ -1361,7 +1373,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
/*non-public*/
/*non-public*/
Object
internalProperties
()
{
Object
internalProperties
()
{
// Override to something
like "/
FOO=bar"
// Override to something
to follow this.form, like "\n&
FOO=bar"
return
""
;
return
""
;
}
}
...
@@ -1469,6 +1481,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
...
@@ -1469,6 +1481,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
/*non-public*/
/*non-public*/
void
updateForm
(
LambdaForm
newForm
)
{
void
updateForm
(
LambdaForm
newForm
)
{
if
(
form
==
newForm
)
return
;
if
(
form
==
newForm
)
return
;
assert
(
this
instanceof
DirectMethodHandle
&&
this
.
internalMemberName
().
isStatic
());
// ISSUE: Should we have a memory fence here?
// ISSUE: Should we have a memory fence here?
UNSAFE
.
putObject
(
this
,
FORM_OFFSET
,
newForm
);
UNSAFE
.
putObject
(
this
,
FORM_OFFSET
,
newForm
);
this
.
form
.
prepare
();
// as in MethodHandle.<init>
this
.
form
.
prepare
();
// as in MethodHandle.<init>
...
...
src/share/classes/java/lang/invoke/MethodHandleImpl.java
浏览文件 @
fbfd2d29
...
@@ -357,7 +357,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -357,7 +357,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static
class
AsVarargsCollector
extends
MethodHandle
{
static
class
AsVarargsCollector
extends
MethodHandle
{
private
final
MethodHandle
target
;
private
final
MethodHandle
target
;
private
final
Class
<?>
arrayType
;
private
final
Class
<?>
arrayType
;
private
/*@Stable*/
MethodHandle
asCollectorCache
;
private
@Stable
MethodHandle
asCollectorCache
;
AsVarargsCollector
(
MethodHandle
target
,
MethodType
type
,
Class
<?>
arrayType
)
{
AsVarargsCollector
(
MethodHandle
target
,
MethodType
type
,
Class
<?>
arrayType
)
{
super
(
type
,
reinvokerForm
(
target
));
super
(
type
,
reinvokerForm
(
target
));
...
@@ -534,7 +534,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -534,7 +534,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static
final
MethodHandle
MH_castReference
;
static
final
MethodHandle
MH_castReference
;
static
final
MethodHandle
MH_copyAsPrimitiveArray
;
static
final
MethodHandle
MH_copyAsPrimitiveArray
;
static
final
MethodHandle
MH_copyAsReferenceArray
;
static
final
MethodHandle
MH_fillNewTypedArray
;
static
final
MethodHandle
MH_fillNewTypedArray
;
static
final
MethodHandle
MH_fillNewArray
;
static
final
MethodHandle
MH_fillNewArray
;
static
final
MethodHandle
MH_arrayIdentity
;
static
final
MethodHandle
MH_arrayIdentity
;
...
@@ -557,8 +556,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -557,8 +556,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodType
.
methodType
(
Object
.
class
,
Class
.
class
,
Object
.
class
));
MethodType
.
methodType
(
Object
.
class
,
Class
.
class
,
Object
.
class
));
MH_copyAsPrimitiveArray
=
IMPL_LOOKUP
.
findStatic
(
MHI
,
"copyAsPrimitiveArray"
,
MH_copyAsPrimitiveArray
=
IMPL_LOOKUP
.
findStatic
(
MHI
,
"copyAsPrimitiveArray"
,
MethodType
.
methodType
(
Object
.
class
,
Wrapper
.
class
,
Object
[].
class
));
MethodType
.
methodType
(
Object
.
class
,
Wrapper
.
class
,
Object
[].
class
));
MH_copyAsReferenceArray
=
IMPL_LOOKUP
.
findStatic
(
MHI
,
"copyAsReferenceArray"
,
MethodType
.
methodType
(
Object
[].
class
,
Class
.
class
,
Object
[].
class
));
MH_arrayIdentity
=
IMPL_LOOKUP
.
findStatic
(
MHI
,
"identity"
,
MH_arrayIdentity
=
IMPL_LOOKUP
.
findStatic
(
MHI
,
"identity"
,
MethodType
.
methodType
(
Object
[].
class
,
Object
[].
class
));
MethodType
.
methodType
(
Object
[].
class
,
Object
[].
class
));
MH_fillNewArray
=
IMPL_LOOKUP
.
findStatic
(
MHI
,
"fillNewArray"
,
MH_fillNewArray
=
IMPL_LOOKUP
.
findStatic
(
MHI
,
"fillNewArray"
,
...
@@ -758,7 +755,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -758,7 +755,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
BoundMethodHandle
mh
;
BoundMethodHandle
mh
;
try
{
try
{
mh
=
(
BoundMethodHandle
)
mh
=
(
BoundMethodHandle
)
data
.
constructor
[
0
]
.
invokeBasic
(
type
,
form
,
(
Object
)
target
,
(
Object
)
exType
,
(
Object
)
catcher
,
data
.
constructor
()
.
invokeBasic
(
type
,
form
,
(
Object
)
target
,
(
Object
)
exType
,
(
Object
)
catcher
,
(
Object
)
collectArgs
,
(
Object
)
unboxResult
);
(
Object
)
collectArgs
,
(
Object
)
unboxResult
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
throw
uncaughtException
(
ex
);
throw
uncaughtException
(
ex
);
...
@@ -1095,6 +1092,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -1095,6 +1092,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
}
private
static
Object
[]
fillNewTypedArray
(
Object
[]
example
,
Integer
len
,
Object
[]
/*not ...*/
args
)
{
private
static
Object
[]
fillNewTypedArray
(
Object
[]
example
,
Integer
len
,
Object
[]
/*not ...*/
args
)
{
Object
[]
a
=
Arrays
.
copyOf
(
example
,
len
);
Object
[]
a
=
Arrays
.
copyOf
(
example
,
len
);
assert
(
a
.
getClass
()
!=
Object
[].
class
);
fillWithArguments
(
a
,
0
,
args
);
fillWithArguments
(
a
,
0
,
args
);
return
a
;
return
a
;
}
}
...
@@ -1143,9 +1141,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -1143,9 +1141,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
}
private
static
final
MethodHandle
[]
FILL_ARRAYS
=
makeFillArrays
();
private
static
final
MethodHandle
[]
FILL_ARRAYS
=
makeFillArrays
();
private
static
Object
[]
copyAsReferenceArray
(
Class
<?
extends
Object
[]>
arrayType
,
Object
...
a
)
{
return
Arrays
.
copyOf
(
a
,
a
.
length
,
arrayType
);
}
private
static
Object
copyAsPrimitiveArray
(
Wrapper
w
,
Object
...
boxes
)
{
private
static
Object
copyAsPrimitiveArray
(
Wrapper
w
,
Object
...
boxes
)
{
Object
a
=
w
.
makeArray
(
boxes
.
length
);
Object
a
=
w
.
makeArray
(
boxes
.
length
);
w
.
copyArrayUnboxing
(
boxes
,
0
,
a
,
0
,
boxes
.
length
);
w
.
copyArrayUnboxing
(
boxes
,
0
,
a
,
0
,
boxes
.
length
);
...
@@ -1265,8 +1260,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -1265,8 +1260,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
if
(
nargs
>=
MAX_JVM_ARITY
/
2
-
1
)
{
if
(
nargs
>=
MAX_JVM_ARITY
/
2
-
1
)
{
int
slots
=
nargs
;
int
slots
=
nargs
;
final
int
MAX_ARRAY_SLOTS
=
MAX_JVM_ARITY
-
1
;
// 1 for receiver MH
final
int
MAX_ARRAY_SLOTS
=
MAX_JVM_ARITY
-
1
;
// 1 for receiver MH
if
(
arrayType
==
double
[].
class
||
arrayType
==
long
[].
class
)
if
(
slots
<=
MAX_ARRAY_SLOTS
&&
elemType
.
isPrimitive
()
)
slots
*=
2
;
slots
*=
Wrapper
.
forPrimitiveType
(
elemType
).
stackSlots
()
;
if
(
slots
>
MAX_ARRAY_SLOTS
)
if
(
slots
>
MAX_ARRAY_SLOTS
)
throw
new
IllegalArgumentException
(
"too many arguments: "
+
arrayType
.
getSimpleName
()+
", length "
+
nargs
);
throw
new
IllegalArgumentException
(
"too many arguments: "
+
arrayType
.
getSimpleName
()+
", length "
+
nargs
);
}
}
...
@@ -1276,16 +1271,18 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -1276,16 +1271,18 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodHandle
cache
[]
=
TYPED_COLLECTORS
.
get
(
elemType
);
MethodHandle
cache
[]
=
TYPED_COLLECTORS
.
get
(
elemType
);
MethodHandle
mh
=
nargs
<
cache
.
length
?
cache
[
nargs
]
:
null
;
MethodHandle
mh
=
nargs
<
cache
.
length
?
cache
[
nargs
]
:
null
;
if
(
mh
!=
null
)
return
mh
;
if
(
mh
!=
null
)
return
mh
;
if
(
elemType
.
isPrimitive
())
{
if
(
nargs
==
0
)
{
Object
example
=
java
.
lang
.
reflect
.
Array
.
newInstance
(
arrayType
.
getComponentType
(),
0
);
mh
=
MethodHandles
.
constant
(
arrayType
,
example
);
}
else
if
(
elemType
.
isPrimitive
())
{
MethodHandle
builder
=
Lazy
.
MH_fillNewArray
;
MethodHandle
builder
=
Lazy
.
MH_fillNewArray
;
MethodHandle
producer
=
buildArrayProducer
(
arrayType
);
MethodHandle
producer
=
buildArrayProducer
(
arrayType
);
mh
=
buildVarargsArray
(
builder
,
producer
,
nargs
);
mh
=
buildVarargsArray
(
builder
,
producer
,
nargs
);
}
else
{
}
else
{
@SuppressWarnings
(
"unchecked"
)
Class
<?
extends
Object
[]>
objArrayType
=
arrayType
.
asSubclass
(
Object
[].
class
);
Class
<?
extends
Object
[]>
objArrayType
=
(
Class
<?
extends
Object
[]>)
arrayType
;
Object
[]
example
=
Arrays
.
copyOf
(
NO_ARGS_ARRAY
,
0
,
objArrayType
);
Object
[]
example
=
Arrays
.
copyOf
(
NO_ARGS_ARRAY
,
0
,
objArrayType
);
MethodHandle
builder
=
Lazy
.
MH_fillNewTypedArray
.
bindTo
(
example
);
MethodHandle
builder
=
Lazy
.
MH_fillNewTypedArray
.
bindTo
(
example
);
MethodHandle
producer
=
Lazy
.
MH_arrayIdentity
;
MethodHandle
producer
=
Lazy
.
MH_arrayIdentity
;
// must be weakly typed
mh
=
buildVarargsArray
(
builder
,
producer
,
nargs
);
mh
=
buildVarargsArray
(
builder
,
producer
,
nargs
);
}
}
mh
=
mh
.
asType
(
MethodType
.
methodType
(
arrayType
,
Collections
.<
Class
<?>>
nCopies
(
nargs
,
elemType
)));
mh
=
mh
.
asType
(
MethodType
.
methodType
(
arrayType
,
Collections
.<
Class
<?>>
nCopies
(
nargs
,
elemType
)));
...
@@ -1297,9 +1294,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
...
@@ -1297,9 +1294,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
private
static
MethodHandle
buildArrayProducer
(
Class
<?>
arrayType
)
{
private
static
MethodHandle
buildArrayProducer
(
Class
<?>
arrayType
)
{
Class
<?>
elemType
=
arrayType
.
getComponentType
();
Class
<?>
elemType
=
arrayType
.
getComponentType
();
if
(
elemType
.
isPrimitive
())
assert
(
elemType
.
isPrimitive
());
return
Lazy
.
MH_copyAsPrimitiveArray
.
bindTo
(
Wrapper
.
forPrimitiveType
(
elemType
));
return
Lazy
.
MH_copyAsPrimitiveArray
.
bindTo
(
Wrapper
.
forPrimitiveType
(
elemType
));
else
return
Lazy
.
MH_copyAsReferenceArray
.
bindTo
(
arrayType
);
}
}
}
}
src/share/classes/java/lang/invoke/MethodHandleProxies.java
浏览文件 @
fbfd2d29
...
@@ -33,6 +33,7 @@ import java.util.ArrayList;
...
@@ -33,6 +33,7 @@ import java.util.ArrayList;
import
sun.reflect.CallerSensitive
;
import
sun.reflect.CallerSensitive
;
import
sun.reflect.Reflection
;
import
sun.reflect.Reflection
;
import
sun.reflect.misc.ReflectUtil
;
import
sun.reflect.misc.ReflectUtil
;
import
static
java
.
lang
.
invoke
.
MethodHandleStatics
.*;
/**
/**
* This class consists exclusively of static methods that help adapt
* This class consists exclusively of static methods that help adapt
...
@@ -148,7 +149,7 @@ public class MethodHandleProxies {
...
@@ -148,7 +149,7 @@ public class MethodHandleProxies {
public
static
public
static
<
T
>
T
asInterfaceInstance
(
final
Class
<
T
>
intfc
,
final
MethodHandle
target
)
{
<
T
>
T
asInterfaceInstance
(
final
Class
<
T
>
intfc
,
final
MethodHandle
target
)
{
if
(!
intfc
.
isInterface
()
||
!
Modifier
.
isPublic
(
intfc
.
getModifiers
()))
if
(!
intfc
.
isInterface
()
||
!
Modifier
.
isPublic
(
intfc
.
getModifiers
()))
throw
new
IllegalArgumentException
(
"not a public interface: "
+
intfc
.
getName
());
throw
new
IllegalArgumentException
(
"not a public interface"
,
intfc
.
getName
());
final
MethodHandle
mh
;
final
MethodHandle
mh
;
if
(
System
.
getSecurityManager
()
!=
null
)
{
if
(
System
.
getSecurityManager
()
!=
null
)
{
final
Class
<?>
caller
=
Reflection
.
getCallerClass
();
final
Class
<?>
caller
=
Reflection
.
getCallerClass
();
...
@@ -165,7 +166,7 @@ public class MethodHandleProxies {
...
@@ -165,7 +166,7 @@ public class MethodHandleProxies {
}
}
final
Method
[]
methods
=
getSingleNameMethods
(
intfc
);
final
Method
[]
methods
=
getSingleNameMethods
(
intfc
);
if
(
methods
==
null
)
if
(
methods
==
null
)
throw
new
IllegalArgumentException
(
"not a single-method interface: "
+
intfc
.
getName
());
throw
new
IllegalArgumentException
(
"not a single-method interface"
,
intfc
.
getName
());
final
MethodHandle
[]
vaTargets
=
new
MethodHandle
[
methods
.
length
];
final
MethodHandle
[]
vaTargets
=
new
MethodHandle
[
methods
.
length
];
for
(
int
i
=
0
;
i
<
methods
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
methods
.
length
;
i
++)
{
Method
sm
=
methods
[
i
];
Method
sm
=
methods
[
i
];
...
@@ -189,7 +190,7 @@ public class MethodHandleProxies {
...
@@ -189,7 +190,7 @@ public class MethodHandleProxies {
return
getArg
(
method
.
getName
());
return
getArg
(
method
.
getName
());
if
(
isObjectMethod
(
method
))
if
(
isObjectMethod
(
method
))
return
callObjectMethod
(
proxy
,
method
,
args
);
return
callObjectMethod
(
proxy
,
method
,
args
);
throw
new
InternalError
(
"bad proxy method: "
+
method
);
throw
newInternalError
(
"bad proxy method: "
+
method
);
}
}
};
};
...
@@ -240,7 +241,7 @@ public class MethodHandleProxies {
...
@@ -240,7 +241,7 @@ public class MethodHandleProxies {
return
(
WrapperInstance
)
x
;
return
(
WrapperInstance
)
x
;
}
catch
(
ClassCastException
ex
)
{
}
catch
(
ClassCastException
ex
)
{
}
}
throw
new
IllegalArgumentException
(
"not a wrapper instance"
);
throw
newIllegalArgumentException
(
"not a wrapper instance"
);
}
}
/**
/**
...
...
src/share/classes/java/lang/invoke/MethodHandleStatics.java
浏览文件 @
fbfd2d29
...
@@ -45,7 +45,7 @@ import sun.misc.Unsafe;
...
@@ -45,7 +45,7 @@ import sun.misc.Unsafe;
static
final
boolean
DUMP_CLASS_FILES
;
static
final
boolean
DUMP_CLASS_FILES
;
static
final
boolean
TRACE_INTERPRETER
;
static
final
boolean
TRACE_INTERPRETER
;
static
final
boolean
TRACE_METHOD_LINKAGE
;
static
final
boolean
TRACE_METHOD_LINKAGE
;
static
final
Integer
COMPILE_THRESHOLD
;
static
final
int
COMPILE_THRESHOLD
;
static
final
int
PROFILE_LEVEL
;
static
final
int
PROFILE_LEVEL
;
static
{
static
{
...
@@ -56,7 +56,7 @@ import sun.misc.Unsafe;
...
@@ -56,7 +56,7 @@ import sun.misc.Unsafe;
values
[
1
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.DUMP_CLASS_FILES"
);
values
[
1
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.DUMP_CLASS_FILES"
);
values
[
2
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.TRACE_INTERPRETER"
);
values
[
2
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.TRACE_INTERPRETER"
);
values
[
3
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"
);
values
[
3
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"
);
values
[
4
]
=
Integer
.
getInteger
(
"java.lang.invoke.MethodHandle.COMPILE_THRESHOLD"
);
values
[
4
]
=
Integer
.
getInteger
(
"java.lang.invoke.MethodHandle.COMPILE_THRESHOLD"
,
30
);
values
[
5
]
=
Integer
.
getInteger
(
"java.lang.invoke.MethodHandle.PROFILE_LEVEL"
,
0
);
values
[
5
]
=
Integer
.
getInteger
(
"java.lang.invoke.MethodHandle.PROFILE_LEVEL"
,
0
);
return
null
;
return
null
;
}
}
...
@@ -131,7 +131,10 @@ import sun.misc.Unsafe;
...
@@ -131,7 +131,10 @@ import sun.misc.Unsafe;
/*non-public*/
static
RuntimeException
newIllegalArgumentException
(
String
message
,
Object
obj
,
Object
obj2
)
{
/*non-public*/
static
RuntimeException
newIllegalArgumentException
(
String
message
,
Object
obj
,
Object
obj2
)
{
return
new
IllegalArgumentException
(
message
(
message
,
obj
,
obj2
));
return
new
IllegalArgumentException
(
message
(
message
,
obj
,
obj2
));
}
}
/** Propagate unchecked exceptions and errors, but wrap anything checked and throw that instead. */
/*non-public*/
static
Error
uncaughtException
(
Throwable
ex
)
{
/*non-public*/
static
Error
uncaughtException
(
Throwable
ex
)
{
if
(
ex
instanceof
Error
)
throw
(
Error
)
ex
;
if
(
ex
instanceof
RuntimeException
)
throw
(
RuntimeException
)
ex
;
throw
newInternalError
(
"uncaught exception"
,
ex
);
throw
newInternalError
(
"uncaught exception"
,
ex
);
}
}
static
Error
NYI
()
{
static
Error
NYI
()
{
...
...
src/share/classes/java/lang/invoke/MethodHandles.java
浏览文件 @
fbfd2d29
...
@@ -863,6 +863,8 @@ assertEquals("", (String) MH_newString.invokeExact());
...
@@ -863,6 +863,8 @@ assertEquals("", (String) MH_newString.invokeExact());
return
invoker
(
type
);
return
invoker
(
type
);
if
(
"invokeExact"
.
equals
(
name
))
if
(
"invokeExact"
.
equals
(
name
))
return
exactInvoker
(
type
);
return
exactInvoker
(
type
);
if
(
"invokeBasic"
.
equals
(
name
))
return
basicInvoker
(
type
);
assert
(!
MemberName
.
isMethodHandleInvokeName
(
name
));
assert
(!
MemberName
.
isMethodHandleInvokeName
(
name
));
return
null
;
return
null
;
}
}
...
@@ -1880,7 +1882,7 @@ return invoker;
...
@@ -1880,7 +1882,7 @@ return invoker;
static
public
static
public
MethodHandle
spreadInvoker
(
MethodType
type
,
int
leadingArgCount
)
{
MethodHandle
spreadInvoker
(
MethodType
type
,
int
leadingArgCount
)
{
if
(
leadingArgCount
<
0
||
leadingArgCount
>
type
.
parameterCount
())
if
(
leadingArgCount
<
0
||
leadingArgCount
>
type
.
parameterCount
())
throw
new
IllegalArgumentException
(
"bad argument count "
+
leadingArgCount
);
throw
new
IllegalArgumentException
(
"bad argument count"
,
leadingArgCount
);
return
type
.
invokers
().
spreadInvoker
(
leadingArgCount
);
return
type
.
invokers
().
spreadInvoker
(
leadingArgCount
);
}
}
...
@@ -1965,7 +1967,7 @@ return invoker;
...
@@ -1965,7 +1967,7 @@ return invoker;
static
/*non-public*/
static
/*non-public*/
MethodHandle
basicInvoker
(
MethodType
type
)
{
MethodHandle
basicInvoker
(
MethodType
type
)
{
return
type
.
form
().
basicInvoker
();
return
type
.
invokers
().
basicInvoker
();
}
}
/// method handle modification (creation from other method handles)
/// method handle modification (creation from other method handles)
...
...
src/share/classes/java/lang/invoke/MethodType.java
浏览文件 @
fbfd2d29
...
@@ -907,7 +907,7 @@ class MethodType implements java.io.Serializable {
...
@@ -907,7 +907,7 @@ class MethodType implements java.io.Serializable {
if
(!
descriptor
.
startsWith
(
"("
)
||
// also generates NPE if needed
if
(!
descriptor
.
startsWith
(
"("
)
||
// also generates NPE if needed
descriptor
.
indexOf
(
')'
)
<
0
||
descriptor
.
indexOf
(
')'
)
<
0
||
descriptor
.
indexOf
(
'.'
)
>=
0
)
descriptor
.
indexOf
(
'.'
)
>=
0
)
throw
new
IllegalArgumentException
(
"not a method descriptor: "
+
descriptor
);
throw
newIllegalArgumentException
(
"not a method descriptor: "
+
descriptor
);
List
<
Class
<?>>
types
=
BytecodeDescriptor
.
parseMethod
(
descriptor
,
loader
);
List
<
Class
<?>>
types
=
BytecodeDescriptor
.
parseMethod
(
descriptor
,
loader
);
Class
<?>
rtype
=
types
.
remove
(
types
.
size
()
-
1
);
Class
<?>
rtype
=
types
.
remove
(
types
.
size
()
-
1
);
checkSlotCount
(
types
.
size
());
checkSlotCount
(
types
.
size
());
...
...
src/share/classes/java/lang/invoke/MethodTypeForm.java
浏览文件 @
fbfd2d29
...
@@ -47,14 +47,10 @@ final class MethodTypeForm {
...
@@ -47,14 +47,10 @@ final class MethodTypeForm {
final
int
[]
argToSlotTable
,
slotToArgTable
;
final
int
[]
argToSlotTable
,
slotToArgTable
;
final
long
argCounts
;
// packed slot & value counts
final
long
argCounts
;
// packed slot & value counts
final
long
primCounts
;
// packed prim & double counts
final
long
primCounts
;
// packed prim & double counts
final
int
vmslots
;
// total number of parameter slots
final
MethodType
erasedType
;
// the canonical erasure
final
MethodType
erasedType
;
// the canonical erasure
final
MethodType
basicType
;
// the canonical erasure, with primitives simplified
final
MethodType
basicType
;
// the canonical erasure, with primitives simplified
// Cached adapter information:
// Cached adapter information:
@Stable
String
typeString
;
// argument type signature characters
@Stable
MethodHandle
genericInvoker
;
// JVM hook for inexact invoke
@Stable
MethodHandle
basicInvoker
;
// cached instance of MH.invokeBasic
@Stable
MethodHandle
namedFunctionInvoker
;
// cached helper for LF.NamedFunction
@Stable
MethodHandle
namedFunctionInvoker
;
// cached helper for LF.NamedFunction
// Cached lambda form information, for basic types only:
// Cached lambda form information, for basic types only:
...
@@ -70,24 +66,40 @@ final class MethodTypeForm {
...
@@ -70,24 +66,40 @@ final class MethodTypeForm {
LF_INTERPRET
=
6
,
// LF interpreter
LF_INTERPRET
=
6
,
// LF interpreter
LF_COUNTER
=
7
,
// CMH wrapper
LF_COUNTER
=
7
,
// CMH wrapper
LF_REINVOKE
=
8
,
// other wrapper
LF_REINVOKE
=
8
,
// other wrapper
LF_EX_LINKER
=
9
,
// invokeExact_MT
LF_EX_LINKER
=
9
,
// invokeExact_MT
(for invokehandle)
LF_EX_INVOKER
=
10
,
//
invokeExact MH
LF_EX_INVOKER
=
10
,
//
MHs.invokeExact
LF_GEN_LINKER
=
11
,
LF_GEN_LINKER
=
11
,
// generic invoke_MT (for invokehandle)
LF_GEN_INVOKER
=
12
,
LF_GEN_INVOKER
=
12
,
// generic MHs.invoke
LF_CS_LINKER
=
13
,
// linkToCallSite_CS
LF_CS_LINKER
=
13
,
// linkToCallSite_CS
LF_MH_LINKER
=
14
,
// linkToCallSite_MH
LF_MH_LINKER
=
14
,
// linkToCallSite_MH
LF_GWC
=
15
,
LF_GWC
=
15
,
// guardWithCatch (catchException)
LF_LIMIT
=
16
;
LF_LIMIT
=
16
;
/** Return the type corresponding uniquely (1-1) to this MT-form.
* It might have any primitive returns or arguments, but will have no references except Object.
*/
public
MethodType
erasedType
()
{
public
MethodType
erasedType
()
{
return
erasedType
;
return
erasedType
;
}
}
/** Return the basic type derived from the erased type of this MT-form.
* A basic type is erased (all references Object) and also has all primitive
* types (except int, long, float, double, void) normalized to int.
* Such basic types correspond to low-level JVM calling sequences.
*/
public
MethodType
basicType
()
{
public
MethodType
basicType
()
{
return
basicType
;
return
basicType
;
}
}
private
boolean
assertIsBasicType
()
{
// primitives must be flattened also
assert
(
erasedType
==
basicType
)
:
"erasedType: "
+
erasedType
+
" != basicType: "
+
basicType
;
return
true
;
}
public
LambdaForm
cachedLambdaForm
(
int
which
)
{
public
LambdaForm
cachedLambdaForm
(
int
which
)
{
assert
(
assertIsBasicType
());
return
lambdaForms
[
which
];
return
lambdaForms
[
which
];
}
}
...
@@ -98,28 +110,6 @@ final class MethodTypeForm {
...
@@ -98,28 +110,6 @@ final class MethodTypeForm {
return
lambdaForms
[
which
]
=
form
;
return
lambdaForms
[
which
]
=
form
;
}
}
public
MethodHandle
basicInvoker
()
{
assert
(
erasedType
==
basicType
)
:
"erasedType: "
+
erasedType
+
" != basicType: "
+
basicType
;
// primitives must be flattened also
MethodHandle
invoker
=
basicInvoker
;
if
(
invoker
!=
null
)
return
invoker
;
invoker
=
DirectMethodHandle
.
make
(
invokeBasicMethod
(
basicType
));
basicInvoker
=
invoker
;
return
invoker
;
}
// This next one is called from LambdaForm.NamedFunction.<init>.
/*non-public*/
static
MemberName
invokeBasicMethod
(
MethodType
basicType
)
{
assert
(
basicType
==
basicType
.
basicType
());
try
{
// Do approximately the same as this public API call:
// Lookup.findVirtual(MethodHandle.class, name, type);
// But bypass access and corner case checks, since we know exactly what we need.
return
IMPL_LOOKUP
.
resolveOrFail
(
REF_invokeVirtual
,
MethodHandle
.
class
,
"invokeBasic"
,
basicType
);
}
catch
(
ReflectiveOperationException
ex
)
{
throw
newInternalError
(
"JVM cannot find invoker for "
+
basicType
,
ex
);
}
}
/**
/**
* Build an MTF for a given type, which must have all references erased to Object.
* Build an MTF for a given type, which must have all references erased to Object.
* This MTF will stand for that type and all un-erased variations.
* This MTF will stand for that type and all un-erased variations.
...
@@ -172,6 +162,15 @@ final class MethodTypeForm {
...
@@ -172,6 +162,15 @@ final class MethodTypeForm {
this
.
basicType
=
erasedType
;
this
.
basicType
=
erasedType
;
}
else
{
}
else
{
this
.
basicType
=
MethodType
.
makeImpl
(
bt
,
bpts
,
true
);
this
.
basicType
=
MethodType
.
makeImpl
(
bt
,
bpts
,
true
);
// fill in rest of data from the basic type:
MethodTypeForm
that
=
this
.
basicType
.
form
();
assert
(
this
!=
that
);
this
.
primCounts
=
that
.
primCounts
;
this
.
argCounts
=
that
.
argCounts
;
this
.
argToSlotTable
=
that
.
argToSlotTable
;
this
.
slotToArgTable
=
that
.
slotToArgTable
;
this
.
lambdaForms
=
null
;
return
;
}
}
if
(
lac
!=
0
)
{
if
(
lac
!=
0
)
{
int
slot
=
ptypeCount
+
lac
;
int
slot
=
ptypeCount
+
lac
;
...
@@ -187,10 +186,14 @@ final class MethodTypeForm {
...
@@ -187,10 +186,14 @@ final class MethodTypeForm {
argToSlotTab
[
1
+
i
]
=
slot
;
argToSlotTab
[
1
+
i
]
=
slot
;
}
}
assert
(
slot
==
0
);
// filled the table
assert
(
slot
==
0
);
// filled the table
}
}
else
if
(
pac
!=
0
)
{
this
.
primCounts
=
pack
(
lrc
,
prc
,
lac
,
pac
);
// have primitives but no long primitives; share slot counts with generic
this
.
argCounts
=
pack
(
rslotCount
,
rtypeCount
,
pslotCount
,
ptypeCount
);
assert
(
ptypeCount
==
pslotCount
);
if
(
slotToArgTab
==
null
)
{
MethodTypeForm
that
=
MethodType
.
genericMethodType
(
ptypeCount
).
form
();
assert
(
this
!=
that
);
slotToArgTab
=
that
.
slotToArgTable
;
argToSlotTab
=
that
.
argToSlotTable
;
}
else
{
int
slot
=
ptypeCount
;
// first arg is deepest in stack
int
slot
=
ptypeCount
;
// first arg is deepest in stack
slotToArgTab
=
new
int
[
slot
+
1
];
slotToArgTab
=
new
int
[
slot
+
1
];
argToSlotTab
=
new
int
[
1
+
ptypeCount
];
argToSlotTab
=
new
int
[
1
+
ptypeCount
];
...
@@ -201,19 +204,16 @@ final class MethodTypeForm {
...
@@ -201,19 +204,16 @@ final class MethodTypeForm {
argToSlotTab
[
1
+
i
]
=
slot
;
argToSlotTab
[
1
+
i
]
=
slot
;
}
}
}
}
this
.
primCounts
=
pack
(
lrc
,
prc
,
lac
,
pac
);
this
.
argCounts
=
pack
(
rslotCount
,
rtypeCount
,
pslotCount
,
ptypeCount
);
this
.
argToSlotTable
=
argToSlotTab
;
this
.
argToSlotTable
=
argToSlotTab
;
this
.
slotToArgTable
=
slotToArgTab
;
this
.
slotToArgTable
=
slotToArgTab
;
if
(
pslotCount
>=
256
)
throw
newIllegalArgumentException
(
"too many arguments"
);
if
(
pslotCount
>=
256
)
throw
newIllegalArgumentException
(
"too many arguments"
);
// send a few bits down to the JVM:
// Initialize caches, but only for basic types
this
.
vmslots
=
parameterSlotCount
();
assert
(
basicType
==
erasedType
);
this
.
lambdaForms
=
new
LambdaForm
[
LF_LIMIT
];
if
(
basicType
==
erasedType
)
{
lambdaForms
=
new
LambdaForm
[
LF_LIMIT
];
}
else
{
lambdaForms
=
null
;
// could be basicType.form().lambdaForms;
}
}
}
private
static
long
pack
(
int
a
,
int
b
,
int
c
,
int
d
)
{
private
static
long
pack
(
int
a
,
int
b
,
int
c
,
int
d
)
{
...
@@ -300,7 +300,7 @@ final class MethodTypeForm {
...
@@ -300,7 +300,7 @@ final class MethodTypeForm {
*/
*/
public
static
MethodType
canonicalize
(
MethodType
mt
,
int
howRet
,
int
howArgs
)
{
public
static
MethodType
canonicalize
(
MethodType
mt
,
int
howRet
,
int
howArgs
)
{
Class
<?>[]
ptypes
=
mt
.
ptypes
();
Class
<?>[]
ptypes
=
mt
.
ptypes
();
Class
<?>[]
ptc
=
MethodTypeForm
.
canonicalize
s
(
ptypes
,
howArgs
);
Class
<?>[]
ptc
=
MethodTypeForm
.
canonicalize
All
(
ptypes
,
howArgs
);
Class
<?>
rtype
=
mt
.
returnType
();
Class
<?>
rtype
=
mt
.
returnType
();
Class
<?>
rtc
=
MethodTypeForm
.
canonicalize
(
rtype
,
howRet
);
Class
<?>
rtc
=
MethodTypeForm
.
canonicalize
(
rtype
,
howRet
);
if
(
ptc
==
null
&&
rtc
==
null
)
{
if
(
ptc
==
null
&&
rtc
==
null
)
{
...
@@ -368,7 +368,7 @@ final class MethodTypeForm {
...
@@ -368,7 +368,7 @@ final class MethodTypeForm {
/** Canonicalize each param type in the given array.
/** Canonicalize each param type in the given array.
* Return null if all types are already canonicalized.
* Return null if all types are already canonicalized.
*/
*/
static
Class
<?>[]
canonicalize
s
(
Class
<?>[]
ts
,
int
how
)
{
static
Class
<?>[]
canonicalize
All
(
Class
<?>[]
ts
,
int
how
)
{
Class
<?>[]
cs
=
null
;
Class
<?>[]
cs
=
null
;
for
(
int
imax
=
ts
.
length
,
i
=
0
;
i
<
imax
;
i
++)
{
for
(
int
imax
=
ts
.
length
,
i
=
0
;
i
<
imax
;
i
++)
{
Class
<?>
c
=
canonicalize
(
ts
[
i
],
how
);
Class
<?>
c
=
canonicalize
(
ts
[
i
],
how
);
...
...
test/java/lang/invoke/MethodHandlesTest.java
浏览文件 @
fbfd2d29
...
@@ -2160,15 +2160,23 @@ public class MethodHandlesTest {
...
@@ -2160,15 +2160,23 @@ public class MethodHandlesTest {
else
else
type
=
type
.
changeParameterType
(
j
,
argType
);
type
=
type
.
changeParameterType
(
j
,
argType
);
if
(
done
.
add
(
type
))
if
(
done
.
add
(
type
))
testInvokers
(
type
);
testInvokers
WithCatch
(
type
);
MethodType
vtype
=
type
.
changeReturnType
(
void
.
class
);
MethodType
vtype
=
type
.
changeReturnType
(
void
.
class
);
if
(
done
.
add
(
vtype
))
if
(
done
.
add
(
vtype
))
testInvokers
(
vtype
);
testInvokers
WithCatch
(
vtype
);
}
}
}
}
}
}
}
}
public
void
testInvokersWithCatch
(
MethodType
type
)
throws
Throwable
{
try
{
testInvokers
(
type
);
}
catch
(
Throwable
ex
)
{
System
.
out
.
println
(
"*** testInvokers on "
+
type
+
" => "
);
ex
.
printStackTrace
(
System
.
out
);
}
}
public
void
testInvokers
(
MethodType
type
)
throws
Throwable
{
public
void
testInvokers
(
MethodType
type
)
throws
Throwable
{
if
(
verbosity
>=
3
)
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"test invokers for "
+
type
);
System
.
out
.
println
(
"test invokers for "
+
type
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录