Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
fff405fa
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看板
提交
fff405fa
编写于
6月 18, 2013
作者:
C
chegar
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
0fdc467c
9cbd3827
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
460 addition
and
506 deletion
+460
-506
src/share/classes/java/lang/Class.java
src/share/classes/java/lang/Class.java
+49
-23
src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
...java/lang/invoke/AbstractValidatingLambdaMetafactory.java
+49
-130
src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
...classes/java/lang/invoke/InnerClassLambdaMetafactory.java
+73
-69
src/share/classes/java/lang/invoke/LambdaMetafactory.java
src/share/classes/java/lang/invoke/LambdaMetafactory.java
+97
-47
src/share/classes/java/lang/invoke/MethodType.java
src/share/classes/java/lang/invoke/MethodType.java
+74
-234
src/share/classes/java/security/Signature.java
src/share/classes/java/security/Signature.java
+2
-1
src/share/classes/sun/reflect/generics/repository/ClassRepository.java
...sses/sun/reflect/generics/repository/ClassRepository.java
+2
-0
src/share/native/java/lang/Class.c
src/share/native/java/lang/Class.c
+2
-2
test/java/security/Signature/SignatureGetAlgorithm.java
test/java/security/Signature/SignatureGetAlgorithm.java
+112
-0
未找到文件。
src/share/classes/java/lang/Class.java
浏览文件 @
fff405fa
...
...
@@ -708,8 +708,9 @@ public final class Class<T> implements java.io.Serializable,
*/
@SuppressWarnings
(
"unchecked"
)
public
TypeVariable
<
Class
<
T
>>[]
getTypeParameters
()
{
if
(
getGenericSignature
()
!=
null
)
return
(
TypeVariable
<
Class
<
T
>>[])
getGenericInfo
().
getTypeParameters
();
ClassRepository
info
=
getGenericInfo
();
if
(
info
!=
null
)
return
(
TypeVariable
<
Class
<
T
>>[])
info
.
getTypeParameters
();
else
return
(
TypeVariable
<
Class
<
T
>>[])
new
TypeVariable
<?>[
0
];
}
...
...
@@ -759,15 +760,19 @@ public final class Class<T> implements java.io.Serializable,
* @since 1.5
*/
public
Type
getGenericSuperclass
()
{
if
(
getGenericSignature
()
!=
null
)
{
// Historical irregularity:
// Generic signature marks interfaces with superclass = Object
// but this API returns null for interfaces
if
(
isInterface
())
return
null
;
return
getGenericInfo
().
getSuperclass
();
}
else
ClassRepository
info
=
getGenericInfo
();
if
(
info
==
null
)
{
return
getSuperclass
();
}
// Historical irregularity:
// Generic signature marks interfaces with superclass = Object
// but this API returns null for interfaces
if
(
isInterface
())
{
return
null
;
}
return
info
.
getSuperclass
();
}
/**
...
...
@@ -830,7 +835,23 @@ public final class Class<T> implements java.io.Serializable,
*
* @return an array of interfaces implemented by this class.
*/
public
native
Class
<?>[]
getInterfaces
();
public
Class
<?>[]
getInterfaces
()
{
ReflectionData
<
T
>
rd
=
reflectionData
();
if
(
rd
==
null
)
{
// no cloning required
return
getInterfaces0
();
}
else
{
Class
<?>[]
interfaces
=
rd
.
interfaces
;
if
(
interfaces
==
null
)
{
interfaces
=
getInterfaces0
();
rd
.
interfaces
=
interfaces
;
}
// defensively copy before handing over to user code
return
interfaces
.
clone
();
}
}
private
native
Class
<?>[]
getInterfaces0
();
/**
* Returns the {@code Type}s representing the interfaces
...
...
@@ -882,10 +903,8 @@ public final class Class<T> implements java.io.Serializable,
* @since 1.5
*/
public
Type
[]
getGenericInterfaces
()
{
if
(
getGenericSignature
()
!=
null
)
return
getGenericInfo
().
getSuperInterfaces
();
else
return
getInterfaces
();
ClassRepository
info
=
getGenericInfo
();
return
(
info
==
null
)
?
getInterfaces
()
:
info
.
getSuperInterfaces
();
}
...
...
@@ -2396,6 +2415,8 @@ public final class Class<T> implements java.io.Serializable,
// Intermediate results for getFields and getMethods
volatile
Field
[]
declaredPublicFields
;
volatile
Method
[]
declaredPublicMethods
;
volatile
Class
<?>[]
interfaces
;
// Value of classRedefinedCount when we created this ReflectionData instance
final
int
redefinedCount
;
...
...
@@ -2471,10 +2492,10 @@ public final class Class<T> implements java.io.Serializable,
}
// Generic signature handling
private
native
String
getGenericSignature
();
private
native
String
getGenericSignature
0
();
// Generic info repository; lazily initialized
private
transient
ClassRepository
genericInfo
;
private
volatile
transient
ClassRepository
genericInfo
;
// accessor for factory
private
GenericsFactory
getFactory
()
{
...
...
@@ -2482,15 +2503,20 @@ public final class Class<T> implements java.io.Serializable,
return
CoreReflectionFactory
.
make
(
this
,
ClassScope
.
make
(
this
));
}
// accessor for generic info repository
// accessor for generic info repository;
// generic info is lazily initialized
private
ClassRepository
getGenericInfo
()
{
// lazily initialize repository if necessary
ClassRepository
genericInfo
=
this
.
genericInfo
;
if
(
genericInfo
==
null
)
{
// create and cache generic info repository
genericInfo
=
ClassRepository
.
make
(
getGenericSignature
(),
getFactory
());
String
signature
=
getGenericSignature0
();
if
(
signature
==
null
)
{
genericInfo
=
ClassRepository
.
NONE
;
}
else
{
genericInfo
=
ClassRepository
.
make
(
signature
,
getFactory
());
}
this
.
genericInfo
=
genericInfo
;
}
return
genericInfo
;
//return cached repository
return
(
genericInfo
!=
ClassRepository
.
NONE
)
?
genericInfo
:
null
;
}
// Annotations handling
...
...
src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
浏览文件 @
fff405fa
...
...
@@ -24,14 +24,11 @@
*/
package
java.lang.invoke
;
import
java.io.Serializable
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
sun.invoke.util.Wrapper
;
import
static
sun
.
invoke
.
util
.
Wrapper
.*;
import
static
sun
.
invoke
.
util
.
Wrapper
.
forPrimitiveType
;
import
static
sun
.
invoke
.
util
.
Wrapper
.
forWrapperType
;
import
static
sun
.
invoke
.
util
.
Wrapper
.
isWrapperType
;
/**
* Abstract implementation of a lambda metafactory which provides parameter unrolling and input validation.
...
...
@@ -67,34 +64,52 @@ import static sun.invoke.util.Wrapper.*;
final
MethodType
instantiatedMethodType
;
// Instantiated erased functional interface method type "(Integer)Object"
final
boolean
isSerializable
;
// Should the returned instance be serializable
final
Class
<?>[]
markerInterfaces
;
// Additional marker interfaces to be implemented
final
MethodType
[]
additionalBridges
;
// Signatures of additional methods to bridge
/**
* Meta-factory constructor.
*
* @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
* of the caller.
* @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the
* expected static type of the returned lambda object, and the static types of the captured
* arguments for the lambda. In the event that the implementation method is an instance method,
* the first argument in the invocation signature will correspond to the receiver.
* @param samMethod The primary method in the functional interface to which the lambda or method reference is
* being converted, represented as a method handle.
* @param implMethod The implementation method which should be called (with suitable adaptation of argument
* types, return types, and adjustment for captured arguments) when methods of the resulting
* functional interface instance are invoked.
* @param instantiatedMethodType The signature of the primary functional interface method after type variables
* are substituted with their instantiation from the capture site
* @param caller Stacked automatically by VM; represents a lookup context
* with the accessibility privileges of the caller.
* @param invokedType Stacked automatically by VM; the signature of the
* invoked method, which includes the expected static
* type of the returned lambda object, and the static
* types of the captured arguments for the lambda. In
* the event that the implementation method is an
* instance method, the first argument in the invocation
* signature will correspond to the receiver.
* @param samMethod The primary method in the functional interface to which
* the lambda or method reference is being converted,
* represented as a method handle.
* @param implMethod The implementation method which should be called
* (with suitable adaptation of argument types, return
* types, and adjustment for captured arguments) when
* methods of the resulting functional interface instance
* are invoked.
* @param instantiatedMethodType The signature of the primary functional
* interface method after type variables are
* substituted with their instantiation from
* the capture site
* @param isSerializable Should the lambda be made serializable? If set,
* either the target type or one of the additional SAM
* types must extend {@code Serializable}.
* @param markerInterfaces Additional interfaces which the lambda object
* should implement.
* @param additionalBridges Method types for additional signatures to be
* bridged to the implementation method
* @throws ReflectiveOperationException
* @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
* @throws LambdaConversionException If any of the meta-factory protocol
* invariants are violated
*/
AbstractValidatingLambdaMetafactory
(
MethodHandles
.
Lookup
caller
,
MethodType
invokedType
,
MethodHandle
samMethod
,
MethodHandle
implMethod
,
MethodType
instantiatedMethodType
,
int
flags
,
Class
<?>[]
markerInterfaces
)
boolean
isSerializable
,
Class
<?>[]
markerInterfaces
,
MethodType
[]
additionalBridges
)
throws
ReflectiveOperationException
,
LambdaConversionException
{
this
.
targetClass
=
caller
.
lookupClass
();
this
.
invokedType
=
invokedType
;
...
...
@@ -118,32 +133,22 @@ import static sun.invoke.util.Wrapper.*;
implKind
==
MethodHandleInfo
.
REF_invokeInterface
;
this
.
implDefiningClass
=
implInfo
.
getDeclaringClass
();
this
.
implMethodType
=
implInfo
.
getMethodType
();
this
.
instantiatedMethodType
=
instantiatedMethodType
;
this
.
isSerializable
=
isSerializable
;
this
.
markerInterfaces
=
markerInterfaces
;
this
.
additionalBridges
=
additionalBridges
;
if
(!
samClass
.
isInterface
())
{
throw
new
LambdaConversionException
(
String
.
format
(
"Functional interface %s is not an interface"
,
samClass
.
getName
()));
"Functional interface %s is not an interface"
,
samClass
.
getName
()));
}
boolean
foundSerializableSupertype
=
Serializable
.
class
.
isAssignableFrom
(
samBase
);
for
(
Class
<?>
c
:
markerInterfaces
)
{
if
(!
c
.
isInterface
())
{
throw
new
LambdaConversionException
(
String
.
format
(
"Marker interface %s is not an interface"
,
c
.
getName
()));
"Marker interface %s is not an interface"
,
c
.
getName
()));
}
foundSerializableSupertype
|=
Serializable
.
class
.
isAssignableFrom
(
c
);
}
this
.
isSerializable
=
((
flags
&
LambdaMetafactory
.
FLAG_SERIALIZABLE
)
!=
0
)
||
foundSerializableSupertype
;
if
(
isSerializable
&&
!
foundSerializableSupertype
)
{
markerInterfaces
=
Arrays
.
copyOf
(
markerInterfaces
,
markerInterfaces
.
length
+
1
);
markerInterfaces
[
markerInterfaces
.
length
-
1
]
=
Serializable
.
class
;
}
this
.
markerInterfaces
=
markerInterfaces
;
}
/**
...
...
@@ -265,9 +270,9 @@ import static sun.invoke.util.Wrapper.*;
}
/**
* Check type adaptability
* @param fromType
* @param toType
* Check type adaptability
for parameter types.
* @param fromType
Type to convert from
* @param toType
Type to convert to
* @param strict If true, do strict checks, else allow that fromType may be parameterized
* @return True if 'fromType' can be passed to an argument of 'toType'
*/
...
...
@@ -299,15 +304,14 @@ import static sun.invoke.util.Wrapper.*;
}
}
else
{
// both are reference types: fromType should be a superclass of toType.
return
strict
?
toType
.
isAssignableFrom
(
fromType
)
:
true
;
return
!
strict
||
toType
.
isAssignableFrom
(
fromType
)
;
}
}
}
/**
* Check type adaptability for return types -- special handling of void type) and parameterized fromType
* @param fromType
* @param toType
* Check type adaptability for return types -- special handling of void type)
* and parameterized fromType
* @return True if 'fromType' can be converted to 'toType'
*/
private
boolean
isAdaptableToAsReturn
(
Class
<?>
fromType
,
Class
<?>
toType
)
{
...
...
@@ -338,89 +342,4 @@ import static sun.invoke.util.Wrapper.*;
}
***********************/
/**
* Find the functional interface method and corresponding abstract methods
* which should be bridged. The functional interface method and those to be
* bridged will have the same name and number of parameters. Check for
* matching default methods (non-abstract), the VM will create bridges for
* default methods; We don't have enough readily available type information
* to distinguish between where the functional interface method should be
* bridged and where the default method should be bridged; This situation is
* flagged.
*/
class
MethodAnalyzer
{
private
final
Method
[]
methods
=
samBase
.
getMethods
();
private
Method
samMethod
=
null
;
private
final
List
<
Method
>
methodsToBridge
=
new
ArrayList
<>(
methods
.
length
);
private
boolean
conflictFoundBetweenDefaultAndBridge
=
false
;
MethodAnalyzer
()
{
String
samMethodName
=
samInfo
.
getName
();
Class
<?>[]
samParamTypes
=
samMethodType
.
parameterArray
();
int
samParamLength
=
samParamTypes
.
length
;
Class
<?>
samReturnType
=
samMethodType
.
returnType
();
Class
<?>
objectClass
=
Object
.
class
;
List
<
Method
>
defaultMethods
=
new
ArrayList
<>(
methods
.
length
);
for
(
Method
m
:
methods
)
{
if
(
m
.
getName
().
equals
(
samMethodName
)
&&
m
.
getDeclaringClass
()
!=
objectClass
)
{
Class
<?>[]
mParamTypes
=
m
.
getParameterTypes
();
if
(
mParamTypes
.
length
==
samParamLength
)
{
// Method matches name and parameter length -- and is not Object
if
(
Modifier
.
isAbstract
(
m
.
getModifiers
()))
{
// Method is abstract
if
(
m
.
getReturnType
().
equals
(
samReturnType
)
&&
Arrays
.
equals
(
mParamTypes
,
samParamTypes
))
{
// Exact match, this is the SAM method signature
samMethod
=
m
;
}
else
if
(!
hasMatchingBridgeSignature
(
m
))
{
// Record bridges, exclude methods with duplicate signatures
methodsToBridge
.
add
(
m
);
}
}
else
{
// Record default methods for conflict testing
defaultMethods
.
add
(
m
);
}
}
}
}
for
(
Method
dm
:
defaultMethods
)
{
if
(
hasMatchingBridgeSignature
(
dm
))
{
conflictFoundBetweenDefaultAndBridge
=
true
;
break
;
}
}
}
Method
getSamMethod
()
{
return
samMethod
;
}
List
<
Method
>
getMethodsToBridge
()
{
return
methodsToBridge
;
}
boolean
conflictFoundBetweenDefaultAndBridge
()
{
return
conflictFoundBetweenDefaultAndBridge
;
}
/**
* Search the list of previously found bridge methods to determine if there is a method with the same signature
* (return and parameter types) as the specified method.
*
* @param m The method to match
* @return True if the method was found, False otherwise
*/
private
boolean
hasMatchingBridgeSignature
(
Method
m
)
{
Class
<?>[]
ptypes
=
m
.
getParameterTypes
();
Class
<?>
rtype
=
m
.
getReturnType
();
for
(
Method
md
:
methodsToBridge
)
{
if
(
md
.
getReturnType
().
equals
(
rtype
)
&&
Arrays
.
equals
(
ptypes
,
md
.
getParameterTypes
()))
{
return
true
;
}
}
return
false
;
}
}
}
src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
浏览文件 @
fff405fa
...
...
@@ -25,15 +25,16 @@
package
java.lang.invoke
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Method
;
import
java.security.ProtectionDomain
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
jdk.internal.org.objectweb.asm.*
;
import
static
jdk
.
internal
.
org
.
objectweb
.
asm
.
Opcodes
.*;
import
sun.misc.Unsafe
;
import
java.lang.reflect.Constructor
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
import
java.security.ProtectionDomain
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
static
jdk
.
internal
.
org
.
objectweb
.
asm
.
Opcodes
.*;
/**
* Lambda metafactory implementation which dynamically creates an inner-class-like class per lambda callsite.
...
...
@@ -41,6 +42,8 @@ import java.security.PrivilegedAction;
* @see LambdaMetafactory
*/
/* package */
final
class
InnerClassLambdaMetafactory
extends
AbstractValidatingLambdaMetafactory
{
private
static
final
Unsafe
UNSAFE
=
Unsafe
.
getUnsafe
();
private
static
final
int
CLASSFILE_VERSION
=
51
;
private
static
final
String
METHOD_DESCRIPTOR_VOID
=
Type
.
getMethodDescriptor
(
Type
.
VOID_TYPE
);
private
static
final
String
NAME_MAGIC_ACCESSOR_IMPL
=
"java/lang/invoke/MagicLambdaImpl"
;
...
...
@@ -77,36 +80,51 @@ import java.security.PrivilegedAction;
private
final
Type
[]
instantiatedArgumentTypes
;
// ASM types for the functional interface arguments
/**
* General meta-factory constructor, standard cases and allowing for uncommon options such as serialization.
* General meta-factory constructor, supporting both standard cases and
* allowing for uncommon options such as serialization or bridging.
*
* @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
* of the caller.
* @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the
* expected static type of the returned lambda object, and the static types of the captured
* arguments for the lambda. In the event that the implementation method is an instance method,
* the first argument in the invocation signature will correspond to the receiver.
* @param samMethod The primary method in the functional interface to which the lambda or method reference is
* being converted, represented as a method handle.
* @param implMethod The implementation method which should be called (with suitable adaptation of argument
* types, return types, and adjustment for captured arguments) when methods of the resulting
* functional interface instance are invoked.
* @param instantiatedMethodType The signature of the primary functional interface method after type variables
* are substituted with their instantiation from the capture site
* @param flags A bitmask containing flags that may influence the translation of this lambda expression. Defined
* fields include FLAG_SERIALIZABLE.
* @param markerInterfaces Additional interfaces which the lambda object should implement.
* @param caller Stacked automatically by VM; represents a lookup context
* with the accessibility privileges of the caller.
* @param invokedType Stacked automatically by VM; the signature of the
* invoked method, which includes the expected static
* type of the returned lambda object, and the static
* types of the captured arguments for the lambda. In
* the event that the implementation method is an
* instance method, the first argument in the invocation
* signature will correspond to the receiver.
* @param samMethod The primary method in the functional interface to which
* the lambda or method reference is being converted,
* represented as a method handle.
* @param implMethod The implementation method which should be called (with
* suitable adaptation of argument types, return types,
* and adjustment for captured arguments) when methods of
* the resulting functional interface instance are invoked.
* @param instantiatedMethodType The signature of the primary functional
* interface method after type variables are
* substituted with their instantiation from
* the capture site
* @param isSerializable Should the lambda be made serializable? If set,
* either the target type or one of the additional SAM
* types must extend {@code Serializable}.
* @param markerInterfaces Additional interfaces which the lambda object
* should implement.
* @param additionalBridges Method types for additional signatures to be
* bridged to the implementation method
* @throws ReflectiveOperationException
* @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
* @throws LambdaConversionException If any of the meta-factory protocol
* invariants are violated
*/
public
InnerClassLambdaMetafactory
(
MethodHandles
.
Lookup
caller
,
MethodType
invokedType
,
MethodHandle
samMethod
,
MethodHandle
implMethod
,
MethodType
instantiatedMethodType
,
int
flags
,
Class
<?>[]
markerInterfaces
)
boolean
isSerializable
,
Class
<?>[]
markerInterfaces
,
MethodType
[]
additionalBridges
)
throws
ReflectiveOperationException
,
LambdaConversionException
{
super
(
caller
,
invokedType
,
samMethod
,
implMethod
,
instantiatedMethodType
,
flags
,
markerInterfaces
);
super
(
caller
,
invokedType
,
samMethod
,
implMethod
,
instantiatedMethodType
,
isSerializable
,
markerInterfaces
,
additionalBridges
);
implMethodClassName
=
implDefiningClass
.
getName
().
replace
(
'.'
,
'/'
);
implMethodName
=
implInfo
.
getName
();
implMethodDesc
=
implMethodType
.
toMethodDescriptorString
();
...
...
@@ -134,7 +152,8 @@ import java.security.PrivilegedAction;
* @return a CallSite, which, when invoked, will return an instance of the
* functional interface
* @throws ReflectiveOperationException
* @throws LambdaConversionException If properly formed functional interface is not found
* @throws LambdaConversionException If properly formed functional interface
* is not found
*/
@Override
CallSite
buildCallSite
()
throws
ReflectiveOperationException
,
LambdaConversionException
{
...
...
@@ -174,8 +193,16 @@ import java.security.PrivilegedAction;
* Generate a class file which implements the functional
* interface, define and return the class.
*
* @implNote The class that is generated does not include signature
* information for exceptions that may be present on the SAM method.
* This is to reduce classfile size, and is harmless as checked exceptions
* are erased anyway, no one will ever compile against this classfile,
* and we make no guarantees about the reflective properties of lambda
* objects.
*
* @return a Class which implements the functional interface
* @throws LambdaConversionException If properly formed functional interface is not found
* @throws LambdaConversionException If properly formed functional interface
* is not found
*/
private
Class
<?>
spinInnerClass
()
throws
LambdaConversionException
{
String
samName
=
samBase
.
getName
().
replace
(
'.'
,
'/'
);
...
...
@@ -197,28 +224,22 @@ import java.security.PrivilegedAction;
generateConstructor
();
MethodAnalyzer
ma
=
new
MethodAnalyzer
();
// Forward the SAM method
if
(
ma
.
getSamMethod
()
==
null
)
{
throw
new
LambdaConversionException
(
String
.
format
(
"Functional interface method not found: %s"
,
samMethodType
));
}
else
{
generateForwardingMethod
(
ma
.
getSamMethod
(),
false
);
}
String
methodDescriptor
=
samMethodType
.
toMethodDescriptorString
();
MethodVisitor
mv
=
cw
.
visitMethod
(
ACC_PUBLIC
,
samInfo
.
getName
(),
methodDescriptor
,
null
,
null
);
new
ForwardingMethodGenerator
(
mv
).
generate
(
methodDescriptor
);
// Forward the bridges
// @@@ The commented-out code is temporary, pending the VM's ability to bridge all methods on request
// @@@ Once the VM can do fail-over, uncomment the !ma.wasDefaultMethodFound() test, and emit the appropriate
// @@@ classfile attribute to request custom bridging. See 8002092.
if
(!
ma
.
getMethodsToBridge
().
isEmpty
()
/* && !ma.conflictFoundBetweenDefaultAndBridge() */
)
{
for
(
Method
m
:
ma
.
getMethodsToBridge
())
{
generateForwardingMethod
(
m
,
true
);
if
(
additionalBridges
!=
null
)
{
for
(
MethodType
mt
:
additionalBridges
)
{
methodDescriptor
=
mt
.
toMethodDescriptorString
();
mv
=
cw
.
visitMethod
(
ACC_PUBLIC
|
ACC_BRIDGE
,
samInfo
.
getName
(),
methodDescriptor
,
null
,
null
);
new
ForwardingMethodGenerator
(
mv
).
generate
(
methodDescriptor
);
}
}
if
(
isSerializable
)
{
if
(
isSerializable
)
generateWriteReplace
();
}
cw
.
visitEnd
();
...
...
@@ -247,8 +268,8 @@ import java.security.PrivilegedAction;
}
);
return
(
Class
<?>)
Unsafe
.
getUnsafe
()
.
defineClass
(
lambdaClassName
,
classBytes
,
0
,
classBytes
.
length
,
loader
,
pd
);
return
UNSAFE
.
defineClass
(
lambdaClassName
,
classBytes
,
0
,
classBytes
.
length
,
loader
,
pd
);
}
/**
...
...
@@ -265,7 +286,8 @@ import java.security.PrivilegedAction;
ctor
.
visitVarInsn
(
ALOAD
,
0
);
ctor
.
visitVarInsn
(
argTypes
[
i
].
getOpcode
(
ILOAD
),
lvIndex
+
1
);
lvIndex
+=
argTypes
[
i
].
getSize
();
ctor
.
visitFieldInsn
(
PUTFIELD
,
lambdaClassName
,
argNames
[
i
],
argTypes
[
i
].
getDescriptor
());
ctor
.
visitFieldInsn
(
PUTFIELD
,
lambdaClassName
,
argNames
[
i
],
argTypes
[
i
].
getDescriptor
());
}
ctor
.
visitInsn
(
RETURN
);
ctor
.
visitMaxs
(-
1
,
-
1
);
// Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
...
...
@@ -283,7 +305,7 @@ import java.security.PrivilegedAction;
mv
.
visitCode
();
mv
.
visitTypeInsn
(
NEW
,
NAME_SERIALIZED_LAMBDA
);
mv
.
visitInsn
(
DUP
);
;
mv
.
visitInsn
(
DUP
);
mv
.
visitLdcInsn
(
Type
.
getType
(
targetClass
));
mv
.
visitLdcInsn
(
samInfo
.
getReferenceKind
());
mv
.
visitLdcInsn
(
invokedType
.
returnType
().
getName
().
replace
(
'.'
,
'/'
));
...
...
@@ -312,24 +334,6 @@ import java.security.PrivilegedAction;
mv
.
visitEnd
();
}
/**
* Generate a method which calls the lambda implementation method,
* converting arguments, as needed.
* @param m The method whose signature should be generated
* @param isBridge True if this methods should be flagged as a bridge
*/
private
void
generateForwardingMethod
(
Method
m
,
boolean
isBridge
)
{
Class
<?>[]
exceptionTypes
=
m
.
getExceptionTypes
();
String
[]
exceptionNames
=
new
String
[
exceptionTypes
.
length
];
for
(
int
i
=
0
;
i
<
exceptionTypes
.
length
;
i
++)
{
exceptionNames
[
i
]
=
exceptionTypes
[
i
].
getName
().
replace
(
'.'
,
'/'
);
}
String
methodDescriptor
=
Type
.
getMethodDescriptor
(
m
);
int
access
=
isBridge
?
ACC_PUBLIC
|
ACC_BRIDGE
:
ACC_PUBLIC
;
MethodVisitor
mv
=
cw
.
visitMethod
(
access
,
m
.
getName
(),
methodDescriptor
,
null
,
exceptionNames
);
new
ForwardingMethodGenerator
(
mv
).
generate
(
m
);
}
/**
* This class generates a method body which calls the lambda implementation
* method, converting arguments, as needed.
...
...
@@ -340,26 +344,26 @@ import java.security.PrivilegedAction;
super
(
mv
);
}
void
generate
(
Method
m
)
throws
InternalError
{
void
generate
(
String
methodDescriptor
)
{
visitCode
();
if
(
implKind
==
MethodHandleInfo
.
REF_newInvokeSpecial
)
{
visitTypeInsn
(
NEW
,
implMethodClassName
);
visitInsn
(
DUP
);
;
visitInsn
(
DUP
);
}
for
(
int
i
=
0
;
i
<
argTypes
.
length
;
i
++)
{
visitVarInsn
(
ALOAD
,
0
);
visitFieldInsn
(
GETFIELD
,
lambdaClassName
,
argNames
[
i
],
argTypes
[
i
].
getDescriptor
());
}
convertArgumentTypes
(
Type
.
getArgumentTypes
(
m
));
convertArgumentTypes
(
Type
.
getArgumentTypes
(
m
ethodDescriptor
));
// Invoke the method we want to forward to
visitMethodInsn
(
invocationOpcode
(),
implMethodClassName
,
implMethodName
,
implMethodDesc
);
// Convert the return value (if any) and return it
// Note: if adapting from non-void to void, the 'return' instruction will pop the unneeded result
Type
samReturnType
=
Type
.
getReturnType
(
m
);
Type
samReturnType
=
Type
.
getReturnType
(
m
ethodDescriptor
);
convertType
(
implMethodReturnType
,
samReturnType
,
samReturnType
);
visitInsn
(
samReturnType
.
getOpcode
(
Opcodes
.
IRETURN
));
...
...
src/share/classes/java/lang/invoke/LambdaMetafactory.java
浏览文件 @
fff405fa
...
...
@@ -25,6 +25,9 @@
package
java.lang.invoke
;
import
java.io.Serializable
;
import
java.util.Arrays
;
/**
* <p>Bootstrap methods for converting lambda expressions and method references to functional interface objects.</p>
*
...
...
@@ -44,16 +47,11 @@ package java.lang.invoke;
*
* <p>When parameterized types are used, the instantiated type of the functional interface method may be different
* from that in the functional interface. For example, consider
*
<code>interface I<T> { int m(T x); }</code>
if this functional interface type is used in a lambda
*
<code>I<Byte> v = ...</code>
, we need both the actual functional interface method which has the signature
*
<code>(Object)int</code>
and the erased instantiated type of the functional interface method (or simply
*
{@code interface I<T> { int m(T x); }}
if this functional interface type is used in a lambda
*
{@code I<Byte>; v = ...}
, we need both the actual functional interface method which has the signature
*
{@code (Object)int}
and the erased instantiated type of the functional interface method (or simply
* <I>instantiated method type</I>), which has signature
* <code>(Byte)int</code>.
*
* <p>While functional interfaces only have a single abstract method from the language perspective (concrete
* methods in Object are and default methods may be present), at the bytecode level they may actually have multiple
* methods because of the need for bridge methods. Invoking any of these methods on the lambda object will result
* in invoking the implementation method.
* {@code (Byte)int}.
*
* <p>The argument list of the implementation method and the argument list of the functional interface method(s)
* may differ in several ways. The implementation methods may have additional arguments to accommodate arguments
...
...
@@ -144,38 +142,59 @@ package java.lang.invoke;
*/
public
class
LambdaMetafactory
{
/** Flag for alternate metafactories indicating the lambda object is must to be serializable */
/** Flag for alternate metafactories indicating the lambda object is
* must to be serializable */
public
static
final
int
FLAG_SERIALIZABLE
=
1
<<
0
;
/**
* Flag for alternate metafactories indicating the lambda object implements other marker interfaces
* Flag for alternate metafactories indicating the lambda object implements
* other marker interfaces
* besides Serializable
*/
public
static
final
int
FLAG_MARKERS
=
1
<<
1
;
/**
* Flag for alternate metafactories indicating the lambda object requires
* additional bridge methods
*/
public
static
final
int
FLAG_BRIDGES
=
1
<<
2
;
private
static
final
Class
<?>[]
EMPTY_CLASS_ARRAY
=
new
Class
<?>[
0
];
private
static
final
MethodType
[]
EMPTY_MT_ARRAY
=
new
MethodType
[
0
];
/**
* Standard meta-factory for conversion of lambda expressions or method references to functional interfaces.
/**
* Standard meta-factory for conversion of lambda expressions or method
* references to functional interfaces.
*
* @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
* of the caller.
* @param invokedName Stacked automatically by VM; the name of the invoked method as it appears at the call site.
* @param caller Stacked automatically by VM; represents a lookup context
* with the accessibility privileges of the caller.
* @param invokedName Stacked automatically by VM; the name of the invoked
* method as it appears at the call site.
* Currently unused.
* @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the
* expected static type of the returned lambda object, and the static types of the captured
* arguments for the lambda. In the event that the implementation method is an instance method,
* the first argument in the invocation signature will correspond to the receiver.
* @param samMethod The primary method in the functional interface to which the lambda or method reference is
* being converted, represented as a method handle.
* @param implMethod The implementation method which should be called (with suitable adaptation of argument
* types, return types, and adjustment for captured arguments) when methods of the resulting
* functional interface instance are invoked.
* @param instantiatedMethodType The signature of the primary functional interface method after type variables
* are substituted with their instantiation from the capture site
* @return a CallSite, which, when invoked, will return an instance of the functional interface
* @param invokedType Stacked automatically by VM; the signature of the
* invoked method, which includes the expected static
* type of the returned lambda object, and the static
* types of the captured arguments for the lambda.
* In the event that the implementation method is an
* instance method, the first argument in the invocation
* signature will correspond to the receiver.
* @param samMethod The primary method in the functional interface to which
* the lambda or method reference is being converted,
* represented as a method handle.
* @param implMethod The implementation method which should be called
* (with suitable adaptation of argument types, return
* types, and adjustment for captured arguments) when
* methods of the resulting functional interface instance
* are invoked.
* @param instantiatedMethodType The signature of the primary functional
* interface method after type variables
* are substituted with their instantiation
* from the capture site
* @return a CallSite, which, when invoked, will return an instance of the
* functional interface
* @throws ReflectiveOperationException
* @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
* @throws LambdaConversionException If any of the meta-factory protocol
* invariants are violated
*/
public
static
CallSite
metaFactory
(
MethodHandles
.
Lookup
caller
,
String
invokedName
,
...
...
@@ -185,15 +204,17 @@ public class LambdaMetafactory {
MethodType
instantiatedMethodType
)
throws
ReflectiveOperationException
,
LambdaConversionException
{
AbstractValidatingLambdaMetafactory
mf
;
mf
=
new
InnerClassLambdaMetafactory
(
caller
,
invokedType
,
samMethod
,
implMethod
,
instantiatedMethodType
,
0
,
EMPTY_CLASS_ARRAY
);
mf
=
new
InnerClassLambdaMetafactory
(
caller
,
invokedType
,
samMethod
,
implMethod
,
instantiatedMethodType
,
false
,
EMPTY_CLASS_ARRAY
,
EMPTY_MT_ARRAY
);
mf
.
validateMetafactoryArgs
();
return
mf
.
buildCallSite
();
}
/**
* Alternate meta-factory for conversion of lambda expressions or method references to functional interfaces,
* which supports serialization and other uncommon options.
* Alternate meta-factory for conversion of lambda expressions or method
* references to functional interfaces, which supports serialization and
* other uncommon options.
*
* The declared argument list for this method is:
*
...
...
@@ -213,21 +234,28 @@ public class LambdaMetafactory {
* int flags,
* int markerInterfaceCount, // IF flags has MARKERS set
* Class... markerInterfaces // IF flags has MARKERS set
* int bridgeCount, // IF flags has BRIDGES set
* MethodType... bridges // IF flags has BRIDGES set
* )
*
*
* @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
* of the caller.
* @param invokedName Stacked automatically by VM; the name of the invoked method as it appears at the call site.
* Currently unused.
* @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes thefu
* expected static type of the returned lambda object, and the static types of the captured
* arguments for the lambda. In the event that the implementation method is an instance method,
* the first argument in the invocation signature will correspond to the receiver.
* @param args argument to pass, flags, marker interface count, and marker interfaces as described above
* @return a CallSite, which, when invoked, will return an instance of the functional interface
* @param caller Stacked automatically by VM; represents a lookup context
* with the accessibility privileges of the caller.
* @param invokedName Stacked automatically by VM; the name of the invoked
* method as it appears at the call site. Currently unused.
* @param invokedType Stacked automatically by VM; the signature of the
* invoked method, which includes the expected static
* type of the returned lambda object, and the static
* types of the captured arguments for the lambda.
* In the event that the implementation method is an
* instance method, the first argument in the invocation
* signature will correspond to the receiver.
* @param args flags and optional arguments, as described above
* @return a CallSite, which, when invoked, will return an instance of the
* functional interface
* @throws ReflectiveOperationException
* @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
* @throws LambdaConversionException If any of the meta-factory protocol
* invariants are violated
*/
public
static
CallSite
altMetaFactory
(
MethodHandles
.
Lookup
caller
,
String
invokedName
,
...
...
@@ -239,6 +267,7 @@ public class LambdaMetafactory {
MethodType
instantiatedMethodType
=
(
MethodType
)
args
[
2
];
int
flags
=
(
Integer
)
args
[
3
];
Class
<?>[]
markerInterfaces
;
MethodType
[]
bridges
;
int
argIndex
=
4
;
if
((
flags
&
FLAG_MARKERS
)
!=
0
)
{
int
markerCount
=
(
Integer
)
args
[
argIndex
++];
...
...
@@ -248,9 +277,30 @@ public class LambdaMetafactory {
}
else
markerInterfaces
=
EMPTY_CLASS_ARRAY
;
AbstractValidatingLambdaMetafactory
mf
;
mf
=
new
InnerClassLambdaMetafactory
(
caller
,
invokedType
,
samMethod
,
implMethod
,
instantiatedMethodType
,
flags
,
markerInterfaces
);
if
((
flags
&
FLAG_BRIDGES
)
!=
0
)
{
int
bridgeCount
=
(
Integer
)
args
[
argIndex
++];
bridges
=
new
MethodType
[
bridgeCount
];
System
.
arraycopy
(
args
,
argIndex
,
bridges
,
0
,
bridgeCount
);
argIndex
+=
bridgeCount
;
}
else
bridges
=
EMPTY_MT_ARRAY
;
boolean
foundSerializableSupertype
=
Serializable
.
class
.
isAssignableFrom
(
invokedType
.
returnType
());
for
(
Class
<?>
c
:
markerInterfaces
)
foundSerializableSupertype
|=
Serializable
.
class
.
isAssignableFrom
(
c
);
boolean
isSerializable
=
((
flags
&
LambdaMetafactory
.
FLAG_SERIALIZABLE
)
!=
0
)
||
foundSerializableSupertype
;
if
(
isSerializable
&&
!
foundSerializableSupertype
)
{
markerInterfaces
=
Arrays
.
copyOf
(
markerInterfaces
,
markerInterfaces
.
length
+
1
);
markerInterfaces
[
markerInterfaces
.
length
-
1
]
=
Serializable
.
class
;
}
AbstractValidatingLambdaMetafactory
mf
=
new
InnerClassLambdaMetafactory
(
caller
,
invokedType
,
samMethod
,
implMethod
,
instantiatedMethodType
,
isSerializable
,
markerInterfaces
,
bridges
);
mf
.
validateMetafactoryArgs
();
return
mf
.
buildCallSite
();
}
...
...
src/share/classes/java/lang/invoke/MethodType.java
浏览文件 @
fff405fa
...
...
@@ -27,10 +27,13 @@ package java.lang.invoke;
import
sun.invoke.util.Wrapper
;
import
java.lang.ref.WeakReference
;
import
java.lang.ref.Reference
;
import
java.lang.ref.ReferenceQueue
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.concurrent.ConcurrentMap
;
import
java.util.concurrent.ConcurrentHashMap
;
import
sun.invoke.util.BytecodeDescriptor
;
import
static
java
.
lang
.
invoke
.
MethodHandleStatics
.*;
import
sun.invoke.util.VerifyType
;
...
...
@@ -171,7 +174,7 @@ class MethodType implements java.io.Serializable {
return
new
IndexOutOfBoundsException
(
num
.
toString
());
}
static
final
WeakInternSet
internTable
=
new
WeakInternSet
();
static
final
ConcurrentWeakInternSet
<
MethodType
>
internTable
=
new
ConcurrentWeakInternSet
<>
();
static
final
Class
<?>[]
NO_PTYPES
=
{};
...
...
@@ -1013,267 +1016,104 @@ s.writeObject(this.parameterArray());
}
/**
* Weak intern set based on implementation of the <tt>HashSet</tt> and
* <tt>WeakHashMap</tt>, with <em>weak values</em>. Note: <tt>null</tt>
* values will yield <tt>NullPointerException</tt>
* Refer to implementation of WeakInternSet for details.
* Simple implementation of weak concurrent intern set.
*
* @see java.util.HashMap
* @see java.util.HashSet
* @see java.util.WeakHashMap
* @see java.lang.ref.WeakReference
* @param <T> interned type
*/
private
static
class
WeakInternSet
{
// The default initial capacity -- MUST be a power of two.
private
static
final
int
DEFAULT_INITIAL_CAPACITY
=
16
;
private
static
class
ConcurrentWeakInternSet
<
T
>
{
// The maximum capacity, used if a higher value is implicitly specified
// by either of the constructors with arguments.
// MUST be a power of two <= 1<<30.
private
static
final
int
MAXIMUM_CAPACITY
=
1
<<
30
;
private
final
ConcurrentMap
<
WeakEntry
<
T
>,
WeakEntry
<
T
>>
map
;
private
final
ReferenceQueue
<
T
>
stale
;
// The load factor used when none specified in constructor.
private
static
final
float
DEFAULT_LOAD_FACTOR
=
0.75f
;
// The table, resized as necessary. Length MUST Always be a power of two.
private
Entry
[]
table
;
// The number of entries contained in this set.
private
int
size
;
// The next size value at which to resize (capacity * load factor).
private
int
threshold
;
// The load factor for the hash table.
private
final
float
loadFactor
;
// Reference queue for cleared WeakEntries
private
final
ReferenceQueue
<
Object
>
queue
=
new
ReferenceQueue
<>();
private
Entry
[]
newTable
(
int
n
)
{
return
new
Entry
[
n
];
}
/**
* Constructs a new, empty <tt>WeakInternSet</tt> with the default initial
* capacity (16) and load factor (0.75).
*/
WeakInternSet
()
{
this
.
loadFactor
=
DEFAULT_LOAD_FACTOR
;
threshold
=
DEFAULT_INITIAL_CAPACITY
;
table
=
newTable
(
DEFAULT_INITIAL_CAPACITY
);
}
/**
* Applies a supplemental hash function to a given hashCode, which
* defends against poor quality hash functions. This is critical
* because hashing uses power-of-two length hash tables, that
* otherwise encounter collisions for hashCodes that do not differ
* in lower bits.
* @param h preliminary hash code value
* @return supplemental hash code value
*/
private
static
int
hash
(
int
h
)
{
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h
^=
(
h
>>>
20
)
^
(
h
>>>
12
);
return
h
^
(
h
>>>
7
)
^
(
h
>>>
4
);
public
ConcurrentWeakInternSet
()
{
this
.
map
=
new
ConcurrentHashMap
<>();
this
.
stale
=
new
ReferenceQueue
<>();
}
/**
* Checks for equality of non-null reference x and possibly-null y. By
* default uses Object.equals.
* @param x first object to compare
* @param y second object to compare
* @return <tt>true</tt> if objects are equal
*/
private
static
boolean
eq
(
Object
x
,
Object
y
)
{
return
x
==
y
||
x
.
equals
(
y
);
}
/**
* Returns index for hash code h.
* @param h raw hash code
* @param length length of table (power of 2)
* @return index in table
*/
private
static
int
indexFor
(
int
h
,
int
length
)
{
return
h
&
(
length
-
1
);
}
/**
* Expunges stale entries from the table.
* Get the existing interned element.
* This method returns null if no element is interned.
*
* @param elem element to look up
* @return the interned element
*/
private
void
expungeStaleEntries
()
{
for
(
Object
x
;
(
x
=
queue
.
poll
())
!=
null
;
)
{
synchronized
(
queue
)
{
Entry
entry
=
(
Entry
)
x
;
int
i
=
indexFor
(
entry
.
hash
,
table
.
length
);
Entry
prev
=
table
[
i
];
Entry
p
=
prev
;
while
(
p
!=
null
)
{
Entry
next
=
p
.
next
;
if
(
p
==
entry
)
{
if
(
prev
==
entry
)
table
[
i
]
=
next
;
else
prev
.
next
=
next
;
entry
.
next
=
null
;
size
--;
break
;
}
prev
=
p
;
p
=
next
;
}
public
T
get
(
T
elem
)
{
if
(
elem
==
null
)
throw
new
NullPointerException
();
expungeStaleElements
();
WeakEntry
<
T
>
value
=
map
.
get
(
new
WeakEntry
<>(
elem
));
if
(
value
!=
null
)
{
T
res
=
value
.
get
();
if
(
res
!=
null
)
{
return
res
;
}
}
return
null
;
}
/**
* Returns the table after first expunging stale entries.
* @return an expunged hash table
*/
private
Entry
[]
getTable
()
{
expungeStaleEntries
();
return
table
;
}
/**
* Returns the entry to which the specified value is mapped,
* or {@code null} if this set contains no entry for the value.
*
* <p>More formally, if this set contains an entry for value
* {@code entry} to a value {@code value} such that
* {@code entry.equals(value)}, then this method returns {@code entry};
* otherwise it returns {@code null}.
* Interns the element.
* Always returns non-null element, matching the one in the intern set.
* Under the race against another add(), it can return <i>different</i>
* element, if another thread beats us to interning it.
*
* @param
value value to search for in set
* @return
interned value if in set, otherwise <tt>null</tt>
* @param
elem element to add
* @return
element that was actually added
*/
synchronized
MethodType
get
(
MethodType
value
)
{
int
h
=
hash
(
value
.
hashCode
());
Entry
[]
tab
=
getTable
();
int
index
=
indexFor
(
h
,
tab
.
length
);
Entry
e
=
tab
[
index
];
MethodType
g
;
while
(
e
!=
null
)
{
if
(
e
.
hash
==
h
&&
eq
(
value
,
g
=
e
.
get
()))
return
g
;
e
=
e
.
next
;
}
return
null
;
public
T
add
(
T
elem
)
{
if
(
elem
==
null
)
throw
new
NullPointerException
();
// Playing double race here, and so spinloop is required.
// First race is with two concurrent updaters.
// Second race is with GC purging weak ref under our feet.
// Hopefully, we almost always end up with a single pass.
T
interned
;
WeakEntry
<
T
>
e
=
new
WeakEntry
<>(
elem
,
stale
);
do
{
expungeStaleElements
();
WeakEntry
<
T
>
exist
=
map
.
putIfAbsent
(
e
,
e
);
interned
=
(
exist
==
null
)
?
elem
:
exist
.
get
();
}
while
(
interned
==
null
);
return
interned
;
}
/**
* Attempts to add the specified value to the set and returns same value.
* If the set previously contained an entry for this value, the old
* value is left untouched and returned as the result.
*
* @param value value to be added
* @return the previous entry associated with <tt>value</tt>, or
* <tt>value</tt> if there was no previous entry found
*/
synchronized
MethodType
add
(
MethodType
value
)
{
int
h
=
hash
(
value
.
hashCode
());
Entry
[]
tab
=
getTable
();
int
i
=
indexFor
(
h
,
tab
.
length
);
MethodType
g
;
for
(
Entry
e
=
tab
[
i
];
e
!=
null
;
e
=
e
.
next
)
{
if
(
h
==
e
.
hash
&&
eq
(
value
,
g
=
e
.
get
()))
{
return
g
;
}
private
void
expungeStaleElements
()
{
Reference
<?
extends
T
>
reference
;
while
((
reference
=
stale
.
poll
())
!=
null
)
{
map
.
remove
(
reference
);
}
Entry
e
=
tab
[
i
];
tab
[
i
]
=
new
Entry
(
value
,
queue
,
h
,
e
);
if
(++
size
>=
threshold
)
resize
(
tab
.
length
*
2
);
return
value
;
}
/**
* Rehashes the contents of this set into a new array with a
* larger capacity. This method is called automatically when the
* number of keys in this set reaches its threshold.
*
* If current capacity is MAXIMUM_CAPACITY, this method does not
* resize the set, but sets threshold to Integer.MAX_VALUE.
* This has the effect of preventing future calls.
*
* @param newCapacity the new capacity, MUST be a power of two;
* must be greater than current capacity unless current
* capacity is MAXIMUM_CAPACITY (in which case value
* is irrelevant)
*/
private
void
resize
(
int
newCapacity
)
{
Entry
[]
oldTable
=
getTable
();
int
oldCapacity
=
oldTable
.
length
;
if
(
oldCapacity
==
MAXIMUM_CAPACITY
)
{
threshold
=
Integer
.
MAX_VALUE
;
return
;
private
static
class
WeakEntry
<
T
>
extends
WeakReference
<
T
>
{
public
final
int
hashcode
;
public
WeakEntry
(
T
key
,
ReferenceQueue
<
T
>
queue
)
{
super
(
key
,
queue
);
hashcode
=
key
.
hashCode
();
}
Entry
[]
newTable
=
newTable
(
newCapacity
);
transfer
(
oldTable
,
newTable
);
table
=
newTable
;
/*
* If ignoring null elements and processing ref queue caused massive
* shrinkage, then restore old table. This should be rare, but avoids
* unbounded expansion of garbage-filled tables.
*/
if
(
size
>=
threshold
/
2
)
{
threshold
=
(
int
)(
newCapacity
*
loadFactor
);
}
else
{
expungeStaleEntries
();
transfer
(
newTable
,
oldTable
);
table
=
oldTable
;
public
WeakEntry
(
T
key
)
{
super
(
key
);
hashcode
=
key
.
hashCode
();
}
}
/**
* Transfers all entries from src to dest tables
* @param src original table
* @param dest new table
*/
private
void
transfer
(
Entry
[]
src
,
Entry
[]
dest
)
{
for
(
int
j
=
0
;
j
<
src
.
length
;
++
j
)
{
Entry
e
=
src
[
j
];
src
[
j
]
=
null
;
while
(
e
!=
null
)
{
Entry
next
=
e
.
next
;
MethodType
key
=
e
.
get
();
if
(
key
==
null
)
{
e
.
next
=
null
;
// Help GC
size
--;
}
else
{
int
i
=
indexFor
(
e
.
hash
,
dest
.
length
);
e
.
next
=
dest
[
i
];
dest
[
i
]
=
e
;
}
e
=
next
;
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
instanceof
WeakEntry
)
{
Object
that
=
((
WeakEntry
)
obj
).
get
();
Object
mine
=
get
();
return
(
that
==
null
||
mine
==
null
)
?
(
this
==
obj
)
:
mine
.
equals
(
that
);
}
return
false
;
}
}
/**
* The entries in this hash table extend WeakReference, using its main ref
* field as the key.
*/
private
static
class
Entry
extends
WeakReference
<
MethodType
>
{
final
int
hash
;
Entry
next
;
/**
* Creates new entry.
*/
Entry
(
MethodType
key
,
ReferenceQueue
<
Object
>
queue
,
int
hash
,
Entry
next
)
{
super
(
key
,
queue
);
this
.
hash
=
hash
;
this
.
next
=
next
;
@Override
public
int
hashCode
()
{
return
hashcode
;
}
}
}
}
src/share/classes/java/security/Signature.java
浏览文件 @
fff405fa
/*
* Copyright (c) 1996, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -248,6 +248,7 @@ public abstract class Signature extends SignatureSpi {
Signature
sig
;
if
(
instance
.
impl
instanceof
Signature
)
{
sig
=
(
Signature
)
instance
.
impl
;
sig
.
algorithm
=
algorithm
;
}
else
{
SignatureSpi
spi
=
(
SignatureSpi
)
instance
.
impl
;
sig
=
new
Delegate
(
spi
,
algorithm
);
...
...
src/share/classes/sun/reflect/generics/repository/ClassRepository.java
浏览文件 @
fff405fa
...
...
@@ -40,6 +40,8 @@ import java.lang.reflect.Type;
*/
public
class
ClassRepository
extends
GenericDeclRepository
<
ClassSignature
>
{
public
static
final
ClassRepository
NONE
=
ClassRepository
.
make
(
"Ljava/lang/Object;"
,
null
);
private
Type
superclass
;
// caches the generic superclass info
private
Type
[]
superInterfaces
;
// caches the generic superinterface info
...
...
src/share/native/java/lang/Class.c
浏览文件 @
fff405fa
...
...
@@ -55,7 +55,7 @@ extern jboolean VerifyFixClassname(char *utf_name);
static
JNINativeMethod
methods
[]
=
{
{
"getName0"
,
"()"
STR
,
(
void
*
)
&
JVM_GetClassName
},
{
"getSuperclass"
,
"()"
CLS
,
NULL
},
{
"getInterfaces
"
,
"()["
CLS
,
(
void
*
)
&
JVM_GetClassInterfaces
},
{
"getInterfaces
0"
,
"()["
CLS
,
(
void
*
)
&
JVM_GetClassInterfaces
},
{
"getClassLoader0"
,
"()"
JCL
,
(
void
*
)
&
JVM_GetClassLoader
},
{
"isInterface"
,
"()Z"
,
(
void
*
)
&
JVM_IsInterface
},
{
"getSigners"
,
"()["
OBJ
,
(
void
*
)
&
JVM_GetClassSigners
},
...
...
@@ -70,7 +70,7 @@ static JNINativeMethod methods[] = {
{
"getProtectionDomain0"
,
"()"
PD
,
(
void
*
)
&
JVM_GetProtectionDomain
},
{
"getDeclaredClasses0"
,
"()["
CLS
,
(
void
*
)
&
JVM_GetDeclaredClasses
},
{
"getDeclaringClass"
,
"()"
CLS
,
(
void
*
)
&
JVM_GetDeclaringClass
},
{
"getGenericSignature
"
,
"()"
STR
,
(
void
*
)
&
JVM_GetClassSignature
},
{
"getGenericSignature
0"
,
"()"
STR
,
(
void
*
)
&
JVM_GetClassSignature
},
{
"getRawAnnotations"
,
"()"
BA
,
(
void
*
)
&
JVM_GetClassAnnotations
},
{
"getConstantPool"
,
"()"
CPL
,
(
void
*
)
&
JVM_GetClassConstantPool
},
{
"desiredAssertionStatus0"
,
"("
CLS
")Z"
,(
void
*
)
&
JVM_DesiredAssertionStatus
},
...
...
test/java/security/Signature/SignatureGetAlgorithm.java
0 → 100644
浏览文件 @
fff405fa
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Portions Copyright (c) 2013 IBM Corporation
*/
/*
* @test
* @bug 8014620
* @summary Signature.getAlgorithm return null in special case
* @run main/othervm SignatureGetAlgorithm
* @author youdwei
*/
import
java.security.*
;
public
class
SignatureGetAlgorithm
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
Provider
testProvider
=
new
TestProvider
();
Security
.
addProvider
(
testProvider
);
Signature
sig
=
Signature
.
getInstance
(
"MySignatureAlg"
);
String
algorithm
=
sig
.
getAlgorithm
();
System
.
out
.
println
(
"Algorithm Name: "
+
algorithm
);
if
(
algorithm
==
null
)
{
throw
new
Exception
(
"algorithm name should be 'MySignatureAlg'"
);
}
}
public
static
class
TestProvider
extends
Provider
{
TestProvider
()
{
super
(
"test"
,
1.0
,
"test"
);
put
(
"Signature.MySignatureAlg"
,
"SignatureGetAlgorithm$MySignatureAlg"
);
}
}
public
static
class
MySignatureAlg
extends
Signature
{
public
MySignatureAlg
()
{
super
(
null
);
}
MySignatureAlg
(
String
s
)
{
super
(
s
);
}
@Override
protected
void
engineInitVerify
(
PublicKey
publicKey
)
throws
InvalidKeyException
{
}
@Override
protected
void
engineInitSign
(
PrivateKey
privateKey
)
throws
InvalidKeyException
{
}
@Override
protected
void
engineUpdate
(
byte
b
)
throws
SignatureException
{
}
@Override
protected
void
engineUpdate
(
byte
[]
b
,
int
off
,
int
len
)
throws
SignatureException
{
}
@Override
protected
byte
[]
engineSign
()
throws
SignatureException
{
return
new
byte
[
0
];
}
@Override
protected
boolean
engineVerify
(
byte
[]
sigBytes
)
throws
SignatureException
{
return
false
;
}
@Override
@Deprecated
protected
void
engineSetParameter
(
String
param
,
Object
value
)
throws
InvalidParameterException
{
}
@Override
@Deprecated
protected
Object
engineGetParameter
(
String
param
)
throws
InvalidParameterException
{
return
null
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录