Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
c2204994
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看板
提交
c2204994
编写于
11月 30, 2015
作者:
P
plevart
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8131129: Attempt to define a duplicate BMH$Species class
Reviewed-by: mhaupt, redestad, vlivanov
上级
2deb6469
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
76 addition
and
75 deletion
+76
-75
src/share/classes/java/lang/invoke/BoundMethodHandle.java
src/share/classes/java/lang/invoke/BoundMethodHandle.java
+76
-75
未找到文件。
src/share/classes/java/lang/invoke/BoundMethodHandle.java
浏览文件 @
c2204994
...
...
@@ -34,14 +34,16 @@ import java.lang.invoke.LambdaForm.NamedFunction;
import
java.lang.invoke.MethodHandles.Lookup
;
import
java.lang.reflect.Field
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.function.Function
;
import
java.util.concurrent.ConcurrentMap
;
import
java.util.concurrent.ConcurrentHashMap
;
import
jdk.internal.org.objectweb.asm.FieldVisitor
;
import
sun.invoke.util.ValueConversions
;
import
sun.invoke.util.Wrapper
;
import
jdk.internal.org.objectweb.asm.ClassWriter
;
import
jdk.internal.org.objectweb.asm.MethodVisitor
;
import
jdk.internal.org.objectweb.asm.Type
;
/**
* The flavor of method handle which emulates an invoke instruction
...
...
@@ -217,7 +219,7 @@ import jdk.internal.org.objectweb.asm.Type;
/*non-public*/
int
fieldCount
()
{
return
1
;
}
/*non-public*/
static
final
SpeciesData
SPECIES_DATA
=
SpeciesData
.
getForClass
(
"L"
,
Species_L
.
class
);
/*non-public*/
static
final
SpeciesData
SPECIES_DATA
=
new
SpeciesData
(
"L"
,
Species_L
.
class
);
/*non-public*/
static
BoundMethodHandle
make
(
MethodType
mt
,
LambdaForm
lf
,
Object
argL0
)
{
return
new
Species_L
(
mt
,
lf
,
argL0
);
}
...
...
@@ -335,7 +337,7 @@ import jdk.internal.org.objectweb.asm.Type;
static
final
SpeciesData
EMPTY
=
new
SpeciesData
(
""
,
BoundMethodHandle
.
class
);
private
SpeciesData
(
String
types
,
Class
<?
extends
BoundMethodHandle
>
clazz
)
{
SpeciesData
(
String
types
,
Class
<?
extends
BoundMethodHandle
>
clazz
)
{
this
.
typeChars
=
types
;
this
.
typeCodes
=
basicTypes
(
types
);
this
.
clazz
=
clazz
;
...
...
@@ -355,26 +357,14 @@ import jdk.internal.org.objectweb.asm.Type;
assert
(!
INIT_DONE
);
if
(
constructor
()
==
null
)
{
String
types
=
typeChars
;
CACHE
.
put
(
types
,
this
);
Factory
.
makeCtors
(
clazz
,
types
,
this
.
constructor
);
Factory
.
makeGetters
(
clazz
,
types
,
this
.
getters
);
Factory
.
makeNominalGetters
(
types
,
this
.
nominalGetters
,
this
.
getters
);
}
}
private
SpeciesData
(
String
typeChars
)
{
// Placeholder only.
this
.
typeChars
=
typeChars
;
this
.
typeCodes
=
basicTypes
(
typeChars
);
this
.
clazz
=
null
;
this
.
constructor
=
null
;
this
.
getters
=
null
;
this
.
nominalGetters
=
null
;
this
.
extensions
=
null
;
}
private
boolean
isPlaceholder
()
{
return
clazz
==
null
;
}
private
static
final
HashMap
<
String
,
SpeciesData
>
CACHE
=
new
HashMap
<>();
static
{
CACHE
.
put
(
""
,
EMPTY
);
}
// make bootstrap predictable
private
static
final
ConcurrentMap
<
String
,
SpeciesData
>
CACHE
=
new
ConcurrentHashMap
<>();
private
static
final
boolean
INIT_DONE
;
// set after <clinit> finishes...
SpeciesData
extendWith
(
byte
type
)
{
...
...
@@ -390,62 +380,52 @@ import jdk.internal.org.objectweb.asm.Type;
}
private
static
SpeciesData
get
(
String
types
)
{
// Acquire cache lock for query.
SpeciesData
d
=
lookupCache
(
types
);
if
(!
d
.
isPlaceholder
())
return
d
;
synchronized
(
d
)
{
// Use synch. on the placeholder to prevent multiple instantiation of one species.
// Creating this class forces a recursive call to getForClass.
if
(
lookupCache
(
types
).
isPlaceholder
())
Factory
.
generateConcreteBMHClass
(
types
);
}
// Reacquire cache lock.
d
=
lookupCache
(
types
);
// Class loading must have upgraded the cache.
assert
(
d
!=
null
&&
!
d
.
isPlaceholder
());
return
d
;
}
static
SpeciesData
getForClass
(
String
types
,
Class
<?
extends
BoundMethodHandle
>
clazz
)
{
// clazz is a new class which is initializing its SPECIES_DATA field
return
updateCache
(
types
,
new
SpeciesData
(
types
,
clazz
));
}
private
static
synchronized
SpeciesData
lookupCache
(
String
types
)
{
SpeciesData
d
=
CACHE
.
get
(
types
);
if
(
d
!=
null
)
return
d
;
d
=
new
SpeciesData
(
types
);
assert
(
d
.
isPlaceholder
());
CACHE
.
put
(
types
,
d
);
return
d
;
}
private
static
synchronized
SpeciesData
updateCache
(
String
types
,
SpeciesData
d
)
{
SpeciesData
d2
;
assert
((
d2
=
CACHE
.
get
(
types
))
==
null
||
d2
.
isPlaceholder
());
assert
(!
d
.
isPlaceholder
());
CACHE
.
put
(
types
,
d
);
return
d
;
return
CACHE
.
computeIfAbsent
(
types
,
new
Function
<
String
,
SpeciesData
>()
{
@Override
public
SpeciesData
apply
(
String
types
)
{
Class
<?
extends
BoundMethodHandle
>
bmhcl
=
Factory
.
getConcreteBMHClass
(
types
);
// SpeciesData instantiation may throw VirtualMachineError because of
// code cache overflow...
SpeciesData
speciesData
=
new
SpeciesData
(
types
,
bmhcl
);
// CHM.computeIfAbsent ensures only one SpeciesData will be set
// successfully on the concrete BMH class if ever
Factory
.
setSpeciesDataToConcreteBMHClass
(
bmhcl
,
speciesData
);
// the concrete BMH class is published via SpeciesData instance
// returned here only after it's SPECIES_DATA field is set
return
speciesData
;
}
});
}
static
{
// pre-fill the BMH speciesdata cache with BMH's inner classes
final
Class
<
BoundMethodHandle
>
rootCls
=
BoundMethodHandle
.
class
;
/**
* This is to be called when assertions are enabled. It checks whether SpeciesData for all of the statically
* defined species subclasses of BoundMethodHandle has been added to the SpeciesData cache. See below in the
* static initializer for
*/
static
boolean
speciesDataCachePopulated
()
{
Class
<
BoundMethodHandle
>
rootCls
=
BoundMethodHandle
.
class
;
try
{
for
(
Class
<?>
c
:
rootCls
.
getDeclaredClasses
())
{
if
(
rootCls
.
isAssignableFrom
(
c
))
{
final
Class
<?
extends
BoundMethodHandle
>
cbmh
=
c
.
asSubclass
(
BoundMethodHandle
.
class
);
SpeciesData
d
=
Factory
.
s
peciesDataFromConcreteBMHClass
(
cbmh
);
SpeciesData
d
=
Factory
.
getS
peciesDataFromConcreteBMHClass
(
cbmh
);
assert
(
d
!=
null
)
:
cbmh
.
getName
();
assert
(
d
.
clazz
==
cbmh
);
assert
(
d
==
lookupCache
(
d
.
typeChars
)
);
assert
(
CACHE
.
get
(
d
.
typeChars
)
==
d
);
}
}
}
catch
(
Throwable
e
)
{
throw
newInternalError
(
e
);
}
return
true
;
}
for
(
SpeciesData
d
:
CACHE
.
values
())
{
d
.
initForBootstrap
();
}
static
{
// Pre-fill the BMH species-data cache with EMPTY and all BMH's inner subclasses.
EMPTY
.
initForBootstrap
();
Species_L
.
SPECIES_DATA
.
initForBootstrap
();
// check that all static SpeciesData instances have been initialized
assert
speciesDataCachePopulated
();
// Note: Do not simplify this, because INIT_DONE must not be
// a compile-time constant during bootstrapping.
INIT_DONE
=
Boolean
.
TRUE
;
...
...
@@ -479,6 +459,7 @@ import jdk.internal.org.objectweb.asm.Type;
static
final
String
BMH_SIG
=
"L"
+
BMH
+
";"
;
static
final
String
SPECIES_DATA
=
"java/lang/invoke/BoundMethodHandle$SpeciesData"
;
static
final
String
SPECIES_DATA_SIG
=
"L"
+
SPECIES_DATA
+
";"
;
static
final
String
STABLE_SIG
=
"Ljava/lang/invoke/Stable;"
;
static
final
String
SPECIES_PREFIX_NAME
=
"Species_"
;
static
final
String
SPECIES_PREFIX_PATH
=
BMH
+
"$"
+
SPECIES_PREFIX_NAME
;
...
...
@@ -493,6 +474,26 @@ import jdk.internal.org.objectweb.asm.Type;
static
final
String
[]
E_THROWABLE
=
new
String
[]
{
"java/lang/Throwable"
};
static
final
ConcurrentMap
<
String
,
Class
<?
extends
BoundMethodHandle
>>
CLASS_CACHE
=
new
ConcurrentHashMap
<>();
/**
* Get a concrete subclass of BMH for a given combination of bound types.
*
* @param types the type signature, wherein reference types are erased to 'L'
* @return the concrete BMH class
*/
static
Class
<?
extends
BoundMethodHandle
>
getConcreteBMHClass
(
String
types
)
{
// CHM.computeIfAbsent ensures generateConcreteBMHClass is called
// only once per key.
return
CLASS_CACHE
.
computeIfAbsent
(
types
,
new
Function
<
String
,
Class
<?
extends
BoundMethodHandle
>>()
{
@Override
public
Class
<?
extends
BoundMethodHandle
>
apply
(
String
types
)
{
return
generateConcreteBMHClass
(
types
);
}
});
}
/**
* Generate a concrete subclass of BMH for a given combination of bound types.
*
...
...
@@ -529,7 +530,7 @@ import jdk.internal.org.objectweb.asm.Type;
* }
* final SpeciesData speciesData() { return SPECIES_DATA; }
* final int fieldCount() { return 3; }
*
static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
*
@Stable static SpeciesData SPECIES_DATA; // injected afterwards
* static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
* return new Species_LLI(mt, lf, argL0, argL1, argI2);
* }
...
...
@@ -568,7 +569,9 @@ import jdk.internal.org.objectweb.asm.Type;
cw
.
visitSource
(
sourceFile
,
null
);
// emit static types and SPECIES_DATA fields
cw
.
visitField
(
NOT_ACC_PUBLIC
+
ACC_STATIC
,
"SPECIES_DATA"
,
SPECIES_DATA_SIG
,
null
,
null
).
visitEnd
();
FieldVisitor
fw
=
cw
.
visitField
(
NOT_ACC_PUBLIC
+
ACC_STATIC
,
"SPECIES_DATA"
,
SPECIES_DATA_SIG
,
null
,
null
);
fw
.
visitAnnotation
(
STABLE_SIG
,
true
);
fw
.
visitEnd
();
// emit bound argument fields
for
(
int
i
=
0
;
i
<
types
.
length
();
++
i
)
{
...
...
@@ -694,17 +697,6 @@ import jdk.internal.org.objectweb.asm.Type;
mv
.
visitEnd
();
}
// emit class initializer
mv
=
cw
.
visitMethod
(
NOT_ACC_PUBLIC
|
ACC_STATIC
,
"<clinit>"
,
VOID_SIG
,
null
,
null
);
mv
.
visitCode
();
mv
.
visitLdcInsn
(
types
);
mv
.
visitLdcInsn
(
Type
.
getObjectType
(
className
));
mv
.
visitMethodInsn
(
INVOKESTATIC
,
SPECIES_DATA
,
"getForClass"
,
BMHSPECIES_DATA_GFC_SIG
,
false
);
mv
.
visitFieldInsn
(
PUTSTATIC
,
className
,
"SPECIES_DATA"
,
SPECIES_DATA_SIG
);
mv
.
visitInsn
(
RETURN
);
mv
.
visitMaxs
(
0
,
0
);
mv
.
visitEnd
();
cw
.
visitEnd
();
// load class
...
...
@@ -715,7 +707,6 @@ import jdk.internal.org.objectweb.asm.Type;
UNSAFE
.
defineClass
(
className
,
classFile
,
0
,
classFile
.
length
,
BoundMethodHandle
.
class
.
getClassLoader
(),
null
)
.
asSubclass
(
BoundMethodHandle
.
class
);
UNSAFE
.
ensureClassInitialized
(
bmhClass
);
return
bmhClass
;
}
...
...
@@ -785,7 +776,7 @@ import jdk.internal.org.objectweb.asm.Type;
// Auxiliary methods.
//
static
SpeciesData
s
peciesDataFromConcreteBMHClass
(
Class
<?
extends
BoundMethodHandle
>
cbmh
)
{
static
SpeciesData
getS
peciesDataFromConcreteBMHClass
(
Class
<?
extends
BoundMethodHandle
>
cbmh
)
{
try
{
Field
F_SPECIES_DATA
=
cbmh
.
getDeclaredField
(
"SPECIES_DATA"
);
return
(
SpeciesData
)
F_SPECIES_DATA
.
get
(
null
);
...
...
@@ -794,6 +785,16 @@ import jdk.internal.org.objectweb.asm.Type;
}
}
static
void
setSpeciesDataToConcreteBMHClass
(
Class
<?
extends
BoundMethodHandle
>
cbmh
,
SpeciesData
speciesData
)
{
try
{
Field
F_SPECIES_DATA
=
cbmh
.
getDeclaredField
(
"SPECIES_DATA"
);
assert
F_SPECIES_DATA
.
getDeclaredAnnotation
(
Stable
.
class
)
!=
null
;
F_SPECIES_DATA
.
set
(
null
,
speciesData
);
}
catch
(
ReflectiveOperationException
ex
)
{
throw
newInternalError
(
ex
);
}
}
/**
* Field names in concrete BMHs adhere to this pattern:
* arg + type + index
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录