Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
d9ff92de
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
d9ff92de
编写于
10月 13, 2010
作者:
T
twisti
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6987555: JSR 292 unboxing to a boolean value fails on big-endian SPARC
Reviewed-by: never, jrose
上级
1e2faee8
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
231 addition
and
35 deletion
+231
-35
src/cpu/sparc/vm/methodHandles_sparc.cpp
src/cpu/sparc/vm/methodHandles_sparc.cpp
+36
-26
src/share/vm/prims/methodHandles.cpp
src/share/vm/prims/methodHandles.cpp
+4
-4
src/share/vm/prims/methodHandles.hpp
src/share/vm/prims/methodHandles.hpp
+14
-5
test/compiler/6987555/Test6987555.java
test/compiler/6987555/Test6987555.java
+177
-0
未找到文件。
src/cpu/sparc/vm/methodHandles_sparc.cpp
浏览文件 @
d9ff92de
...
@@ -27,6 +27,14 @@
...
@@ -27,6 +27,14 @@
#define __ _masm->
#define __ _masm->
#ifdef PRODUCT
#define BLOCK_COMMENT(str)
/* nothing */
#else
#define BLOCK_COMMENT(str) __ block_comment(str)
#endif
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
address
MethodHandleEntry
::
start_compiled_entry
(
MacroAssembler
*
_masm
,
address
MethodHandleEntry
::
start_compiled_entry
(
MacroAssembler
*
_masm
,
address
interpreted_entry
)
{
address
interpreted_entry
)
{
// Just before the actual machine code entry point, allocate space
// Just before the actual machine code entry point, allocate space
...
@@ -105,6 +113,7 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
...
@@ -105,6 +113,7 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
static
void
verify_argslot
(
MacroAssembler
*
_masm
,
Register
argslot_reg
,
Register
temp_reg
,
const
char
*
error_message
)
{
static
void
verify_argslot
(
MacroAssembler
*
_masm
,
Register
argslot_reg
,
Register
temp_reg
,
const
char
*
error_message
)
{
// Verify that argslot lies within (Gargs, FP].
// Verify that argslot lies within (Gargs, FP].
Label
L_ok
,
L_bad
;
Label
L_ok
,
L_bad
;
BLOCK_COMMENT
(
"{ verify_argslot"
);
#ifdef _LP64
#ifdef _LP64
__
add
(
FP
,
STACK_BIAS
,
temp_reg
);
__
add
(
FP
,
STACK_BIAS
,
temp_reg
);
__
cmp
(
argslot_reg
,
temp_reg
);
__
cmp
(
argslot_reg
,
temp_reg
);
...
@@ -119,6 +128,7 @@ static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register
...
@@ -119,6 +128,7 @@ static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register
__
bind
(
L_bad
);
__
bind
(
L_bad
);
__
stop
(
error_message
);
__
stop
(
error_message
);
__
bind
(
L_ok
);
__
bind
(
L_ok
);
BLOCK_COMMENT
(
"} verify_argslot"
);
}
}
#endif
#endif
...
@@ -175,6 +185,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
...
@@ -175,6 +185,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
// for (temp = sp + size; temp < argslot; temp++)
// for (temp = sp + size; temp < argslot; temp++)
// temp[-size] = temp[0]
// temp[-size] = temp[0]
// argslot -= size;
// argslot -= size;
BLOCK_COMMENT
(
"insert_arg_slots {"
);
RegisterOrConstant
offset
=
__
regcon_sll_ptr
(
arg_slots
,
LogBytesPerWord
,
temp3_reg
);
RegisterOrConstant
offset
=
__
regcon_sll_ptr
(
arg_slots
,
LogBytesPerWord
,
temp3_reg
);
// Keep the stack pointer 2*wordSize aligned.
// Keep the stack pointer 2*wordSize aligned.
...
@@ -187,7 +198,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
...
@@ -187,7 +198,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
{
{
Label
loop
;
Label
loop
;
__
bind
(
loop
);
__
BIND
(
loop
);
// pull one word down each time through the loop
// pull one word down each time through the loop
__
ld_ptr
(
Address
(
temp_reg
,
0
),
temp2_reg
);
__
ld_ptr
(
Address
(
temp_reg
,
0
),
temp2_reg
);
__
st_ptr
(
temp2_reg
,
Address
(
temp_reg
,
offset
));
__
st_ptr
(
temp2_reg
,
Address
(
temp_reg
,
offset
));
...
@@ -199,6 +210,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
...
@@ -199,6 +210,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
// Now move the argslot down, to point to the opened-up space.
// Now move the argslot down, to point to the opened-up space.
__
add
(
argslot_reg
,
offset
,
argslot_reg
);
__
add
(
argslot_reg
,
offset
,
argslot_reg
);
BLOCK_COMMENT
(
"} insert_arg_slots"
);
}
}
...
@@ -235,6 +247,7 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
...
@@ -235,6 +247,7 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
}
}
#endif // ASSERT
#endif // ASSERT
BLOCK_COMMENT
(
"remove_arg_slots {"
);
// Pull up everything shallower than argslot.
// Pull up everything shallower than argslot.
// Then remove the excess space on the stack.
// Then remove the excess space on the stack.
// The stacked return address gets pulled up with everything else.
// The stacked return address gets pulled up with everything else.
...
@@ -246,7 +259,7 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
...
@@ -246,7 +259,7 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
__
sub
(
argslot_reg
,
wordSize
,
temp_reg
);
// source pointer for copy
__
sub
(
argslot_reg
,
wordSize
,
temp_reg
);
// source pointer for copy
{
{
Label
loop
;
Label
loop
;
__
bind
(
loop
);
__
BIND
(
loop
);
// pull one word up each time through the loop
// pull one word up each time through the loop
__
ld_ptr
(
Address
(
temp_reg
,
0
),
temp2_reg
);
__
ld_ptr
(
Address
(
temp_reg
,
0
),
temp2_reg
);
__
st_ptr
(
temp2_reg
,
Address
(
temp_reg
,
offset
));
__
st_ptr
(
temp2_reg
,
Address
(
temp_reg
,
offset
));
...
@@ -265,29 +278,35 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
...
@@ -265,29 +278,35 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
const
int
TwoWordAlignmentMask
=
right_n_bits
(
LogBytesPerWord
+
1
);
const
int
TwoWordAlignmentMask
=
right_n_bits
(
LogBytesPerWord
+
1
);
RegisterOrConstant
masked_offset
=
__
regcon_andn_ptr
(
offset
,
TwoWordAlignmentMask
,
temp_reg
);
RegisterOrConstant
masked_offset
=
__
regcon_andn_ptr
(
offset
,
TwoWordAlignmentMask
,
temp_reg
);
__
add
(
SP
,
masked_offset
,
SP
);
__
add
(
SP
,
masked_offset
,
SP
);
BLOCK_COMMENT
(
"} remove_arg_slots"
);
}
}
#ifndef PRODUCT
#ifndef PRODUCT
extern
"C"
void
print_method_handle
(
oop
mh
);
extern
"C"
void
print_method_handle
(
oop
mh
);
void
trace_method_handle_stub
(
const
char
*
adaptername
,
void
trace_method_handle_stub
(
const
char
*
adaptername
,
oop
mh
)
{
oopDesc
*
mh
)
{
#if 0
intptr_t* entry_sp,
intptr_t* saved_sp,
intptr_t* saved_bp) {
// called as a leaf from native code: do not block the JVM!
intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
if (last_sp != saved_sp)
printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
#endif
printf
(
"MH %s mh="
INTPTR_FORMAT
"
\n
"
,
adaptername
,
(
intptr_t
)
mh
);
printf
(
"MH %s mh="
INTPTR_FORMAT
"
\n
"
,
adaptername
,
(
intptr_t
)
mh
);
print_method_handle
(
mh
);
print_method_handle
(
mh
);
}
}
void
MethodHandles
::
trace_method_handle
(
MacroAssembler
*
_masm
,
const
char
*
adaptername
)
{
if
(
!
TraceMethodHandles
)
return
;
BLOCK_COMMENT
(
"trace_method_handle {"
);
// save: Gargs, O5_savedSP
__
save_frame
(
16
);
__
set
((
intptr_t
)
adaptername
,
O0
);
__
mov
(
G3_method_handle
,
O1
);
__
mov
(
G3_method_handle
,
L3
);
__
mov
(
Gargs
,
L4
);
__
mov
(
G5_method_type
,
L5
);
__
call_VM_leaf
(
L7
,
CAST_FROM_FN_PTR
(
address
,
trace_method_handle_stub
));
__
mov
(
L3
,
G3_method_handle
);
__
mov
(
L4
,
Gargs
);
__
mov
(
L5
,
G5_method_type
);
__
restore
();
BLOCK_COMMENT
(
"} trace_method_handle"
);
}
#endif // PRODUCT
#endif // PRODUCT
// which conversion op types are implemented here?
// which conversion op types are implemented here?
...
@@ -349,16 +368,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
...
@@ -349,16 +368,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
address
interp_entry
=
__
pc
();
address
interp_entry
=
__
pc
();
#ifndef PRODUCT
trace_method_handle
(
_masm
,
entry_name
(
ek
));
if
(
TraceMethodHandles
)
{
// save: Gargs, O5_savedSP
__
save
(
SP
,
-
16
*
wordSize
,
SP
);
__
set
((
intptr_t
)
entry_name
(
ek
),
O0
);
__
mov
(
G3_method_handle
,
O1
);
__
call_VM_leaf
(
Lscratch
,
CAST_FROM_FN_PTR
(
address
,
trace_method_handle_stub
));
__
restore
(
SP
,
16
*
wordSize
,
SP
);
}
#endif // PRODUCT
switch
((
int
)
ek
)
{
switch
((
int
)
ek
)
{
case
_raise_exception
:
case
_raise_exception
:
...
...
src/share/vm/prims/methodHandles.cpp
浏览文件 @
d9ff92de
...
@@ -1568,7 +1568,7 @@ void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnu
...
@@ -1568,7 +1568,7 @@ void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnu
if
(
ptype
!=
T_INT
)
{
if
(
ptype
!=
T_INT
)
{
int
value_offset
=
java_lang_boxing_object
::
value_offset_in_bytes
(
T_INT
);
int
value_offset
=
java_lang_boxing_object
::
value_offset_in_bytes
(
T_INT
);
jint
value
=
argument
->
int_field
(
value_offset
);
jint
value
=
argument
->
int_field
(
value_offset
);
int
vminfo
=
adapter_subword_vminfo
(
ptype
);
int
vminfo
=
adapter_
unbox_
subword_vminfo
(
ptype
);
jint
subword
=
truncate_subword_from_vminfo
(
value
,
vminfo
);
jint
subword
=
truncate_subword_from_vminfo
(
value
,
vminfo
);
if
(
value
!=
subword
)
{
if
(
value
!=
subword
)
{
err
=
"bound subword value does not fit into the subword type"
;
err
=
"bound subword value does not fit into the subword type"
;
...
@@ -2018,12 +2018,12 @@ void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnu
...
@@ -2018,12 +2018,12 @@ void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnu
assert
(
src
==
T_INT
||
is_subword_type
(
src
),
"source is not float"
);
assert
(
src
==
T_INT
||
is_subword_type
(
src
),
"source is not float"
);
// Subword-related cases are int -> {boolean,byte,char,short}.
// Subword-related cases are int -> {boolean,byte,char,short}.
ek_opt
=
_adapter_opt_i2i
;
ek_opt
=
_adapter_opt_i2i
;
vminfo
=
adapter_subword_vminfo
(
dest
);
vminfo
=
adapter_
prim_to_prim_
subword_vminfo
(
dest
);
break
;
break
;
case
2
*
4
+
1
:
case
2
*
4
+
1
:
if
(
src
==
T_LONG
&&
(
dest
==
T_INT
||
is_subword_type
(
dest
)))
{
if
(
src
==
T_LONG
&&
(
dest
==
T_INT
||
is_subword_type
(
dest
)))
{
ek_opt
=
_adapter_opt_l2i
;
ek_opt
=
_adapter_opt_l2i
;
vminfo
=
adapter_subword_vminfo
(
dest
);
vminfo
=
adapter_
prim_to_prim_
subword_vminfo
(
dest
);
}
else
if
(
src
==
T_DOUBLE
&&
dest
==
T_FLOAT
)
{
}
else
if
(
src
==
T_DOUBLE
&&
dest
==
T_FLOAT
)
{
ek_opt
=
_adapter_opt_d2f
;
ek_opt
=
_adapter_opt_d2f
;
}
else
{
}
else
{
...
@@ -2051,7 +2051,7 @@ void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnu
...
@@ -2051,7 +2051,7 @@ void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnu
switch
(
type2size
[
dest
])
{
switch
(
type2size
[
dest
])
{
case
1
:
case
1
:
ek_opt
=
_adapter_opt_unboxi
;
ek_opt
=
_adapter_opt_unboxi
;
vminfo
=
adapter_subword_vminfo
(
dest
);
vminfo
=
adapter_
unbox_
subword_vminfo
(
dest
);
break
;
break
;
case
2
:
case
2
:
ek_opt
=
_adapter_opt_unboxl
;
ek_opt
=
_adapter_opt_unboxl
;
...
...
src/share/vm/prims/methodHandles.hpp
浏览文件 @
d9ff92de
...
@@ -226,11 +226,20 @@ class MethodHandles: AllStatic {
...
@@ -226,11 +226,20 @@ class MethodHandles: AllStatic {
}
}
enum
{
CONV_VMINFO_SIGN_FLAG
=
0x80
};
enum
{
CONV_VMINFO_SIGN_FLAG
=
0x80
};
static
int
adapter_subword_vminfo
(
BasicType
dest
)
{
// Shift values for prim-to-prim conversions.
if
(
dest
==
T_BOOLEAN
)
return
(
BitsPerInt
-
1
);
static
int
adapter_prim_to_prim_subword_vminfo
(
BasicType
dest
)
{
if
(
dest
==
T_CHAR
)
return
(
BitsPerInt
-
16
);
if
(
dest
==
T_BOOLEAN
)
return
(
BitsPerInt
-
1
);
// boolean is 1 bit
if
(
dest
==
T_BYTE
)
return
(
BitsPerInt
-
8
)
|
CONV_VMINFO_SIGN_FLAG
;
if
(
dest
==
T_CHAR
)
return
(
BitsPerInt
-
BitsPerShort
);
if
(
dest
==
T_SHORT
)
return
(
BitsPerInt
-
16
)
|
CONV_VMINFO_SIGN_FLAG
;
if
(
dest
==
T_BYTE
)
return
(
BitsPerInt
-
BitsPerByte
)
|
CONV_VMINFO_SIGN_FLAG
;
if
(
dest
==
T_SHORT
)
return
(
BitsPerInt
-
BitsPerShort
)
|
CONV_VMINFO_SIGN_FLAG
;
return
0
;
// case T_INT
}
// Shift values for unboxing a primitive.
static
int
adapter_unbox_subword_vminfo
(
BasicType
dest
)
{
if
(
dest
==
T_BOOLEAN
)
return
(
BitsPerInt
-
BitsPerByte
);
// implemented as 1 byte
if
(
dest
==
T_CHAR
)
return
(
BitsPerInt
-
BitsPerShort
);
if
(
dest
==
T_BYTE
)
return
(
BitsPerInt
-
BitsPerByte
)
|
CONV_VMINFO_SIGN_FLAG
;
if
(
dest
==
T_SHORT
)
return
(
BitsPerInt
-
BitsPerShort
)
|
CONV_VMINFO_SIGN_FLAG
;
return
0
;
// case T_INT
return
0
;
// case T_INT
}
}
// Here is the transformation the i2i adapter must perform:
// Here is the transformation the i2i adapter must perform:
...
...
test/compiler/6987555/Test6987555.java
0 → 100644
浏览文件 @
d9ff92de
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/**
* @test
* @bug 6987555
* @summary JSR 292 unboxing to a boolean value fails on big-endian SPARC
*
* @run main/othervm -Xint -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6987555
*/
import
java.dyn.*
;
public
class
Test6987555
{
private
static
final
Class
CLASS
=
Test6987555
.
class
;
private
static
final
String
NAME
=
"foo"
;
private
static
final
boolean
DEBUG
=
false
;
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
testboolean
();
testbyte
();
testchar
();
testshort
();
testint
();
}
// boolean
static
void
testboolean
()
throws
Throwable
{
doboolean
(
false
);
doboolean
(
true
);
}
static
void
doboolean
(
boolean
x
)
throws
Throwable
{
if
(
DEBUG
)
System
.
out
.
println
(
"boolean="
+
x
);
MethodHandle
mh1
=
MethodHandles
.
lookup
().
findStatic
(
CLASS
,
NAME
,
MethodType
.
methodType
(
boolean
.
class
,
boolean
.
class
));
MethodHandle
mh2
=
mh1
.
asType
(
MethodType
.
methodType
(
boolean
.
class
,
Boolean
.
class
));
boolean
a
=
mh1
.<
boolean
>
invokeExact
(
x
);
boolean
b
=
mh2
.<
boolean
>
invokeExact
(
Boolean
.
valueOf
(
x
));
assert
a
==
b
:
a
+
" != "
+
b
;
}
// byte
static
void
testbyte
()
throws
Throwable
{
byte
[]
a
=
new
byte
[]
{
Byte
.
MIN_VALUE
,
Byte
.
MIN_VALUE
+
1
,
-
0x0F
,
-
1
,
0
,
1
,
0x0F
,
Byte
.
MAX_VALUE
-
1
,
Byte
.
MAX_VALUE
};
for
(
int
i
=
0
;
i
<
a
.
length
;
i
++)
{
dobyte
(
a
[
i
]);
}
}
static
void
dobyte
(
byte
x
)
throws
Throwable
{
if
(
DEBUG
)
System
.
out
.
println
(
"byte="
+
x
);
MethodHandle
mh1
=
MethodHandles
.
lookup
().
findStatic
(
CLASS
,
NAME
,
MethodType
.
methodType
(
byte
.
class
,
byte
.
class
));
MethodHandle
mh2
=
mh1
.
asType
(
MethodType
.
methodType
(
byte
.
class
,
Byte
.
class
));
byte
a
=
mh1
.<
byte
>
invokeExact
(
x
);
byte
b
=
mh2
.<
byte
>
invokeExact
(
Byte
.
valueOf
(
x
));
assert
a
==
b
:
a
+
" != "
+
b
;
}
// char
static
void
testchar
()
throws
Throwable
{
char
[]
a
=
new
char
[]
{
Character
.
MIN_VALUE
,
Character
.
MIN_VALUE
+
1
,
0x000F
,
0x00FF
,
0x0FFF
,
Character
.
MAX_VALUE
-
1
,
Character
.
MAX_VALUE
};
for
(
int
i
=
0
;
i
<
a
.
length
;
i
++)
{
dochar
(
a
[
i
]);
}
}
static
void
dochar
(
char
x
)
throws
Throwable
{
if
(
DEBUG
)
System
.
out
.
println
(
"char="
+
x
);
MethodHandle
mh1
=
MethodHandles
.
lookup
().
findStatic
(
CLASS
,
NAME
,
MethodType
.
methodType
(
char
.
class
,
char
.
class
));
MethodHandle
mh2
=
mh1
.
asType
(
MethodType
.
methodType
(
char
.
class
,
Character
.
class
));
char
a
=
mh1
.<
char
>
invokeExact
(
x
);
char
b
=
mh2
.<
char
>
invokeExact
(
Character
.
valueOf
(
x
));
assert
a
==
b
:
a
+
" != "
+
b
;
}
// short
static
void
testshort
()
throws
Throwable
{
short
[]
a
=
new
short
[]
{
Short
.
MIN_VALUE
,
Short
.
MIN_VALUE
+
1
,
-
0x0FFF
,
-
0x00FF
,
-
0x000F
,
-
1
,
0
,
1
,
0x000F
,
0x00FF
,
0x0FFF
,
Short
.
MAX_VALUE
-
1
,
Short
.
MAX_VALUE
};
for
(
int
i
=
0
;
i
<
a
.
length
;
i
++)
{
doshort
(
a
[
i
]);
}
}
static
void
doshort
(
short
x
)
throws
Throwable
{
if
(
DEBUG
)
System
.
out
.
println
(
"short="
+
x
);
MethodHandle
mh1
=
MethodHandles
.
lookup
().
findStatic
(
CLASS
,
NAME
,
MethodType
.
methodType
(
short
.
class
,
short
.
class
));
MethodHandle
mh2
=
mh1
.
asType
(
MethodType
.
methodType
(
short
.
class
,
Short
.
class
));
short
a
=
mh1
.<
short
>
invokeExact
(
x
);
short
b
=
mh2
.<
short
>
invokeExact
(
Short
.
valueOf
(
x
));
assert
a
==
b
:
a
+
" != "
+
b
;
}
// int
static
void
testint
()
throws
Throwable
{
int
[]
a
=
new
int
[]
{
Integer
.
MIN_VALUE
,
Integer
.
MIN_VALUE
+
1
,
-
0x00000FFF
,
-
0x000000FF
,
-
0x0000000F
,
-
1
,
0
,
1
,
0x0000000F
,
0x000000FF
,
0x00000FFF
,
Integer
.
MAX_VALUE
-
1
,
Integer
.
MAX_VALUE
};
for
(
int
i
=
0
;
i
<
a
.
length
;
i
++)
{
doint
(
a
[
i
]);
}
}
static
void
doint
(
int
x
)
throws
Throwable
{
if
(
DEBUG
)
System
.
out
.
println
(
"int="
+
x
);
MethodHandle
mh1
=
MethodHandles
.
lookup
().
findStatic
(
CLASS
,
NAME
,
MethodType
.
methodType
(
int
.
class
,
int
.
class
));
MethodHandle
mh2
=
mh1
.
asType
(
MethodType
.
methodType
(
int
.
class
,
Integer
.
class
));
int
a
=
mh1
.<
int
>
invokeExact
(
x
);
int
b
=
mh2
.<
int
>
invokeExact
(
Integer
.
valueOf
(
x
));
assert
a
==
b
:
a
+
" != "
+
b
;
}
public
static
boolean
foo
(
boolean
i
)
{
return
i
;
}
public
static
byte
foo
(
byte
i
)
{
return
i
;
}
public
static
char
foo
(
char
i
)
{
return
i
;
}
public
static
short
foo
(
short
i
)
{
return
i
;
}
public
static
int
foo
(
int
i
)
{
return
i
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录