Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
0b7b9e13
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看板
提交
0b7b9e13
编写于
12月 04, 2008
作者:
K
kvn
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
b96293be
190dc7bf
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
373 addition
and
120 deletion
+373
-120
src/share/vm/c1/c1_GraphBuilder.cpp
src/share/vm/c1/c1_GraphBuilder.cpp
+4
-27
src/share/vm/c1/c1_GraphBuilder.hpp
src/share/vm/c1/c1_GraphBuilder.hpp
+0
-2
src/share/vm/c1/c1_ValueMap.hpp
src/share/vm/c1/c1_ValueMap.hpp
+71
-47
src/share/vm/opto/callnode.cpp
src/share/vm/opto/callnode.cpp
+13
-5
src/share/vm/opto/callnode.hpp
src/share/vm/opto/callnode.hpp
+6
-1
src/share/vm/opto/compile.cpp
src/share/vm/opto/compile.cpp
+0
-5
src/share/vm/opto/escape.cpp
src/share/vm/opto/escape.cpp
+2
-1
src/share/vm/opto/locknode.cpp
src/share/vm/opto/locknode.cpp
+6
-1
src/share/vm/opto/locknode.hpp
src/share/vm/opto/locknode.hpp
+1
-1
src/share/vm/opto/macro.cpp
src/share/vm/opto/macro.cpp
+90
-26
src/share/vm/opto/output.cpp
src/share/vm/opto/output.cpp
+3
-4
test/compiler/6756768/Test6756768.java
test/compiler/6756768/Test6756768.java
+55
-0
test/compiler/6756768/Test6756768_2.java
test/compiler/6756768/Test6756768_2.java
+55
-0
test/compiler/6775880/Test.java
test/compiler/6775880/Test.java
+67
-0
未找到文件。
src/share/vm/c1/c1_GraphBuilder.cpp
浏览文件 @
0b7b9e13
...
...
@@ -676,21 +676,6 @@ GraphBuilder::ScopeData::ScopeData(ScopeData* parent)
}
void
GraphBuilder
::
kill_field
(
ciField
*
field
)
{
if
(
UseLocalValueNumbering
)
{
vmap
()
->
kill_field
(
field
);
}
}
void
GraphBuilder
::
kill_array
(
Value
value
)
{
if
(
UseLocalValueNumbering
)
{
vmap
()
->
kill_array
(
value
->
type
());
}
_memory
->
store_value
(
value
);
}
void
GraphBuilder
::
kill_all
()
{
if
(
UseLocalValueNumbering
)
{
vmap
()
->
kill_all
();
...
...
@@ -987,8 +972,8 @@ void GraphBuilder::store_indexed(BasicType type) {
length
=
append
(
new
ArrayLength
(
array
,
lock_stack
()));
}
StoreIndexed
*
result
=
new
StoreIndexed
(
array
,
index
,
length
,
type
,
value
,
lock_stack
());
kill_array
(
value
);
// invalidate all CSEs that are memory accesses of the same type
append
(
result
);
_memory
->
store_value
(
value
);
}
...
...
@@ -1478,9 +1463,6 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
case
Bytecodes
::
_putstatic
:
{
Value
val
=
pop
(
type
);
append
(
new
StoreField
(
append
(
obj
),
offset
,
field
,
val
,
true
,
lock_stack
(),
state_copy
,
is_loaded
,
is_initialized
));
if
(
UseLocalValueNumbering
)
{
vmap
()
->
kill_field
(
field
);
// invalidate all CSEs that are memory accesses
}
}
break
;
case
Bytecodes
::
_getfield
:
...
...
@@ -1503,7 +1485,6 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
if
(
is_loaded
)
store
=
_memory
->
store
(
store
);
if
(
store
!=
NULL
)
{
append
(
store
);
kill_field
(
field
);
// invalidate all CSEs that are accesses of this field
}
}
break
;
...
...
@@ -1900,6 +1881,8 @@ Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
assert
(
i2
->
bci
()
!=
-
1
,
"should already be linked"
);
return
i2
;
}
ValueNumberingEffects
vne
(
vmap
());
i1
->
visit
(
&
vne
);
}
if
(
i1
->
as_Phi
()
==
NULL
&&
i1
->
as_Local
()
==
NULL
)
{
...
...
@@ -1926,14 +1909,8 @@ Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
assert
(
_last
==
i1
,
"adjust code below"
);
StateSplit
*
s
=
i1
->
as_StateSplit
();
if
(
s
!=
NULL
&&
i1
->
as_BlockEnd
()
==
NULL
)
{
// Continue CSE across certain intrinsics
Intrinsic
*
intrinsic
=
s
->
as_Intrinsic
();
if
(
UseLocalValueNumbering
)
{
if
(
intrinsic
==
NULL
||
!
intrinsic
->
preserves_state
())
{
vmap
()
->
kill_all
();
// for now, hopefully we need this only for calls eventually
}
}
if
(
EliminateFieldAccess
)
{
Intrinsic
*
intrinsic
=
s
->
as_Intrinsic
();
if
(
s
->
as_Invoke
()
!=
NULL
||
(
intrinsic
&&
!
intrinsic
->
preserves_state
()))
{
_memory
->
kill
();
}
...
...
src/share/vm/c1/c1_GraphBuilder.hpp
浏览文件 @
0b7b9e13
...
...
@@ -283,8 +283,6 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC {
Dependencies
*
dependency_recorder
()
const
;
// = compilation()->dependencies()
bool
direct_compare
(
ciKlass
*
k
);
void
kill_field
(
ciField
*
field
);
void
kill_array
(
Value
value
);
void
kill_all
();
ValueStack
*
lock_stack
();
...
...
src/share/vm/c1/c1_ValueMap.hpp
浏览文件 @
0b7b9e13
...
...
@@ -133,53 +133,77 @@ class ValueNumberingVisitor: public InstructionVisitor {
virtual
void
kill_array
(
ValueType
*
type
)
=
0
;
// visitor functions
void
do_StoreField
(
StoreField
*
x
)
{
kill_field
(
x
->
field
());
};
void
do_StoreIndexed
(
StoreIndexed
*
x
)
{
kill_array
(
x
->
type
());
};
void
do_MonitorEnter
(
MonitorEnter
*
x
)
{
kill_memory
();
};
void
do_MonitorExit
(
MonitorExit
*
x
)
{
kill_memory
();
};
void
do_Invoke
(
Invoke
*
x
)
{
kill_memory
();
};
void
do_UnsafePutRaw
(
UnsafePutRaw
*
x
)
{
kill_memory
();
};
void
do_UnsafePutObject
(
UnsafePutObject
*
x
)
{
kill_memory
();
};
void
do_Intrinsic
(
Intrinsic
*
x
)
{
if
(
!
x
->
preserves_state
())
kill_memory
();
};
void
do_Phi
(
Phi
*
x
)
{
/* nothing to do */
};
void
do_Local
(
Local
*
x
)
{
/* nothing to do */
};
void
do_Constant
(
Constant
*
x
)
{
/* nothing to do */
};
void
do_LoadField
(
LoadField
*
x
)
{
/* nothing to do */
};
void
do_ArrayLength
(
ArrayLength
*
x
)
{
/* nothing to do */
};
void
do_LoadIndexed
(
LoadIndexed
*
x
)
{
/* nothing to do */
};
void
do_NegateOp
(
NegateOp
*
x
)
{
/* nothing to do */
};
void
do_ArithmeticOp
(
ArithmeticOp
*
x
)
{
/* nothing to do */
};
void
do_ShiftOp
(
ShiftOp
*
x
)
{
/* nothing to do */
};
void
do_LogicOp
(
LogicOp
*
x
)
{
/* nothing to do */
};
void
do_CompareOp
(
CompareOp
*
x
)
{
/* nothing to do */
};
void
do_IfOp
(
IfOp
*
x
)
{
/* nothing to do */
};
void
do_Convert
(
Convert
*
x
)
{
/* nothing to do */
};
void
do_NullCheck
(
NullCheck
*
x
)
{
/* nothing to do */
};
void
do_NewInstance
(
NewInstance
*
x
)
{
/* nothing to do */
};
void
do_NewTypeArray
(
NewTypeArray
*
x
)
{
/* nothing to do */
};
void
do_NewObjectArray
(
NewObjectArray
*
x
)
{
/* nothing to do */
};
void
do_NewMultiArray
(
NewMultiArray
*
x
)
{
/* nothing to do */
};
void
do_CheckCast
(
CheckCast
*
x
)
{
/* nothing to do */
};
void
do_InstanceOf
(
InstanceOf
*
x
)
{
/* nothing to do */
};
void
do_BlockBegin
(
BlockBegin
*
x
)
{
/* nothing to do */
};
void
do_Goto
(
Goto
*
x
)
{
/* nothing to do */
};
void
do_If
(
If
*
x
)
{
/* nothing to do */
};
void
do_IfInstanceOf
(
IfInstanceOf
*
x
)
{
/* nothing to do */
};
void
do_TableSwitch
(
TableSwitch
*
x
)
{
/* nothing to do */
};
void
do_LookupSwitch
(
LookupSwitch
*
x
)
{
/* nothing to do */
};
void
do_Return
(
Return
*
x
)
{
/* nothing to do */
};
void
do_Throw
(
Throw
*
x
)
{
/* nothing to do */
};
void
do_Base
(
Base
*
x
)
{
/* nothing to do */
};
void
do_OsrEntry
(
OsrEntry
*
x
)
{
/* nothing to do */
};
void
do_ExceptionObject
(
ExceptionObject
*
x
)
{
/* nothing to do */
};
void
do_RoundFP
(
RoundFP
*
x
)
{
/* nothing to do */
};
void
do_UnsafeGetRaw
(
UnsafeGetRaw
*
x
)
{
/* nothing to do */
};
void
do_UnsafeGetObject
(
UnsafeGetObject
*
x
)
{
/* nothing to do */
};
void
do_UnsafePrefetchRead
(
UnsafePrefetchRead
*
x
)
{
/* nothing to do */
};
void
do_UnsafePrefetchWrite
(
UnsafePrefetchWrite
*
x
)
{
/* nothing to do */
};
void
do_ProfileCall
(
ProfileCall
*
x
)
{
/* nothing to do */
};
void
do_ProfileCounter
(
ProfileCounter
*
x
)
{
/* nothing to do */
};
void
do_StoreField
(
StoreField
*
x
)
{
if
(
!
x
->
is_initialized
())
{
kill_memory
();
}
else
{
kill_field
(
x
->
field
());
}
}
void
do_StoreIndexed
(
StoreIndexed
*
x
)
{
kill_array
(
x
->
type
());
}
void
do_MonitorEnter
(
MonitorEnter
*
x
)
{
kill_memory
();
}
void
do_MonitorExit
(
MonitorExit
*
x
)
{
kill_memory
();
}
void
do_Invoke
(
Invoke
*
x
)
{
kill_memory
();
}
void
do_UnsafePutRaw
(
UnsafePutRaw
*
x
)
{
kill_memory
();
}
void
do_UnsafePutObject
(
UnsafePutObject
*
x
)
{
kill_memory
();
}
void
do_Intrinsic
(
Intrinsic
*
x
)
{
if
(
!
x
->
preserves_state
())
kill_memory
();
}
void
do_Phi
(
Phi
*
x
)
{
/* nothing to do */
}
void
do_Local
(
Local
*
x
)
{
/* nothing to do */
}
void
do_Constant
(
Constant
*
x
)
{
/* nothing to do */
}
void
do_LoadField
(
LoadField
*
x
)
{
if
(
!
x
->
is_initialized
())
{
kill_memory
();
}
}
void
do_ArrayLength
(
ArrayLength
*
x
)
{
/* nothing to do */
}
void
do_LoadIndexed
(
LoadIndexed
*
x
)
{
/* nothing to do */
}
void
do_NegateOp
(
NegateOp
*
x
)
{
/* nothing to do */
}
void
do_ArithmeticOp
(
ArithmeticOp
*
x
)
{
/* nothing to do */
}
void
do_ShiftOp
(
ShiftOp
*
x
)
{
/* nothing to do */
}
void
do_LogicOp
(
LogicOp
*
x
)
{
/* nothing to do */
}
void
do_CompareOp
(
CompareOp
*
x
)
{
/* nothing to do */
}
void
do_IfOp
(
IfOp
*
x
)
{
/* nothing to do */
}
void
do_Convert
(
Convert
*
x
)
{
/* nothing to do */
}
void
do_NullCheck
(
NullCheck
*
x
)
{
/* nothing to do */
}
void
do_NewInstance
(
NewInstance
*
x
)
{
/* nothing to do */
}
void
do_NewTypeArray
(
NewTypeArray
*
x
)
{
/* nothing to do */
}
void
do_NewObjectArray
(
NewObjectArray
*
x
)
{
/* nothing to do */
}
void
do_NewMultiArray
(
NewMultiArray
*
x
)
{
/* nothing to do */
}
void
do_CheckCast
(
CheckCast
*
x
)
{
/* nothing to do */
}
void
do_InstanceOf
(
InstanceOf
*
x
)
{
/* nothing to do */
}
void
do_BlockBegin
(
BlockBegin
*
x
)
{
/* nothing to do */
}
void
do_Goto
(
Goto
*
x
)
{
/* nothing to do */
}
void
do_If
(
If
*
x
)
{
/* nothing to do */
}
void
do_IfInstanceOf
(
IfInstanceOf
*
x
)
{
/* nothing to do */
}
void
do_TableSwitch
(
TableSwitch
*
x
)
{
/* nothing to do */
}
void
do_LookupSwitch
(
LookupSwitch
*
x
)
{
/* nothing to do */
}
void
do_Return
(
Return
*
x
)
{
/* nothing to do */
}
void
do_Throw
(
Throw
*
x
)
{
/* nothing to do */
}
void
do_Base
(
Base
*
x
)
{
/* nothing to do */
}
void
do_OsrEntry
(
OsrEntry
*
x
)
{
/* nothing to do */
}
void
do_ExceptionObject
(
ExceptionObject
*
x
)
{
/* nothing to do */
}
void
do_RoundFP
(
RoundFP
*
x
)
{
/* nothing to do */
}
void
do_UnsafeGetRaw
(
UnsafeGetRaw
*
x
)
{
/* nothing to do */
}
void
do_UnsafeGetObject
(
UnsafeGetObject
*
x
)
{
/* nothing to do */
}
void
do_UnsafePrefetchRead
(
UnsafePrefetchRead
*
x
)
{
/* nothing to do */
}
void
do_UnsafePrefetchWrite
(
UnsafePrefetchWrite
*
x
)
{
/* nothing to do */
}
void
do_ProfileCall
(
ProfileCall
*
x
)
{
/* nothing to do */
}
void
do_ProfileCounter
(
ProfileCounter
*
x
)
{
/* nothing to do */
}
};
class
ValueNumberingEffects
:
public
ValueNumberingVisitor
{
private:
ValueMap
*
_map
;
public:
// implementation for abstract methods of ValueNumberingVisitor
void
kill_memory
()
{
_map
->
kill_memory
();
}
void
kill_field
(
ciField
*
field
)
{
_map
->
kill_field
(
field
);
}
void
kill_array
(
ValueType
*
type
)
{
_map
->
kill_array
(
type
);
}
ValueNumberingEffects
(
ValueMap
*
map
)
:
_map
(
map
)
{}
};
...
...
src/share/vm/opto/callnode.cpp
浏览文件 @
0b7b9e13
...
...
@@ -395,7 +395,13 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
OptoReg
::
regname
(
OptoReg
::
c_frame_pointer
),
regalloc
->
reg2offset
(
box_reg
));
}
format_helper
(
regalloc
,
st
,
obj
,
"MON-OBJ["
,
i
,
&
scobjs
);
const
char
*
obj_msg
=
"MON-OBJ["
;
if
(
EliminateLocks
)
{
while
(
!
box
->
is_BoxLock
()
)
box
=
box
->
in
(
1
);
if
(
box
->
as_BoxLock
()
->
is_eliminated
())
obj_msg
=
"MON-OBJ(LOCK ELIMINATED)["
;
}
format_helper
(
regalloc
,
st
,
obj
,
obj_msg
,
i
,
&
scobjs
);
}
for
(
i
=
0
;
i
<
(
uint
)
scobjs
.
length
();
i
++
)
{
...
...
@@ -908,8 +914,9 @@ void SafePointNode::push_monitor(const FastLockNode *lock) {
add_req
(
lock
->
box_node
());
add_req
(
lock
->
obj_node
());
}
else
{
add_req
(
NULL
);
add_req
(
NULL
);
Node
*
top
=
Compile
::
current
()
->
top
();
add_req
(
top
);
add_req
(
top
);
}
jvms
()
->
set_scloff
(
nextmon
+
MonitorEdges
);
jvms
()
->
set_endoff
(
req
());
...
...
@@ -1382,7 +1389,7 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
//
// If we are locking an unescaped object, the lock/unlock is unnecessary
//
ConnectionGraph
*
cgr
=
Compile
::
current
()
->
congraph
();
ConnectionGraph
*
cgr
=
phase
->
C
->
congraph
();
PointsToNode
::
EscapeState
es
=
PointsToNode
::
GlobalEscape
;
if
(
cgr
!=
NULL
)
es
=
cgr
->
escape_state
(
obj_node
(),
phase
);
...
...
@@ -1450,6 +1457,7 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Mark it eliminated to update any counters
lock
->
set_eliminated
();
lock
->
set_coarsened
();
}
}
else
if
(
result
!=
NULL
&&
ctrl
->
is_Region
()
&&
iter
->
_worklist
.
member
(
ctrl
))
{
...
...
@@ -1484,7 +1492,7 @@ Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
//
// If we are unlocking an unescaped object, the lock/unlock is unnecessary.
//
ConnectionGraph
*
cgr
=
Compile
::
current
()
->
congraph
();
ConnectionGraph
*
cgr
=
phase
->
C
->
congraph
();
PointsToNode
::
EscapeState
es
=
PointsToNode
::
GlobalEscape
;
if
(
cgr
!=
NULL
)
es
=
cgr
->
escape_state
(
obj_node
(),
phase
);
...
...
src/share/vm/opto/callnode.hpp
浏览文件 @
0b7b9e13
...
...
@@ -780,7 +780,8 @@ public:
//------------------------------AbstractLockNode-----------------------------------
class
AbstractLockNode
:
public
CallNode
{
private:
bool
_eliminate
;
// indicates this lock can be safely eliminated
bool
_eliminate
;
// indicates this lock can be safely eliminated
bool
_coarsened
;
// indicates this lock was coarsened
#ifndef PRODUCT
NamedCounter
*
_counter
;
#endif
...
...
@@ -801,6 +802,7 @@ protected:
public:
AbstractLockNode
(
const
TypeFunc
*
tf
)
:
CallNode
(
tf
,
NULL
,
TypeRawPtr
::
BOTTOM
),
_coarsened
(
false
),
_eliminate
(
false
)
{
#ifndef PRODUCT
...
...
@@ -819,6 +821,9 @@ public:
// mark node as eliminated and update the counter if there is one
void
set_eliminated
();
bool
is_coarsened
()
{
return
_coarsened
;
}
void
set_coarsened
()
{
_coarsened
=
true
;
}
// locking does not modify its arguments
virtual
bool
may_modify
(
const
TypePtr
*
addr_t
,
PhaseTransform
*
phase
){
return
false
;}
...
...
src/share/vm/opto/compile.cpp
浏览文件 @
0b7b9e13
...
...
@@ -1532,11 +1532,6 @@ void Compile::Optimize() {
if
(
failing
())
return
;
// get rid of the connection graph since it's information is not
// updated by optimizations
_congraph
=
NULL
;
// Loop transforms on the ideal graph. Range Check Elimination,
// peeling, unrolling, etc.
...
...
src/share/vm/opto/escape.cpp
浏览文件 @
0b7b9e13
...
...
@@ -199,7 +199,8 @@ PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n, PhaseTransform
es
=
ptnode_adr
(
idx
)
->
escape_state
();
// if we have already computed a value, return it
if
(
es
!=
PointsToNode
::
UnknownEscape
)
if
(
es
!=
PointsToNode
::
UnknownEscape
&&
ptnode_adr
(
idx
)
->
node_type
()
==
PointsToNode
::
JavaObject
)
return
es
;
// PointsTo() calls n->uncast() which can return a new ideal node.
...
...
src/share/vm/opto/locknode.cpp
浏览文件 @
0b7b9e13
...
...
@@ -44,10 +44,15 @@ BoxLockNode::BoxLockNode( int slot ) : Node( Compile::current()->root() ),
_inmask
.
Insert
(
reg
);
}
//-----------------------------hash--------------------------------------------
uint
BoxLockNode
::
hash
()
const
{
return
Node
::
hash
()
+
_slot
+
(
_is_eliminated
?
Compile
::
current
()
->
fixed_slots
()
:
0
);
}
//------------------------------cmp--------------------------------------------
uint
BoxLockNode
::
cmp
(
const
Node
&
n
)
const
{
const
BoxLockNode
&
bn
=
(
const
BoxLockNode
&
)
n
;
return
bn
.
_slot
==
_slot
;
return
bn
.
_slot
==
_slot
&&
bn
.
_is_eliminated
==
_is_eliminated
;
}
OptoReg
::
Name
BoxLockNode
::
stack_slot
(
Node
*
box_node
)
{
...
...
src/share/vm/opto/locknode.hpp
浏览文件 @
0b7b9e13
...
...
@@ -36,7 +36,7 @@ public:
virtual
const
RegMask
&
in_RegMask
(
uint
)
const
;
virtual
const
RegMask
&
out_RegMask
()
const
;
virtual
uint
size_of
()
const
;
virtual
uint
hash
()
const
{
return
Node
::
hash
()
+
_slot
;
}
virtual
uint
hash
()
const
;
virtual
uint
cmp
(
const
Node
&
n
)
const
;
virtual
const
class
Type
*
bottom_type
()
const
{
return
TypeRawPtr
::
BOTTOM
;
}
virtual
uint
ideal_reg
()
const
{
return
Op_RegP
;
}
...
...
src/share/vm/opto/macro.cpp
浏览文件 @
0b7b9e13
...
...
@@ -59,7 +59,7 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal
for
(
uint
i
=
old_dbg_start
;
i
<
oldcall
->
req
();
i
++
)
{
Node
*
old_in
=
oldcall
->
in
(
i
);
// Clone old SafePointScalarObjectNodes, adjusting their field contents.
if
(
old_in
->
is_SafePointScalarObject
())
{
if
(
old_in
!=
NULL
&&
old_in
->
is_SafePointScalarObject
())
{
SafePointScalarObjectNode
*
old_sosn
=
old_in
->
as_SafePointScalarObject
();
uint
old_unique
=
C
->
unique
();
Node
*
new_in
=
old_sosn
->
clone
(
jvms_adj
,
sosn_map
);
...
...
@@ -1509,21 +1509,63 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
if
(
!
alock
->
is_eliminated
())
{
return
false
;
}
// Mark the box lock as eliminated if all correspondent locks are eliminated
// to construct correct debug info.
BoxLockNode
*
box
=
alock
->
box_node
()
->
as_BoxLock
();
if
(
!
box
->
is_eliminated
())
{
bool
eliminate
=
true
;
for
(
DUIterator_Fast
imax
,
i
=
box
->
fast_outs
(
imax
);
i
<
imax
;
i
++
)
{
Node
*
lck
=
box
->
fast_out
(
i
);
if
(
lck
->
is_Lock
()
&&
!
lck
->
as_AbstractLock
()
->
is_eliminated
())
{
eliminate
=
false
;
break
;
}
}
if
(
eliminate
)
box
->
set_eliminated
();
}
if
(
alock
->
is_Lock
()
&&
!
alock
->
is_coarsened
())
{
// Create new "eliminated" BoxLock node and use it
// in monitor debug info for the same object.
BoxLockNode
*
oldbox
=
alock
->
box_node
()
->
as_BoxLock
();
Node
*
obj
=
alock
->
obj_node
();
if
(
!
oldbox
->
is_eliminated
())
{
BoxLockNode
*
newbox
=
oldbox
->
clone
()
->
as_BoxLock
();
newbox
->
set_eliminated
();
transform_later
(
newbox
);
// Replace old box node with new box for all users
// of the same object.
for
(
uint
i
=
0
;
i
<
oldbox
->
outcnt
();)
{
bool
next_edge
=
true
;
Node
*
u
=
oldbox
->
raw_out
(
i
);
if
(
u
==
alock
)
{
i
++
;
continue
;
// It will be removed below
}
if
(
u
->
is_Lock
()
&&
u
->
as_Lock
()
->
obj_node
()
==
obj
&&
// oldbox could be referenced in debug info also
u
->
as_Lock
()
->
box_node
()
==
oldbox
)
{
assert
(
u
->
as_Lock
()
->
is_eliminated
(),
"sanity"
);
_igvn
.
hash_delete
(
u
);
u
->
set_req
(
TypeFunc
::
Parms
+
1
,
newbox
);
next_edge
=
false
;
#ifdef ASSERT
}
else
if
(
u
->
is_Unlock
()
&&
u
->
as_Unlock
()
->
obj_node
()
==
obj
)
{
assert
(
u
->
as_Unlock
()
->
is_eliminated
(),
"sanity"
);
#endif
}
// Replace old box in monitor debug info.
if
(
u
->
is_SafePoint
()
&&
u
->
as_SafePoint
()
->
jvms
())
{
SafePointNode
*
sfn
=
u
->
as_SafePoint
();
JVMState
*
youngest_jvms
=
sfn
->
jvms
();
int
max_depth
=
youngest_jvms
->
depth
();
for
(
int
depth
=
1
;
depth
<=
max_depth
;
depth
++
)
{
JVMState
*
jvms
=
youngest_jvms
->
of_depth
(
depth
);
int
num_mon
=
jvms
->
nof_monitors
();
// Loop over monitors
for
(
int
idx
=
0
;
idx
<
num_mon
;
idx
++
)
{
Node
*
obj_node
=
sfn
->
monitor_obj
(
jvms
,
idx
);
Node
*
box_node
=
sfn
->
monitor_box
(
jvms
,
idx
);
if
(
box_node
==
oldbox
&&
obj_node
==
obj
)
{
int
j
=
jvms
->
monitor_box_offset
(
idx
);
_igvn
.
hash_delete
(
u
);
u
->
set_req
(
j
,
newbox
);
next_edge
=
false
;
}
}
// for (int idx = 0;
}
// for (int depth = 1;
}
// if (u->is_SafePoint()
if
(
next_edge
)
i
++
;
}
// for (uint i = 0; i < oldbox->outcnt();)
}
// if (!oldbox->is_eliminated())
}
// if (alock->is_Lock() && !lock->is_coarsened())
#ifndef PRODUCT
if
(
PrintEliminateLocks
)
{
...
...
@@ -1562,6 +1604,15 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
_igvn
.
subsume_node
(
ctrlproj
,
fallthroughproj
);
_igvn
.
hash_delete
(
memproj
);
_igvn
.
subsume_node
(
memproj
,
memproj_fallthrough
);
// Delete FastLock node also if this Lock node is unique user
// (a loop peeling may clone a Lock node).
Node
*
flock
=
alock
->
as_Lock
()
->
fastlock_node
();
if
(
flock
->
outcnt
()
==
1
)
{
assert
(
flock
->
unique_out
()
==
alock
,
"sanity"
);
_igvn
.
hash_delete
(
flock
);
_igvn
.
subsume_node
(
flock
,
top
());
}
}
// Seach for MemBarRelease node and delete it also.
...
...
@@ -1887,8 +1938,28 @@ void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) {
bool
PhaseMacroExpand
::
expand_macro_nodes
()
{
if
(
C
->
macro_count
()
==
0
)
return
false
;
//
attempt to eliminate allocation
s
//
First, attempt to eliminate lock
s
bool
progress
=
true
;
while
(
progress
)
{
progress
=
false
;
for
(
int
i
=
C
->
macro_count
();
i
>
0
;
i
--
)
{
Node
*
n
=
C
->
macro_node
(
i
-
1
);
bool
success
=
false
;
debug_only
(
int
old_macro_count
=
C
->
macro_count
(););
if
(
n
->
is_AbstractLock
())
{
success
=
eliminate_locking_node
(
n
->
as_AbstractLock
());
}
else
if
(
n
->
Opcode
()
==
Op_Opaque1
||
n
->
Opcode
()
==
Op_Opaque2
)
{
_igvn
.
add_users_to_worklist
(
n
);
_igvn
.
hash_delete
(
n
);
_igvn
.
subsume_node
(
n
,
n
->
in
(
1
));
success
=
true
;
}
assert
(
success
==
(
C
->
macro_count
()
<
old_macro_count
),
"elimination reduces macro count"
);
progress
=
progress
||
success
;
}
}
// Next, attempt to eliminate allocations
progress
=
true
;
while
(
progress
)
{
progress
=
false
;
for
(
int
i
=
C
->
macro_count
();
i
>
0
;
i
--
)
{
...
...
@@ -1902,17 +1973,10 @@ bool PhaseMacroExpand::expand_macro_nodes() {
break
;
case
Node
::
Class_Lock
:
case
Node
::
Class_Unlock
:
success
=
eliminate_locking_node
(
n
->
as_AbstractLock
()
);
assert
(
!
n
->
as_AbstractLock
()
->
is_eliminated
(),
"sanity"
);
break
;
default:
if
(
n
->
Opcode
()
==
Op_Opaque1
||
n
->
Opcode
()
==
Op_Opaque2
)
{
_igvn
.
add_users_to_worklist
(
n
);
_igvn
.
hash_delete
(
n
);
_igvn
.
subsume_node
(
n
,
n
->
in
(
1
));
success
=
true
;
}
else
{
assert
(
false
,
"unknown node type in macro list"
);
}
assert
(
false
,
"unknown node type in macro list"
);
}
assert
(
success
==
(
C
->
macro_count
()
<
old_macro_count
),
"elimination reduces macro count"
);
progress
=
progress
||
success
;
...
...
src/share/vm/opto/output.cpp
浏览文件 @
0b7b9e13
...
...
@@ -849,10 +849,8 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
// Loop over monitors and insert into array
for
(
idx
=
0
;
idx
<
num_mon
;
idx
++
)
{
// Grab the node that defines this monitor
Node
*
box_node
;
Node
*
obj_node
;
box_node
=
sfn
->
monitor_box
(
jvms
,
idx
);
obj_node
=
sfn
->
monitor_obj
(
jvms
,
idx
);
Node
*
box_node
=
sfn
->
monitor_box
(
jvms
,
idx
);
Node
*
obj_node
=
sfn
->
monitor_obj
(
jvms
,
idx
);
// Create ScopeValue for object
ScopeValue
*
scval
=
NULL
;
...
...
@@ -890,6 +888,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
OptoReg
::
Name
box_reg
=
BoxLockNode
::
stack_slot
(
box_node
);
Location
basic_lock
=
Location
::
new_stk_loc
(
Location
::
normal
,
_regalloc
->
reg2offset
(
box_reg
));
while
(
!
box_node
->
is_BoxLock
()
)
box_node
=
box_node
->
in
(
1
);
monarray
->
append
(
new
MonitorValue
(
scval
,
basic_lock
,
box_node
->
as_BoxLock
()
->
is_eliminated
()));
}
...
...
test/compiler/6756768/Test6756768.java
0 → 100644
浏览文件 @
0b7b9e13
/*
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6756768
* @summary C1 generates invalid code
*
* @run main/othervm -Xcomp Test6756768
*/
class
Test6756768a
{
static
boolean
var_1
=
true
;
}
final
class
Test6756768b
{
static
boolean
var_24
=
false
;
static
int
var_25
=
0
;
static
boolean
var_temp1
=
Test6756768a
.
var_1
=
false
;
}
public
final
class
Test6756768
extends
Test6756768a
{
final
static
int
var
=
var_1
^
(
Test6756768b
.
var_24
?
var_1
:
var_1
)
?
Test6756768b
.
var_25
:
1
;
static
public
void
main
(
String
[]
args
)
{
if
(
var
!=
0
)
{
throw
new
InternalError
(
"var = "
+
var
);
}
}
}
test/compiler/6756768/Test6756768_2.java
0 → 100644
浏览文件 @
0b7b9e13
/*
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6756768
* @summary C1 generates invalid code
*
* @run main/othervm -Xcomp Test6756768_2
*/
class
Test6756768_2a
{
static
int
var
=
++
Test6756768_2
.
var
;
}
public
class
Test6756768_2
{
static
int
var
=
1
;
static
Object
d2
=
null
;
static
void
test_static_field
()
{
int
v
=
var
;
int
v2
=
Test6756768_2a
.
var
;
int
v3
=
var
;
var
=
v3
;
}
public
static
void
main
(
String
[]
args
)
{
var
=
1
;
test_static_field
();
if
(
var
!=
2
)
{
throw
new
InternalError
();
}
}
}
test/compiler/6775880/Test.java
0 → 100644
浏览文件 @
0b7b9e13
/*
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
/*
* @test
* @bug 6775880
* @summary EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
* @compile -source 1.4 -target 1.4 Test.java
* @run main/othervm -server -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test
*/
public
class
Test
{
int
cnt
;
int
b
[];
String
s
;
String
test
()
{
String
res
=
""
;
for
(
int
i
=
0
;
i
<
cnt
;
i
++)
{
if
(
i
!=
0
)
{
res
=
res
+
"."
;
}
res
=
res
+
b
[
i
];
}
return
res
;
}
public
static
void
main
(
String
[]
args
)
{
Test
t
=
new
Test
();
t
.
cnt
=
3
;
t
.
b
=
new
int
[
3
];
t
.
b
[
0
]
=
0
;
t
.
b
[
1
]
=
1
;
t
.
b
[
2
]
=
2
;
int
j
=
0
;
t
.
s
=
""
;
for
(
int
i
=
0
;
i
<
10001
;
i
++)
{
t
.
s
=
"c"
;
t
.
s
=
t
.
test
();
}
System
.
out
.
println
(
"After s="
+
t
.
s
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录