Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
766034c2
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看板
提交
766034c2
编写于
10月 13, 2010
作者:
R
roland
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
9910a565
27925402
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
254 addition
and
43 deletion
+254
-43
src/cpu/sparc/vm/assembler_sparc.hpp
src/cpu/sparc/vm/assembler_sparc.hpp
+6
-0
src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
+14
-4
src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
+1
-1
src/cpu/sparc/vm/methodHandles_sparc.cpp
src/cpu/sparc/vm/methodHandles_sparc.cpp
+36
-26
src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
+0
-2
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
+1
-1
src/share/vm/c1/c1_LIRGenerator.cpp
src/share/vm/c1/c1_LIRGenerator.cpp
+1
-0
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/assembler_sparc.hpp
浏览文件 @
766034c2
...
...
@@ -825,6 +825,12 @@ class Assembler : public AbstractAssembler {
// test if -4096 <= x <= 4095
static
bool
is_simm13
(
int
x
)
{
return
is_simm
(
x
,
13
);
}
// test if label is in simm16 range in words (wdisp16).
bool
is_in_wdisp16_range
(
Label
&
L
)
{
intptr_t
d
=
intptr_t
(
pc
())
-
intptr_t
(
target
(
L
));
return
is_simm
(
d
,
18
);
}
enum
ASIs
{
// page 72, v9
ASI_PRIMARY
=
0x80
,
ASI_PRIMARY_LITTLE
=
0x88
...
...
src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
浏览文件 @
766034c2
...
...
@@ -425,8 +425,13 @@ void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
Register
pre_val_reg
=
pre_val
()
->
as_register
();
ce
->
mem2reg
(
addr
(),
pre_val
(),
T_OBJECT
,
patch_code
(),
info
(),
false
);
__
br_on_reg_cond
(
Assembler
::
rc_z
,
/*annul*/
false
,
Assembler
::
pt
,
pre_val_reg
,
_continuation
);
if
(
__
is_in_wdisp16_range
(
_continuation
))
{
__
br_on_reg_cond
(
Assembler
::
rc_z
,
/*annul*/
false
,
Assembler
::
pt
,
pre_val_reg
,
_continuation
);
}
else
{
__
cmp
(
pre_val_reg
,
G0
);
__
brx
(
Assembler
::
equal
,
false
,
Assembler
::
pn
,
_continuation
);
}
__
delayed
()
->
nop
();
__
call
(
Runtime1
::
entry_for
(
Runtime1
::
Runtime1
::
g1_pre_barrier_slow_id
));
...
...
@@ -452,8 +457,13 @@ void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
assert
(
new_val
()
->
is_register
(),
"Precondition."
);
Register
addr_reg
=
addr
()
->
as_pointer_register
();
Register
new_val_reg
=
new_val
()
->
as_register
();
__
br_on_reg_cond
(
Assembler
::
rc_z
,
/*annul*/
false
,
Assembler
::
pt
,
new_val_reg
,
_continuation
);
if
(
__
is_in_wdisp16_range
(
_continuation
))
{
__
br_on_reg_cond
(
Assembler
::
rc_z
,
/*annul*/
false
,
Assembler
::
pt
,
new_val_reg
,
_continuation
);
}
else
{
__
cmp
(
new_val_reg
,
G0
);
__
brx
(
Assembler
::
equal
,
false
,
Assembler
::
pn
,
_continuation
);
}
__
delayed
()
->
nop
();
__
call
(
Runtime1
::
entry_for
(
Runtime1
::
Runtime1
::
g1_post_barrier_slow_id
));
...
...
src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
浏览文件 @
766034c2
...
...
@@ -664,7 +664,7 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
// Use temps to avoid kills
LIR_Opr
t1
=
FrameMap
::
G1_opr
;
LIR_Opr
t2
=
FrameMap
::
G3_opr
;
LIR_Opr
addr
=
new_pointer_register
();
LIR_Opr
addr
=
(
type
==
objectType
)
?
new_register
(
T_OBJECT
)
:
new_pointer_register
();
// get address of field
obj
.
load_item
();
...
...
src/cpu/sparc/vm/methodHandles_sparc.cpp
浏览文件 @
766034c2
...
...
@@ -27,6 +27,14 @@
#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
interpreted_entry
)
{
// Just before the actual machine code entry point, allocate space
...
...
@@ -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
)
{
// Verify that argslot lies within (Gargs, FP].
Label
L_ok
,
L_bad
;
BLOCK_COMMENT
(
"{ verify_argslot"
);
#ifdef _LP64
__
add
(
FP
,
STACK_BIAS
,
temp_reg
);
__
cmp
(
argslot_reg
,
temp_reg
);
...
...
@@ -119,6 +128,7 @@ static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register
__
bind
(
L_bad
);
__
stop
(
error_message
);
__
bind
(
L_ok
);
BLOCK_COMMENT
(
"} verify_argslot"
);
}
#endif
...
...
@@ -175,6 +185,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
// for (temp = sp + size; temp < argslot; temp++)
// temp[-size] = temp[0]
// argslot -= size;
BLOCK_COMMENT
(
"insert_arg_slots {"
);
RegisterOrConstant
offset
=
__
regcon_sll_ptr
(
arg_slots
,
LogBytesPerWord
,
temp3_reg
);
// Keep the stack pointer 2*wordSize aligned.
...
...
@@ -187,7 +198,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
{
Label
loop
;
__
bind
(
loop
);
__
BIND
(
loop
);
// pull one word down each time through the loop
__
ld_ptr
(
Address
(
temp_reg
,
0
),
temp2_reg
);
__
st_ptr
(
temp2_reg
,
Address
(
temp_reg
,
offset
));
...
...
@@ -199,6 +210,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
// Now move the argslot down, to point to the opened-up space.
__
add
(
argslot_reg
,
offset
,
argslot_reg
);
BLOCK_COMMENT
(
"} insert_arg_slots"
);
}
...
...
@@ -235,6 +247,7 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
}
#endif // ASSERT
BLOCK_COMMENT
(
"remove_arg_slots {"
);
// Pull up everything shallower than argslot.
// Then remove the excess space on the stack.
// The stacked return address gets pulled up with everything else.
...
...
@@ -246,7 +259,7 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
__
sub
(
argslot_reg
,
wordSize
,
temp_reg
);
// source pointer for copy
{
Label
loop
;
__
bind
(
loop
);
__
BIND
(
loop
);
// pull one word up each time through the loop
__
ld_ptr
(
Address
(
temp_reg
,
0
),
temp2_reg
);
__
st_ptr
(
temp2_reg
,
Address
(
temp_reg
,
offset
));
...
...
@@ -265,29 +278,35 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
const
int
TwoWordAlignmentMask
=
right_n_bits
(
LogBytesPerWord
+
1
);
RegisterOrConstant
masked_offset
=
__
regcon_andn_ptr
(
offset
,
TwoWordAlignmentMask
,
temp_reg
);
__
add
(
SP
,
masked_offset
,
SP
);
BLOCK_COMMENT
(
"} remove_arg_slots"
);
}
#ifndef PRODUCT
extern
"C"
void
print_method_handle
(
oop
mh
);
void
trace_method_handle_stub
(
const
char
*
adaptername
,
oop
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
oopDesc
*
mh
)
{
printf
(
"MH %s mh="
INTPTR_FORMAT
"
\n
"
,
adaptername
,
(
intptr_t
)
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
// which conversion op types are implemented here?
...
...
@@ -349,16 +368,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
address
interp_entry
=
__
pc
();
#ifndef PRODUCT
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
trace_method_handle
(
_masm
,
entry_name
(
ek
));
switch
((
int
)
ek
)
{
case
_raise_exception
:
...
...
src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
浏览文件 @
766034c2
...
...
@@ -1941,8 +1941,6 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
__
cmpxchgptr
(
newval
,
Address
(
addr
,
0
));
}
else
if
(
op
->
code
()
==
lir_cas_int
)
{
__
cmpxchgl
(
newval
,
Address
(
addr
,
0
));
}
else
{
LP64_ONLY
(
__
cmpxchgq
(
newval
,
Address
(
addr
,
0
)));
}
#ifdef _LP64
}
else
if
(
op
->
code
()
==
lir_cas_long
)
{
...
...
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
浏览文件 @
766034c2
...
...
@@ -765,7 +765,7 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
ShouldNotReachHere
();
}
LIR_Opr
addr
=
new_pointer_register
();
LIR_Opr
addr
=
(
type
==
objectType
)
?
new_register
(
T_OBJECT
)
:
new_pointer_register
();
LIR_Address
*
a
;
if
(
offset
.
result
()
->
is_constant
())
{
a
=
new
LIR_Address
(
obj
.
result
(),
...
...
src/share/vm/c1/c1_LIRGenerator.cpp
浏览文件 @
766034c2
...
...
@@ -1350,6 +1350,7 @@ void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_Opr
addr
=
ptr
;
}
assert
(
addr
->
is_register
(),
"must be a register at this point"
);
assert
(
addr
->
type
()
==
T_OBJECT
,
"addr should point to an object"
);
LIR_Opr
xor_res
=
new_pointer_register
();
LIR_Opr
xor_shift_res
=
new_pointer_register
();
...
...
src/share/vm/prims/methodHandles.cpp
浏览文件 @
766034c2
...
...
@@ -1568,7 +1568,7 @@ void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnu
if
(
ptype
!=
T_INT
)
{
int
value_offset
=
java_lang_boxing_object
::
value_offset_in_bytes
(
T_INT
);
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
);
if
(
value
!=
subword
)
{
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
assert
(
src
==
T_INT
||
is_subword_type
(
src
),
"source is not float"
);
// Subword-related cases are int -> {boolean,byte,char,short}.
ek_opt
=
_adapter_opt_i2i
;
vminfo
=
adapter_subword_vminfo
(
dest
);
vminfo
=
adapter_
prim_to_prim_
subword_vminfo
(
dest
);
break
;
case
2
*
4
+
1
:
if
(
src
==
T_LONG
&&
(
dest
==
T_INT
||
is_subword_type
(
dest
)))
{
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
)
{
ek_opt
=
_adapter_opt_d2f
;
}
else
{
...
...
@@ -2051,7 +2051,7 @@ void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnu
switch
(
type2size
[
dest
])
{
case
1
:
ek_opt
=
_adapter_opt_unboxi
;
vminfo
=
adapter_subword_vminfo
(
dest
);
vminfo
=
adapter_
unbox_
subword_vminfo
(
dest
);
break
;
case
2
:
ek_opt
=
_adapter_opt_unboxl
;
...
...
src/share/vm/prims/methodHandles.hpp
浏览文件 @
766034c2
...
...
@@ -226,11 +226,20 @@ class MethodHandles: AllStatic {
}
enum
{
CONV_VMINFO_SIGN_FLAG
=
0x80
};
static
int
adapter_subword_vminfo
(
BasicType
dest
)
{
if
(
dest
==
T_BOOLEAN
)
return
(
BitsPerInt
-
1
);
if
(
dest
==
T_CHAR
)
return
(
BitsPerInt
-
16
);
if
(
dest
==
T_BYTE
)
return
(
BitsPerInt
-
8
)
|
CONV_VMINFO_SIGN_FLAG
;
if
(
dest
==
T_SHORT
)
return
(
BitsPerInt
-
16
)
|
CONV_VMINFO_SIGN_FLAG
;
// Shift values for prim-to-prim conversions.
static
int
adapter_prim_to_prim_subword_vminfo
(
BasicType
dest
)
{
if
(
dest
==
T_BOOLEAN
)
return
(
BitsPerInt
-
1
);
// boolean is 1 bit
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
}
// 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
}
// Here is the transformation the i2i adapter must perform:
...
...
test/compiler/6987555/Test6987555.java
0 → 100644
浏览文件 @
766034c2
/*
* 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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录