Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
4a61e19d
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4a61e19d
编写于
1月 13, 2010
作者:
J
jcoomes
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
a2c10ef9
d348896f
变更
31
展开全部
隐藏空白更改
内联
并排
Showing
31 changed file
with
10375 addition
and
1474 deletion
+10375
-1474
jdk/src/share/classes/java/dyn/CallSite.java
jdk/src/share/classes/java/dyn/CallSite.java
+38
-15
jdk/src/share/classes/java/dyn/InvokeDynamic.java
jdk/src/share/classes/java/dyn/InvokeDynamic.java
+18
-0
jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
...c/share/classes/java/dyn/InvokeDynamicBootstrapError.java
+12
-0
jdk/src/share/classes/java/dyn/JavaMethodHandle.java
jdk/src/share/classes/java/dyn/JavaMethodHandle.java
+168
-17
jdk/src/share/classes/java/dyn/Linkage.java
jdk/src/share/classes/java/dyn/Linkage.java
+22
-13
jdk/src/share/classes/java/dyn/LinkagePermission.java
jdk/src/share/classes/java/dyn/LinkagePermission.java
+1
-1
jdk/src/share/classes/java/dyn/MethodHandle.java
jdk/src/share/classes/java/dyn/MethodHandle.java
+441
-6
jdk/src/share/classes/java/dyn/MethodHandles.java
jdk/src/share/classes/java/dyn/MethodHandles.java
+541
-299
jdk/src/share/classes/java/dyn/MethodType.java
jdk/src/share/classes/java/dyn/MethodType.java
+151
-48
jdk/src/share/classes/java/dyn/package-info.java
jdk/src/share/classes/java/dyn/package-info.java
+1
-0
jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java
jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java
+267
-77
jdk/src/share/classes/sun/dyn/BoundMethodHandle.java
jdk/src/share/classes/sun/dyn/BoundMethodHandle.java
+95
-30
jdk/src/share/classes/sun/dyn/CallSiteImpl.java
jdk/src/share/classes/sun/dyn/CallSiteImpl.java
+48
-16
jdk/src/share/classes/sun/dyn/FilterGeneric.java
jdk/src/share/classes/sun/dyn/FilterGeneric.java
+4332
-170
jdk/src/share/classes/sun/dyn/FilterOneArgument.java
jdk/src/share/classes/sun/dyn/FilterOneArgument.java
+11
-11
jdk/src/share/classes/sun/dyn/FromGeneric.java
jdk/src/share/classes/sun/dyn/FromGeneric.java
+79
-74
jdk/src/share/classes/sun/dyn/Invokers.java
jdk/src/share/classes/sun/dyn/Invokers.java
+13
-3
jdk/src/share/classes/sun/dyn/MemberName.java
jdk/src/share/classes/sun/dyn/MemberName.java
+21
-14
jdk/src/share/classes/sun/dyn/MethodHandleImpl.java
jdk/src/share/classes/sun/dyn/MethodHandleImpl.java
+807
-71
jdk/src/share/classes/sun/dyn/MethodHandleNatives.java
jdk/src/share/classes/sun/dyn/MethodHandleNatives.java
+21
-18
jdk/src/share/classes/sun/dyn/MethodTypeImpl.java
jdk/src/share/classes/sun/dyn/MethodTypeImpl.java
+6
-5
jdk/src/share/classes/sun/dyn/SpreadGeneric.java
jdk/src/share/classes/sun/dyn/SpreadGeneric.java
+682
-0
jdk/src/share/classes/sun/dyn/ToGeneric.java
jdk/src/share/classes/sun/dyn/ToGeneric.java
+446
-419
jdk/src/share/classes/sun/dyn/empty/Empty.java
jdk/src/share/classes/sun/dyn/empty/Empty.java
+4
-0
jdk/src/share/classes/sun/dyn/util/BytecodeDescriptor.java
jdk/src/share/classes/sun/dyn/util/BytecodeDescriptor.java
+2
-2
jdk/src/share/classes/sun/dyn/util/BytecodeName.java
jdk/src/share/classes/sun/dyn/util/BytecodeName.java
+34
-118
jdk/src/share/classes/sun/dyn/util/ValueConversions.java
jdk/src/share/classes/sun/dyn/util/ValueConversions.java
+179
-20
jdk/src/share/classes/sun/dyn/util/VerifyAccess.java
jdk/src/share/classes/sun/dyn/util/VerifyAccess.java
+43
-5
jdk/src/share/classes/sun/dyn/util/VerifyType.java
jdk/src/share/classes/sun/dyn/util/VerifyType.java
+19
-14
jdk/src/share/classes/sun/dyn/util/Wrapper.java
jdk/src/share/classes/sun/dyn/util/Wrapper.java
+34
-8
jdk/test/java/dyn/MethodHandlesTest.java
jdk/test/java/dyn/MethodHandlesTest.java
+1839
-0
未找到文件。
jdk/src/share/classes/java/dyn/CallSite.java
浏览文件 @
4a61e19d
...
...
@@ -26,6 +26,9 @@
package
java.dyn
;
import
sun.dyn.util.BytecodeName
;
import
sun.dyn.Access
;
import
sun.dyn.CallSiteImpl
;
import
sun.dyn.MethodHandleImpl
;
/**
* An {@code invokedynamic} call site, as reified by the
...
...
@@ -52,15 +55,25 @@ import sun.dyn.util.BytecodeName;
* @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
* @author John Rose, JSR 292 EG
*/
public
class
CallSite
{
public
class
CallSite
// Note: This is an implementation inheritance hack, and will be removed
// with a JVM change which moves the required hidden state onto this class.
extends
CallSiteImpl
{
private
static
final
Access
IMPL_TOKEN
=
Access
.
getToken
();
/*
// Fields used only by the JVM. Do not use or change.
private Object vmmethod;
int callerMID, callerBCI; // supplied by the JVM
MethodHandle
target
;
private MethodHandle target;
final Object caller; // usually a class
final String name;
final MethodType type;
*/
/**
* Make a call site given the parameters from a call to the bootstrap method.
...
...
@@ -72,16 +85,21 @@ public class CallSite {
* @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
*/
public
CallSite
(
Object
caller
,
String
name
,
MethodType
type
)
{
this
.
caller
=
caller
;
this
.
name
=
name
;
this
.
type
=
type
;
super
(
IMPL_TOKEN
,
caller
,
name
,
type
);
}
private
static
void
privateInitializeCallSite
(
CallSite
site
,
int
callerMID
,
int
callerBCI
)
{
site
.
callerMID
=
callerMID
;
site
.
callerBCI
=
callerBCI
;
if
(
site
.
target
==
null
)
site
.
setTarget
(
site
.
initialTarget
());
site
.
ensureTarget
();
}
private
void
ensureTarget
()
{
// Note use of super, which accesses the field directly,
// without deferring to possible subclass overrides.
if
(
super
.
getTarget
()
==
null
)
{
super
.
setTarget
(
this
.
initialTarget
());
super
.
getTarget
().
type
();
// provoke NPE if still null
}
}
/**
...
...
@@ -102,10 +120,11 @@ public class CallSite {
/**
* Report the current linkage state of the call site. (This is mutable.)
* The value maybe null only if the call site is currently unlinked.
* When a linked call site is invoked, the target method is used directly.
* When an unlinked call site is invoked, its bootstrap method receives
* the call, as if via {@link Linkage#bootstrapInvokeDynamic}.
* The value may not be null after the {@code CallSite} object is returned
* from the bootstrap method of the {@code invokedynamic} instruction.
* When an {@code invokedynamic} instruction is executed, the target method
* of its associated {@code call site} object is invoked directly,
* as if via {@link MethodHandle}{@code .invoke}.
* <p>
* The interactions of {@code getTarget} with memory are the same
* as of a read from an ordinary variable, such as an array element or a
...
...
@@ -118,7 +137,7 @@ public class CallSite {
* @see #setTarget
*/
public
MethodHandle
getTarget
()
{
return
target
;
return
super
.
getTarget
()
;
}
/**
...
...
@@ -140,13 +159,13 @@ public class CallSite {
*/
public
void
setTarget
(
MethodHandle
target
)
{
checkTarget
(
target
);
this
.
target
=
target
;
super
.
setTarget
(
target
)
;
}
protected
void
checkTarget
(
MethodHandle
target
)
{
target
.
type
();
// provoke NPE
if
(!
canSetTarget
(
target
))
throw
new
WrongMethodTypeException
(
String
.
valueOf
(
target
));
throw
new
WrongMethodTypeException
(
String
.
valueOf
(
target
)
+
target
.
type
()+
" should be of type "
+
type
()
);
}
protected
boolean
canSetTarget
(
MethodHandle
target
)
{
...
...
@@ -219,6 +238,10 @@ public class CallSite {
@Override
public
String
toString
()
{
return
"CallSite#"
+
hashCode
()+
"["
+
name
+
type
+
" => "
+
target
+
"]"
;
return
"CallSite#"
+
hashCode
()+
"["
+
name
+
type
+
" => "
+
getTarget
()
+
"]"
;
}
// Package-local constant:
static
final
MethodHandle
GET_TARGET
=
MethodHandleImpl
.
getLookup
(
IMPL_TOKEN
).
findVirtual
(
CallSite
.
class
,
"getTarget"
,
MethodType
.
methodType
(
MethodHandle
.
class
));
}
jdk/src/share/classes/java/dyn/InvokeDynamic.java
浏览文件 @
4a61e19d
...
...
@@ -45,6 +45,24 @@ package java.dyn;
* class or interface supertype, or an object type; it can never be instantiated.
* Logically, it denotes a source of all dynamically typed methods.
* It may be viewed as a pure syntactic marker (an importable one) of static calls.
* <p>
* Here are some examples of usage:
* <p><blockquote><pre>
* Object x; String s; int i;
* x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
* s = InvokeDynamic.<String>hail(x); // hail(Ljava/lang/Object;)Ljava/lang/String;
* InvokeDynamic.<void>cogito(); // cogito()V
* i = InvokeDynamic.<int>#"op:+"(2, 3); // "op:+"(II)I
* </pre></blockquote>
* Each of the above calls generates a single invokedynamic instruction
* with the name-and-type descriptors indicated in the comments.
* The argument types are taken directly from the actual arguments,
* while the return type is taken from the type parameter.
* (This type parameter may be a primtive, and it defaults to {@code Object}.)
* The final example uses a special syntax for uttering non-Java names.
* Any name legal to the JVM may be given between the double quotes.
* None of these calls is complete without a bootstrap method,
* which must be registered by the static initializer of the enclosing class.
* @author John Rose, JSR 292 EG
*/
public
final
class
InvokeDynamic
{
...
...
jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
浏览文件 @
4a61e19d
...
...
@@ -52,4 +52,16 @@ public class InvokeDynamicBootstrapError extends LinkageError {
public
InvokeDynamicBootstrapError
(
String
s
)
{
super
(
s
);
}
/**
* Constructs a {@code InvokeDynamicBootstrapError} with the specified
* detail message and cause.
*
* @param s the detail message.
* @param cause the cause.
*/
public
InvokeDynamicBootstrapError
(
String
s
,
Throwable
cause
)
{
super
(
s
);
this
.
initCause
(
cause
);
}
}
jdk/src/share/classes/java/dyn/JavaMethodHandle.java
浏览文件 @
4a61e19d
...
...
@@ -25,6 +25,8 @@
package
java.dyn
;
import
sun.dyn.Access
;
/**
* A Java method handle extends the basic method handle type with additional
* programmer defined methods and fields.
...
...
@@ -39,31 +41,105 @@ package java.dyn;
* of the entry point method handle, with the leading parameter type
* omitted.
* <p>
* Here is an example of usage:
* Here is an example of usage, creating a hybrid object/functional datum:
* <p><blockquote><pre>
* class Greeter extends JavaMethodHandle {
* private String greeting = "hello";
* public void setGreeting(String s) { greeting = s; }
* public void run() { System.out.println(greeting+", "+greetee); }
* private final String greetee;
* Greeter(String greetee) {
* super(RUN); // alternatively, super("run")
* this.greetee = greetee;
* }
* // the entry point function is computed once:
* private static final MethodHandle RUN
* = MethodHandles.lookup().findVirtual(Greeter.class, "run",
* MethodType.make(void.class));
* }
* // class Main { public static void main(String... av) { ...
* Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world"
* // Statically typed method handle invocation (most direct):
* MethodHandle mh = greeter;
* mh.<void>invoke(); // also prints "hello, world"
* // Dynamically typed method handle invocation:
* MethodHandles.invoke(greeter); // also prints "hello, world"
* greeter.setGreeting("howdy");
* mh.invoke(); // prints "howdy, world" (object-like mutable behavior)
* </pre></blockquote>
* <p>
* In the example of {@code Greeter}, the method {@code run} provides the entry point.
* The entry point need not be a constant value; it may be independently
* computed in each call to the constructor. The entry point does not
* even need to be a method on the {@code Greeter} class, though
* that is the typical case.
* <p>
* The entry point may also be provided symbolically, in which case the the
* {@code JavaMethodHandle} constructor performs the lookup of the entry point.
* This makes it possible to use {@code JavaMethodHandle} to create an anonymous
* inner class:
* <p><blockquote><pre>
* class Greeter extends JavaMethodHandle {
* // We can also do this with symbolic names and/or inner classes:
* MethodHandles.invoke(new JavaMethodHandle("yow") {
* void yow() { System.out.println("yow, world"); }
* });
* </pre></blockquote>
* <p>
* Here is similar lower-level code which works in terms of a bound method handle.
* <p><blockquote><pre>
* class Greeter {
* public void run() { System.out.println("hello, "+greetee); }
* private final String greetee;
* Greeter(String greetee) {
* super(RUN);
* this.greetee = greetee;
* }
* Greeter(String greetee) { this.greetee = greetee; }
* // the entry point function is computed once:
* private static final MethodHandle RUN
* = MethodHandles.findVirtual(
MyMethodHandle
.class, "run",
* = MethodHandles.findVirtual(
Greeter
.class, "run",
* MethodType.make(void.class));
* }
* // class Main { public static void main(String... av) { ...
* Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world"
* MethodHandle mh =
greeter
;
* MethodHandle mh =
MethodHanndles.insertArgument(Greeter.RUN, 0, greeter)
;
* mh.invoke(); // also prints "hello, world"
* </pre></blockquote>
* Note that the method handle must be separately created as a view on the base object.
* This increases footprint, complexity, and dynamic indirections.
* <p>
* In this example, the method {@code run} provides the entry point.
* The entry point need not be a constant value; it may be independently
* computed in each call to the constructor. The entry point does not
* even need to be a method on the Java method handle class, though
* that is the typical case.
* Here is a pure functional value expressed most concisely as an anonymous inner class:
* <p><blockquote><pre>
* // class Main { public static void main(String... av) { ...
* final String greetee = "world";
* MethodHandle greeter = new JavaMethodHandle("run") {
* private void run() { System.out.println("hello, "+greetee); }
* }
* greeter.invoke(); // prints "hello, world"
* </pre></blockquote>
* <p>
* Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
* and instantiated as an anonymous class. The data structure is a handle to 1-D array,
* with a specialized index type (long). It is created by inner class, and uses
* signature-polymorphic APIs throughout.
* <p><blockquote><pre>
* abstract class AssignableMethodHandle extends JavaMethodHandle {
* private final MethodHandle setter;
* public MethodHandle setter() { return setter; }
* public AssignableMethodHandle(String get, String set) {
* super(get);
* MethodType getType = this.type();
* MethodType setType = getType.insertParameterType(getType.parameterCount(), getType.returnType()).changeReturnType(void.class);
* this.setter = MethodHandles.publicLookup().bind(this, set, setType);
* }
* }
* // class Main { public static void main(String... av) { ...
* final Number[] stuff = { 123, 456 };
* AssignableMethodHandle stuffPtr = new AssignableMethodHandle("get", "set") {
* public Number get(long i) { return stuff[(int)i]; }
* public void set(long i, Object x) { stuff[(int)i] = x; }
* }
* int x = (Integer) stuffPtr.<Number>invoke(1L); // 456
* stuffPtr.setter().<void>invoke(0L, (Number) 789); // replaces 123 with 789
* </pre></blockquote>
* @see MethodHandle
* @author John Rose, JSR 292 EG
*/
...
...
@@ -72,12 +148,87 @@ public abstract class JavaMethodHandle
// with a JVM change which moves the required hidden behavior onto this class.
extends
sun
.
dyn
.
BoundMethodHandle
{
private
static
final
Access
IMPL_TOKEN
=
Access
.
getToken
();
/**
* When creating a, pass in {@code entryPoint}, any method handle which
* can take the current object
* @param entryPoint
* When creating a {@code JavaMethodHandle}, the actual method handle
* invocation behavior will be delegated to the specified {@code entryPoint}.
* This may be any method handle which can take the newly constructed object
* as a leading parameter.
* <p>
* The method handle type of {@code this} (i.e, the fully constructed object)
* will be {@code entryPoint}, minus the leading argument.
* The leading argument will be bound to {@code this} on every method
* handle invocation.
* @param entryPoint the method handle to handle calls
*/
protected
JavaMethodHandle
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
,
0
);
super
(
entryPoint
);
}
/**
* Create a method handle whose entry point is a non-static method
* visible in the exact (most specific) class of
* the newly constructed object.
* <p>
* The method is specified by name and type, as if via this expression:
* {@code MethodHandles.lookup().findVirtual(this.getClass(), name, type)}.
* The class defining the method might be an anonymous inner class.
* <p>
* The method handle type of {@code this} (i.e, the fully constructed object)
* will be the given method handle type.
* A call to {@code this} will invoke the selected method.
* The receiver argument will be bound to {@code this} on every method
* handle invocation.
* <p>
* <i>Rationale:</i>
* Although this constructor may seem to be a mere luxury,
* it is not subsumed by the more general constructor which
* takes any {@code MethodHandle} as the entry point argument.
* In order to convert an entry point name to a method handle,
* the self-class of the object is required (in order to do
* the lookup). The self-class, in turn, is generally not
* available at the time of the constructor invocation,
* due to the rules of Java and the JVM verifier.
* One cannot call {@code this.getClass()}, because
* the value of {@code this} is inaccessible at the point
* of the constructor call. (Changing this would require
* change to the Java language, verifiers, and compilers.)
* In particular, this constructor allows {@code JavaMethodHandle}s
* to be created in combination with the anonymous inner class syntax.
* @param entryPointName the name of the entry point method
* @param type (optional) the desired type of the method handle
*/
protected
JavaMethodHandle
(
String
entryPointName
,
MethodType
type
)
{
super
(
entryPointName
,
type
,
true
);
}
/**
* Create a method handle whose entry point is a non-static method
* visible in the exact (most specific) class of
* the newly constructed object.
* <p>
* The method is specified only by name.
* There must be exactly one method of that name visible in the object class,
* either inherited or locally declared.
* (That is, the method must not be overloaded.)
* <p>
* The method handle type of {@code this} (i.e, the fully constructed object)
* will be the same as the type of the selected non-static method.
* The receiver argument will be bound to {@code this} on every method
* handle invocation.
* <p>ISSUE: This signature wildcarding feature does not correspond to
* any MethodHandles.Lookup API element. Can we eliminate it?
* Alternatively, it is useful for naming non-overloaded methods.
* Shall we make type arguments optional in the Lookup methods,
* throwing an error in cases of ambiguity?
* <p>
* For this method's rationale, see the documentation
* for {@link #JavaMethodHandle(String,MethodType)}.
* @param entryPointName the name of the entry point method
*/
protected
JavaMethodHandle
(
String
entryPointName
)
{
super
(
entryPointName
,
(
MethodType
)
null
,
false
);
}
}
jdk/src/share/classes/java/dyn/Linkage.java
浏览文件 @
4a61e19d
...
...
@@ -25,7 +25,9 @@
package
java.dyn
;
import
java.dyn.MethodHandles.Lookup
;
import
java.util.WeakHashMap
;
import
sun.dyn.Access
;
import
sun.reflect.Reflection
;
import
static
sun
.
dyn
.
util
.
VerifyAccess
.
checkBootstrapPrivilege
;
...
...
@@ -34,6 +36,8 @@ import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege;
* @author John Rose, JSR 292 EG
*/
public
class
Linkage
{
private
static
final
Access
IMPL_TOKEN
=
Access
.
getToken
();
private
Linkage
()
{}
// do not instantiate
/**
...
...
@@ -53,19 +57,23 @@ public class Linkage {
* call to this method.
* <li>The given class is already fully initialized.
* <li>The given class is in the process of initialization, in another thread.
* <li>The same {@code CallSite} object has already been returned from
* a bootstrap method call to another {@code invokedynamic} call site.
* </ul>
* Because of these rules, a class may install its own bootstrap method in
* a static initializer.
* @param callerClass a class that may have {@code invokedynamic} sites
* @param bootstrapMethod the method to use to bootstrap all such sites
*/
public
static
void
registerBootstrapMethod
(
Class
callerClass
,
MethodHandle
mh
)
{
void
registerBootstrapMethod
(
Class
callerClass
,
MethodHandle
bootstrapMethod
)
{
Class
callc
=
Reflection
.
getCallerClass
(
2
);
checkBootstrapPrivilege
(
callc
,
callerClass
,
"registerBootstrapMethod"
);
checkBSM
(
mh
);
checkBSM
(
bootstrapMethod
);
synchronized
(
bootstrapMethods
)
{
if
(
bootstrapMethods
.
containsKey
(
callerClass
))
throw
new
IllegalStateException
(
"bootstrap method already declared in "
+
callerClass
);
bootstrapMethods
.
put
(
callerClass
,
mh
);
bootstrapMethods
.
put
(
callerClass
,
bootstrapMethod
);
}
}
...
...
@@ -88,8 +96,9 @@ public class Linkage {
public
static
void
registerBootstrapMethod
(
Class
<?>
runtime
,
String
name
)
{
Class
callc
=
Reflection
.
getCallerClass
(
2
);
Lookup
lookup
=
new
Lookup
(
IMPL_TOKEN
,
callc
);
MethodHandle
bootstrapMethod
=
MethodHandles
.
findStaticFrom
(
callc
,
runtime
,
name
,
BOOTSTRAP_METHOD_TYPE
);
lookup
.
findStatic
(
runtime
,
name
,
BOOTSTRAP_METHOD_TYPE
);
// FIXME: exception processing wrong here
checkBSM
(
bootstrapMethod
);
Linkage
.
registerBootstrapMethod
(
callc
,
bootstrapMethod
);
...
...
@@ -106,8 +115,9 @@ public class Linkage {
public
static
void
registerBootstrapMethod
(
String
name
)
{
Class
callc
=
Reflection
.
getCallerClass
(
2
);
Lookup
lookup
=
new
Lookup
(
IMPL_TOKEN
,
callc
);
MethodHandle
bootstrapMethod
=
MethodHandles
.
findStaticFrom
(
callc
,
callc
,
name
,
BOOTSTRAP_METHOD_TYPE
);
lookup
.
findStatic
(
callc
,
name
,
BOOTSTRAP_METHOD_TYPE
);
// FIXME: exception processing wrong here
checkBSM
(
bootstrapMethod
);
Linkage
.
registerBootstrapMethod
(
callc
,
bootstrapMethod
);
...
...
@@ -116,8 +126,7 @@ public class Linkage {
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Report the bootstrap method registered for a given class.
* Returns null if the class has never yet registered a bootstrap method,
* or if the class has explicitly registered a null bootstrap method.
* Returns null if the class has never yet registered a bootstrap method.
* Only callers privileged to set the bootstrap method may inquire
* about it, because a bootstrap method is potentially a back-door entry
* point into its class.
...
...
@@ -137,12 +146,12 @@ public class Linkage {
* {@code (Class, String, MethodType)} returning a {@code CallSite}.
*/
public
static
final
MethodType
BOOTSTRAP_METHOD_TYPE
=
MethodType
.
m
ak
e
(
CallSite
.
class
,
Class
.
class
,
String
.
class
,
MethodType
.
class
);
=
MethodType
.
m
ethodTyp
e
(
CallSite
.
class
,
Class
.
class
,
String
.
class
,
MethodType
.
class
);
private
static
final
MethodType
OLD_BOOTSTRAP_METHOD_TYPE
=
MethodType
.
m
ak
e
(
Object
.
class
,
CallSite
.
class
,
Object
[].
class
);
=
MethodType
.
m
ethodTyp
e
(
Object
.
class
,
CallSite
.
class
,
Object
[].
class
);
private
static
final
WeakHashMap
<
Class
,
MethodHandle
>
bootstrapMethods
=
new
WeakHashMap
<
Class
,
MethodHandle
>();
...
...
@@ -173,8 +182,8 @@ public class Linkage {
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Invalidate all <code>invokedynamic</code> call sites
associated
*
with
the given class.
* Invalidate all <code>invokedynamic</code> call sites
in the bytecodes
*
of any methods of
the given class.
* (These are exactly those sites which report the given class
* via the {@link CallSite#callerClass()} method.)
* <p>
...
...
jdk/src/share/classes/java/dyn/LinkagePermission.java
浏览文件 @
4a61e19d
...
...
@@ -88,7 +88,7 @@ public final class LinkagePermission extends BasicPermission {
/**
* Create a new LinkagePermission with the given name.
* The name is the symbolic name of the LinkagePermission, such as
* "registerBootstrapMethod", "invalidateClass.*", etc. An asterisk
* "registerBootstrapMethod", "invalidateC
allerC
lass.*", etc. An asterisk
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match.
*
...
...
jdk/src/share/classes/java/dyn/MethodHandle.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/java/dyn/MethodHandles.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/java/dyn/MethodType.java
浏览文件 @
4a61e19d
...
...
@@ -32,7 +32,7 @@ import java.util.List;
import
sun.dyn.Access
;
import
sun.dyn.Invokers
;
import
sun.dyn.MethodTypeImpl
;
import
sun.dyn.util.Bytecode
Signature
;
import
sun.dyn.util.Bytecode
Descriptor
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
/**
...
...
@@ -63,7 +63,7 @@ class MethodType {
static
{
// This hack allows the implementation package special access to
// the internals of MethodType. In particular, the
Form
has all sorts
// the internals of MethodType. In particular, the
MTImpl
has all sorts
// of cached information useful to the implementation code.
MethodTypeImpl
.
setMethodTypeFriend
(
IMPL_TOKEN
,
new
MethodTypeImpl
.
MethodTypeFriend
()
{
public
Class
<?>[]
ptypes
(
MethodType
mt
)
{
return
mt
.
ptypes
;
}
...
...
@@ -114,51 +114,76 @@ class MethodType {
* @throws IllegalArgumentException if any of the ptypes is void
*/
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
,
Class
<?>[]
ptypes
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
,
Class
<?>[]
ptypes
)
{
return
makeImpl
(
rtype
,
ptypes
,
false
);
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
Class
<?>[]
ptypes
)
{
return
methodType
(
rtype
,
ptypes
);
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}. */
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}. */
public
static
MethodType
methodType
(
Class
<?>
rtype
,
List
<?
extends
Class
<?>>
ptypes
)
{
boolean
notrust
=
false
;
// random List impl. could return evil ptypes array
return
makeImpl
(
rtype
,
ptypes
.
toArray
(
NO_PTYPES
),
notrust
);
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
List
<?
extends
Class
<?>>
ptypes
)
{
return
m
akeImpl
(
rtype
,
ptypes
.
toArray
(
NO_PTYPES
),
true
);
return
m
ethodType
(
rtype
,
ptypes
);
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* The leading parameter type is prepended to the remaining array.
*/
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
,
Class
<?>
ptype0
,
Class
<?>...
ptypes
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
,
Class
<?>
ptype0
,
Class
<?>...
ptypes
)
{
Class
<?>[]
ptypes1
=
new
Class
<?>[
1
+
ptypes
.
length
];
ptypes1
[
0
]
=
ptype0
;
System
.
arraycopy
(
ptypes
,
0
,
ptypes1
,
1
,
ptypes
.
length
);
return
makeImpl
(
rtype
,
ptypes1
,
true
);
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
Class
<?>
ptype0
,
Class
<?>...
ptypes
)
{
return
methodType
(
rtype
,
ptype0
,
ptypes
);
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* The resulting method has no parameter types.
*/
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
)
{
return
makeImpl
(
rtype
,
NO_PTYPES
,
true
);
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
)
{
return
methodType
(
rtype
);
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* The resulting method has the single given parameter type.
*/
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
,
Class
<?>
ptype0
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
,
Class
<?>
ptype0
)
{
return
makeImpl
(
rtype
,
new
Class
<?>[]{
ptype0
},
true
);
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
Class
<?>
ptype0
)
{
return
methodType
(
rtype
,
ptype0
);
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* The resulting method has the same parameter types as {@code ptypes},
* and the specified return type.
*/
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
,
MethodType
ptypes
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
,
MethodType
ptypes
)
{
return
makeImpl
(
rtype
,
ptypes
.
ptypes
,
true
);
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
MethodType
ptypes
)
{
return
methodType
(
rtype
,
ptypes
);
}
/**
* Sole factory method to find or create an interned method type.
...
...
@@ -202,15 +227,16 @@ class MethodType {
private
static
final
MethodType
[]
objectOnlyTypes
=
new
MethodType
[
20
];
/**
* Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
* All parameters and the return type will be Object, except the final varargs parameter if any.
* Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* All parameters and the return type will be {@code Object},
* except the final varargs parameter if any, which will be {@code Object[]}.
* @param objectArgCount number of parameters (excluding the varargs parameter if any)
* @param varargs whether there will be a varargs parameter, of type
Object[]
* @param varargs whether there will be a varargs parameter, of type
{@code Object[]}
* @return a totally generic method type, given only its count of parameters and varargs
* @see #
makeGeneric
(int)
* @see #
genericMethodType
(int)
*/
public
static
MethodType
makeGeneric
(
int
objectArgCount
,
boolean
varargs
)
{
MethodType
genericMethodType
(
int
objectArgCount
,
boolean
varargs
)
{
MethodType
mt
;
int
ivarargs
=
(!
varargs
?
0
:
1
);
int
ootIndex
=
objectArgCount
*
2
+
ivarargs
;
...
...
@@ -227,19 +253,27 @@ class MethodType {
}
return
mt
;
}
@Deprecated
public
static
MethodType
makeGeneric
(
int
objectArgCount
,
boolean
varargs
)
{
return
genericMethodType
(
objectArgCount
,
varargs
);
}
/**
* All parameters and the return type will be Object.
* @param objectArgCount number of parameters
* @return a totally generic method type, given only its count of parameters
* @see #
makeGeneric
(int, boolean)
* @see #
genericMethodType
(int, boolean)
*/
public
static
MethodType
genericMethodType
(
int
objectArgCount
)
{
return
genericMethodType
(
objectArgCount
,
false
);
}
@Deprecated
public
static
MethodType
makeGeneric
(
int
objectArgCount
)
{
return
makeGeneric
(
objectArgCount
,
false
);
return
genericMethodType
(
objectArgCount
);
}
/** Convenience method for {@link #m
ake(java.lang.Class, java.lang.Class[], boolean
)}.
/** Convenience method for {@link #m
ethodType(java.lang.Class, java.lang.Class[]
)}.
* @param num the index (zero-based) of the parameter type to change
* @param nptype a new parameter type to replace the old one with
* @return the same type, except with the selected parameter changed
...
...
@@ -251,11 +285,10 @@ class MethodType {
return
makeImpl
(
rtype
,
nptypes
,
true
);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
* @param num the position (zero-based) of the inserted parameter type
* @param nptype a new parameter type to insert into the parameter list
* @return the same type, except with the selected parameter inserted
/** Convenience method for {@link #insertParameterTypes}.
* @deprecated Use {@link #insertParameterTypes} instead.
*/
@Deprecated
public
MethodType
insertParameterType
(
int
num
,
Class
<?>
nptype
)
{
int
len
=
ptypes
.
length
;
Class
<?>[]
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
len
+
1
);
...
...
@@ -264,23 +297,73 @@ class MethodType {
return
makeImpl
(
rtype
,
nptypes
,
true
);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
* @param num the index (zero-based) of the parameter type to remove
* @return the same type, except with the selected parameter removed
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param num the position (zero-based) of the inserted parameter type(s)
* @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
* @return the same type, except with the selected parameter(s) inserted
*/
public
MethodType
dropParameterType
(
int
num
)
{
public
MethodType
insertParameterTypes
(
int
num
,
Class
<?>...
ptypesToInsert
)
{
int
len
=
ptypes
.
length
;
if
(
num
<
0
||
num
>
len
)
throw
newIllegalArgumentException
(
"num="
+
num
);
//SPECME
int
ilen
=
ptypesToInsert
.
length
;
if
(
ilen
==
0
)
return
this
;
Class
<?>[]
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
len
+
ilen
);
System
.
arraycopy
(
nptypes
,
num
,
nptypes
,
num
+
ilen
,
len
-
num
);
System
.
arraycopy
(
ptypesToInsert
,
0
,
nptypes
,
num
,
ilen
);
return
makeImpl
(
rtype
,
nptypes
,
true
);
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param num the position (zero-based) of the inserted parameter type(s)
* @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
* @return the same type, except with the selected parameter(s) inserted
*/
public
MethodType
insertParameterTypes
(
int
num
,
List
<
Class
<?>>
ptypesToInsert
)
{
return
insertParameterTypes
(
num
,
ptypesToInsert
.
toArray
(
NO_PTYPES
));
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param start the index (zero-based) of the first parameter type to remove
* @param end the index (greater than {@code start}) of the first parameter type after not to remove
* @return the same type, except with the selected parameter(s) removed
*/
public
MethodType
dropParameterTypes
(
int
start
,
int
end
)
{
int
len
=
ptypes
.
length
;
if
(!(
0
<=
start
&&
start
<=
end
&&
end
<=
len
))
throw
newIllegalArgumentException
(
"start="
+
start
+
" end="
+
end
);
//SPECME
if
(
start
==
end
)
return
this
;
Class
<?>[]
nptypes
;
if
(
num
==
0
)
{
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
1
,
len
);
if
(
start
==
0
)
{
if
(
end
==
len
)
{
// drop all parameters
nptypes
=
NO_PTYPES
;
}
else
{
// drop initial parameter(s)
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
end
,
len
);
}
}
else
{
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
len
-
1
);
System
.
arraycopy
(
ptypes
,
num
+
1
,
nptypes
,
num
,
(
len
-
1
)-
num
);
if
(
end
==
len
)
{
// drop trailing parameter(s)
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
start
);
}
else
{
int
tail
=
len
-
end
;
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
start
+
tail
);
System
.
arraycopy
(
ptypes
,
end
,
nptypes
,
start
,
tail
);
}
}
return
makeImpl
(
rtype
,
nptypes
,
true
);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
/** Convenience method for {@link #dropParameterTypes}.
* @deprecated Use {@link #dropParameterTypes} instead.
*/
@Deprecated
public
MethodType
dropParameterType
(
int
num
)
{
return
dropParameterTypes
(
num
,
num
+
1
);
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param nrtype a return parameter type to replace the old one with
* @return the same type, except with the return type change
*/
...
...
@@ -291,6 +374,7 @@ class MethodType {
/** Convenience method.
* Report if this type contains a primitive argument or return value.
* The return type {@code void} counts as a primitive.
* @return true if any of the types are primitives
*/
public
boolean
hasPrimitives
()
{
...
...
@@ -300,39 +384,47 @@ class MethodType {
/** Convenience method.
* Report if this type contains a wrapper argument or return value.
* Wrappers are types which box primitive values, such as {@link Integer}.
* The reference type {@code java.lang.Void} counts as a wrapper.
* @return true if any of the types are wrappers
*/
public
boolean
hasWrappers
()
{
return
unwrap
()
!=
this
;
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
* Erase all reference types to Object.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* Erase all reference types to {@code Object}.
* All primitive types (including {@code void}) will remain unchanged.
* @return a version of the original type with all reference types replaced
*/
public
MethodType
erase
()
{
return
form
.
erasedType
();
}
/** Convenience method for {@link #makeGeneric(int)}.
* Convert all types, both reference and primitive, to Object.
/** Convenience method for {@link #genericMethodType(int)}.
* Convert all types, both reference and primitive, to {@code Object}.
* The expression {@code type.wrap().erase()} produces the same value
* as {@code type.generic()}.
* @return a version of the original type with all types replaced
*/
public
MethodType
generic
()
{
return
makeGeneric
(
parameterCount
());
return
genericMethodType
(
parameterCount
());
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* Convert all primitive types to their corresponding wrapper types.
* All reference types (including wrapper types) will remain unchanged.
* A {@code void} return type is changed to the type {@code java.lang.Void}.
* The expression {@code type.wrap().erase()} produces the same value
* as {@code type.generic()}.
* @return a version of the original type with all primitive types replaced
*/
public
MethodType
wrap
()
{
return
hasPrimitives
()
?
wrapWithPrims
(
this
)
:
this
;
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* Convert all wrapper types to their corresponding primitive types.
* All primitive types (including {@code void}) will remain unchanged.
* A return type of {@code java.lang.Void} is changed to {@code void}.
* @return a version of the original type with all wrapper types replaced
*/
...
...
@@ -391,6 +483,7 @@ class MethodType {
/**
* Convenience method to present the arguments as an array.
* Changes to the array will not result in changes to the type.
* @return the parameter types (as a fresh copy if necessary)
*/
public
Class
<?>[]
parameterArray
()
{
...
...
@@ -491,7 +584,7 @@ class MethodType {
return
form
.
parameterSlotCount
();
}
/** Number of JVM stack slots which carry all parameters after
/** Number of JVM stack slots which carry all parameters
including and
after
* the given position, which must be in the range of 0 to
* {@code parameterCount} inclusive. Successive parameters are
* more shallowly stacked, and parameters are indexed in the bytecodes
...
...
@@ -532,7 +625,7 @@ class MethodType {
return
form
.
returnSlotCount
();
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* Find or create an instance (interned) of the given method type.
* Any class or interface name embedded in the signature string
* will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
...
...
@@ -544,16 +637,16 @@ class MethodType {
* <p>
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
* @param
bytecodeSignature
a bytecode-level signature string "(T...)T"
* @param
descriptor
a bytecode-level signature string "(T...)T"
* @param loader the class loader in which to look up the types
* @return a method type matching the bytecode-level signature
* @throws IllegalArgumentException if the string is not well-formed
* @throws TypeNotPresentException if a named type cannot be found
*/
public
static
MethodType
from
BytecodeString
(
String
bytecodeSignature
,
ClassLoader
loader
)
public
static
MethodType
from
MethodDescriptorString
(
String
descriptor
,
ClassLoader
loader
)
throws
IllegalArgumentException
,
TypeNotPresentException
{
List
<
Class
<?>>
types
=
Bytecode
Signature
.
parseMethod
(
bytecodeSignature
,
loader
);
List
<
Class
<?>>
types
=
Bytecode
Descriptor
.
parseMethod
(
descriptor
,
loader
);
Class
<?>
rtype
=
types
.
remove
(
types
.
size
()
-
1
);
Class
<?>[]
ptypes
=
types
.
toArray
(
NO_PTYPES
);
return
makeImpl
(
rtype
,
ptypes
,
true
);
...
...
@@ -565,11 +658,21 @@ class MethodType {
* <p>
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
* {@link #from
Bytecode
String(java.lang.String, java.lang.ClassLoader)},
* {@link #from
MethodDescriptor
String(java.lang.String, java.lang.ClassLoader)},
* because the latter requires a suitable class loader argument.
* @return the bytecode signature representation
*/
public
String
toMethodDescriptorString
()
{
return
BytecodeDescriptor
.
unparse
(
this
);
}
/** Temporary alias for toMethodDescriptorString; delete after M3. */
public
String
toBytecodeString
()
{
return
BytecodeSignature
.
unparse
(
this
);
return
toMethodDescriptorString
();
}
/** Temporary alias for fromMethodDescriptorString; delete after M3. */
public
static
MethodType
fromBytecodeString
(
String
descriptor
,
ClassLoader
loader
)
throws
IllegalArgumentException
,
TypeNotPresentException
{
return
fromMethodDescriptorString
(
descriptor
,
loader
);
}
}
jdk/src/share/classes/java/dyn/package-info.java
浏览文件 @
4a61e19d
...
...
@@ -24,6 +24,7 @@
*/
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* This package contains dynamic language support provided directly by
* the Java core class libraries and virtual machine.
* @author John Rose, JSR 292 EG
...
...
jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/sun/dyn/BoundMethodHandle.java
浏览文件 @
4a61e19d
...
...
@@ -28,6 +28,10 @@ package sun.dyn;
import
sun.dyn.util.VerifyType
;
import
sun.dyn.util.Wrapper
;
import
java.dyn.*
;
import
java.util.List
;
import
sun.dyn.MethodHandleNatives.Constants
;
import
static
sun
.
dyn
.
MethodHandleImpl
.
IMPL_LOOKUP
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
/**
* The flavor of method handle which emulates an invoke instruction
...
...
@@ -35,18 +39,23 @@ import java.dyn.*;
* when the handle is created, not when it is invoked.
* @author jrose
*/
public
class
BoundMethodHandle
extends
MethodHandle
{
public
class
BoundMethodHandle
extends
MethodHandle
{
//MethodHandle vmtarget; // next BMH or final DMH or methodOop
private
final
Object
argument
;
// argument to insert
private
final
int
vmargslot
;
// position at which it is inserted
private
static
final
Access
IMPL_TOKEN
=
Access
.
getToken
();
private
static
final
MemberName
.
Factory
IMPL_NAMES
=
MemberName
.
getFactory
(
IMPL_TOKEN
);
// Constructors in this class *must* be package scoped or private.
// Exception: JavaMethodHandle constructors are protected.
// (The link between JMH and BMH is temporary.)
/** Bind a direct MH to its receiver (or first ref. argument).
* The JVM will pre-dispatch the MH if it is not already static.
*/
BoundMethodHandle
(
DirectMethodHandle
mh
,
Object
argument
)
{
super
(
Access
.
TOKEN
,
mh
.
type
().
dropParameterType
(
0
));
super
(
Access
.
TOKEN
,
mh
.
type
().
dropParameterType
s
(
0
,
1
));
// check the type now, once for all:
this
.
argument
=
checkReferenceArgument
(
argument
,
mh
,
0
);
this
.
vmargslot
=
this
.
type
().
parameterSlotCount
();
...
...
@@ -56,32 +65,34 @@ public class BoundMethodHandle extends MethodHandle {
}
else
{
this
.
vmtarget
=
mh
;
}
}
private
static
final
int
REF_ARG
=
0
,
PRIM_ARG
=
1
,
SELF_ARG
=
2
;
}
/** Insert an argument into an arbitrary method handle.
* If argnum is zero, inserts the first argument, etc.
* The argument type must be a reference.
*/
BoundMethodHandle
(
MethodHandle
mh
,
Object
argument
,
int
argnum
)
{
this
(
mh
,
argument
,
argnum
,
mh
.
type
().
parameterType
(
argnum
).
isPrimitive
()
?
PRIM_ARG
:
REF_ARG
);
this
(
mh
.
type
().
dropParameterTypes
(
argnum
,
argnum
+
1
),
mh
,
argument
,
argnum
);
}
/** Insert an argument into an arbitrary method handle.
* If argnum is zero, inserts the first argument, etc.
*/
BoundMethodHandle
(
Method
Handle
mh
,
Object
argument
,
int
argnum
,
int
whichArg
)
{
super
(
Access
.
TOKEN
,
mh
.
type
().
dropParameterType
(
argnum
)
);
if
(
whichArg
==
PRIM_ARG
)
BoundMethodHandle
(
Method
Type
type
,
MethodHandle
mh
,
Object
argument
,
int
argnum
)
{
super
(
Access
.
TOKEN
,
type
);
if
(
mh
.
type
().
parameterType
(
argnum
).
isPrimitive
()
)
this
.
argument
=
bindPrimitiveArgument
(
argument
,
mh
,
argnum
);
else
{
if
(
whichArg
==
SELF_ARG
)
argument
=
this
;
this
.
argument
=
checkReferenceArgument
(
argument
,
mh
,
argnum
);
}
this
.
vmargslot
=
this
.
type
().
parameterSlotDepth
(
argnum
);
this
.
vmargslot
=
type
.
parameterSlotDepth
(
argnum
);
initTarget
(
mh
,
argnum
);
}
private
void
initTarget
(
MethodHandle
mh
,
int
argnum
)
{
if
(
MethodHandleNatives
.
JVM_SUPPORT
)
{
this
.
vmtarget
=
null
;
// maybe updated by JVM
this
.
vmtarget
=
null
;
// maybe updated by JVM
MethodHandleNatives
.
init
(
this
,
mh
,
argnum
);
}
else
{
this
.
vmtarget
=
mh
;
...
...
@@ -97,29 +108,65 @@ public class BoundMethodHandle extends MethodHandle {
assert
(
this
.
getClass
()
==
AdapterMethodHandle
.
class
);
}
/** Initialize the current object as a method handle, binding it
* as the
{@code argnum}th
argument of the method handle {@code entryPoint}.
/** Initialize the current object as a
Java
method handle, binding it
* as the
first
argument of the method handle {@code entryPoint}.
* The invocation type of the resulting method handle will be the
* same as {@code entryPoint}, except that the
{@code argnum}th
argument
* same as {@code entryPoint}, except that the
first
argument
* type will be dropped.
*/
public
BoundMethodHandle
(
MethodHandle
entryPoint
,
int
argnum
)
{
this
(
entryPoint
,
null
,
argnum
,
SELF_ARG
);
// Note: If the conversion fails, perhaps because of a bad entryPoint,
// the MethodHandle.type field will not be filled in, and therefore
// no MH.invoke call will ever succeed. The caller may retain a pointer
// to the broken method handle, but no harm can be done with it.
protected
BoundMethodHandle
(
MethodHandle
entryPoint
)
{
super
(
Access
.
TOKEN
,
entryPoint
.
type
().
dropParameterTypes
(
0
,
1
));
this
.
argument
=
this
;
// kludge; get rid of
this
.
vmargslot
=
this
.
type
().
parameterSlotDepth
(
0
);
initTarget
(
entryPoint
,
0
);
assert
(
this
instanceof
JavaMethodHandle
);
}
/** Initialize the current object as a method handle, binding it
* as the first argument of the method handle {@code entryPoint}.
* The invocation type of the resulting method handle will be the
* same as {@code entryPoint}, except that the first argument
* type will be dropped.
/** Initialize the current object as a Java method handle.
*/
public
BoundMethodHandle
(
MethodHandle
entryPoint
)
{
this
(
entryPoint
,
null
,
0
,
SELF_ARG
);
protected
BoundMethodHandle
(
String
entryPointName
,
MethodType
type
,
boolean
matchArity
)
{
super
(
Access
.
TOKEN
,
null
);
MethodHandle
entryPoint
=
findJavaMethodHandleEntryPoint
(
this
.
getClass
(),
entryPointName
,
type
,
matchArity
);
MethodHandleImpl
.
initType
(
this
,
entryPoint
.
type
().
dropParameterTypes
(
0
,
1
));
this
.
argument
=
this
;
// kludge; get rid of
this
.
vmargslot
=
this
.
type
().
parameterSlotDepth
(
0
);
initTarget
(
entryPoint
,
0
);
assert
(
this
instanceof
JavaMethodHandle
);
}
private
static
MethodHandle
findJavaMethodHandleEntryPoint
(
Class
<?>
caller
,
String
name
,
MethodType
type
,
boolean
matchArity
)
{
if
(
matchArity
)
type
.
getClass
();
// elicit NPE
List
<
MemberName
>
methods
=
IMPL_NAMES
.
getMethods
(
caller
,
true
,
name
,
null
,
caller
);
MethodType
foundType
=
null
;
MemberName
foundMethod
=
null
;
for
(
MemberName
method
:
methods
)
{
MethodType
mtype
=
method
.
getMethodType
();
if
(
type
!=
null
&&
type
.
parameterCount
()
!=
mtype
.
parameterCount
())
continue
;
else
if
(
foundType
==
null
)
foundType
=
mtype
;
else
if
(
foundType
!=
mtype
)
throw
newIllegalArgumentException
(
"more than one method named "
+
name
+
" in "
+
caller
.
getName
());
// discard overrides
if
(
foundMethod
==
null
)
foundMethod
=
method
;
else
if
(
foundMethod
.
getDeclaringClass
().
isAssignableFrom
(
method
.
getDeclaringClass
()))
foundMethod
=
method
;
}
if
(
foundMethod
==
null
)
throw
newIllegalArgumentException
(
"no method named "
+
name
+
" in "
+
caller
.
getName
());
MethodHandle
entryPoint
=
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
foundMethod
,
true
,
caller
);
if
(
type
!=
null
)
{
MethodType
epType
=
type
.
insertParameterTypes
(
0
,
entryPoint
.
type
().
parameterType
(
0
));
entryPoint
=
MethodHandles
.
convertArguments
(
entryPoint
,
epType
);
}
return
entryPoint
;
}
/** Make sure the given {@code argument} can be used as {@code argnum}-th
...
...
@@ -175,6 +222,24 @@ public class BoundMethodHandle extends MethodHandle {
@Override
public
String
toString
()
{
return
"Bound["
+
super
.
toString
()
+
"]"
;
MethodHandle
mh
=
this
;
while
(
mh
instanceof
BoundMethodHandle
)
{
Object
info
=
MethodHandleNatives
.
getTargetInfo
(
mh
);
if
(
info
instanceof
MethodHandle
)
{
mh
=
(
MethodHandle
)
info
;
}
else
{
String
name
=
null
;
if
(
info
instanceof
MemberName
)
name
=
((
MemberName
)
info
).
getName
();
if
(
name
!=
null
)
return
name
;
else
return
super
.
toString
();
// <unknown>, probably
}
assert
(
mh
!=
this
);
if
(
mh
instanceof
JavaMethodHandle
)
break
;
// access JMH.toString(), not BMH.toString()
}
return
mh
.
toString
();
}
}
jdk/src/share/classes/sun/dyn/CallSiteImpl.java
浏览文件 @
4a61e19d
...
...
@@ -26,34 +26,51 @@
package
sun.dyn
;
import
java.dyn.*
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
/**
* The CallSite privately created by the JVM at every invokedynamic instruction.
* Parts of CallSite known to the JVM.
* FIXME: Merge all this into CallSite proper.
* @author jrose
*/
class
CallSiteImpl
extends
CallSite
{
// Field
s
used only by the JVM. Do not use or change.
public
class
CallSiteImpl
{
// Field used only by the JVM. Do not use or change.
private
Object
vmmethod
;
// Values supplied by the JVM:
int
callerMID
,
callerBCI
;
protected
int
callerMID
,
callerBCI
;
private
CallSiteImpl
(
Class
<?>
caller
,
String
name
,
MethodType
type
)
{
super
(
caller
,
name
,
type
);
private
MethodHandle
target
;
protected
final
Object
caller
;
// usually a class
protected
final
String
name
;
protected
final
MethodType
type
;
/** called only directly from CallSite() */
protected
CallSiteImpl
(
Access
token
,
Object
caller
,
String
name
,
MethodType
type
)
{
Access
.
check
(
token
);
this
.
caller
=
caller
;
this
.
name
=
name
;
this
.
type
=
type
;
}
/** native version of setTarget */
protected
void
setTarget
(
MethodHandle
mh
)
{
//System.out.println("setTarget "+this+" := "+mh);
// XXX I don't know how to fix this properly.
// if (false && MethodHandleNatives.JVM_SUPPORT) // FIXME: enable this
// MethodHandleNatives.linkCallSite(this, mh);
// else
this
.
target
=
mh
;
}
@Override
public
void
setTarget
(
MethodHandle
mh
)
{
checkTarget
(
mh
);
if
(
MethodHandleNatives
.
JVM_SUPPORT
)
MethodHandleNatives
.
linkCallSite
(
this
,
(
MethodHandle
)
mh
);
else
super
.
setTarget
(
mh
);
protected
MethodHandle
getTarget
()
{
return
target
;
}
private
static
final
MethodHandle
PRIVATE_INITIALIZE_CALL_SITE
=
MethodHandleImpl
.
IMPL_LOOKUP
.
findStatic
(
CallSite
.
class
,
"privateInitializeCallSite"
,
MethodType
.
m
ak
e
(
void
.
class
,
CallSite
.
class
,
int
.
class
,
int
.
class
));
MethodType
.
m
ethodTyp
e
(
void
.
class
,
CallSite
.
class
,
int
.
class
,
int
.
class
));
// this is the up-call from the JVM:
static
CallSite
makeSite
(
Class
<?>
caller
,
String
name
,
MethodType
type
,
...
...
@@ -61,10 +78,25 @@ class CallSiteImpl extends CallSite {
MethodHandle
bsm
=
Linkage
.
getBootstrapMethod
(
caller
);
if
(
bsm
==
null
)
throw
new
InvokeDynamicBootstrapError
(
"class has no bootstrap method: "
+
caller
);
CallSite
site
=
bsm
.<
CallSite
>
invoke
(
caller
,
name
,
type
);
CallSite
site
;
try
{
site
=
bsm
.<
CallSite
>
invoke
(
caller
,
name
,
type
);
}
catch
(
Throwable
ex
)
{
throw
new
InvokeDynamicBootstrapError
(
"exception thrown while linking"
,
ex
);
}
if
(
site
==
null
)
throw
new
InvokeDynamicBootstrapError
(
"class bootstrap method failed to create a call site: "
+
caller
);
PRIVATE_INITIALIZE_CALL_SITE
.<
void
>
invoke
(
site
,
callerMID
,
callerBCI
);
if
(
site
.
type
()
!=
type
)
throw
new
InvokeDynamicBootstrapError
(
"call site type not initialized correctly: "
+
site
);
if
(
site
.
callerClass
()
!=
caller
)
throw
new
InvokeDynamicBootstrapError
(
"call site caller not initialized correctly: "
+
site
);
if
((
Object
)
site
.
name
()
!=
name
)
throw
new
InvokeDynamicBootstrapError
(
"call site name not initialized correctly: "
+
site
);
try
{
PRIVATE_INITIALIZE_CALL_SITE
.<
void
>
invoke
(
site
,
callerMID
,
callerBCI
);
}
catch
(
Throwable
ex
)
{
throw
new
InvokeDynamicBootstrapError
(
"call site initialization exception"
,
ex
);
}
return
site
;
}
}
jdk/src/share/classes/sun/dyn/FilterGeneric.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/sun/dyn/FilterOneArgument.java
浏览文件 @
4a61e19d
...
...
@@ -27,7 +27,6 @@ package sun.dyn;
import
java.dyn.JavaMethodHandle
;
import
java.dyn.MethodHandle
;
import
java.dyn.MethodHandles
;
import
java.dyn.MethodType
;
/**
...
...
@@ -42,16 +41,21 @@ public class FilterOneArgument extends JavaMethodHandle {
protected
final
MethodHandle
filter
;
// Object -> Object
protected
final
MethodHandle
target
;
// Object -> Object
protected
Object
entryPoint
(
Object
argument
)
{
Object
filteredArgument
=
filter
.<
Object
>
invoke
(
argument
);
return
target
.<
Object
>
invoke
(
filteredArgument
);
@Override
public
String
toString
()
{
return
target
.
toString
();
}
protected
Object
invoke
(
Object
argument
)
throws
Throwable
{
Object
filteredArgument
=
filter
.
invoke
(
argument
);
return
target
.
invoke
(
filteredArgument
);
}
private
static
final
MethodHandle
entryPoint
=
MethodHandleImpl
.
IMPL_LOOKUP
.
findVirtual
(
FilterOneArgument
.
class
,
"
entryPoint"
,
MethodType
.
makeGeneric
(
1
));
private
static
final
MethodHandle
INVOKE
=
MethodHandleImpl
.
IMPL_LOOKUP
.
findVirtual
(
FilterOneArgument
.
class
,
"
invoke"
,
MethodType
.
genericMethodType
(
1
));
protected
FilterOneArgument
(
MethodHandle
filter
,
MethodHandle
target
)
{
super
(
entryPoint
);
super
(
INVOKE
);
this
.
filter
=
filter
;
this
.
target
=
target
;
}
...
...
@@ -62,10 +66,6 @@ public class FilterOneArgument extends JavaMethodHandle {
return
new
FilterOneArgument
(
filter
,
target
);
}
public
String
toString
()
{
return
filter
+
"|>"
+
target
;
}
// MethodHandle make(MethodHandle filter1, MethodHandle filter2, MethodHandle target) {
// MethodHandle filter = make(filter1, filter2);
// return make(filter, target);
...
...
jdk/src/share/classes/sun/dyn/FromGeneric.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/sun/dyn/Invokers.java
浏览文件 @
4a61e19d
...
...
@@ -44,16 +44,20 @@ public class Invokers {
// generic (untyped) invoker for the outgoing call
private
/*lazy*/
MethodHandle
genericInvoker
;
// generic (untyped) invoker for the outgoing call; accepts a single Object[]
private
final
/*lazy*/
MethodHandle
[]
varargsInvokers
;
/** Compute and cache information common to all collecting adapters
* that implement members of the erasure-family of the given erased type.
*/
public
Invokers
(
Access
token
,
MethodType
targetType
)
{
Access
.
check
(
token
);
this
.
targetType
=
targetType
;
this
.
varargsInvokers
=
new
MethodHandle
[
targetType
.
parameterCount
()+
1
];
}
public
static
MethodType
invokerType
(
MethodType
targetType
)
{
return
targetType
.
insertParameterType
(
0
,
MethodHandle
.
class
);
return
targetType
.
insertParameterType
s
(
0
,
MethodHandle
.
class
);
}
public
MethodHandle
exactInvoker
()
{
...
...
@@ -76,8 +80,14 @@ public class Invokers {
return
invoker
;
}
public
MethodHandle
varargsInvoker
()
{
throw
new
UnsupportedOperationException
(
"NYI"
);
public
MethodHandle
varargsInvoker
(
int
objectArgCount
)
{
MethodHandle
vaInvoker
=
varargsInvokers
[
objectArgCount
];
if
(
vaInvoker
!=
null
)
return
vaInvoker
;
MethodHandle
gInvoker
=
genericInvoker
();
MethodType
vaType
=
MethodType
.
genericMethodType
(
objectArgCount
,
true
);
vaInvoker
=
MethodHandles
.
spreadArguments
(
gInvoker
,
invokerType
(
vaType
));
varargsInvokers
[
objectArgCount
]
=
vaInvoker
;
return
vaInvoker
;
}
public
String
toString
()
{
...
...
jdk/src/share/classes/sun/dyn/MemberName.java
浏览文件 @
4a61e19d
...
...
@@ -25,7 +25,7 @@
package
sun.dyn
;
import
sun.dyn.util.Bytecode
Signature
;
import
sun.dyn.util.Bytecode
Descriptor
;
import
java.dyn.*
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Field
;
...
...
@@ -33,6 +33,7 @@ import java.lang.reflect.Method;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Modifier
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.List
;
...
...
@@ -93,7 +94,7 @@ public final class MemberName implements Member, Cloneable {
}
if
(
type
instanceof
String
)
{
String
sig
=
(
String
)
type
;
MethodType
res
=
MethodType
.
from
Bytecode
String
(
sig
,
getClassLoader
());
MethodType
res
=
MethodType
.
from
MethodDescriptor
String
(
sig
,
getClassLoader
());
this
.
type
=
res
;
return
res
;
}
...
...
@@ -101,7 +102,7 @@ public final class MemberName implements Member, Cloneable {
Object
[]
typeInfo
=
(
Object
[])
type
;
Class
<?>[]
ptypes
=
(
Class
<?>[])
typeInfo
[
1
];
Class
<?>
rtype
=
(
Class
<?>)
typeInfo
[
0
];
MethodType
res
=
MethodType
.
m
ak
e
(
rtype
,
ptypes
);
MethodType
res
=
MethodType
.
m
ethodTyp
e
(
rtype
,
ptypes
);
this
.
type
=
res
;
return
res
;
}
...
...
@@ -111,7 +112,7 @@ public final class MemberName implements Member, Cloneable {
public
MethodType
getInvocationType
()
{
MethodType
itype
=
getMethodType
();
if
(!
isStatic
())
itype
=
itype
.
insertParameterType
(
0
,
clazz
);
itype
=
itype
.
insertParameterType
s
(
0
,
clazz
);
return
itype
;
}
...
...
@@ -135,7 +136,7 @@ public final class MemberName implements Member, Cloneable {
}
if
(
type
instanceof
String
)
{
String
sig
=
(
String
)
type
;
MethodType
mtype
=
MethodType
.
from
Bytecode
String
(
"()"
+
sig
,
getClassLoader
());
MethodType
mtype
=
MethodType
.
from
MethodDescriptor
String
(
"()"
+
sig
,
getClassLoader
());
Class
<?>
res
=
mtype
.
returnType
();
this
.
type
=
res
;
return
res
;
...
...
@@ -155,9 +156,9 @@ public final class MemberName implements Member, Cloneable {
if
(
type
instanceof
String
)
return
(
String
)
type
;
if
(
isInvocable
())
return
Bytecode
Signature
.
unparse
(
getMethodType
());
return
Bytecode
Descriptor
.
unparse
(
getMethodType
());
else
return
Bytecode
Signature
.
unparse
(
getFieldType
());
return
Bytecode
Descriptor
.
unparse
(
getFieldType
());
}
public
int
getModifiers
()
{
...
...
@@ -353,6 +354,8 @@ public final class MemberName implements Member, Cloneable {
return
type
.
toString
();
// class java.lang.String
// else it is a field, method, or constructor
StringBuilder
buf
=
new
StringBuilder
();
if
(!
isResolved
())
buf
.
append
(
"*."
);
if
(
getDeclaringClass
()
!=
null
)
{
buf
.
append
(
getName
(
clazz
));
buf
.
append
(
'.'
);
...
...
@@ -381,7 +384,7 @@ public final class MemberName implements Member, Cloneable {
private
static
String
getName
(
Object
obj
)
{
if
(
obj
instanceof
Class
<?>)
return
((
Class
<?>)
obj
).
getName
();
return
obj
.
toString
(
);
return
String
.
valueOf
(
obj
);
}
// Queries to the JVM:
...
...
@@ -408,6 +411,9 @@ public final class MemberName implements Member, Cloneable {
public
static
NoAccessException
newNoAccessException
(
MemberName
name
,
Class
<?>
lookupClass
)
{
return
newNoAccessException
(
"cannot access"
,
name
,
lookupClass
);
}
public
static
NoAccessException
newNoAccessException
(
MemberName
name
,
MethodHandles
.
Lookup
lookup
)
{
return
newNoAccessException
(
name
,
lookup
.
lookupClass
());
}
public
static
NoAccessException
newNoAccessException
(
String
message
,
MemberName
name
,
Class
<?>
lookupClass
)
{
message
+=
": "
+
name
;
...
...
@@ -436,7 +442,7 @@ public final class MemberName implements Member, Cloneable {
matchFlags
&=
ALLOWED_FLAGS
;
String
matchSig
=
null
;
if
(
matchType
!=
null
)
{
matchSig
=
Bytecode
Signature
.
unparse
(
matchType
);
matchSig
=
Bytecode
Descriptor
.
unparse
(
matchType
);
if
(
matchSig
.
startsWith
(
"("
))
matchFlags
&=
~(
ALL_KINDS
&
~
IS_INVOCABLE
);
else
...
...
@@ -447,17 +453,18 @@ public final class MemberName implements Member, Cloneable {
MemberName
[]
buf
=
newMemberBuffer
(
len1
);
int
totalCount
=
0
;
ArrayList
<
MemberName
[]>
bufs
=
null
;
int
bufCount
=
0
;
for
(;;)
{
int
bufCount
=
MethodHandleNatives
.
getMembers
(
defc
,
bufCount
=
MethodHandleNatives
.
getMembers
(
defc
,
matchName
,
matchSig
,
matchFlags
,
lookupClass
,
totalCount
,
buf
);
if
(
bufCount
<=
buf
.
length
)
{
if
(
bufCount
>=
0
)
totalCount
+=
bufCount
;
if
(
bufCount
<
0
)
bufCount
=
0
;
totalCount
+=
bufCount
;
break
;
}
// JVM returned t
p
us with an intentional overflow!
// JVM returned t
o
us with an intentional overflow!
totalCount
+=
buf
.
length
;
int
excess
=
bufCount
-
buf
.
length
;
if
(
bufs
==
null
)
bufs
=
new
ArrayList
<
MemberName
[]>(
1
);
...
...
@@ -473,7 +480,7 @@ public final class MemberName implements Member, Cloneable {
Collections
.
addAll
(
result
,
buf0
);
}
}
Collections
.
addAll
(
result
,
buf
);
result
.
addAll
(
Arrays
.
asList
(
buf
).
subList
(
0
,
bufCount
)
);
// Signature matching is not the same as type matching, since
// one signature might correspond to several types.
// So if matchType is a Class or MethodType, refilter the results.
...
...
jdk/src/share/classes/sun/dyn/MethodHandleImpl.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/sun/dyn/MethodHandleNatives.java
浏览文件 @
4a61e19d
...
...
@@ -25,6 +25,7 @@
package
sun.dyn
;
import
java.dyn.CallSite
;
import
java.dyn.MethodHandle
;
import
java.dyn.MethodType
;
import
java.lang.reflect.AccessibleObject
;
...
...
@@ -60,7 +61,7 @@ class MethodHandleNatives {
static
native
void
init
(
MethodType
self
);
/** Tell the JVM that we need to change the target of an invokedynamic. */
static
native
void
linkCallSite
(
CallSite
Impl
site
,
MethodHandle
target
);
static
native
void
linkCallSite
(
CallSite
site
,
MethodHandle
target
);
/** Fetch the vmtarget field.
* It will be sanitized as necessary to avoid exposing non-Java references.
...
...
@@ -84,8 +85,7 @@ class MethodHandleNatives {
}
/** Fetch the target of this method handle.
* If it directly targets a method, return a tuple of method info.
* The info is of the form new Object[]{defclass, name, sig, refclass}.
* If it directly targets a method, return a MemberName for the method.
* If it is chained to another method handle, return that handle.
*/
static
Object
getTargetInfo
(
MethodHandle
self
)
{
...
...
@@ -123,7 +123,7 @@ class MethodHandleNatives {
registerNatives
();
JVM_SUPPORT_
=
true
;
JVM_PUSH_LIMIT_
=
getConstant
(
Constants
.
GC_JVM_PUSH_LIMIT
);
JVM_STACK_MOVE_UNIT_
=
getConstant
(
Constants
.
GC_JVM_STACK_MOVE_
LIM
IT
);
JVM_STACK_MOVE_UNIT_
=
getConstant
(
Constants
.
GC_JVM_STACK_MOVE_
UN
IT
);
//sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
}
catch
(
UnsatisfiedLinkError
ee
)
{
// ignore; if we use init() methods later we'll see linkage errors
...
...
@@ -149,7 +149,7 @@ class MethodHandleNatives {
// MethodHandleImpl
static
final
int
// for getConstant
GC_JVM_PUSH_LIMIT
=
0
,
GC_JVM_STACK_MOVE_
LIM
IT
=
1
;
GC_JVM_STACK_MOVE_
UN
IT
=
1
;
static
final
int
ETF_HANDLE_OR_METHOD_NAME
=
0
,
// all available data (immediate MH or method)
ETF_DIRECT_HANDLE
=
1
,
// ultimate method handle (will be a DMH, may be self)
...
...
@@ -178,19 +178,20 @@ class MethodHandleNatives {
*/
static
final
int
OP_RETYPE_ONLY
=
0x0
,
// no argument changes; straight retype
OP_CHECK_CAST
=
0x1
,
// ref-to-ref conversion; requires a Class argument
OP_PRIM_TO_PRIM
=
0x2
,
// converts from one primitive to another
OP_REF_TO_PRIM
=
0x3
,
// unboxes a wrapper to produce a primitive
OP_PRIM_TO_REF
=
0x4
,
// boxes a primitive into a wrapper (NYI)
OP_SWAP_ARGS
=
0x5
,
// swap arguments (vminfo is 2nd arg)
OP_ROT_ARGS
=
0x6
,
// rotate arguments (vminfo is displaced arg)
OP_DUP_ARGS
=
0x7
,
// duplicates one or more arguments (at TOS)
OP_DROP_ARGS
=
0x8
,
// remove one or more argument slots
OP_COLLECT_ARGS
=
0x9
,
// combine one or more arguments into a varargs (NYI)
OP_SPREAD_ARGS
=
0xA
,
// expand in place a varargs array (of known size)
OP_FLYBY
=
0xB
,
// operate first on reified argument list (NYI)
OP_RICOCHET
=
0xC
,
// run an adapter chain on the return value (NYI)
CONV_OP_LIMIT
=
0xD
;
// limit of CONV_OP enumeration
OP_RETYPE_RAW
=
0x1
,
// no argument changes; straight retype
OP_CHECK_CAST
=
0x2
,
// ref-to-ref conversion; requires a Class argument
OP_PRIM_TO_PRIM
=
0x3
,
// converts from one primitive to another
OP_REF_TO_PRIM
=
0x4
,
// unboxes a wrapper to produce a primitive
OP_PRIM_TO_REF
=
0x5
,
// boxes a primitive into a wrapper (NYI)
OP_SWAP_ARGS
=
0x6
,
// swap arguments (vminfo is 2nd arg)
OP_ROT_ARGS
=
0x7
,
// rotate arguments (vminfo is displaced arg)
OP_DUP_ARGS
=
0x8
,
// duplicates one or more arguments (at TOS)
OP_DROP_ARGS
=
0x9
,
// remove one or more argument slots
OP_COLLECT_ARGS
=
0xA
,
// combine one or more arguments into a varargs (NYI)
OP_SPREAD_ARGS
=
0xB
,
// expand in place a varargs array (of known size)
OP_FLYBY
=
0xC
,
// operate first on reified argument list (NYI)
OP_RICOCHET
=
0xD
,
// run an adapter chain on the return value (NYI)
CONV_OP_LIMIT
=
0xE
;
// limit of CONV_OP enumeration
/** Shift and mask values for decoding the AMH.conversion field.
* These numbers are shared with the JVM for creating AMHs.
*/
...
...
@@ -209,6 +210,7 @@ class MethodHandleNatives {
// TODO: The following expression should be replaced by
// a JVM query.
((
1
<<
OP_RETYPE_ONLY
)
|(
1
<<
OP_RETYPE_RAW
)
|(
1
<<
OP_CHECK_CAST
)
|(
1
<<
OP_PRIM_TO_PRIM
)
|(
1
<<
OP_REF_TO_PRIM
)
...
...
@@ -216,6 +218,7 @@ class MethodHandleNatives {
|(
1
<<
OP_ROT_ARGS
)
|(
1
<<
OP_DUP_ARGS
)
|(
1
<<
OP_DROP_ARGS
)
//|(1<<OP_SPREAD_ARGS) // FIXME: Check JVM assembly code.
);
/**
...
...
jdk/src/share/classes/sun/dyn/MethodTypeImpl.java
浏览文件 @
4a61e19d
...
...
@@ -27,6 +27,7 @@ package sun.dyn;
import
java.dyn.*
;
import
sun.dyn.util.Wrapper
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
/**
* Shared information for a group of method types, which differ
...
...
@@ -56,8 +57,8 @@ public class MethodTypeImpl {
// Cached adapter information:
/*lazy*/
ToGeneric
toGeneric
;
// convert cs. with prims to w/o
/*lazy*/
FromGeneric
fromGeneric
;
// convert cs. w/o prims to with
/*lazy*/
SpreadGeneric
[]
spreadGeneric
;
// expand one argument to many
/*lazy*/
FilterGeneric
filterGeneric
;
// convert argument(s) on the fly
///*lazy*/ Invokers invokers; // cache of handy higher-order adapters
public
MethodType
erasedType
()
{
return
erasedType
;
...
...
@@ -68,7 +69,7 @@ public class MethodTypeImpl {
}
/** Access methods for the internals of MethodType, supplied to
* MethodType
Form
as a trusted agent.
* MethodType
Impl
as a trusted agent.
*/
static
public
interface
MethodTypeFriend
{
Class
<?>[]
ptypes
(
MethodType
mt
);
...
...
@@ -150,7 +151,7 @@ public class MethodTypeImpl {
this
.
argToSlotTable
=
argToSlotTab
;
this
.
slotToArgTable
=
slotToArgTab
;
if
(
pslotCount
>=
256
)
throw
new
IllegalArgumentException
(
"too many arguments"
);
if
(
pslotCount
>=
256
)
throw
newIllegalArgumentException
(
"too many arguments"
);
// send a few bits down to the JVM:
this
.
vmslots
=
parameterSlotCount
();
...
...
@@ -378,10 +379,10 @@ public class MethodTypeImpl {
static
MethodTypeImpl
findForm
(
MethodType
mt
)
{
MethodType
erased
=
canonicalize
(
mt
,
ERASE
,
ERASE
);
if
(
erased
==
null
)
{
// It is already erased. Make a new MethodType
Form
.
// It is already erased. Make a new MethodType
Impl
.
return
METHOD_TYPE_FRIEND
.
newMethodTypeForm
(
mt
);
}
else
{
// Share the MethodType
Form
with the erased version.
// Share the MethodType
Impl
with the erased version.
return
METHOD_TYPE_FRIEND
.
form
(
erased
);
}
}
...
...
jdk/src/share/classes/sun/dyn/SpreadGeneric.java
0 → 100644
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/sun/dyn/ToGeneric.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/sun/dyn/empty/Empty.java
浏览文件 @
4a61e19d
...
...
@@ -29,6 +29,10 @@ package sun.dyn.empty;
* An empty class in an empty package.
* Used as a proxy for unprivileged code, since making access checks
* against it will only succeed against public methods in public types.
* <p>
* This class also stands (internally to sun.dyn) for the type of a
* value that cannot be produced, because the expression of this type
* always returns abnormally. (Cf. Nothing in the closures proposal.)
* @author jrose
*/
public
class
Empty
{
...
...
jdk/src/share/classes/sun/dyn/util/Bytecode
Signature
.java
→
jdk/src/share/classes/sun/dyn/util/Bytecode
Descriptor
.java
浏览文件 @
4a61e19d
...
...
@@ -33,9 +33,9 @@ import java.util.List;
* Utility routines for dealing with bytecode-level signatures.
* @author jrose
*/
public
class
Bytecode
Signature
{
public
class
Bytecode
Descriptor
{
private
Bytecode
Signature
()
{
}
// cannot instantiate
private
Bytecode
Descriptor
()
{
}
// cannot instantiate
public
static
List
<
Class
<?>>
parseMethod
(
String
bytecodeSignature
,
ClassLoader
loader
)
{
return
parseMethod
(
bytecodeSignature
,
0
,
bytecodeSignature
.
length
(),
loader
);
...
...
jdk/src/share/classes/sun/dyn/util/BytecodeName.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/sun/dyn/util/ValueConversions.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/sun/dyn/util/VerifyAccess.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/src/share/classes/sun/dyn/util/VerifyType.java
浏览文件 @
4a61e19d
...
...
@@ -26,6 +26,7 @@
package
sun.dyn.util
;
import
java.dyn.MethodType
;
import
sun.dyn.empty.Empty
;
/**
* This class centralizes information about the JVM verifier
...
...
@@ -73,29 +74,28 @@ public class VerifyType {
}
/**
* Is the given type either java.lang.Void or java.lang.Null?
* These types serve as markers for bare nulls and therefore
* may be promoted to any type. This is secure, since
* Is the given type java.lang.Null or an equivalent null-only type?
*/
public
static
boolean
isNullType
(
Class
<?>
type
)
{
if
(
type
==
null
)
return
false
;
return
type
==
NULL_CLASS_1
||
type
==
NULL_CLASS_2
;
return
type
==
NULL_CLASS
// This one may also be used as a null type.
// TO DO: Decide if we really want to legitimize it here.
// Probably we do, unless java.lang.Null really makes it into Java 7
//|| type == Void.class
// Locally known null-only class:
||
type
==
Empty
.
class
;
}
private
static
final
Class
<?>
NULL_CLASS
_1
,
NULL_CLASS_2
;
private
static
final
Class
<?>
NULL_CLASS
;
static
{
Class
<?>
nullClass
1
=
null
,
nullClass2
=
null
;
Class
<?>
nullClass
=
null
;
try
{
nullClass
1
=
Class
.
forName
(
"java.lang.Null"
);
nullClass
=
Class
.
forName
(
"java.lang.Null"
);
}
catch
(
ClassNotFoundException
ex
)
{
// OK, we'll cope
}
NULL_CLASS_1
=
nullClass1
;
// This one may also be used as a null type.
// TO DO: Decide if we really want to legitimize it here.
// Probably we do, unless java.lang.Null really makes it into Java 7
nullClass2
=
Void
.
class
;
NULL_CLASS_2
=
nullClass2
;
NULL_CLASS
=
nullClass
;
}
/**
...
...
@@ -191,6 +191,11 @@ public class VerifyType {
// to be captured as a garbage int.
// Caller promises that the actual value will be disregarded.
return
dst
==
int
.
class
?
1
:
0
;
if
(
isNullType
(
src
))
// Special permission for raw conversions: allow a null
// to be reinterpreted as anything. For objects, it is safe,
// and for primitives you get a garbage value (probably zero).
return
1
;
if
(!
src
.
isPrimitive
())
return
0
;
Wrapper
sw
=
Wrapper
.
forPrimitiveType
(
src
);
...
...
jdk/src/share/classes/sun/dyn/util/Wrapper.java
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
jdk/test/java/dyn/MethodHandlesTest.java
0 → 100644
浏览文件 @
4a61e19d
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录