Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
715ab60a
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,发现更多精彩内容 >>
提交
715ab60a
编写于
9月 22, 2017
作者:
J
jrose
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8185993: MethodHandle.invokeWithArguments jumbo-arity
Reviewed-by: psandoz, vlivanov
上级
e120cd7f
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
293 addition
and
45 deletion
+293
-45
src/java.base/share/classes/java/lang/invoke/CallSite.java
src/java.base/share/classes/java/lang/invoke/CallSite.java
+15
-7
src/java.base/share/classes/java/lang/invoke/MethodHandle.java
...ava.base/share/classes/java/lang/invoke/MethodHandle.java
+106
-22
src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
...base/share/classes/java/lang/invoke/MethodHandleImpl.java
+49
-0
src/java.base/share/classes/java/lang/invoke/MethodType.java
src/java.base/share/classes/java/lang/invoke/MethodType.java
+18
-2
src/java.base/share/classes/java/lang/invoke/package-info.java
...ava.base/share/classes/java/lang/invoke/package-info.java
+20
-11
test/jdk/java/lang/invoke/BigArityTest.java
test/jdk/java/lang/invoke/BigArityTest.java
+85
-3
未找到文件。
src/java.base/share/classes/java/lang/invoke/CallSite.java
浏览文件 @
715ab60a
...
...
@@ -344,13 +344,21 @@ public class CallSite {
break
;
default
:
final
int
NON_SPREAD_ARG_COUNT
=
3
;
// (caller, name, type)
if
(
NON_SPREAD_ARG_COUNT
+
argv
.
length
>
MethodType
.
MAX_MH_ARITY
)
throw
new
BootstrapMethodError
(
"too many bootstrap method arguments"
);
MethodType
invocationType
=
MethodType
.
genericMethodType
(
NON_SPREAD_ARG_COUNT
+
argv
.
length
);
MethodHandle
typedBSM
=
bootstrapMethod
.
asType
(
invocationType
);
MethodHandle
spreader
=
invocationType
.
invokers
().
spreadInvoker
(
NON_SPREAD_ARG_COUNT
);
binding
=
spreader
.
invokeExact
(
typedBSM
,
(
Object
)
caller
,
(
Object
)
name
,
(
Object
)
type
,
argv
);
final
int
MAX_SAFE_SIZE
=
MethodType
.
MAX_MH_ARITY
/
2
-
NON_SPREAD_ARG_COUNT
;
if
(
argv
.
length
>=
MAX_SAFE_SIZE
)
{
// to be on the safe side, use invokeWithArguments which handles jumbo lists
Object
[]
newargv
=
new
Object
[
NON_SPREAD_ARG_COUNT
+
argv
.
length
];
newargv
[
0
]
=
caller
;
newargv
[
1
]
=
name
;
newargv
[
2
]
=
type
;
System
.
arraycopy
(
argv
,
0
,
newargv
,
NON_SPREAD_ARG_COUNT
,
argv
.
length
);
binding
=
bootstrapMethod
.
invokeWithArguments
(
newargv
);
}
else
{
MethodType
invocationType
=
MethodType
.
genericMethodType
(
NON_SPREAD_ARG_COUNT
+
argv
.
length
);
MethodHandle
typedBSM
=
bootstrapMethod
.
asType
(
invocationType
);
MethodHandle
spreader
=
invocationType
.
invokers
().
spreadInvoker
(
NON_SPREAD_ARG_COUNT
);
binding
=
spreader
.
invokeExact
(
typedBSM
,
(
Object
)
caller
,
(
Object
)
name
,
(
Object
)
type
,
argv
);
}
}
}
if
(
binding
instanceof
CallSite
)
{
...
...
src/java.base/share/classes/java/lang/invoke/MethodHandle.java
浏览文件 @
715ab60a
...
...
@@ -584,10 +584,10 @@ public abstract class MethodHandle {
/*non-public*/
static
native
@PolymorphicSignature
Object
linkToInterface
(
Object
...
args
)
throws
Throwable
;
/**
* Performs a variable arity invocation, passing the arguments in the given
list
* Performs a variable arity invocation, passing the arguments in the given
array
* to the method handle, as if via an inexact {@link #invoke invoke} from a call site
* which mentions only the type {@code Object}, and whose a
rity
is the length
* of the argument
list
.
* which mentions only the type {@code Object}, and whose a
ctual argument count
is the length
* of the argument
array
.
* <p>
* Specifically, execution proceeds as if by the following steps,
* although the methods are not guaranteed to be called if the JVM
...
...
@@ -595,36 +595,104 @@ public abstract class MethodHandle {
* <ul>
* <li>Determine the length of the argument array as {@code N}.
* For a null reference, {@code N=0}. </li>
* <li>Determine the general type {@code TN} of {@code N} arguments as
* as {@code TN=MethodType.genericMethodType(N)}.</li>
* <li>Collect the {@code N} elements of the array as a logical
* argument list, each argument statically typed as an {@code Object}. </li>
* <li>Determine, as {@code M}, the parameter count of the type of this
* method handle. </li>
* <li>Determine the general type {@code TN} of {@code N} arguments or
* {@code M} arguments, if smaller than {@code N}, as
* {@code TN=MethodType.genericMethodType(Math.min(N, M))}.</li>
* <li>If {@code N} is greater than {@code M}, perform the following
* checks and actions to shorten the logical argument list: <ul>
* <li>Check that this method handle has variable arity with a
* {@linkplain MethodType#lastParameterType trailing parameter}
* of some array type {@code A[]}. If not, fail with a
* {@code WrongMethodTypeException}. </li>
* <li>Collect the trailing elements (there are {@code N-M+1} of them)
* from the logical argument list into a single array of
* type {@code A[]}, using {@code asType} conversions to
* convert each trailing argument to type {@code A}. </li>
* <li>If any of these conversions proves impossible, fail with either
* a {@code ClassCastException} if any trailing element cannot be
* cast to {@code A} or a {@code NullPointerException} if any
* trailing element is {@code null} and {@code A} is not a reference
* type. </li>
* <li>Replace the logical arguments gathered into the array of
* type {@code A[]} with the array itself, thus shortening
* the argument list to length {@code M}. This final argument
* retains the static type {@code A[]}.</li>
* <li>Adjust the type {@code TN} by changing the {@code N}th
* parameter type from {@code Object} to {@code A[]}.
* </ul>
* <li>Force the original target method handle {@code MH0} to the
* required type, as {@code MH1 = MH0.asType(TN)}. </li>
* <li>Spread the ar
ray
into {@code N} separate arguments {@code A0, ...}. </li>
* <li>Spread the ar
gument list
into {@code N} separate arguments {@code A0, ...}. </li>
* <li>Invoke the type-adjusted method handle on the unpacked arguments:
* MH1.invokeExact(A0, ...). </li>
* <li>Take the return value as an {@code Object} reference. </li>
* </ul>
* <p>
* If the target method handle has variable arity, and the argument list is longer
* than that arity, the excess arguments, starting at the position of the trailing
* array argument, will be gathered (if possible, as if by {@code asType} conversions)
* into an array of the appropriate type, and invocation will proceed on the
* shortened argument list.
* In this way, <em>jumbo argument lists</em> which would spread into more
* than 254 slots can still be processed uniformly.
* <p>
* Unlike the {@link #invoke(Object...) generic} invocation mode, which can
* "recycle" an array argument, passing it directly to the target method,
* this invocation mode <em>always</em> creates a new array parameter, even
* if the original array passed to {@code invokeWithArguments} would have
* been acceptable as a direct argument to the target method.
* Even if the number {@code M} of actual arguments is the arity {@code N},
* and the last argument is dynamically a suitable array of type {@code A[]},
* it will still be boxed into a new one-element array, since the call
* site statically types the argument as {@code Object}, not an array type.
* This is not a special rule for this method, but rather a regular effect
* of the {@linkplain #asVarargsCollector rules for variable-arity invocation}.
* <p>
* Because of the action of the {@code asType} step, the following argument
* conversions are applied as necessary:
* <ul>
* <li>reference casting
* <li>unboxing
* <li>widening primitive conversions
* <li>variable arity conversion
* </ul>
* <p>
* The result returned by the call is boxed if it is a primitive,
* or forced to null if the return type is void.
* <p>
* This call is equivalent to the following code:
* Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke},
* {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
* It can therefore be used as a bridge between native or reflective code and method handles.
* @apiNote
* This call is approximately equivalent to the following code:
* <blockquote><pre>{@code
* // for jumbo argument lists, adapt varargs explicitly:
* int N = (arguments == null? 0: arguments.length);
* int M = this.type.parameterCount();
* int MAX_SAFE = 127; // 127 longs require 254 slots, which is OK
* if (N > MAX_SAFE && N > M && this.isVarargsCollector()) {
* Class<?> arrayType = this.type().lastParameterType();
* Class<?> elemType = arrayType.getComponentType();
* if (elemType != null) {
* Object args2 = Array.newInstance(elemType, M);
* MethodHandle arraySetter = MethodHandles.arrayElementSetter(arrayType);
* for (int i = 0; i < M; i++) {
* arraySetter.invoke(args2, i, arguments[M-1 + i]);
* }
* arguments = Arrays.copyOf(arguments, M);
* arguments[M-1] = args2;
* return this.asFixedArity().invokeWithArguments(arguments);
* }
* } // done with explicit varargs processing
*
* // Handle fixed arity and non-jumbo variable arity invocation.
* MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
* Object result = invoker.invokeExact(this, arguments);
* }</pre></blockquote>
* <p>
* Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke},
* {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
* It can therefore be used as a bridge between native or reflective code and method handles.
*
* @param arguments the arguments to pass to the target
* @return the result returned by the target
...
...
@@ -634,20 +702,24 @@ public abstract class MethodHandle {
* @see MethodHandles#spreadInvoker
*/
public
Object
invokeWithArguments
(
Object
...
arguments
)
throws
Throwable
{
// Note: Jumbo argument lists are handled in the variable-arity subclass.
MethodType
invocationType
=
MethodType
.
genericMethodType
(
arguments
==
null
?
0
:
arguments
.
length
);
return
invocationType
.
invokers
().
spreadInvoker
(
0
).
invokeExact
(
asType
(
invocationType
),
arguments
);
}
/**
* Performs a variable arity invocation, passing the arguments in the given
array
* Performs a variable arity invocation, passing the arguments in the given
list
* to the method handle, as if via an inexact {@link #invoke invoke} from a call site
* which mentions only the type {@code Object}, and whose a
rity
is the length
* of the argument
array
.
* which mentions only the type {@code Object}, and whose a
ctual argument count
is the length
* of the argument
list
.
* <p>
* This method is also equivalent to the following code:
* <blockquote><pre>{@code
* invokeWithArguments(arguments.toArray())
* }</pre></blockquote>
* <p>
* Jumbo-sized lists are acceptable if this method handle has variable arity.
* See {@link #invokeWithArguments(Object[])} for details.
*
* @param arguments the arguments to pass to the target
* @return the result returned by the target
...
...
@@ -987,6 +1059,16 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
* disturbing its variable arity property:
* {@code mh.asType(mh.type().changeParameterType(0,int.class))
* .withVarargs(mh.isVarargsCollector())}
* <p>
* This call is approximately equivalent to the following code:
* <blockquote><pre>{@code
* if (makeVarargs == isVarargsCollector())
* return this;
* else if (makeVarargs)
* return asVarargsCollector(type().lastParameterType());
* else
* return return asFixedArity();
* }</pre></blockquote>
* @param makeVarargs true if the return method handle should have variable arity behavior
* @return a method handle of the same type, with possibly adjusted variable arity behavior
* @throws IllegalArgumentException if {@code makeVarargs} is true and
...
...
@@ -995,11 +1077,10 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
* @see #asVarargsCollector
* @see #asFixedArity
*/
public
MethodHandle
withVarargs
(
boolean
makeVarargs
)
{
if
(!
makeVarargs
)
{
return
asFixedArity
();
}
else
if
(!
isVarargsCollector
())
{
return
asVarargsCollector
(
type
().
lastParameterType
());
public
MethodHandle
withVarargs
(
boolean
makeVarargs
)
{
assert
(!
isVarargsCollector
());
// subclass responsibility
if
(
makeVarargs
)
{
return
asVarargsCollector
(
type
().
lastParameterType
());
}
else
{
return
this
;
}
...
...
@@ -1026,8 +1107,9 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
* <p>
* (The array may also be a shared constant when {@code arrayLength} is zero.)
* <p>
* (<em>Note:</em> The {@code arrayType} is often identical to the last
* parameter type of the original target.
* (<em>Note:</em> The {@code arrayType} is often identical to the
* {@linkplain MethodType#lastParameterType last parameter type}
* of the original target.
* It is an explicit argument for symmetry with {@code asSpreader}, and also
* to allow the target to use a simple {@code Object} as its last parameter type.)
* <p>
...
...
@@ -1168,7 +1250,9 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
* {@code invoke} and {@code asType} requests can lead to
* trailing positional arguments being collected into target's
* trailing parameter.
* Also, the last parameter type of the adapter will be
* Also, the
* {@linkplain MethodType#lastParameterType last parameter type}
* of the adapter will be
* {@code arrayType}, even if the target has a different
* last parameter type.
* <p>
...
...
src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
浏览文件 @
715ab60a
...
...
@@ -523,6 +523,12 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
return
asFixedArity
();
}
@Override
public
MethodHandle
withVarargs
(
boolean
makeVarargs
)
{
if
(
makeVarargs
)
return
this
;
return
asFixedArity
();
}
@Override
public
MethodHandle
asTypeUncached
(
MethodType
newType
)
{
MethodType
type
=
this
.
type
();
...
...
@@ -561,6 +567,49 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
:
Arrays
.
asList
(
this
,
newType
);
return
true
;
}
@Override
public
Object
invokeWithArguments
(
Object
...
arguments
)
throws
Throwable
{
MethodType
type
=
this
.
type
();
int
argc
;
final
int
MAX_SAFE
=
127
;
// 127 longs require 254 slots, which is safe to spread
if
(
arguments
==
null
||
(
argc
=
arguments
.
length
)
<=
MAX_SAFE
||
argc
<
type
.
parameterCount
())
{
return
super
.
invokeWithArguments
(
arguments
);
}
// a jumbo invocation requires more explicit reboxing of the trailing arguments
int
uncollected
=
type
.
parameterCount
()
-
1
;
Class
<?>
elemType
=
arrayType
.
getComponentType
();
int
collected
=
argc
-
uncollected
;
Object
collArgs
=
(
elemType
==
Object
.
class
)
?
new
Object
[
collected
]
:
Array
.
newInstance
(
elemType
,
collected
);
if
(!
elemType
.
isPrimitive
())
{
// simple cast: just do some casting
try
{
System
.
arraycopy
(
arguments
,
uncollected
,
collArgs
,
0
,
collected
);
}
catch
(
ArrayStoreException
ex
)
{
return
super
.
invokeWithArguments
(
arguments
);
}
}
else
{
// corner case of flat array requires reflection (or specialized copy loop)
MethodHandle
arraySetter
=
MethodHandles
.
arrayElementSetter
(
arrayType
);
try
{
for
(
int
i
=
0
;
i
<
collected
;
i
++)
{
arraySetter
.
invoke
(
collArgs
,
i
,
arguments
[
uncollected
+
i
]);
}
}
catch
(
WrongMethodTypeException
|
ClassCastException
ex
)
{
return
super
.
invokeWithArguments
(
arguments
);
}
}
// chop the jumbo list down to size and call in non-varargs mode
Object
[]
newArgs
=
new
Object
[
uncollected
+
1
];
System
.
arraycopy
(
arguments
,
0
,
newArgs
,
0
,
uncollected
);
newArgs
[
uncollected
]
=
collArgs
;
return
asFixedArity
().
invokeWithArguments
(
newArgs
);
}
}
/** Factory method: Spread selected argument. */
...
...
src/java.base/share/classes/java/lang/invoke/MethodType.java
浏览文件 @
715ab60a
/*
* Copyright (c) 2008, 201
5
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -759,7 +759,23 @@ class MethodType implements java.io.Serializable {
return
Collections
.
unmodifiableList
(
Arrays
.
asList
(
ptypes
.
clone
()));
}
/*non-public*/
Class
<?>
lastParameterType
()
{
/**
* Returns the last parameter type of this method type.
* If this type has no parameters, the sentinel value
* {@code void.class} is returned instead.
* @apiNote
* <p>
* The sentinel value is chosen so that reflective queries can be
* made directly against the result value.
* The sentinel value cannot be confused with a real parameter,
* since {@code void} is never acceptable as a parameter type.
* For variable arity invocation modes, the expression
* {@link Class#getComponentType lastParameterType().getComponentType()}
* is useful to query the type of the "varargs" parameter.
* @return the last parameter type if any, else {@code void.class}
* @since 10
*/
public
Class
<?>
lastParameterType
()
{
int
len
=
ptypes
.
length
;
return
len
==
0
?
void
.
class
:
ptypes
[
len
-
1
];
}
...
...
src/java.base/share/classes/java/lang/invoke/package-info.java
浏览文件 @
715ab60a
...
...
@@ -81,12 +81,19 @@
* in which dynamic call site occurs </li>
* <li>a {@code String}, the method name mentioned in the call site </li>
* <li>a {@code MethodType}, the resolved type descriptor of the call </li>
* <li>optionally,
between 1 and 251
additional static arguments taken from the constant pool </li>
* <li>optionally,
any number of
additional static arguments taken from the constant pool </li>
* </ul>
* Invocation is as if by
* {@link java.lang.invoke.MethodHandle#invoke MethodHandle.invoke}.
* The returned result must be a {@link java.lang.invoke.CallSite CallSite}
* (or a subclass), otherwise a
* <p>
* In all cases, bootstrap method invocation is as if by
* {@link java.lang.invoke.MethodHandle#invokeWithArguments MethodHandle.invokeWithArguments},
* (This is also equivalent to
* {@linkplain java.lang.invoke.MethodHandle#invoke generic invocation}
* if the number of arguments is small enough.)
* <p>
* For an {@code invokedynamic} instruction, the
* returned result must be convertible to a non-null reference to a
* {@link java.lang.invoke.CallSite CallSite}.
* If the returned result cannot be converted to the expected type,
* {@link java.lang.BootstrapMethodError BootstrapMethodError} is thrown.
* The type of the call site's target must be exactly equal to the type
* derived from the dynamic call site's type descriptor and passed to
...
...
@@ -150,10 +157,12 @@
* If the {@code invokedynamic} instruction specifies one or more static arguments,
* those values will be passed as additional arguments to the method handle.
* (Note that because there is a limit of 255 arguments to any method,
* at most 251 extra arguments can be supplied, since the bootstrap method
* at most 251 extra arguments can be supplied to a non-varargs bootstrap method,
* since the bootstrap method
* handle itself and its first three arguments must also be stacked.)
* The bootstrap method will be invoked as if by either {@code MethodHandle.invoke}
* or {@code invokeWithArguments}. (There is no way to tell the difference.)
* The bootstrap method will be invoked as if by {@code MethodHandle.invokeWithArguments}.
* A variable-arity bootstrap method can accept thousands of static arguments,
* subject only by limits imposed by the class-file format.
* <p>
* The normal argument conversion rules for {@code MethodHandle.invoke} apply to all stacked arguments.
* For example, if a pushed value is a primitive type, it may be converted to a reference by boxing conversion.
...
...
@@ -194,9 +203,9 @@
* </tbody>
* </table>
* The last example assumes that the extra arguments are of type
* {@code
CONSTANT_String} and {@code CONSTANT_Integer}
, respectively.
* {@code
String} and {@code Integer} (or {@code int})
, respectively.
* The second-to-last example assumes that all extra arguments are of type
* {@code
CONSTANT_
String}.
* {@code String}.
* The other examples work with all types of extra arguments.
* <p>
* As noted above, the actual method type of the bootstrap method can vary.
...
...
@@ -220,7 +229,7 @@
* to safely and compactly encode metadata.
* In principle, the name and extra arguments are redundant,
* since each call site could be given its own unique bootstrap method.
* Such a practice
is
likely to produce large class files and constant pools.
* Such a practice
would be
likely to produce large class files and constant pools.
*
* @author John Rose, JSR 292 EG
* @since 1.7
...
...
test/jdk/java/lang/invoke/BigArityTest.java
浏览文件 @
715ab60a
/*
* Copyright (c) 2012, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -22,13 +22,15 @@
*/
/* @test
* @summary High arity invocations
, up to the maximum of 255 arguments
* @summary High arity invocations
* @compile BigArityTest.java
* @run junit/othervm/timeout=2500 -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -esa -DBigArityTest.ITERATION_COUNT=1 test.java.lang.invoke.BigArityTest
*/
package
test.java.lang.invoke
;
import
org.junit.Test
;
import
java.lang.invoke.MethodHandle
;
import
java.lang.invoke.MethodHandles
;
import
java.lang.invoke.MethodType
;
...
...
@@ -37,8 +39,8 @@ import java.util.ArrayList;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Objects
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
org.junit.Test
;
public
class
BigArityTest
{
...
...
@@ -63,12 +65,70 @@ public class BigArityTest {
static
Object
hashArguments
(
Object
...
args
)
{
return
Objects
.
hash
(
args
);
}
static
Object
hashArguments
(
int
...
args
)
{
Object
[]
wrappedArgs
=
new
Object
[
args
.
length
];
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
wrappedArgs
[
i
]
=
args
[
i
];
}
return
hashArguments
(
wrappedArgs
);
}
static
Object
hashArguments
(
long
...
args
)
{
Object
[]
wrappedArgs
=
new
Object
[
args
.
length
];
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
wrappedArgs
[
i
]
=
(
int
)
args
[
i
];
}
return
hashArguments
(
wrappedArgs
);
}
static
Object
hashArguments1
(
Object
o
,
Object
...
args
)
{
Object
[]
arr
=
new
Object
[
args
.
length
+
1
];
arr
[
0
]
=
0
;
System
.
arraycopy
(
args
,
0
,
arr
,
1
,
args
.
length
);
return
Objects
.
hash
(
arr
);
}
static
Object
hashArguments1
(
int
i0
,
int
...
args
)
{
Object
[]
wrappedArgs
=
new
Object
[
args
.
length
+
1
];
wrappedArgs
[
0
]
=
i0
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
wrappedArgs
[
i
+
1
]
=
args
[
i
];
}
return
hashArguments
(
wrappedArgs
);
}
static
Object
hashArguments1
(
long
l0
,
long
...
args
)
{
Object
[]
wrappedArgs
=
new
Object
[
args
.
length
+
1
];
wrappedArgs
[
0
]
=
l0
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
wrappedArgs
[
i
+
1
]
=
(
int
)
args
[
i
];
}
return
hashArguments
(
wrappedArgs
);
}
static
final
MethodHandle
MH_hashArguments_VA
;
static
final
MethodHandle
MH_hashArguments_IVA
;
static
final
MethodHandle
MH_hashArguments_JVA
;
static
final
MethodHandle
MH_hashArguments1_VA
;
static
final
MethodHandle
MH_hashArguments1_IVA
;
static
final
MethodHandle
MH_hashArguments1_JVA
;
static
{
try
{
MH_hashArguments_VA
=
MethodHandles
.
lookup
().
unreflect
(
BigArityTest
.
class
.
getDeclaredMethod
(
"hashArguments"
,
Object
[].
class
));
MH_hashArguments_IVA
=
MethodHandles
.
lookup
().
unreflect
(
BigArityTest
.
class
.
getDeclaredMethod
(
"hashArguments"
,
int
[].
class
));
MH_hashArguments_JVA
=
MethodHandles
.
lookup
().
unreflect
(
BigArityTest
.
class
.
getDeclaredMethod
(
"hashArguments"
,
long
[].
class
));
MH_hashArguments1_VA
=
MethodHandles
.
lookup
().
unreflect
(
BigArityTest
.
class
.
getDeclaredMethod
(
"hashArguments1"
,
Object
.
class
,
Object
[].
class
));
MH_hashArguments1_IVA
=
MethodHandles
.
lookup
().
unreflect
(
BigArityTest
.
class
.
getDeclaredMethod
(
"hashArguments1"
,
int
.
class
,
int
[].
class
));
MH_hashArguments1_JVA
=
MethodHandles
.
lookup
().
unreflect
(
BigArityTest
.
class
.
getDeclaredMethod
(
"hashArguments1"
,
long
.
class
,
long
[].
class
));
}
catch
(
ReflectiveOperationException
ex
)
{
throw
new
Error
(
ex
);
}
...
...
@@ -345,6 +405,28 @@ public class BigArityTest {
assertEquals
(
"arity=MAX_ARITY"
,
r0
,
r
);
}
@Test
public
void
testInvokeWithArgumentsJumbo
()
throws
Throwable
{
System
.
out
.
println
(
"testing invokeWithArguments on jumbo arities"
);
ArrayList
<
Integer
>
arities
=
new
ArrayList
<>();
for
(
int
arity
=
125
;
arity
<
1000
;
arity
+=
(
arity
<
MAX_ARITY
+
10
?
1
:
arity
/
7
))
{
arities
.
add
(
arity
);
Object
[]
args
=
testArgs
(
arity
);
Object
r0
=
Objects
.
hash
(
args
);
assertEquals
(
"jumbo arity="
+
arity
,
r0
,
MH_hashArguments_VA
.
invokeWithArguments
(
args
));
assertEquals
(
"jumbo arity="
+
arity
,
r0
,
MH_hashArguments1_VA
.
invokeWithArguments
(
args
));
// use primitive typed argument lists also:
assertEquals
(
"jumbo int arity="
+
arity
,
r0
,
MH_hashArguments_IVA
.
invokeWithArguments
(
args
));
assertEquals
(
"jumbo int arity="
+
arity
,
r0
,
MH_hashArguments1_IVA
.
invokeWithArguments
(
args
));
assertEquals
(
"jumbo long arity="
+
arity
,
r0
,
MH_hashArguments_JVA
.
invokeWithArguments
(
args
));
assertEquals
(
"jumbo long arity="
+
arity
,
r0
,
MH_hashArguments1_JVA
.
invokeWithArguments
(
args
));
}
System
.
out
.
println
(
" jumbo arities = "
+
arities
);
}
static
Object
[]
cat
(
Object
a
,
Object
[]
b
)
{
int
alen
=
1
,
blen
=
b
.
length
;
Object
[]
c
=
new
Object
[
alen
+
blen
];
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录