Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
0ba7505d
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看板
提交
0ba7505d
编写于
1月 24, 2013
作者:
K
kmo
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
6b94025c
b471683d
变更
31
隐藏空白更改
内联
并排
Showing
31 changed file
with
811 addition
and
151 deletion
+811
-151
src/cpu/x86/vm/assembler_x86.cpp
src/cpu/x86/vm/assembler_x86.cpp
+13
-1
src/cpu/x86/vm/assembler_x86.hpp
src/cpu/x86/vm/assembler_x86.hpp
+4
-0
src/cpu/x86/vm/macroAssembler_x86.cpp
src/cpu/x86/vm/macroAssembler_x86.cpp
+122
-0
src/cpu/x86/vm/macroAssembler_x86.hpp
src/cpu/x86/vm/macroAssembler_x86.hpp
+4
-0
src/cpu/x86/vm/vm_version_x86.cpp
src/cpu/x86/vm/vm_version_x86.cpp
+8
-0
src/cpu/x86/vm/x86_32.ad
src/cpu/x86/vm/x86_32.ad
+17
-0
src/cpu/x86/vm/x86_64.ad
src/cpu/x86/vm/x86_64.ad
+17
-0
src/share/vm/adlc/formssel.cpp
src/share/vm/adlc/formssel.cpp
+3
-1
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+3
-5
src/share/vm/classfile/vmSymbols.hpp
src/share/vm/classfile/vmSymbols.hpp
+5
-0
src/share/vm/compiler/oopMap.cpp
src/share/vm/compiler/oopMap.cpp
+4
-4
src/share/vm/opto/c2_globals.hpp
src/share/vm/opto/c2_globals.hpp
+3
-0
src/share/vm/opto/callnode.cpp
src/share/vm/opto/callnode.cpp
+31
-29
src/share/vm/opto/callnode.hpp
src/share/vm/opto/callnode.hpp
+3
-3
src/share/vm/opto/classes.hpp
src/share/vm/opto/classes.hpp
+1
-0
src/share/vm/opto/escape.cpp
src/share/vm/opto/escape.cpp
+35
-6
src/share/vm/opto/lcm.cpp
src/share/vm/opto/lcm.cpp
+1
-0
src/share/vm/opto/library_call.cpp
src/share/vm/opto/library_call.cpp
+49
-0
src/share/vm/opto/loopTransform.cpp
src/share/vm/opto/loopTransform.cpp
+2
-0
src/share/vm/opto/machnode.cpp
src/share/vm/opto/machnode.cpp
+1
-1
src/share/vm/opto/macro.cpp
src/share/vm/opto/macro.cpp
+11
-4
src/share/vm/opto/matcher.cpp
src/share/vm/opto/matcher.cpp
+9
-0
src/share/vm/opto/memnode.cpp
src/share/vm/opto/memnode.cpp
+20
-0
src/share/vm/opto/memnode.hpp
src/share/vm/opto/memnode.hpp
+16
-0
src/share/vm/opto/node.cpp
src/share/vm/opto/node.cpp
+61
-62
src/share/vm/opto/node.hpp
src/share/vm/opto/node.hpp
+5
-4
src/share/vm/opto/optoreg.hpp
src/share/vm/opto/optoreg.hpp
+1
-1
src/share/vm/opto/regalloc.cpp
src/share/vm/opto/regalloc.cpp
+1
-0
src/share/vm/opto/regmask.cpp
src/share/vm/opto/regmask.cpp
+29
-29
src/share/vm/opto/regmask.hpp
src/share/vm/opto/regmask.hpp
+1
-1
test/compiler/6896617/Test6896617.java
test/compiler/6896617/Test6896617.java
+331
-0
未找到文件。
src/cpu/x86/vm/assembler_x86.cpp
浏览文件 @
0ba7505d
...
...
@@ -2263,6 +2263,18 @@ void Assembler::packuswb(XMMRegister dst, XMMRegister src) {
emit_simd_arith
(
0x67
,
dst
,
src
,
VEX_SIMD_66
);
}
void
Assembler
::
vpackuswb
(
XMMRegister
dst
,
XMMRegister
nds
,
XMMRegister
src
,
bool
vector256
)
{
assert
(
VM_Version
::
supports_avx
()
&&
!
vector256
||
VM_Version
::
supports_avx2
(),
"256 bit integer vectors requires AVX2"
);
emit_vex_arith
(
0x67
,
dst
,
nds
,
src
,
VEX_SIMD_66
,
vector256
);
}
void
Assembler
::
vpermq
(
XMMRegister
dst
,
XMMRegister
src
,
int
imm8
,
bool
vector256
)
{
int
encode
=
simd_prefix_and_encode
(
dst
,
xnoreg
,
src
,
VEX_SIMD_66
,
VEX_OPCODE_0F_3A
,
true
,
vector256
);
emit_int8
(
0x00
);
emit_int8
(
0xC0
|
encode
);
emit_int8
(
imm8
);
}
void
Assembler
::
pcmpestri
(
XMMRegister
dst
,
Address
src
,
int
imm8
)
{
assert
(
VM_Version
::
supports_sse4_2
(),
""
);
InstructionMark
im
(
this
);
...
...
@@ -2475,7 +2487,7 @@ void Assembler::vptest(XMMRegister dst, Address src) {
assert
(
dst
!=
xnoreg
,
"sanity"
);
int
dst_enc
=
dst
->
encoding
();
// swap src<->dst for encoding
vex_prefix
(
src
,
dst_enc
,
dst_enc
,
VEX_SIMD_66
,
VEX_OPCODE_0F_38
,
false
,
vector256
);
vex_prefix
(
src
,
0
,
dst_enc
,
VEX_SIMD_66
,
VEX_OPCODE_0F_38
,
false
,
vector256
);
emit_int8
(
0x17
);
emit_operand
(
dst
,
src
);
}
...
...
src/cpu/x86/vm/assembler_x86.hpp
浏览文件 @
0ba7505d
...
...
@@ -1395,6 +1395,10 @@ private:
// Pack with unsigned saturation
void
packuswb
(
XMMRegister
dst
,
XMMRegister
src
);
void
packuswb
(
XMMRegister
dst
,
Address
src
);
void
vpackuswb
(
XMMRegister
dst
,
XMMRegister
nds
,
XMMRegister
src
,
bool
vector256
);
// Pemutation of 64bit words
void
vpermq
(
XMMRegister
dst
,
XMMRegister
src
,
int
imm8
,
bool
vector256
);
// SSE4.2 string instructions
void
pcmpestri
(
XMMRegister
xmm1
,
XMMRegister
xmm2
,
int
imm8
);
...
...
src/cpu/x86/vm/macroAssembler_x86.cpp
浏览文件 @
0ba7505d
...
...
@@ -6209,6 +6209,128 @@ void MacroAssembler::generate_fill(BasicType t, bool aligned,
}
BIND
(
L_exit
);
}
// encode char[] to byte[] in ISO_8859_1
void
MacroAssembler
::
encode_iso_array
(
Register
src
,
Register
dst
,
Register
len
,
XMMRegister
tmp1Reg
,
XMMRegister
tmp2Reg
,
XMMRegister
tmp3Reg
,
XMMRegister
tmp4Reg
,
Register
tmp5
,
Register
result
)
{
// rsi: src
// rdi: dst
// rdx: len
// rcx: tmp5
// rax: result
ShortBranchVerifier
sbv
(
this
);
assert_different_registers
(
src
,
dst
,
len
,
tmp5
,
result
);
Label
L_done
,
L_copy_1_char
,
L_copy_1_char_exit
;
// set result
xorl
(
result
,
result
);
// check for zero length
testl
(
len
,
len
);
jcc
(
Assembler
::
zero
,
L_done
);
movl
(
result
,
len
);
// Setup pointers
lea
(
src
,
Address
(
src
,
len
,
Address
::
times_2
));
// char[]
lea
(
dst
,
Address
(
dst
,
len
,
Address
::
times_1
));
// byte[]
negptr
(
len
);
if
(
UseSSE42Intrinsics
||
UseAVX
>=
2
)
{
Label
L_chars_8_check
,
L_copy_8_chars
,
L_copy_8_chars_exit
;
Label
L_chars_16_check
,
L_copy_16_chars
,
L_copy_16_chars_exit
;
if
(
UseAVX
>=
2
)
{
Label
L_chars_32_check
,
L_copy_32_chars
,
L_copy_32_chars_exit
;
movl
(
tmp5
,
0xff00ff00
);
// create mask to test for Unicode chars in vector
movdl
(
tmp1Reg
,
tmp5
);
vpbroadcastd
(
tmp1Reg
,
tmp1Reg
);
jmpb
(
L_chars_32_check
);
bind
(
L_copy_32_chars
);
vmovdqu
(
tmp3Reg
,
Address
(
src
,
len
,
Address
::
times_2
,
-
64
));
vmovdqu
(
tmp4Reg
,
Address
(
src
,
len
,
Address
::
times_2
,
-
32
));
vpor
(
tmp2Reg
,
tmp3Reg
,
tmp4Reg
,
/* vector256 */
true
);
vptest
(
tmp2Reg
,
tmp1Reg
);
// check for Unicode chars in vector
jccb
(
Assembler
::
notZero
,
L_copy_32_chars_exit
);
vpackuswb
(
tmp3Reg
,
tmp3Reg
,
tmp4Reg
,
/* vector256 */
true
);
vpermq
(
tmp4Reg
,
tmp3Reg
,
0xD8
,
/* vector256 */
true
);
vmovdqu
(
Address
(
dst
,
len
,
Address
::
times_1
,
-
32
),
tmp4Reg
);
bind
(
L_chars_32_check
);
addptr
(
len
,
32
);
jccb
(
Assembler
::
lessEqual
,
L_copy_32_chars
);
bind
(
L_copy_32_chars_exit
);
subptr
(
len
,
16
);
jccb
(
Assembler
::
greater
,
L_copy_16_chars_exit
);
}
else
if
(
UseSSE42Intrinsics
)
{
movl
(
tmp5
,
0xff00ff00
);
// create mask to test for Unicode chars in vector
movdl
(
tmp1Reg
,
tmp5
);
pshufd
(
tmp1Reg
,
tmp1Reg
,
0
);
jmpb
(
L_chars_16_check
);
}
bind
(
L_copy_16_chars
);
if
(
UseAVX
>=
2
)
{
vmovdqu
(
tmp2Reg
,
Address
(
src
,
len
,
Address
::
times_2
,
-
32
));
vptest
(
tmp2Reg
,
tmp1Reg
);
jccb
(
Assembler
::
notZero
,
L_copy_16_chars_exit
);
vpackuswb
(
tmp2Reg
,
tmp2Reg
,
tmp1Reg
,
/* vector256 */
true
);
vpermq
(
tmp3Reg
,
tmp2Reg
,
0xD8
,
/* vector256 */
true
);
}
else
{
if
(
UseAVX
>
0
)
{
movdqu
(
tmp3Reg
,
Address
(
src
,
len
,
Address
::
times_2
,
-
32
));
movdqu
(
tmp4Reg
,
Address
(
src
,
len
,
Address
::
times_2
,
-
16
));
vpor
(
tmp2Reg
,
tmp3Reg
,
tmp4Reg
,
/* vector256 */
false
);
}
else
{
movdqu
(
tmp3Reg
,
Address
(
src
,
len
,
Address
::
times_2
,
-
32
));
por
(
tmp2Reg
,
tmp3Reg
);
movdqu
(
tmp4Reg
,
Address
(
src
,
len
,
Address
::
times_2
,
-
16
));
por
(
tmp2Reg
,
tmp4Reg
);
}
ptest
(
tmp2Reg
,
tmp1Reg
);
// check for Unicode chars in vector
jccb
(
Assembler
::
notZero
,
L_copy_16_chars_exit
);
packuswb
(
tmp3Reg
,
tmp4Reg
);
}
movdqu
(
Address
(
dst
,
len
,
Address
::
times_1
,
-
16
),
tmp3Reg
);
bind
(
L_chars_16_check
);
addptr
(
len
,
16
);
jccb
(
Assembler
::
lessEqual
,
L_copy_16_chars
);
bind
(
L_copy_16_chars_exit
);
subptr
(
len
,
8
);
jccb
(
Assembler
::
greater
,
L_copy_8_chars_exit
);
bind
(
L_copy_8_chars
);
movdqu
(
tmp3Reg
,
Address
(
src
,
len
,
Address
::
times_2
,
-
16
));
ptest
(
tmp3Reg
,
tmp1Reg
);
jccb
(
Assembler
::
notZero
,
L_copy_8_chars_exit
);
packuswb
(
tmp3Reg
,
tmp1Reg
);
movq
(
Address
(
dst
,
len
,
Address
::
times_1
,
-
8
),
tmp3Reg
);
addptr
(
len
,
8
);
jccb
(
Assembler
::
lessEqual
,
L_copy_8_chars
);
bind
(
L_copy_8_chars_exit
);
subptr
(
len
,
8
);
jccb
(
Assembler
::
zero
,
L_done
);
}
bind
(
L_copy_1_char
);
load_unsigned_short
(
tmp5
,
Address
(
src
,
len
,
Address
::
times_2
,
0
));
testl
(
tmp5
,
0xff00
);
// check if Unicode char
jccb
(
Assembler
::
notZero
,
L_copy_1_char_exit
);
movb
(
Address
(
dst
,
len
,
Address
::
times_1
,
0
),
tmp5
);
addptr
(
len
,
1
);
jccb
(
Assembler
::
less
,
L_copy_1_char
);
bind
(
L_copy_1_char_exit
);
addptr
(
result
,
len
);
// len is negative count of not processed elements
bind
(
L_done
);
}
#undef BIND
#undef BLOCK_COMMENT
...
...
src/cpu/x86/vm/macroAssembler_x86.hpp
浏览文件 @
0ba7505d
...
...
@@ -1135,6 +1135,10 @@ public:
Register
to
,
Register
value
,
Register
count
,
Register
rtmp
,
XMMRegister
xtmp
);
void
encode_iso_array
(
Register
src
,
Register
dst
,
Register
len
,
XMMRegister
tmp1
,
XMMRegister
tmp2
,
XMMRegister
tmp3
,
XMMRegister
tmp4
,
Register
tmp5
,
Register
result
);
#undef VIRTUAL
};
...
...
src/cpu/x86/vm/vm_version_x86.cpp
浏览文件 @
0ba7505d
...
...
@@ -661,6 +661,14 @@ void VM_Version::get_processor_features() {
}
}
}
#if defined(COMPILER2) && defined(_ALLBSD_SOURCE)
if
(
MaxVectorSize
>
16
)
{
// Limit vectors size to 16 bytes on BSD until it fixes
// restoring upper 128bit of YMM registers on return
// from signal handler.
FLAG_SET_DEFAULT
(
MaxVectorSize
,
16
);
}
#endif // COMPILER2
// Use population count instruction if available.
if
(
supports_popcnt
())
{
...
...
src/cpu/x86/vm/x86_32.ad
浏览文件 @
0ba7505d
...
...
@@ -11687,6 +11687,23 @@ instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
ins_pipe( pipe_slow );
%}
// encode char[] to byte[] in ISO_8859_1
instruct encode_iso_array(eSIRegP src, eDIRegP dst, eDXRegI len,
regD tmp1, regD tmp2, regD tmp3, regD tmp4,
eCXRegI tmp5, eAXRegI result, eFlagsReg cr) %{
match(Set result (EncodeISOArray src (Binary dst len)));
effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
format %{ "Encode array $src,$dst,$len -> $result // KILL ECX, EDX, $tmp1, $tmp2, $tmp3, $tmp4, ESI, EDI " %}
ins_encode %{
__ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
$tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
$tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
%}
ins_pipe( pipe_slow );
%}
//----------Control Flow Instructions------------------------------------------
// Signed compare Instructions
instruct compI_eReg(eFlagsReg cr, rRegI op1, rRegI op2) %{
...
...
src/cpu/x86/vm/x86_64.ad
浏览文件 @
0ba7505d
...
...
@@ -10495,6 +10495,23 @@ instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
ins_pipe( pipe_slow );
%}
// encode char[] to byte[] in ISO_8859_1
instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len,
regD tmp1, regD tmp2, regD tmp3, regD tmp4,
rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
match(Set result (EncodeISOArray src (Binary dst len)));
effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %}
ins_encode %{
__ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
$tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
$tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
%}
ins_pipe( pipe_slow );
%}
//----------Control Flow Instructions------------------------------------------
// Signed compare Instructions
...
...
src/share/vm/adlc/formssel.cpp
浏览文件 @
0ba7505d
...
...
@@ -862,8 +862,10 @@ uint InstructForm::oper_input_base(FormDict &globals) {
(
strcmp
(
_matrule
->
_rChild
->
_opType
,
"AryEq"
)
==
0
||
strcmp
(
_matrule
->
_rChild
->
_opType
,
"StrComp"
)
==
0
||
strcmp
(
_matrule
->
_rChild
->
_opType
,
"StrEquals"
)
==
0
||
strcmp
(
_matrule
->
_rChild
->
_opType
,
"StrIndexOf"
)
==
0
))
{
strcmp
(
_matrule
->
_rChild
->
_opType
,
"StrIndexOf"
)
==
0
||
strcmp
(
_matrule
->
_rChild
->
_opType
,
"EncodeISOArray"
)
==
0
))
{
// String.(compareTo/equals/indexOf) and Arrays.equals
// and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray
// take 1 control and 1 memory edges.
return
2
;
}
...
...
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
0ba7505d
...
...
@@ -1802,11 +1802,9 @@ ClassFileParser::AnnotationCollector::ID
ClassFileParser
::
AnnotationCollector
::
annotation_index
(
ClassLoaderData
*
loader_data
,
Symbol
*
name
)
{
vmSymbols
::
SID
sid
=
vmSymbols
::
find_sid
(
name
);
bool
privileged
=
false
;
if
(
loader_data
->
is_the_null_class_loader_data
())
{
// Privileged code can use all annotations. Other code silently drops some.
privileged
=
true
;
}
// Privileged code can use all annotations. Other code silently drops some.
bool
privileged
=
loader_data
->
is_the_null_class_loader_data
()
||
loader_data
->
is_anonymous
();
switch
(
sid
)
{
case
vmSymbols
::
VM_SYMBOL_ENUM_NAME
(
java_lang_invoke_ForceInline_signature
):
if
(
_location
!=
_in_method
)
break
;
// only allow for methods
...
...
src/share/vm/classfile/vmSymbols.hpp
浏览文件 @
0ba7505d
...
...
@@ -735,6 +735,11 @@
do_intrinsic(_checkIndex, java_nio_Buffer, checkIndex_name, int_int_signature, F_R) \
do_name( checkIndex_name, "checkIndex") \
\
do_class(sun_nio_cs_iso8859_1_Encoder, "sun/nio/cs/ISO_8859_1$Encoder") \
do_intrinsic(_encodeISOArray, sun_nio_cs_iso8859_1_Encoder, encodeISOArray_name, encodeISOArray_signature, F_S) \
do_name( encodeISOArray_name, "encodeISOArray") \
do_signature(encodeISOArray_signature, "([CI[BII)I") \
\
/* java/lang/ref/Reference */
\
do_intrinsic(_Reference_get, java_lang_ref_Reference, get_name, void_object_signature, F_R) \
\
...
...
src/share/vm/compiler/oopMap.cpp
浏览文件 @
0ba7505d
...
...
@@ -542,17 +542,17 @@ void print_register_type(OopMapValue::oop_types x, VMReg optional,
st
->
print
(
"Oop"
);
break
;
case
OopMapValue
::
value_value
:
st
->
print
(
"Value"
);
st
->
print
(
"Value"
);
break
;
case
OopMapValue
::
narrowoop_value
:
tty
->
print
(
"NarrowOop"
);
st
->
print
(
"NarrowOop"
);
break
;
case
OopMapValue
::
callee_saved_value
:
st
->
print
(
"Callers_"
);
st
->
print
(
"Callers_"
);
optional
->
print_on
(
st
);
break
;
case
OopMapValue
::
derived_oop_value
:
st
->
print
(
"Derived_oop_"
);
st
->
print
(
"Derived_oop_"
);
optional
->
print_on
(
st
);
break
;
default:
...
...
src/share/vm/opto/c2_globals.hpp
浏览文件 @
0ba7505d
...
...
@@ -516,6 +516,9 @@
develop(bool, SpecialArraysEquals, true, \
"special version of Arrays.equals(char[],char[])") \
\
product(bool, SpecialEncodeISOArray, true, \
"special version of ISO_8859_1$Encoder.encodeISOArray") \
\
develop(bool, BailoutToInterpreterForThrows, false, \
"Compiled methods which throws/catches exceptions will be " \
"deopt and intp.") \
...
...
src/share/vm/opto/callnode.cpp
浏览文件 @
0ba7505d
...
...
@@ -165,13 +165,13 @@ uint ReturnNode::match_edge(uint idx) const {
#ifndef PRODUCT
void
ReturnNode
::
dump_req
()
const
{
void
ReturnNode
::
dump_req
(
outputStream
*
st
)
const
{
// Dump the required inputs, enclosed in '(' and ')'
uint
i
;
// Exit value of loop
for
(
i
=
0
;
i
<
req
();
i
++
)
{
// For all required inputs
if
(
i
==
TypeFunc
::
Parms
)
tty
->
print
(
"returns"
);
if
(
in
(
i
)
)
tty
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
in
(
i
))
?
' '
:
'o'
,
in
(
i
)
->
_idx
);
else
tty
->
print
(
"_ "
);
for
(
i
=
0
;
i
<
req
();
i
++
)
{
// For all required inputs
if
(
i
==
TypeFunc
::
Parms
)
st
->
print
(
"returns"
);
if
(
in
(
i
))
st
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
in
(
i
))
?
' '
:
'o'
,
in
(
i
)
->
_idx
);
else
st
->
print
(
"_ "
);
}
}
#endif
...
...
@@ -208,13 +208,13 @@ uint RethrowNode::match_edge(uint idx) const {
}
#ifndef PRODUCT
void
RethrowNode
::
dump_req
()
const
{
void
RethrowNode
::
dump_req
(
outputStream
*
st
)
const
{
// Dump the required inputs, enclosed in '(' and ')'
uint
i
;
// Exit value of loop
for
(
i
=
0
;
i
<
req
();
i
++
)
{
// For all required inputs
if
(
i
==
TypeFunc
::
Parms
)
tty
->
print
(
"exception"
);
if
(
in
(
i
)
)
tty
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
in
(
i
))
?
' '
:
'o'
,
in
(
i
)
->
_idx
);
else
tty
->
print
(
"_ "
);
for
(
i
=
0
;
i
<
req
();
i
++
)
{
// For all required inputs
if
(
i
==
TypeFunc
::
Parms
)
st
->
print
(
"exception"
);
if
(
in
(
i
))
st
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
in
(
i
))
?
' '
:
'o'
,
in
(
i
)
->
_idx
);
else
st
->
print
(
"_ "
);
}
}
#endif
...
...
@@ -330,7 +330,8 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c
st
->
print
(
" %s%d]=#ScObj"
INT32_FORMAT
,
msg
,
i
,
sco_n
);
return
;
}
if
(
OptoReg
::
is_valid
(
regalloc
->
get_reg_first
(
n
)))
{
// Check for undefined
if
(
regalloc
->
node_regs_max_index
()
>
0
&&
OptoReg
::
is_valid
(
regalloc
->
get_reg_first
(
n
)))
{
// Check for undefined
char
buf
[
50
];
regalloc
->
dump_register
(
n
,
buf
);
st
->
print
(
" %s%d]=%s"
,
msg
,
i
,
buf
);
...
...
@@ -381,7 +382,7 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c
//------------------------------format-----------------------------------------
void
JVMState
::
format
(
PhaseRegAlloc
*
regalloc
,
const
Node
*
n
,
outputStream
*
st
)
const
{
st
->
print
(
" #"
);
if
(
_method
)
{
if
(
_method
)
{
_method
->
print_short_name
(
st
);
st
->
print
(
" @ bci:%d "
,
_bci
);
}
else
{
...
...
@@ -393,21 +394,22 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
MachSafePointNode
*
mcall
=
n
->
as_MachSafePoint
();
uint
i
;
// Print locals
for
(
i
=
0
;
i
<
(
uint
)
loc_size
();
i
++
)
format_helper
(
regalloc
,
st
,
mcall
->
local
(
this
,
i
),
"L["
,
i
,
&
scobjs
);
for
(
i
=
0
;
i
<
(
uint
)
loc_size
();
i
++
)
format_helper
(
regalloc
,
st
,
mcall
->
local
(
this
,
i
),
"L["
,
i
,
&
scobjs
);
// Print stack
for
(
i
=
0
;
i
<
(
uint
)
stk_size
();
i
++
)
{
if
((
uint
)(
_stkoff
+
i
)
>=
mcall
->
len
())
st
->
print
(
" oob "
);
else
format_helper
(
regalloc
,
st
,
mcall
->
stack
(
this
,
i
),
"STK["
,
i
,
&
scobjs
);
format_helper
(
regalloc
,
st
,
mcall
->
stack
(
this
,
i
),
"STK["
,
i
,
&
scobjs
);
}
for
(
i
=
0
;
(
int
)
i
<
nof_monitors
();
i
++
)
{
Node
*
box
=
mcall
->
monitor_box
(
this
,
i
);
Node
*
obj
=
mcall
->
monitor_obj
(
this
,
i
);
if
(
OptoReg
::
is_valid
(
regalloc
->
get_reg_first
(
box
))
)
{
if
(
regalloc
->
node_regs_max_index
()
>
0
&&
OptoReg
::
is_valid
(
regalloc
->
get_reg_first
(
box
)))
{
box
=
BoxLockNode
::
box_node
(
box
);
format_helper
(
regalloc
,
st
,
box
,
"MON-BOX["
,
i
,
&
scobjs
);
format_helper
(
regalloc
,
st
,
box
,
"MON-BOX["
,
i
,
&
scobjs
);
}
else
{
OptoReg
::
Name
box_reg
=
BoxLockNode
::
reg
(
box
);
st
->
print
(
" MON-BOX%d=%s+%d"
,
...
...
@@ -420,7 +422,7 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
if
(
BoxLockNode
::
box_node
(
box
)
->
is_eliminated
())
obj_msg
=
"MON-OBJ(LOCK ELIMINATED)["
;
}
format_helper
(
regalloc
,
st
,
obj
,
obj_msg
,
i
,
&
scobjs
);
format_helper
(
regalloc
,
st
,
obj
,
obj_msg
,
i
,
&
scobjs
);
}
for
(
i
=
0
;
i
<
(
uint
)
scobjs
.
length
();
i
++
)
{
...
...
@@ -463,9 +465,9 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
st
->
print
(
" ["
);
cifield
=
iklass
->
nonstatic_field_at
(
0
);
cifield
->
print_name_on
(
st
);
format_helper
(
regalloc
,
st
,
fld_node
,
":"
,
0
,
&
scobjs
);
format_helper
(
regalloc
,
st
,
fld_node
,
":"
,
0
,
&
scobjs
);
}
else
{
format_helper
(
regalloc
,
st
,
fld_node
,
"["
,
0
,
&
scobjs
);
format_helper
(
regalloc
,
st
,
fld_node
,
"["
,
0
,
&
scobjs
);
}
for
(
uint
j
=
1
;
j
<
nf
;
j
++
)
{
fld_node
=
mcall
->
in
(
first_ind
+
j
);
...
...
@@ -473,9 +475,9 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
st
->
print
(
", ["
);
cifield
=
iklass
->
nonstatic_field_at
(
j
);
cifield
->
print_name_on
(
st
);
format_helper
(
regalloc
,
st
,
fld_node
,
":"
,
j
,
&
scobjs
);
format_helper
(
regalloc
,
st
,
fld_node
,
":"
,
j
,
&
scobjs
);
}
else
{
format_helper
(
regalloc
,
st
,
fld_node
,
", ["
,
j
,
&
scobjs
);
format_helper
(
regalloc
,
st
,
fld_node
,
", ["
,
j
,
&
scobjs
);
}
}
}
...
...
@@ -483,7 +485,7 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
}
}
st
->
print_cr
(
""
);
if
(
caller
()
!=
NULL
)
caller
()
->
format
(
regalloc
,
n
,
st
);
if
(
caller
()
!=
NULL
)
caller
()
->
format
(
regalloc
,
n
,
st
);
}
...
...
@@ -586,15 +588,15 @@ JVMState* JVMState::clone_deep(Compile* C) const {
uint
CallNode
::
cmp
(
const
Node
&
n
)
const
{
return
_tf
==
((
CallNode
&
)
n
).
_tf
&&
_jvms
==
((
CallNode
&
)
n
).
_jvms
;
}
#ifndef PRODUCT
void
CallNode
::
dump_req
()
const
{
void
CallNode
::
dump_req
(
outputStream
*
st
)
const
{
// Dump the required inputs, enclosed in '(' and ')'
uint
i
;
// Exit value of loop
for
(
i
=
0
;
i
<
req
();
i
++
)
{
// For all required inputs
if
(
i
==
TypeFunc
::
Parms
)
tty
->
print
(
"("
);
if
(
in
(
i
)
)
tty
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
in
(
i
))
?
' '
:
'o'
,
in
(
i
)
->
_idx
);
else
tty
->
print
(
"_ "
);
for
(
i
=
0
;
i
<
req
();
i
++
)
{
// For all required inputs
if
(
i
==
TypeFunc
::
Parms
)
st
->
print
(
"("
);
if
(
in
(
i
))
st
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
in
(
i
))
?
' '
:
'o'
,
in
(
i
)
->
_idx
);
else
st
->
print
(
"_ "
);
}
tty
->
print
(
")"
);
st
->
print
(
")"
);
}
void
CallNode
::
dump_spec
(
outputStream
*
st
)
const
{
...
...
src/share/vm/opto/callnode.hpp
浏览文件 @
0ba7505d
...
...
@@ -126,7 +126,7 @@ public:
virtual
uint
ideal_reg
()
const
{
return
NotAMachineReg
;
}
virtual
uint
match_edge
(
uint
idx
)
const
;
#ifndef PRODUCT
virtual
void
dump_req
()
const
;
virtual
void
dump_req
(
outputStream
*
st
=
tty
)
const
;
#endif
};
...
...
@@ -147,7 +147,7 @@ class RethrowNode : public Node {
virtual
uint
match_edge
(
uint
idx
)
const
;
virtual
uint
ideal_reg
()
const
{
return
NotAMachineReg
;
}
#ifndef PRODUCT
virtual
void
dump_req
()
const
;
virtual
void
dump_req
(
outputStream
*
st
=
tty
)
const
;
#endif
};
...
...
@@ -579,7 +579,7 @@ public:
virtual
uint
match_edge
(
uint
idx
)
const
;
#ifndef PRODUCT
virtual
void
dump_req
(
)
const
;
virtual
void
dump_req
(
outputStream
*
st
=
tty
)
const
;
virtual
void
dump_spec
(
outputStream
*
st
)
const
;
#endif
};
...
...
src/share/vm/opto/classes.hpp
浏览文件 @
0ba7505d
...
...
@@ -127,6 +127,7 @@ macro(DivL)
macro
(
DivMod
)
macro
(
DivModI
)
macro
(
DivModL
)
macro
(
EncodeISOArray
)
macro
(
EncodeP
)
macro
(
EncodePKlass
)
macro
(
ExpD
)
...
...
src/share/vm/opto/escape.cpp
浏览文件 @
0ba7505d
...
...
@@ -523,7 +523,8 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
case
Op_AryEq
:
case
Op_StrComp
:
case
Op_StrEquals
:
case
Op_StrIndexOf
:
{
case
Op_StrIndexOf
:
case
Op_EncodeISOArray
:
{
add_local_var
(
n
,
PointsToNode
::
ArgEscape
);
delayed_worklist
->
push
(
n
);
// Process it later.
break
;
...
...
@@ -701,7 +702,8 @@ void ConnectionGraph::add_final_edges(Node *n) {
case
Op_AryEq
:
case
Op_StrComp
:
case
Op_StrEquals
:
case
Op_StrIndexOf
:
{
case
Op_StrIndexOf
:
case
Op_EncodeISOArray
:
{
// char[] arrays passed to string intrinsic do not escape but
// they are not scalar replaceable. Adjust escape state for them.
// Start from in(2) edge since in(1) is memory edge.
...
...
@@ -2581,15 +2583,22 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra
}
// Otherwise skip it (the call updated 'result' value).
}
else
if
(
result
->
Opcode
()
==
Op_SCMemProj
)
{
assert
(
result
->
in
(
0
)
->
is_LoadStore
(),
"sanity"
);
const
Type
*
at
=
igvn
->
type
(
result
->
in
(
0
)
->
in
(
MemNode
::
Address
));
Node
*
mem
=
result
->
in
(
0
);
Node
*
adr
=
NULL
;
if
(
mem
->
is_LoadStore
())
{
adr
=
mem
->
in
(
MemNode
::
Address
);
}
else
{
assert
(
mem
->
Opcode
()
==
Op_EncodeISOArray
,
"sanity"
);
adr
=
mem
->
in
(
3
);
// Memory edge corresponds to destination array
}
const
Type
*
at
=
igvn
->
type
(
adr
);
if
(
at
!=
Type
::
TOP
)
{
assert
(
at
->
isa_ptr
()
!=
NULL
,
"pointer type required."
);
int
idx
=
C
->
get_alias_index
(
at
->
is_ptr
());
assert
(
idx
!=
alias_idx
,
"Object is not scalar replaceable if a LoadStore node access its field"
);
break
;
}
result
=
result
->
in
(
0
)
->
in
(
MemNode
::
Memory
);
result
=
mem
->
in
(
MemNode
::
Memory
);
}
}
if
(
result
->
is_Phi
())
{
...
...
@@ -2927,6 +2936,11 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
if
(
m
->
is_MergeMem
())
{
assert
(
_mergemem_worklist
.
contains
(
m
->
as_MergeMem
()),
"EA: missing MergeMem node in the worklist"
);
}
}
else
if
(
use
->
Opcode
()
==
Op_EncodeISOArray
)
{
if
(
use
->
in
(
MemNode
::
Memory
)
==
n
||
use
->
in
(
3
)
==
n
)
{
// EncodeISOArray overwrites destination array
memnode_worklist
.
append_if_missing
(
use
);
}
}
else
{
uint
op
=
use
->
Opcode
();
if
(
!
(
op
==
Op_CmpP
||
op
==
Op_Conv2B
||
...
...
@@ -2962,6 +2976,16 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
n
=
n
->
as_MemBar
()
->
proj_out
(
TypeFunc
::
Memory
);
if
(
n
==
NULL
)
continue
;
}
else
if
(
n
->
Opcode
()
==
Op_EncodeISOArray
)
{
// get the memory projection
for
(
DUIterator_Fast
imax
,
i
=
n
->
fast_outs
(
imax
);
i
<
imax
;
i
++
)
{
Node
*
use
=
n
->
fast_out
(
i
);
if
(
use
->
Opcode
()
==
Op_SCMemProj
)
{
n
=
use
;
break
;
}
}
assert
(
n
->
Opcode
()
==
Op_SCMemProj
,
"memory projection required"
);
}
else
{
assert
(
n
->
is_Mem
(),
"memory node required."
);
Node
*
addr
=
n
->
in
(
MemNode
::
Address
);
...
...
@@ -2999,7 +3023,7 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
Node
*
use
=
n
->
fast_out
(
i
);
if
(
use
->
is_Phi
()
||
use
->
is_ClearArray
())
{
memnode_worklist
.
append_if_missing
(
use
);
}
else
if
(
use
->
is_Mem
()
&&
use
->
in
(
MemNode
::
Memory
)
==
n
)
{
}
else
if
(
use
->
is_Mem
()
&&
use
->
in
(
MemNode
::
Memory
)
==
n
)
{
if
(
use
->
Opcode
()
==
Op_StoreCM
)
// Ignore cardmark stores
continue
;
memnode_worklist
.
append_if_missing
(
use
);
...
...
@@ -3010,6 +3034,11 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
assert
(
use
->
in
(
MemNode
::
Memory
)
!=
n
,
"EA: missing memory path"
);
}
else
if
(
use
->
is_MergeMem
())
{
assert
(
_mergemem_worklist
.
contains
(
use
->
as_MergeMem
()),
"EA: missing MergeMem node in the worklist"
);
}
else
if
(
use
->
Opcode
()
==
Op_EncodeISOArray
)
{
if
(
use
->
in
(
MemNode
::
Memory
)
==
n
||
use
->
in
(
3
)
==
n
)
{
// EncodeISOArray overwrites destination array
memnode_worklist
.
append_if_missing
(
use
);
}
}
else
{
uint
op
=
use
->
Opcode
();
if
(
!
(
op
==
Op_StoreCM
||
...
...
src/share/vm/opto/lcm.cpp
浏览文件 @
0ba7505d
...
...
@@ -175,6 +175,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe
case
Op_StrEquals
:
case
Op_StrIndexOf
:
case
Op_AryEq
:
case
Op_EncodeISOArray
:
// Not a legit memory op for implicit null check regardless of
// embedded loads
continue
;
...
...
src/share/vm/opto/library_call.cpp
浏览文件 @
0ba7505d
...
...
@@ -290,6 +290,7 @@ class LibraryCallKit : public GraphKit {
bool
inline_cipherBlockChaining_AESCrypt
(
vmIntrinsics
::
ID
id
);
Node
*
inline_cipherBlockChaining_AESCrypt_predicate
(
bool
decrypting
);
Node
*
get_key_start_from_aescrypt_object
(
Node
*
aescrypt_object
);
bool
inline_encodeISOArray
();
};
...
...
@@ -381,6 +382,10 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
// These also use the arraycopy intrinsic mechanism:
if
(
!
InlineArrayCopy
)
return
NULL
;
break
;
case
vmIntrinsics
::
_encodeISOArray
:
if
(
!
SpecialEncodeISOArray
)
return
NULL
;
if
(
!
Matcher
::
match_rule_supported
(
Op_EncodeISOArray
))
return
NULL
;
break
;
case
vmIntrinsics
::
_checkIndex
:
// We do not intrinsify this. The optimizer does fine with it.
return
NULL
;
...
...
@@ -799,6 +804,9 @@ bool LibraryCallKit::try_to_inline() {
case
vmIntrinsics
::
_cipherBlockChaining_decryptAESCrypt
:
return
inline_cipherBlockChaining_AESCrypt
(
intrinsic_id
());
case
vmIntrinsics
::
_encodeISOArray
:
return
inline_encodeISOArray
();
default:
// If you get here, it may be that someone has added a new intrinsic
// to the list in vmSymbols.hpp without implementing it here.
...
...
@@ -5368,6 +5376,47 @@ LibraryCallKit::generate_unchecked_arraycopy(const TypePtr* adr_type,
src_start
,
dest_start
,
copy_length
XTOP
);
}
//-------------inline_encodeISOArray-----------------------------------
// encode char[] to byte[] in ISO_8859_1
bool
LibraryCallKit
::
inline_encodeISOArray
()
{
assert
(
callee
()
->
signature
()
->
size
()
==
5
,
"encodeISOArray has 5 parameters"
);
// no receiver since it is static method
Node
*
src
=
argument
(
0
);
Node
*
src_offset
=
argument
(
1
);
Node
*
dst
=
argument
(
2
);
Node
*
dst_offset
=
argument
(
3
);
Node
*
length
=
argument
(
4
);
const
Type
*
src_type
=
src
->
Value
(
&
_gvn
);
const
Type
*
dst_type
=
dst
->
Value
(
&
_gvn
);
const
TypeAryPtr
*
top_src
=
src_type
->
isa_aryptr
();
const
TypeAryPtr
*
top_dest
=
dst_type
->
isa_aryptr
();
if
(
top_src
==
NULL
||
top_src
->
klass
()
==
NULL
||
top_dest
==
NULL
||
top_dest
->
klass
()
==
NULL
)
{
// failed array check
return
false
;
}
// Figure out the size and type of the elements we will be copying.
BasicType
src_elem
=
src_type
->
isa_aryptr
()
->
klass
()
->
as_array_klass
()
->
element_type
()
->
basic_type
();
BasicType
dst_elem
=
dst_type
->
isa_aryptr
()
->
klass
()
->
as_array_klass
()
->
element_type
()
->
basic_type
();
if
(
src_elem
!=
T_CHAR
||
dst_elem
!=
T_BYTE
)
{
return
false
;
}
Node
*
src_start
=
array_element_address
(
src
,
src_offset
,
src_elem
);
Node
*
dst_start
=
array_element_address
(
dst
,
dst_offset
,
dst_elem
);
// 'src_start' points to src array + scaled offset
// 'dst_start' points to dst array + scaled offset
const
TypeAryPtr
*
mtype
=
TypeAryPtr
::
BYTES
;
Node
*
enc
=
new
(
C
)
EncodeISOArrayNode
(
control
(),
memory
(
mtype
),
src_start
,
dst_start
,
length
);
enc
=
_gvn
.
transform
(
enc
);
Node
*
res_mem
=
_gvn
.
transform
(
new
(
C
)
SCMemProjNode
(
enc
));
set_memory
(
res_mem
,
mtype
);
set_result
(
enc
);
return
true
;
}
//----------------------------inline_reference_get----------------------------
// public T java.lang.ref.Reference.get();
bool
LibraryCallKit
::
inline_reference_get
()
{
...
...
src/share/vm/opto/loopTransform.cpp
浏览文件 @
0ba7505d
...
...
@@ -613,6 +613,7 @@ bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const {
case
Op_StrComp
:
case
Op_StrEquals
:
case
Op_StrIndexOf
:
case
Op_EncodeISOArray
:
case
Op_AryEq
:
{
return
false
;
}
...
...
@@ -717,6 +718,7 @@ bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const {
case
Op_StrComp
:
case
Op_StrEquals
:
case
Op_StrIndexOf
:
case
Op_EncodeISOArray
:
case
Op_AryEq
:
{
// Do not unroll a loop with String intrinsics code.
// String intrinsics are large and have loops.
...
...
src/share/vm/opto/machnode.cpp
浏览文件 @
0ba7505d
...
...
@@ -506,7 +506,7 @@ int MachConstantNode::constant_offset() {
#ifndef PRODUCT
void
MachNullCheckNode
::
format
(
PhaseRegAlloc
*
ra_
,
outputStream
*
st
)
const
{
int
reg
=
ra_
->
get_reg_first
(
in
(
1
)
->
in
(
_vidx
));
tty
->
print
(
"%s %s"
,
Name
(),
Matcher
::
regName
[
reg
]);
st
->
print
(
"%s %s"
,
Name
(),
Matcher
::
regName
[
reg
]);
}
#endif
...
...
src/share/vm/opto/macro.cpp
浏览文件 @
0ba7505d
...
...
@@ -361,14 +361,21 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me
}
// Otherwise skip it (the call updated 'mem' value).
}
else
if
(
mem
->
Opcode
()
==
Op_SCMemProj
)
{
assert
(
mem
->
in
(
0
)
->
is_LoadStore
(),
"sanity"
);
const
TypePtr
*
atype
=
mem
->
in
(
0
)
->
in
(
MemNode
::
Address
)
->
bottom_type
()
->
is_ptr
();
mem
=
mem
->
in
(
0
);
Node
*
adr
=
NULL
;
if
(
mem
->
is_LoadStore
())
{
adr
=
mem
->
in
(
MemNode
::
Address
);
}
else
{
assert
(
mem
->
Opcode
()
==
Op_EncodeISOArray
,
"sanity"
);
adr
=
mem
->
in
(
3
);
// Destination array
}
const
TypePtr
*
atype
=
adr
->
bottom_type
()
->
is_ptr
();
int
adr_idx
=
Compile
::
current
()
->
get_alias_index
(
atype
);
if
(
adr_idx
==
alias_idx
)
{
assert
(
false
,
"Object is not scalar replaceable if a LoadStore node access its field"
);
return
NULL
;
}
mem
=
mem
->
in
(
0
)
->
in
(
MemNode
::
Memory
);
mem
=
mem
->
in
(
MemNode
::
Memory
);
}
else
{
return
mem
;
}
...
...
@@ -445,7 +452,7 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *
}
values
.
at_put
(
j
,
val
);
}
else
if
(
val
->
Opcode
()
==
Op_SCMemProj
)
{
assert
(
val
->
in
(
0
)
->
is_LoadStore
(),
"sanity"
);
assert
(
val
->
in
(
0
)
->
is_LoadStore
()
||
val
->
in
(
0
)
->
Opcode
()
==
Op_EncodeISOArray
,
"sanity"
);
assert
(
false
,
"Object is not scalar replaceable if a LoadStore node access its field"
);
return
NULL
;
}
else
{
...
...
src/share/vm/opto/matcher.cpp
浏览文件 @
0ba7505d
...
...
@@ -919,6 +919,7 @@ static void match_alias_type(Compile* C, Node* n, Node* m) {
case
Op_AryEq
:
case
Op_MemBarVolatile
:
case
Op_MemBarCPUOrder
:
// %%% these ideals should have narrower adr_type?
case
Op_EncodeISOArray
:
nidx
=
Compile
::
AliasIdxTop
;
nat
=
NULL
;
break
;
...
...
@@ -1982,6 +1983,7 @@ void Matcher::find_shared( Node *n ) {
case
Op_StrEquals
:
case
Op_StrIndexOf
:
case
Op_AryEq
:
case
Op_EncodeISOArray
:
set_shared
(
n
);
// Force result into register (it will be anyways)
break
;
case
Op_ConP
:
{
// Convert pointers above the centerline to NUL
...
...
@@ -2183,6 +2185,13 @@ void Matcher::find_shared( Node *n ) {
n
->
del_req
(
4
);
break
;
}
case
Op_EncodeISOArray
:
{
// Restructure into a binary tree for Matching.
Node
*
pair
=
new
(
C
)
BinaryNode
(
n
->
in
(
3
),
n
->
in
(
4
));
n
->
set_req
(
3
,
pair
);
n
->
del_req
(
4
);
break
;
}
default:
break
;
}
...
...
src/share/vm/opto/memnode.cpp
浏览文件 @
0ba7505d
...
...
@@ -2796,6 +2796,26 @@ const Type *StrIntrinsicNode::Value( PhaseTransform *phase ) const {
return
bottom_type
();
}
//=============================================================================
//------------------------------match_edge-------------------------------------
// Do not match memory edge
uint
EncodeISOArrayNode
::
match_edge
(
uint
idx
)
const
{
return
idx
==
2
||
idx
==
3
;
// EncodeISOArray src (Binary dst len)
}
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node. Strip out
// control copies
Node
*
EncodeISOArrayNode
::
Ideal
(
PhaseGVN
*
phase
,
bool
can_reshape
)
{
return
remove_dead_region
(
phase
,
can_reshape
)
?
this
:
NULL
;
}
//------------------------------Value------------------------------------------
const
Type
*
EncodeISOArrayNode
::
Value
(
PhaseTransform
*
phase
)
const
{
if
(
in
(
0
)
&&
phase
->
type
(
in
(
0
))
==
Type
::
TOP
)
return
Type
::
TOP
;
return
bottom_type
();
}
//=============================================================================
MemBarNode
::
MemBarNode
(
Compile
*
C
,
int
alias_idx
,
Node
*
precedent
)
:
MultiNode
(
TypeFunc
::
Parms
+
(
precedent
==
NULL
?
0
:
1
)),
...
...
src/share/vm/opto/memnode.hpp
浏览文件 @
0ba7505d
...
...
@@ -888,6 +888,22 @@ public:
virtual
const
Type
*
bottom_type
()
const
{
return
TypeInt
::
BOOL
;
}
};
//------------------------------EncodeISOArray--------------------------------
// encode char[] to byte[] in ISO_8859_1
class
EncodeISOArrayNode
:
public
Node
{
public:
EncodeISOArrayNode
(
Node
*
control
,
Node
*
arymem
,
Node
*
s1
,
Node
*
s2
,
Node
*
c
)
:
Node
(
control
,
arymem
,
s1
,
s2
,
c
)
{};
virtual
int
Opcode
()
const
;
virtual
bool
depends_only_on_test
()
const
{
return
false
;
}
virtual
const
Type
*
bottom_type
()
const
{
return
TypeInt
::
INT
;
}
virtual
const
TypePtr
*
adr_type
()
const
{
return
TypePtr
::
BOTTOM
;
}
virtual
uint
match_edge
(
uint
idx
)
const
;
virtual
uint
ideal_reg
()
const
{
return
Op_RegI
;
}
virtual
Node
*
Ideal
(
PhaseGVN
*
phase
,
bool
can_reshape
);
virtual
const
Type
*
Value
(
PhaseTransform
*
phase
)
const
;
};
//------------------------------MemBar-----------------------------------------
// There are different flavors of Memory Barriers to match the Java Memory
// Model. Monitor-enter and volatile-load act as Aquires: no following ref
...
...
src/share/vm/opto/node.cpp
浏览文件 @
0ba7505d
...
...
@@ -1476,35 +1476,35 @@ static bool is_disconnected(const Node* n) {
}
#ifdef ASSERT
static
void
dump_orig
(
Node
*
orig
)
{
static
void
dump_orig
(
Node
*
orig
,
outputStream
*
st
)
{
Compile
*
C
=
Compile
::
current
();
if
(
NotANode
(
orig
))
orig
=
NULL
;
if
(
orig
!=
NULL
&&
!
C
->
node_arena
()
->
contains
(
orig
))
orig
=
NULL
;
if
(
orig
==
NULL
)
return
;
tty
->
print
(
" !orig="
);
if
(
NotANode
(
orig
))
orig
=
NULL
;
if
(
orig
!=
NULL
&&
!
C
->
node_arena
()
->
contains
(
orig
))
orig
=
NULL
;
if
(
orig
==
NULL
)
return
;
st
->
print
(
" !orig="
);
Node
*
fast
=
orig
->
debug_orig
();
// tortoise & hare algorithm to detect loops
if
(
NotANode
(
fast
))
fast
=
NULL
;
if
(
NotANode
(
fast
))
fast
=
NULL
;
while
(
orig
!=
NULL
)
{
bool
discon
=
is_disconnected
(
orig
);
// if discon, print [123] else 123
if
(
discon
)
tty
->
print
(
"["
);
if
(
discon
)
st
->
print
(
"["
);
if
(
!
Compile
::
current
()
->
node_arena
()
->
contains
(
orig
))
tty
->
print
(
"o"
);
tty
->
print
(
"%d"
,
orig
->
_idx
);
if
(
discon
)
tty
->
print
(
"]"
);
st
->
print
(
"o"
);
st
->
print
(
"%d"
,
orig
->
_idx
);
if
(
discon
)
st
->
print
(
"]"
);
orig
=
orig
->
debug_orig
();
if
(
NotANode
(
orig
))
orig
=
NULL
;
if
(
orig
!=
NULL
&&
!
C
->
node_arena
()
->
contains
(
orig
))
orig
=
NULL
;
if
(
orig
!=
NULL
)
tty
->
print
(
","
);
if
(
NotANode
(
orig
))
orig
=
NULL
;
if
(
orig
!=
NULL
&&
!
C
->
node_arena
()
->
contains
(
orig
))
orig
=
NULL
;
if
(
orig
!=
NULL
)
st
->
print
(
","
);
if
(
fast
!=
NULL
)
{
// Step fast twice for each single step of orig:
fast
=
fast
->
debug_orig
();
if
(
NotANode
(
fast
))
fast
=
NULL
;
if
(
NotANode
(
fast
))
fast
=
NULL
;
if
(
fast
!=
NULL
&&
fast
!=
orig
)
{
fast
=
fast
->
debug_orig
();
if
(
NotANode
(
fast
))
fast
=
NULL
;
if
(
NotANode
(
fast
))
fast
=
NULL
;
}
if
(
fast
==
orig
)
{
tty
->
print
(
"..."
);
st
->
print
(
"..."
);
break
;
}
}
...
...
@@ -1531,35 +1531,34 @@ void Node::set_debug_orig(Node* orig) {
//------------------------------dump------------------------------------------
// Dump a Node
void
Node
::
dump
()
const
{
void
Node
::
dump
(
const
char
*
suffix
,
outputStream
*
st
)
const
{
Compile
*
C
=
Compile
::
current
();
bool
is_new
=
C
->
node_arena
()
->
contains
(
this
);
_in_dump_cnt
++
;
tty
->
print
(
"%c%d
\t
%s
\t
=== "
,
is_new
?
' '
:
'o'
,
_idx
,
Name
());
st
->
print
(
"%c%d
\t
%s
\t
=== "
,
is_new
?
' '
:
'o'
,
_idx
,
Name
());
// Dump the required and precedence inputs
dump_req
();
dump_prec
();
dump_req
(
st
);
dump_prec
(
st
);
// Dump the outputs
dump_out
();
dump_out
(
st
);
if
(
is_disconnected
(
this
))
{
#ifdef ASSERT
tty
->
print
(
" [%d]"
,
debug_idx
());
dump_orig
(
debug_orig
());
st
->
print
(
" [%d]"
,
debug_idx
());
dump_orig
(
debug_orig
()
,
st
);
#endif
tty
->
cr
();
st
->
cr
();
_in_dump_cnt
--
;
return
;
// don't process dead nodes
}
// Dump node-specific info
dump_spec
(
tty
);
dump_spec
(
st
);
#ifdef ASSERT
// Dump the non-reset _debug_idx
if
(
Verbose
&&
WizardMode
)
{
tty
->
print
(
" [%d]"
,
debug_idx
());
if
(
Verbose
&&
WizardMode
)
{
st
->
print
(
" [%d]"
,
debug_idx
());
}
#endif
...
...
@@ -1569,88 +1568,88 @@ void Node::dump() const {
const
TypeInstPtr
*
toop
=
t
->
isa_instptr
();
const
TypeKlassPtr
*
tkls
=
t
->
isa_klassptr
();
ciKlass
*
klass
=
toop
?
toop
->
klass
()
:
(
tkls
?
tkls
->
klass
()
:
NULL
);
if
(
klass
&&
klass
->
is_loaded
()
&&
klass
->
is_interface
()
)
{
tty
->
print
(
" Interface:"
);
}
else
if
(
toop
)
{
tty
->
print
(
" Oop:"
);
}
else
if
(
tkls
)
{
tty
->
print
(
" Klass:"
);
if
(
klass
&&
klass
->
is_loaded
()
&&
klass
->
is_interface
()
)
{
st
->
print
(
" Interface:"
);
}
else
if
(
toop
)
{
st
->
print
(
" Oop:"
);
}
else
if
(
tkls
)
{
st
->
print
(
" Klass:"
);
}
t
->
dump
(
);
}
else
if
(
t
==
Type
::
MEMORY
)
{
tty
->
print
(
" Memory:"
);
MemNode
::
dump_adr_type
(
this
,
adr_type
(),
tty
);
}
else
if
(
Verbose
||
WizardMode
)
{
tty
->
print
(
" Type:"
);
if
(
t
)
{
t
->
dump
(
);
t
->
dump
_on
(
st
);
}
else
if
(
t
==
Type
::
MEMORY
)
{
st
->
print
(
" Memory:"
);
MemNode
::
dump_adr_type
(
this
,
adr_type
(),
st
);
}
else
if
(
Verbose
||
WizardMode
)
{
st
->
print
(
" Type:"
);
if
(
t
)
{
t
->
dump
_on
(
st
);
}
else
{
tty
->
print
(
"no type"
);
st
->
print
(
"no type"
);
}
}
else
if
(
t
->
isa_vect
()
&&
this
->
is_MachSpillCopy
())
{
// Dump MachSpillcopy vector type.
t
->
dump
(
);
t
->
dump
_on
(
st
);
}
if
(
is_new
)
{
debug_only
(
dump_orig
(
debug_orig
()));
debug_only
(
dump_orig
(
debug_orig
()
,
st
));
Node_Notes
*
nn
=
C
->
node_notes_at
(
_idx
);
if
(
nn
!=
NULL
&&
!
nn
->
is_clear
())
{
if
(
nn
->
jvms
()
!=
NULL
)
{
tty
->
print
(
" !jvms:"
);
nn
->
jvms
()
->
dump_spec
(
tty
);
st
->
print
(
" !jvms:"
);
nn
->
jvms
()
->
dump_spec
(
st
);
}
}
}
tty
->
cr
(
);
if
(
suffix
)
st
->
print
(
suffix
);
_in_dump_cnt
--
;
}
//------------------------------dump_req--------------------------------------
void
Node
::
dump_req
()
const
{
void
Node
::
dump_req
(
outputStream
*
st
)
const
{
// Dump the required input edges
for
(
uint
i
=
0
;
i
<
req
();
i
++
)
{
// For all required inputs
Node
*
d
=
in
(
i
);
if
(
d
==
NULL
)
{
tty
->
print
(
"_ "
);
st
->
print
(
"_ "
);
}
else
if
(
NotANode
(
d
))
{
tty
->
print
(
"NotANode "
);
// uninitialized, sentinel, garbage, etc.
st
->
print
(
"NotANode "
);
// uninitialized, sentinel, garbage, etc.
}
else
{
tty
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
d
)
?
' '
:
'o'
,
d
->
_idx
);
st
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
d
)
?
' '
:
'o'
,
d
->
_idx
);
}
}
}
//------------------------------dump_prec-------------------------------------
void
Node
::
dump_prec
()
const
{
void
Node
::
dump_prec
(
outputStream
*
st
)
const
{
// Dump the precedence edges
int
any_prec
=
0
;
for
(
uint
i
=
req
();
i
<
len
();
i
++
)
{
// For all precedence inputs
Node
*
p
=
in
(
i
);
if
(
p
!=
NULL
)
{
if
(
!
any_prec
++
)
tty
->
print
(
" |"
);
if
(
NotANode
(
p
))
{
tty
->
print
(
"NotANode "
);
continue
;
}
tty
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
in
(
i
))
?
' '
:
'o'
,
in
(
i
)
->
_idx
);
if
(
!
any_prec
++
)
st
->
print
(
" |"
);
if
(
NotANode
(
p
))
{
st
->
print
(
"NotANode "
);
continue
;
}
st
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
in
(
i
))
?
' '
:
'o'
,
in
(
i
)
->
_idx
);
}
}
}
//------------------------------dump_out--------------------------------------
void
Node
::
dump_out
()
const
{
void
Node
::
dump_out
(
outputStream
*
st
)
const
{
// Delimit the output edges
tty
->
print
(
" [["
);
st
->
print
(
" [["
);
// Dump the output edges
for
(
uint
i
=
0
;
i
<
_outcnt
;
i
++
)
{
// For all outputs
Node
*
u
=
_out
[
i
];
if
(
u
==
NULL
)
{
tty
->
print
(
"_ "
);
st
->
print
(
"_ "
);
}
else
if
(
NotANode
(
u
))
{
tty
->
print
(
"NotANode "
);
st
->
print
(
"NotANode "
);
}
else
{
tty
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
u
)
?
' '
:
'o'
,
u
->
_idx
);
st
->
print
(
"%c%d "
,
Compile
::
current
()
->
node_arena
()
->
contains
(
u
)
?
' '
:
'o'
,
u
->
_idx
);
}
}
tty
->
print
(
"]] "
);
st
->
print
(
"]] "
);
}
//------------------------------dump_nodes-------------------------------------
...
...
src/share/vm/opto/node.hpp
浏览文件 @
0ba7505d
...
...
@@ -994,12 +994,13 @@ public:
#ifndef PRODUCT
Node
*
find
(
int
idx
)
const
;
// Search the graph for the given idx.
Node
*
find_ctrl
(
int
idx
)
const
;
// Search control ancestors for the given idx.
void
dump
()
const
;
// Print this node,
void
dump
()
const
{
dump
(
"
\n
"
);
}
// Print this node.
void
dump
(
const
char
*
suffix
,
outputStream
*
st
=
tty
)
const
;
// Print this node.
void
dump
(
int
depth
)
const
;
// Print this node, recursively to depth d
void
dump_ctrl
(
int
depth
)
const
;
// Print control nodes, to depth d
virtual
void
dump_req
()
const
;
// Print required-edge info
virtual
void
dump_prec
()
const
;
// Print precedence-edge info
virtual
void
dump_out
()
const
;
// Print the output edge info
virtual
void
dump_req
(
outputStream
*
st
=
tty
)
const
;
// Print required-edge info
virtual
void
dump_prec
(
outputStream
*
st
=
tty
)
const
;
// Print precedence-edge info
virtual
void
dump_out
(
outputStream
*
st
=
tty
)
const
;
// Print the output edge info
virtual
void
dump_spec
(
outputStream
*
st
)
const
{};
// Print per-node info
void
verify_edges
(
Unique_Node_List
&
visited
);
// Verify bi-directional edges
void
verify
()
const
;
// Check Def-Use info for my subgraph
...
...
src/share/vm/opto/optoreg.hpp
浏览文件 @
0ba7505d
...
...
@@ -77,7 +77,7 @@ class OptoReg VALUE_OBJ_CLASS_SPEC {
// (We would like to have an operator+ for RegName, but it is not
// a class, so this would be illegal in C++.)
static
void
dump
(
int
);
static
void
dump
(
int
,
outputStream
*
st
=
tty
);
// Get the stack slot number of an OptoReg::Name
static
unsigned
int
reg2stack
(
OptoReg
::
Name
r
)
{
...
...
src/share/vm/opto/regalloc.cpp
浏览文件 @
0ba7505d
...
...
@@ -40,6 +40,7 @@ PhaseRegAlloc::PhaseRegAlloc( uint unique, PhaseCFG &cfg,
Phase
(
Register_Allocation
),
_cfg
(
cfg
),
_matcher
(
matcher
),
_node_oops
(
Thread
::
current
()
->
resource_area
()),
_node_regs
(
0
),
_node_regs_max_index
(
0
),
_framesize
(
0xdeadbeef
)
{
int
i
;
...
...
src/share/vm/opto/regmask.cpp
浏览文件 @
0ba7505d
...
...
@@ -108,13 +108,13 @@ int find_hihghest_bit( uint32 mask ) {
//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void
OptoReg
::
dump
(
int
r
)
{
switch
(
r
)
{
case
Special
:
tty
->
print
(
"r---"
);
break
;
case
Bad
:
tty
->
print
(
"rBAD"
);
break
;
void
OptoReg
::
dump
(
int
r
,
outputStream
*
st
)
{
switch
(
r
)
{
case
Special
:
st
->
print
(
"r---"
);
break
;
case
Bad
:
st
->
print
(
"rBAD"
);
break
;
default:
if
(
r
<
_last_Mach_Reg
)
tty
->
print
(
Matcher
::
regName
[
r
]);
else
tty
->
print
(
"rS%d"
,
r
);
if
(
r
<
_last_Mach_Reg
)
st
->
print
(
Matcher
::
regName
[
r
]);
else
st
->
print
(
"rS%d"
,
r
);
break
;
}
}
...
...
@@ -404,53 +404,53 @@ uint RegMask::Size() const {
#ifndef PRODUCT
//------------------------------print------------------------------------------
void
RegMask
::
dump
(
)
const
{
tty
->
print
(
"["
);
void
RegMask
::
dump
(
outputStream
*
st
)
const
{
st
->
print
(
"["
);
RegMask
rm
=
*
this
;
// Structure copy into local temp
OptoReg
::
Name
start
=
rm
.
find_first_elem
();
// Get a register
if
(
OptoReg
::
is_valid
(
start
)
)
{
// Check for empty mask
if
(
OptoReg
::
is_valid
(
start
)
)
{
// Check for empty mask
rm
.
Remove
(
start
);
// Yank from mask
OptoReg
::
dump
(
start
);
// Print register
OptoReg
::
dump
(
start
,
st
);
// Print register
OptoReg
::
Name
last
=
start
;
// Now I have printed an initial register.
// Print adjacent registers as "rX-rZ" instead of "rX,rY,rZ".
// Begin looping over the remaining registers.
while
(
1
)
{
//
while
(
1
)
{
//
OptoReg
::
Name
reg
=
rm
.
find_first_elem
();
// Get a register
if
(
!
OptoReg
::
is_valid
(
reg
)
)
if
(
!
OptoReg
::
is_valid
(
reg
)
)
break
;
// Empty mask, end loop
rm
.
Remove
(
reg
);
// Yank from mask
if
(
last
+
1
==
reg
)
{
// See if they are adjacent
if
(
last
+
1
==
reg
)
{
// See if they are adjacent
// Adjacent registers just collect into long runs, no printing.
last
=
reg
;
}
else
{
// Ending some kind of run
if
(
start
==
last
)
{
// 1-register run; no special printing
}
else
if
(
start
+
1
==
last
)
{
tty
->
print
(
","
);
// 2-register run; print as "rX,rY"
OptoReg
::
dump
(
last
);
if
(
start
==
last
)
{
// 1-register run; no special printing
}
else
if
(
start
+
1
==
last
)
{
st
->
print
(
","
);
// 2-register run; print as "rX,rY"
OptoReg
::
dump
(
last
,
st
);
}
else
{
// Multi-register run; print as "rX-rZ"
tty
->
print
(
"-"
);
OptoReg
::
dump
(
last
);
st
->
print
(
"-"
);
OptoReg
::
dump
(
last
,
st
);
}
tty
->
print
(
","
);
// Seperate start of new run
st
->
print
(
","
);
// Seperate start of new run
start
=
last
=
reg
;
// Start a new register run
OptoReg
::
dump
(
start
);
// Print register
OptoReg
::
dump
(
start
,
st
);
// Print register
}
// End of if ending a register run or not
}
// End of while regmask not empty
if
(
start
==
last
)
{
// 1-register run; no special printing
}
else
if
(
start
+
1
==
last
)
{
tty
->
print
(
","
);
// 2-register run; print as "rX,rY"
OptoReg
::
dump
(
last
);
if
(
start
==
last
)
{
// 1-register run; no special printing
}
else
if
(
start
+
1
==
last
)
{
st
->
print
(
","
);
// 2-register run; print as "rX,rY"
OptoReg
::
dump
(
last
,
st
);
}
else
{
// Multi-register run; print as "rX-rZ"
tty
->
print
(
"-"
);
OptoReg
::
dump
(
last
);
st
->
print
(
"-"
);
OptoReg
::
dump
(
last
,
st
);
}
if
(
rm
.
is_AllStack
()
)
tty
->
print
(
"..."
);
if
(
rm
.
is_AllStack
())
st
->
print
(
"..."
);
}
tty
->
print
(
"]"
);
st
->
print
(
"]"
);
}
#endif
src/share/vm/opto/regmask.hpp
浏览文件 @
0ba7505d
...
...
@@ -310,7 +310,7 @@ public:
#ifndef PRODUCT
void
print
()
const
{
dump
();
}
void
dump
(
)
const
;
// Print a mask
void
dump
(
outputStream
*
st
=
tty
)
const
;
// Print a mask
#endif
static
const
RegMask
Empty
;
// Common empty mask
...
...
test/compiler/6896617/Test6896617.java
0 → 100644
浏览文件 @
0ba7505d
/*
* Copyright (c) 2013, 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 6896617
* @summary Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() with SSE instructions on x86
* @run main/othervm/timeout=1200 -Xbatch -Xmx256m Test6896617
*
*/
import
java.util.*
;
import
java.nio.*
;
import
java.nio.charset.*
;
public
class
Test6896617
{
final
static
int
SIZE
=
256
;
public
static
void
main
(
String
[]
args
)
{
String
csn
=
"ISO-8859-1"
;
Charset
cs
=
Charset
.
forName
(
csn
);
CharsetEncoder
enc
=
cs
.
newEncoder
();
enc
.
onMalformedInput
(
CodingErrorAction
.
REPLACE
)
.
onUnmappableCharacter
(
CodingErrorAction
.
REPLACE
);
CharsetDecoder
dec
=
cs
.
newDecoder
();
dec
.
onMalformedInput
(
CodingErrorAction
.
REPLACE
)
.
onUnmappableCharacter
(
CodingErrorAction
.
REPLACE
);
byte
repl
=
(
byte
)
'?'
;
enc
.
replaceWith
(
new
byte
[]
{
repl
});
// Use internal API for tests.
sun
.
nio
.
cs
.
ArrayEncoder
arrenc
=
(
sun
.
nio
.
cs
.
ArrayEncoder
)
enc
;
sun
.
nio
.
cs
.
ArrayDecoder
arrdec
=
(
sun
.
nio
.
cs
.
ArrayDecoder
)
dec
;
// Populate char[] with chars which can be encoded by ISO_8859_1 (<= 0xFF)
Random
rnd
=
new
Random
(
0
);
int
maxchar
=
0xFF
;
char
[]
a
=
new
char
[
SIZE
];
byte
[]
b
=
new
byte
[
SIZE
];
char
[]
at
=
new
char
[
SIZE
];
byte
[]
bt
=
new
byte
[
SIZE
];
for
(
int
i
=
0
;
i
<
SIZE
;
i
++)
{
char
c
=
(
char
)
rnd
.
nextInt
(
maxchar
);
if
(!
enc
.
canEncode
(
c
))
{
System
.
out
.
printf
(
"Something wrong: can't encode c=%03x\n"
,
(
int
)
c
);
System
.
exit
(
97
);
}
a
[
i
]
=
c
;
b
[
i
]
=
(
byte
)
c
;
at
[
i
]
=
(
char
)-
1
;
bt
[
i
]
=
(
byte
)-
1
;
}
if
(
arrenc
.
encode
(
a
,
0
,
SIZE
,
bt
)
!=
SIZE
||
!
Arrays
.
equals
(
b
,
bt
))
{
System
.
out
.
println
(
"Something wrong: ArrayEncoder.encode failed"
);
System
.
exit
(
97
);
}
if
(
arrdec
.
decode
(
b
,
0
,
SIZE
,
at
)
!=
SIZE
||
!
Arrays
.
equals
(
a
,
at
))
{
System
.
out
.
println
(
"Something wrong: ArrayDecoder.decode failed"
);
System
.
exit
(
97
);
}
for
(
int
i
=
0
;
i
<
SIZE
;
i
++)
{
at
[
i
]
=
(
char
)-
1
;
bt
[
i
]
=
(
byte
)-
1
;
}
ByteBuffer
bb
=
ByteBuffer
.
wrap
(
b
);
CharBuffer
ba
=
CharBuffer
.
wrap
(
a
);
ByteBuffer
bbt
=
ByteBuffer
.
wrap
(
bt
);
CharBuffer
bat
=
CharBuffer
.
wrap
(
at
);
if
(!
enc
.
encode
(
ba
,
bbt
,
true
).
isUnderflow
()
||
!
Arrays
.
equals
(
b
,
bt
))
{
System
.
out
.
println
(
"Something wrong: Encoder.encode failed"
);
System
.
exit
(
97
);
}
if
(!
dec
.
decode
(
bb
,
bat
,
true
).
isUnderflow
()
||
!
Arrays
.
equals
(
a
,
at
))
{
System
.
out
.
println
(
"Something wrong: Decoder.decode failed"
);
System
.
exit
(
97
);
}
for
(
int
i
=
0
;
i
<
SIZE
;
i
++)
{
at
[
i
]
=
(
char
)-
1
;
bt
[
i
]
=
(
byte
)-
1
;
}
// Warm up
boolean
failed
=
false
;
int
result
=
0
;
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
result
+=
arrenc
.
encode
(
a
,
0
,
SIZE
,
bt
);
result
-=
arrdec
.
decode
(
b
,
0
,
SIZE
,
at
);
}
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
result
+=
arrenc
.
encode
(
a
,
0
,
SIZE
,
bt
);
result
-=
arrdec
.
decode
(
b
,
0
,
SIZE
,
at
);
}
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
result
+=
arrenc
.
encode
(
a
,
0
,
SIZE
,
bt
);
result
-=
arrdec
.
decode
(
b
,
0
,
SIZE
,
at
);
}
if
(
result
!=
0
||
!
Arrays
.
equals
(
b
,
bt
)
||
!
Arrays
.
equals
(
a
,
at
))
{
failed
=
true
;
System
.
out
.
println
(
"Failed: ArrayEncoder.encode char["
+
SIZE
+
"] and ArrayDecoder.decode byte["
+
SIZE
+
"]"
);
}
for
(
int
i
=
0
;
i
<
SIZE
;
i
++)
{
at
[
i
]
=
(
char
)-
1
;
bt
[
i
]
=
(
byte
)-
1
;
}
boolean
is_underflow
=
true
;
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
ba
.
clear
();
bb
.
clear
();
bat
.
clear
();
bbt
.
clear
();
boolean
enc_res
=
enc
.
encode
(
ba
,
bbt
,
true
).
isUnderflow
();
boolean
dec_res
=
dec
.
decode
(
bb
,
bat
,
true
).
isUnderflow
();
is_underflow
=
is_underflow
&&
enc_res
&&
dec_res
;
}
for
(
int
i
=
0
;
i
<
SIZE
;
i
++)
{
at
[
i
]
=
(
char
)-
1
;
bt
[
i
]
=
(
byte
)-
1
;
}
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
ba
.
clear
();
bb
.
clear
();
bat
.
clear
();
bbt
.
clear
();
boolean
enc_res
=
enc
.
encode
(
ba
,
bbt
,
true
).
isUnderflow
();
boolean
dec_res
=
dec
.
decode
(
bb
,
bat
,
true
).
isUnderflow
();
is_underflow
=
is_underflow
&&
enc_res
&&
dec_res
;
}
for
(
int
i
=
0
;
i
<
SIZE
;
i
++)
{
at
[
i
]
=
(
char
)-
1
;
bt
[
i
]
=
(
byte
)-
1
;
}
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
ba
.
clear
();
bb
.
clear
();
bat
.
clear
();
bbt
.
clear
();
boolean
enc_res
=
enc
.
encode
(
ba
,
bbt
,
true
).
isUnderflow
();
boolean
dec_res
=
dec
.
decode
(
bb
,
bat
,
true
).
isUnderflow
();
is_underflow
=
is_underflow
&&
enc_res
&&
dec_res
;
}
if
(!
is_underflow
||
!
Arrays
.
equals
(
b
,
bt
)
||
!
Arrays
.
equals
(
a
,
at
))
{
failed
=
true
;
System
.
out
.
println
(
"Failed: Encoder.encode char["
+
SIZE
+
"] and Decoder.decode byte["
+
SIZE
+
"]"
);
}
// Test encoder with different source and destination sizes
System
.
out
.
println
(
"Testing different source and destination sizes"
);
for
(
int
i
=
1
;
i
<=
SIZE
;
i
++)
{
for
(
int
j
=
1
;
j
<=
SIZE
;
j
++)
{
bt
=
new
byte
[
j
];
// very source's SIZE
result
=
arrenc
.
encode
(
a
,
0
,
i
,
bt
);
int
l
=
Math
.
min
(
i
,
j
);
if
(
result
!=
l
)
{
failed
=
true
;
System
.
out
.
println
(
"Failed: encode char["
+
i
+
"] to byte["
+
j
+
"]: result = "
+
result
+
", expected "
+
l
);
}
for
(
int
k
=
0
;
k
<
l
;
k
++)
{
if
(
bt
[
k
]
!=
b
[
k
])
{
failed
=
true
;
System
.
out
.
println
(
"Failed: encoded byte["
+
k
+
"] ("
+
bt
[
k
]
+
") != "
+
b
[
k
]);
}
}
// very source's offset
int
sz
=
SIZE
-
i
+
1
;
result
=
arrenc
.
encode
(
a
,
i
-
1
,
sz
,
bt
);
l
=
Math
.
min
(
sz
,
j
);
if
(
result
!=
l
)
{
failed
=
true
;
System
.
out
.
println
(
"Failed: encode char["
+
sz
+
"] to byte["
+
j
+
"]: result = "
+
result
+
", expected "
+
l
);
}
for
(
int
k
=
0
;
k
<
l
;
k
++)
{
if
(
bt
[
k
]
!=
b
[
i
+
k
-
1
])
{
failed
=
true
;
System
.
out
.
println
(
"Failed: encoded byte["
+
k
+
"] ("
+
bt
[
k
]
+
") != "
+
b
[
i
+
k
-
1
]);
}
}
}
}
// Test encoder with char > 0xFF
System
.
out
.
println
(
"Testing big char"
);
byte
orig
=
(
byte
)
'A'
;
bt
=
new
byte
[
SIZE
];
for
(
int
i
=
1
;
i
<=
SIZE
;
i
++)
{
for
(
int
j
=
0
;
j
<
i
;
j
++)
{
a
[
j
]
+=
0x100
;
// make sure to replace a different byte
bt
[
j
]
=
orig
;
result
=
arrenc
.
encode
(
a
,
0
,
i
,
bt
);
if
(
result
!=
i
)
{
failed
=
true
;
System
.
out
.
println
(
"Failed: encode char["
+
i
+
"] to byte["
+
i
+
"]: result = "
+
result
+
", expected "
+
i
);
}
if
(
bt
[
j
]
!=
repl
)
{
failed
=
true
;
System
.
out
.
println
(
"Failed: encoded replace byte["
+
j
+
"] ("
+
bt
[
j
]
+
") != "
+
repl
);
}
bt
[
j
]
=
b
[
j
];
// Restore to compare whole array
for
(
int
k
=
0
;
k
<
i
;
k
++)
{
if
(
bt
[
k
]
!=
b
[
k
])
{
failed
=
true
;
System
.
out
.
println
(
"Failed: encoded byte["
+
k
+
"] ("
+
bt
[
k
]
+
") != "
+
b
[
k
]);
}
}
a
[
j
]
-=
0x100
;
// Restore
}
}
// Test sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() performance.
int
itrs
=
Integer
.
getInteger
(
"iterations"
,
1000000
);
int
size
=
Integer
.
getInteger
(
"size"
,
256
);
a
=
new
char
[
size
];
b
=
new
byte
[
size
];
bt
=
new
byte
[
size
];
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
char
c
=
(
char
)
rnd
.
nextInt
(
maxchar
);
if
(!
enc
.
canEncode
(
c
))
{
System
.
out
.
printf
(
"Something wrong: can't encode c=%03x\n"
,
(
int
)
c
);
System
.
exit
(
97
);
}
a
[
i
]
=
c
;
b
[
i
]
=
(
byte
)-
1
;
bt
[
i
]
=
(
byte
)
c
;
}
ba
=
CharBuffer
.
wrap
(
a
);
bb
=
ByteBuffer
.
wrap
(
b
);
boolean
enc_res
=
enc
.
encode
(
ba
,
bb
,
true
).
isUnderflow
();
if
(!
enc_res
||
!
Arrays
.
equals
(
b
,
bt
))
{
failed
=
true
;
System
.
out
.
println
(
"Failed 1: Encoder.encode char["
+
size
+
"]"
);
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
b
[
i
]
=
(
byte
)-
1
;
}
// Make sure to recompile method if needed before performance run.
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
ba
.
clear
();
bb
.
clear
();
enc_res
=
enc_res
&&
enc
.
encode
(
ba
,
bb
,
true
).
isUnderflow
();
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
b
[
i
]
=
(
byte
)-
1
;
}
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
ba
.
clear
();
bb
.
clear
();
enc_res
=
enc_res
&&
enc
.
encode
(
ba
,
bb
,
true
).
isUnderflow
();
}
if
(!
enc_res
||
!
Arrays
.
equals
(
b
,
bt
))
{
failed
=
true
;
System
.
out
.
println
(
"Failed 2: Encoder.encode char["
+
size
+
"]"
);
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
b
[
i
]
=
(
byte
)-
1
;
}
System
.
out
.
println
(
"Testing ISO_8859_1$Encode.encodeArrayLoop() performance"
);
long
start
=
System
.
currentTimeMillis
();
for
(
int
i
=
0
;
i
<
itrs
;
i
++)
{
ba
.
clear
();
bb
.
clear
();
enc_res
=
enc_res
&&
enc
.
encode
(
ba
,
bb
,
true
).
isUnderflow
();
}
long
end
=
System
.
currentTimeMillis
();
if
(!
enc_res
||
!
Arrays
.
equals
(
b
,
bt
))
{
failed
=
true
;
System
.
out
.
println
(
"Failed 3: Encoder.encode char["
+
size
+
"]"
);
}
else
{
System
.
out
.
println
(
"size: "
+
size
+
" time: "
+
(
end
-
start
));
}
// Test sun.nio.cs.ISO_8859_1$Encode.encode() performance.
// Make sure to recompile method if needed before performance run.
result
=
0
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
b
[
i
]
=
(
byte
)-
1
;
}
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
result
+=
arrenc
.
encode
(
a
,
0
,
size
,
b
);
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
b
[
i
]
=
(
byte
)-
1
;
}
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
result
+=
arrenc
.
encode
(
a
,
0
,
size
,
b
);
}
if
(
result
!=
size
*
20000
||
!
Arrays
.
equals
(
b
,
bt
))
{
failed
=
true
;
System
.
out
.
println
(
"Failed 1: ArrayEncoder.encode char["
+
SIZE
+
"]"
);
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
b
[
i
]
=
(
byte
)-
1
;
}
System
.
out
.
println
(
"Testing ISO_8859_1$Encode.encode() performance"
);
result
=
0
;
start
=
System
.
currentTimeMillis
();
for
(
int
i
=
0
;
i
<
itrs
;
i
++)
{
result
+=
arrenc
.
encode
(
a
,
0
,
size
,
b
);
}
end
=
System
.
currentTimeMillis
();
if
(!
Arrays
.
equals
(
b
,
bt
))
{
failed
=
true
;
System
.
out
.
println
(
"Failed 2: ArrayEncoder.encode char["
+
size
+
"]"
);
}
else
{
System
.
out
.
println
(
"size: "
+
size
+
" time: "
+
(
end
-
start
));
}
if
(
failed
)
{
System
.
out
.
println
(
"FAILED"
);
System
.
exit
(
97
);
}
System
.
out
.
println
(
"PASSED"
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录