meth: argument rotation adapters
authorjrose
Thu Jul 02 03:34:06 2009 -0700 (4 months ago)
changeset 51e1f9d04b190c
parent 50d132ac2af97a
child 52c9eda12bdd9e
meth: argument rotation adapters
indy.patch
--- a/indy.patch Tue Jun 30 19:05:20 2009 +0200
+++ b/indy.patch Thu Jul 02 03:34:06 2009 -0700
@@ -13,7 +13,7 @@ diff --git a/src/share/classes/java/dyn/
/**
* An {@code invokedynamic} call site, as reified by the
-@@ -52,15 +55,25 @@ import sun.dyn.util.BytecodeName;
+@@ -52,15 +55,25 @@
* @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
* @author John Rose, JSR 292 EG
*/
@@ -41,7 +41,7 @@ diff --git a/src/share/classes/java/dyn/
/**
* Make a call site given the parameters from a call to the bootstrap method.
-@@ -72,16 +85,21 @@ public class CallSite {
+@@ -72,16 +85,21 @@
* @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
*/
public CallSite(Object caller, String name, MethodType type) {
@@ -68,7 +68,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -102,10 +120,11 @@ public class CallSite {
+@@ -102,10 +120,11 @@
/**
* Report the current linkage state of the call site. (This is mutable.)
@@ -84,7 +84,7 @@ diff --git a/src/share/classes/java/dyn/
* <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 {
+@@ -118,7 +137,7 @@
* @see #setTarget
*/
public MethodHandle getTarget() {
@@ -93,7 +93,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -140,7 +159,7 @@ public class CallSite {
+@@ -140,7 +159,7 @@
*/
public void setTarget(MethodHandle target) {
checkTarget(target);
@@ -102,7 +102,7 @@ diff --git a/src/share/classes/java/dyn/
}
protected void checkTarget(MethodHandle target) {
-@@ -219,6 +238,10 @@ public class CallSite {
+@@ -219,6 +238,10 @@
@Override
public String toString() {
@@ -117,7 +117,7 @@ diff --git a/src/share/classes/java/dyn/
diff --git a/src/share/classes/java/dyn/InvokeDynamic.java b/src/share/classes/java/dyn/InvokeDynamic.java
--- a/src/share/classes/java/dyn/InvokeDynamic.java
+++ b/src/share/classes/java/dyn/InvokeDynamic.java
-@@ -45,6 +45,24 @@ package java.dyn;
+@@ -45,6 +45,24 @@
* 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.
@@ -145,7 +145,7 @@ diff --git a/src/share/classes/java/dyn/
diff --git a/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java b/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
--- a/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
+++ b/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
-@@ -52,4 +52,16 @@ public class InvokeDynamicBootstrapError
+@@ -52,4 +52,16 @@
public InvokeDynamicBootstrapError(String s) {
super(s);
}
@@ -174,7 +174,7 @@ diff --git a/src/share/classes/java/dyn/
/**
* A Java method handle extends the basic method handle type with additional
* programmer defined methods and fields.
-@@ -41,29 +43,43 @@ package java.dyn;
+@@ -41,29 +43,43 @@
* <p>
* Here is an example of usage:
* <p><blockquote><pre>
@@ -235,7 +235,7 @@ diff --git a/src/share/classes/java/dyn/
* @see MethodHandle
* @author John Rose, JSR 292 EG
*/
-@@ -72,12 +88,63 @@ public abstract class JavaMethodHandle
+@@ -72,12 +88,63 @@
// with a JVM change which moves the required hidden behavior onto this class.
extends sun.dyn.BoundMethodHandle
{
@@ -316,7 +316,7 @@ diff --git a/src/share/classes/java/dyn/
import sun.reflect.Reflection;
import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege;
-@@ -34,6 +36,8 @@ import static sun.dyn.util.VerifyAccess.
+@@ -34,6 +36,8 @@
* @author John Rose, JSR 292 EG
*/
public class Linkage {
@@ -325,7 +325,7 @@ diff --git a/src/share/classes/java/dyn/
private Linkage() {} // do not instantiate
/**
-@@ -53,19 +57,23 @@ public class Linkage {
+@@ -53,19 +57,23 @@
* 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.
@@ -352,7 +352,7 @@ diff --git a/src/share/classes/java/dyn/
}
}
-@@ -88,8 +96,9 @@ public class Linkage {
+@@ -88,8 +96,9 @@
public static
void registerBootstrapMethod(Class<?> runtime, String name) {
Class callc = Reflection.getCallerClass(2);
@@ -363,7 +363,7 @@ diff --git a/src/share/classes/java/dyn/
// FIXME: exception processing wrong here
checkBSM(bootstrapMethod);
Linkage.registerBootstrapMethod(callc, bootstrapMethod);
-@@ -106,8 +115,9 @@ public class Linkage {
+@@ -106,8 +115,9 @@
public static
void registerBootstrapMethod(String name) {
Class callc = Reflection.getCallerClass(2);
@@ -374,7 +374,7 @@ diff --git a/src/share/classes/java/dyn/
// FIXME: exception processing wrong here
checkBSM(bootstrapMethod);
Linkage.registerBootstrapMethod(callc, bootstrapMethod);
-@@ -116,8 +126,7 @@ public class Linkage {
+@@ -116,8 +126,7 @@
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Report the bootstrap method registered for a given class.
@@ -384,7 +384,7 @@ diff --git a/src/share/classes/java/dyn/
* 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.
-@@ -173,8 +182,8 @@ public class Linkage {
+@@ -173,8 +182,8 @@
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
@@ -398,7 +398,7 @@ diff --git a/src/share/classes/java/dyn/
diff --git a/src/share/classes/java/dyn/LinkagePermission.java b/src/share/classes/java/dyn/LinkagePermission.java
--- a/src/share/classes/java/dyn/LinkagePermission.java
+++ b/src/share/classes/java/dyn/LinkagePermission.java
-@@ -88,7 +88,7 @@ public final class LinkagePermission ext
+@@ -88,7 +88,7 @@
/**
* Create a new LinkagePermission with the given name.
* The name is the symbolic name of the LinkagePermission, such as
@@ -410,7 +410,7 @@ diff --git a/src/share/classes/java/dyn/
diff --git a/src/share/classes/java/dyn/MethodHandle.java b/src/share/classes/java/dyn/MethodHandle.java
--- a/src/share/classes/java/dyn/MethodHandle.java
+++ b/src/share/classes/java/dyn/MethodHandle.java
-@@ -45,8 +45,9 @@ import sun.dyn.MethodHandleImpl;
+@@ -45,8 +45,9 @@
* Every method handle appears as an object containing a method named
* <code>invoke</code>, whose signature exactly matches
* the method handle's type.
@@ -422,7 +422,7 @@ diff --git a/src/share/classes/java/dyn/
* <p>
* Every call to a method handle specifies an intended method type,
* which must exactly match the type of the method handle.
-@@ -57,6 +58,10 @@ import sun.dyn.MethodHandleImpl;
+@@ -57,6 +58,10 @@
* The call fails with a {@link WrongMethodTypeException}
* if the method does not exist, even if there is an <code>invoke</code>
* method of a closely similar signature.
@@ -433,7 +433,7 @@ diff --git a/src/share/classes/java/dyn/
* <p>
* A method handle is an unrestricted capability to call a method.
* A method handle can be formed on a non-public method by a class
-@@ -74,6 +79,15 @@ import sun.dyn.MethodHandleImpl;
+@@ -74,6 +79,15 @@
* (after resolving symbolic type names) must exactly match the method type
* of the target method.
* <p>
@@ -449,7 +449,7 @@ diff --git a/src/share/classes/java/dyn/
* Bytecode in an extended JVM can directly obtain a method handle
* for any accessible method from a <code>ldc</code> instruction
* which refers to a <code>CONSTANT_Methodref</code> or
-@@ -97,6 +111,59 @@ import sun.dyn.MethodHandleImpl;
+@@ -97,6 +111,59 @@
* can also be created. These do not perform virtual lookup based on
* receiver type. Such a method handle simulates the effect of
* an <code>invokespecial</code> instruction to the same method.
@@ -509,7 +509,7 @@ diff --git a/src/share/classes/java/dyn/
*
* @see MethodType
* @see MethodHandles
-@@ -107,10 +174,12 @@ public abstract class MethodHandle
+@@ -107,10 +174,12 @@
// with a JVM change which moves the required hidden state onto this class.
extends MethodHandleImpl
{
@@ -525,7 +525,7 @@ diff --git a/src/share/classes/java/dyn/
/**
* Report the type of this method handle.
-@@ -130,6 +199,33 @@ public abstract class MethodHandle
+@@ -130,6 +199,33 @@
*/
protected MethodHandle(Access token, MethodType type) {
super(token);
@@ -562,7 +562,7 @@ diff --git a/src/share/classes/java/dyn/
diff --git a/src/share/classes/java/dyn/MethodHandles.java b/src/share/classes/java/dyn/MethodHandles.java
--- a/src/share/classes/java/dyn/MethodHandles.java
+++ b/src/share/classes/java/dyn/MethodHandles.java
-@@ -44,17 +44,14 @@ import static sun.dyn.MemberName.newNoAc
+@@ -44,17 +44,14 @@
/**
* Fundamental operations and utilities for MethodHandle.
@@ -587,7 +587,7 @@ diff --git a/src/share/classes/java/dyn/
* @author John Rose, JSR 292 EG
*/
public class MethodHandles {
-@@ -68,12 +65,22 @@ public class MethodHandles {
+@@ -68,12 +65,22 @@
//// Method handle creation from ordinary methods.
@@ -611,7 +611,7 @@ diff --git a/src/share/classes/java/dyn/
* A factory object for creating method handles, when the creation
* requires access checking. Method handles do not perform
* access checks when they are called; this is a major difference
-@@ -121,7 +128,8 @@ public class MethodHandles {
+@@ -121,7 +128,8 @@
/** Which class is performing the lookup? It is this class against
* which checks are performed for visibility and access permissions.
* <p>
@@ -621,7 +621,7 @@ diff --git a/src/share/classes/java/dyn/
*/
public Class<?> lookupClass() {
return lookupClass;
-@@ -135,23 +143,46 @@ public class MethodHandles {
+@@ -135,23 +143,46 @@
* an access$N method.
*/
Lookup() {
@@ -673,7 +673,7 @@ diff --git a/src/share/classes/java/dyn/
/** Package-private version of lookup which is trusted. */
static final Lookup IMPL_LOOKUP = new Lookup(null);
-@@ -178,12 +209,16 @@ public class MethodHandles {
+@@ -178,12 +209,16 @@
// 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
// 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
// Note: This should be the only use of getCallerClass in this file.
@@ -690,7 +690,7 @@ diff --git a/src/share/classes/java/dyn/
* The method and all its argument types must be accessible to the lookup class.
* If the method's class has not yet been initialized, that is done
* immediately, before the method handle is returned.
-@@ -196,10 +231,11 @@ public class MethodHandles {
+@@ -196,10 +231,11 @@
*/
public
MethodHandle findStatic(Class<?> defc, String name, MethodType type) throws NoAccessException {
@@ -705,7 +705,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -228,9 +264,10 @@ public class MethodHandles {
+@@ -228,9 +264,10 @@
* @exception NoAccessException if the method does not exist or access checking fails
*/
public MethodHandle findVirtual(Class<?> defc, String name, MethodType type) throws NoAccessException {
@@ -719,7 +719,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -259,15 +296,17 @@ public class MethodHandles {
+@@ -259,15 +296,17 @@
*/
public MethodHandle findSpecial(Class<?> defc, String name, MethodType type,
Class<?> specialCaller) throws NoAccessException {
@@ -742,7 +742,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -275,13 +314,19 @@ public class MethodHandles {
+@@ -275,13 +314,19 @@
* The receiver must have a supertype {@code defc} in which a method
* of the given name and type is accessible to the lookup class.
* The method and all its argument types must be accessible to the lookup class.
@@ -766,7 +766,7 @@ diff --git a/src/share/classes/java/dyn/
* @param receiver the object from which the method is accessed
* @param name the name of the method
* @param type the type of the method, with the receiver argument omitted
-@@ -292,16 +337,18 @@ public class MethodHandles {
+@@ -292,16 +337,18 @@
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoAccessException {
Class<? extends Object> rcvc = receiver.getClass(); // may get NPE
MemberName reference = new MemberName(rcvc, name, type);
@@ -789,7 +789,7 @@ diff --git a/src/share/classes/java/dyn/
* Make a direct method handle to <i>m</i>, if the lookup class has permission.
* If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
* If <i>m</i> is virtual, overriding is respected on every call.
-@@ -316,10 +363,11 @@ public class MethodHandles {
+@@ -316,10 +363,11 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflect(Method m) throws NoAccessException {
@@ -802,7 +802,7 @@ diff --git a/src/share/classes/java/dyn/
* Produce a method handle for a reflected method.
* It will bypass checks for overriding methods on the receiver,
* as if by the {@code invokespecial} instruction.
-@@ -333,37 +381,41 @@ public class MethodHandles {
+@@ -333,37 +381,41 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws NoAccessException {
@@ -853,7 +853,7 @@ diff --git a/src/share/classes/java/dyn/
* If the method's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field
-@@ -371,16 +423,17 @@ public class MethodHandles {
+@@ -371,16 +423,17 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectGetter(Field f) throws NoAccessException {
@@ -875,7 +875,7 @@ diff --git a/src/share/classes/java/dyn/
* If the method's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field
-@@ -388,59 +441,63 @@ public class MethodHandles {
+@@ -388,59 +441,63 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSetter(Field f) throws NoAccessException {
@@ -958,7 +958,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -472,7 +529,6 @@ public class MethodHandles {
+@@ -472,7 +529,6 @@
return MethodHandleImpl.accessArrayElement(IMPL_TOKEN, arrayClass, true);
}
@@ -966,7 +966,7 @@ diff --git a/src/share/classes/java/dyn/
/// method handle invocation (reflective style)
/**
-@@ -500,110 +556,203 @@ public class MethodHandles {
+@@ -500,110 +556,203 @@
* or forced to null if the return type is void.
* <p>
* This call is a convenience method for the following code:
@@ -1213,7 +1213,7 @@ diff --git a/src/share/classes/java/dyn/
* @param type the desired target type
* @return a method handle suitable for invoking any method handle of the given type
*/
-@@ -612,6 +761,29 @@ public class MethodHandles {
+@@ -612,6 +761,29 @@
return invokers(type).exactInvoker();
}
@@ -1243,7 +1243,7 @@ diff --git a/src/share/classes/java/dyn/
static private Invokers invokers(MethodType type) {
return MethodTypeImpl.invokers(IMPL_TOKEN, type);
}
-@@ -690,12 +862,10 @@ public class MethodHandles {
+@@ -690,12 +862,10 @@
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts the type of the
@@ -1259,7 +1259,7 @@ diff --git a/src/share/classes/java/dyn/
* <p>
* If the original type and new type are equal, returns target.
* <p>
-@@ -703,26 +873,15 @@ public class MethodHandles {
+@@ -703,26 +873,15 @@
* arguments and return types. Let T0 and T1 be the differing
* new and old parameter types (or old and new return types)
* for corresponding values passed by the new and old method types.
@@ -1292,7 +1292,7 @@ diff --git a/src/share/classes/java/dyn/
* <li>If T0 and T1 are primitives, then a Java casting
* conversion (JLS 5.5) is applied, if one exists.
* <li>If T0 and T1 are primitives and one is boolean,
-@@ -745,9 +904,9 @@ public class MethodHandles {
+@@ -745,9 +904,9 @@
* if necessary to T1 by one of the preceding conversions.
* Otherwise, T0 is converted directly to the wrapper type for T1,
* which is then unboxed.
@@ -1305,7 +1305,7 @@ diff --git a/src/share/classes/java/dyn/
* </ul>
* @param target the method handle to invoke after arguments are retyped
* @param newType the expected type of the new method handle
-@@ -872,20 +1031,14 @@ public class MethodHandles {
+@@ -872,20 +1031,14 @@
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts the type of the
* given method handle to a new type, by collecting a series of
@@ -1328,7 +1328,7 @@ diff --git a/src/share/classes/java/dyn/
* @param target the method handle to invoke after the argument is prepended
* @param newType the expected type of the new method handle
* @return a new method handle which collects some trailings argument
-@@ -900,50 +1053,66 @@ public class MethodHandles {
+@@ -900,50 +1053,66 @@
int numCollect = (inargs - collectPos);
if (collectPos < 0 || numCollect < 0)
throw newIllegalArgumentException("wrong number of arguments");
@@ -1420,7 +1420,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -953,10 +1122,25 @@ public class MethodHandles {
+@@ -953,10 +1122,25 @@
* The type of the new method handle will insert the given argument
* type(s), at that position, into the original handle's type.
* <p>
@@ -1447,7 +1447,7 @@ diff --git a/src/share/classes/java/dyn/
* @param target the method handle to invoke after the argument is dropped
* @param valueTypes the type(s) of the argument to drop
* @param pos which argument to drop (zero for the first)
-@@ -980,6 +1164,131 @@ public class MethodHandles {
+@@ -980,6 +1164,131 @@
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
@@ -1579,7 +1579,7 @@ diff --git a/src/share/classes/java/dyn/
* Make a method handle which adapts a target method handle,
* by guarding it with a test, a boolean-valued method handle.
* If the guard fails, a fallback handle is called instead.
-@@ -1040,65 +1349,100 @@ public class MethodHandles {
+@@ -1040,65 +1349,100 @@
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
@@ -1735,7 +1735,7 @@ diff --git a/src/share/classes/java/dyn/
diff --git a/src/share/classes/java/dyn/MethodType.java b/src/share/classes/java/dyn/MethodType.java
--- a/src/share/classes/java/dyn/MethodType.java
+++ b/src/share/classes/java/dyn/MethodType.java
-@@ -32,7 +32,7 @@ import java.util.List;
+@@ -32,7 +32,7 @@
import sun.dyn.Access;
import sun.dyn.Invokers;
import sun.dyn.MethodTypeImpl;
@@ -1744,7 +1744,7 @@ diff --git a/src/share/classes/java/dyn/
import static sun.dyn.MemberName.newIllegalArgumentException;
/**
-@@ -63,7 +63,7 @@ class MethodType {
+@@ -63,7 +63,7 @@
static {
// This hack allows the implementation package special access to
@@ -1753,7 +1753,7 @@ diff --git a/src/share/classes/java/dyn/
// of cached information useful to the implementation code.
MethodTypeImpl.setMethodTypeFriend(IMPL_TOKEN, new MethodTypeImpl.MethodTypeFriend() {
public Class<?>[] ptypes(MethodType mt) { return mt.ptypes; }
-@@ -202,10 +202,11 @@ class MethodType {
+@@ -202,10 +202,11 @@
private static final MethodType[] objectOnlyTypes = new MethodType[20];
/**
@@ -1768,7 +1768,7 @@ diff --git a/src/share/classes/java/dyn/
* @return a totally generic method type, given only its count of parameters and varargs
* @see #makeGeneric(int)
*/
-@@ -239,7 +240,7 @@ class MethodType {
+@@ -239,7 +240,7 @@
return makeGeneric(objectArgCount, false);
}
@@ -1777,7 +1777,7 @@ diff --git a/src/share/classes/java/dyn/
* @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,7 +252,7 @@ class MethodType {
+@@ -251,7 +252,7 @@
return makeImpl(rtype, nptypes, true);
}
@@ -1786,7 +1786,7 @@ diff --git a/src/share/classes/java/dyn/
* @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
-@@ -264,7 +265,7 @@ class MethodType {
+@@ -264,7 +265,7 @@
return makeImpl(rtype, nptypes, true);
}
@@ -1795,7 +1795,7 @@ diff --git a/src/share/classes/java/dyn/
* @param num the index (zero-based) of the parameter type to remove
* @return the same type, except with the selected parameter removed
*/
-@@ -280,7 +281,7 @@ class MethodType {
+@@ -280,7 +281,7 @@
return makeImpl(rtype, nptypes, true);
}
@@ -1804,7 +1804,7 @@ diff --git a/src/share/classes/java/dyn/
* @param nrtype a return parameter type to replace the old one with
* @return the same type, except with the return type change
*/
-@@ -291,6 +292,7 @@ class MethodType {
+@@ -291,6 +292,7 @@
/** Convenience method.
* Report if this type contains a primitive argument or return value.
@@ -1812,7 +1812,7 @@ diff --git a/src/share/classes/java/dyn/
* @return true if any of the types are primitives
*/
public boolean hasPrimitives() {
-@@ -300,6 +302,7 @@ class MethodType {
+@@ -300,6 +302,7 @@
/** Convenience method.
* Report if this type contains a wrapper argument or return value.
* Wrappers are types which box primitive values, such as {@link Integer}.
@@ -1820,7 +1820,7 @@ diff --git a/src/share/classes/java/dyn/
* @return true if any of the types are wrappers
*/
public boolean hasWrappers() {
-@@ -307,7 +310,8 @@ class MethodType {
+@@ -307,7 +310,8 @@
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
@@ -1830,7 +1830,7 @@ diff --git a/src/share/classes/java/dyn/
* @return a version of the original type with all reference types replaced
*/
public MethodType erase() {
-@@ -315,7 +319,9 @@ class MethodType {
+@@ -315,7 +319,9 @@
}
/** Convenience method for {@link #makeGeneric(int)}.
@@ -1841,7 +1841,7 @@ diff --git a/src/share/classes/java/dyn/
* @return a version of the original type with all types replaced
*/
public MethodType generic() {
-@@ -324,7 +330,10 @@ class MethodType {
+@@ -324,7 +330,10 @@
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
* Convert all primitive types to their corresponding wrapper types.
@@ -1852,7 +1852,7 @@ diff --git a/src/share/classes/java/dyn/
* @return a version of the original type with all primitive types replaced
*/
public MethodType wrap() {
-@@ -333,6 +342,7 @@ class MethodType {
+@@ -333,6 +342,7 @@
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
* Convert all wrapper types to their corresponding primitive types.
@@ -1860,7 +1860,7 @@ diff --git a/src/share/classes/java/dyn/
* 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 +401,7 @@ class MethodType {
+@@ -391,6 +401,7 @@
/**
* Convenience method to present the arguments as an array.
@@ -1868,7 +1868,7 @@ diff --git a/src/share/classes/java/dyn/
* @return the parameter types (as a fresh copy if necessary)
*/
public Class<?>[] parameterArray() {
-@@ -491,7 +502,7 @@ class MethodType {
+@@ -491,7 +502,7 @@
return form.parameterSlotCount();
}
@@ -1877,7 +1877,7 @@ diff --git a/src/share/classes/java/dyn/
* 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
-@@ -544,16 +555,16 @@ class MethodType {
+@@ -544,16 +555,16 @@
* <p>
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
@@ -1897,7 +1897,7 @@ diff --git a/src/share/classes/java/dyn/
Class<?> rtype = types.remove(types.size() - 1);
Class<?>[] ptypes = types.toArray(NO_PTYPES);
return makeImpl(rtype, ptypes, true);
-@@ -565,11 +576,21 @@ class MethodType {
+@@ -565,11 +576,21 @@
* <p>
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
@@ -1935,12 +1935,15 @@ diff --git a/src/share/classes/sun/dyn/A
diff --git a/src/share/classes/sun/dyn/AdapterMethodHandle.java b/src/share/classes/sun/dyn/AdapterMethodHandle.java
--- a/src/share/classes/sun/dyn/AdapterMethodHandle.java
+++ b/src/share/classes/sun/dyn/AdapterMethodHandle.java
-@@ -302,7 +302,19 @@ public class AdapterMethodHandle extends
+@@ -302,7 +302,22 @@
*/
private static int type2size(int type) {
assert(type >= T_BOOLEAN && type <= T_OBJECT);
- return (type == T_FLOAT || type == T_DOUBLE) ? 2 : 1;
+ return (type == T_LONG || type == T_DOUBLE) ? 2 : 1;
++ }
++ private static int type2size(Class<?> type) {
++ return type2size(basicType(type));
+ }
+
+ /** The given stackMove is the number of slots pushed.
@@ -1956,7 +1959,7 @@ diff --git a/src/share/classes/sun/dyn/A
}
/** Construct an adapter conversion descriptor for a single-argument conversion. */
-@@ -310,16 +322,16 @@ public class AdapterMethodHandle extends
+@@ -310,16 +325,16 @@
assert(src == (src & 0xF));
assert(dest == (dest & 0xF));
assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF);
@@ -1976,7 +1979,7 @@ diff --git a/src/share/classes/sun/dyn/A
byte src = 0, dest = 0;
if (convOp >= OP_COLLECT_ARGS && convOp <= OP_SPREAD_ARGS)
src = dest = T_OBJECT;
-@@ -327,12 +339,22 @@ public class AdapterMethodHandle extends
+@@ -327,12 +342,21 @@
(long) convOp << CONV_OP_SHIFT |
(int) src << CONV_SRC_TYPE_SHIFT |
(int) dest << CONV_DEST_TYPE_SHIFT |
@@ -1984,14 +1987,13 @@ diff --git a/src/share/classes/sun/dyn/A
+ insertStackMove(stackMove)
+ );
+ }
-+ private static long makeSwapConv(int convOp, int argnum, byte src, int slot2) {
++ private static long makeSwapConv(int convOp, int srcArg, byte type, int destSlot) {
+ assert(convOp >= OP_SWAP_ARGS && convOp <= OP_ROT_ARGS);
-+ byte dest = src;
-+ return ((long) argnum << 32 |
++ return ((long) srcArg << 32 |
+ (long) convOp << CONV_OP_SHIFT |
-+ (int) src << CONV_SRC_TYPE_SHIFT |
-+ (int) dest << CONV_DEST_TYPE_SHIFT |
-+ (int) slot2 << CONV_VMINFO_SHIFT
++ (int) type << CONV_SRC_TYPE_SHIFT |
++ (int) type << CONV_DEST_TYPE_SHIFT |
++ (int) destSlot << CONV_VMINFO_SHIFT
);
}
private static long makeConv(int convOp) {
@@ -2002,7 +2004,7 @@ diff --git a/src/share/classes/sun/dyn/A
}
private static int convCode(long conv) {
return (int)conv;
-@@ -348,16 +370,6 @@ public class AdapterMethodHandle extends
+@@ -348,16 +372,6 @@
/** One of OP_RETYPE_ONLY, etc. */
int conversionOp() { return (conversion & CONV_OP_MASK) >> CONV_OP_SHIFT; }
@@ -2019,7 +2021,7 @@ diff --git a/src/share/classes/sun/dyn/A
/* Return one plus the position of the first non-trivial difference
* between the given types. This is not a symmetric operation;
* we are considering adapting the targetType to adapterType.
-@@ -399,14 +411,14 @@ public class AdapterMethodHandle extends
+@@ -399,14 +413,14 @@
//if (false) return 1; // never adaptable!
return -1; // some significant difference
}
@@ -2038,7 +2040,7 @@ diff --git a/src/share/classes/sun/dyn/A
if ((!raw
? VerifyType.canPassUnchecked(src, dest)
: VerifyType.canPassRaw(src, dest)
-@@ -422,7 +434,7 @@ public class AdapterMethodHandle extends
+@@ -422,7 +436,7 @@
/** Can a retyping adapter (alone) validly convert the target to newType? */
public static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
@@ -2047,7 +2049,7 @@ diff --git a/src/share/classes/sun/dyn/A
}
/** Can a retyping adapter (alone) convert the target to newType?
* It is allowed to widen subword types and void to int, to make bitwise
-@@ -430,14 +442,14 @@ public class AdapterMethodHandle extends
+@@ -430,14 +444,14 @@
* reference conversions on return. This last feature requires that the
* caller be trusted, and perform explicit cast conversions on return values.
*/
@@ -2067,7 +2069,7 @@ diff --git a/src/share/classes/sun/dyn/A
return diff == 0;
}
-@@ -447,19 +459,21 @@ public class AdapterMethodHandle extends
+@@ -447,19 +461,21 @@
*/
public static MethodHandle makeRetypeOnly(Access token,
MethodType newType, MethodHandle target) {
@@ -2095,7 +2097,7 @@ diff --git a/src/share/classes/sun/dyn/A
}
/** Can a checkcast adapter validly convert the target to newType?
-@@ -492,7 +506,7 @@ public class AdapterMethodHandle extends
+@@ -492,7 +508,7 @@
Access.check(token);
if (!canCheckCast(newType, target.type(), arg, castType))
return null;
@@ -2104,7 +2106,19 @@ diff --git a/src/share/classes/sun/dyn/A
return new AdapterMethodHandle(target, newType, conv, castType);
}
-@@ -607,8 +621,6 @@ public class AdapterMethodHandle extends
+@@ -537,10 +553,9 @@
+ int arg, Class<?> convType) {
+ Access.check(token);
+ MethodType oldType = target.type();
+- Class<?> src = newType.parameterType(arg);
+- Class<?> dst = oldType.parameterType(arg);
+ if (!canPrimCast(newType, oldType, arg, convType))
+ return null;
++ Class<?> src = newType.parameterType(arg);
+ long conv = makeConv(OP_PRIM_TO_PRIM, arg, basicType(src), basicType(convType));
+ return new AdapterMethodHandle(target, newType, conv);
+ }
+@@ -607,8 +622,6 @@
return null;
}
@@ -2113,7 +2127,7 @@ diff --git a/src/share/classes/sun/dyn/A
/** Can an adapter simply drop arguments to convert the target to newType? */
public static boolean canDropArguments(MethodType newType, MethodType targetType,
int dropArgPos, int dropArgCount) {
-@@ -643,26 +655,106 @@ public class AdapterMethodHandle extends
+@@ -643,26 +656,195 @@
Access.check(token);
if (dropArgCount == 0)
return makeRetypeOnly(IMPL_TOKEN, newType, target);
@@ -2127,17 +2141,6 @@ diff --git a/src/share/classes/sun/dyn/A
- assert(dropArgPos == argCount-1);
- dropSlotPos = 0;
- dropSlotCount = mt.parameterSlotCount();
-- } else {
-- // arglist: [0: keep... | dpos: drop... | dpos+dcount: keep... ]
-- int lastDroppedArg = dropArgPos + dropArgCount - 1;
-- int lastKeptArg = dropArgPos - 1; // might be -1, which is OK
-- dropSlotPos = mt.parameterSlotDepth(1+lastDroppedArg);
-- int lastKeptSlot = mt.parameterSlotDepth(1+lastKeptArg);
-- dropSlotCount = lastKeptSlot - dropSlotPos;
-- assert(dropSlotCount >= dropArgCount);
-- }
-- long conv = makeConv(OP_DROP_ARGS, dropArgPos, +dropSlotCount);
-- return new AdapterMethodHandle(target, newType, dropSlotCount, conv);
+ // in arglist: [0: ...keep1 | dpos: drop... | dpos+dcount: keep2... ]
+ // out arglist: [0: ...keep1 | dpos: keep2... ]
+ int keep2InPos = dropArgPos + dropArgCount;
@@ -2232,14 +2235,112 @@ diff --git a/src/share/classes/sun/dyn/A
+ Class<?> swapType = newType.parameterType(swapArg1);
+ // in arglist: [0: ...keep1 | pos1: a1 | pos1+1: keep2... | pos2: a2 | pos2+1: keep3... ]
+ // out arglist: [0: ...keep1 | pos1: a2 | pos1+1: keep2... | pos2: a1 | pos2+1: keep3... ]
-+ int swapSlot1 = newType.parameterSlotDepth(swapArg1 + 1);
+ int swapSlot2 = newType.parameterSlotDepth(swapArg2 + 1);
+ long conv = makeSwapConv(OP_SWAP_ARGS, swapArg1, basicType(swapType), swapSlot2);
+ return new AdapterMethodHandle(target, newType, conv);
++ }
++
++ static int positiveRotation(int argCount, int rotateBy) {
++ assert(argCount > 0);
++ if (rotateBy >= 0) {
++ if (rotateBy < argCount)
++ return rotateBy;
++ return rotateBy % argCount;
++ } else if (rotateBy >= -argCount) {
++ return rotateBy + argCount;
+ } else {
+- // arglist: [0: keep... | dpos: drop... | dpos+dcount: keep... ]
+- int lastDroppedArg = dropArgPos + dropArgCount - 1;
+- int lastKeptArg = dropArgPos - 1; // might be -1, which is OK
+- dropSlotPos = mt.parameterSlotDepth(1+lastDroppedArg);
+- int lastKeptSlot = mt.parameterSlotDepth(1+lastKeptArg);
+- dropSlotCount = lastKeptSlot - dropSlotPos;
+- assert(dropSlotCount >= dropArgCount);
++ return (-1-((-1-rotateBy) % argCount)) + argCount;
+ }
+- long conv = makeConv(OP_DROP_ARGS, dropArgPos, +dropSlotCount);
+- return new AdapterMethodHandle(target, newType, dropSlotCount, conv);
++ }
++
++ final static int MAX_ARG_ROTATION = 1;
++
++ /** Can an adapter rotate arguments to convert the target to newType? */
++ public static boolean canRotateArguments(MethodType newType, MethodType targetType,
++ int firstArg, int argCount, int rotateBy) {
++ if (!convOpSupported(OP_ROT_ARGS)) return false;
++ if (argCount <= 2) return false; // must be a swap, not a rotate
++ rotateBy = positiveRotation(argCount, rotateBy);
++ if (rotateBy == 0) return false; // no rotation
++ if (rotateBy > MAX_ARG_ROTATION && rotateBy < argCount - MAX_ARG_ROTATION)
++ return false; // too many argument positions
++ // Rotate incoming args right N to the out args, N in 1..(argCouunt-1).
++ if (diffReturnTypes(newType, targetType, false) != 0)
++ return false;
++ int nptypes = newType.parameterCount();
++ if (targetType.parameterCount() != nptypes)
++ return false;
++ if (firstArg < 0 || firstArg >= nptypes) return false;
++ int argLimit = firstArg + argCount;
++ if (argLimit > nptypes) return false;
++ if (diffParamTypes(newType, 0, targetType, 0, firstArg, false) != 0)
++ return false;
++ int newChunk1 = argCount - rotateBy, newChunk2 = rotateBy;
++ // swap new chunk1 with target chunk2
++ if (diffParamTypes(newType, firstArg, targetType, argLimit-newChunk1, newChunk1, false) != 0)
++ return false;
++ // swap new chunk2 with target chunk1
++ if (diffParamTypes(newType, firstArg+newChunk1, targetType, firstArg, newChunk2, false) != 0)
++ return false;
++ return true;
++ }
++
++ /** Factory method: Rotate the selected argument range.
++ * Return null if this is not possible.
++ */
++ public static MethodHandle makeRotateArguments(Access token,
++ MethodType newType, MethodHandle target,
++ int firstArg, int argCount, int rotateBy) {
++ Access.check(token);
++ rotateBy = positiveRotation(argCount, rotateBy);
++ if (!canRotateArguments(newType, target.type(), firstArg, argCount, rotateBy))
++ return null;
++ // Decide whether it should be done as a right or left rotation,
++ // on the JVM stack. Return the number of stack slots to rotate by,
++ // positive if right, negative if left.
++ int limit = firstArg + argCount;
++ int depth0 = newType.parameterSlotDepth(firstArg);
++ int depth1 = newType.parameterSlotDepth(limit-rotateBy);
++ int depth2 = newType.parameterSlotDepth(limit);
++ int chunk1Slots = depth0 - depth1; assert(chunk1Slots > 0);
++ int chunk2Slots = depth1 - depth2; assert(chunk2Slots > 0);
++ // From here on out, it assumes a single-argument shift.
++ assert(MAX_ARG_ROTATION == 1);
++ int srcArg, dstArg;
++ byte basicType;
++ if (chunk2Slots <= chunk1Slots) {
++ // Rotate right/down N (rotateBy = +N, N small, c2 small):
++ // in arglist: [0: ...keep1 | arg1: c1... | limit-N: c2 | limit: keep2... ]
++ // out arglist: [0: ...keep1 | arg1: c2 | arg1+N: c1... | limit: keep2... ]
++ srcArg = limit-1;
++ dstArg = firstArg;
++ basicType = basicType(newType.parameterType(srcArg));
++ assert(chunk2Slots == type2size(basicType));
++ } else {
++ // Rotate left/up N (rotateBy = -N, N small, c1 small):
++ // in arglist: [0: ...keep1 | arg1: c1 | arg1+N: c2... | limit: keep2... ]
++ // out arglist: [0: ...keep1 | arg1: c2 ... | limit-N: c1 | limit: keep2... ]
++ srcArg = firstArg;
++ dstArg = limit-1;
++ basicType = basicType(newType.parameterType(srcArg));
++ assert(chunk1Slots == type2size(basicType));
++ }
++ int dstSlot = newType.parameterSlotDepth(dstArg + 1);
++ long conv = makeSwapConv(OP_ROT_ARGS, srcArg, basicType, dstSlot);
++ return new AdapterMethodHandle(target, newType, conv);
}
/** Can an adapter spread an argument to convert the target to newType? */
-@@ -676,10 +768,10 @@ public class AdapterMethodHandle extends
+@@ -676,10 +858,10 @@
if (spreadArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, spreadArgPos, false) != 0)
return false;
int afterPos = spreadArgPos + spreadArgCount;
@@ -2252,7 +2353,7 @@ diff --git a/src/share/classes/sun/dyn/A
return false;
// parameter types after the spread point must also be the same
if (afterCount != 0 && diffParamTypes(newType, spreadArgPos+1, targetType, afterPos, afterCount, false) != 0)
-@@ -697,32 +789,40 @@ public class AdapterMethodHandle extends
+@@ -697,32 +879,40 @@
return true;
}
@@ -2315,7 +2416,7 @@ diff --git a/src/share/classes/sun/dyn/B
diff --git a/src/share/classes/sun/dyn/BoundMethodHandle.java b/src/share/classes/sun/dyn/BoundMethodHandle.java
--- a/src/share/classes/sun/dyn/BoundMethodHandle.java
+++ b/src/share/classes/sun/dyn/BoundMethodHandle.java
-@@ -28,6 +28,9 @@ package sun.dyn;
+@@ -28,6 +28,9 @@
import sun.dyn.util.VerifyType;
import sun.dyn.util.Wrapper;
import java.dyn.*;
@@ -2325,7 +2426,7 @@ diff --git a/src/share/classes/sun/dyn/B
/**
* The flavor of method handle which emulates an invoke instruction
-@@ -40,7 +43,12 @@ public class BoundMethodHandle extends M
+@@ -40,7 +43,12 @@
private final Object argument; // argument to insert
private final int vmargslot; // position at which it is inserted
@@ -2338,7 +2439,7 @@ diff --git a/src/share/classes/sun/dyn/B
/** Bind a direct MH to its receiver (or first ref. argument).
* The JVM will pre-dispatch the MH if it is not already static.
-@@ -56,32 +64,34 @@ public class BoundMethodHandle extends M
+@@ -56,32 +64,34 @@
} else {
this.vmtarget = mh;
}
@@ -2383,7 +2484,7 @@ diff --git a/src/share/classes/sun/dyn/B
MethodHandleNatives.init(this, mh, argnum);
} else {
this.vmtarget = mh;
-@@ -97,29 +107,65 @@ public class BoundMethodHandle extends M
+@@ -97,29 +107,65 @@
assert(this.getClass() == AdapterMethodHandle.class);
}
@@ -2467,7 +2568,7 @@ diff --git a/src/share/classes/sun/dyn/B
}
/** Make sure the given {@code argument} can be used as {@code argnum}-th
-@@ -175,6 +221,24 @@ public class BoundMethodHandle extends M
+@@ -175,6 +221,24 @@
@Override
public String toString() {
@@ -2556,7 +2657,7 @@ diff --git a/src/share/classes/sun/dyn/C
}
private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE =
-@@ -61,10 +78,25 @@ class CallSiteImpl extends CallSite {
+@@ -61,10 +78,25 @@
MethodHandle bsm = Linkage.getBootstrapMethod(caller);
if (bsm == null)
throw new InvokeDynamicBootstrapError("class has no bootstrap method: "+caller);
@@ -2596,7 +2697,7 @@ diff --git a/src/share/classes/sun/dyn/F
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
-@@ -33,172 +33,158 @@ import java.lang.reflect.Constructor;
+@@ -33,172 +33,158 @@
import java.lang.reflect.InvocationTargetException;
/**
@@ -2902,7 +3003,7 @@ diff --git a/src/share/classes/sun/dyn/F
for (String cname : cnames) {
Class<? extends Adapter> acls = Adapter.findSubClass(cname);
if (acls == null) continue;
-@@ -220,7 +206,10 @@ class FilterGeneric {
+@@ -220,7 +206,10 @@
// Produce an instance configured as a prototype.
return ctor.newInstance(entryPoint);
} catch (IllegalArgumentException ex) {
@@ -2914,7 +3015,7 @@ diff --git a/src/share/classes/sun/dyn/F
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
}
-@@ -228,7 +217,7 @@ class FilterGeneric {
+@@ -228,7 +217,7 @@
return null;
}
@@ -2923,7 +3024,7 @@ diff --git a/src/share/classes/sun/dyn/F
throw new UnsupportedOperationException("NYI");
}
-@@ -242,8 +231,13 @@ class FilterGeneric {
+@@ -242,8 +231,13 @@
* generated once per type erasure family, and reused across adapters.
*/
static abstract class Adapter extends JavaMethodHandle {
@@ -2939,7 +3040,7 @@ diff --git a/src/share/classes/sun/dyn/F
protected boolean isPrototype() { return target == null; }
protected Adapter(MethodHandle entryPoint) {
-@@ -287,52 +281,4221 @@ class FilterGeneric {
+@@ -287,52 +281,4221 @@
}
}
@@ -7208,7 +7309,7 @@ diff --git a/src/share/classes/sun/dyn/F
diff --git a/src/share/classes/sun/dyn/FilterOneArgument.java b/src/share/classes/sun/dyn/FilterOneArgument.java
--- a/src/share/classes/sun/dyn/FilterOneArgument.java
+++ b/src/share/classes/sun/dyn/FilterOneArgument.java
-@@ -27,7 +27,6 @@ package sun.dyn;
+@@ -27,7 +27,6 @@
import java.dyn.JavaMethodHandle;
import java.dyn.MethodHandle;
@@ -7216,7 +7317,7 @@ diff --git a/src/share/classes/sun/dyn/F
import java.dyn.MethodType;
/**
-@@ -42,16 +41,21 @@ public class FilterOneArgument extends J
+@@ -42,16 +41,21 @@
protected final MethodHandle filter; // Object -> Object
protected final MethodHandle target; // Object -> Object
@@ -7244,7 +7345,7 @@ diff --git a/src/share/classes/sun/dyn/F
this.filter = filter;
this.target = target;
}
-@@ -62,10 +66,6 @@ public class FilterOneArgument extends J
+@@ -62,10 +66,6 @@
return new FilterOneArgument(filter, target);
}
@@ -7258,7 +7359,7 @@ diff --git a/src/share/classes/sun/dyn/F
diff --git a/src/share/classes/sun/dyn/FromGeneric.java b/src/share/classes/sun/dyn/FromGeneric.java
--- a/src/share/classes/sun/dyn/FromGeneric.java
+++ b/src/share/classes/sun/dyn/FromGeneric.java
-@@ -36,8 +36,8 @@ import sun.dyn.util.ValueConversions;
+@@ -36,8 +36,8 @@
import sun.dyn.util.Wrapper;
/**
@@ -7269,7 +7370,7 @@ diff --git a/src/share/classes/sun/dyn/F
* boxing up its arguments, and (on return) unboxing the return value.
* <p>
* A call is "generic" (in MethodHandle terms) if its MethodType features
-@@ -50,9 +50,6 @@ import sun.dyn.util.Wrapper;
+@@ -50,9 +50,6 @@
* either binds internally or else takes as a leading argument).
* (To stretch the term, adapter-like method handles may have multiple
* targets or be polymorphic across multiple call types.)
@@ -7279,7 +7380,7 @@ diff --git a/src/share/classes/sun/dyn/F
* @author jrose
*/
class FromGeneric {
-@@ -146,7 +143,7 @@ class FromGeneric {
+@@ -146,7 +143,7 @@
if (fixArgs == null)
throw new InternalError("bad fixArgs");
// reinterpret the calling sequence as raw:
@@ -7288,7 +7389,7 @@ diff --git a/src/share/classes/sun/dyn/F
Invokers.invokerType(internalType), fixArgs);
if (retyper == null)
throw new InternalError("bad retyper");
-@@ -226,7 +223,10 @@ class FromGeneric {
+@@ -226,7 +223,10 @@
// Produce an instance configured as a prototype.
return ctor.newInstance(entryPoint);
} catch (IllegalArgumentException ex) {
@@ -7300,7 +7401,7 @@ diff --git a/src/share/classes/sun/dyn/F
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
}
-@@ -260,6 +260,11 @@ class FromGeneric {
+@@ -260,6 +260,11 @@
protected final MethodHandle convert; // raw(R) => Object
protected final MethodHandle target; // (any**N) => R
@@ -7312,7 +7413,7 @@ diff --git a/src/share/classes/sun/dyn/F
protected boolean isPrototype() { return target == null; }
protected Adapter(MethodHandle entryPoint) {
this(entryPoint, null, entryPoint, null);
-@@ -284,11 +289,11 @@ class FromGeneric {
+@@ -284,11 +289,11 @@
// { return new ThisType(entryPoint, convert, target); }
/// Conversions on the value returned from the target.
@@ -7329,7 +7430,7 @@ diff --git a/src/share/classes/sun/dyn/F
static private final String CLASS_PREFIX; // "sun.dyn.FromGeneric$"
static {
-@@ -317,11 +322,11 @@ class FromGeneric {
+@@ -317,11 +322,11 @@
{ super(e, i, c, t); }
protected xA2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new xA2(e, i, c, t); }
@@ -7346,7 +7447,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
// */
-@@ -342,7 +347,7 @@ class genclasses {
+@@ -342,7 +347,7 @@
" protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
" { return new @cat@(e, i, c, t); }",
" //@each-R@",
@@ -7355,7 +7456,7 @@ diff --git a/src/share/classes/sun/dyn/F
" //@end-R@",
" }",
} };
-@@ -498,11 +503,11 @@ class genclasses {
+@@ -498,11 +503,11 @@
{ super(e, i, c, t); }
protected A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A0(e, i, c, t); }
@@ -7372,7 +7473,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A1 extends Adapter {
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -510,11 +515,11 @@ class genclasses {
+@@ -510,11 +515,11 @@
{ super(e, i, c, t); }
protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A1(e, i, c, t); }
@@ -7389,7 +7490,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A2 extends Adapter {
protected A2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -522,11 +527,11 @@ class genclasses {
+@@ -522,11 +527,11 @@
{ super(e, i, c, t); }
protected A2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A2(e, i, c, t); }
@@ -7406,7 +7507,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A3 extends Adapter {
protected A3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -534,11 +539,11 @@ class genclasses {
+@@ -534,11 +539,11 @@
{ super(e, i, c, t); }
protected A3 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A3(e, i, c, t); }
@@ -7423,7 +7524,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A4 extends Adapter {
protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -546,11 +551,11 @@ class genclasses {
+@@ -546,11 +551,11 @@
{ super(e, i, c, t); }
protected A4 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A4(e, i, c, t); }
@@ -7440,7 +7541,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A5 extends Adapter {
protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -558,11 +563,11 @@ class genclasses {
+@@ -558,11 +563,11 @@
{ super(e, i, c, t); }
protected A5 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A5(e, i, c, t); }
@@ -7457,7 +7558,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A6 extends Adapter {
protected A6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -570,11 +575,11 @@ class genclasses {
+@@ -570,11 +575,11 @@
{ super(e, i, c, t); }
protected A6 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A6(e, i, c, t); }
@@ -7474,7 +7575,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A7 extends Adapter {
protected A7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -582,11 +587,11 @@ class genclasses {
+@@ -582,11 +587,11 @@
{ super(e, i, c, t); }
protected A7 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A7(e, i, c, t); }
@@ -7491,7 +7592,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A8 extends Adapter {
protected A8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -594,11 +599,11 @@ class genclasses {
+@@ -594,11 +599,11 @@
{ super(e, i, c, t); }
protected A8 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A8(e, i, c, t); }
@@ -7508,7 +7609,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A9 extends Adapter {
protected A9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -606,11 +611,11 @@ class genclasses {
+@@ -606,11 +611,11 @@
{ super(e, i, c, t); }
protected A9 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A9(e, i, c, t); }
@@ -7525,7 +7626,7 @@ diff --git a/src/share/classes/sun/dyn/F
}
static class A10 extends Adapter {
protected A10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
-@@ -618,10 +623,10 @@ class genclasses {
+@@ -618,10 +623,10 @@
{ super(e, i, c, t); }
protected A10 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A10(e, i, c, t); }
@@ -7544,7 +7645,7 @@ diff --git a/src/share/classes/sun/dyn/I
diff --git a/src/share/classes/sun/dyn/Invokers.java b/src/share/classes/sun/dyn/Invokers.java
--- a/src/share/classes/sun/dyn/Invokers.java
+++ b/src/share/classes/sun/dyn/Invokers.java
-@@ -44,12 +44,16 @@ public class Invokers {
+@@ -44,12 +44,16 @@
// generic (untyped) invoker for the outgoing call
private /*lazy*/ MethodHandle genericInvoker;
@@ -7561,7 +7662,7 @@ diff --git a/src/share/classes/sun/dyn/I
}
public static MethodType invokerType(MethodType targetType) {
-@@ -76,8 +80,14 @@ public class Invokers {
+@@ -76,8 +80,14 @@
return invoker;
}
@@ -7590,7 +7691,7 @@ diff --git a/src/share/classes/sun/dyn/M
import java.dyn.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
-@@ -33,6 +33,7 @@ import java.lang.reflect.Method;
+@@ -33,6 +33,7 @@
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
@@ -7598,7 +7699,7 @@ diff --git a/src/share/classes/sun/dyn/M
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-@@ -93,7 +94,7 @@ public final class MemberName implements
+@@ -93,7 +94,7 @@
}
if (type instanceof String) {
String sig = (String) type;
@@ -7607,7 +7708,7 @@ diff --git a/src/share/classes/sun/dyn/M
this.type = res;
return res;
}
-@@ -135,7 +136,7 @@ public final class MemberName implements
+@@ -135,7 +136,7 @@
}
if (type instanceof String) {
String sig = (String) type;
@@ -7616,7 +7717,7 @@ diff --git a/src/share/classes/sun/dyn/M
Class<?> res = mtype.returnType();
this.type = res;
return res;
-@@ -155,9 +156,9 @@ public final class MemberName implements
+@@ -155,9 +156,9 @@
if (type instanceof String)
return (String) type;
if (isInvocable())
@@ -7628,7 +7729,7 @@ diff --git a/src/share/classes/sun/dyn/M
}
public int getModifiers() {
-@@ -353,6 +354,8 @@ public final class MemberName implements
+@@ -353,6 +354,8 @@
return type.toString(); // class java.lang.String
// else it is a field, method, or constructor
StringBuilder buf = new StringBuilder();
@@ -7637,7 +7738,7 @@ diff --git a/src/share/classes/sun/dyn/M
if (getDeclaringClass() != null) {
buf.append(getName(clazz));
buf.append('.');
-@@ -381,7 +384,7 @@ public final class MemberName implements
+@@ -381,7 +384,7 @@
private static String getName(Object obj) {
if (obj instanceof Class<?>)
return ((Class<?>)obj).getName();
@@ -7646,7 +7747,7 @@ diff --git a/src/share/classes/sun/dyn/M
}
// Queries to the JVM:
-@@ -408,6 +411,9 @@ public final class MemberName implements
+@@ -408,6 +411,9 @@
public static NoAccessException newNoAccessException(MemberName name, Class<?> lookupClass) {
return newNoAccessException("cannot access", name, lookupClass);
}
@@ -7656,7 +7757,7 @@ diff --git a/src/share/classes/sun/dyn/M
public static NoAccessException newNoAccessException(String message,
MemberName name, Class<?> lookupClass) {
message += ": " + name;
-@@ -436,7 +442,7 @@ public final class MemberName implements
+@@ -436,7 +442,7 @@
matchFlags &= ALLOWED_FLAGS;
String matchSig = null;
if (matchType != null) {
@@ -7665,7 +7766,7 @@ diff --git a/src/share/classes/sun/dyn/M
if (matchSig.startsWith("("))
matchFlags &= ~(ALL_KINDS & ~IS_INVOCABLE);
else
-@@ -447,17 +453,18 @@ public final class MemberName implements
+@@ -447,17 +453,18 @@
MemberName[] buf = newMemberBuffer(len1);
int totalCount = 0;
ArrayList<MemberName[]> bufs = null;
@@ -7688,7 +7789,7 @@ diff --git a/src/share/classes/sun/dyn/M
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
+@@ -473,7 +480,7 @@
Collections.addAll(result, buf0);
}
}
@@ -7700,7 +7801,7 @@ diff --git a/src/share/classes/sun/dyn/M
diff --git a/src/share/classes/sun/dyn/MethodHandleImpl.java b/src/share/classes/sun/dyn/MethodHandleImpl.java
--- a/src/share/classes/sun/dyn/MethodHandleImpl.java
+++ b/src/share/classes/sun/dyn/MethodHandleImpl.java
-@@ -25,12 +25,19 @@
+@@ -25,12 +25,20 @@
package sun.dyn;
@@ -7712,6 +7813,7 @@ diff --git a/src/share/classes/sun/dyn/M
import sun.dyn.util.VerifyType;
import java.dyn.NoAccessException;
+import java.util.ArrayList;
++import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
@@ -7720,7 +7822,7 @@ diff --git a/src/share/classes/sun/dyn/M
import static sun.dyn.MemberName.newIllegalArgumentException;
import static sun.dyn.MemberName.newNoAccessException;
-@@ -57,6 +64,25 @@ public abstract class MethodHandleImpl {
+@@ -57,6 +65,25 @@
static final int INT_FIELD = 0;
static final long LONG_FIELD = 0;
@@ -7746,7 +7848,7 @@ diff --git a/src/share/classes/sun/dyn/M
// type is defined in java.dyn.MethodHandle, which is platform-independent
// vmentry (a void* field) is used *only* by by the JVM.
-@@ -106,8 +132,8 @@ public abstract class MethodHandleImpl {
+@@ -106,8 +133,8 @@
}
static {
@@ -7757,7 +7859,7 @@ diff --git a/src/share/classes/sun/dyn/M
if (IMPL_LOOKUP_INIT == null)
throw new InternalError();
}
-@@ -203,8 +229,11 @@ public abstract class MethodHandleImpl {
+@@ -203,8 +230,11 @@
if (info instanceof DirectMethodHandle) {
DirectMethodHandle dmh = (DirectMethodHandle) info;
if (receiver == null ||
@@ -7771,7 +7873,7 @@ diff --git a/src/share/classes/sun/dyn/M
}
}
if (target instanceof DirectMethodHandle)
-@@ -223,7 +252,7 @@ public abstract class MethodHandleImpl {
+@@ -223,7 +253,7 @@
MethodHandle bindArgument(Access token,
MethodHandle target, int argnum, Object receiver) {
Access.check(token);
@@ -7780,7 +7882,7 @@ diff --git a/src/share/classes/sun/dyn/M
}
public static MethodHandle convertArguments(Access token,
-@@ -232,6 +261,87 @@ public abstract class MethodHandleImpl {
+@@ -232,6 +262,189 @@
MethodType oldType,
int[] permutationOrNull) {
Access.check(token);
@@ -7796,10 +7898,10 @@ diff --git a/src/share/classes/sun/dyn/M
+ target = convertArguments(token, target, callType, oldType, null);
+ assert(target != null);
+ oldType = target.type();
-+ List<Integer> goal = new ArrayList<Integer>();
-+ List<Integer> state = new ArrayList<Integer>();
-+ List<Integer> drops = new ArrayList<Integer>();
-+ List<Integer> dups = new ArrayList<Integer>();
++ List<Integer> goal = new ArrayList<Integer>(); // i*TOKEN
++ List<Integer> state = new ArrayList<Integer>(); // i*TOKEN
++ List<Integer> drops = new ArrayList<Integer>(); // not tokens
++ List<Integer> dups = new ArrayList<Integer>(); // not tokens
+ final int TOKEN = 10; // to mark items which are symbolic only
+ // state represents the argument values coming into target
+ for (int i = 0; i < outargs; i++) {
@@ -7831,31 +7933,133 @@ diff --git a/src/share/classes/sun/dyn/M
+ assert(state.size() == goal.size());
+ int size = goal.size();
+ while (!state.equals(goal)) {
-+ // Swap like the wind!
-+ // FIXME: Use a rotation when possible.
++ // Look for a maximal sequence of adjacent misplaced arguments,
++ // and try to rotate them into place.
++ int bestRotArg = -10 * TOKEN, bestRotLen = 0;
++ int thisRotArg = -10 * TOKEN, thisRotLen = 0;
+ for (int i = 0; i < size; i++) {
+ int arg = state.get(i);
-+ if (arg != goal.get(i)) {
-+ int j = goal.indexOf(arg);
-+ target = AdapterMethodHandle.makeSwapArguments(token, target.type(), target, i, j);
++ // Does this argument match the current run?
++ if (arg == thisRotArg + TOKEN) {
++ thisRotArg = arg;
++ thisRotLen += 1;
++ if (bestRotLen < thisRotLen) {
++ bestRotLen = thisRotLen;
++ bestRotArg = thisRotArg;
++ }
++ } else {
++ // The old sequence (if any) stops here.
++ thisRotLen = 0;
++ thisRotArg = -10 * TOKEN;
++ // But maybe a new one starts here also.
++ int wantArg = goal.get(i);
++ final int MAX_ARG_ROTATION = AdapterMethodHandle.MAX_ARG_ROTATION;
++ if (arg != wantArg &&
++ arg >= wantArg - TOKEN * MAX_ARG_ROTATION &&
++ arg <= wantArg + TOKEN * MAX_ARG_ROTATION) {
++ thisRotArg = arg;
++ thisRotLen = 1;
++ }
++ }
++ }
++ if (bestRotLen >= 2) {
++ // Do a rotation if it can improve argument positioning
++ // by at least 2 arguments. This is not always optimal,
++ // but it seems to catch common cases.
++ int dstEnd = state.indexOf(bestRotArg);
++ int srcEnd = goal.indexOf(bestRotArg);
++ int rotBy = dstEnd - srcEnd;
++ int dstBeg = dstEnd - (bestRotLen - 1);
++ int srcBeg = srcEnd - (bestRotLen - 1);
++ assert((dstEnd | dstBeg | srcEnd | srcBeg) >= 0); // no negs
++ // Make a span which covers both source and destination.
++ int rotBeg = Math.min(dstBeg, srcBeg);
++ int rotEnd = Math.max(dstEnd, srcEnd);
++ int score = 0;
++ for (int i = rotBeg; i <= rotEnd; i++) {
++ if ((int)state.get(i) != (int)goal.get(i))
++ score += 1;
++ }
++ List<Integer> rotSpan = state.subList(rotBeg, rotEnd+1);
++ Collections.rotate(rotSpan, -rotBy); // reverse direction
++ for (int i = rotBeg; i <= rotEnd; i++) {
++ if ((int)state.get(i) != (int)goal.get(i))
++ score -= 1;
++ }
++ if (score >= 2) {
++ // Improved at least two argument positions. Do it.
++ List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
++ Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy);
++ MethodType rotType = MethodType.make(oldType.returnType(), ptypes);
++ MethodHandle nextTarget
++ = AdapterMethodHandle.makeRotateArguments(token, rotType, target,
++ rotBeg, rotSpan.size(), rotBy);
++ if (nextTarget != null) {
++ //System.out.println("Rot: "+rotSpan+" by "+rotBy);
++ target = nextTarget;
++ oldType = rotType;
++ continue;
++ }
++ }
++ // Else de-rotate, and drop through to the swap-fest.
++ Collections.rotate(rotSpan, rotBy);
++ }
++
++ // Now swap like the wind!
++ List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
++ for (int i = 0; i < size; i++) {
++ // What argument do I want here?
++ int arg = goal.get(i);
++ if (arg != state.get(i)) {
++ // Where is it now?
++ int j = state.indexOf(arg);
++ Collections.swap(ptypes, i, j);
++ MethodType swapType = MethodType.make(oldType.returnType(), ptypes);
++ target = AdapterMethodHandle.makeSwapArguments(token, swapType, target, i, j);
+ if (target == null) throw newIllegalArgumentException("cannot swap");
-+ oldType = target.type();
++ assert(target.type() == swapType);
++ oldType = swapType;
+ Collections.swap(state, i, j);
+ }
+ }
++ // One pass of swapping must finish the job.
++ assert(state.equals(goal));
+ }
-+ Collections.reverse(dups);
-+ for (int i : dups) {
-+ MethodType dupType = oldType.dropParameterType(i);
-+ int dupArgPos = i, dupArgCount = 1; // FIXME: Batch up the dups.
++ while (!dups.isEmpty()) {
++ // Grab a contiguous trailing sequence of dups.
++ int grab = dups.size() - 1;
++ int dupArgPos = dups.get(grab), dupArgCount = 1;
++ while (grab - 1 >= 0) {
++ int dup0 = dups.get(grab - 1);
++ if (dup0 != dupArgPos - 1) break;
++ dupArgPos -= 1;
++ dupArgCount += 1;
++ grab -= 1;
++ }
++ //if (dupArgCount > 1) System.out.println("Dup: "+dups.subList(grab, dups.size()));
++ dups.subList(grab, dups.size()).clear();
++ // In the new target type drop that many args from the tail:
++ List<Class<?>> ptypes = oldType.parameterList();
++ ptypes = ptypes.subList(0, ptypes.size() - dupArgCount);
++ MethodType dupType = MethodType.make(oldType.returnType(), ptypes);
+ target = AdapterMethodHandle.makeDupArguments(token, dupType, target, dupArgPos, dupArgCount);
-+ if (target == null) throw newIllegalArgumentException("cannot dup");
++ if (target == null)
++ throw newIllegalArgumentException("cannot dup");
+ oldType = target.type();
+ }
-+ //Collections.reverse(drops);
-+ for (int i : drops) {
-+ MethodType dropType = oldType.insertParameterType(i, newType.parameterType(i));
-+ int dropArgPos = i, dropArgCount = 1; // FIXME: Batch up drops.
++ while (!drops.isEmpty()) {
++ // Grab a contiguous initial sequence of drops.
++ int dropArgPos = drops.get(0), dropArgCount = 1;
++ while (dropArgCount < drops.size()) {
++ int drop1 = drops.get(dropArgCount);
++ if (drop1 != dropArgPos + dropArgCount) break;
++ dropArgCount += 1;
++ }
++ //if (dropArgCount > 1) System.out.println("Drop: "+drops.subList(0, dropArgCount));
++ drops.subList(0, dropArgCount).clear();
++ MethodType dropType = oldType;
++ for (int i = dropArgPos; i < dropArgPos + dropArgCount; i++)
++ dropType = dropType.insertParameterType(i, newType.parameterType(i));
+ target = AdapterMethodHandle.makeDropArguments(token, dropType, target, dropArgPos, dropArgCount);
+ if (target == null) throw newIllegalArgumentException("cannot drop");
+ oldType = target.type();
@@ -7868,7 +8072,7 @@ diff --git a/src/share/classes/sun/dyn/M
MethodHandle res = AdapterMethodHandle.makePairwiseConvert(token, newType, target);
if (res != null)
return res;
-@@ -274,81 +384,343 @@ public abstract class MethodHandleImpl {
+@@ -274,81 +487,343 @@
ptypes[spreadArg + i] = VerifyType.spreadArgElementType(spreadType, i);
MethodType midType = MethodType.make(newType.returnType(), ptypes);
// after spreading, some arguments may need further conversion
@@ -8258,7 +8462,7 @@ diff --git a/src/share/classes/sun/dyn/M
MemberName name = null;
if (target != null)
name = MethodHandleNatives.getMethodName(target);
-@@ -357,17 +729,13 @@ public abstract class MethodHandleImpl {
+@@ -357,17 +832,13 @@
return name.getName();
}
@@ -8291,7 +8495,7 @@ diff --git a/src/share/classes/sun/dyn/M
import java.dyn.MethodHandle;
import java.dyn.MethodType;
import java.lang.reflect.AccessibleObject;
-@@ -60,7 +61,7 @@ class MethodHandleNatives {
+@@ -60,7 +61,7 @@
static native void init(MethodType self);
/** Tell the JVM that we need to change the target of an invokedynamic. */
@@ -8300,7 +8504,7 @@ diff --git a/src/share/classes/sun/dyn/M
/** Fetch the vmtarget field.
* It will be sanitized as necessary to avoid exposing non-Java references.
-@@ -84,8 +85,7 @@ class MethodHandleNatives {
+@@ -84,8 +85,7 @@
}
/** Fetch the target of this method handle.
@@ -8310,7 +8514,7 @@ diff --git a/src/share/classes/sun/dyn/M
* If it is chained to another method handle, return that handle.
*/
static Object getTargetInfo(MethodHandle self) {
-@@ -123,7 +123,7 @@ class MethodHandleNatives {
+@@ -123,7 +123,7 @@
registerNatives();
JVM_SUPPORT_ = true;
JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT);
@@ -8319,7 +8523,7 @@ diff --git a/src/share/classes/sun/dyn/M
//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 {
+@@ -149,7 +149,7 @@
// MethodHandleImpl
static final int // for getConstant
GC_JVM_PUSH_LIMIT = 0,
@@ -8328,7 +8532,7 @@ diff --git a/src/share/classes/sun/dyn/M
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 {
+@@ -178,19 +178,20 @@
*/
static final int
OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype
@@ -8362,7 +8566,7 @@ diff --git a/src/share/classes/sun/dyn/M
/** 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 {
+@@ -209,6 +210,7 @@
// TODO: The following expression should be replaced by
// a JVM query.
((1<<OP_RETYPE_ONLY)
@@ -8370,7 +8574,7 @@ diff --git a/src/share/classes/sun/dyn/M
|(1<<OP_CHECK_CAST)
|(1<<OP_PRIM_TO_PRIM)
|(1<<OP_REF_TO_PRIM)
-@@ -216,6 +218,7 @@ class MethodHandleNatives {
+@@ -216,6 +218,7 @@
|(1<<OP_ROT_ARGS)
|(1<<OP_DUP_ARGS)
|(1<<OP_DROP_ARGS)
@@ -8381,7 +8585,7 @@ diff --git a/src/share/classes/sun/dyn/M
diff --git a/src/share/classes/sun/dyn/MethodTypeImpl.java b/src/share/classes/sun/dyn/MethodTypeImpl.java
--- a/src/share/classes/sun/dyn/MethodTypeImpl.java
+++ b/src/share/classes/sun/dyn/MethodTypeImpl.java
-@@ -56,8 +56,8 @@ public class MethodTypeImpl {
+@@ -56,8 +56,8 @@
// Cached adapter information:
/*lazy*/ ToGeneric toGeneric; // convert cs. with prims to w/o
/*lazy*/ FromGeneric fromGeneric; // convert cs. w/o prims to with
@@ -8391,7 +8595,7 @@ diff --git a/src/share/classes/sun/dyn/M
public MethodType erasedType() {
return erasedType;
-@@ -68,7 +68,7 @@ public class MethodTypeImpl {
+@@ -68,7 +68,7 @@
}
/** Access methods for the internals of MethodType, supplied to
@@ -8400,7 +8604,7 @@ diff --git a/src/share/classes/sun/dyn/M
*/
static public interface MethodTypeFriend {
Class<?>[] ptypes(MethodType mt);
-@@ -378,10 +378,10 @@ public class MethodTypeImpl {
+@@ -378,10 +378,10 @@
static MethodTypeImpl findForm(MethodType mt) {
MethodType erased = canonicalize(mt, ERASE, ERASE);
if (erased == null) {
@@ -9103,7 +9307,7 @@ diff --git a/src/share/classes/sun/dyn/T
diff --git a/src/share/classes/sun/dyn/ToGeneric.java b/src/share/classes/sun/dyn/ToGeneric.java
--- a/src/share/classes/sun/dyn/ToGeneric.java
+++ b/src/share/classes/sun/dyn/ToGeneric.java
-@@ -68,7 +68,7 @@ class ToGeneric {
+@@ -68,7 +68,7 @@
// conversion which unboxes a primitive return value
private final MethodHandle returnConversion;
@@ -9112,7 +9316,7 @@ diff --git a/src/share/classes/sun/dyn/T
* that implement members of the erasure-family of the given erased type.
*/
private ToGeneric(MethodType entryType) {
-@@ -111,30 +111,48 @@ class ToGeneric {
+@@ -111,30 +111,48 @@
// primitive arguments according to their "raw" types int/long
MethodType intsAtEnd = MethodTypeImpl.of(primsAtEnd).primsAsInts();
ad = findAdapter(rawEntryTypeInit = intsAtEnd);
@@ -9167,7 +9371,7 @@ diff --git a/src/share/classes/sun/dyn/T
}
/** A generic argument list will be created by a call of type 'raw'.
-@@ -157,8 +175,8 @@ class ToGeneric {
+@@ -157,8 +175,8 @@
if (filteredInvoker == null) throw new UnsupportedOperationException("NYI");
}
MethodHandle reboxer = ValueConversions.rebox(dst, false);
@@ -9178,7 +9382,7 @@ diff --git a/src/share/classes/sun/dyn/T
}
if (filteredInvoker == null) return invoker;
return AdapterMethodHandle.makeRetypeOnly(Access.TOKEN, invoker.type(), filteredInvoker);
-@@ -211,7 +229,7 @@ class ToGeneric {
+@@ -211,7 +229,7 @@
// retype erased reference arguments (the cast makes it safe to do this)
MethodType tepType = type.insertParameterType(0, adapter.getClass());
MethodHandle typedEntryPoint =
@@ -9187,7 +9391,7 @@ diff --git a/src/share/classes/sun/dyn/T
return adapter.makeInstance(typedEntryPoint, invoker, convert, genericTarget);
}
-@@ -283,7 +301,10 @@ class ToGeneric {
+@@ -283,7 +301,10 @@
try {
return ctor.newInstance(entryPoint);
} catch (IllegalArgumentException ex) {
@@ -9199,7 +9403,7 @@ diff --git a/src/share/classes/sun/dyn/T
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
}
-@@ -317,6 +338,11 @@ class ToGeneric {
+@@ -317,6 +338,11 @@
protected final MethodHandle target; // Object... -> Object
protected final MethodHandle convert; // Object -> R
@@ -9211,7 +9415,7 @@ diff --git a/src/share/classes/sun/dyn/T
protected boolean isPrototype() { return target == null; }
/* Prototype constructor. */
protected Adapter(MethodHandle entryPoint) {
-@@ -344,33 +370,33 @@ class ToGeneric {
+@@ -344,33 +370,33 @@
// { return new ThisType(entryPoint, convert, target); }
// Code to run when the arguments (<= 4) have all been boxed.
@@ -9260,7 +9464,7 @@ diff --git a/src/share/classes/sun/dyn/T
static private final String CLASS_PREFIX; // "sun.dyn.ToGeneric$"
static {
-@@ -397,25 +423,25 @@ class ToGeneric {
+@@ -397,25 +423,25 @@
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
@@ -9305,7 +9509,7 @@ diff --git a/src/share/classes/sun/dyn/T
}
// */
-@@ -435,13 +461,13 @@ class genclasses {
+@@ -435,13 +461,13 @@
" protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
" protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }",
" protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new @cat@(e, i, c, t); }",
@@ -9322,7 +9526,7 @@ diff --git a/src/share/classes/sun/dyn/T
" //@end-R@",
" //@end-Tv@",
" }",
-@@ -595,424 +621,424 @@ class genclasses {
+@@ -595,424 +621,424 @@
protected A0(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A0(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A0(e, i, c, t); }
@@ -10117,7 +10321,7 @@ diff --git a/src/share/classes/sun/dyn/e
diff --git a/src/share/classes/sun/dyn/empty/Empty.java b/src/share/classes/sun/dyn/empty/Empty.java
--- a/src/share/classes/sun/dyn/empty/Empty.java
+++ b/src/share/classes/sun/dyn/empty/Empty.java
-@@ -29,6 +29,10 @@ package sun.dyn.empty;
+@@ -29,6 +29,10 @@
* 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.
@@ -10133,7 +10337,7 @@ rename to src/share/classes/sun/dyn/util
rename to src/share/classes/sun/dyn/util/BytecodeDescriptor.java
--- a/src/share/classes/sun/dyn/util/BytecodeSignature.java
+++ b/src/share/classes/sun/dyn/util/BytecodeDescriptor.java
-@@ -33,9 +33,9 @@ import java.util.List;
+@@ -33,9 +33,9 @@
* Utility routines for dealing with bytecode-level signatures.
* @author jrose
*/
@@ -10148,7 +10352,7 @@ diff --git a/src/share/classes/sun/dyn/u
diff --git a/src/share/classes/sun/dyn/util/ValueConversions.java b/src/share/classes/sun/dyn/util/ValueConversions.java
--- a/src/share/classes/sun/dyn/util/ValueConversions.java
+++ b/src/share/classes/sun/dyn/util/ValueConversions.java
-@@ -27,7 +27,10 @@ package sun.dyn.util;
+@@ -27,7 +27,10 @@
import java.dyn.*;
import java.dyn.MethodHandles.Lookup;
@@ -10159,7 +10363,7 @@ diff --git a/src/share/classes/sun/dyn/u
import sun.dyn.Access;
import sun.dyn.AdapterMethodHandle;
import sun.dyn.MethodHandleImpl;
-@@ -37,6 +40,7 @@ public class ValueConversions {
+@@ -37,6 +40,7 @@
private static final Lookup IMPL_LOOKUP = MethodHandleImpl.getLookup(IMPL_TOKEN);
private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
@@ -10167,7 +10371,7 @@ diff --git a/src/share/classes/sun/dyn/u
EnumMap<Wrapper, MethodHandle>[] caches
= (EnumMap<Wrapper, MethodHandle>[]) new EnumMap[n]; // unchecked warning expected here
for (int i = 0; i < n; i++)
-@@ -305,29 +309,47 @@ public class ValueConversions {
+@@ -305,29 +309,47 @@
/// Kludges for when raw values get accidentally boxed.
@@ -10220,7 +10424,7 @@ diff --git a/src/share/classes/sun/dyn/u
}
static Double reboxRawDouble(Object x) {
-@@ -343,6 +365,15 @@ public class ValueConversions {
+@@ -343,6 +365,15 @@
private static final EnumMap<Wrapper, MethodHandle>[]
REBOX_CONVERSIONS = newWrapperCaches(2);
@@ -10236,7 +10440,7 @@ diff --git a/src/share/classes/sun/dyn/u
public static MethodHandle rebox(Wrapper wrap, boolean exact) {
EnumMap<Wrapper, MethodHandle> cache = REBOX_CONVERSIONS[exact?1:0];
MethodHandle mh = cache.get(wrap);
-@@ -355,9 +386,6 @@ public class ValueConversions {
+@@ -355,9 +386,6 @@
mh = IDENTITY; break;
case VOID:
throw new IllegalArgumentException("cannot rebox a void");
@@ -10246,7 +10450,7 @@ diff --git a/src/share/classes/sun/dyn/u
}
if (mh != null) {
cache.put(wrap, mh);
-@@ -384,13 +412,21 @@ public class ValueConversions {
+@@ -384,13 +412,21 @@
/// Width-changing conversions between int and long.
static long widenInt(int x) {
@@ -10269,7 +10473,7 @@ diff --git a/src/share/classes/sun/dyn/u
/// Constant functions
static void ignore(Object x) {
-@@ -543,10 +579,10 @@ public class ValueConversions {
+@@ -543,10 +579,10 @@
else if (VerifyType.isNullType(type))
mh = ALWAYS_NULL;
else
@@ -10282,7 +10486,7 @@ diff --git a/src/share/classes/sun/dyn/u
}
if (cache != null)
cache.put(wrap, mh);
-@@ -560,4 +596,127 @@ public class ValueConversions {
+@@ -560,4 +596,127 @@
private static MethodHandle retype(MethodType type, MethodHandle mh) {
return AdapterMethodHandle.makeRetypeOnly(IMPL_TOKEN, type, mh);
}
@@ -10427,7 +10631,7 @@ diff --git a/src/share/classes/sun/dyn/u
/**
* This class centralizes information about the JVM's linkage access control.
-@@ -166,4 +170,38 @@ public class VerifyAccess {
+@@ -166,4 +170,38 @@
if (isSamePackage(requestingClass, subjectClass)) return;
security.checkPermission(new LinkagePermission(permissionName, requestingClass));
}
@@ -10477,7 +10681,7 @@ diff --git a/src/share/classes/sun/dyn/u
/**
* This class centralizes information about the JVM verifier
-@@ -73,29 +74,28 @@ public class VerifyType {
+@@ -73,29 +74,28 @@
}
/**
@@ -10520,7 +10724,7 @@ diff --git a/src/share/classes/sun/dyn/u
}
/**
-@@ -191,6 +191,11 @@ public class VerifyType {
+@@ -191,6 +191,11 @@
// to be captured as a garbage int.
// Caller promises that the actual value will be disregarded.
return dst == int.class ? 1 : 0;
@@ -10535,7 +10739,7 @@ diff --git a/src/share/classes/sun/dyn/u
diff --git a/src/share/classes/sun/dyn/util/Wrapper.java b/src/share/classes/sun/dyn/util/Wrapper.java
--- a/src/share/classes/sun/dyn/util/Wrapper.java
+++ b/src/share/classes/sun/dyn/util/Wrapper.java
-@@ -141,13 +141,19 @@ public enum Wrapper {
+@@ -141,13 +141,19 @@
* @throws IllegalArgumentException for unexpected types
*/
public static Wrapper forPrimitiveType(Class<?> type) {
@@ -10558,7 +10762,7 @@ diff --git a/src/share/classes/sun/dyn/u
}
/** Return the wrapper that wraps values into the given wrapper type.
-@@ -244,8 +250,10 @@ public enum Wrapper {
+@@ -244,8 +250,10 @@
public Class<?> wrapperType() { return wrapperType; }
/** What is the wrapper type for this wrapper?
@@ -10570,7 +10774,7 @@ diff --git a/src/share/classes/sun/dyn/u
* The resulting class type has the same type parameter.
*/
public <T> Class<T> wrapperType(Class<T> exampleType) {
-@@ -309,7 +317,7 @@ public enum Wrapper {
+@@ -309,7 +317,7 @@
/** Cast a wrapped value to the given type, which may be either a primitive or wrapper type.
* Performs standard primitive conversions, including truncation and float conversions.
* The given type must be compatible with this wrapper. That is, it must either
@@ -10579,7 +10783,7 @@ diff --git a/src/share/classes/sun/dyn/u
* it must be the wrapper's primitive type.
* @throws ClassCastException if the given type is not compatible with this wrapper
*/
-@@ -326,9 +334,17 @@ public enum Wrapper {
+@@ -326,9 +334,17 @@
* If the target type is a primitive, change it to a wrapper.
*/
static <T> Class<T> forceType(Class<?> type, Class<T> exampleType) {