Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
b85595b7
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看板
提交
b85595b7
编写于
12月 05, 2007
作者:
N
never
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
Reviewed-by: kvn, rasbold
上级
6cfe96aa
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
540 addition
and
67 deletion
+540
-67
src/share/vm/ci/ciObjArray.cpp
src/share/vm/ci/ciObjArray.cpp
+43
-0
src/share/vm/ci/ciObjArray.hpp
src/share/vm/ci/ciObjArray.hpp
+2
-0
src/share/vm/classfile/vmSymbols.hpp
src/share/vm/classfile/vmSymbols.hpp
+6
-0
src/share/vm/includeDB_core
src/share/vm/includeDB_core
+10
-5
src/share/vm/opto/addnode.cpp
src/share/vm/opto/addnode.cpp
+22
-0
src/share/vm/opto/addnode.hpp
src/share/vm/opto/addnode.hpp
+5
-0
src/share/vm/opto/c2_globals.hpp
src/share/vm/opto/c2_globals.hpp
+6
-0
src/share/vm/opto/cfgnode.hpp
src/share/vm/opto/cfgnode.hpp
+6
-0
src/share/vm/opto/ifnode.cpp
src/share/vm/opto/ifnode.cpp
+158
-0
src/share/vm/opto/loopnode.cpp
src/share/vm/opto/loopnode.cpp
+1
-54
src/share/vm/opto/loopnode.hpp
src/share/vm/opto/loopnode.hpp
+0
-1
src/share/vm/opto/memnode.cpp
src/share/vm/opto/memnode.cpp
+224
-0
src/share/vm/opto/memnode.hpp
src/share/vm/opto/memnode.hpp
+3
-0
src/share/vm/opto/parse2.cpp
src/share/vm/opto/parse2.cpp
+36
-7
src/share/vm/opto/type.hpp
src/share/vm/opto/type.hpp
+2
-0
src/share/vm/runtime/arguments.cpp
src/share/vm/runtime/arguments.cpp
+16
-0
未找到文件。
src/share/vm/ci/ciObjArray.cpp
0 → 100644
浏览文件 @
b85595b7
/*
* Copyright 1999-2007 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.
*
*/
#include "incls/_precompiled.incl"
#include "incls/_ciObjArray.cpp.incl"
// ciObjArray
//
// This class represents an objArrayOop in the HotSpot virtual
// machine.
ciObject
*
ciObjArray
::
obj_at
(
int
index
)
{
VM_ENTRY_MARK
;
objArrayOop
array
=
get_objArrayOop
();
if
(
index
<
0
||
index
>=
array
->
length
())
return
NULL
;
oop
o
=
array
->
obj_at
(
index
);
if
(
o
==
NULL
)
{
return
ciNullObject
::
make
();
}
else
{
return
CURRENT_ENV
->
get_object
(
o
);
}
}
src/share/vm/ci/ciObjArray.hpp
浏览文件 @
b85595b7
...
@@ -43,4 +43,6 @@ protected:
...
@@ -43,4 +43,6 @@ protected:
public:
public:
// What kind of ciObject is this?
// What kind of ciObject is this?
bool
is_obj_array
()
{
return
true
;
}
bool
is_obj_array
()
{
return
true
;
}
ciObject
*
obj_at
(
int
index
);
};
};
src/share/vm/classfile/vmSymbols.hpp
浏览文件 @
b85595b7
...
@@ -58,12 +58,17 @@
...
@@ -58,12 +58,17 @@
template(java_lang_ThreadDeath, "java/lang/ThreadDeath") \
template(java_lang_ThreadDeath, "java/lang/ThreadDeath") \
template(java_lang_Boolean, "java/lang/Boolean") \
template(java_lang_Boolean, "java/lang/Boolean") \
template(java_lang_Character, "java/lang/Character") \
template(java_lang_Character, "java/lang/Character") \
template(java_lang_Character_CharacterCache, "java/lang/Character$CharacterCache") \
template(java_lang_Float, "java/lang/Float") \
template(java_lang_Float, "java/lang/Float") \
template(java_lang_Double, "java/lang/Double") \
template(java_lang_Double, "java/lang/Double") \
template(java_lang_Byte, "java/lang/Byte") \
template(java_lang_Byte, "java/lang/Byte") \
template(java_lang_Byte_Cache, "java/lang/Byte$ByteCache") \
template(java_lang_Short, "java/lang/Short") \
template(java_lang_Short, "java/lang/Short") \
template(java_lang_Short_ShortCache, "java/lang/Short$ShortCache") \
template(java_lang_Integer, "java/lang/Integer") \
template(java_lang_Integer, "java/lang/Integer") \
template(java_lang_Integer_IntegerCache, "java/lang/Integer$IntegerCache") \
template(java_lang_Long, "java/lang/Long") \
template(java_lang_Long, "java/lang/Long") \
template(java_lang_Long_LongCache, "java/lang/Long$LongCache") \
template(java_lang_Shutdown, "java/lang/Shutdown") \
template(java_lang_Shutdown, "java/lang/Shutdown") \
template(java_lang_ref_Reference, "java/lang/ref/Reference") \
template(java_lang_ref_Reference, "java/lang/ref/Reference") \
template(java_lang_ref_SoftReference, "java/lang/ref/SoftReference") \
template(java_lang_ref_SoftReference, "java/lang/ref/SoftReference") \
...
@@ -274,6 +279,7 @@
...
@@ -274,6 +279,7 @@
template(exclusive_owner_thread_name, "exclusiveOwnerThread") \
template(exclusive_owner_thread_name, "exclusiveOwnerThread") \
template(park_blocker_name, "parkBlocker") \
template(park_blocker_name, "parkBlocker") \
template(park_event_name, "nativeParkEventPointer") \
template(park_event_name, "nativeParkEventPointer") \
template(cache_field_name, "cache") \
template(value_name, "value") \
template(value_name, "value") \
\
\
/* non-intrinsic name/signature pairs: */
\
/* non-intrinsic name/signature pairs: */
\
...
...
src/share/vm/includeDB_core
浏览文件 @
b85595b7
...
@@ -19,7 +19,7 @@
...
@@ -19,7 +19,7 @@
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// CA 95054 USA or visit www.sun.com if you need additional information or
// have any questions.
// have any questions.
//
//
//
//
// NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps!
// NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps!
...
@@ -46,13 +46,13 @@
...
@@ -46,13 +46,13 @@
// as dependencies. Header files named H.inline.hpp generally contain
// as dependencies. Header files named H.inline.hpp generally contain
// bodies for inline functions declared in H.hpp.
// bodies for inline functions declared in H.hpp.
//
//
// NOTE: Files that use the token "generate_platform_dependent_include"
// NOTE: Files that use the token "generate_platform_dependent_include"
// are expected to contain macro references like <os>, <arch_model>, ... and
// are expected to contain macro references like <os>, <arch_model>, ... and
// makedeps has a dependency on these platform files looking like:
// makedeps has a dependency on these platform files looking like:
// foo_<macro>.trailing_string
// foo_<macro>.trailing_string
// (where "trailing_string" can be any legal filename strings but typically
// (where "trailing_string" can be any legal filename strings but typically
// is "hpp" or "inline.hpp").
// is "hpp" or "inline.hpp").
//
//
// The dependency in makedeps (and enforced) is that an underscore
// The dependency in makedeps (and enforced) is that an underscore
// will precedure the macro invocation. Note that this restriction
// will precedure the macro invocation. Note that this restriction
// is only enforced on filenames that have the dependency token
// is only enforced on filenames that have the dependency token
...
@@ -720,6 +720,11 @@ ciObjArray.hpp ciArray.hpp
...
@@ -720,6 +720,11 @@ ciObjArray.hpp ciArray.hpp
ciObjArray.hpp ciClassList.hpp
ciObjArray.hpp ciClassList.hpp
ciObjArray.hpp objArrayOop.hpp
ciObjArray.hpp objArrayOop.hpp
ciObjArray.cpp ciObjArray.hpp
ciObjArray.cpp ciNullObject.hpp
ciObjArray.cpp ciUtilities.hpp
ciObjArray.cpp objArrayOop.hpp
ciObjArrayKlass.cpp ciInstanceKlass.hpp
ciObjArrayKlass.cpp ciInstanceKlass.hpp
ciObjArrayKlass.cpp ciObjArrayKlass.hpp
ciObjArrayKlass.cpp ciObjArrayKlass.hpp
ciObjArrayKlass.cpp ciObjArrayKlassKlass.hpp
ciObjArrayKlass.cpp ciObjArrayKlassKlass.hpp
...
@@ -1935,7 +1940,7 @@ icache_<arch>.hpp generate_platform_dependent_include
...
@@ -1935,7 +1940,7 @@ icache_<arch>.hpp generate_platform_dependent_include
init.cpp bytecodes.hpp
init.cpp bytecodes.hpp
init.cpp collectedHeap.hpp
init.cpp collectedHeap.hpp
init.cpp
handles.inline.hpp
init.cpp
handles.inline.hpp
init.cpp icBuffer.hpp
init.cpp icBuffer.hpp
init.cpp icache.hpp
init.cpp icache.hpp
init.cpp init.hpp
init.cpp init.hpp
...
...
src/share/vm/opto/addnode.cpp
浏览文件 @
b85595b7
...
@@ -608,6 +608,28 @@ Node* AddPNode::Ideal_base_and_offset(Node* ptr, PhaseTransform* phase,
...
@@ -608,6 +608,28 @@ Node* AddPNode::Ideal_base_and_offset(Node* ptr, PhaseTransform* phase,
return
NULL
;
return
NULL
;
}
}
//------------------------------unpack_offsets----------------------------------
// Collect the AddP offset values into the elements array, giving up
// if there are more than length.
int
AddPNode
::
unpack_offsets
(
Node
*
elements
[],
int
length
)
{
int
count
=
0
;
Node
*
addr
=
this
;
Node
*
base
=
addr
->
in
(
AddPNode
::
Base
);
while
(
addr
->
is_AddP
())
{
if
(
addr
->
in
(
AddPNode
::
Base
)
!=
base
)
{
// give up
return
-
1
;
}
elements
[
count
++
]
=
addr
->
in
(
AddPNode
::
Offset
);
if
(
count
==
length
)
{
// give up
return
-
1
;
}
addr
=
addr
->
in
(
AddPNode
::
Address
);
}
return
count
;
}
//------------------------------match_edge-------------------------------------
//------------------------------match_edge-------------------------------------
// Do we Match on this edge index or not? Do not match base pointer edge
// Do we Match on this edge index or not? Do not match base pointer edge
uint
AddPNode
::
match_edge
(
uint
idx
)
const
{
uint
AddPNode
::
match_edge
(
uint
idx
)
const
{
...
...
src/share/vm/opto/addnode.hpp
浏览文件 @
b85595b7
...
@@ -144,6 +144,11 @@ public:
...
@@ -144,6 +144,11 @@ public:
static
Node
*
Ideal_base_and_offset
(
Node
*
ptr
,
PhaseTransform
*
phase
,
static
Node
*
Ideal_base_and_offset
(
Node
*
ptr
,
PhaseTransform
*
phase
,
// second return value:
// second return value:
intptr_t
&
offset
);
intptr_t
&
offset
);
// Collect the AddP offset values into the elements array, giving up
// if there are more than length.
int
unpack_offsets
(
Node
*
elements
[],
int
length
);
// Do not match base-ptr edge
// Do not match base-ptr edge
virtual
uint
match_edge
(
uint
idx
)
const
;
virtual
uint
match_edge
(
uint
idx
)
const
;
static
const
Type
*
mach_bottom_type
(
const
MachNode
*
n
);
// used by ad_<arch>.hpp
static
const
Type
*
mach_bottom_type
(
const
MachNode
*
n
);
// used by ad_<arch>.hpp
...
...
src/share/vm/opto/c2_globals.hpp
浏览文件 @
b85595b7
...
@@ -367,6 +367,12 @@
...
@@ -367,6 +367,12 @@
notproduct(bool, PrintEliminateLocks, false, \
notproduct(bool, PrintEliminateLocks, false, \
"Print out when locks are eliminated") \
"Print out when locks are eliminated") \
\
\
diagnostic(bool, EliminateAutoBox, false, \
"Private flag to control optimizations for autobox elimination") \
\
product(intx, AutoBoxCacheMax, 128, \
"Sets max value cached by the java.lang.Integer autobox cache") \
\
product(bool, DoEscapeAnalysis, false, \
product(bool, DoEscapeAnalysis, false, \
"Perform escape analysis") \
"Perform escape analysis") \
\
\
...
...
src/share/vm/opto/cfgnode.hpp
浏览文件 @
b85595b7
...
@@ -310,8 +310,14 @@ public:
...
@@ -310,8 +310,14 @@ public:
virtual
const
RegMask
&
out_RegMask
()
const
;
virtual
const
RegMask
&
out_RegMask
()
const
;
void
dominated_by
(
Node
*
prev_dom
,
PhaseIterGVN
*
igvn
);
void
dominated_by
(
Node
*
prev_dom
,
PhaseIterGVN
*
igvn
);
int
is_range_check
(
Node
*
&
range
,
Node
*
&
index
,
jint
&
offset
);
int
is_range_check
(
Node
*
&
range
,
Node
*
&
index
,
jint
&
offset
);
Node
*
fold_compares
(
PhaseGVN
*
phase
);
static
Node
*
up_one_dom
(
Node
*
curr
,
bool
linear_only
=
false
);
static
Node
*
up_one_dom
(
Node
*
curr
,
bool
linear_only
=
false
);
// Takes the type of val and filters it through the test represented
// by if_proj and returns a more refined type if one is produced.
// Returns NULL is it couldn't improve the type.
static
const
TypeInt
*
filtered_int_type
(
PhaseGVN
*
phase
,
Node
*
val
,
Node
*
if_proj
);
#ifndef PRODUCT
#ifndef PRODUCT
virtual
void
dump_spec
(
outputStream
*
st
)
const
;
virtual
void
dump_spec
(
outputStream
*
st
)
const
;
#endif
#endif
...
...
src/share/vm/opto/ifnode.cpp
浏览文件 @
b85595b7
...
@@ -543,6 +543,159 @@ Node* IfNode::up_one_dom(Node *curr, bool linear_only) {
...
@@ -543,6 +543,159 @@ Node* IfNode::up_one_dom(Node *curr, bool linear_only) {
return
NULL
;
// Dead loop? Or hit root?
return
NULL
;
// Dead loop? Or hit root?
}
}
//------------------------------filtered_int_type--------------------------------
// Return a possibly more restrictive type for val based on condition control flow for an if
const
TypeInt
*
IfNode
::
filtered_int_type
(
PhaseGVN
*
gvn
,
Node
*
val
,
Node
*
if_proj
)
{
assert
(
if_proj
&&
(
if_proj
->
Opcode
()
==
Op_IfTrue
||
if_proj
->
Opcode
()
==
Op_IfFalse
),
"expecting an if projection"
);
if
(
if_proj
->
in
(
0
)
&&
if_proj
->
in
(
0
)
->
is_If
())
{
IfNode
*
iff
=
if_proj
->
in
(
0
)
->
as_If
();
if
(
iff
->
in
(
1
)
&&
iff
->
in
(
1
)
->
is_Bool
())
{
BoolNode
*
bol
=
iff
->
in
(
1
)
->
as_Bool
();
if
(
bol
->
in
(
1
)
&&
bol
->
in
(
1
)
->
is_Cmp
())
{
const
CmpNode
*
cmp
=
bol
->
in
(
1
)
->
as_Cmp
();
if
(
cmp
->
in
(
1
)
==
val
)
{
const
TypeInt
*
cmp2_t
=
gvn
->
type
(
cmp
->
in
(
2
))
->
isa_int
();
if
(
cmp2_t
!=
NULL
)
{
jint
lo
=
cmp2_t
->
_lo
;
jint
hi
=
cmp2_t
->
_hi
;
BoolTest
::
mask
msk
=
if_proj
->
Opcode
()
==
Op_IfTrue
?
bol
->
_test
.
_test
:
bol
->
_test
.
negate
();
switch
(
msk
)
{
case
BoolTest
::
ne
:
// Can't refine type
return
NULL
;
case
BoolTest
::
eq
:
return
cmp2_t
;
case
BoolTest
::
lt
:
lo
=
TypeInt
::
INT
->
_lo
;
if
(
hi
-
1
<
hi
)
{
hi
=
hi
-
1
;
}
break
;
case
BoolTest
::
le
:
lo
=
TypeInt
::
INT
->
_lo
;
break
;
case
BoolTest
::
gt
:
if
(
lo
+
1
>
lo
)
{
lo
=
lo
+
1
;
}
hi
=
TypeInt
::
INT
->
_hi
;
break
;
case
BoolTest
::
ge
:
// lo unchanged
hi
=
TypeInt
::
INT
->
_hi
;
break
;
}
const
TypeInt
*
rtn_t
=
TypeInt
::
make
(
lo
,
hi
,
cmp2_t
->
_widen
);
return
rtn_t
;
}
}
}
}
}
return
NULL
;
}
//------------------------------fold_compares----------------------------
// See if a pair of CmpIs can be converted into a CmpU. In some cases
// the direction of this if is determined by the preciding if so it
// can be eliminate entirely. Given an if testing (CmpI n c) check
// for an immediately control dependent if that is testing (CmpI n c2)
// and has one projection leading to this if and the other projection
// leading to a region that merges one of this ifs control
// projections.
//
// If
// / |
// / |
// / |
// If |
// /\ |
// / \ |
// / \ |
// / Region
//
Node
*
IfNode
::
fold_compares
(
PhaseGVN
*
phase
)
{
if
(
!
EliminateAutoBox
||
Opcode
()
!=
Op_If
)
return
NULL
;
Node
*
this_cmp
=
in
(
1
)
->
in
(
1
);
if
(
this_cmp
!=
NULL
&&
this_cmp
->
Opcode
()
==
Op_CmpI
&&
this_cmp
->
in
(
2
)
->
is_Con
()
&&
this_cmp
->
in
(
2
)
!=
phase
->
C
->
top
())
{
Node
*
ctrl
=
in
(
0
);
BoolNode
*
this_bool
=
in
(
1
)
->
as_Bool
();
Node
*
n
=
this_cmp
->
in
(
1
);
int
hi
=
this_cmp
->
in
(
2
)
->
get_int
();
if
(
ctrl
!=
NULL
&&
ctrl
->
is_Proj
()
&&
ctrl
->
outcnt
()
==
1
&&
ctrl
->
in
(
0
)
->
is_If
()
&&
ctrl
->
in
(
0
)
->
outcnt
()
==
2
&&
ctrl
->
in
(
0
)
->
in
(
1
)
->
is_Bool
()
&&
ctrl
->
in
(
0
)
->
in
(
1
)
->
in
(
1
)
->
Opcode
()
==
Op_CmpI
&&
ctrl
->
in
(
0
)
->
in
(
1
)
->
in
(
1
)
->
in
(
2
)
->
is_Con
()
&&
ctrl
->
in
(
0
)
->
in
(
1
)
->
in
(
1
)
->
in
(
1
)
==
n
)
{
IfNode
*
dom_iff
=
ctrl
->
in
(
0
)
->
as_If
();
Node
*
otherproj
=
dom_iff
->
proj_out
(
!
ctrl
->
as_Proj
()
->
_con
);
if
(
otherproj
->
outcnt
()
==
1
&&
otherproj
->
unique_out
()
->
is_Region
()
&&
this_bool
->
_test
.
_test
!=
BoolTest
::
ne
&&
this_bool
->
_test
.
_test
!=
BoolTest
::
eq
)
{
// Identify which proj goes to the region and which continues on
RegionNode
*
region
=
otherproj
->
unique_out
()
->
as_Region
();
Node
*
success
=
NULL
;
Node
*
fail
=
NULL
;
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
Node
*
proj
=
proj_out
(
i
);
if
(
success
==
NULL
&&
proj
->
outcnt
()
==
1
&&
proj
->
unique_out
()
==
region
)
{
success
=
proj
;
}
else
if
(
fail
==
NULL
)
{
fail
=
proj
;
}
else
{
success
=
fail
=
NULL
;
}
}
if
(
success
!=
NULL
&&
fail
!=
NULL
&&
!
region
->
has_phi
())
{
int
lo
=
dom_iff
->
in
(
1
)
->
in
(
1
)
->
in
(
2
)
->
get_int
();
BoolNode
*
dom_bool
=
dom_iff
->
in
(
1
)
->
as_Bool
();
Node
*
dom_cmp
=
dom_bool
->
in
(
1
);
const
TypeInt
*
failtype
=
filtered_int_type
(
phase
,
n
,
ctrl
);
if
(
failtype
!=
NULL
)
{
const
TypeInt
*
type2
=
filtered_int_type
(
phase
,
n
,
fail
);
if
(
type2
!=
NULL
)
{
failtype
=
failtype
->
join
(
type2
)
->
is_int
();
}
else
{
failtype
=
NULL
;
}
}
if
(
failtype
!=
NULL
&&
dom_bool
->
_test
.
_test
!=
BoolTest
::
ne
&&
dom_bool
->
_test
.
_test
!=
BoolTest
::
eq
)
{
int
bound
=
failtype
->
_hi
-
failtype
->
_lo
+
1
;
if
(
failtype
->
_hi
!=
max_jint
&&
failtype
->
_lo
!=
min_jint
&&
bound
>
1
)
{
// Merge the two compares into a single unsigned compare by building (CmpU (n - lo) hi)
BoolTest
::
mask
cond
=
fail
->
as_Proj
()
->
_con
?
BoolTest
::
lt
:
BoolTest
::
ge
;
Node
*
adjusted
=
phase
->
transform
(
new
(
phase
->
C
,
3
)
SubINode
(
n
,
phase
->
intcon
(
failtype
->
_lo
)));
Node
*
newcmp
=
phase
->
transform
(
new
(
phase
->
C
,
3
)
CmpUNode
(
adjusted
,
phase
->
intcon
(
bound
)));
Node
*
newbool
=
phase
->
transform
(
new
(
phase
->
C
,
2
)
BoolNode
(
newcmp
,
cond
));
phase
->
hash_delete
(
dom_iff
);
dom_iff
->
set_req
(
1
,
phase
->
intcon
(
ctrl
->
as_Proj
()
->
_con
));
phase
->
is_IterGVN
()
->
_worklist
.
push
(
dom_iff
);
phase
->
hash_delete
(
this
);
set_req
(
1
,
newbool
);
return
this
;
}
if
(
failtype
->
_lo
>
failtype
->
_hi
)
{
// previous if determines the result of this if so
// replace Bool with constant
phase
->
hash_delete
(
this
);
set_req
(
1
,
phase
->
intcon
(
success
->
as_Proj
()
->
_con
));
return
this
;
}
}
}
}
}
}
return
NULL
;
}
//------------------------------remove_useless_bool----------------------------
//------------------------------remove_useless_bool----------------------------
// Check for people making a useless boolean: things like
// Check for people making a useless boolean: things like
// if( (x < y ? true : false) ) { ... }
// if( (x < y ? true : false) ) { ... }
...
@@ -744,6 +897,11 @@ Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) {
...
@@ -744,6 +897,11 @@ Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Normal equivalent-test check.
// Normal equivalent-test check.
if
(
!
dom
)
return
NULL
;
// Dead loop?
if
(
!
dom
)
return
NULL
;
// Dead loop?
Node
*
result
=
fold_compares
(
phase
);
if
(
result
!=
NULL
)
{
return
result
;
}
// Search up the dominator tree for an If with an identical test
// Search up the dominator tree for an If with an identical test
while
(
dom
->
Opcode
()
!=
op
||
// Not same opcode?
while
(
dom
->
Opcode
()
!=
op
||
// Not same opcode?
dom
->
in
(
1
)
!=
in
(
1
)
||
// Not same input 1?
dom
->
in
(
1
)
!=
in
(
1
)
||
// Not same input 1?
...
...
src/share/vm/opto/loopnode.cpp
浏览文件 @
b85595b7
...
@@ -651,7 +651,7 @@ const TypeInt* PhaseIdealLoop::filtered_type_from_dominators( Node* val, Node *u
...
@@ -651,7 +651,7 @@ const TypeInt* PhaseIdealLoop::filtered_type_from_dominators( Node* val, Node *u
while
(
if_cnt
<
if_limit
)
{
while
(
if_cnt
<
if_limit
)
{
if
((
pred
->
Opcode
()
==
Op_IfTrue
||
pred
->
Opcode
()
==
Op_IfFalse
))
{
if
((
pred
->
Opcode
()
==
Op_IfTrue
||
pred
->
Opcode
()
==
Op_IfFalse
))
{
if_cnt
++
;
if_cnt
++
;
const
TypeInt
*
if_t
=
filtered_type_at_if
(
val
,
pred
);
const
TypeInt
*
if_t
=
IfNode
::
filtered_int_type
(
&
_igvn
,
val
,
pred
);
if
(
if_t
!=
NULL
)
{
if
(
if_t
!=
NULL
)
{
if
(
rtn_t
==
NULL
)
{
if
(
rtn_t
==
NULL
)
{
rtn_t
=
if_t
;
rtn_t
=
if_t
;
...
@@ -674,59 +674,6 @@ const TypeInt* PhaseIdealLoop::filtered_type_from_dominators( Node* val, Node *u
...
@@ -674,59 +674,6 @@ const TypeInt* PhaseIdealLoop::filtered_type_from_dominators( Node* val, Node *u
}
}
//------------------------------filtered_type_at_if--------------------------------
// Return a possibly more restrictive type for val based on condition control flow for an if
const
TypeInt
*
PhaseIdealLoop
::
filtered_type_at_if
(
Node
*
val
,
Node
*
if_proj
)
{
assert
(
if_proj
&&
(
if_proj
->
Opcode
()
==
Op_IfTrue
||
if_proj
->
Opcode
()
==
Op_IfFalse
),
"expecting an if projection"
);
if
(
if_proj
->
in
(
0
)
&&
if_proj
->
in
(
0
)
->
is_If
())
{
IfNode
*
iff
=
if_proj
->
in
(
0
)
->
as_If
();
if
(
iff
->
in
(
1
)
&&
iff
->
in
(
1
)
->
is_Bool
())
{
BoolNode
*
bol
=
iff
->
in
(
1
)
->
as_Bool
();
if
(
bol
->
in
(
1
)
&&
bol
->
in
(
1
)
->
is_Cmp
())
{
const
CmpNode
*
cmp
=
bol
->
in
(
1
)
->
as_Cmp
();
if
(
cmp
->
in
(
1
)
==
val
)
{
const
TypeInt
*
cmp2_t
=
_igvn
.
type
(
cmp
->
in
(
2
))
->
isa_int
();
if
(
cmp2_t
!=
NULL
)
{
jint
lo
=
cmp2_t
->
_lo
;
jint
hi
=
cmp2_t
->
_hi
;
BoolTest
::
mask
msk
=
if_proj
->
Opcode
()
==
Op_IfTrue
?
bol
->
_test
.
_test
:
bol
->
_test
.
negate
();
switch
(
msk
)
{
case
BoolTest
::
ne
:
// Can't refine type
return
NULL
;
case
BoolTest
::
eq
:
return
cmp2_t
;
case
BoolTest
::
lt
:
lo
=
TypeInt
::
INT
->
_lo
;
if
(
hi
-
1
<
hi
)
{
hi
=
hi
-
1
;
}
break
;
case
BoolTest
::
le
:
lo
=
TypeInt
::
INT
->
_lo
;
break
;
case
BoolTest
::
gt
:
if
(
lo
+
1
>
lo
)
{
lo
=
lo
+
1
;
}
hi
=
TypeInt
::
INT
->
_hi
;
break
;
case
BoolTest
::
ge
:
// lo unchanged
hi
=
TypeInt
::
INT
->
_hi
;
break
;
}
const
TypeInt
*
rtn_t
=
TypeInt
::
make
(
lo
,
hi
,
cmp2_t
->
_widen
);
return
rtn_t
;
}
}
}
}
}
return
NULL
;
}
//------------------------------dump_spec--------------------------------------
//------------------------------dump_spec--------------------------------------
// Dump special per-node info
// Dump special per-node info
#ifndef PRODUCT
#ifndef PRODUCT
...
...
src/share/vm/opto/loopnode.hpp
浏览文件 @
b85595b7
...
@@ -850,7 +850,6 @@ private:
...
@@ -850,7 +850,6 @@ private:
const
TypeInt
*
filtered_type
(
Node
*
n
)
{
return
filtered_type
(
n
,
NULL
);
}
const
TypeInt
*
filtered_type
(
Node
*
n
)
{
return
filtered_type
(
n
,
NULL
);
}
// Helpers for filtered type
// Helpers for filtered type
const
TypeInt
*
filtered_type_from_dominators
(
Node
*
val
,
Node
*
val_ctrl
);
const
TypeInt
*
filtered_type_from_dominators
(
Node
*
val
,
Node
*
val_ctrl
);
const
TypeInt
*
filtered_type_at_if
(
Node
*
val
,
Node
*
if_proj
);
// Helper functions
// Helper functions
void
register_new_node
(
Node
*
n
,
Node
*
blk
);
void
register_new_node
(
Node
*
n
,
Node
*
blk
);
...
...
src/share/vm/opto/memnode.cpp
浏览文件 @
b85595b7
...
@@ -634,6 +634,46 @@ uint LoadNode::hash() const {
...
@@ -634,6 +634,46 @@ uint LoadNode::hash() const {
Node
*
MemNode
::
can_see_stored_value
(
Node
*
st
,
PhaseTransform
*
phase
)
const
{
Node
*
MemNode
::
can_see_stored_value
(
Node
*
st
,
PhaseTransform
*
phase
)
const
{
Node
*
ld_adr
=
in
(
MemNode
::
Address
);
Node
*
ld_adr
=
in
(
MemNode
::
Address
);
const
TypeInstPtr
*
tp
=
phase
->
type
(
ld_adr
)
->
isa_instptr
();
Compile
::
AliasType
*
atp
=
tp
!=
NULL
?
phase
->
C
->
alias_type
(
tp
)
:
NULL
;
if
(
EliminateAutoBox
&&
atp
!=
NULL
&&
atp
->
index
()
>=
Compile
::
AliasIdxRaw
&&
atp
->
field
()
!=
NULL
&&
!
atp
->
field
()
->
is_volatile
())
{
uint
alias_idx
=
atp
->
index
();
bool
final
=
atp
->
field
()
->
is_final
();
Node
*
result
=
NULL
;
Node
*
current
=
st
;
// Skip through chains of MemBarNodes checking the MergeMems for
// new states for the slice of this load. Stop once any other
// kind of node is encountered. Loads from final memory can skip
// through any kind of MemBar but normal loads shouldn't skip
// through MemBarAcquire since the could allow them to move out of
// a synchronized region.
while
(
current
->
is_Proj
())
{
int
opc
=
current
->
in
(
0
)
->
Opcode
();
if
((
final
&&
opc
==
Op_MemBarAcquire
)
||
opc
==
Op_MemBarRelease
||
opc
==
Op_MemBarCPUOrder
)
{
Node
*
mem
=
current
->
in
(
0
)
->
in
(
TypeFunc
::
Memory
);
if
(
mem
->
is_MergeMem
())
{
MergeMemNode
*
merge
=
mem
->
as_MergeMem
();
Node
*
new_st
=
merge
->
memory_at
(
alias_idx
);
if
(
new_st
==
merge
->
base_memory
())
{
// Keep searching
current
=
merge
->
base_memory
();
continue
;
}
// Save the new memory state for the slice and fall through
// to exit.
result
=
new_st
;
}
}
break
;
}
if
(
result
!=
NULL
)
{
st
=
result
;
}
}
// Loop around twice in the case Load -> Initialize -> Store.
// Loop around twice in the case Load -> Initialize -> Store.
// (See PhaseIterGVN::add_users_to_worklist, which knows about this case.)
// (See PhaseIterGVN::add_users_to_worklist, which knows about this case.)
for
(
int
trip
=
0
;
trip
<=
1
;
trip
++
)
{
for
(
int
trip
=
0
;
trip
<=
1
;
trip
++
)
{
...
@@ -723,6 +763,168 @@ Node *LoadNode::Identity( PhaseTransform *phase ) {
...
@@ -723,6 +763,168 @@ Node *LoadNode::Identity( PhaseTransform *phase ) {
return
this
;
return
this
;
}
}
// Returns true if the AliasType refers to the field that holds the
// cached box array. Currently only handles the IntegerCache case.
static
bool
is_autobox_cache
(
Compile
::
AliasType
*
atp
)
{
if
(
atp
!=
NULL
&&
atp
->
field
()
!=
NULL
)
{
ciField
*
field
=
atp
->
field
();
ciSymbol
*
klass
=
field
->
holder
()
->
name
();
if
(
field
->
name
()
==
ciSymbol
::
cache_field_name
()
&&
field
->
holder
()
->
uses_default_loader
()
&&
klass
==
ciSymbol
::
java_lang_Integer_IntegerCache
())
{
return
true
;
}
}
return
false
;
}
// Fetch the base value in the autobox array
static
bool
fetch_autobox_base
(
Compile
::
AliasType
*
atp
,
int
&
cache_offset
)
{
if
(
atp
!=
NULL
&&
atp
->
field
()
!=
NULL
)
{
ciField
*
field
=
atp
->
field
();
ciSymbol
*
klass
=
field
->
holder
()
->
name
();
if
(
field
->
name
()
==
ciSymbol
::
cache_field_name
()
&&
field
->
holder
()
->
uses_default_loader
()
&&
klass
==
ciSymbol
::
java_lang_Integer_IntegerCache
())
{
assert
(
field
->
is_constant
(),
"what?"
);
ciObjArray
*
array
=
field
->
constant_value
().
as_object
()
->
as_obj_array
();
// Fetch the box object at the base of the array and get its value
ciInstance
*
box
=
array
->
obj_at
(
0
)
->
as_instance
();
ciInstanceKlass
*
ik
=
box
->
klass
()
->
as_instance_klass
();
if
(
ik
->
nof_nonstatic_fields
()
==
1
)
{
// This should be true nonstatic_field_at requires calling
// nof_nonstatic_fields so check it anyway
ciConstant
c
=
box
->
field_value
(
ik
->
nonstatic_field_at
(
0
));
cache_offset
=
c
.
as_int
();
}
return
true
;
}
}
return
false
;
}
// Returns true if the AliasType refers to the value field of an
// autobox object. Currently only handles Integer.
static
bool
is_autobox_object
(
Compile
::
AliasType
*
atp
)
{
if
(
atp
!=
NULL
&&
atp
->
field
()
!=
NULL
)
{
ciField
*
field
=
atp
->
field
();
ciSymbol
*
klass
=
field
->
holder
()
->
name
();
if
(
field
->
name
()
==
ciSymbol
::
value_name
()
&&
field
->
holder
()
->
uses_default_loader
()
&&
klass
==
ciSymbol
::
java_lang_Integer
())
{
return
true
;
}
}
return
false
;
}
// We're loading from an object which has autobox behaviour.
// If this object is result of a valueOf call we'll have a phi
// merging a newly allocated object and a load from the cache.
// We want to replace this load with the original incoming
// argument to the valueOf call.
Node
*
LoadNode
::
eliminate_autobox
(
PhaseGVN
*
phase
)
{
Node
*
base
=
in
(
Address
)
->
in
(
AddPNode
::
Base
);
if
(
base
->
is_Phi
()
&&
base
->
req
()
==
3
)
{
AllocateNode
*
allocation
=
NULL
;
int
allocation_index
=
-
1
;
int
load_index
=
-
1
;
for
(
uint
i
=
1
;
i
<
base
->
req
();
i
++
)
{
allocation
=
AllocateNode
::
Ideal_allocation
(
base
->
in
(
i
),
phase
);
if
(
allocation
!=
NULL
)
{
allocation_index
=
i
;
load_index
=
3
-
allocation_index
;
break
;
}
}
LoadNode
*
load
=
NULL
;
if
(
allocation
!=
NULL
&&
base
->
in
(
load_index
)
->
is_Load
())
{
load
=
base
->
in
(
load_index
)
->
as_Load
();
}
if
(
load
!=
NULL
&&
in
(
Memory
)
->
is_Phi
()
&&
in
(
Memory
)
->
in
(
0
)
==
base
->
in
(
0
))
{
// Push the loads from the phi that comes from valueOf up
// through it to allow elimination of the loads and the recovery
// of the original value.
Node
*
mem_phi
=
in
(
Memory
);
Node
*
offset
=
in
(
Address
)
->
in
(
AddPNode
::
Offset
);
Node
*
in1
=
clone
();
Node
*
in1_addr
=
in1
->
in
(
Address
)
->
clone
();
in1_addr
->
set_req
(
AddPNode
::
Base
,
base
->
in
(
allocation_index
));
in1_addr
->
set_req
(
AddPNode
::
Address
,
base
->
in
(
allocation_index
));
in1_addr
->
set_req
(
AddPNode
::
Offset
,
offset
);
in1
->
set_req
(
0
,
base
->
in
(
allocation_index
));
in1
->
set_req
(
Address
,
in1_addr
);
in1
->
set_req
(
Memory
,
mem_phi
->
in
(
allocation_index
));
Node
*
in2
=
clone
();
Node
*
in2_addr
=
in2
->
in
(
Address
)
->
clone
();
in2_addr
->
set_req
(
AddPNode
::
Base
,
base
->
in
(
load_index
));
in2_addr
->
set_req
(
AddPNode
::
Address
,
base
->
in
(
load_index
));
in2_addr
->
set_req
(
AddPNode
::
Offset
,
offset
);
in2
->
set_req
(
0
,
base
->
in
(
load_index
));
in2
->
set_req
(
Address
,
in2_addr
);
in2
->
set_req
(
Memory
,
mem_phi
->
in
(
load_index
));
in1_addr
=
phase
->
transform
(
in1_addr
);
in1
=
phase
->
transform
(
in1
);
in2_addr
=
phase
->
transform
(
in2_addr
);
in2
=
phase
->
transform
(
in2
);
PhiNode
*
result
=
PhiNode
::
make_blank
(
base
->
in
(
0
),
this
);
result
->
set_req
(
allocation_index
,
in1
);
result
->
set_req
(
load_index
,
in2
);
return
result
;
}
}
else
if
(
base
->
is_Load
())
{
// Eliminate the load of Integer.value for integers from the cache
// array by deriving the value from the index into the array.
// Capture the offset of the load and then reverse the computation.
Node
*
load_base
=
base
->
in
(
Address
)
->
in
(
AddPNode
::
Base
);
if
(
load_base
!=
NULL
)
{
Compile
::
AliasType
*
atp
=
phase
->
C
->
alias_type
(
load_base
->
adr_type
());
intptr_t
cache_offset
;
int
shift
=
-
1
;
Node
*
cache
=
NULL
;
if
(
is_autobox_cache
(
atp
))
{
shift
=
exact_log2
(
type2aelembytes
[
T_OBJECT
]);
cache
=
AddPNode
::
Ideal_base_and_offset
(
load_base
->
in
(
Address
),
phase
,
cache_offset
);
}
if
(
cache
!=
NULL
&&
base
->
in
(
Address
)
->
is_AddP
())
{
Node
*
elements
[
4
];
int
count
=
base
->
in
(
Address
)
->
as_AddP
()
->
unpack_offsets
(
elements
,
ARRAY_SIZE
(
elements
));
int
cache_low
;
if
(
count
>
0
&&
fetch_autobox_base
(
atp
,
cache_low
))
{
int
offset
=
arrayOopDesc
::
base_offset_in_bytes
(
memory_type
())
-
(
cache_low
<<
shift
);
// Add up all the offsets making of the address of the load
Node
*
result
=
elements
[
0
];
for
(
int
i
=
1
;
i
<
count
;
i
++
)
{
result
=
phase
->
transform
(
new
(
phase
->
C
,
3
)
AddXNode
(
result
,
elements
[
i
]));
}
// Remove the constant offset from the address and then
// remove the scaling of the offset to recover the original index.
result
=
phase
->
transform
(
new
(
phase
->
C
,
3
)
AddXNode
(
result
,
phase
->
MakeConX
(
-
offset
)));
if
(
result
->
Opcode
()
==
Op_LShiftX
&&
result
->
in
(
2
)
==
phase
->
intcon
(
shift
))
{
// Peel the shift off directly but wrap it in a dummy node
// since Ideal can't return existing nodes
result
=
new
(
phase
->
C
,
3
)
RShiftXNode
(
result
->
in
(
1
),
phase
->
intcon
(
0
));
}
else
{
result
=
new
(
phase
->
C
,
3
)
RShiftXNode
(
result
,
phase
->
intcon
(
shift
));
}
#ifdef _LP64
result
=
new
(
phase
->
C
,
2
)
ConvL2INode
(
phase
->
transform
(
result
));
#endif
return
result
;
}
}
}
}
return
NULL
;
}
//------------------------------Ideal------------------------------------------
//------------------------------Ideal------------------------------------------
// If the load is from Field memory and the pointer is non-null, we can
// If the load is from Field memory and the pointer is non-null, we can
// zero out the control input.
// zero out the control input.
...
@@ -755,6 +957,17 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
...
@@ -755,6 +957,17 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
}
}
}
if
(
EliminateAutoBox
&&
can_reshape
&&
in
(
Address
)
->
is_AddP
())
{
Node
*
base
=
in
(
Address
)
->
in
(
AddPNode
::
Base
);
if
(
base
!=
NULL
)
{
Compile
::
AliasType
*
atp
=
phase
->
C
->
alias_type
(
adr_type
());
if
(
is_autobox_object
(
atp
))
{
Node
*
result
=
eliminate_autobox
(
phase
);
if
(
result
!=
NULL
)
return
result
;
}
}
}
// Check for prior store with a different base or offset; make Load
// Check for prior store with a different base or offset; make Load
// independent. Skip through any number of them. Bail out if the stores
// independent. Skip through any number of them. Bail out if the stores
// are in an endless dead cycle and report no progress. This is a key
// are in an endless dead cycle and report no progress. This is a key
...
@@ -858,6 +1071,17 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
...
@@ -858,6 +1071,17 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
// This can happen if a interface-typed array narrows to a class type.
// This can happen if a interface-typed array narrows to a class type.
jt
=
_type
;
jt
=
_type
;
}
}
if
(
EliminateAutoBox
)
{
// The pointers in the autobox arrays are always non-null
Node
*
base
=
in
(
Address
)
->
in
(
AddPNode
::
Base
);
if
(
base
!=
NULL
)
{
Compile
::
AliasType
*
atp
=
phase
->
C
->
alias_type
(
base
->
adr_type
());
if
(
is_autobox_cache
(
atp
))
{
return
jt
->
join
(
TypePtr
::
NOTNULL
)
->
is_ptr
();
}
}
}
return
jt
;
return
jt
;
}
}
}
}
...
...
src/share/vm/opto/memnode.hpp
浏览文件 @
b85595b7
...
@@ -141,6 +141,9 @@ public:
...
@@ -141,6 +141,9 @@ public:
// zero out the control input.
// zero out the control input.
virtual
Node
*
Ideal
(
PhaseGVN
*
phase
,
bool
can_reshape
);
virtual
Node
*
Ideal
(
PhaseGVN
*
phase
,
bool
can_reshape
);
// Recover original value from boxed values
Node
*
eliminate_autobox
(
PhaseGVN
*
phase
);
// Compute a new Type for this node. Basically we just do the pre-check,
// Compute a new Type for this node. Basically we just do the pre-check,
// then call the virtual add() to set the type.
// then call the virtual add() to set the type.
virtual
const
Type
*
Value
(
PhaseTransform
*
phase
)
const
;
virtual
const
Type
*
Value
(
PhaseTransform
*
phase
)
const
;
...
...
src/share/vm/opto/parse2.cpp
浏览文件 @
b85595b7
...
@@ -885,6 +885,9 @@ inline void Parse::repush_if_args() {
...
@@ -885,6 +885,9 @@ inline void Parse::repush_if_args() {
void
Parse
::
do_ifnull
(
BoolTest
::
mask
btest
)
{
void
Parse
::
do_ifnull
(
BoolTest
::
mask
btest
)
{
int
target_bci
=
iter
().
get_dest
();
int
target_bci
=
iter
().
get_dest
();
Block
*
branch_block
=
successor_for_bci
(
target_bci
);
Block
*
next_block
=
successor_for_bci
(
iter
().
next_bci
());
float
cnt
;
float
cnt
;
float
prob
=
branch_prediction
(
cnt
,
btest
,
target_bci
);
float
prob
=
branch_prediction
(
cnt
,
btest
,
target_bci
);
if
(
prob
==
PROB_UNKNOWN
)
{
if
(
prob
==
PROB_UNKNOWN
)
{
...
@@ -902,13 +905,16 @@ void Parse::do_ifnull(BoolTest::mask btest) {
...
@@ -902,13 +905,16 @@ void Parse::do_ifnull(BoolTest::mask btest) {
uncommon_trap
(
Deoptimization
::
Reason_unreached
,
uncommon_trap
(
Deoptimization
::
Reason_unreached
,
Deoptimization
::
Action_reinterpret
,
Deoptimization
::
Action_reinterpret
,
NULL
,
"cold"
);
NULL
,
"cold"
);
if
(
EliminateAutoBox
)
{
// Mark the successor blocks as parsed
branch_block
->
next_path_num
();
next_block
->
next_path_num
();
}
return
;
return
;
}
}
// If this is a backwards branch in the bytecodes, add Safepoint
// If this is a backwards branch in the bytecodes, add Safepoint
maybe_add_safepoint
(
target_bci
);
maybe_add_safepoint
(
target_bci
);
Block
*
branch_block
=
successor_for_bci
(
target_bci
);
Block
*
next_block
=
successor_for_bci
(
iter
().
next_bci
());
explicit_null_checks_inserted
++
;
explicit_null_checks_inserted
++
;
Node
*
a
=
null
();
Node
*
a
=
null
();
...
@@ -935,6 +941,10 @@ void Parse::do_ifnull(BoolTest::mask btest) {
...
@@ -935,6 +941,10 @@ void Parse::do_ifnull(BoolTest::mask btest) {
if
(
stopped
())
{
// Path is dead?
if
(
stopped
())
{
// Path is dead?
explicit_null_checks_elided
++
;
explicit_null_checks_elided
++
;
if
(
EliminateAutoBox
)
{
// Mark the successor block as parsed
branch_block
->
next_path_num
();
}
}
else
{
// Path is live.
}
else
{
// Path is live.
// Update method data
// Update method data
profile_taken_branch
(
target_bci
);
profile_taken_branch
(
target_bci
);
...
@@ -950,6 +960,10 @@ void Parse::do_ifnull(BoolTest::mask btest) {
...
@@ -950,6 +960,10 @@ void Parse::do_ifnull(BoolTest::mask btest) {
if
(
stopped
())
{
// Path is dead?
if
(
stopped
())
{
// Path is dead?
explicit_null_checks_elided
++
;
explicit_null_checks_elided
++
;
if
(
EliminateAutoBox
)
{
// Mark the successor block as parsed
next_block
->
next_path_num
();
}
}
else
{
// Path is live.
}
else
{
// Path is live.
// Update method data
// Update method data
profile_not_taken_branch
();
profile_not_taken_branch
();
...
@@ -962,6 +976,9 @@ void Parse::do_ifnull(BoolTest::mask btest) {
...
@@ -962,6 +976,9 @@ void Parse::do_ifnull(BoolTest::mask btest) {
void
Parse
::
do_if
(
BoolTest
::
mask
btest
,
Node
*
c
)
{
void
Parse
::
do_if
(
BoolTest
::
mask
btest
,
Node
*
c
)
{
int
target_bci
=
iter
().
get_dest
();
int
target_bci
=
iter
().
get_dest
();
Block
*
branch_block
=
successor_for_bci
(
target_bci
);
Block
*
next_block
=
successor_for_bci
(
iter
().
next_bci
());
float
cnt
;
float
cnt
;
float
prob
=
branch_prediction
(
cnt
,
btest
,
target_bci
);
float
prob
=
branch_prediction
(
cnt
,
btest
,
target_bci
);
float
untaken_prob
=
1.0
-
prob
;
float
untaken_prob
=
1.0
-
prob
;
...
@@ -980,6 +997,11 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
...
@@ -980,6 +997,11 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
uncommon_trap
(
Deoptimization
::
Reason_unreached
,
uncommon_trap
(
Deoptimization
::
Reason_unreached
,
Deoptimization
::
Action_reinterpret
,
Deoptimization
::
Action_reinterpret
,
NULL
,
"cold"
);
NULL
,
"cold"
);
if
(
EliminateAutoBox
)
{
// Mark the successor blocks as parsed
branch_block
->
next_path_num
();
next_block
->
next_path_num
();
}
return
;
return
;
}
}
...
@@ -1018,15 +1040,17 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
...
@@ -1018,15 +1040,17 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
untaken_branch
=
tmp
;
untaken_branch
=
tmp
;
}
}
Block
*
branch_block
=
successor_for_bci
(
target_bci
);
Block
*
next_block
=
successor_for_bci
(
iter
().
next_bci
());
// Branch is taken:
// Branch is taken:
{
PreserveJVMState
pjvms
(
this
);
{
PreserveJVMState
pjvms
(
this
);
taken_branch
=
_gvn
.
transform
(
taken_branch
);
taken_branch
=
_gvn
.
transform
(
taken_branch
);
set_control
(
taken_branch
);
set_control
(
taken_branch
);
if
(
!
stopped
())
{
if
(
stopped
())
{
if
(
EliminateAutoBox
)
{
// Mark the successor block as parsed
branch_block
->
next_path_num
();
}
}
else
{
// Update method data
// Update method data
profile_taken_branch
(
target_bci
);
profile_taken_branch
(
target_bci
);
adjust_map_after_if
(
taken_btest
,
c
,
prob
,
branch_block
,
next_block
);
adjust_map_after_if
(
taken_btest
,
c
,
prob
,
branch_block
,
next_block
);
...
@@ -1039,7 +1063,12 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
...
@@ -1039,7 +1063,12 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
set_control
(
untaken_branch
);
set_control
(
untaken_branch
);
// Branch not taken.
// Branch not taken.
if
(
!
stopped
())
{
if
(
stopped
())
{
if
(
EliminateAutoBox
)
{
// Mark the successor block as parsed
next_block
->
next_path_num
();
}
}
else
{
// Update method data
// Update method data
profile_not_taken_branch
();
profile_not_taken_branch
();
adjust_map_after_if
(
untaken_btest
,
c
,
untaken_prob
,
adjust_map_after_if
(
untaken_btest
,
c
,
untaken_prob
,
...
...
src/share/vm/opto/type.hpp
浏览文件 @
b85595b7
...
@@ -1070,6 +1070,7 @@ inline bool Type::is_floatingpoint() const {
...
@@ -1070,6 +1070,7 @@ inline bool Type::is_floatingpoint() const {
#define LShiftXNode LShiftLNode
#define LShiftXNode LShiftLNode
// For object size computation:
// For object size computation:
#define AddXNode AddLNode
#define AddXNode AddLNode
#define RShiftXNode RShiftLNode
// For card marks and hashcodes
// For card marks and hashcodes
#define URShiftXNode URShiftLNode
#define URShiftXNode URShiftLNode
// Opcodes
// Opcodes
...
@@ -1108,6 +1109,7 @@ inline bool Type::is_floatingpoint() const {
...
@@ -1108,6 +1109,7 @@ inline bool Type::is_floatingpoint() const {
#define LShiftXNode LShiftINode
#define LShiftXNode LShiftINode
// For object size computation:
// For object size computation:
#define AddXNode AddINode
#define AddXNode AddINode
#define RShiftXNode RShiftINode
// For card marks and hashcodes
// For card marks and hashcodes
#define URShiftXNode URShiftINode
#define URShiftXNode URShiftINode
// Opcodes
// Opcodes
...
...
src/share/vm/runtime/arguments.cpp
浏览文件 @
b85595b7
...
@@ -1254,6 +1254,22 @@ void Arguments::set_bytecode_flags() {
...
@@ -1254,6 +1254,22 @@ void Arguments::set_bytecode_flags() {
// Aggressive optimization flags -XX:+AggressiveOpts
// Aggressive optimization flags -XX:+AggressiveOpts
void
Arguments
::
set_aggressive_opts_flags
()
{
void
Arguments
::
set_aggressive_opts_flags
()
{
#ifdef COMPILER2
if
(
AggressiveOpts
||
!
FLAG_IS_DEFAULT
(
AutoBoxCacheMax
))
{
if
(
FLAG_IS_DEFAULT
(
EliminateAutoBox
))
{
FLAG_SET_DEFAULT
(
EliminateAutoBox
,
true
);
}
if
(
FLAG_IS_DEFAULT
(
AutoBoxCacheMax
))
{
FLAG_SET_DEFAULT
(
AutoBoxCacheMax
,
20000
);
}
// Feed the cache size setting into the JDK
char
buffer
[
1024
];
sprintf
(
buffer
,
"java.lang.Integer.IntegerCache.high=%d"
,
AutoBoxCacheMax
);
add_property
(
buffer
);
}
#endif
if
(
AggressiveOpts
)
{
if
(
AggressiveOpts
)
{
NOT_WINDOWS
(
NOT_WINDOWS
(
// No measured benefit on Windows
// No measured benefit on Windows
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录