Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
361d5538
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看板
提交
361d5538
编写于
8月 27, 2012
作者:
L
lana
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
5fe2cb6a
efe18d26
变更
39
展开全部
隐藏空白更改
内联
并排
Showing
39 changed file
with
7887 addition
and
3687 deletion
+7887
-3687
.hgtags
.hgtags
+2
-0
src/share/classes/java/lang/ClassValue.java
src/share/classes/java/lang/ClassValue.java
+11
-2
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
+0
-1204
src/share/classes/java/lang/invoke/BoundMethodHandle.java
src/share/classes/java/lang/invoke/BoundMethodHandle.java
+796
-132
src/share/classes/java/lang/invoke/CallSite.java
src/share/classes/java/lang/invoke/CallSite.java
+6
-31
src/share/classes/java/lang/invoke/DirectMethodHandle.java
src/share/classes/java/lang/invoke/DirectMethodHandle.java
+619
-13
src/share/classes/java/lang/invoke/DontInline.java
src/share/classes/java/lang/invoke/DontInline.java
+7
-20
src/share/classes/java/lang/invoke/ForceInline.java
src/share/classes/java/lang/invoke/ForceInline.java
+37
-0
src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
...re/classes/java/lang/invoke/InvokerBytecodeGenerator.java
+1065
-0
src/share/classes/java/lang/invoke/Invokers.java
src/share/classes/java/lang/invoke/Invokers.java
+250
-17
src/share/classes/java/lang/invoke/LambdaForm.java
src/share/classes/java/lang/invoke/LambdaForm.java
+1620
-0
src/share/classes/java/lang/invoke/MemberName.java
src/share/classes/java/lang/invoke/MemberName.java
+356
-123
src/share/classes/java/lang/invoke/MethodHandle.java
src/share/classes/java/lang/invoke/MethodHandle.java
+256
-52
src/share/classes/java/lang/invoke/MethodHandleImpl.java
src/share/classes/java/lang/invoke/MethodHandleImpl.java
+492
-669
src/share/classes/java/lang/invoke/MethodHandleInfo.java
src/share/classes/java/lang/invoke/MethodHandleInfo.java
+71
-0
src/share/classes/java/lang/invoke/MethodHandleNatives.java
src/share/classes/java/lang/invoke/MethodHandleNatives.java
+190
-211
src/share/classes/java/lang/invoke/MethodHandleStatics.java
src/share/classes/java/lang/invoke/MethodHandleStatics.java
+20
-16
src/share/classes/java/lang/invoke/MethodHandles.java
src/share/classes/java/lang/invoke/MethodHandles.java
+211
-280
src/share/classes/java/lang/invoke/MethodType.java
src/share/classes/java/lang/invoke/MethodType.java
+353
-28
src/share/classes/java/lang/invoke/MethodTypeForm.java
src/share/classes/java/lang/invoke/MethodTypeForm.java
+83
-186
src/share/classes/java/lang/invoke/SimpleMethodHandle.java
src/share/classes/java/lang/invoke/SimpleMethodHandle.java
+66
-0
src/share/classes/java/lang/invoke/package-info.java
src/share/classes/java/lang/invoke/package-info.java
+7
-0
src/share/classes/sun/invoke/util/ValueConversions.java
src/share/classes/sun/invoke/util/ValueConversions.java
+228
-324
src/share/classes/sun/invoke/util/VerifyAccess.java
src/share/classes/sun/invoke/util/VerifyAccess.java
+40
-0
src/share/classes/sun/invoke/util/VerifyType.java
src/share/classes/sun/invoke/util/VerifyType.java
+0
-36
src/share/classes/sun/invoke/util/Wrapper.java
src/share/classes/sun/invoke/util/Wrapper.java
+26
-73
src/share/classes/sun/misc/Unsafe.java
src/share/classes/sun/misc/Unsafe.java
+8
-0
src/share/classes/sun/util/resources/es/CurrencyNames_es_VE.properties
...sses/sun/util/resources/es/CurrencyNames_es_VE.properties
+1
-1
test/java/lang/invoke/7157574/Test7157574.java
test/java/lang/invoke/7157574/Test7157574.java
+111
-0
test/java/lang/invoke/InvokeGenericTest.java
test/java/lang/invoke/InvokeGenericTest.java
+0
-18
test/java/lang/invoke/JavaDocExamplesTest.java
test/java/lang/invoke/JavaDocExamplesTest.java
+0
-1
test/java/lang/invoke/MaxTest.java
test/java/lang/invoke/MaxTest.java
+143
-0
test/java/lang/invoke/MethodHandlesTest.java
test/java/lang/invoke/MethodHandlesTest.java
+306
-157
test/java/lang/invoke/PrivateInvokeTest.java
test/java/lang/invoke/PrivateInvokeTest.java
+376
-0
test/java/lang/invoke/ThrowExceptionsTest.java
test/java/lang/invoke/ThrowExceptionsTest.java
+1
-1
test/java/lang/invoke/remote/RemoteExample.java
test/java/lang/invoke/remote/RemoteExample.java
+40
-0
test/sun/invoke/util/ValueConversionsTest.java
test/sun/invoke/util/ValueConversionsTest.java
+86
-90
test/sun/text/resources/LocaleData
test/sun/text/resources/LocaleData
+2
-1
test/sun/text/resources/LocaleDataTest.java
test/sun/text/resources/LocaleDataTest.java
+1
-1
未找到文件。
.hgtags
浏览文件 @
361d5538
...
@@ -173,3 +173,5 @@ b92353a01aa049bc508fc56f0347d5934b7c4390 jdk8-b45
...
@@ -173,3 +173,5 @@ b92353a01aa049bc508fc56f0347d5934b7c4390 jdk8-b45
51707c3b75c0f521794d9ab425f4e5b2351c70c1 jdk8-b49
51707c3b75c0f521794d9ab425f4e5b2351c70c1 jdk8-b49
e4bae5c53fca8fcb9393d47fd36a34b9e2e8d4ec jdk8-b50
e4bae5c53fca8fcb9393d47fd36a34b9e2e8d4ec jdk8-b50
e865efbc71059a414b3b2dd2e0adfcb3d2ab6ff9 jdk8-b51
e865efbc71059a414b3b2dd2e0adfcb3d2ab6ff9 jdk8-b51
e8569a473cee7f4955bd9e76a9bdf6c6a07ced27 jdk8-b52
2c6933c5106b81a8578b70996fe5b735fb3adb60 jdk8-b53
src/share/classes/java/lang/ClassValue.java
浏览文件 @
361d5538
...
@@ -489,9 +489,18 @@ public abstract class ClassValue<T> {
...
@@ -489,9 +489,18 @@ public abstract class ClassValue<T> {
/** Remove an entry. */
/** Remove an entry. */
synchronized
synchronized
void
removeEntry
(
ClassValue
<?>
classValue
)
{
void
removeEntry
(
ClassValue
<?>
classValue
)
{
// make all cache elements for this guy go stale:
Entry
<?>
e
=
remove
(
classValue
.
identity
);
if
(
remove
(
classValue
.
identity
)
!=
null
)
{
if
(
e
==
null
)
{
// Uninitialized, and no pending calls to computeValue. No change.
}
else
if
(
e
.
isPromise
())
{
// State is uninitialized, with a pending call to finishEntry.
// Since remove is a no-op in such a state, keep the promise
// by putting it back into the map.
put
(
classValue
.
identity
,
e
);
}
else
{
// In an initialized state. Bump forward, and de-initialize.
classValue
.
bumpVersion
();
classValue
.
bumpVersion
();
// Make all cache elements for this guy go stale.
removeStaleEntries
(
classValue
);
removeStaleEntries
(
classValue
);
}
}
}
}
...
...
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
已删除
100644 → 0
浏览文件 @
5fe2cb6a
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/BoundMethodHandle.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/CallSite.java
浏览文件 @
361d5538
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
package
java.lang.invoke
;
package
java.lang.invoke
;
import
sun.invoke.empty.Empty
;
import
sun.invoke.empty.Empty
;
import
s
un.misc.Unsafe
;
import
s
tatic
java
.
lang
.
invoke
.
MethodHandleStatics
.*
;
import
static
java
.
lang
.
invoke
.
MethodHandles
.
Lookup
.
IMPL_LOOKUP
;
import
static
java
.
lang
.
invoke
.
MethodHandles
.
Lookup
.
IMPL_LOOKUP
;
/**
/**
...
@@ -86,13 +86,9 @@ abstract
...
@@ -86,13 +86,9 @@ abstract
public
class
CallSite
{
public
class
CallSite
{
static
{
MethodHandleImpl
.
initStatics
();
}
static
{
MethodHandleImpl
.
initStatics
();
}
// Fields used only by the JVM. Do not use or change.
private
MemberName
vmmethod
;
// supplied by the JVM (ref. to calling method)
private
int
vmindex
;
// supplied by the JVM (BCI within calling method)
// The actual payload of this call site:
// The actual payload of this call site:
/*package-private*/
/*package-private*/
MethodHandle
target
;
MethodHandle
target
;
// Note: This field is known to the JVM. Do not change.
/**
/**
* Make a blank call site object with the given method type.
* Make a blank call site object with the given method type.
...
@@ -151,24 +147,6 @@ public class CallSite {
...
@@ -151,24 +147,6 @@ public class CallSite {
return
target
.
type
();
return
target
.
type
();
}
}
/** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
* The parameters are JVM-specific.
*/
void
initializeFromJVM
(
String
name
,
MethodType
type
,
MemberName
callerMethod
,
int
callerBCI
)
{
if
(
this
.
vmmethod
!=
null
)
{
// FIXME
throw
new
BootstrapMethodError
(
"call site has already been linked to an invokedynamic instruction"
);
}
if
(!
this
.
type
().
equals
(
type
))
{
throw
wrongTargetType
(
target
,
type
);
}
this
.
vmindex
=
callerBCI
;
this
.
vmmethod
=
callerMethod
;
}
/**
/**
* Returns the target method of the call site, according to the
* Returns the target method of the call site, according to the
* behavior defined by this call site's specific class.
* behavior defined by this call site's specific class.
...
@@ -233,7 +211,7 @@ public class CallSite {
...
@@ -233,7 +211,7 @@ public class CallSite {
public
abstract
MethodHandle
dynamicInvoker
();
public
abstract
MethodHandle
dynamicInvoker
();
/*non-public*/
MethodHandle
makeDynamicInvoker
()
{
/*non-public*/
MethodHandle
makeDynamicInvoker
()
{
MethodHandle
getTarget
=
MethodHandleImpl
.
bindReceiver
(
GET_TARGET
,
this
);
MethodHandle
getTarget
=
GET_TARGET
.
bindReceiver
(
this
);
MethodHandle
invoker
=
MethodHandles
.
exactInvoker
(
this
.
type
());
MethodHandle
invoker
=
MethodHandles
.
exactInvoker
(
this
.
type
());
return
MethodHandles
.
foldArguments
(
invoker
,
getTarget
);
return
MethodHandles
.
foldArguments
(
invoker
,
getTarget
);
}
}
...
@@ -255,12 +233,10 @@ public class CallSite {
...
@@ -255,12 +233,10 @@ public class CallSite {
}
}
// unsafe stuff:
// unsafe stuff:
private
static
final
Unsafe
unsafe
=
Unsafe
.
getUnsafe
();
private
static
final
long
TARGET_OFFSET
;
private
static
final
long
TARGET_OFFSET
;
static
{
static
{
try
{
try
{
TARGET_OFFSET
=
unsafe
.
objectFieldOffset
(
CallSite
.
class
.
getDeclaredField
(
"target"
));
TARGET_OFFSET
=
UNSAFE
.
objectFieldOffset
(
CallSite
.
class
.
getDeclaredField
(
"target"
));
}
catch
(
Exception
ex
)
{
throw
new
Error
(
ex
);
}
}
catch
(
Exception
ex
)
{
throw
new
Error
(
ex
);
}
}
}
...
@@ -270,7 +246,7 @@ public class CallSite {
...
@@ -270,7 +246,7 @@ public class CallSite {
}
}
/*package-private*/
/*package-private*/
MethodHandle
getTargetVolatile
()
{
MethodHandle
getTargetVolatile
()
{
return
(
MethodHandle
)
unsafe
.
getObjectVolatile
(
this
,
TARGET_OFFSET
);
return
(
MethodHandle
)
UNSAFE
.
getObjectVolatile
(
this
,
TARGET_OFFSET
);
}
}
/*package-private*/
/*package-private*/
void
setTargetVolatile
(
MethodHandle
newTarget
)
{
void
setTargetVolatile
(
MethodHandle
newTarget
)
{
...
@@ -284,8 +260,7 @@ public class CallSite {
...
@@ -284,8 +260,7 @@ public class CallSite {
// Extra arguments for BSM, if any:
// Extra arguments for BSM, if any:
Object
info
,
Object
info
,
// Caller information:
// Caller information:
MemberName
callerMethod
,
int
callerBCI
)
{
Class
<?>
callerClass
)
{
Class
<?>
callerClass
=
callerMethod
.
getDeclaringClass
();
Object
caller
=
IMPL_LOOKUP
.
in
(
callerClass
);
Object
caller
=
IMPL_LOOKUP
.
in
(
callerClass
);
CallSite
site
;
CallSite
site
;
try
{
try
{
...
...
src/share/classes/java/lang/invoke/DirectMethodHandle.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/
CountingMethodHandl
e.java
→
src/share/classes/java/lang/invoke/
DontInlin
e.java
浏览文件 @
361d5538
/*
/*
* Copyright (c) 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -25,26 +25,13 @@
...
@@ -25,26 +25,13 @@
package
java.lang.invoke
;
package
java.lang.invoke
;
import
static
java
.
lang
.
invoke
.
MethodHandleNatives
.
Constants
.*;
import
java.lang.annotation
.*
;
/**
/**
* This method handle is used to optionally provide a count of how
* Internal marker for some methods in the JSR 292 implementation.
* many times it was invoked.
*
* @author never
*/
*/
class
CountingMethodHandle
extends
AdapterMethodHandle
{
/*non-public*/
private
int
vmcount
;
@Target
({
ElementType
.
METHOD
,
ElementType
.
CONSTRUCTOR
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
private
CountingMethodHandle
(
MethodHandle
target
)
{
@interface
DontInline
{
super
(
target
,
target
.
type
(),
AdapterMethodHandle
.
makeConv
(
OP_RETYPE_ONLY
));
}
/** Wrap the incoming MethodHandle in a CountingMethodHandle if they are enabled */
static
MethodHandle
wrap
(
MethodHandle
mh
)
{
if
(
MethodHandleNatives
.
COUNT_GWT
)
{
return
new
CountingMethodHandle
(
mh
);
}
return
mh
;
}
}
}
src/share/classes/java/lang/invoke/ForceInline.java
0 → 100644
浏览文件 @
361d5538
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
java.lang.invoke
;
import
java.lang.annotation.*
;
/**
* Internal marker for some methods in the JSR 292 implementation.
*/
/*non-public*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
CONSTRUCTOR
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
ForceInline
{
}
src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
0 → 100644
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/Invokers.java
浏览文件 @
361d5538
...
@@ -25,8 +25,11 @@
...
@@ -25,8 +25,11 @@
package
java.lang.invoke
;
package
java.lang.invoke
;
import
java.util.Arrays
;
import
sun.invoke.empty.Empty
;
import
sun.invoke.empty.Empty
;
import
static
java
.
lang
.
invoke
.
MethodHandleNatives
.
Constants
.*;
import
static
java
.
lang
.
invoke
.
MethodHandles
.
Lookup
.
IMPL_LOOKUP
;
import
static
java
.
lang
.
invoke
.
MethodHandles
.
Lookup
.
IMPL_LOOKUP
;
import
static
java
.
lang
.
invoke
.
LambdaForm
.*;
/**
/**
* Construction and caching of often-used invokers.
* Construction and caching of often-used invokers.
...
@@ -36,11 +39,15 @@ class Invokers {
...
@@ -36,11 +39,15 @@ class Invokers {
// exact type (sans leading taget MH) for the outgoing call
// exact type (sans leading taget MH) for the outgoing call
private
final
MethodType
targetType
;
private
final
MethodType
targetType
;
// FIXME: Get rid of the invokers that are not useful.
// exact invoker for the outgoing call
// exact invoker for the outgoing call
private
/*lazy*/
MethodHandle
exactInvoker
;
private
/*lazy*/
MethodHandle
exactInvoker
;
// erased (partially untyped but with primitives) invoker for the outgoing call
// erased (partially untyped but with primitives) invoker for the outgoing call
// FIXME: get rid of
private
/*lazy*/
MethodHandle
erasedInvoker
;
private
/*lazy*/
MethodHandle
erasedInvoker
;
// FIXME: get rid of
/*lazy*/
MethodHandle
erasedInvokerWithDrops
;
// for InvokeGeneric
/*lazy*/
MethodHandle
erasedInvokerWithDrops
;
// for InvokeGeneric
// general invoker for the outgoing call
// general invoker for the outgoing call
...
@@ -63,14 +70,13 @@ class Invokers {
...
@@ -63,14 +70,13 @@ class Invokers {
this
.
spreadInvokers
=
new
MethodHandle
[
targetType
.
parameterCount
()+
1
];
this
.
spreadInvokers
=
new
MethodHandle
[
targetType
.
parameterCount
()+
1
];
}
}
/*non-public*/
static
MethodType
invokerType
(
MethodType
targetType
)
{
return
targetType
.
insertParameterTypes
(
0
,
MethodHandle
.
class
);
}
/*non-public*/
MethodHandle
exactInvoker
()
{
/*non-public*/
MethodHandle
exactInvoker
()
{
MethodHandle
invoker
=
exactInvoker
;
MethodHandle
invoker
=
exactInvoker
;
if
(
invoker
!=
null
)
return
invoker
;
if
(
invoker
!=
null
)
return
invoker
;
invoker
=
lookupInvoker
(
"invokeExact"
);
MethodType
mtype
=
targetType
;
LambdaForm
lform
=
invokeForm
(
mtype
,
MethodTypeForm
.
LF_EX_INVOKER
);
invoker
=
BoundMethodHandle
.
bindSingle
(
mtype
.
invokerType
(),
lform
,
mtype
);
assert
(
checkInvoker
(
invoker
));
exactInvoker
=
invoker
;
exactInvoker
=
invoker
;
return
invoker
;
return
invoker
;
}
}
...
@@ -78,29 +84,50 @@ class Invokers {
...
@@ -78,29 +84,50 @@ class Invokers {
/*non-public*/
MethodHandle
generalInvoker
()
{
/*non-public*/
MethodHandle
generalInvoker
()
{
MethodHandle
invoker
=
generalInvoker
;
MethodHandle
invoker
=
generalInvoker
;
if
(
invoker
!=
null
)
return
invoker
;
if
(
invoker
!=
null
)
return
invoker
;
invoker
=
lookupInvoker
(
"invoke"
);
MethodType
mtype
=
targetType
;
prepareForGenericCall
(
mtype
);
LambdaForm
lform
=
invokeForm
(
mtype
,
MethodTypeForm
.
LF_GEN_INVOKER
);
invoker
=
BoundMethodHandle
.
bindSingle
(
mtype
.
invokerType
(),
lform
,
mtype
);
assert
(
checkInvoker
(
invoker
));
generalInvoker
=
invoker
;
generalInvoker
=
invoker
;
return
invoker
;
return
invoker
;
}
}
private
MethodHandle
lookupInvoker
(
String
name
)
{
/*non-public*/
MethodHandle
makeBasicInvoker
()
{
MethodHandle
invoker
;
MethodHandle
invoker
=
DirectMethodHandle
.
make
(
invokeBasicMethod
(
targetType
));
assert
(
targetType
==
targetType
.
basicType
());
// Note: This is not cached here. It is cached by the calling MethodTypeForm.
assert
(
checkInvoker
(
invoker
));
return
invoker
;
}
static
MemberName
invokeBasicMethod
(
MethodType
type
)
{
String
name
=
"invokeBasic"
;
try
{
try
{
invoker
=
IMPL_LOOKUP
.
findVirtual
(
MethodHandle
.
class
,
name
,
targetType
);
//Lookup.findVirtual(MethodHandle.class, name, type);
return
IMPL_LOOKUP
.
resolveOrFail
(
REF_invokeVirtual
,
MethodHandle
.
class
,
name
,
type
);
}
catch
(
ReflectiveOperationException
ex
)
{
}
catch
(
ReflectiveOperationException
ex
)
{
throw
new
InternalError
(
"JVM cannot find invoker for "
+
t
argetT
ype
,
ex
);
throw
new
InternalError
(
"JVM cannot find invoker for "
+
type
,
ex
);
}
}
assert
(
invokerType
(
targetType
)
==
invoker
.
type
());
}
private
boolean
checkInvoker
(
MethodHandle
invoker
)
{
assert
(
targetType
.
invokerType
().
equals
(
invoker
.
type
()))
:
java
.
util
.
Arrays
.
asList
(
targetType
,
targetType
.
invokerType
(),
invoker
);
assert
(
invoker
.
internalMemberName
()
==
null
||
invoker
.
internalMemberName
().
getMethodType
().
equals
(
targetType
));
assert
(!
invoker
.
isVarargsCollector
());
assert
(!
invoker
.
isVarargsCollector
());
return
invoker
;
return
true
;
}
}
// FIXME: get rid of
/*non-public*/
MethodHandle
erasedInvoker
()
{
/*non-public*/
MethodHandle
erasedInvoker
()
{
MethodHandle
xinvoker
=
exactInvoker
();
MethodHandle
xinvoker
=
exactInvoker
();
MethodHandle
invoker
=
erasedInvoker
;
MethodHandle
invoker
=
erasedInvoker
;
if
(
invoker
!=
null
)
return
invoker
;
if
(
invoker
!=
null
)
return
invoker
;
MethodType
erasedType
=
targetType
.
erase
();
MethodType
erasedType
=
targetType
.
erase
();
invoker
=
xinvoker
.
asType
(
invokerType
(
erasedType
));
invoker
=
xinvoker
.
asType
(
erasedType
.
invokerType
(
));
erasedInvoker
=
invoker
;
erasedInvoker
=
invoker
;
return
invoker
;
return
invoker
;
}
}
...
@@ -118,7 +145,7 @@ class Invokers {
...
@@ -118,7 +145,7 @@ class Invokers {
/*non-public*/
MethodHandle
varargsInvoker
()
{
/*non-public*/
MethodHandle
varargsInvoker
()
{
MethodHandle
vaInvoker
=
varargsInvoker
;
MethodHandle
vaInvoker
=
varargsInvoker
;
if
(
vaInvoker
!=
null
)
return
vaInvoker
;
if
(
vaInvoker
!=
null
)
return
vaInvoker
;
vaInvoker
=
spreadInvoker
(
0
).
asType
(
invokerType
(
MethodType
.
genericMethodType
(
0
,
true
)
));
vaInvoker
=
spreadInvoker
(
0
).
asType
(
MethodType
.
genericMethodType
(
0
,
true
).
invokerType
(
));
varargsInvoker
=
vaInvoker
;
varargsInvoker
=
vaInvoker
;
return
vaInvoker
;
return
vaInvoker
;
}
}
...
@@ -137,16 +164,18 @@ class Invokers {
...
@@ -137,16 +164,18 @@ class Invokers {
uninitializedCallSite
=
invoker
;
uninitializedCallSite
=
invoker
;
return
invoker
;
return
invoker
;
}
}
if
(
THROW_UCS
==
null
)
{
invoker
=
THROW_UCS
;
if
(
invoker
==
null
)
{
try
{
try
{
THROW_UCS
=
IMPL_LOOKUP
THROW_UCS
=
invoker
=
IMPL_LOOKUP
.
findStatic
(
CallSite
.
class
,
"uninitializedCallSite"
,
.
findStatic
(
CallSite
.
class
,
"uninitializedCallSite"
,
MethodType
.
methodType
(
Empty
.
class
));
MethodType
.
methodType
(
Empty
.
class
));
}
catch
(
ReflectiveOperationException
ex
)
{
}
catch
(
ReflectiveOperationException
ex
)
{
throw
new
RuntimeException
(
ex
);
throw
new
RuntimeException
(
ex
);
}
}
}
}
invoker
=
AdapterMethodHandle
.
makeRetypeRaw
(
targetType
,
THROW_UCS
);
invoker
=
MethodHandles
.
explicitCastArguments
(
invoker
,
MethodType
.
methodType
(
targetType
.
returnType
()));
invoker
=
invoker
.
dropArguments
(
targetType
,
0
,
targetType
.
parameterCount
());
assert
(
invoker
.
type
().
equals
(
targetType
));
assert
(
invoker
.
type
().
equals
(
targetType
));
uninitializedCallSite
=
invoker
;
uninitializedCallSite
=
invoker
;
return
invoker
;
return
invoker
;
...
@@ -155,4 +184,208 @@ class Invokers {
...
@@ -155,4 +184,208 @@ class Invokers {
public
String
toString
()
{
public
String
toString
()
{
return
"Invokers"
+
targetType
;
return
"Invokers"
+
targetType
;
}
}
private
static
MethodType
fixMethodType
(
Class
<?>
callerClass
,
Object
type
)
{
if
(
type
instanceof
MethodType
)
return
(
MethodType
)
type
;
else
return
MethodType
.
fromMethodDescriptorString
((
String
)
type
,
callerClass
.
getClassLoader
());
}
static
MemberName
exactInvokerMethod
(
Class
<?>
callerClass
,
Object
type
,
Object
[]
appendixResult
)
{
MethodType
mtype
=
fixMethodType
(
callerClass
,
type
);
LambdaForm
lform
=
invokeForm
(
mtype
,
MethodTypeForm
.
LF_EX_LINKER
);
appendixResult
[
0
]
=
mtype
;
return
lform
.
vmentry
;
}
static
MemberName
genericInvokerMethod
(
Class
<?>
callerClass
,
Object
type
,
Object
[]
appendixResult
)
{
MethodType
mtype
=
fixMethodType
(
callerClass
,
type
);
LambdaForm
lform
=
invokeForm
(
mtype
,
MethodTypeForm
.
LF_GEN_LINKER
);
prepareForGenericCall
(
mtype
);
appendixResult
[
0
]
=
mtype
;
return
lform
.
vmentry
;
}
private
static
LambdaForm
invokeForm
(
MethodType
mtype
,
int
which
)
{
mtype
=
mtype
.
basicType
();
// normalize Z to I, String to Object, etc.
boolean
isLinker
,
isGeneric
;
String
debugName
;
switch
(
which
)
{
case
MethodTypeForm
.
LF_EX_LINKER
:
isLinker
=
true
;
isGeneric
=
false
;
debugName
=
"invokeExact_MT"
;
break
;
case
MethodTypeForm
.
LF_EX_INVOKER
:
isLinker
=
false
;
isGeneric
=
false
;
debugName
=
"exactInvoker"
;
break
;
case
MethodTypeForm
.
LF_GEN_LINKER
:
isLinker
=
true
;
isGeneric
=
true
;
debugName
=
"invoke_MT"
;
break
;
case
MethodTypeForm
.
LF_GEN_INVOKER
:
isLinker
=
false
;
isGeneric
=
true
;
debugName
=
"invoker"
;
break
;
default
:
throw
new
InternalError
();
}
LambdaForm
lform
=
mtype
.
form
().
cachedLambdaForm
(
which
);
if
(
lform
!=
null
)
return
lform
;
// exactInvokerForm (Object,Object)Object
// link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
final
int
THIS_MH
=
0
;
final
int
CALL_MH
=
THIS_MH
+
(
isLinker
?
0
:
1
);
final
int
ARG_BASE
=
CALL_MH
+
1
;
final
int
OUTARG_LIMIT
=
ARG_BASE
+
mtype
.
parameterCount
();
final
int
INARG_LIMIT
=
OUTARG_LIMIT
+
(
isLinker
?
1
:
0
);
int
nameCursor
=
OUTARG_LIMIT
;
final
int
MTYPE_ARG
=
nameCursor
++;
// might be last in-argument
final
int
CHECK_TYPE
=
nameCursor
++;
final
int
LINKER_CALL
=
nameCursor
++;
MethodType
invokerFormType
=
mtype
.
invokerType
();
if
(
isLinker
)
{
invokerFormType
=
invokerFormType
.
appendParameterTypes
(
MemberName
.
class
);
}
else
{
invokerFormType
=
invokerFormType
.
invokerType
();
}
Name
[]
names
=
arguments
(
nameCursor
-
INARG_LIMIT
,
invokerFormType
);
assert
(
names
.
length
==
nameCursor
);
if
(
MTYPE_ARG
>=
INARG_LIMIT
)
{
assert
(
names
[
MTYPE_ARG
]
==
null
);
names
[
MTYPE_ARG
]
=
BoundMethodHandle
.
getSpeciesData
(
"L"
).
getterName
(
names
[
THIS_MH
],
0
);
// else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
}
// Make the final call. If isGeneric, then prepend the result of type checking.
MethodType
outCallType
;
Object
[]
outArgs
;
if
(!
isGeneric
)
{
names
[
CHECK_TYPE
]
=
new
Name
(
NF_checkExactType
,
names
[
CALL_MH
],
names
[
MTYPE_ARG
]);
// mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
outArgs
=
Arrays
.
copyOfRange
(
names
,
CALL_MH
,
OUTARG_LIMIT
,
Object
[].
class
);
outCallType
=
mtype
;
}
else
{
names
[
CHECK_TYPE
]
=
new
Name
(
NF_checkGenericType
,
names
[
CALL_MH
],
names
[
MTYPE_ARG
]);
// mh.invokeGeneric(a*):R =>
// let mt=TYPEOF(a*:R), gamh=checkGenericType(mh, mt);
// gamh.invokeBasic(mt, mh, a*)
final
int
PREPEND_GAMH
=
0
,
PREPEND_MT
=
1
,
PREPEND_COUNT
=
2
;
outArgs
=
Arrays
.
copyOfRange
(
names
,
CALL_MH
,
OUTARG_LIMIT
+
PREPEND_COUNT
,
Object
[].
class
);
// prepend arguments:
System
.
arraycopy
(
outArgs
,
0
,
outArgs
,
PREPEND_COUNT
,
outArgs
.
length
-
PREPEND_COUNT
);
outArgs
[
PREPEND_GAMH
]
=
names
[
CHECK_TYPE
];
outArgs
[
PREPEND_MT
]
=
names
[
MTYPE_ARG
];
outCallType
=
mtype
.
insertParameterTypes
(
0
,
MethodType
.
class
,
MethodHandle
.
class
);
}
names
[
LINKER_CALL
]
=
new
Name
(
invokeBasicMethod
(
outCallType
),
outArgs
);
lform
=
new
LambdaForm
(
debugName
,
INARG_LIMIT
,
names
);
if
(
isLinker
)
lform
.
compileToBytecode
();
// JVM needs a real methodOop
lform
=
mtype
.
form
().
setCachedLambdaForm
(
which
,
lform
);
return
lform
;
}
/*non-public*/
static
WrongMethodTypeException
newWrongMethodTypeException
(
MethodType
actual
,
MethodType
expected
)
{
// FIXME: merge with JVM logic for throwing WMTE
return
new
WrongMethodTypeException
(
"expected "
+
expected
+
" but found "
+
actual
);
}
/** Static definition of MethodHandle.invokeExact checking code. */
/*non-public*/
static
@ForceInline
void
checkExactType
(
Object
mhObj
,
Object
expectedObj
)
{
MethodHandle
mh
=
(
MethodHandle
)
mhObj
;
MethodType
expected
=
(
MethodType
)
expectedObj
;
MethodType
actual
=
mh
.
type
();
if
(
actual
!=
expected
)
throw
newWrongMethodTypeException
(
expected
,
actual
);
}
/** Static definition of MethodHandle.invokeGeneric checking code. */
/*non-public*/
static
@ForceInline
Object
checkGenericType
(
Object
mhObj
,
Object
expectedObj
)
{
MethodHandle
mh
=
(
MethodHandle
)
mhObj
;
MethodType
expected
=
(
MethodType
)
expectedObj
;
//MethodType actual = mh.type();
MethodHandle
gamh
=
expected
.
form
().
genericInvoker
;
if
(
gamh
!=
null
)
return
gamh
;
return
prepareForGenericCall
(
expected
);
}
/**
* Returns an adapter GA for invoking a MH with type adjustments.
* The MethodType of the generic invocation site is prepended to MH
* and its arguments as follows:
* {@code (R)MH.invoke(A*) => GA.invokeBasic(TYPEOF<A*,R>, MH, A*)}
*/
/*non-public*/
static
MethodHandle
prepareForGenericCall
(
MethodType
mtype
)
{
// force any needed adapters to be preconstructed
MethodTypeForm
form
=
mtype
.
form
();
MethodHandle
gamh
=
form
.
genericInvoker
;
if
(
gamh
!=
null
)
return
gamh
;
try
{
// Trigger adapter creation.
gamh
=
InvokeGeneric
.
generalInvokerOf
(
form
.
erasedType
);
form
.
genericInvoker
=
gamh
;
return
gamh
;
}
catch
(
Exception
ex
)
{
throw
new
InternalError
(
"Exception while resolving inexact invoke"
,
ex
);
}
}
static
MemberName
linkToCallSiteMethod
(
MethodType
mtype
)
{
LambdaForm
lform
=
callSiteForm
(
mtype
);
return
lform
.
vmentry
;
}
private
static
LambdaForm
callSiteForm
(
MethodType
mtype
)
{
mtype
=
mtype
.
basicType
();
// normalize Z to I, String to Object, etc.
LambdaForm
lform
=
mtype
.
form
().
cachedLambdaForm
(
MethodTypeForm
.
LF_CS_LINKER
);
if
(
lform
!=
null
)
return
lform
;
// exactInvokerForm (Object,Object)Object
// link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
final
int
ARG_BASE
=
0
;
final
int
OUTARG_LIMIT
=
ARG_BASE
+
mtype
.
parameterCount
();
final
int
INARG_LIMIT
=
OUTARG_LIMIT
+
1
;
int
nameCursor
=
OUTARG_LIMIT
;
final
int
CSITE_ARG
=
nameCursor
++;
// the last in-argument
final
int
CALL_MH
=
nameCursor
++;
// result of getTarget
final
int
LINKER_CALL
=
nameCursor
++;
MethodType
invokerFormType
=
mtype
.
appendParameterTypes
(
CallSite
.
class
);
Name
[]
names
=
arguments
(
nameCursor
-
INARG_LIMIT
,
invokerFormType
);
assert
(
names
.
length
==
nameCursor
);
assert
(
names
[
CSITE_ARG
]
!=
null
);
names
[
CALL_MH
]
=
new
Name
(
NF_getCallSiteTarget
,
names
[
CSITE_ARG
]);
// (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*)
final
int
PREPEND_MH
=
0
,
PREPEND_COUNT
=
1
;
Object
[]
outArgs
=
Arrays
.
copyOfRange
(
names
,
ARG_BASE
,
OUTARG_LIMIT
+
PREPEND_COUNT
,
Object
[].
class
);
// prepend MH argument:
System
.
arraycopy
(
outArgs
,
0
,
outArgs
,
PREPEND_COUNT
,
outArgs
.
length
-
PREPEND_COUNT
);
outArgs
[
PREPEND_MH
]
=
names
[
CALL_MH
];
names
[
LINKER_CALL
]
=
new
Name
(
invokeBasicMethod
(
mtype
),
outArgs
);
lform
=
new
LambdaForm
(
"linkToCallSite"
,
INARG_LIMIT
,
names
);
lform
.
compileToBytecode
();
// JVM needs a real methodOop
lform
=
mtype
.
form
().
setCachedLambdaForm
(
MethodTypeForm
.
LF_CS_LINKER
,
lform
);
return
lform
;
}
/** Static definition of MethodHandle.invokeGeneric checking code. */
/*non-public*/
static
@ForceInline
Object
getCallSiteTarget
(
Object
site
)
{
return
((
CallSite
)
site
).
getTarget
();
}
// Local constant functions:
private
static
final
NamedFunction
NF_checkExactType
;
private
static
final
NamedFunction
NF_checkGenericType
;
private
static
final
NamedFunction
NF_getCallSiteTarget
;
static
{
try
{
NF_checkExactType
=
new
NamedFunction
(
Invokers
.
class
.
getDeclaredMethod
(
"checkExactType"
,
Object
.
class
,
Object
.
class
));
NF_checkGenericType
=
new
NamedFunction
(
Invokers
.
class
.
getDeclaredMethod
(
"checkGenericType"
,
Object
.
class
,
Object
.
class
));
NF_getCallSiteTarget
=
new
NamedFunction
(
Invokers
.
class
.
getDeclaredMethod
(
"getCallSiteTarget"
,
Object
.
class
));
NF_checkExactType
.
resolve
();
NF_checkGenericType
.
resolve
();
NF_getCallSiteTarget
.
resolve
();
// bound
}
catch
(
ReflectiveOperationException
ex
)
{
throw
new
InternalError
(
ex
);
}
}
}
}
src/share/classes/java/lang/invoke/LambdaForm.java
0 → 100644
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/MemberName.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/MethodHandle.java
浏览文件 @
361d5538
...
@@ -26,9 +26,13 @@
...
@@ -26,9 +26,13 @@
package
java.lang.invoke
;
package
java.lang.invoke
;
import
java.util.ArrayList
;
import
java.util.*
;
import
sun.invoke.util.ValueConversions
;
import
sun.invoke.util.*
;
import
sun.misc.Unsafe
;
import
static
java
.
lang
.
invoke
.
MethodHandleStatics
.*;
import
static
java
.
lang
.
invoke
.
MethodHandleStatics
.*;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
/**
/**
* A method handle is a typed, directly executable reference to an underlying method,
* A method handle is a typed, directly executable reference to an underlying method,
...
@@ -208,8 +212,8 @@ import static java.lang.invoke.MethodHandleStatics.*;
...
@@ -208,8 +212,8 @@ import static java.lang.invoke.MethodHandleStatics.*;
* refers directly to an associated {@code CONSTANT_Methodref},
* refers directly to an associated {@code CONSTANT_Methodref},
* {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
* {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
* constant pool entry.
* constant pool entry.
* (For
more
details on method handle constants,
* (For
full
details on method handle constants,
* see
the <a href="package-summary.html#mhcon">package summary</a>
.)
* see
sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification
.)
* <p>
* <p>
* Method handles produced by lookups or constant loads from methods or
* Method handles produced by lookups or constant loads from methods or
* constructors with the variable arity modifier bit ({@code 0x0080})
* constructors with the variable arity modifier bit ({@code 0x0080})
...
@@ -224,6 +228,19 @@ import static java.lang.invoke.MethodHandleStatics.*;
...
@@ -224,6 +228,19 @@ import static java.lang.invoke.MethodHandleStatics.*;
* (E.g., if a non-static method handle is obtained via {@code ldc},
* (E.g., if a non-static method handle is obtained via {@code ldc},
* the type of the receiver is the class named in the constant pool entry.)
* the type of the receiver is the class named in the constant pool entry.)
* <p>
* <p>
* Method handle constants are subject to the same link-time access checks
* their corresponding bytecode instructions, and the {@code ldc} instruction
* will throw corresponding linkage errors if the bytecode behaviors would
* throw such errors.
* <p>
* As a corollary of this, access to protected members is restricted
* to receivers only of the accessing class, or one of its subclasses,
* and the accessing class must in turn be a subclass (or package sibling)
* of the protected member's defining class.
* If a method reference refers to a protected non-static method or field
* of a class outside the current package, the receiver argument will
* be narrowed to the type of the accessing class.
* <p>
* When a method handle to a virtual method is invoked, the method is
* When a method handle to a virtual method is invoked, the method is
* always looked up in the receiver (that is, the first argument).
* always looked up in the receiver (that is, the first argument).
* <p>
* <p>
...
@@ -390,39 +407,8 @@ mh.invokeExact(System.out, "Hello, world.");
...
@@ -390,39 +407,8 @@ mh.invokeExact(System.out, "Hello, world.");
* @author John Rose, JSR 292 EG
* @author John Rose, JSR 292 EG
*/
*/
public
abstract
class
MethodHandle
{
public
abstract
class
MethodHandle
{
// { JVM internals:
private
byte
vmentry
;
// adapter stub or method entry point
//private int vmslots; // optionally, hoist type.form.vmslots
/*non-public*/
Object
vmtarget
;
// VM-specific, class-specific target value
// TO DO: vmtarget should be invisible to Java, since the JVM puts internal
// managed pointers into it. Making it visible exposes it to debuggers,
// which can cause errors when they treat the pointer as an Object.
// These two dummy fields are present to force 'I' and 'J' signatures
// into this class's constant pool, so they can be transferred
// to vmentry when this class is loaded.
static
final
int
INT_FIELD
=
0
;
static
final
long
LONG_FIELD
=
0
;
// vmentry (a void* field) is used *only* by the JVM.
// The JVM adjusts its type to int or long depending on system wordsize.
// Since it is statically typed as neither int nor long, it is impossible
// to use this field from Java bytecode. (Please don't try to, either.)
// The vmentry is an assembly-language stub which is jumped to
// immediately after the method type is verified.
// For a direct MH, this stub loads the vmtarget's entry point
// and jumps to it.
// } End of JVM internals.
static
{
MethodHandleImpl
.
initStatics
();
}
static
{
MethodHandleImpl
.
initStatics
();
}
// interface MethodHandle<R throws X extends Exception,A...>
// { MethodType<R throws X,A...> type(); public R invokeExact(A...) throws X; }
/**
/**
* Internal marker interface which distinguishes (to the Java compiler)
* Internal marker interface which distinguishes (to the Java compiler)
* those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
* those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
...
@@ -431,7 +417,9 @@ public abstract class MethodHandle {
...
@@ -431,7 +417,9 @@ public abstract class MethodHandle {
@java
.
lang
.
annotation
.
Retention
(
java
.
lang
.
annotation
.
RetentionPolicy
.
RUNTIME
)
@java
.
lang
.
annotation
.
Retention
(
java
.
lang
.
annotation
.
RetentionPolicy
.
RUNTIME
)
@interface
PolymorphicSignature
{
}
@interface
PolymorphicSignature
{
}
private
MethodType
type
;
private
final
MethodType
type
;
/*private*/
final
LambdaForm
form
;
// form is not private so that invokers can easily fetch it
/**
/**
* Reports the type of this method handle.
* Reports the type of this method handle.
...
@@ -448,9 +436,13 @@ public abstract class MethodHandle {
...
@@ -448,9 +436,13 @@ public abstract class MethodHandle {
* the {@code java.lang.invoke} package.
* the {@code java.lang.invoke} package.
*/
*/
// @param type type (permanently assigned) of the new method handle
// @param type type (permanently assigned) of the new method handle
/*non-public*/
MethodHandle
(
MethodType
type
)
{
/*non-public*/
MethodHandle
(
MethodType
type
,
LambdaForm
form
)
{
type
.
getClass
();
// elicit NPE
type
.
getClass
();
// explicit NPE
form
.
getClass
();
// explicit NPE
this
.
type
=
type
;
this
.
type
=
type
;
this
.
form
=
form
;
form
.
prepare
();
// TO DO: Try to delay this step until just before invocation.
}
}
/**
/**
...
@@ -505,6 +497,46 @@ public abstract class MethodHandle {
...
@@ -505,6 +497,46 @@ public abstract class MethodHandle {
*/
*/
public
final
native
@PolymorphicSignature
Object
invoke
(
Object
...
args
)
throws
Throwable
;
public
final
native
@PolymorphicSignature
Object
invoke
(
Object
...
args
)
throws
Throwable
;
/**
* Private method for trusted invocation of a method handle respecting simplified signatures.
* Type mismatches will not throw {@code WrongMethodTypeException}, but could crash the JVM.
* <p>
* The caller signature is restricted to the following basic types:
* Object, int, long, float, double, and void return.
* <p>
* The caller is responsible for maintaining type correctness by ensuring
* that the each outgoing argument value is a member of the range of the corresponding
* callee argument type.
* (The caller should therefore issue appropriate casts and integer narrowing
* operations on outgoing argument values.)
* The caller can assume that the incoming result value is part of the range
* of the callee's return type.
*/
/*non-public*/
final
native
@PolymorphicSignature
Object
invokeBasic
(
Object
...
args
)
throws
Throwable
;
/*non-public*/
static
native
@PolymorphicSignature
Object
linkToVirtual
(
Object
...
args
)
throws
Throwable
;
/**
* Private method for trusted invocation of a MemberName of kind {@code REF_invokeStatic}.
* The caller signature is restricted to basic types as with {@code invokeBasic}.
* The trailing (not leading) argument must be a MemberName.
*/
/*non-public*/
static
native
@PolymorphicSignature
Object
linkToStatic
(
Object
...
args
)
throws
Throwable
;
/**
* Private method for trusted invocation of a MemberName of kind {@code REF_invokeSpecial}.
* The caller signature is restricted to basic types as with {@code invokeBasic}.
* The trailing (not leading) argument must be a MemberName.
*/
/*non-public*/
static
native
@PolymorphicSignature
Object
linkToSpecial
(
Object
...
args
)
throws
Throwable
;
/**
* Private method for trusted invocation of a MemberName of kind {@code REF_invokeInterface}.
* The caller signature is restricted to basic types as with {@code invokeBasic}.
* The trailing (not leading) argument must be a MemberName.
*/
/*non-public*/
static
native
@PolymorphicSignature
Object
linkToInterface
(
Object
...
args
)
throws
Throwable
;
/**
/**
* Performs a variable arity invocation, passing the arguments in the given array
* Performs a variable arity invocation, passing the arguments in the given array
* to the method handle, as if via an inexact {@link #invoke invoke} from a call site
* to the method handle, as if via an inexact {@link #invoke invoke} from a call site
...
@@ -557,6 +589,7 @@ public abstract class MethodHandle {
...
@@ -557,6 +589,7 @@ public abstract class MethodHandle {
*/
*/
public
Object
invokeWithArguments
(
Object
...
arguments
)
throws
Throwable
{
public
Object
invokeWithArguments
(
Object
...
arguments
)
throws
Throwable
{
int
argc
=
arguments
==
null
?
0
:
arguments
.
length
;
int
argc
=
arguments
==
null
?
0
:
arguments
.
length
;
@SuppressWarnings
(
"LocalVariableHidesMemberVariable"
)
MethodType
type
=
type
();
MethodType
type
=
type
();
if
(
type
.
parameterCount
()
!=
argc
||
isVarargsCollector
())
{
if
(
type
.
parameterCount
()
!=
argc
||
isVarargsCollector
())
{
// simulate invoke
// simulate invoke
...
@@ -690,7 +723,7 @@ public abstract class MethodHandle {
...
@@ -690,7 +723,7 @@ public abstract class MethodHandle {
if
(!
type
.
isConvertibleTo
(
newType
))
{
if
(!
type
.
isConvertibleTo
(
newType
))
{
throw
new
WrongMethodTypeException
(
"cannot convert "
+
this
+
" to "
+
newType
);
throw
new
WrongMethodTypeException
(
"cannot convert "
+
this
+
" to "
+
newType
);
}
}
return
MethodHandleImpl
.
convertArguments
(
this
,
newType
,
1
);
return
convertArguments
(
newType
);
}
}
/**
/**
...
@@ -772,7 +805,8 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
...
@@ -772,7 +805,8 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
*/
*/
public
MethodHandle
asSpreader
(
Class
<?>
arrayType
,
int
arrayLength
)
{
public
MethodHandle
asSpreader
(
Class
<?>
arrayType
,
int
arrayLength
)
{
asSpreaderChecks
(
arrayType
,
arrayLength
);
asSpreaderChecks
(
arrayType
,
arrayLength
);
return
MethodHandleImpl
.
spreadArguments
(
this
,
arrayType
,
arrayLength
);
int
spreadArgPos
=
type
.
parameterCount
()
-
arrayLength
;
return
MethodHandleImpl
.
makeSpreadArguments
(
this
,
arrayType
,
spreadArgPos
,
arrayLength
);
}
}
private
void
asSpreaderChecks
(
Class
<?>
arrayType
,
int
arrayLength
)
{
private
void
asSpreaderChecks
(
Class
<?>
arrayType
,
int
arrayLength
)
{
...
@@ -790,7 +824,7 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
...
@@ -790,7 +824,7 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
}
}
}
}
if
(
sawProblem
)
{
if
(
sawProblem
)
{
ArrayList
<
Class
<?>>
ptypes
=
new
ArrayList
<
Class
<?>
>(
type
().
parameterList
());
ArrayList
<
Class
<?>>
ptypes
=
new
ArrayList
<>(
type
().
parameterList
());
for
(
int
i
=
nargs
-
arrayLength
;
i
<
nargs
;
i
++)
{
for
(
int
i
=
nargs
-
arrayLength
;
i
<
nargs
;
i
++)
{
ptypes
.
set
(
i
,
arrayElement
);
ptypes
.
set
(
i
,
arrayElement
);
}
}
...
@@ -885,8 +919,12 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
...
@@ -885,8 +919,12 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
*/
*/
public
MethodHandle
asCollector
(
Class
<?>
arrayType
,
int
arrayLength
)
{
public
MethodHandle
asCollector
(
Class
<?>
arrayType
,
int
arrayLength
)
{
asCollectorChecks
(
arrayType
,
arrayLength
);
asCollectorChecks
(
arrayType
,
arrayLength
);
int
collectArgPos
=
type
().
parameterCount
()-
1
;
MethodHandle
target
=
this
;
if
(
arrayType
!=
type
().
parameterType
(
collectArgPos
))
target
=
convertArguments
(
type
().
changeParameterType
(
collectArgPos
,
arrayType
));
MethodHandle
collector
=
ValueConversions
.
varargsArray
(
arrayType
,
arrayLength
);
MethodHandle
collector
=
ValueConversions
.
varargsArray
(
arrayType
,
arrayLength
);
return
MethodHandleImpl
.
collectArguments
(
this
,
type
.
parameterCount
()-
1
,
collector
);
return
MethodHandleImpl
.
makeCollectArguments
(
target
,
collector
,
collectArgPos
,
false
);
}
}
// private API: return true if last param exactly matches arrayType
// private API: return true if last param exactly matches arrayType
...
@@ -1056,7 +1094,7 @@ assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
...
@@ -1056,7 +1094,7 @@ assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
boolean
lastMatch
=
asCollectorChecks
(
arrayType
,
0
);
boolean
lastMatch
=
asCollectorChecks
(
arrayType
,
0
);
if
(
isVarargsCollector
()
&&
lastMatch
)
if
(
isVarargsCollector
()
&&
lastMatch
)
return
this
;
return
this
;
return
AdapterMethodHandle
.
makeVarargsCollector
(
this
,
arrayType
);
return
MethodHandleImpl
.
makeVarargsCollector
(
this
,
arrayType
);
}
}
/**
/**
...
@@ -1155,14 +1193,13 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
...
@@ -1155,14 +1193,13 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
*/
*/
public
MethodHandle
bindTo
(
Object
x
)
{
public
MethodHandle
bindTo
(
Object
x
)
{
Class
<?>
ptype
;
Class
<?>
ptype
;
if
(
type
().
parameterCount
()
==
0
||
@SuppressWarnings
(
"LocalVariableHidesMemberVariable"
)
(
ptype
=
type
().
parameterType
(
0
)).
isPrimitive
())
MethodType
type
=
type
();
if
(
type
.
parameterCount
()
==
0
||
(
ptype
=
type
.
parameterType
(
0
)).
isPrimitive
())
throw
newIllegalArgumentException
(
"no leading reference parameter"
,
x
);
throw
newIllegalArgumentException
(
"no leading reference parameter"
,
x
);
x
=
MethodHandles
.
checkValue
(
ptype
,
x
);
x
=
ptype
.
cast
(
x
);
// throw CCE if needed
// Cf. MethodHandles.insertArguments for the following logic:
return
bindReceiver
(
x
);
MethodHandle
bmh
=
MethodHandleImpl
.
bindReceiver
(
this
,
x
);
if
(
bmh
!=
null
)
return
bmh
;
return
MethodHandleImpl
.
bindArgument
(
this
,
0
,
x
);
}
}
/**
/**
...
@@ -1183,11 +1220,178 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
...
@@ -1183,11 +1220,178 @@ 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
debugString
();
return
standardString
();
}
String
standardString
()
{
return
"MethodHandle"
+
type
;
return
"MethodHandle"
+
type
;
}
}
String
debugString
()
{
return
standardString
()+
"="
+
internalForm
()+
internalValues
();
}
//// Implementation methods.
//// Sub-classes can override these default implementations.
//// All these methods assume arguments are already validated.
// Other transforms to do: convert, explicitCast, permute, drop, filter, fold, GWT, catch
/*non-public*/
/*non-public*/
String
debugString
()
{
MethodHandle
setVarargs
(
MemberName
member
)
throws
IllegalAccessException
{
return
getNameString
(
this
);
if
(!
member
.
isVarargs
())
return
this
;
int
argc
=
type
().
parameterCount
();
if
(
argc
!=
0
)
{
Class
<?>
arrayType
=
type
().
parameterType
(
argc
-
1
);
if
(
arrayType
.
isArray
())
{
return
MethodHandleImpl
.
makeVarargsCollector
(
this
,
arrayType
);
}
}
throw
member
.
makeAccessException
(
"cannot make variable arity"
,
null
);
}
/*non-public*/
MethodHandle
viewAsType
(
MethodType
newType
)
{
// No actual conversions, just a new view of the same method.
if
(!
type
.
isViewableAs
(
newType
))
throw
new
InternalError
();
return
MethodHandleImpl
.
makePairwiseConvert
(
this
,
newType
,
0
);
}
// Decoding
/*non-public*/
LambdaForm
internalForm
()
{
return
form
;
}
/*non-public*/
MemberName
internalMemberName
()
{
return
null
;
// DMH returns DMH.member
}
/*non-public*/
Object
internalValues
()
{
return
""
;
}
//// Method handle implementation methods.
//// Sub-classes can override these default implementations.
//// All these methods assume arguments are already validated.
/*non-public*/
MethodHandle
convertArguments
(
MethodType
newType
)
{
// Override this if it can be improved.
return
MethodHandleImpl
.
makePairwiseConvert
(
this
,
newType
,
1
);
}
/*non-public*/
MethodHandle
bindArgument
(
int
pos
,
char
basicType
,
Object
value
)
{
// Override this if it can be improved.
return
rebind
().
bindArgument
(
pos
,
basicType
,
value
);
}
/*non-public*/
MethodHandle
bindReceiver
(
Object
receiver
)
{
// Override this if it can be improved.
return
bindArgument
(
0
,
'L'
,
receiver
);
}
/*non-public*/
MethodHandle
bindImmediate
(
int
pos
,
char
basicType
,
Object
value
)
{
// Bind an immediate value to a position in the arguments.
// This means, elide the respective argument,
// and replace all references to it in NamedFunction args with the specified value.
// CURRENT RESTRICTIONS
// * only for pos 0 and UNSAFE (position is adjusted in MHImpl to make API usable for others)
assert
pos
==
0
&&
basicType
==
'L'
&&
value
instanceof
Unsafe
;
MethodType
type2
=
type
.
dropParameterTypes
(
pos
,
pos
+
1
);
// adjustment: ignore receiver!
LambdaForm
form2
=
form
.
bindImmediate
(
pos
+
1
,
basicType
,
value
);
// adjust pos to form-relative pos
return
copyWith
(
type2
,
form2
);
}
/*non-public*/
MethodHandle
copyWith
(
MethodType
mt
,
LambdaForm
lf
)
{
throw
new
InternalError
(
"copyWith: "
+
this
.
getClass
());
}
/*non-public*/
MethodHandle
dropArguments
(
MethodType
srcType
,
int
pos
,
int
drops
)
{
// Override this if it can be improved.
return
rebind
().
dropArguments
(
srcType
,
pos
,
drops
);
}
/*non-public*/
MethodHandle
permuteArguments
(
MethodType
newType
,
int
[]
reorder
)
{
// Override this if it can be improved.
return
rebind
().
permuteArguments
(
newType
,
reorder
);
}
/*non-public*/
MethodHandle
rebind
()
{
// Bind 'this' into a new invoker, of the known class BMH.
MethodType
type2
=
type
();
LambdaForm
form2
=
reinvokerForm
(
type2
.
basicType
());
// form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }
return
BoundMethodHandle
.
bindSingle
(
type2
,
form2
,
this
);
}
/*non-public*/
MethodHandle
reinvokerTarget
()
{
throw
new
InternalError
(
"not a reinvoker MH: "
+
this
.
getClass
().
getName
()+
": "
+
this
);
}
/** Create a LF which simply reinvokes a target of the given basic type.
* The target MH must override {@link #reinvokerTarget} to provide the target.
*/
static
LambdaForm
reinvokerForm
(
MethodType
mtype
)
{
mtype
=
mtype
.
basicType
();
LambdaForm
reinvoker
=
mtype
.
form
().
cachedLambdaForm
(
MethodTypeForm
.
LF_REINVOKE
);
if
(
reinvoker
!=
null
)
return
reinvoker
;
MethodHandle
MH_invokeBasic
=
MethodHandles
.
basicInvoker
(
mtype
);
final
int
THIS_BMH
=
0
;
final
int
ARG_BASE
=
1
;
final
int
ARG_LIMIT
=
ARG_BASE
+
mtype
.
parameterCount
();
int
nameCursor
=
ARG_LIMIT
;
final
int
NEXT_MH
=
nameCursor
++;
final
int
REINVOKE
=
nameCursor
++;
LambdaForm
.
Name
[]
names
=
LambdaForm
.
arguments
(
nameCursor
-
ARG_LIMIT
,
mtype
.
invokerType
());
names
[
NEXT_MH
]
=
new
LambdaForm
.
Name
(
NF_reinvokerTarget
,
names
[
THIS_BMH
]);
Object
[]
targetArgs
=
Arrays
.
copyOfRange
(
names
,
THIS_BMH
,
ARG_LIMIT
,
Object
[].
class
);
targetArgs
[
0
]
=
names
[
NEXT_MH
];
// overwrite this MH with next MH
names
[
REINVOKE
]
=
new
LambdaForm
.
Name
(
MH_invokeBasic
,
targetArgs
);
return
mtype
.
form
().
setCachedLambdaForm
(
MethodTypeForm
.
LF_REINVOKE
,
new
LambdaForm
(
"BMH.reinvoke"
,
ARG_LIMIT
,
names
));
}
private
static
final
LambdaForm
.
NamedFunction
NF_reinvokerTarget
;
static
{
try
{
NF_reinvokerTarget
=
new
LambdaForm
.
NamedFunction
(
MethodHandle
.
class
.
getDeclaredMethod
(
"reinvokerTarget"
));
}
catch
(
ReflectiveOperationException
ex
)
{
throw
new
InternalError
(
ex
);
}
}
/**
* Replace the old lambda form of this method handle with a new one.
* The new one must be functionally equivalent to the old one.
* Threads may continue running the old form indefinitely,
* but it is likely that the new one will be preferred for new executions.
* Use with discretion.
* @param newForm
*/
/*non-public*/
void
updateForm
(
LambdaForm
newForm
)
{
if
(
form
==
newForm
)
return
;
// ISSUE: Should we have a memory fence here?
UNSAFE
.
putObject
(
this
,
FORM_OFFSET
,
newForm
);
this
.
form
.
prepare
();
// as in MethodHandle.<init>
}
private
static
final
long
FORM_OFFSET
;
static
{
try
{
FORM_OFFSET
=
UNSAFE
.
objectFieldOffset
(
MethodHandle
.
class
.
getDeclaredField
(
"form"
));
}
catch
(
ReflectiveOperationException
ex
)
{
throw
new
InternalError
(
ex
);
}
}
}
}
}
src/share/classes/java/lang/invoke/MethodHandleImpl.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/MethodHandleInfo.java
0 → 100644
浏览文件 @
361d5538
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
java.lang.invoke
;
import
java.lang.invoke.MethodHandleNatives.Constants
;
//Not yet public: public
class
MethodHandleInfo
{
public
static
final
int
REF_NONE
=
Constants
.
REF_NONE
,
REF_getField
=
Constants
.
REF_getField
,
REF_getStatic
=
Constants
.
REF_getStatic
,
REF_putField
=
Constants
.
REF_putField
,
REF_putStatic
=
Constants
.
REF_putStatic
,
REF_invokeVirtual
=
Constants
.
REF_invokeVirtual
,
REF_invokeStatic
=
Constants
.
REF_invokeStatic
,
REF_invokeSpecial
=
Constants
.
REF_invokeSpecial
,
REF_newInvokeSpecial
=
Constants
.
REF_newInvokeSpecial
,
REF_invokeInterface
=
Constants
.
REF_invokeInterface
;
private
final
Class
<?>
declaringClass
;
private
final
String
name
;
private
final
MethodType
methodType
;
private
final
int
referenceKind
;
public
MethodHandleInfo
(
MethodHandle
mh
)
throws
ReflectiveOperationException
{
MemberName
mn
=
mh
.
internalMemberName
();
this
.
declaringClass
=
mn
.
getDeclaringClass
();
this
.
name
=
mn
.
getName
();
this
.
methodType
=
mn
.
getMethodType
();
this
.
referenceKind
=
mn
.
getReferenceKind
();
}
public
Class
<?>
getDeclaringClass
()
{
return
declaringClass
;
}
public
String
getName
()
{
return
name
;
}
public
MethodType
getMethodType
()
{
return
methodType
;
}
public
int
getReferenceKind
()
{
return
referenceKind
;
}
}
src/share/classes/java/lang/invoke/MethodHandleNatives.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/MethodHandleStatics.java
浏览文件 @
361d5538
...
@@ -27,6 +27,7 @@ package java.lang.invoke;
...
@@ -27,6 +27,7 @@ package java.lang.invoke;
import
java.security.AccessController
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
import
java.security.PrivilegedAction
;
import
sun.misc.Unsafe
;
/**
/**
* This class consists exclusively of static names internal to the
* This class consists exclusively of static names internal to the
...
@@ -38,16 +39,30 @@ import java.security.PrivilegedAction;
...
@@ -38,16 +39,30 @@ import java.security.PrivilegedAction;
private
MethodHandleStatics
()
{
}
// do not instantiate
private
MethodHandleStatics
()
{
}
// do not instantiate
static
final
Unsafe
UNSAFE
=
Unsafe
.
getUnsafe
();
static
final
boolean
DEBUG_METHOD_HANDLE_NAMES
;
static
final
boolean
DEBUG_METHOD_HANDLE_NAMES
;
static
final
boolean
DUMP_CLASS_FILES
;
static
final
boolean
TRACE_INTERPRETER
;
static
final
boolean
TRACE_METHOD_LINKAGE
;
static
final
Integer
COMPILE_THRESHOLD
;
static
{
static
{
final
Object
[]
values
=
{
false
};
final
Object
[]
values
=
{
false
,
false
,
false
,
false
,
null
};
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Void
>()
{
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
public
Void
run
()
{
values
[
0
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.DEBUG_NAMES"
);
values
[
0
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.DEBUG_NAMES"
);
values
[
1
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.DUMP_CLASS_FILES"
);
values
[
2
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.TRACE_INTERPRETER"
);
values
[
3
]
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"
);
values
[
4
]
=
Integer
.
getInteger
(
"java.lang.invoke.MethodHandle.COMPILE_THRESHOLD"
);
return
null
;
return
null
;
}
}
});
});
DEBUG_METHOD_HANDLE_NAMES
=
(
Boolean
)
values
[
0
];
DEBUG_METHOD_HANDLE_NAMES
=
(
Boolean
)
values
[
0
];
DUMP_CLASS_FILES
=
(
Boolean
)
values
[
1
];
TRACE_INTERPRETER
=
(
Boolean
)
values
[
2
];
TRACE_METHOD_LINKAGE
=
(
Boolean
)
values
[
3
];
COMPILE_THRESHOLD
=
(
Integer
)
values
[
4
];
}
}
/*non-public*/
static
String
getNameString
(
MethodHandle
target
,
MethodType
type
)
{
/*non-public*/
static
String
getNameString
(
MethodHandle
target
,
MethodType
type
)
{
...
@@ -55,7 +70,7 @@ import java.security.PrivilegedAction;
...
@@ -55,7 +70,7 @@ import java.security.PrivilegedAction;
type
=
target
.
type
();
type
=
target
.
type
();
MemberName
name
=
null
;
MemberName
name
=
null
;
if
(
target
!=
null
)
if
(
target
!=
null
)
name
=
MethodHandleNatives
.
getMethodName
(
target
);
name
=
target
.
internalMemberName
(
);
if
(
name
==
null
)
if
(
name
==
null
)
return
"invoke"
+
type
;
return
"invoke"
+
type
;
return
name
.
getName
()
+
type
;
return
name
.
getName
()
+
type
;
...
@@ -77,20 +92,6 @@ import java.security.PrivilegedAction;
...
@@ -77,20 +92,6 @@ import java.security.PrivilegedAction;
return
str
+
target
.
type
();
return
str
+
target
.
type
();
}
}
static
void
checkSpreadArgument
(
Object
av
,
int
n
)
{
if
(
av
==
null
)
{
if
(
n
==
0
)
return
;
}
else
if
(
av
instanceof
Object
[])
{
int
len
=
((
Object
[])
av
).
length
;
if
(
len
==
n
)
return
;
}
else
{
int
len
=
java
.
lang
.
reflect
.
Array
.
getLength
(
av
);
if
(
len
==
n
)
return
;
}
// fall through to error:
throw
newIllegalArgumentException
(
"Array is not of length "
+
n
);
}
// handy shared exception makers (they simplify the common case code)
// handy shared exception makers (they simplify the common case code)
/*non-public*/
static
RuntimeException
newIllegalStateException
(
String
message
)
{
/*non-public*/
static
RuntimeException
newIllegalStateException
(
String
message
)
{
return
new
IllegalStateException
(
message
);
return
new
IllegalStateException
(
message
);
...
@@ -110,6 +111,9 @@ import java.security.PrivilegedAction;
...
@@ -110,6 +111,9 @@ import java.security.PrivilegedAction;
/*non-public*/
static
Error
uncaughtException
(
Exception
ex
)
{
/*non-public*/
static
Error
uncaughtException
(
Exception
ex
)
{
throw
new
InternalError
(
"uncaught exception"
,
ex
);
throw
new
InternalError
(
"uncaught exception"
,
ex
);
}
}
static
Error
NYI
()
{
throw
new
AssertionError
(
"NYI"
);
}
private
static
String
message
(
String
message
,
Object
obj
)
{
private
static
String
message
(
String
message
,
Object
obj
)
{
if
(
obj
!=
null
)
message
=
message
+
": "
+
obj
;
if
(
obj
!=
null
)
message
=
message
+
": "
+
obj
;
return
message
;
return
message
;
...
...
src/share/classes/java/lang/invoke/MethodHandles.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/MethodType.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/MethodTypeForm.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/SimpleMethodHandle.java
0 → 100644
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/package-info.java
浏览文件 @
361d5538
...
@@ -191,6 +191,13 @@
...
@@ -191,6 +191,13 @@
* (If a string constant were passed instead, by badly generated code, that cast would then fail,
* (If a string constant were passed instead, by badly generated code, that cast would then fail,
* resulting in a {@code BootstrapMethodError}.)
* resulting in a {@code BootstrapMethodError}.)
* <p>
* <p>
* Note that, as a consequence of the above rules, the bootstrap method may accept a primitive
* argument, if it can be represented by a constant pool entry.
* However, arguments of type {@code boolean}, {@code byte}, {@code short}, or {@code char}
* cannot be created for bootstrap methods, since such constants cannot be directly
* represented in the constant pool, and the invocation of the bootstrap method will
* not perform the necessary narrowing primitive conversions.
* <p>
* Extra bootstrap method arguments are intended to allow language implementors
* Extra bootstrap method arguments are intended to allow language implementors
* to safely and compactly encode metadata.
* to safely and compactly encode metadata.
* In principle, the name and extra arguments are redundant,
* In principle, the name and extra arguments are redundant,
...
...
src/share/classes/sun/invoke/util/ValueConversions.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/sun/invoke/util/VerifyAccess.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/sun/invoke/util/VerifyType.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/sun/invoke/util/Wrapper.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
src/share/classes/sun/misc/Unsafe.java
浏览文件 @
361d5538
...
@@ -677,6 +677,14 @@ public final class Unsafe {
...
@@ -677,6 +677,14 @@ public final class Unsafe {
*/
*/
public
native
Object
staticFieldBase
(
Field
f
);
public
native
Object
staticFieldBase
(
Field
f
);
/**
* Detect if the given class may need to be initialized. This is often
* needed in conjunction with obtaining the static field base of a
* class.
* @return false only if a call to {@code ensureClassInitialized} would have no effect
*/
public
native
boolean
shouldBeInitialized
(
Class
<?>
c
);
/**
/**
* Ensure the given class has been initialized. This is often
* Ensure the given class has been initialized. This is often
* needed in conjunction with obtaining the static field base of a
* needed in conjunction with obtaining the static field base of a
...
...
src/share/classes/sun/util/resources/es/CurrencyNames_es_VE.properties
浏览文件 @
361d5538
...
@@ -36,5 +36,5 @@
...
@@ -36,5 +36,5 @@
# Taligent is a registered trademark of Taligent, Inc.
# Taligent is a registered trademark of Taligent, Inc.
VEB
=
Bs
VEB
=
Bs
VEF
=
BsF.
VEF
=
Bs
.
F.
test/java/lang/invoke/7157574/Test7157574.java
0 → 100644
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
test/java/lang/invoke/InvokeGenericTest.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
test/java/lang/invoke/JavaDocExamplesTest.java
浏览文件 @
361d5538
...
@@ -54,7 +54,6 @@ import static org.junit.Assert.*;
...
@@ -54,7 +54,6 @@ import static org.junit.Assert.*;
/**
/**
* @author jrose
* @author jrose
*/
*/
@SuppressWarnings
(
"LocalVariableHidesMemberVariable"
)
public
class
JavaDocExamplesTest
{
public
class
JavaDocExamplesTest
{
/** Wrapper for running the JUnit tests in this module.
/** Wrapper for running the JUnit tests in this module.
* Put JUnit on the classpath!
* Put JUnit on the classpath!
...
...
test/java/lang/invoke/MaxTest.java
0 → 100644
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
test/java/lang/invoke/MethodHandlesTest.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
test/java/lang/invoke/PrivateInvokeTest.java
0 → 100644
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
test/java/lang/invoke/ThrowExceptionsTest.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
test/java/lang/invoke/remote/RemoteExample.java
0 → 100644
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
test/sun/invoke/util/ValueConversionsTest.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
test/sun/text/resources/LocaleData
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
test/sun/text/resources/LocaleDataTest.java
浏览文件 @
361d5538
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录