Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
d32e17c6
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看板
提交
d32e17c6
编写于
11月 05, 2013
作者:
I
iveresov
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
69cac249
8bb934e4
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
131 addition
and
23 deletion
+131
-23
src/share/vm/c1/c1_LinearScan.cpp
src/share/vm/c1/c1_LinearScan.cpp
+4
-2
src/share/vm/opto/compile.cpp
src/share/vm/opto/compile.cpp
+67
-0
src/share/vm/opto/compile.hpp
src/share/vm/opto/compile.hpp
+3
-0
src/share/vm/opto/loopTransform.cpp
src/share/vm/opto/loopTransform.cpp
+1
-1
src/share/vm/opto/memnode.hpp
src/share/vm/opto/memnode.hpp
+11
-20
test/compiler/regalloc/C1ObjectSpillInLogicOp.java
test/compiler/regalloc/C1ObjectSpillInLogicOp.java
+45
-0
未找到文件。
src/share/vm/c1/c1_LinearScan.cpp
浏览文件 @
d32e17c6
...
...
@@ -1138,8 +1138,10 @@ IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) {
}
}
}
}
else
if
(
opr_type
!=
T_LONG
)
{
// We want to sometimes use logical operations on pointers, in particular in GC barriers.
// Since 64bit logical operations do not current support operands on stack, we have to make sure
// T_OBJECT doesn't get spilled along with T_LONG.
}
else
if
(
opr_type
!=
T_LONG
LP64_ONLY
(
&&
opr_type
!=
T_OBJECT
))
{
// integer instruction (note: long operands must always be in register)
switch
(
op
->
code
())
{
case
lir_cmp
:
...
...
src/share/vm/opto/compile.cpp
浏览文件 @
d32e17c6
...
...
@@ -848,6 +848,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
}
#endif
NOT_PRODUCT
(
verify_barriers
();
)
// Now that we know the size of all the monitors we can add a fixed slot
// for the original deopt pc.
...
...
@@ -3373,6 +3374,72 @@ void Compile::verify_graph_edges(bool no_dead_code) {
}
}
}
// Verify GC barriers consistency
// Currently supported:
// - G1 pre-barriers (see GraphKit::g1_write_barrier_pre())
void
Compile
::
verify_barriers
()
{
if
(
UseG1GC
)
{
// Verify G1 pre-barriers
const
int
marking_offset
=
in_bytes
(
JavaThread
::
satb_mark_queue_offset
()
+
PtrQueue
::
byte_offset_of_active
());
ResourceArea
*
area
=
Thread
::
current
()
->
resource_area
();
Unique_Node_List
visited
(
area
);
Node_List
worklist
(
area
);
// We're going to walk control flow backwards starting from the Root
worklist
.
push
(
_root
);
while
(
worklist
.
size
()
>
0
)
{
Node
*
x
=
worklist
.
pop
();
if
(
x
==
NULL
||
x
==
top
())
continue
;
if
(
visited
.
member
(
x
))
{
continue
;
}
else
{
visited
.
push
(
x
);
}
if
(
x
->
is_Region
())
{
for
(
uint
i
=
1
;
i
<
x
->
req
();
i
++
)
{
worklist
.
push
(
x
->
in
(
i
));
}
}
else
{
worklist
.
push
(
x
->
in
(
0
));
// We are looking for the pattern:
// /->ThreadLocal
// If->Bool->CmpI->LoadB->AddP->ConL(marking_offset)
// \->ConI(0)
// We want to verify that the If and the LoadB have the same control
// See GraphKit::g1_write_barrier_pre()
if
(
x
->
is_If
())
{
IfNode
*
iff
=
x
->
as_If
();
if
(
iff
->
in
(
1
)
->
is_Bool
()
&&
iff
->
in
(
1
)
->
in
(
1
)
->
is_Cmp
())
{
CmpNode
*
cmp
=
iff
->
in
(
1
)
->
in
(
1
)
->
as_Cmp
();
if
(
cmp
->
Opcode
()
==
Op_CmpI
&&
cmp
->
in
(
2
)
->
is_Con
()
&&
cmp
->
in
(
2
)
->
bottom_type
()
->
is_int
()
->
get_con
()
==
0
&&
cmp
->
in
(
1
)
->
is_Load
())
{
LoadNode
*
load
=
cmp
->
in
(
1
)
->
as_Load
();
if
(
load
->
Opcode
()
==
Op_LoadB
&&
load
->
in
(
2
)
->
is_AddP
()
&&
load
->
in
(
2
)
->
in
(
2
)
->
Opcode
()
==
Op_ThreadLocal
&&
load
->
in
(
2
)
->
in
(
3
)
->
is_Con
()
&&
load
->
in
(
2
)
->
in
(
3
)
->
bottom_type
()
->
is_intptr_t
()
->
get_con
()
==
marking_offset
)
{
Node
*
if_ctrl
=
iff
->
in
(
0
);
Node
*
load_ctrl
=
load
->
in
(
0
);
if
(
if_ctrl
!=
load_ctrl
)
{
// Skip possible CProj->NeverBranch in infinite loops
if
((
if_ctrl
->
is_Proj
()
&&
if_ctrl
->
Opcode
()
==
Op_CProj
)
&&
(
if_ctrl
->
in
(
0
)
->
is_MultiBranch
()
&&
if_ctrl
->
in
(
0
)
->
Opcode
()
==
Op_NeverBranch
))
{
if_ctrl
=
if_ctrl
->
in
(
0
)
->
in
(
0
);
}
}
assert
(
load_ctrl
!=
NULL
&&
if_ctrl
==
load_ctrl
,
"controls must match"
);
}
}
}
}
}
}
}
}
#endif
// The Compile object keeps track of failure reasons separately from the ciEnv.
...
...
src/share/vm/opto/compile.hpp
浏览文件 @
d32e17c6
...
...
@@ -1148,6 +1148,9 @@ class Compile : public Phase {
// graph is strongly connected from root in both directions.
void
verify_graph_edges
(
bool
no_dead_code
=
false
)
PRODUCT_RETURN
;
// Verify GC barrier patterns
void
verify_barriers
()
PRODUCT_RETURN
;
// End-of-run dumps.
static
void
print_statistics
()
PRODUCT_RETURN
;
...
...
src/share/vm/opto/loopTransform.cpp
浏览文件 @
d32e17c6
...
...
@@ -1964,7 +1964,7 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
// Find loads off the surviving projection; remove their control edge
for
(
DUIterator_Fast
imax
,
i
=
dp
->
fast_outs
(
imax
);
i
<
imax
;
i
++
)
{
Node
*
cd
=
dp
->
fast_out
(
i
);
// Control-dependent node
if
(
cd
->
is_Load
()
)
{
// Loads can now float around in the loop
if
(
cd
->
is_Load
()
&&
cd
->
depends_only_on_test
()
)
{
// Loads can now float around in the loop
// Allow the load to float around in the loop, or before it
// but NOT before the pre-loop.
_igvn
.
replace_input_of
(
cd
,
0
,
ctrl
);
// ctrl, not NULL
...
...
src/share/vm/opto/memnode.hpp
浏览文件 @
d32e17c6
...
...
@@ -204,6 +204,17 @@ public:
protected:
const
Type
*
load_array_final_field
(
const
TypeKlassPtr
*
tkls
,
ciKlass
*
klass
)
const
;
// depends_only_on_test is almost always true, and needs to be almost always
// true to enable key hoisting & commoning optimizations. However, for the
// special case of RawPtr loads from TLS top & end, and other loads performed by
// GC barriers, the control edge carries the dependence preventing hoisting past
// a Safepoint instead of the memory edge. (An unfortunate consequence of having
// Safepoints not set Raw Memory; itself an unfortunate consequence of having Nodes
// which produce results (new raw memory state) inside of loops preventing all
// manner of other optimizations). Basically, it's ugly but so is the alternative.
// See comment in macro.cpp, around line 125 expand_allocate_common().
virtual
bool
depends_only_on_test
()
const
{
return
adr_type
()
!=
TypeRawPtr
::
BOTTOM
;
}
};
//------------------------------LoadBNode--------------------------------------
...
...
@@ -370,16 +381,6 @@ public:
virtual
uint
ideal_reg
()
const
{
return
Op_RegP
;
}
virtual
int
store_Opcode
()
const
{
return
Op_StoreP
;
}
virtual
BasicType
memory_type
()
const
{
return
T_ADDRESS
;
}
// depends_only_on_test is almost always true, and needs to be almost always
// true to enable key hoisting & commoning optimizations. However, for the
// special case of RawPtr loads from TLS top & end, the control edge carries
// the dependence preventing hoisting past a Safepoint instead of the memory
// edge. (An unfortunate consequence of having Safepoints not set Raw
// Memory; itself an unfortunate consequence of having Nodes which produce
// results (new raw memory state) inside of loops preventing all manner of
// other optimizations). Basically, it's ugly but so is the alternative.
// See comment in macro.cpp, around line 125 expand_allocate_common().
virtual
bool
depends_only_on_test
()
const
{
return
adr_type
()
!=
TypeRawPtr
::
BOTTOM
;
}
};
...
...
@@ -393,16 +394,6 @@ public:
virtual
uint
ideal_reg
()
const
{
return
Op_RegN
;
}
virtual
int
store_Opcode
()
const
{
return
Op_StoreN
;
}
virtual
BasicType
memory_type
()
const
{
return
T_NARROWOOP
;
}
// depends_only_on_test is almost always true, and needs to be almost always
// true to enable key hoisting & commoning optimizations. However, for the
// special case of RawPtr loads from TLS top & end, the control edge carries
// the dependence preventing hoisting past a Safepoint instead of the memory
// edge. (An unfortunate consequence of having Safepoints not set Raw
// Memory; itself an unfortunate consequence of having Nodes which produce
// results (new raw memory state) inside of loops preventing all manner of
// other optimizations). Basically, it's ugly but so is the alternative.
// See comment in macro.cpp, around line 125 expand_allocate_common().
virtual
bool
depends_only_on_test
()
const
{
return
adr_type
()
!=
TypeRawPtr
::
BOTTOM
;
}
};
//------------------------------LoadKlassNode----------------------------------
...
...
test/compiler/regalloc/C1ObjectSpillInLogicOp.java
0 → 100644
浏览文件 @
d32e17c6
/*
* 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 8027751
* @summary C1 crashes generating G1 post-barrier in Unsafe.getAndSetObject() intrinsic because of the new value spill
* @run main/othervm -XX:+UseG1GC C1ObjectSpillInLogicOp
*
* G1 barriers use logical operators (xor) on T_OBJECT mixed with T_LONG or T_INT.
* The current implementation of logical operations on x86 in C1 doesn't allow for long operands to be on stack.
* There is a special code in the register allocator that forces long arguments in registers on x86. However T_OBJECT
* can be spilled just fine, and in that case the xor emission will fail.
*/
import
java.util.concurrent.atomic.*
;
class
C1ObjectSpillInLogicOp
{
static
public
void
main
(
String
[]
args
)
{
AtomicReferenceArray
<
Integer
>
x
=
new
AtomicReferenceArray
(
128
);
Integer
y
=
new
Integer
(
0
);
for
(
int
i
=
0
;
i
<
50000
;
i
++)
{
x
.
getAndSet
(
i
%
x
.
length
(),
y
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录