Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
e0052d8a
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看板
提交
e0052d8a
编写于
4月 12, 2017
作者:
R
robm
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
3fd8a75d
6fcf6146
变更
22
显示空白变更内容
内联
并排
Showing
22 changed file
with
551 addition
and
228 deletion
+551
-228
src/cpu/sparc/vm/vm_version_sparc.cpp
src/cpu/sparc/vm/vm_version_sparc.cpp
+41
-4
src/cpu/sparc/vm/vm_version_sparc.hpp
src/cpu/sparc/vm/vm_version_sparc.hpp
+12
-8
src/cpu/x86/vm/vm_version_x86.cpp
src/cpu/x86/vm/vm_version_x86.cpp
+4
-0
src/cpu/x86/vm/vm_version_x86.hpp
src/cpu/x86/vm/vm_version_x86.hpp
+6
-2
src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
+163
-160
src/share/vm/c1/c1_LIR.cpp
src/share/vm/c1/c1_LIR.cpp
+11
-0
src/share/vm/c1/c1_LIR.hpp
src/share/vm/c1/c1_LIR.hpp
+1
-1
src/share/vm/c1/c1_LIRGenerator.cpp
src/share/vm/c1/c1_LIRGenerator.cpp
+8
-4
src/share/vm/code/nmethod.cpp
src/share/vm/code/nmethod.cpp
+12
-8
src/share/vm/code/nmethod.hpp
src/share/vm/code/nmethod.hpp
+9
-6
src/share/vm/opto/connode.cpp
src/share/vm/opto/connode.cpp
+3
-11
src/share/vm/prims/jni.cpp
src/share/vm/prims/jni.cpp
+1
-0
src/share/vm/runtime/objectMonitor.cpp
src/share/vm/runtime/objectMonitor.cpp
+64
-0
src/share/vm/runtime/objectMonitor.hpp
src/share/vm/runtime/objectMonitor.hpp
+2
-2
src/share/vm/runtime/synchronizer.cpp
src/share/vm/runtime/synchronizer.cpp
+63
-12
src/share/vm/runtime/synchronizer.hpp
src/share/vm/runtime/synchronizer.hpp
+3
-0
src/share/vm/runtime/vmStructs.cpp
src/share/vm/runtime/vmStructs.cpp
+2
-2
src/share/vm/runtime/vm_version.cpp
src/share/vm/runtime/vm_version.cpp
+1
-0
src/share/vm/runtime/vm_version.hpp
src/share/vm/runtime/vm_version.hpp
+6
-1
test/compiler/c1/TestUnresolvedField.jasm
test/compiler/c1/TestUnresolvedField.jasm
+38
-0
test/compiler/c1/TestUnresolvedFieldMain.java
test/compiler/c1/TestUnresolvedFieldMain.java
+48
-0
test/compiler/loopopts/TestLoopPeeling.java
test/compiler/loopopts/TestLoopPeeling.java
+53
-7
未找到文件。
src/cpu/sparc/vm/vm_version_sparc.cpp
浏览文件 @
e0052d8a
...
@@ -236,7 +236,7 @@ void VM_Version::initialize() {
...
@@ -236,7 +236,7 @@ void VM_Version::initialize() {
assert
((
OptoLoopAlignment
%
relocInfo
::
addr_unit
())
==
0
,
"alignment is not a multiple of NOP size"
);
assert
((
OptoLoopAlignment
%
relocInfo
::
addr_unit
())
==
0
,
"alignment is not a multiple of NOP size"
);
char
buf
[
512
];
char
buf
[
512
];
jio_snprintf
(
buf
,
sizeof
(
buf
),
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
,
jio_snprintf
(
buf
,
sizeof
(
buf
),
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s
%s
"
,
(
has_v9
()
?
", v9"
:
(
has_v8
()
?
", v8"
:
""
)),
(
has_v9
()
?
", v9"
:
(
has_v8
()
?
", v8"
:
""
)),
(
has_hardware_popc
()
?
", popc"
:
""
),
(
has_hardware_popc
()
?
", popc"
:
""
),
(
has_vis1
()
?
", vis1"
:
""
),
(
has_vis1
()
?
", vis1"
:
""
),
...
@@ -249,6 +249,7 @@ void VM_Version::initialize() {
...
@@ -249,6 +249,7 @@ void VM_Version::initialize() {
(
has_sha256
()
?
", sha256"
:
""
),
(
has_sha256
()
?
", sha256"
:
""
),
(
has_sha512
()
?
", sha512"
:
""
),
(
has_sha512
()
?
", sha512"
:
""
),
(
is_ultra3
()
?
", ultra3"
:
""
),
(
is_ultra3
()
?
", ultra3"
:
""
),
(
has_sparc5_instr
()
?
", sparc5"
:
""
),
(
is_sun4v
()
?
", sun4v"
:
""
),
(
is_sun4v
()
?
", sun4v"
:
""
),
(
is_niagara_plus
()
?
", niagara_plus"
:
(
is_niagara
()
?
", niagara"
:
""
)),
(
is_niagara_plus
()
?
", niagara_plus"
:
(
is_niagara
()
?
", niagara"
:
""
)),
(
is_sparc64
()
?
", sparc64"
:
""
),
(
is_sparc64
()
?
", sparc64"
:
""
),
...
@@ -364,6 +365,7 @@ void VM_Version::initialize() {
...
@@ -364,6 +365,7 @@ void VM_Version::initialize() {
#ifndef PRODUCT
#ifndef PRODUCT
if
(
PrintMiscellaneous
&&
Verbose
)
{
if
(
PrintMiscellaneous
&&
Verbose
)
{
tty
->
print_cr
(
"L1 data cache line size: %u"
,
L1_data_cache_line_size
());
tty
->
print_cr
(
"L2 data cache line size: %u"
,
L2_data_cache_line_size
());
tty
->
print_cr
(
"L2 data cache line size: %u"
,
L2_data_cache_line_size
());
tty
->
print
(
"Allocation"
);
tty
->
print
(
"Allocation"
);
if
(
AllocatePrefetchStyle
<=
0
)
{
if
(
AllocatePrefetchStyle
<=
0
)
{
...
@@ -447,9 +449,10 @@ void VM_Version::revert() {
...
@@ -447,9 +449,10 @@ void VM_Version::revert() {
unsigned
int
VM_Version
::
calc_parallel_worker_threads
()
{
unsigned
int
VM_Version
::
calc_parallel_worker_threads
()
{
unsigned
int
result
;
unsigned
int
result
;
if
(
is_M_series
())
{
if
(
is_M_series
()
||
is_S_series
())
{
// for now, use same gc thread calculation for M-series as for niagara-plus
// for now, use same gc thread calculation for M-series and S-series as for
// in future, we may want to tweak parameters for nof_parallel_worker_thread
// niagara-plus. In future, we may want to tweak parameters for
// nof_parallel_worker_thread
result
=
nof_parallel_worker_threads
(
5
,
16
,
8
);
result
=
nof_parallel_worker_threads
(
5
,
16
,
8
);
}
else
if
(
is_niagara_plus
())
{
}
else
if
(
is_niagara_plus
())
{
result
=
nof_parallel_worker_threads
(
5
,
16
,
8
);
result
=
nof_parallel_worker_threads
(
5
,
16
,
8
);
...
@@ -458,3 +461,37 @@ unsigned int VM_Version::calc_parallel_worker_threads() {
...
@@ -458,3 +461,37 @@ unsigned int VM_Version::calc_parallel_worker_threads() {
}
}
return
result
;
return
result
;
}
}
int
VM_Version
::
parse_features
(
const
char
*
implementation
)
{
int
features
=
unknown_m
;
// Convert to UPPER case before compare.
char
*
impl
=
os
::
strdup
(
implementation
);
for
(
int
i
=
0
;
impl
[
i
]
!=
0
;
i
++
)
impl
[
i
]
=
(
char
)
toupper
((
uint
)
impl
[
i
]);
if
(
strstr
(
impl
,
"SPARC64"
)
!=
NULL
)
{
features
|=
sparc64_family_m
;
}
else
if
(
strstr
(
impl
,
"SPARC-M"
)
!=
NULL
)
{
// M-series SPARC is based on T-series.
features
|=
(
M_family_m
|
T_family_m
);
}
else
if
(
strstr
(
impl
,
"SPARC-S"
)
!=
NULL
)
{
// S-series SPARC is based on T-series.
features
|=
(
S_family_m
|
T_family_m
);
}
else
if
(
strstr
(
impl
,
"SPARC-T"
)
!=
NULL
)
{
features
|=
T_family_m
;
if
(
strstr
(
impl
,
"SPARC-T1"
)
!=
NULL
)
{
features
|=
T1_model_m
;
}
}
else
if
(
strstr
(
impl
,
"SUN4V-CPU"
)
!=
NULL
)
{
// Generic or migration class LDOM
features
|=
T_family_m
;
}
else
{
#ifndef PRODUCT
warning
(
"Failed to parse CPU implementation = '%s'"
,
impl
);
#endif
}
os
::
free
((
void
*
)
impl
);
return
features
;
}
src/cpu/sparc/vm/vm_version_sparc.hpp
浏览文件 @
e0052d8a
...
@@ -47,13 +47,14 @@ protected:
...
@@ -47,13 +47,14 @@ protected:
cbcond_instructions
=
13
,
cbcond_instructions
=
13
,
sparc64_family
=
14
,
sparc64_family
=
14
,
M_family
=
15
,
M_family
=
15
,
T_family
=
16
,
S_family
=
16
,
T1_model
=
17
,
T_family
=
17
,
sparc5_instructions
=
18
,
T1_model
=
18
,
aes_instructions
=
19
,
sparc5_instructions
=
19
,
sha1_instruction
=
20
,
aes_instructions
=
20
,
sha256_instruction
=
21
,
sha1_instruction
=
21
,
sha512_instruction
=
22
sha256_instruction
=
22
,
sha512_instruction
=
23
};
};
enum
Feature_Flag_Set
{
enum
Feature_Flag_Set
{
...
@@ -76,6 +77,7 @@ protected:
...
@@ -76,6 +77,7 @@ protected:
cbcond_instructions_m
=
1
<<
cbcond_instructions
,
cbcond_instructions_m
=
1
<<
cbcond_instructions
,
sparc64_family_m
=
1
<<
sparc64_family
,
sparc64_family_m
=
1
<<
sparc64_family
,
M_family_m
=
1
<<
M_family
,
M_family_m
=
1
<<
M_family
,
S_family_m
=
1
<<
S_family
,
T_family_m
=
1
<<
T_family
,
T_family_m
=
1
<<
T_family
,
T1_model_m
=
1
<<
T1_model
,
T1_model_m
=
1
<<
T1_model
,
sparc5_instructions_m
=
1
<<
sparc5_instructions
,
sparc5_instructions_m
=
1
<<
sparc5_instructions
,
...
@@ -105,6 +107,7 @@ protected:
...
@@ -105,6 +107,7 @@ protected:
// Returns true if the platform is in the niagara line (T series)
// Returns true if the platform is in the niagara line (T series)
static
bool
is_M_family
(
int
features
)
{
return
(
features
&
M_family_m
)
!=
0
;
}
static
bool
is_M_family
(
int
features
)
{
return
(
features
&
M_family_m
)
!=
0
;
}
static
bool
is_S_family
(
int
features
)
{
return
(
features
&
S_family_m
)
!=
0
;
}
static
bool
is_T_family
(
int
features
)
{
return
(
features
&
T_family_m
)
!=
0
;
}
static
bool
is_T_family
(
int
features
)
{
return
(
features
&
T_family_m
)
!=
0
;
}
static
bool
is_niagara
()
{
return
is_T_family
(
_features
);
}
static
bool
is_niagara
()
{
return
is_T_family
(
_features
);
}
#ifdef ASSERT
#ifdef ASSERT
...
@@ -119,7 +122,7 @@ protected:
...
@@ -119,7 +122,7 @@ protected:
static
bool
is_T1_model
(
int
features
)
{
return
is_T_family
(
features
)
&&
((
features
&
T1_model_m
)
!=
0
);
}
static
bool
is_T1_model
(
int
features
)
{
return
is_T_family
(
features
)
&&
((
features
&
T1_model_m
)
!=
0
);
}
static
int
maximum_niagara1_processor_count
()
{
return
32
;
}
static
int
maximum_niagara1_processor_count
()
{
return
32
;
}
static
int
parse_features
(
const
char
*
implementation
);
public:
public:
// Initialization
// Initialization
static
void
initialize
();
static
void
initialize
();
...
@@ -152,6 +155,7 @@ public:
...
@@ -152,6 +155,7 @@ public:
static
bool
is_niagara_plus
()
{
return
is_T_family
(
_features
)
&&
!
is_T1_model
(
_features
);
}
static
bool
is_niagara_plus
()
{
return
is_T_family
(
_features
)
&&
!
is_T1_model
(
_features
);
}
static
bool
is_M_series
()
{
return
is_M_family
(
_features
);
}
static
bool
is_M_series
()
{
return
is_M_family
(
_features
);
}
static
bool
is_S_series
()
{
return
is_S_family
(
_features
);
}
static
bool
is_T4
()
{
return
is_T_family
(
_features
)
&&
has_cbcond
();
}
static
bool
is_T4
()
{
return
is_T_family
(
_features
)
&&
has_cbcond
();
}
static
bool
is_T7
()
{
return
is_T_family
(
_features
)
&&
has_sparc5_instr
();
}
static
bool
is_T7
()
{
return
is_T_family
(
_features
)
&&
has_sparc5_instr
();
}
...
...
src/cpu/x86/vm/vm_version_x86.cpp
浏览文件 @
e0052d8a
...
@@ -406,6 +406,8 @@ void VM_Version::get_processor_features() {
...
@@ -406,6 +406,8 @@ void VM_Version::get_processor_features() {
_stepping
=
0
;
_stepping
=
0
;
_cpuFeatures
=
0
;
_cpuFeatures
=
0
;
_logical_processors_per_package
=
1
;
_logical_processors_per_package
=
1
;
// i486 internal cache is both I&D and has a 16-byte line size
_L1_data_cache_line_size
=
16
;
if
(
!
Use486InstrsOnly
)
{
if
(
!
Use486InstrsOnly
)
{
// Get raw processor info
// Get raw processor info
...
@@ -424,6 +426,7 @@ void VM_Version::get_processor_features() {
...
@@ -424,6 +426,7 @@ void VM_Version::get_processor_features() {
// Logical processors are only available on P4s and above,
// Logical processors are only available on P4s and above,
// and only if hyperthreading is available.
// and only if hyperthreading is available.
_logical_processors_per_package
=
logical_processor_count
();
_logical_processors_per_package
=
logical_processor_count
();
_L1_data_cache_line_size
=
L1_line_size
();
}
}
}
}
...
@@ -1034,6 +1037,7 @@ void VM_Version::get_processor_features() {
...
@@ -1034,6 +1037,7 @@ void VM_Version::get_processor_features() {
if
(
PrintMiscellaneous
&&
Verbose
)
{
if
(
PrintMiscellaneous
&&
Verbose
)
{
tty
->
print_cr
(
"Logical CPUs per core: %u"
,
tty
->
print_cr
(
"Logical CPUs per core: %u"
,
logical_processors_per_package
());
logical_processors_per_package
());
tty
->
print_cr
(
"L1 data cache line size: %u"
,
L1_data_cache_line_size
());
tty
->
print
(
"UseSSE=%d"
,
(
int
)
UseSSE
);
tty
->
print
(
"UseSSE=%d"
,
(
int
)
UseSSE
);
if
(
UseAVX
>
0
)
{
if
(
UseAVX
>
0
)
{
tty
->
print
(
" UseAVX=%d"
,
(
int
)
UseAVX
);
tty
->
print
(
" UseAVX=%d"
,
(
int
)
UseAVX
);
...
...
src/cpu/x86/vm/vm_version_x86.hpp
浏览文件 @
e0052d8a
/*
/*
* Copyright (c) 1997, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
4
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -595,7 +595,7 @@ public:
...
@@ -595,7 +595,7 @@ public:
return
(
result
==
0
?
1
:
result
);
return
(
result
==
0
?
1
:
result
);
}
}
static
intx
prefetch_data
_size
()
{
static
intx
L1_line
_size
()
{
intx
result
=
0
;
intx
result
=
0
;
if
(
is_intel
())
{
if
(
is_intel
())
{
result
=
(
_cpuid_info
.
dcp_cpuid4_ebx
.
bits
.
L1_line_size
+
1
);
result
=
(
_cpuid_info
.
dcp_cpuid4_ebx
.
bits
.
L1_line_size
+
1
);
...
@@ -607,6 +607,10 @@ public:
...
@@ -607,6 +607,10 @@ public:
return
result
;
return
result
;
}
}
static
intx
prefetch_data_size
()
{
return
L1_line_size
();
}
//
//
// Feature identification
// Feature identification
//
//
...
...
src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
浏览文件 @
e0052d8a
...
@@ -262,6 +262,7 @@ void PICL::close_library() {
...
@@ -262,6 +262,7 @@ void PICL::close_library() {
// We need to keep these here as long as we have to build on Solaris
// We need to keep these here as long as we have to build on Solaris
// versions before 10.
// versions before 10.
#ifndef SI_ARCHITECTURE_32
#ifndef SI_ARCHITECTURE_32
#define SI_ARCHITECTURE_32 516
/* basic 32-bit SI_ARCHITECTURE */
#define SI_ARCHITECTURE_32 516
/* basic 32-bit SI_ARCHITECTURE */
#endif
#endif
...
@@ -270,38 +271,88 @@ void PICL::close_library() {
...
@@ -270,38 +271,88 @@ void PICL::close_library() {
#define SI_ARCHITECTURE_64 517
/* basic 64-bit SI_ARCHITECTURE */
#define SI_ARCHITECTURE_64 517
/* basic 64-bit SI_ARCHITECTURE */
#endif
#endif
static
void
do_sysinfo
(
int
si
,
const
char
*
string
,
int
*
features
,
int
mask
)
{
#ifndef SI_CPUBRAND
#define SI_CPUBRAND 523
/* return cpu brand string */
#endif
class
Sysinfo
{
char
*
_string
;
public:
Sysinfo
(
int
si
)
:
_string
(
NULL
)
{
char
tmp
;
char
tmp
;
size_t
bufsize
=
sysinfo
(
si
,
&
tmp
,
1
);
size_t
bufsize
=
sysinfo
(
si
,
&
tmp
,
1
);
// All SI defines used below must be supported.
if
(
bufsize
!=
-
1
)
{
guarantee
(
bufsize
!=
-
1
,
"must be supported"
);
char
*
buf
=
(
char
*
)
os
::
malloc
(
bufsize
,
mtInternal
);
if
(
buf
!=
NULL
)
{
if
(
sysinfo
(
si
,
buf
,
bufsize
)
==
bufsize
)
{
_string
=
buf
;
}
else
{
os
::
free
(
buf
);
}
}
}
}
char
*
buf
=
(
char
*
)
malloc
(
bufsize
);
~
Sysinfo
()
{
if
(
_string
!=
NULL
)
{
os
::
free
(
_string
);
}
}
if
(
buf
==
NULL
)
const
char
*
value
()
const
{
return
;
return
_string
;
}
if
(
sysinfo
(
si
,
buf
,
bufsize
)
==
bufsize
)
{
bool
valid
()
const
{
// Compare the string.
return
_string
!=
NULL
;
if
(
strcmp
(
buf
,
string
)
==
0
)
{
*
features
|=
mask
;
}
}
bool
match
(
const
char
*
s
)
const
{
return
valid
()
?
strcmp
(
_string
,
s
)
==
0
:
false
;
}
}
free
(
buf
);
bool
match_substring
(
const
char
*
s
)
const
{
}
return
valid
()
?
strstr
(
_string
,
s
)
!=
NULL
:
false
;
}
};
class
Sysconf
{
int
_value
;
public:
Sysconf
(
int
sc
)
:
_value
(
-
1
)
{
_value
=
sysconf
(
sc
);
}
bool
valid
()
const
{
return
_value
!=
-
1
;
}
int
value
()
const
{
return
_value
;
}
};
#ifndef _SC_DCACHE_LINESZ
#define _SC_DCACHE_LINESZ 508
/* Data cache line size */
#endif
#ifndef _SC_L2CACHE_LINESZ
#define _SC_L2CACHE_LINESZ 527
/* Size of L2 cache line */
#endif
int
VM_Version
::
platform_features
(
int
features
)
{
int
VM_Version
::
platform_features
(
int
features
)
{
// getisax(2), SI_ARCHITECTURE_32, and SI_ARCHITECTURE_64 are
assert
(
os
::
Solaris
::
supports_getisax
(),
"getisax() must be available"
);
// supported on Solaris 10 and later.
if
(
os
::
Solaris
::
supports_getisax
())
{
// Check 32-bit architecture.
// Check 32-bit architecture.
do_sysinfo
(
SI_ARCHITECTURE_32
,
"sparc"
,
&
features
,
v8_instructions_m
);
if
(
Sysinfo
(
SI_ARCHITECTURE_32
).
match
(
"sparc"
))
{
features
|=
v8_instructions_m
;
}
// Check 64-bit architecture.
// Check 64-bit architecture.
do_sysinfo
(
SI_ARCHITECTURE_64
,
"sparcv9"
,
&
features
,
generic_v9_m
);
if
(
Sysinfo
(
SI_ARCHITECTURE_64
).
match
(
"sparcv9"
))
{
features
|=
generic_v9_m
;
}
// Extract valid instruction set extensions.
// Extract valid instruction set extensions.
uint_t
avs
[
2
];
uint_t
avs
[
2
];
...
@@ -334,8 +385,9 @@ int VM_Version::platform_features(int features) {
...
@@ -334,8 +385,9 @@ int VM_Version::platform_features(int features) {
if
(
av2
&
AV2_SPARC_SPARC5
)
features
|=
sparc5_instructions_m
;
if
(
av2
&
AV2_SPARC_SPARC5
)
features
|=
sparc5_instructions_m
;
}
}
// Next values are not defined before Solaris 10
// We only build on Solaris 10 and up, but some of the values below
// but Solaris 8 is used for jdk6 update builds.
// are not defined on all versions of Solaris 10, so we define them,
// if necessary.
#ifndef AV_SPARC_ASI_BLK_INIT
#ifndef AV_SPARC_ASI_BLK_INIT
#define AV_SPARC_ASI_BLK_INIT 0x0080
/* ASI_BLK_INIT_xxx ASI */
#define AV_SPARC_ASI_BLK_INIT 0x0080
/* ASI_BLK_INIT_xxx ASI */
#endif
#endif
...
@@ -381,120 +433,71 @@ int VM_Version::platform_features(int features) {
...
@@ -381,120 +433,71 @@ int VM_Version::platform_features(int features) {
#endif
#endif
if
(
av
&
AV_SPARC_SHA512
)
features
|=
sha512_instruction_m
;
if
(
av
&
AV_SPARC_SHA512
)
features
|=
sha512_instruction_m
;
}
else
{
// Determine the machine type.
// getisax(2) failed, use the old legacy code.
if
(
Sysinfo
(
SI_MACHINE
).
match
(
"sun4v"
))
{
features
|=
sun4v_m
;
}
// If SI_CPUBRAND works, that means Solaris 12 API to get the cache line sizes
// is available to us as well
Sysinfo
cpu_info
(
SI_CPUBRAND
);
bool
use_solaris_12_api
=
cpu_info
.
valid
();
const
char
*
impl
;
int
impl_m
=
0
;
if
(
use_solaris_12_api
)
{
impl
=
cpu_info
.
value
();
#ifndef PRODUCT
#ifndef PRODUCT
if
(
PrintMiscellaneous
&&
Verbose
)
if
(
PrintMiscellaneous
&&
Verbose
)
{
tty
->
print_cr
(
"getisax(2) is not supported."
);
tty
->
print_cr
(
"Parsing CPU implementation from %s"
,
impl
);
#endif
char
tmp
;
size_t
bufsize
=
sysinfo
(
SI_ISALIST
,
&
tmp
,
1
);
char
*
buf
=
(
char
*
)
malloc
(
bufsize
);
if
(
buf
!=
NULL
)
{
if
(
sysinfo
(
SI_ISALIST
,
buf
,
bufsize
)
==
bufsize
)
{
// Figure out what kind of sparc we have
char
*
sparc_string
=
strstr
(
buf
,
"sparc"
);
if
(
sparc_string
!=
NULL
)
{
features
|=
v8_instructions_m
;
if
(
sparc_string
[
5
]
==
'v'
)
{
if
(
sparc_string
[
6
]
==
'8'
)
{
if
(
sparc_string
[
7
]
==
'-'
)
{
features
|=
hardware_mul32_m
;
features
|=
hardware_div32_m
;
}
else
if
(
sparc_string
[
7
]
==
'p'
)
features
|=
generic_v9_m
;
else
features
|=
generic_v8_m
;
}
else
if
(
sparc_string
[
6
]
==
'9'
)
features
|=
generic_v9_m
;
}
}
// Check for visualization instructions
char
*
vis
=
strstr
(
buf
,
"vis"
);
if
(
vis
!=
NULL
)
{
features
|=
vis1_instructions_m
;
if
(
vis
[
3
]
==
'2'
)
features
|=
vis2_instructions_m
;
}
}
free
(
buf
);
}
}
}
#endif
// Determine the machine type.
impl_m
=
parse_features
(
impl
);
do_sysinfo
(
SI_MACHINE
,
"sun4v"
,
&
features
,
sun4v_m
);
}
else
{
// Otherwise use kstat to determine the machine type.
{
// Using kstat to determine the machine type.
kstat_ctl_t
*
kc
=
kstat_open
();
kstat_ctl_t
*
kc
=
kstat_open
();
if
(
kc
!=
NULL
)
{
kstat_t
*
ksp
=
kstat_lookup
(
kc
,
(
char
*
)
"cpu_info"
,
-
1
,
NULL
);
kstat_t
*
ksp
=
kstat_lookup
(
kc
,
(
char
*
)
"cpu_info"
,
-
1
,
NULL
);
const
char
*
implementation
=
"UNKNOWN"
;
if
(
ksp
!=
NULL
)
{
if
(
ksp
!=
NULL
)
{
if
(
kstat_read
(
kc
,
ksp
,
NULL
)
!=
-
1
&&
ksp
->
ks_data
!=
NULL
)
{
if
(
kstat_read
(
kc
,
ksp
,
NULL
)
!=
-
1
&&
ksp
->
ks_data
!=
NULL
)
{
kstat_named_t
*
knm
=
(
kstat_named_t
*
)
ksp
->
ks_data
;
kstat_named_t
*
knm
=
(
kstat_named_t
*
)
ksp
->
ks_data
;
for
(
int
i
=
0
;
i
<
ksp
->
ks_ndata
;
i
++
)
{
for
(
int
i
=
0
;
i
<
ksp
->
ks_ndata
;
i
++
)
{
if
(
strcmp
((
const
char
*
)
&
(
knm
[
i
].
name
),
"implementation"
)
==
0
)
{
if
(
strcmp
((
const
char
*
)
&
(
knm
[
i
].
name
),
"implementation"
)
==
0
)
{
#ifndef KSTAT_DATA_STRING
impl
=
KSTAT_NAMED_STR_PTR
(
&
knm
[
i
]);
#define KSTAT_DATA_STRING 9
#endif
if
(
knm
[
i
].
data_type
==
KSTAT_DATA_CHAR
)
{
// VM is running on Solaris 8 which does not have value.str.
implementation
=
&
(
knm
[
i
].
value
.
c
[
0
]);
}
else
if
(
knm
[
i
].
data_type
==
KSTAT_DATA_STRING
)
{
// VM is running on Solaris 10.
#ifndef KSTAT_NAMED_STR_PTR
// Solaris 8 was used to build VM, define the structure it misses.
struct
str_t
{
union
{
char
*
ptr
;
/* NULL-term string */
char
__pad
[
8
];
/* 64-bit padding */
}
addr
;
uint32_t
len
;
/* # bytes for strlen + '\0' */
};
#define KSTAT_NAMED_STR_PTR(knptr) (( (str_t*)&((knptr)->value) )->addr.ptr)
#endif
implementation
=
KSTAT_NAMED_STR_PTR
(
&
knm
[
i
]);
}
#ifndef PRODUCT
#ifndef PRODUCT
if
(
PrintMiscellaneous
&&
Verbose
)
{
if
(
PrintMiscellaneous
&&
Verbose
)
{
tty
->
print_cr
(
"cpu_info.implementation: %s"
,
implementation
);
tty
->
print_cr
(
"Parsing CPU implementation from %s"
,
impl
);
}
}
#endif
#endif
// Convert to UPPER case before compare.
impl_m
=
parse_features
(
impl
);
char
*
impl
=
strdup
(
implementation
);
break
;
for
(
int
i
=
0
;
impl
[
i
]
!=
0
;
i
++
)
impl
[
i
]
=
(
char
)
toupper
((
uint
)
impl
[
i
]);
if
(
strstr
(
impl
,
"SPARC64"
)
!=
NULL
)
{
features
|=
sparc64_family_m
;
}
else
if
(
strstr
(
impl
,
"SPARC-M"
)
!=
NULL
)
{
// M-series SPARC is based on T-series.
features
|=
(
M_family_m
|
T_family_m
);
}
else
if
(
strstr
(
impl
,
"SPARC-T"
)
!=
NULL
)
{
features
|=
T_family_m
;
if
(
strstr
(
impl
,
"SPARC-T1"
)
!=
NULL
)
{
features
|=
T1_model_m
;
}
}
}
else
{
if
(
strstr
(
impl
,
"SPARC"
)
==
NULL
)
{
#ifndef PRODUCT
// kstat on Solaris 8 virtual machines (branded zones)
// returns "(unsupported)" implementation.
warning
(
"kstat cpu_info implementation = '%s', should contain SPARC"
,
impl
);
#endif
implementation
=
"SPARC"
;
}
}
}
}
free
((
void
*
)
impl
);
break
;
}
}
}
// for(
kstat_close
(
kc
);
}
}
}
}
assert
(
strcmp
(
implementation
,
"UNKNOWN"
)
!=
0
,
assert
(
impl_m
!=
0
,
err_msg
(
"Unknown CPU implementation %s"
,
impl
));
"unknown cpu info (changed kstat interface?)"
);
features
|=
impl_m
;
kstat_close
(
kc
);
bool
is_sun4v
=
(
features
&
sun4v_m
)
!=
0
;
if
(
use_solaris_12_api
&&
is_sun4v
)
{
// If Solaris 12 API is supported and it's sun4v use sysconf() to get the cache line sizes
Sysconf
l1_dcache_line_size
(
_SC_DCACHE_LINESZ
);
if
(
l1_dcache_line_size
.
valid
())
{
_L1_data_cache_line_size
=
l1_dcache_line_size
.
value
();
}
}
// Figure out cache line sizes using PICL
Sysconf
l2_dcache_line_size
(
_SC_L2CACHE_LINESZ
);
PICL
picl
((
features
&
sparc64_family_m
)
!=
0
,
(
features
&
sun4v_m
)
!=
0
);
if
(
l2_dcache_line_size
.
valid
())
{
_L2_data_cache_line_size
=
l2_dcache_line_size
.
value
();
}
}
else
{
// Otherwise figure out the cache line sizes using PICL
bool
is_fujitsu
=
(
features
&
sparc64_family_m
)
!=
0
;
PICL
picl
(
is_fujitsu
,
is_sun4v
);
_L1_data_cache_line_size
=
picl
.
L1_data_cache_line_size
();
_L2_data_cache_line_size
=
picl
.
L2_data_cache_line_size
();
_L2_data_cache_line_size
=
picl
.
L2_data_cache_line_size
();
}
return
features
;
return
features
;
}
}
src/share/vm/c1/c1_LIR.cpp
浏览文件 @
e0052d8a
...
@@ -1516,6 +1516,17 @@ void LIR_List::store_check(LIR_Opr object, LIR_Opr array, LIR_Opr tmp1, LIR_Opr
...
@@ -1516,6 +1516,17 @@ void LIR_List::store_check(LIR_Opr object, LIR_Opr array, LIR_Opr tmp1, LIR_Opr
append
(
c
);
append
(
c
);
}
}
void
LIR_List
::
null_check
(
LIR_Opr
opr
,
CodeEmitInfo
*
info
,
bool
deoptimize_on_null
)
{
if
(
deoptimize_on_null
)
{
// Emit an explicit null check and deoptimize if opr is null
CodeStub
*
deopt
=
new
DeoptimizeStub
(
info
);
cmp
(
lir_cond_equal
,
opr
,
LIR_OprFact
::
oopConst
(
NULL
));
branch
(
lir_cond_equal
,
T_OBJECT
,
deopt
);
}
else
{
// Emit an implicit null check
append
(
new
LIR_Op1
(
lir_null_check
,
opr
,
info
));
}
}
void
LIR_List
::
cas_long
(
LIR_Opr
addr
,
LIR_Opr
cmp_value
,
LIR_Opr
new_value
,
void
LIR_List
::
cas_long
(
LIR_Opr
addr
,
LIR_Opr
cmp_value
,
LIR_Opr
new_value
,
LIR_Opr
t1
,
LIR_Opr
t2
,
LIR_Opr
result
)
{
LIR_Opr
t1
,
LIR_Opr
t2
,
LIR_Opr
result
)
{
...
...
src/share/vm/c1/c1_LIR.hpp
浏览文件 @
e0052d8a
...
@@ -2153,7 +2153,7 @@ class LIR_List: public CompilationResourceObj {
...
@@ -2153,7 +2153,7 @@ class LIR_List: public CompilationResourceObj {
void
pack64
(
LIR_Opr
src
,
LIR_Opr
dst
)
{
append
(
new
LIR_Op1
(
lir_pack64
,
src
,
dst
,
T_LONG
,
lir_patch_none
,
NULL
));
}
void
pack64
(
LIR_Opr
src
,
LIR_Opr
dst
)
{
append
(
new
LIR_Op1
(
lir_pack64
,
src
,
dst
,
T_LONG
,
lir_patch_none
,
NULL
));
}
void
unpack64
(
LIR_Opr
src
,
LIR_Opr
dst
)
{
append
(
new
LIR_Op1
(
lir_unpack64
,
src
,
dst
,
T_LONG
,
lir_patch_none
,
NULL
));
}
void
unpack64
(
LIR_Opr
src
,
LIR_Opr
dst
)
{
append
(
new
LIR_Op1
(
lir_unpack64
,
src
,
dst
,
T_LONG
,
lir_patch_none
,
NULL
));
}
void
null_check
(
LIR_Opr
opr
,
CodeEmitInfo
*
info
)
{
append
(
new
LIR_Op1
(
lir_null_check
,
opr
,
info
));
}
void
null_check
(
LIR_Opr
opr
,
CodeEmitInfo
*
info
,
bool
deoptimize_on_null
=
false
);
void
throw_exception
(
LIR_Opr
exceptionPC
,
LIR_Opr
exceptionOop
,
CodeEmitInfo
*
info
)
{
void
throw_exception
(
LIR_Opr
exceptionPC
,
LIR_Opr
exceptionOop
,
CodeEmitInfo
*
info
)
{
append
(
new
LIR_Op2
(
lir_throw
,
exceptionPC
,
exceptionOop
,
LIR_OprFact
::
illegalOpr
,
info
));
append
(
new
LIR_Op2
(
lir_throw
,
exceptionPC
,
exceptionOop
,
LIR_OprFact
::
illegalOpr
,
info
));
}
}
...
...
src/share/vm/c1/c1_LIRGenerator.cpp
浏览文件 @
e0052d8a
...
@@ -1700,8 +1700,10 @@ void LIRGenerator::do_StoreField(StoreField* x) {
...
@@ -1700,8 +1700,10 @@ void LIRGenerator::do_StoreField(StoreField* x) {
if
(
x
->
needs_null_check
()
&&
if
(
x
->
needs_null_check
()
&&
(
needs_patching
||
(
needs_patching
||
MacroAssembler
::
needs_explicit_null_check
(
x
->
offset
())))
{
MacroAssembler
::
needs_explicit_null_check
(
x
->
offset
())))
{
// emit an explicit null check because the offset is too large
// Emit an explicit null check because the offset is too large.
__
null_check
(
object
.
result
(),
new
CodeEmitInfo
(
info
));
// If the class is not loaded and the object is NULL, we need to deoptimize to throw a
// NoClassDefFoundError in the interpreter instead of an implicit NPE from compiled code.
__
null_check
(
object
.
result
(),
new
CodeEmitInfo
(
info
),
/* deoptimize */
needs_patching
);
}
}
LIR_Address
*
address
;
LIR_Address
*
address
;
...
@@ -1785,8 +1787,10 @@ void LIRGenerator::do_LoadField(LoadField* x) {
...
@@ -1785,8 +1787,10 @@ void LIRGenerator::do_LoadField(LoadField* x) {
obj
=
new_register
(
T_OBJECT
);
obj
=
new_register
(
T_OBJECT
);
__
move
(
LIR_OprFact
::
oopConst
(
NULL
),
obj
);
__
move
(
LIR_OprFact
::
oopConst
(
NULL
),
obj
);
}
}
// emit an explicit null check because the offset is too large
// Emit an explicit null check because the offset is too large.
__
null_check
(
obj
,
new
CodeEmitInfo
(
info
));
// If the class is not loaded and the object is NULL, we need to deoptimize to throw a
// NoClassDefFoundError in the interpreter instead of an implicit NPE from compiled code.
__
null_check
(
obj
,
new
CodeEmitInfo
(
info
),
/* deoptimize */
needs_patching
);
}
}
LIR_Opr
reg
=
rlock_result
(
x
,
field_type
);
LIR_Opr
reg
=
rlock_result
(
x
,
field_type
);
...
...
src/share/vm/code/nmethod.cpp
浏览文件 @
e0052d8a
/*
/*
* Copyright (c) 1997, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -254,7 +254,8 @@ bool ExceptionCache::match_exception_with_space(Handle exception) {
...
@@ -254,7 +254,8 @@ bool ExceptionCache::match_exception_with_space(Handle exception) {
address
ExceptionCache
::
test_address
(
address
addr
)
{
address
ExceptionCache
::
test_address
(
address
addr
)
{
for
(
int
i
=
0
;
i
<
count
();
i
++
)
{
int
limit
=
count
();
for
(
int
i
=
0
;
i
<
limit
;
i
++
)
{
if
(
pc_at
(
i
)
==
addr
)
{
if
(
pc_at
(
i
)
==
addr
)
{
return
handler_at
(
i
);
return
handler_at
(
i
);
}
}
...
@@ -265,9 +266,11 @@ address ExceptionCache::test_address(address addr) {
...
@@ -265,9 +266,11 @@ address ExceptionCache::test_address(address addr) {
bool
ExceptionCache
::
add_address_and_handler
(
address
addr
,
address
handler
)
{
bool
ExceptionCache
::
add_address_and_handler
(
address
addr
,
address
handler
)
{
if
(
test_address
(
addr
)
==
handler
)
return
true
;
if
(
test_address
(
addr
)
==
handler
)
return
true
;
if
(
count
()
<
cache_size
)
{
set_pc_at
(
count
(),
addr
);
int
index
=
count
();
set_handler_at
(
count
(),
handler
);
if
(
index
<
cache_size
)
{
set_pc_at
(
index
,
addr
);
set_handler_at
(
index
,
handler
);
increment_count
();
increment_count
();
return
true
;
return
true
;
}
}
...
@@ -380,10 +383,11 @@ void nmethod::add_exception_cache_entry(ExceptionCache* new_entry) {
...
@@ -380,10 +383,11 @@ void nmethod::add_exception_cache_entry(ExceptionCache* new_entry) {
assert
(
new_entry
!=
NULL
,
"Must be non null"
);
assert
(
new_entry
!=
NULL
,
"Must be non null"
);
assert
(
new_entry
->
next
()
==
NULL
,
"Must be null"
);
assert
(
new_entry
->
next
()
==
NULL
,
"Must be null"
);
if
(
exception_cache
()
!=
NULL
)
{
ExceptionCache
*
ec
=
exception_cache
();
new_entry
->
set_next
(
exception_cache
());
if
(
ec
!=
NULL
)
{
new_entry
->
set_next
(
ec
);
}
}
set_exception_cache
(
new_entry
);
release_
set_exception_cache
(
new_entry
);
}
}
void
nmethod
::
clean_exception_cache
(
BoolObjectClosure
*
is_alive
)
{
void
nmethod
::
clean_exception_cache
(
BoolObjectClosure
*
is_alive
)
{
...
...
src/share/vm/code/nmethod.hpp
浏览文件 @
e0052d8a
/*
/*
* Copyright (c) 1997, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -39,15 +39,16 @@ class ExceptionCache : public CHeapObj<mtCode> {
...
@@ -39,15 +39,16 @@ class ExceptionCache : public CHeapObj<mtCode> {
Klass
*
_exception_type
;
Klass
*
_exception_type
;
address
_pc
[
cache_size
];
address
_pc
[
cache_size
];
address
_handler
[
cache_size
];
address
_handler
[
cache_size
];
int
_count
;
volatile
int
_count
;
ExceptionCache
*
_next
;
ExceptionCache
*
_next
;
address
pc_at
(
int
index
)
{
assert
(
index
>=
0
&&
index
<
count
(),
""
);
return
_pc
[
index
];
}
address
pc_at
(
int
index
)
{
assert
(
index
>=
0
&&
index
<
count
(),
""
);
return
_pc
[
index
];
}
void
set_pc_at
(
int
index
,
address
a
)
{
assert
(
index
>=
0
&&
index
<
cache_size
,
""
);
_pc
[
index
]
=
a
;
}
void
set_pc_at
(
int
index
,
address
a
)
{
assert
(
index
>=
0
&&
index
<
cache_size
,
""
);
_pc
[
index
]
=
a
;
}
address
handler_at
(
int
index
)
{
assert
(
index
>=
0
&&
index
<
count
(),
""
);
return
_handler
[
index
];
}
address
handler_at
(
int
index
)
{
assert
(
index
>=
0
&&
index
<
count
(),
""
);
return
_handler
[
index
];
}
void
set_handler_at
(
int
index
,
address
a
)
{
assert
(
index
>=
0
&&
index
<
cache_size
,
""
);
_handler
[
index
]
=
a
;
}
void
set_handler_at
(
int
index
,
address
a
)
{
assert
(
index
>=
0
&&
index
<
cache_size
,
""
);
_handler
[
index
]
=
a
;
}
int
count
()
{
return
_count
;
}
int
count
()
{
return
OrderAccess
::
load_acquire
(
&
_count
);
}
void
increment_count
()
{
_count
++
;
}
// increment_count is only called under lock, but there may be concurrent readers.
void
increment_count
()
{
OrderAccess
::
release_store
(
&
_count
,
_count
+
1
);
}
public:
public:
...
@@ -237,7 +238,7 @@ class nmethod : public CodeBlob {
...
@@ -237,7 +238,7 @@ class nmethod : public CodeBlob {
// counter is decreased (by 1) while sweeping.
// counter is decreased (by 1) while sweeping.
int
_hotness_counter
;
int
_hotness_counter
;
ExceptionCache
*
_exception_cache
;
ExceptionCache
*
volatile
_exception_cache
;
PcDescCache
_pc_desc_cache
;
PcDescCache
_pc_desc_cache
;
// These are used for compiled synchronized native methods to
// These are used for compiled synchronized native methods to
...
@@ -433,7 +434,7 @@ class nmethod : public CodeBlob {
...
@@ -433,7 +434,7 @@ class nmethod : public CodeBlob {
// flag accessing and manipulation
// flag accessing and manipulation
bool
is_in_use
()
const
{
return
_state
==
in_use
;
}
bool
is_in_use
()
const
{
return
_state
==
in_use
;
}
bool
is_alive
()
const
{
return
_state
==
in_use
||
_state
==
not_entrant
;
}
bool
is_alive
()
const
{
unsigned
char
s
=
_state
;
return
s
==
in_use
||
s
==
not_entrant
;
}
bool
is_not_entrant
()
const
{
return
_state
==
not_entrant
;
}
bool
is_not_entrant
()
const
{
return
_state
==
not_entrant
;
}
bool
is_zombie
()
const
{
return
_state
==
zombie
;
}
bool
is_zombie
()
const
{
return
_state
==
zombie
;
}
bool
is_unloaded
()
const
{
return
_state
==
unloaded
;
}
bool
is_unloaded
()
const
{
return
_state
==
unloaded
;
}
...
@@ -555,8 +556,10 @@ public:
...
@@ -555,8 +556,10 @@ public:
void
set_stack_traversal_mark
(
long
l
)
{
_stack_traversal_mark
=
l
;
}
void
set_stack_traversal_mark
(
long
l
)
{
_stack_traversal_mark
=
l
;
}
// Exception cache support
// Exception cache support
// Note: _exception_cache may be read concurrently. We rely on memory_order_consume here.
ExceptionCache
*
exception_cache
()
const
{
return
_exception_cache
;
}
ExceptionCache
*
exception_cache
()
const
{
return
_exception_cache
;
}
void
set_exception_cache
(
ExceptionCache
*
ec
)
{
_exception_cache
=
ec
;
}
void
set_exception_cache
(
ExceptionCache
*
ec
)
{
_exception_cache
=
ec
;
}
void
release_set_exception_cache
(
ExceptionCache
*
ec
)
{
OrderAccess
::
release_store_ptr
(
&
_exception_cache
,
ec
);
}
address
handler_for_exception_and_pc
(
Handle
exception
,
address
pc
);
address
handler_for_exception_and_pc
(
Handle
exception
,
address
pc
);
void
add_handler_for_exception_and_pc
(
Handle
exception
,
address
pc
,
address
handler
);
void
add_handler_for_exception_and_pc
(
Handle
exception
,
address
pc
,
address
handler
);
void
clean_exception_cache
(
BoolObjectClosure
*
is_alive
);
void
clean_exception_cache
(
BoolObjectClosure
*
is_alive
);
...
...
src/share/vm/opto/connode.cpp
浏览文件 @
e0052d8a
...
@@ -999,8 +999,7 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
...
@@ -999,8 +999,7 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
}
#ifdef _LP64
#ifdef _LP64
// Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) or
// Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y))
// ConvI2L(CastII(AddI(x, y))) to AddL(ConvI2L(CastII(x)), ConvI2L(CastII(y))),
// but only if x and y have subranges that cannot cause 32-bit overflow,
// but only if x and y have subranges that cannot cause 32-bit overflow,
// under the assumption that x+y is in my own subrange this->type().
// under the assumption that x+y is in my own subrange this->type().
...
@@ -1024,13 +1023,6 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
...
@@ -1024,13 +1023,6 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node
*
z
=
in
(
1
);
Node
*
z
=
in
(
1
);
int
op
=
z
->
Opcode
();
int
op
=
z
->
Opcode
();
Node
*
ctrl
=
NULL
;
if
(
op
==
Op_CastII
&&
z
->
as_CastII
()
->
has_range_check
())
{
// Skip CastII node but save control dependency
ctrl
=
z
->
in
(
0
);
z
=
z
->
in
(
1
);
op
=
z
->
Opcode
();
}
if
(
op
==
Op_AddI
||
op
==
Op_SubI
)
{
if
(
op
==
Op_AddI
||
op
==
Op_SubI
)
{
Node
*
x
=
z
->
in
(
1
);
Node
*
x
=
z
->
in
(
1
);
Node
*
y
=
z
->
in
(
2
);
Node
*
y
=
z
->
in
(
2
);
...
@@ -1090,8 +1082,8 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
...
@@ -1090,8 +1082,8 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
}
assert
(
rxlo
==
(
int
)
rxlo
&&
rxhi
==
(
int
)
rxhi
,
"x should not overflow"
);
assert
(
rxlo
==
(
int
)
rxlo
&&
rxhi
==
(
int
)
rxhi
,
"x should not overflow"
);
assert
(
rylo
==
(
int
)
rylo
&&
ryhi
==
(
int
)
ryhi
,
"y should not overflow"
);
assert
(
rylo
==
(
int
)
rylo
&&
ryhi
==
(
int
)
ryhi
,
"y should not overflow"
);
Node
*
cx
=
phase
->
C
->
constrained_convI2L
(
phase
,
x
,
TypeInt
::
make
(
rxlo
,
rxhi
,
widen
),
ctrl
);
Node
*
cx
=
phase
->
C
->
constrained_convI2L
(
phase
,
x
,
TypeInt
::
make
(
rxlo
,
rxhi
,
widen
),
NULL
);
Node
*
cy
=
phase
->
C
->
constrained_convI2L
(
phase
,
y
,
TypeInt
::
make
(
rylo
,
ryhi
,
widen
),
ctrl
);
Node
*
cy
=
phase
->
C
->
constrained_convI2L
(
phase
,
y
,
TypeInt
::
make
(
rylo
,
ryhi
,
widen
),
NULL
);
switch
(
op
)
{
switch
(
op
)
{
case
Op_AddI
:
return
new
(
phase
->
C
)
AddLNode
(
cx
,
cy
);
case
Op_AddI
:
return
new
(
phase
->
C
)
AddLNode
(
cx
,
cy
);
case
Op_SubI
:
return
new
(
phase
->
C
)
SubLNode
(
cx
,
cy
);
case
Op_SubI
:
return
new
(
phase
->
C
)
SubLNode
(
cx
,
cy
);
...
...
src/share/vm/prims/jni.cpp
浏览文件 @
e0052d8a
...
@@ -5129,6 +5129,7 @@ void execute_internal_vm_tests() {
...
@@ -5129,6 +5129,7 @@ void execute_internal_vm_tests() {
run_unit_test
(
TestKlass_test
());
run_unit_test
(
TestKlass_test
());
run_unit_test
(
Test_linked_list
());
run_unit_test
(
Test_linked_list
());
run_unit_test
(
TestChunkedList_test
());
run_unit_test
(
TestChunkedList_test
());
run_unit_test
(
ObjectMonitor
::
sanity_checks
());
#if INCLUDE_VM_STRUCTS
#if INCLUDE_VM_STRUCTS
run_unit_test
(
VMStructs
::
test
());
run_unit_test
(
VMStructs
::
test
());
#endif
#endif
...
...
src/share/vm/runtime/objectMonitor.cpp
浏览文件 @
e0052d8a
...
@@ -2529,6 +2529,10 @@ void ObjectMonitor::DeferredInitialize () {
...
@@ -2529,6 +2529,10 @@ void ObjectMonitor::DeferredInitialize () {
SETKNOB
(
FastHSSEC
)
;
SETKNOB
(
FastHSSEC
)
;
#undef SETKNOB
#undef SETKNOB
if
(
Knob_Verbose
)
{
sanity_checks
();
}
if
(
os
::
is_MP
())
{
if
(
os
::
is_MP
())
{
BackOffMask
=
(
1
<<
Knob_SpinBackOff
)
-
1
;
BackOffMask
=
(
1
<<
Knob_SpinBackOff
)
-
1
;
if
(
Knob_ReportSettings
)
::
printf
(
"BackOffMask=%X
\n
"
,
BackOffMask
)
;
if
(
Knob_ReportSettings
)
::
printf
(
"BackOffMask=%X
\n
"
,
BackOffMask
)
;
...
@@ -2549,6 +2553,66 @@ void ObjectMonitor::DeferredInitialize () {
...
@@ -2549,6 +2553,66 @@ void ObjectMonitor::DeferredInitialize () {
InitDone
=
1
;
InitDone
=
1
;
}
}
void
ObjectMonitor
::
sanity_checks
()
{
int
error_cnt
=
0
;
int
warning_cnt
=
0
;
bool
verbose
=
Knob_Verbose
!=
0
NOT_PRODUCT
(
||
VerboseInternalVMTests
);
if
(
verbose
)
{
tty
->
print_cr
(
"INFO: sizeof(ObjectMonitor)="
SIZE_FORMAT
,
sizeof
(
ObjectMonitor
));
}
uint
cache_line_size
=
VM_Version
::
L1_data_cache_line_size
();
if
(
verbose
)
{
tty
->
print_cr
(
"INFO: L1_data_cache_line_size=%u"
,
cache_line_size
);
}
ObjectMonitor
dummy
;
u_char
*
addr_begin
=
(
u_char
*
)
&
dummy
;
u_char
*
addr_header
=
(
u_char
*
)
&
dummy
.
_header
;
u_char
*
addr_owner
=
(
u_char
*
)
&
dummy
.
_owner
;
uint
offset_header
=
(
uint
)(
addr_header
-
addr_begin
);
if
(
verbose
)
tty
->
print_cr
(
"INFO: offset(_header)=%u"
,
offset_header
);
uint
offset_owner
=
(
uint
)(
addr_owner
-
addr_begin
);
if
(
verbose
)
tty
->
print_cr
(
"INFO: offset(_owner)=%u"
,
offset_owner
);
if
((
uint
)(
addr_header
-
addr_begin
)
!=
0
)
{
tty
->
print_cr
(
"ERROR: offset(_header) must be zero (0)."
);
error_cnt
++
;
}
if
(
cache_line_size
!=
0
)
{
// We were able to determine the L1 data cache line size so
// do some cache line specific sanity checks
if
((
offset_owner
-
offset_header
)
<
cache_line_size
)
{
tty
->
print_cr
(
"WARNING: the _header and _owner fields are closer "
"than a cache line which permits false sharing."
);
warning_cnt
++
;
}
if
((
sizeof
(
ObjectMonitor
)
%
cache_line_size
)
!=
0
)
{
tty
->
print_cr
(
"WARNING: ObjectMonitor size is not a multiple of "
"a cache line which permits false sharing."
);
warning_cnt
++
;
}
}
ObjectSynchronizer
::
sanity_checks
(
verbose
,
cache_line_size
,
&
error_cnt
,
&
warning_cnt
);
if
(
verbose
||
error_cnt
!=
0
||
warning_cnt
!=
0
)
{
tty
->
print_cr
(
"INFO: error_cnt=%d"
,
error_cnt
);
tty
->
print_cr
(
"INFO: warning_cnt=%d"
,
warning_cnt
);
}
guarantee
(
error_cnt
==
0
,
"Fatal error(s) found in ObjectMonitor::sanity_checks()"
);
}
#ifndef PRODUCT
#ifndef PRODUCT
void
ObjectMonitor
::
verify
()
{
void
ObjectMonitor
::
verify
()
{
}
}
...
...
src/share/vm/runtime/objectMonitor.hpp
浏览文件 @
e0052d8a
...
@@ -189,6 +189,8 @@ public:
...
@@ -189,6 +189,8 @@ public:
bool
check
(
TRAPS
);
// true if the thread owns the monitor.
bool
check
(
TRAPS
);
// true if the thread owns the monitor.
void
check_slow
(
TRAPS
);
void
check_slow
(
TRAPS
);
void
clear
();
void
clear
();
static
void
sanity_checks
();
// public for -XX:+ExecuteInternalVMTests
// in PRODUCT for -XX:SyncKnobs=Verbose=1
#ifndef PRODUCT
#ifndef PRODUCT
void
verify
();
void
verify
();
void
print
();
void
print
();
...
@@ -234,8 +236,6 @@ public:
...
@@ -234,8 +236,6 @@ public:
// WARNING: this must be the very first word of ObjectMonitor
// WARNING: this must be the very first word of ObjectMonitor
// This means this class can't use any virtual member functions.
// This means this class can't use any virtual member functions.
// TODO-FIXME: assert that offsetof(_header) is 0 or get rid of the
// implicit 0 offset in emitted code.
volatile
markOop
_header
;
// displaced object header word - mark
volatile
markOop
_header
;
// displaced object header word - mark
void
*
volatile
_object
;
// backward object pointer - strong root
void
*
volatile
_object
;
// backward object pointer - strong root
...
...
src/share/vm/runtime/synchronizer.cpp
浏览文件 @
e0052d8a
...
@@ -437,19 +437,22 @@ void ObjectSynchronizer::notifyall(Handle obj, TRAPS) {
...
@@ -437,19 +437,22 @@ void ObjectSynchronizer::notifyall(Handle obj, TRAPS) {
// Hash Code handling
// Hash Code handling
//
//
// Performance concern:
// Performance concern:
// OrderAccess::storestore() calls release() which STs 0 into the global volatile
// OrderAccess::storestore() calls release() which at one time stored 0
// OrderAccess::Dummy variable. This store is unnecessary for correctness.
// into the global volatile OrderAccess::dummy variable. This store was
// Many threads STing into a common location causes considerable cache migration
// unnecessary for correctness. Many threads storing into a common location
// or "sloshing" on large SMP system. As such, I avoid using OrderAccess::storestore()
// causes considerable cache migration or "sloshing" on large SMP systems.
// until it's repaired. In some cases OrderAccess::fence() -- which incurs local
// As such, I avoided using OrderAccess::storestore(). In some cases
// latency on the executing processor -- is a better choice as it scales on SMP
// OrderAccess::fence() -- which incurs local latency on the executing
// systems. See http://blogs.sun.com/dave/entry/biased_locking_in_hotspot for a
// processor -- is a better choice as it scales on SMP systems.
// discussion of coherency costs. Note that all our current reference platforms
//
// provide strong ST-ST order, so the issue is moot on IA32, x64, and SPARC.
// See http://blogs.oracle.com/dave/entry/biased_locking_in_hotspot for
// a discussion of coherency costs. Note that all our current reference
// platforms provide strong ST-ST order, so the issue is moot on IA32,
// x64, and SPARC.
//
//
// As a general policy we use "volatile" to control compiler-based reordering
// As a general policy we use "volatile" to control compiler-based reordering
// and explicit fences (barriers) to control for architectural reordering
performed
// and explicit fences (barriers) to control for architectural reordering
// by the CPU(s) or platform.
//
performed
by the CPU(s) or platform.
struct
SharedGlobals
{
struct
SharedGlobals
{
// These are highly shared mostly-read variables.
// These are highly shared mostly-read variables.
...
@@ -1636,7 +1639,55 @@ void ObjectSynchronizer::release_monitors_owned_by_thread(TRAPS) {
...
@@ -1636,7 +1639,55 @@ void ObjectSynchronizer::release_monitors_owned_by_thread(TRAPS) {
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Non-product code
// Debugging code
void
ObjectSynchronizer
::
sanity_checks
(
const
bool
verbose
,
const
uint
cache_line_size
,
int
*
error_cnt_ptr
,
int
*
warning_cnt_ptr
)
{
u_char
*
addr_begin
=
(
u_char
*
)
&
GVars
;
u_char
*
addr_stwRandom
=
(
u_char
*
)
&
GVars
.
stwRandom
;
u_char
*
addr_hcSequence
=
(
u_char
*
)
&
GVars
.
hcSequence
;
if
(
verbose
)
{
tty
->
print_cr
(
"INFO: sizeof(SharedGlobals)="
SIZE_FORMAT
,
sizeof
(
SharedGlobals
));
}
uint
offset_stwRandom
=
(
uint
)(
addr_stwRandom
-
addr_begin
);
if
(
verbose
)
tty
->
print_cr
(
"INFO: offset(stwRandom)=%u"
,
offset_stwRandom
);
uint
offset_hcSequence
=
(
uint
)(
addr_hcSequence
-
addr_begin
);
if
(
verbose
)
{
tty
->
print_cr
(
"INFO: offset(_hcSequence)=%u"
,
offset_hcSequence
);
}
if
(
cache_line_size
!=
0
)
{
// We were able to determine the L1 data cache line size so
// do some cache line specific sanity checks
if
(
offset_stwRandom
<
cache_line_size
)
{
tty
->
print_cr
(
"WARNING: the SharedGlobals.stwRandom field is closer "
"to the struct beginning than a cache line which permits "
"false sharing."
);
(
*
warning_cnt_ptr
)
++
;
}
if
((
offset_hcSequence
-
offset_stwRandom
)
<
cache_line_size
)
{
tty
->
print_cr
(
"WARNING: the SharedGlobals.stwRandom and "
"SharedGlobals.hcSequence fields are closer than a cache "
"line which permits false sharing."
);
(
*
warning_cnt_ptr
)
++
;
}
if
((
sizeof
(
SharedGlobals
)
-
offset_hcSequence
)
<
cache_line_size
)
{
tty
->
print_cr
(
"WARNING: the SharedGlobals.hcSequence field is closer "
"to the struct end than a cache line which permits false "
"sharing."
);
(
*
warning_cnt_ptr
)
++
;
}
}
}
#ifndef PRODUCT
#ifndef PRODUCT
...
...
src/share/vm/runtime/synchronizer.hpp
浏览文件 @
e0052d8a
...
@@ -121,6 +121,9 @@ class ObjectSynchronizer : AllStatic {
...
@@ -121,6 +121,9 @@ class ObjectSynchronizer : AllStatic {
static
void
oops_do
(
OopClosure
*
f
);
static
void
oops_do
(
OopClosure
*
f
);
// debugging
// debugging
static
void
sanity_checks
(
const
bool
verbose
,
const
unsigned
int
cache_line_size
,
int
*
error_cnt_ptr
,
int
*
warning_cnt_ptr
);
static
void
verify
()
PRODUCT_RETURN
;
static
void
verify
()
PRODUCT_RETURN
;
static
int
verify_objmon_isinpool
(
ObjectMonitor
*
addr
)
PRODUCT_RETURN0
;
static
int
verify_objmon_isinpool
(
ObjectMonitor
*
addr
)
PRODUCT_RETURN0
;
...
...
src/share/vm/runtime/vmStructs.cpp
浏览文件 @
e0052d8a
/*
/*
* Copyright (c) 2000, 201
5
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -879,7 +879,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
...
@@ -879,7 +879,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
nonstatic_field(nmethod, _stack_traversal_mark, long) \
nonstatic_field(nmethod, _stack_traversal_mark, long) \
nonstatic_field(nmethod, _compile_id, int) \
nonstatic_field(nmethod, _compile_id, int) \
nonstatic_field(nmethod, _comp_level, int) \
nonstatic_field(nmethod, _comp_level, int) \
nonstatic_field(nmethod,
_exception_cache, ExceptionCache*) \
volatile_nonstatic_field(nmethod,
_exception_cache, ExceptionCache*) \
nonstatic_field(nmethod, _marked_for_deoptimization, bool) \
nonstatic_field(nmethod, _marked_for_deoptimization, bool) \
\
\
unchecked_c2_static_field(Deoptimization, _trap_reason_name, void*) \
unchecked_c2_static_field(Deoptimization, _trap_reason_name, void*) \
...
...
src/share/vm/runtime/vm_version.cpp
浏览文件 @
e0052d8a
...
@@ -50,6 +50,7 @@ bool Abstract_VM_Version::_supports_atomic_getset8 = false;
...
@@ -50,6 +50,7 @@ bool Abstract_VM_Version::_supports_atomic_getset8 = false;
bool
Abstract_VM_Version
::
_supports_atomic_getadd4
=
false
;
bool
Abstract_VM_Version
::
_supports_atomic_getadd4
=
false
;
bool
Abstract_VM_Version
::
_supports_atomic_getadd8
=
false
;
bool
Abstract_VM_Version
::
_supports_atomic_getadd8
=
false
;
unsigned
int
Abstract_VM_Version
::
_logical_processors_per_package
=
1U
;
unsigned
int
Abstract_VM_Version
::
_logical_processors_per_package
=
1U
;
unsigned
int
Abstract_VM_Version
::
_L1_data_cache_line_size
=
0
;
int
Abstract_VM_Version
::
_reserve_for_allocation_prefetch
=
0
;
int
Abstract_VM_Version
::
_reserve_for_allocation_prefetch
=
0
;
#ifndef HOTSPOT_RELEASE_VERSION
#ifndef HOTSPOT_RELEASE_VERSION
...
...
src/share/vm/runtime/vm_version.hpp
浏览文件 @
e0052d8a
/*
/*
* Copyright (c) 1997, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
4
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -42,6 +42,7 @@ class Abstract_VM_Version: AllStatic {
...
@@ -42,6 +42,7 @@ class Abstract_VM_Version: AllStatic {
static
bool
_supports_atomic_getadd4
;
static
bool
_supports_atomic_getadd4
;
static
bool
_supports_atomic_getadd8
;
static
bool
_supports_atomic_getadd8
;
static
unsigned
int
_logical_processors_per_package
;
static
unsigned
int
_logical_processors_per_package
;
static
unsigned
int
_L1_data_cache_line_size
;
static
int
_vm_major_version
;
static
int
_vm_major_version
;
static
int
_vm_minor_version
;
static
int
_vm_minor_version
;
static
int
_vm_build_number
;
static
int
_vm_build_number
;
...
@@ -114,6 +115,10 @@ class Abstract_VM_Version: AllStatic {
...
@@ -114,6 +115,10 @@ class Abstract_VM_Version: AllStatic {
return
_logical_processors_per_package
;
return
_logical_processors_per_package
;
}
}
static
unsigned
int
L1_data_cache_line_size
()
{
return
_L1_data_cache_line_size
;
}
// Need a space at the end of TLAB for prefetch instructions
// Need a space at the end of TLAB for prefetch instructions
// which may fault when accessing memory outside of heap.
// which may fault when accessing memory outside of heap.
static
int
reserve_for_allocation_prefetch
()
{
static
int
reserve_for_allocation_prefetch
()
{
...
...
test/compiler/c1/TestUnresolvedField.jasm
0 → 100644
浏览文件 @
e0052d8a
/*
* Copyright (c) 2017, 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.
*
*/
public class compiler/c1/TestUnresolvedField version 52:0 {
public static Method testGetField:"()V" stack 1 locals 1 {
aconst_null;
getfield Field T.f:I; // T does not exist
return;
}
public static Method testPutField:"()V" stack 2 locals 1 {
aconst_null;
iconst_0;
putfield Field T.f:I; // T does not exist
return;
}
}
test/compiler/c1/TestUnresolvedFieldMain.java
0 → 100644
浏览文件 @
e0052d8a
/*
* Copyright (c) 2017, 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 8173373
* @compile TestUnresolvedField.jasm
* @run main/othervm -XX:TieredStopAtLevel=1 -Xcomp
* -XX:CompileCommand=compileonly,compiler.c1.TestUnresolvedField::test*
* compiler.c1.TestUnresolvedFieldMain
*/
package
compiler.c1
;
public
class
TestUnresolvedFieldMain
{
public
static
void
main
(
String
[]
args
)
{
try
{
TestUnresolvedField
.
testGetField
();
}
catch
(
java
.
lang
.
NoClassDefFoundError
error
)
{
// Expected
}
try
{
TestUnresolvedField
.
testPutField
();
}
catch
(
java
.
lang
.
NoClassDefFoundError
error
)
{
// Expected
}
}
}
test/compiler/loopopts/TestLoopPeeling.java
浏览文件 @
e0052d8a
/*
/*
* Copyright (c) 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -23,10 +23,16 @@
...
@@ -23,10 +23,16 @@
/*
/*
* @test
* @test
* @bug 8078262
* @bug 8078262
8177095
* @summary Tests correct dominator information after loop peeling.
* @summary Tests correct dominator information after loop peeling.
* @run main/othervm -Xcomp -XX:CompileCommand=compileonly,TestLoopPeeling::test* TestLoopPeeling
*
* @run main/othervm -Xcomp
* -XX:CompileCommand=compileonly,compiler.loopopts.TestLoopPeeling::test*
* compiler.loopopts.TestLoopPeeling
*/
*/
package
compiler.loopopts
;
public
class
TestLoopPeeling
{
public
class
TestLoopPeeling
{
public
int
[]
array
=
new
int
[
100
];
public
int
[]
array
=
new
int
[
100
];
...
@@ -34,14 +40,16 @@ public class TestLoopPeeling {
...
@@ -34,14 +40,16 @@ public class TestLoopPeeling {
public
static
void
main
(
String
args
[])
{
public
static
void
main
(
String
args
[])
{
TestLoopPeeling
test
=
new
TestLoopPeeling
();
TestLoopPeeling
test
=
new
TestLoopPeeling
();
try
{
try
{
test
.
testArrayAccess
(
0
,
1
);
test
.
testArrayAccess1
(
0
,
1
);
test
.
testArrayAccess2
(
0
);
test
.
testArrayAccess3
(
0
,
false
);
test
.
testArrayAllocation
(
0
,
1
);
test
.
testArrayAllocation
(
0
,
1
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
// Ignore exceptions
// Ignore exceptions
}
}
}
}
public
void
testArrayAccess
(
int
index
,
int
inc
)
{
public
void
testArrayAccess
1
(
int
index
,
int
inc
)
{
int
storeIndex
=
-
1
;
int
storeIndex
=
-
1
;
for
(;
index
<
10
;
index
+=
inc
)
{
for
(;
index
<
10
;
index
+=
inc
)
{
...
@@ -57,7 +65,7 @@ public class TestLoopPeeling {
...
@@ -57,7 +65,7 @@ public class TestLoopPeeling {
if
(
index
==
42
)
{
if
(
index
==
42
)
{
// This store and the corresponding range check are moved out of the
// This store and the corresponding range check are moved out of the
// loop and both used after
old
loop and the peeled iteration exit.
// loop and both used after
main
loop and the peeled iteration exit.
// For the peeled iteration, storeIndex is always -1 and the ConvI2L
// For the peeled iteration, storeIndex is always -1 and the ConvI2L
// is replaced by TOP. However, the range check is not folded because
// is replaced by TOP. However, the range check is not folded because
// we don't do the split if optimization in PhaseIdealLoop2.
// we don't do the split if optimization in PhaseIdealLoop2.
...
@@ -71,6 +79,44 @@ public class TestLoopPeeling {
...
@@ -71,6 +79,44 @@ public class TestLoopPeeling {
}
}
}
}
public
int
testArrayAccess2
(
int
index
)
{
// Load1 and the corresponding range check are moved out of the loop
// and both are used after the main loop and the peeled iteration exit.
// For the peeled iteration, storeIndex is always Integer.MIN_VALUE and
// for the main loop it is 0. Hence, the merging phi has type int:<=0.
// Load1 reads the array at index ConvI2L(CastII(AddI(storeIndex, -1)))
// where the CastII is range check dependent and has type int:>=0.
// The CastII gets pushed through the AddI and its type is changed to int:>=1
// which does not overlap with the input type of storeIndex (int:<=0).
// The CastII is replaced by TOP causing a cascade of other eliminations.
// Since the control path through the range check CmpU(AddI(storeIndex, -1))
// is not eliminated, the graph is in a corrupted state. We fail once we merge
// with the result of Load2 because we get data from a non-dominating region.
int
storeIndex
=
Integer
.
MIN_VALUE
;
for
(;
index
<
10
;
++
index
)
{
if
(
index
==
42
)
{
return
array
[
storeIndex
-
1
];
// Load1
}
storeIndex
=
0
;
}
return
array
[
42
];
// Load2
}
public
int
testArrayAccess3
(
int
index
,
boolean
b
)
{
// Same as testArrayAccess2 but manifests as crash in register allocator.
int
storeIndex
=
Integer
.
MIN_VALUE
;
for
(;
index
<
10
;
++
index
)
{
if
(
b
)
{
return
0
;
}
if
(
index
==
42
)
{
return
array
[
storeIndex
-
1
];
// Load1
}
storeIndex
=
0
;
}
return
array
[
42
];
// Load2
}
public
byte
[]
testArrayAllocation
(
int
index
,
int
inc
)
{
public
byte
[]
testArrayAllocation
(
int
index
,
int
inc
)
{
int
allocationCount
=
-
1
;
int
allocationCount
=
-
1
;
byte
[]
result
;
byte
[]
result
;
...
@@ -82,7 +128,7 @@ public class TestLoopPeeling {
...
@@ -82,7 +128,7 @@ public class TestLoopPeeling {
if
(
index
==
42
)
{
if
(
index
==
42
)
{
// This allocation and the corresponding size check are moved out of the
// This allocation and the corresponding size check are moved out of the
// loop and both used after
old
loop and the peeled iteration exit.
// loop and both used after
main
loop and the peeled iteration exit.
// For the peeled iteration, allocationCount is always -1 and the ConvI2L
// For the peeled iteration, allocationCount is always -1 and the ConvI2L
// is replaced by TOP. However, the size check is not folded because
// is replaced by TOP. However, the size check is not folded because
// we don't do the split if optimization in PhaseIdealLoop2.
// we don't do the split if optimization in PhaseIdealLoop2.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录