Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
e0f98d44
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看板
提交
e0f98d44
编写于
1月 23, 2015
作者:
A
amurillo
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
df834987
4619dfcb
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
276 addition
and
35 deletion
+276
-35
agent/src/os/bsd/MacosxDebuggerLocal.m
agent/src/os/bsd/MacosxDebuggerLocal.m
+2
-2
agent/src/os/bsd/Makefile
agent/src/os/bsd/Makefile
+3
-3
make/bsd/makefiles/saproc.make
make/bsd/makefiles/saproc.make
+18
-10
make/hotspot_version
make/hotspot_version
+1
-1
src/share/vm/opto/chaitin.cpp
src/share/vm/opto/chaitin.cpp
+3
-0
src/share/vm/opto/chaitin.hpp
src/share/vm/opto/chaitin.hpp
+26
-0
src/share/vm/opto/lcm.cpp
src/share/vm/opto/lcm.cpp
+8
-1
src/share/vm/opto/machnode.hpp
src/share/vm/opto/machnode.hpp
+23
-0
src/share/vm/opto/node.hpp
src/share/vm/opto/node.hpp
+3
-0
src/share/vm/opto/phase.cpp
src/share/vm/opto/phase.cpp
+3
-1
src/share/vm/opto/phase.hpp
src/share/vm/opto/phase.hpp
+1
-0
src/share/vm/opto/postaloc.cpp
src/share/vm/opto/postaloc.cpp
+88
-14
src/share/vm/opto/stringopts.cpp
src/share/vm/opto/stringopts.cpp
+8
-3
test/compiler/stringopts/TestOptimizeStringConcat.java
test/compiler/stringopts/TestOptimizeStringConcat.java
+89
-0
未找到文件。
agent/src/os/bsd/MacosxDebuggerLocal.m
浏览文件 @
e0f98d44
/*
*
Copyright
(
c
)
2002
,
201
3
,
Oracle
and
/
or
its
affiliates
.
All
rights
reserved
.
*
Copyright
(
c
)
2002
,
201
5
,
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
...
...
@@ -26,7 +26,7 @@
#import
<
Foundation
/
Foundation
.
h
>
#import
<
JavaNativeFoundation
/
JavaNativeFoundation
.
h
>
#include
<
JavaVM
/
jni
.
h
>
#include
<
jni
.
h
>
#import
<
mach
/
mach
.
h
>
#import
<
mach
/
mach
_
types
.
h
>
...
...
agent/src/os/bsd/Makefile
浏览文件 @
e0f98d44
#
# Copyright (c) 2002, 201
3
, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 201
5
, 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
...
...
@@ -50,9 +50,9 @@ SOURCES = symtab.c \
ps_core.c
OBJS
=
$(SOURCES:.c=.o)
OBJSPLUS
=
MacosxDebuggerLocal.o sadis.o
$(OBJS)
EXTINCLUDE
=
-I
/System/Library/Frameworks/JavaVM.framework/Headers
-I
.
EXTINCLUDE
=
-I
.
EXTCFLAGS
=
-m64
-D__APPLE__
-framework
JavaNativeFoundation
FOUNDATIONFLAGS
=
-framework
Foundation
-
F
/System/Library/Frameworks/JavaVM.framework/Frameworks
-
framework
JavaNativeFoundation
-framework
Security
-framework
CoreFoundation
FOUNDATIONFLAGS
=
-framework
Foundation
-framework
JavaNativeFoundation
-framework
Security
-framework
CoreFoundation
LIBSA
=
$(ARCH)
/libsaproc.dylib
endif
# Darwin
...
...
make/bsd/makefiles/saproc.make
浏览文件 @
e0f98d44
#
# Copyright (c) 2005, 201
3
, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2005, 201
5
, 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
...
...
@@ -64,9 +64,22 @@ ifeq ($(OS_VENDOR), FreeBSD)
else
ifeq
($(OS_VENDOR), Darwin)
SASRCFILES
=
$(DARWIN_NON_STUB_SASRCFILES)
SALIBS
=
-g
-framework
Foundation
-F
/System/Library/Frameworks/JavaVM.framework/Frameworks
-framework
JavaNativeFoundation
-framework
Security
-framework
CoreFoundation
SALIBS
=
-g
\
-framework
Foundation
\
-framework
JavaNativeFoundation
\
-framework
Security
\
-framework
CoreFoundation
#objc compiler blows up on -march=i586, perhaps it should not be included in the macosx intel 32-bit C++ compiles?
SAARCH
=
$(
subst
-march
=
i586,,
$(ARCHFLAG)
)
# This is needed to locate JavaNativeFoundation.framework
# JDK 8 doesn't have SYSROOT_CFLAGS, so we'll cobble it together here
SA_SYSROOT_FLAGS
=
ifneq
($(SDKPATH),)
SA_SYSROOT_FLAGS
+=
-isysroot
"
$(SDKPATH)
"
-iframework
"
$(SDKPATH)
/System/Library/Frameworks"
endif
# always needed, even if SDKPATH is empty
SA_SYSROOT_FLAGS
+=
-F
"
$(SDKPATH)
/System/Library/Frameworks/JavaVM.framework/Frameworks"
else
SASRCFILES
=
$(SASRCDIR)
/StubDebuggerLocal.c
SALIBS
=
...
...
@@ -100,14 +113,8 @@ SA_LFLAGS = $(MAPFLAG:FILENAME=$(SAMAPFILE))
endif
SA_LFLAGS
+=
$(LDFLAGS_HASH_STYLE)
ifeq
($(OS_VENDOR), Darwin)
BOOT_JAVA_INCLUDES
=
-I
$(BOOT_JAVA_HOME)
/include
\
-I
$(BOOT_JAVA_HOME)
/include/
$(
shell
uname
-s
|
tr
"[:upper:]"
"[:lower:]"
)
\
-I
/System/Library/Frameworks/JavaVM.framework/Headers
else
BOOT_JAVA_INCLUDES
=
-I
$(BOOT_JAVA_HOME)
/include
\
-I
$(BOOT_JAVA_HOME)
/include/
$(
shell
uname
-s
|
tr
"[:upper:]"
"[:lower:]"
)
endif
BOOT_JAVA_INCLUDES
=
-I
$(BOOT_JAVA_HOME)
/include
\
-I
$(BOOT_JAVA_HOME)
/include/
$(
shell
uname
-s
|
tr
"[:upper:]"
"[:lower:]"
)
$(LIBSAPROC)
:
$(SASRCFILES) $(SAMAPFILE)
$(QUIETLY)
if
[
"
$(BOOT_JAVA_HOME)
"
=
""
]
;
then
\
...
...
@@ -116,6 +123,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
fi
@
echo
Making SA debugger back-end...
$(QUIETLY)
$(CC)
-D
$(BUILDARCH)
-D_GNU_SOURCE
\
$(SA_SYSROOT_FLAGS)
\
$(SYMFLAG)
$(SAARCH)
$(SHARED_FLAG)
$(PICFLAG)
\
-I
$(SASRCDIR)
\
-I
$(GENERATED)
\
...
...
make/hotspot_version
浏览文件 @
e0f98d44
...
...
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2015
HS_MAJOR_VER=25
HS_MINOR_VER=60
HS_BUILD_NUMBER=0
1
HS_BUILD_NUMBER=0
2
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
...
...
src/share/vm/opto/chaitin.cpp
浏览文件 @
e0f98d44
...
...
@@ -575,6 +575,9 @@ void PhaseChaitin::Register_Allocate() {
// Peephole remove copies
post_allocate_copy_removal
();
// Merge multidefs if multiple defs representing the same value are used in a single block.
merge_multidefs
();
#ifdef ASSERT
// Veify the graph after RA.
verify
(
&
live_arena
);
...
...
src/share/vm/opto/chaitin.hpp
浏览文件 @
e0f98d44
...
...
@@ -578,6 +578,32 @@ private:
// Extend the node to LRG mapping
void
add_reference
(
const
Node
*
node
,
const
Node
*
old_node
);
// Record the first use of a def in the block for a register.
class
RegDefUse
{
Node
*
_def
;
Node
*
_first_use
;
public:
RegDefUse
()
:
_def
(
NULL
),
_first_use
(
NULL
)
{
}
Node
*
def
()
const
{
return
_def
;
}
Node
*
first_use
()
const
{
return
_first_use
;
}
void
update
(
Node
*
def
,
Node
*
use
)
{
if
(
_def
!=
def
)
{
_def
=
def
;
_first_use
=
use
;
}
}
void
clear
()
{
_def
=
NULL
;
_first_use
=
NULL
;
}
};
typedef
GrowableArray
<
RegDefUse
>
RegToDefUseMap
;
int
possibly_merge_multidef
(
Node
*
n
,
uint
k
,
Block
*
block
,
RegToDefUseMap
&
reg2defuse
);
// Merge nodes that are a part of a multidef lrg and produce the same value within a block.
void
merge_multidefs
();
private:
static
int
_final_loads
,
_final_stores
,
_final_copies
,
_final_memoves
;
...
...
src/share/vm/opto/lcm.cpp
浏览文件 @
e0f98d44
...
...
@@ -437,8 +437,15 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo
for
(
DUIterator_Last
i2min
,
i2
=
old_tst
->
last_outs
(
i2min
);
i2
>=
i2min
;
--
i2
)
old_tst
->
last_out
(
i2
)
->
set_req
(
0
,
nul_chk
);
// Clean-up any dead code
for
(
uint
i3
=
0
;
i3
<
old_tst
->
req
();
i3
++
)
for
(
uint
i3
=
0
;
i3
<
old_tst
->
req
();
i3
++
)
{
Node
*
in
=
old_tst
->
in
(
i3
);
old_tst
->
set_req
(
i3
,
NULL
);
if
(
in
->
outcnt
()
==
0
)
{
// Remove dead input node
in
->
disconnect_inputs
(
NULL
,
C
);
block
->
find_remove
(
in
);
}
}
latency_from_uses
(
nul_chk
);
latency_from_uses
(
best
);
...
...
src/share/vm/opto/machnode.hpp
浏览文件 @
e0f98d44
...
...
@@ -558,6 +558,29 @@ public:
#endif
};
// MachMergeNode is similar to a PhiNode in a sense it merges multiple values,
// however it doesn't have a control input and is more like a MergeMem.
// It is inserted after the register allocation is done to ensure that nodes use single
// definition of a multidef lrg in a block.
class
MachMergeNode
:
public
MachIdealNode
{
public:
MachMergeNode
(
Node
*
n1
)
{
init_class_id
(
Class_MachMerge
);
add_req
(
NULL
);
add_req
(
n1
);
}
virtual
const
RegMask
&
out_RegMask
()
const
{
return
in
(
1
)
->
out_RegMask
();
}
virtual
const
RegMask
&
in_RegMask
(
uint
idx
)
const
{
return
in
(
1
)
->
in_RegMask
(
idx
);
}
virtual
const
class
Type
*
bottom_type
()
const
{
return
in
(
1
)
->
bottom_type
();
}
virtual
uint
ideal_reg
()
const
{
return
bottom_type
()
->
ideal_reg
();
}
virtual
uint
oper_input_base
()
const
{
return
1
;
}
virtual
void
emit
(
CodeBuffer
&
cbuf
,
PhaseRegAlloc
*
ra_
)
const
{
}
virtual
uint
size
(
PhaseRegAlloc
*
ra_
)
const
{
return
0
;
}
#ifndef PRODUCT
virtual
const
char
*
Name
()
const
{
return
"MachMerge"
;
}
#endif
};
//------------------------------MachBranchNode--------------------------------
// Abstract machine branch Node
class
MachBranchNode
:
public
MachIdealNode
{
...
...
src/share/vm/opto/node.hpp
浏览文件 @
e0f98d44
...
...
@@ -98,6 +98,7 @@ class MachReturnNode;
class
MachSafePointNode
;
class
MachSpillCopyNode
;
class
MachTempNode
;
class
MachMergeNode
;
class
Matcher
;
class
MemBarNode
;
class
MemBarStoreStoreNode
;
...
...
@@ -591,6 +592,7 @@ public:
DEFINE_CLASS_ID
(
MachTemp
,
Mach
,
3
)
DEFINE_CLASS_ID
(
MachConstantBase
,
Mach
,
4
)
DEFINE_CLASS_ID
(
MachConstant
,
Mach
,
5
)
DEFINE_CLASS_ID
(
MachMerge
,
Mach
,
6
)
DEFINE_CLASS_ID
(
Type
,
Node
,
2
)
DEFINE_CLASS_ID
(
Phi
,
Type
,
0
)
...
...
@@ -761,6 +763,7 @@ public:
DEFINE_CLASS_QUERY
(
MachSafePoint
)
DEFINE_CLASS_QUERY
(
MachSpillCopy
)
DEFINE_CLASS_QUERY
(
MachTemp
)
DEFINE_CLASS_QUERY
(
MachMerge
)
DEFINE_CLASS_QUERY
(
Mem
)
DEFINE_CLASS_QUERY
(
MemBar
)
DEFINE_CLASS_QUERY
(
MemBarStoreStore
)
...
...
src/share/vm/opto/phase.cpp
浏览文件 @
e0f98d44
...
...
@@ -74,6 +74,7 @@ elapsedTimer Phase::_t_buildIFGphysical;
elapsedTimer
Phase
::
_t_computeLive
;
elapsedTimer
Phase
::
_t_regAllocSplit
;
elapsedTimer
Phase
::
_t_postAllocCopyRemoval
;
elapsedTimer
Phase
::
_t_mergeMultidefs
;
elapsedTimer
Phase
::
_t_fixupSpills
;
// Subtimers for _t_output
...
...
@@ -136,11 +137,12 @@ void Phase::print_timers() {
tty
->
print_cr
(
" computeLive : %3.3f sec"
,
Phase
::
_t_computeLive
.
seconds
());
tty
->
print_cr
(
" regAllocSplit : %3.3f sec"
,
Phase
::
_t_regAllocSplit
.
seconds
());
tty
->
print_cr
(
" postAllocCopyRemoval: %3.3f sec"
,
Phase
::
_t_postAllocCopyRemoval
.
seconds
());
tty
->
print_cr
(
" mergeMultidefs: %3.3f sec"
,
Phase
::
_t_mergeMultidefs
.
seconds
());
tty
->
print_cr
(
" fixupSpills : %3.3f sec"
,
Phase
::
_t_fixupSpills
.
seconds
());
double
regalloc_subtotal
=
Phase
::
_t_ctorChaitin
.
seconds
()
+
Phase
::
_t_buildIFGphysical
.
seconds
()
+
Phase
::
_t_computeLive
.
seconds
()
+
Phase
::
_t_regAllocSplit
.
seconds
()
+
Phase
::
_t_fixupSpills
.
seconds
()
+
Phase
::
_t_postAllocCopyRemoval
.
seconds
();
Phase
::
_t_postAllocCopyRemoval
.
seconds
()
+
Phase
::
_t_mergeMultidefs
.
seconds
()
;
double
percent_of_regalloc
=
((
regalloc_subtotal
==
0.0
)
?
0.0
:
(
regalloc_subtotal
/
Phase
::
_t_registerAllocation
.
seconds
()
*
100.0
));
tty
->
print_cr
(
" subtotal : %3.3f sec, %3.2f %%"
,
regalloc_subtotal
,
percent_of_regalloc
);
}
...
...
src/share/vm/opto/phase.hpp
浏览文件 @
e0f98d44
...
...
@@ -109,6 +109,7 @@ protected:
static
elapsedTimer
_t_computeLive
;
static
elapsedTimer
_t_regAllocSplit
;
static
elapsedTimer
_t_postAllocCopyRemoval
;
static
elapsedTimer
_t_mergeMultidefs
;
static
elapsedTimer
_t_fixupSpills
;
// Subtimers for _t_output
...
...
src/share/vm/opto/postaloc.cpp
浏览文件 @
e0f98d44
...
...
@@ -263,20 +263,6 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v
// intermediate copies might be illegal, i.e., value is stored down to stack
// then reloaded BUT survives in a register the whole way.
Node
*
val
=
skip_copies
(
n
->
in
(
k
));
if
(
val
==
x
&&
nk_idx
!=
0
&&
regnd
[
nk_reg
]
!=
NULL
&&
regnd
[
nk_reg
]
!=
x
&&
_lrg_map
.
live_range_id
(
x
)
==
_lrg_map
.
live_range_id
(
regnd
[
nk_reg
]))
{
// When rematerialzing nodes and stretching lifetimes, the
// allocator will reuse the original def for multidef LRG instead
// of the current reaching def because it can't know it's safe to
// do so. After allocation completes if they are in the same LRG
// then it should use the current reaching def instead.
n
->
set_req
(
k
,
regnd
[
nk_reg
]);
blk_adjust
+=
yank_if_dead
(
val
,
current_block
,
&
value
,
&
regnd
);
val
=
skip_copies
(
n
->
in
(
k
));
}
if
(
val
==
x
)
return
blk_adjust
;
// No progress?
int
n_regs
=
RegMask
::
num_registers
(
val
->
ideal_reg
());
...
...
@@ -382,6 +368,94 @@ bool PhaseChaitin::eliminate_copy_of_constant(Node* val, Node* n,
return
false
;
}
// The algorithms works as follows:
// We traverse the block top to bottom. possibly_merge_multidef() is invoked for every input edge k
// of the instruction n. We check to see if the input is a multidef lrg. If it is, we record the fact that we've
// seen a definition (coming as an input) and add that fact to the reg2defuse array. The array maps registers to their
// current reaching definitions (we track only multidefs though). With each definition we also associate the first
// instruction we saw use it. If we encounter the situation when we observe an def (an input) that is a part of the
// same lrg but is different from the previous seen def we merge the two with a MachMerge node and substitute
// all the uses that we've seen so far to use the merge. After that we keep replacing the new defs in the same lrg
// as they get encountered with the merge node and keep adding these defs to the merge inputs.
void
PhaseChaitin
::
merge_multidefs
()
{
NOT_PRODUCT
(
Compile
::
TracePhase
t3
(
"mergeMultidefs"
,
&
_t_mergeMultidefs
,
TimeCompiler
);
)
ResourceMark
rm
;
// Keep track of the defs seen in registers and collect their uses in the block.
RegToDefUseMap
reg2defuse
(
_max_reg
,
_max_reg
,
RegDefUse
());
for
(
uint
i
=
0
;
i
<
_cfg
.
number_of_blocks
();
i
++
)
{
Block
*
block
=
_cfg
.
get_block
(
i
);
for
(
uint
j
=
1
;
j
<
block
->
number_of_nodes
();
j
++
)
{
Node
*
n
=
block
->
get_node
(
j
);
if
(
n
->
is_Phi
())
continue
;
for
(
uint
k
=
1
;
k
<
n
->
req
();
k
++
)
{
j
+=
possibly_merge_multidef
(
n
,
k
,
block
,
reg2defuse
);
}
// Null out the value produced by the instruction itself, since we're only interested in defs
// implicitly defined by the uses. We are actually interested in tracking only redefinitions
// of the multidef lrgs in the same register. For that matter it's enough to track changes in
// the base register only and ignore other effects of multi-register lrgs and fat projections.
// It is also ok to ignore defs coming from singledefs. After an implicit overwrite by one of
// those our register is guaranteed to be used by another lrg and we won't attempt to merge it.
uint
lrg
=
_lrg_map
.
live_range_id
(
n
);
if
(
lrg
>
0
&&
lrgs
(
lrg
).
is_multidef
())
{
OptoReg
::
Name
reg
=
lrgs
(
lrg
).
reg
();
reg2defuse
.
at
(
reg
).
clear
();
}
}
// Clear reg->def->use tracking for the next block
for
(
int
j
=
0
;
j
<
reg2defuse
.
length
();
j
++
)
{
reg2defuse
.
at
(
j
).
clear
();
}
}
}
int
PhaseChaitin
::
possibly_merge_multidef
(
Node
*
n
,
uint
k
,
Block
*
block
,
RegToDefUseMap
&
reg2defuse
)
{
int
blk_adjust
=
0
;
uint
lrg
=
_lrg_map
.
live_range_id
(
n
->
in
(
k
));
if
(
lrg
>
0
&&
lrgs
(
lrg
).
is_multidef
())
{
OptoReg
::
Name
reg
=
lrgs
(
lrg
).
reg
();
Node
*
def
=
reg2defuse
.
at
(
reg
).
def
();
if
(
def
!=
NULL
&&
lrg
==
_lrg_map
.
live_range_id
(
def
)
&&
def
!=
n
->
in
(
k
))
{
// Same lrg but different node, we have to merge.
MachMergeNode
*
merge
;
if
(
def
->
is_MachMerge
())
{
// is it already a merge?
merge
=
def
->
as_MachMerge
();
}
else
{
merge
=
new
(
C
)
MachMergeNode
(
def
);
// Insert the merge node into the block before the first use.
uint
use_index
=
block
->
find_node
(
reg2defuse
.
at
(
reg
).
first_use
());
block
->
insert_node
(
merge
,
use_index
++
);
// Let the allocator know about the new node, use the same lrg
_lrg_map
.
extend
(
merge
->
_idx
,
lrg
);
blk_adjust
++
;
// Fixup all the uses (there is at least one) that happened between the first
// use and before the current one.
for
(;
use_index
<
block
->
number_of_nodes
();
use_index
++
)
{
Node
*
use
=
block
->
get_node
(
use_index
);
if
(
use
==
n
)
{
break
;
}
use
->
replace_edge
(
def
,
merge
);
}
}
if
(
merge
->
find_edge
(
n
->
in
(
k
))
==
-
1
)
{
merge
->
add_req
(
n
->
in
(
k
));
}
n
->
set_req
(
k
,
merge
);
}
// update the uses
reg2defuse
.
at
(
reg
).
update
(
n
->
in
(
k
),
n
);
}
return
blk_adjust
;
}
//------------------------------post_allocate_copy_removal---------------------
// Post-Allocation peephole copy removal. We do this in 1 pass over the
...
...
src/share/vm/opto/stringopts.cpp
浏览文件 @
e0f98d44
...
...
@@ -1507,10 +1507,12 @@ void PhaseStringOpts::replace_string_concat(StringConcat* sc) {
}
case
StringConcat
::
StringMode
:
{
const
Type
*
type
=
kit
.
gvn
().
type
(
arg
);
Node
*
count
=
NULL
;
if
(
type
==
TypePtr
::
NULL_PTR
)
{
// replace the argument with the null checked version
arg
=
null_string
;
sc
->
set_argument
(
argi
,
arg
);
count
=
kit
.
load_String_length
(
kit
.
control
(),
arg
);
}
else
if
(
!
type
->
higher_equal
(
TypeInstPtr
::
NOTNULL
))
{
// s = s != null ? s : "null";
// length = length + (s.count - s.offset);
...
...
@@ -1533,10 +1535,13 @@ void PhaseStringOpts::replace_string_concat(StringConcat* sc) {
// replace the argument with the null checked version
arg
=
phi
;
sc
->
set_argument
(
argi
,
arg
);
count
=
kit
.
load_String_length
(
kit
.
control
(),
arg
);
}
else
{
// A corresponding nullcheck will be connected during IGVN MemNode::Ideal_common_DU_postCCP
// kit.control might be a different test, that can be hoisted above the actual nullcheck
// in case, that the control input is not null, Ideal_common_DU_postCCP will not look for a nullcheck.
count
=
kit
.
load_String_length
(
NULL
,
arg
);
}
Node
*
count
=
kit
.
load_String_length
(
kit
.
control
(),
arg
);
length
=
__
AddI
(
length
,
count
);
string_sizes
->
init_req
(
argi
,
NULL
);
break
;
...
...
test/compiler/stringopts/TestOptimizeStringConcat.java
0 → 100644
浏览文件 @
e0f98d44
/*
* Copyright 2015 SAP AG. 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 8068909
* @key regression
* @summary test that string optimizations produce code, that doesn't lead to a crash.
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestOptimizeStringConcat
* @author axel.siebenborn@sap.com
*/
public
class
TestOptimizeStringConcat
{
static
boolean
checkArgumentSyntax
(
String
value
,
String
allowedchars
,
String
notallowedchars
,
String
logmsg
)
{
String
rc
=
null
;
int
maxchar
=
99999
;
int
minchar
=
1
;
if
((
allowedchars
!=
null
&&
notallowedchars
!=
null
)
||
minchar
>
maxchar
)
{
rc
=
"internal error"
;
}
else
{
if
(
value
==
null
)
{
rc
=
"the value null is not allowed, it is missing"
;
}
else
if
(
value
!=
null
&&
minchar
>
0
&&
value
.
trim
().
equals
(
""
))
{
rc
=
"the value must not be empty"
;
}
else
if
(
value
!=
null
)
{
if
(
value
.
length
()
<
minchar
||
value
.
length
()
>
maxchar
)
{
if
(
rc
==
null
)
{
rc
=
"the value length must be between +minchar+ and +maxchar"
;
}
}
char
[]
_value
=
value
.
toCharArray
();
boolean
dotfound
=
false
;
int
i
=
1
;
if
(
_value
[
i
]
==
'.'
&&
!
dotfound
)
{
dotfound
=
true
;
}
else
if
(
allowedchars
!=
null
&&
allowedchars
.
indexOf
(
_value
[
i
])
==
-
1
)
{
if
(
rc
==
null
)
{
rc
=
"the value contains an illegal character: '"
+
_value
[
i
]
+
"', only following characters are allowed: '+allowedchars+'"
;
}
else
{
rc
+=
" / the value contains an illegal character: '"
+
_value
[
i
]
+
"', only following characters are allowed: '+allowedchars+'"
;
}
}
else
if
(
notallowedchars
!=
null
&&
notallowedchars
.
indexOf
(
_value
[
i
])
!=
-
1
)
{
if
(
rc
==
null
)
{
rc
=
"the value contains an illegal character: '"
+
_value
[
i
]
+
"', following characters are not allowed '+notallowedchars+'"
;
}
else
{
rc
+=
" / the value contains an illegal character: '"
+
_value
[
i
]
+
"', following characters are not allowed '+notallowedchars+'"
;
}
}
}
}
if
(
rc
!=
null
)
{
System
.
out
.
println
(
logmsg
+
" ==> "
+
rc
);
return
false
;
}
return
true
;
}
public
static
void
main
(
String
[]
args
)
{
boolean
failed
=
false
;
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
failed
|=
!
checkArgumentSyntax
(
"theName"
,
null
,
"\"<&"
,
"Error consistencyCheck: name in component definition"
);
failed
|=
!
checkArgumentSyntax
(
null
,
null
,
"\"<&"
,
"Error consistencyCheck: name in component definition"
);
failed
|=
!
checkArgumentSyntax
(
"42"
,
"0123456789."
,
null
,
"Error consistencyCheck: counter in component definition"
);
}
System
.
out
.
println
(
failed
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录