Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
c4ea8057
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看板
提交
c4ea8057
编写于
9月 18, 2013
作者:
Z
zgu
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
4bbfb70f
23e0d420
变更
32
显示空白变更内容
内联
并排
Showing
32 changed file
with
1105 addition
and
390 deletion
+1105
-390
make/bsd/makefiles/gcc.make
make/bsd/makefiles/gcc.make
+8
-1
src/os/linux/vm/os_linux.cpp
src/os/linux/vm/os_linux.cpp
+150
-56
src/os/linux/vm/os_linux.hpp
src/os/linux/vm/os_linux.hpp
+20
-5
src/os/windows/vm/decoder_windows.cpp
src/os/windows/vm/decoder_windows.cpp
+86
-5
src/os/windows/vm/decoder_windows.hpp
src/os/windows/vm/decoder_windows.hpp
+41
-0
src/os_cpu/windows_x86/vm/os_windows_x86.cpp
src/os_cpu/windows_x86/vm/os_windows_x86.cpp
+92
-0
src/os_cpu/windows_x86/vm/os_windows_x86.hpp
src/os_cpu/windows_x86/vm/os_windows_x86.hpp
+6
-0
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+56
-15
src/share/vm/classfile/defaultMethods.cpp
src/share/vm/classfile/defaultMethods.cpp
+13
-5
src/share/vm/prims/jni.cpp
src/share/vm/prims/jni.cpp
+2
-0
src/share/vm/prims/jvmtiRedefineClasses.cpp
src/share/vm/prims/jvmtiRedefineClasses.cpp
+41
-13
src/share/vm/runtime/arguments.cpp
src/share/vm/runtime/arguments.cpp
+53
-1
src/share/vm/runtime/frame.cpp
src/share/vm/runtime/frame.cpp
+1
-1
src/share/vm/runtime/frame.hpp
src/share/vm/runtime/frame.hpp
+1
-0
src/share/vm/runtime/os.hpp
src/share/vm/runtime/os.hpp
+8
-0
src/share/vm/runtime/thread.cpp
src/share/vm/runtime/thread.cpp
+2
-0
src/share/vm/services/gcNotifier.cpp
src/share/vm/services/gcNotifier.cpp
+1
-1
src/share/vm/services/memPtr.cpp
src/share/vm/services/memPtr.cpp
+3
-3
src/share/vm/trace/traceMacros.hpp
src/share/vm/trace/traceMacros.hpp
+1
-0
src/share/vm/utilities/decoder.cpp
src/share/vm/utilities/decoder.cpp
+17
-1
src/share/vm/utilities/decoder.hpp
src/share/vm/utilities/decoder.hpp
+14
-0
src/share/vm/utilities/ostream.cpp
src/share/vm/utilities/ostream.cpp
+290
-93
src/share/vm/utilities/ostream.hpp
src/share/vm/utilities/ostream.hpp
+11
-7
src/share/vm/utilities/vmError.cpp
src/share/vm/utilities/vmError.cpp
+5
-0
src/share/vm/utilities/vmError.hpp
src/share/vm/utilities/vmError.hpp
+4
-0
test/runtime/6878713/Test6878713.sh
test/runtime/6878713/Test6878713.sh
+0
-137
test/runtime/7020373/Test7020373.sh
test/runtime/7020373/Test7020373.sh
+0
-43
test/runtime/ClassFile/JsrRewriting.java
test/runtime/ClassFile/JsrRewriting.java
+102
-0
test/runtime/ClassFile/JsrRewritingTestCase.jar
test/runtime/ClassFile/JsrRewritingTestCase.jar
+0
-0
test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java
test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java
+74
-0
test/runtime/ClassFile/testcase.jar
test/runtime/ClassFile/testcase.jar
+0
-0
test/runtime/InitialThreadOverflow/testme.sh
test/runtime/InitialThreadOverflow/testme.sh
+3
-3
未找到文件。
make/bsd/makefiles/gcc.make
浏览文件 @
c4ea8057
...
...
@@ -80,7 +80,7 @@ ifeq ($(SPEC),)
HOSTCC
=
$(CC)
endif
AS
=
$(CC)
-c
-x
assembler-with-cpp
AS
=
$(CC)
-c
endif
...
...
@@ -347,6 +347,13 @@ ifeq ($(OS_VENDOR), Darwin)
LDFLAGS
+=
-mmacosx-version-min
=
$(MACOSX_VERSION_MIN)
endif
#------------------------------------------------------------------------
# Assembler flags
# Enforce prerpocessing of .s files
ASFLAGS
+=
-x
assembler-with-cpp
#------------------------------------------------------------------------
# Linker flags
...
...
src/os/linux/vm/os_linux.cpp
浏览文件 @
c4ea8057
...
...
@@ -131,6 +131,7 @@ bool os::Linux::_is_NPTL = false;
bool
os
::
Linux
::
_supports_fast_thread_cpu_time
=
false
;
const
char
*
os
::
Linux
::
_glibc_version
=
NULL
;
const
char
*
os
::
Linux
::
_libpthread_version
=
NULL
;
pthread_condattr_t
os
::
Linux
::
_condattr
[
1
];
static
jlong
initial_time_count
=
0
;
...
...
@@ -1399,12 +1400,15 @@ void os::Linux::clock_init() {
clock_gettime_func
(
CLOCK_MONOTONIC
,
&
tp
)
==
0
)
{
// yes, monotonic clock is supported
_clock_gettime
=
clock_gettime_func
;
return
;
}
else
{
// close librt if there is no monotonic clock
dlclose
(
handle
);
}
}
}
warning
(
"No monotonic clock was available - timed services may "
\
"be adversely affected if the time-of-day clock changes"
);
}
#ifndef SYS_clock_getres
...
...
@@ -2165,22 +2169,48 @@ void os::print_os_info(outputStream* st) {
}
// Try to identify popular distros.
// Most Linux distributions have /etc/XXX-release file, which contains
// the OS version string. Some have more than one /etc/XXX-release file
// (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.),
// so the order is important.
// Most Linux distributions have a /etc/XXX-release file, which contains
// the OS version string. Newer Linux distributions have a /etc/lsb-release
// file that also contains the OS version string. Some have more than one
// /etc/XXX-release file (e.g. Mandrake has both /etc/mandrake-release and
// /etc/redhat-release.), so the order is important.
// Any Linux that is based on Redhat (i.e. Oracle, Mandrake, Sun JDS...) have
// their own specific XXX-release file as well as a redhat-release file.
// Because of this the XXX-release file needs to be searched for before the
// redhat-release file.
// Since Red Hat has a lsb-release file that is not very descriptive the
// search for redhat-release needs to be before lsb-release.
// Since the lsb-release file is the new standard it needs to be searched
// before the older style release files.
// Searching system-release (Red Hat) and os-release (other Linuxes) are a
// next to last resort. The os-release file is a new standard that contains
// distribution information and the system-release file seems to be an old
// standard that has been replaced by the lsb-release and os-release files.
// Searching for the debian_version file is the last resort. It contains
// an informative string like "6.0.6" or "wheezy/sid". Because of this
// "Debian " is printed before the contents of the debian_version file.
void
os
::
Linux
::
print_distro_info
(
outputStream
*
st
)
{
if
(
!
_print_ascii_file
(
"/etc/mandrake-release"
,
st
)
&&
if
(
!
_print_ascii_file
(
"/etc/oracle-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/mandriva-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/mandrake-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/sun-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/redhat-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/lsb-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/SuSE-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/turbolinux-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/gentoo-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/debian_version"
,
st
)
&&
!
_print_ascii_file
(
"/etc/ltib-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/angstrom-version"
,
st
))
{
!
_print_ascii_file
(
"/etc/angstrom-version"
,
st
)
&&
!
_print_ascii_file
(
"/etc/system-release"
,
st
)
&&
!
_print_ascii_file
(
"/etc/os-release"
,
st
))
{
if
(
file_exists
(
"/etc/debian_version"
))
{
st
->
print
(
"Debian "
);
_print_ascii_file
(
"/etc/debian_version"
,
st
);
}
else
{
st
->
print
(
"Linux"
);
}
}
st
->
cr
();
}
...
...
@@ -4709,6 +4739,26 @@ void os::init(void) {
Linux
::
clock_init
();
initial_time_count
=
os
::
elapsed_counter
();
// pthread_condattr initialization for monotonic clock
int
status
;
pthread_condattr_t
*
_condattr
=
os
::
Linux
::
condAttr
();
if
((
status
=
pthread_condattr_init
(
_condattr
))
!=
0
)
{
fatal
(
err_msg
(
"pthread_condattr_init: %s"
,
strerror
(
status
)));
}
// Only set the clock if CLOCK_MONOTONIC is available
if
(
Linux
::
supports_monotonic_clock
())
{
if
((
status
=
pthread_condattr_setclock
(
_condattr
,
CLOCK_MONOTONIC
))
!=
0
)
{
if
(
status
==
EINVAL
)
{
warning
(
"Unable to use monotonic clock with relative timed-waits"
\
" - changes to the time-of-day clock may have adverse affects"
);
}
else
{
fatal
(
err_msg
(
"pthread_condattr_setclock: %s"
,
strerror
(
status
)));
}
}
}
// else it defaults to CLOCK_REALTIME
pthread_mutex_init
(
&
dl_mutex
,
NULL
);
// If the pagesize of the VM is greater than 8K determine the appropriate
...
...
@@ -5519,14 +5569,28 @@ void os::pause() {
static
struct
timespec
*
compute_abstime
(
timespec
*
abstime
,
jlong
millis
)
{
if
(
millis
<
0
)
millis
=
0
;
struct
timeval
now
;
int
status
=
gettimeofday
(
&
now
,
NULL
);
assert
(
status
==
0
,
"gettimeofday"
);
jlong
seconds
=
millis
/
1000
;
millis
%=
1000
;
if
(
seconds
>
50000000
)
{
// see man cond_timedwait(3T)
seconds
=
50000000
;
}
if
(
os
::
Linux
::
supports_monotonic_clock
())
{
struct
timespec
now
;
int
status
=
os
::
Linux
::
clock_gettime
(
CLOCK_MONOTONIC
,
&
now
);
assert_status
(
status
==
0
,
status
,
"clock_gettime"
);
abstime
->
tv_sec
=
now
.
tv_sec
+
seconds
;
long
nanos
=
now
.
tv_nsec
+
millis
*
NANOSECS_PER_MILLISEC
;
if
(
nanos
>=
NANOSECS_PER_SEC
)
{
abstime
->
tv_sec
+=
1
;
nanos
-=
NANOSECS_PER_SEC
;
}
abstime
->
tv_nsec
=
nanos
;
}
else
{
struct
timeval
now
;
int
status
=
gettimeofday
(
&
now
,
NULL
);
assert
(
status
==
0
,
"gettimeofday"
);
abstime
->
tv_sec
=
now
.
tv_sec
+
seconds
;
long
usec
=
now
.
tv_usec
+
millis
*
1000
;
if
(
usec
>=
1000000
)
{
...
...
@@ -5534,6 +5598,7 @@ static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
usec
-=
1000000
;
}
abstime
->
tv_nsec
=
usec
*
1000
;
}
return
abstime
;
}
...
...
@@ -5625,7 +5690,7 @@ int os::PlatformEvent::park(jlong millis) {
status
=
os
::
Linux
::
safe_cond_timedwait
(
_cond
,
_mutex
,
&
abst
);
if
(
status
!=
0
&&
WorkAroundNPTLTimedWaitHang
)
{
pthread_cond_destroy
(
_cond
);
pthread_cond_init
(
_cond
,
NULL
)
;
pthread_cond_init
(
_cond
,
os
::
Linux
::
condAttr
()
)
;
}
assert_status
(
status
==
0
||
status
==
EINTR
||
status
==
ETIME
||
status
==
ETIMEDOUT
,
...
...
@@ -5726,30 +5791,29 @@ void os::PlatformEvent::unpark() {
static
void
unpackTime
(
timespec
*
absTime
,
bool
isAbsolute
,
jlong
time
)
{
assert
(
time
>
0
,
"convertTime"
);
time_t
max_secs
=
0
;
if
(
!
os
::
Linux
::
supports_monotonic_clock
()
||
isAbsolute
)
{
struct
timeval
now
;
int
status
=
gettimeofday
(
&
now
,
NULL
);
assert
(
status
==
0
,
"gettimeofday"
);
time_t
max_secs
=
now
.
tv_sec
+
MAX_SECS
;
max_secs
=
now
.
tv_sec
+
MAX_SECS
;
if
(
isAbsolute
)
{
jlong
secs
=
time
/
1000
;
if
(
secs
>
max_secs
)
{
absTime
->
tv_sec
=
max_secs
;
}
else
{
}
else
{
absTime
->
tv_sec
=
secs
;
}
absTime
->
tv_nsec
=
(
time
%
1000
)
*
NANOSECS_PER_MILLISEC
;
}
else
{
}
else
{
jlong
secs
=
time
/
NANOSECS_PER_SEC
;
if
(
secs
>=
MAX_SECS
)
{
absTime
->
tv_sec
=
max_secs
;
absTime
->
tv_nsec
=
0
;
}
else
{
}
else
{
absTime
->
tv_sec
=
now
.
tv_sec
+
secs
;
absTime
->
tv_nsec
=
(
time
%
NANOSECS_PER_SEC
)
+
now
.
tv_usec
*
1000
;
if
(
absTime
->
tv_nsec
>=
NANOSECS_PER_SEC
)
{
...
...
@@ -5758,6 +5822,25 @@ static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
}
}
}
}
else
{
// must be relative using monotonic clock
struct
timespec
now
;
int
status
=
os
::
Linux
::
clock_gettime
(
CLOCK_MONOTONIC
,
&
now
);
assert_status
(
status
==
0
,
status
,
"clock_gettime"
);
max_secs
=
now
.
tv_sec
+
MAX_SECS
;
jlong
secs
=
time
/
NANOSECS_PER_SEC
;
if
(
secs
>=
MAX_SECS
)
{
absTime
->
tv_sec
=
max_secs
;
absTime
->
tv_nsec
=
0
;
}
else
{
absTime
->
tv_sec
=
now
.
tv_sec
+
secs
;
absTime
->
tv_nsec
=
(
time
%
NANOSECS_PER_SEC
)
+
now
.
tv_nsec
;
if
(
absTime
->
tv_nsec
>=
NANOSECS_PER_SEC
)
{
absTime
->
tv_nsec
-=
NANOSECS_PER_SEC
;
++
absTime
->
tv_sec
;
// note: this must be <= max_secs
}
}
}
assert
(
absTime
->
tv_sec
>=
0
,
"tv_sec < 0"
);
assert
(
absTime
->
tv_sec
<=
max_secs
,
"tv_sec > max_secs"
);
assert
(
absTime
->
tv_nsec
>=
0
,
"tv_nsec < 0"
);
...
...
@@ -5831,15 +5914,19 @@ void Parker::park(bool isAbsolute, jlong time) {
jt
->
set_suspend_equivalent
();
// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
assert
(
_cur_index
==
-
1
,
"invariant"
);
if
(
time
==
0
)
{
status
=
pthread_cond_wait
(
_cond
,
_mutex
)
;
_cur_index
=
REL_INDEX
;
// arbitrary choice when not timed
status
=
pthread_cond_wait
(
&
_cond
[
_cur_index
],
_mutex
)
;
}
else
{
status
=
os
::
Linux
::
safe_cond_timedwait
(
_cond
,
_mutex
,
&
absTime
)
;
_cur_index
=
isAbsolute
?
ABS_INDEX
:
REL_INDEX
;
status
=
os
::
Linux
::
safe_cond_timedwait
(
&
_cond
[
_cur_index
],
_mutex
,
&
absTime
)
;
if
(
status
!=
0
&&
WorkAroundNPTLTimedWaitHang
)
{
pthread_cond_destroy
(
_cond
)
;
pthread_cond_init
(
_cond
,
NULL
);
pthread_cond_destroy
(
&
_cond
[
_cur_index
]
)
;
pthread_cond_init
(
&
_cond
[
_cur_index
],
isAbsolute
?
NULL
:
os
::
Linux
::
condAttr
()
);
}
}
_cur_index
=
-
1
;
assert_status
(
status
==
0
||
status
==
EINTR
||
status
==
ETIME
||
status
==
ETIMEDOUT
,
status
,
"cond_timedwait"
);
...
...
@@ -5868,15 +5955,22 @@ void Parker::unpark() {
s
=
_counter
;
_counter
=
1
;
if
(
s
<
1
)
{
// thread might be parked
if
(
_cur_index
!=
-
1
)
{
// thread is definitely parked
if
(
WorkAroundNPTLTimedWaitHang
)
{
status
=
pthread_cond_signal
(
_cond
)
;
assert
(
status
==
0
,
"invariant"
)
;
status
=
pthread_cond_signal
(
&
_cond
[
_cur_index
])
;
assert
(
status
==
0
,
"invariant"
);
status
=
pthread_mutex_unlock
(
_mutex
);
assert
(
status
==
0
,
"invariant"
)
;
assert
(
status
==
0
,
"invariant"
);
}
else
{
status
=
pthread_mutex_unlock
(
_mutex
);
assert
(
status
==
0
,
"invariant"
)
;
status
=
pthread_cond_signal
(
_cond
)
;
assert
(
status
==
0
,
"invariant"
);
status
=
pthread_cond_signal
(
&
_cond
[
_cur_index
]);
assert
(
status
==
0
,
"invariant"
);
}
}
else
{
pthread_mutex_unlock
(
_mutex
);
assert
(
status
==
0
,
"invariant"
)
;
}
}
else
{
...
...
src/os/linux/vm/os_linux.hpp
浏览文件 @
c4ea8057
...
...
@@ -221,6 +221,13 @@ class Linux {
static
jlong
fast_thread_cpu_time
(
clockid_t
clockid
);
// pthread_cond clock suppport
private:
static
pthread_condattr_t
_condattr
[
1
];
public:
static
pthread_condattr_t
*
condAttr
()
{
return
_condattr
;
}
// Stack repair handling
// none present
...
...
@@ -295,7 +302,7 @@ class PlatformEvent : public CHeapObj<mtInternal> {
public:
PlatformEvent
()
{
int
status
;
status
=
pthread_cond_init
(
_cond
,
NULL
);
status
=
pthread_cond_init
(
_cond
,
os
::
Linux
::
condAttr
()
);
assert_status
(
status
==
0
,
status
,
"cond_init"
);
status
=
pthread_mutex_init
(
_mutex
,
NULL
);
assert_status
(
status
==
0
,
status
,
"mutex_init"
);
...
...
@@ -310,14 +317,19 @@ class PlatformEvent : public CHeapObj<mtInternal> {
void
park
()
;
void
unpark
()
;
int
TryPark
()
;
int
park
(
jlong
millis
)
;
int
park
(
jlong
millis
)
;
// relative timed-wait only
void
SetAssociation
(
Thread
*
a
)
{
_Assoc
=
a
;
}
}
;
class
PlatformParker
:
public
CHeapObj
<
mtInternal
>
{
protected:
enum
{
REL_INDEX
=
0
,
ABS_INDEX
=
1
};
int
_cur_index
;
// which cond is in use: -1, 0, 1
pthread_mutex_t
_mutex
[
1
]
;
pthread_cond_t
_cond
[
1
]
;
pthread_cond_t
_cond
[
2
]
;
// one for relative times and one for abs.
public:
// TODO-FIXME: make dtor private
~
PlatformParker
()
{
guarantee
(
0
,
"invariant"
)
;
}
...
...
@@ -325,10 +337,13 @@ class PlatformParker : public CHeapObj<mtInternal> {
public:
PlatformParker
()
{
int
status
;
status
=
pthread_cond_init
(
_cond
,
NULL
);
assert_status
(
status
==
0
,
status
,
"cond_init"
);
status
=
pthread_cond_init
(
&
_cond
[
REL_INDEX
],
os
::
Linux
::
condAttr
());
assert_status
(
status
==
0
,
status
,
"cond_init rel"
);
status
=
pthread_cond_init
(
&
_cond
[
ABS_INDEX
],
NULL
);
assert_status
(
status
==
0
,
status
,
"cond_init abs"
);
status
=
pthread_mutex_init
(
_mutex
,
NULL
);
assert_status
(
status
==
0
,
status
,
"mutex_init"
);
_cur_index
=
-
1
;
// mark as unused
}
};
...
...
src/os/windows/vm/decoder_windows.cpp
浏览文件 @
c4ea8057
...
...
@@ -32,7 +32,11 @@ WindowsDecoder::WindowsDecoder() {
_can_decode_in_vm
=
false
;
_pfnSymGetSymFromAddr64
=
NULL
;
_pfnUndecorateSymbolName
=
NULL
;
#ifdef AMD64
_pfnStackWalk64
=
NULL
;
_pfnSymFunctionTableAccess64
=
NULL
;
_pfnSymGetModuleBase64
=
NULL
;
#endif
_decoder_status
=
no_error
;
initialize
();
}
...
...
@@ -53,14 +57,24 @@ void WindowsDecoder::initialize() {
_pfnUndecorateSymbolName
=
(
pfn_UndecorateSymbolName
)
::
GetProcAddress
(
handle
,
"UnDecorateSymbolName"
);
if
(
_pfnSymSetOptions
==
NULL
||
_pfnSymInitialize
==
NULL
||
_pfnSymGetSymFromAddr64
==
NULL
)
{
_pfnSymGetSymFromAddr64
=
NULL
;
_pfnUndecorateSymbolName
=
NULL
;
::
FreeLibrary
(
handle
);
_dbghelp_handle
=
NULL
;
uninitialize
();
_decoder_status
=
helper_func_error
;
return
;
}
#ifdef AMD64
_pfnStackWalk64
=
(
pfn_StackWalk64
)
::
GetProcAddress
(
handle
,
"StackWalk64"
);
_pfnSymFunctionTableAccess64
=
(
pfn_SymFunctionTableAccess64
)
::
GetProcAddress
(
handle
,
"SymFunctionTableAccess64"
);
_pfnSymGetModuleBase64
=
(
pfn_SymGetModuleBase64
)
::
GetProcAddress
(
handle
,
"SymGetModuleBase64"
);
if
(
_pfnStackWalk64
==
NULL
||
_pfnSymFunctionTableAccess64
==
NULL
||
_pfnSymGetModuleBase64
==
NULL
)
{
// We can't call StackWalk64 to walk the stack, but we are still
// able to decode the symbols. Let's limp on.
_pfnStackWalk64
=
NULL
;
_pfnSymFunctionTableAccess64
=
NULL
;
_pfnSymGetModuleBase64
=
NULL
;
}
#endif
HANDLE
hProcess
=
::
GetCurrentProcess
();
_pfnSymSetOptions
(
SYMOPT_UNDNAME
|
SYMOPT_DEFERRED_LOADS
|
SYMOPT_EXACT_SYMBOLS
);
if
(
!
_pfnSymInitialize
(
hProcess
,
NULL
,
TRUE
))
{
...
...
@@ -156,6 +170,11 @@ void WindowsDecoder::initialize() {
void
WindowsDecoder
::
uninitialize
()
{
_pfnSymGetSymFromAddr64
=
NULL
;
_pfnUndecorateSymbolName
=
NULL
;
#ifdef AMD64
_pfnStackWalk64
=
NULL
;
_pfnSymFunctionTableAccess64
=
NULL
;
_pfnSymGetModuleBase64
=
NULL
;
#endif
if
(
_dbghelp_handle
!=
NULL
)
{
::
FreeLibrary
(
_dbghelp_handle
);
}
...
...
@@ -195,3 +214,65 @@ bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) {
_pfnUndecorateSymbolName
(
symbol
,
buf
,
buflen
,
UNDNAME_COMPLETE
);
}
#ifdef AMD64
BOOL
WindowsDbgHelp
::
StackWalk64
(
DWORD
MachineType
,
HANDLE
hProcess
,
HANDLE
hThread
,
LPSTACKFRAME64
StackFrame
,
PVOID
ContextRecord
,
PREAD_PROCESS_MEMORY_ROUTINE64
ReadMemoryRoutine
,
PFUNCTION_TABLE_ACCESS_ROUTINE64
FunctionTableAccessRoutine
,
PGET_MODULE_BASE_ROUTINE64
GetModuleBaseRoutine
,
PTRANSLATE_ADDRESS_ROUTINE64
TranslateAddress
)
{
DecoderLocker
locker
;
WindowsDecoder
*
wd
=
(
WindowsDecoder
*
)
locker
.
decoder
();
if
(
!
wd
->
has_error
()
&&
wd
->
_pfnStackWalk64
)
{
return
wd
->
_pfnStackWalk64
(
MachineType
,
hProcess
,
hThread
,
StackFrame
,
ContextRecord
,
ReadMemoryRoutine
,
FunctionTableAccessRoutine
,
GetModuleBaseRoutine
,
TranslateAddress
);
}
else
{
return
false
;
}
}
PVOID
WindowsDbgHelp
::
SymFunctionTableAccess64
(
HANDLE
hProcess
,
DWORD64
AddrBase
)
{
DecoderLocker
locker
;
WindowsDecoder
*
wd
=
(
WindowsDecoder
*
)
locker
.
decoder
();
if
(
!
wd
->
has_error
()
&&
wd
->
_pfnSymFunctionTableAccess64
)
{
return
wd
->
_pfnSymFunctionTableAccess64
(
hProcess
,
AddrBase
);
}
else
{
return
NULL
;
}
}
pfn_SymFunctionTableAccess64
WindowsDbgHelp
::
pfnSymFunctionTableAccess64
()
{
DecoderLocker
locker
;
WindowsDecoder
*
wd
=
(
WindowsDecoder
*
)
locker
.
decoder
();
if
(
!
wd
->
has_error
())
{
return
wd
->
_pfnSymFunctionTableAccess64
;
}
else
{
return
NULL
;
}
}
pfn_SymGetModuleBase64
WindowsDbgHelp
::
pfnSymGetModuleBase64
()
{
DecoderLocker
locker
;
WindowsDecoder
*
wd
=
(
WindowsDecoder
*
)
locker
.
decoder
();
if
(
!
wd
->
has_error
())
{
return
wd
->
_pfnSymGetModuleBase64
;
}
else
{
return
NULL
;
}
}
#endif // AMD64
src/os/windows/vm/decoder_windows.hpp
浏览文件 @
c4ea8057
...
...
@@ -38,6 +38,20 @@ typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWOR
typedef
BOOL
(
WINAPI
*
pfn_SymSetSearchPath
)(
HANDLE
,
PCTSTR
);
typedef
BOOL
(
WINAPI
*
pfn_SymGetSearchPath
)(
HANDLE
,
PTSTR
,
int
);
#ifdef AMD64
typedef
BOOL
(
WINAPI
*
pfn_StackWalk64
)(
DWORD
MachineType
,
HANDLE
hProcess
,
HANDLE
hThread
,
LPSTACKFRAME64
StackFrame
,
PVOID
ContextRecord
,
PREAD_PROCESS_MEMORY_ROUTINE64
ReadMemoryRoutine
,
PFUNCTION_TABLE_ACCESS_ROUTINE64
FunctionTableAccessRoutine
,
PGET_MODULE_BASE_ROUTINE64
GetModuleBaseRoutine
,
PTRANSLATE_ADDRESS_ROUTINE64
TranslateAddress
);
typedef
PVOID
(
WINAPI
*
pfn_SymFunctionTableAccess64
)(
HANDLE
hProcess
,
DWORD64
AddrBase
);
typedef
DWORD64
(
WINAPI
*
pfn_SymGetModuleBase64
)(
HANDLE
hProcess
,
DWORD64
dwAddr
);
#endif
class
WindowsDecoder
:
public
AbstractDecoder
{
public:
...
...
@@ -61,7 +75,34 @@ private:
bool
_can_decode_in_vm
;
pfn_SymGetSymFromAddr64
_pfnSymGetSymFromAddr64
;
pfn_UndecorateSymbolName
_pfnUndecorateSymbolName
;
#ifdef AMD64
pfn_StackWalk64
_pfnStackWalk64
;
pfn_SymFunctionTableAccess64
_pfnSymFunctionTableAccess64
;
pfn_SymGetModuleBase64
_pfnSymGetModuleBase64
;
friend
class
WindowsDbgHelp
;
#endif
};
#ifdef AMD64
// TODO: refactor and move the handling of dbghelp.dll outside of Decoder
class
WindowsDbgHelp
:
public
Decoder
{
public:
static
BOOL
StackWalk64
(
DWORD
MachineType
,
HANDLE
hProcess
,
HANDLE
hThread
,
LPSTACKFRAME64
StackFrame
,
PVOID
ContextRecord
,
PREAD_PROCESS_MEMORY_ROUTINE64
ReadMemoryRoutine
,
PFUNCTION_TABLE_ACCESS_ROUTINE64
FunctionTableAccessRoutine
,
PGET_MODULE_BASE_ROUTINE64
GetModuleBaseRoutine
,
PTRANSLATE_ADDRESS_ROUTINE64
TranslateAddress
);
static
PVOID
SymFunctionTableAccess64
(
HANDLE
hProcess
,
DWORD64
AddrBase
);
static
pfn_SymFunctionTableAccess64
pfnSymFunctionTableAccess64
();
static
pfn_SymGetModuleBase64
pfnSymGetModuleBase64
();
};
#endif
#endif // OS_WINDOWS_VM_DECODER_WINDOWS_HPP
src/os_cpu/windows_x86/vm/os_windows_x86.cpp
浏览文件 @
c4ea8057
...
...
@@ -29,6 +29,7 @@
#include "classfile/vmSymbols.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "decoder_windows.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_windows.h"
#include "memory/allocation.inline.hpp"
...
...
@@ -327,6 +328,94 @@ add_ptr_func_t* os::atomic_add_ptr_func = os::atomic_add_ptr_bootstrap
cmpxchg_long_func_t
*
os
::
atomic_cmpxchg_long_func
=
os
::
atomic_cmpxchg_long_bootstrap
;
#ifdef AMD64
/*
* Windows/x64 does not use stack frames the way expected by Java:
* [1] in most cases, there is no frame pointer. All locals are addressed via RSP
* [2] in rare cases, when alloca() is used, a frame pointer is used, but this may
* not be RBP.
* See http://msdn.microsoft.com/en-us/library/ew5tede7.aspx
*
* So it's not possible to print the native stack using the
* while (...) {... fr = os::get_sender_for_C_frame(&fr); }
* loop in vmError.cpp. We need to roll our own loop.
*/
bool
os
::
platform_print_native_stack
(
outputStream
*
st
,
void
*
context
,
char
*
buf
,
int
buf_size
)
{
CONTEXT
ctx
;
if
(
context
!=
NULL
)
{
memcpy
(
&
ctx
,
context
,
sizeof
(
ctx
));
}
else
{
RtlCaptureContext
(
&
ctx
);
}
st
->
print_cr
(
"Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"
);
STACKFRAME
stk
;
memset
(
&
stk
,
0
,
sizeof
(
stk
));
stk
.
AddrStack
.
Offset
=
ctx
.
Rsp
;
stk
.
AddrStack
.
Mode
=
AddrModeFlat
;
stk
.
AddrFrame
.
Offset
=
ctx
.
Rbp
;
stk
.
AddrFrame
.
Mode
=
AddrModeFlat
;
stk
.
AddrPC
.
Offset
=
ctx
.
Rip
;
stk
.
AddrPC
.
Mode
=
AddrModeFlat
;
int
count
=
0
;
address
lastpc
=
0
;
while
(
count
++
<
StackPrintLimit
)
{
intptr_t
*
sp
=
(
intptr_t
*
)
stk
.
AddrStack
.
Offset
;
intptr_t
*
fp
=
(
intptr_t
*
)
stk
.
AddrFrame
.
Offset
;
// NOT necessarily the same as ctx.Rbp!
address
pc
=
(
address
)
stk
.
AddrPC
.
Offset
;
if
(
pc
!=
NULL
&&
sp
!=
NULL
&&
fp
!=
NULL
)
{
if
(
count
==
2
&&
lastpc
==
pc
)
{
// Skip it -- StackWalk64() may return the same PC
// (but different SP) on the first try.
}
else
{
// Don't try to create a frame(sp, fp, pc) -- on WinX64, stk.AddrFrame
// may not contain what Java expects, and may cause the frame() constructor
// to crash. Let's just print out the symbolic address.
frame
::
print_C_frame
(
st
,
buf
,
buf_size
,
pc
);
st
->
cr
();
}
lastpc
=
pc
;
}
else
{
break
;
}
PVOID
p
=
WindowsDbgHelp
::
SymFunctionTableAccess64
(
GetCurrentProcess
(),
stk
.
AddrPC
.
Offset
);
if
(
!
p
)
{
// StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash.
break
;
}
BOOL
result
=
WindowsDbgHelp
::
StackWalk64
(
IMAGE_FILE_MACHINE_AMD64
,
// __in DWORD MachineType,
GetCurrentProcess
(),
// __in HANDLE hProcess,
GetCurrentThread
(),
// __in HANDLE hThread,
&
stk
,
// __inout LP STACKFRAME64 StackFrame,
&
ctx
,
// __inout PVOID ContextRecord,
NULL
,
// __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
WindowsDbgHelp
::
pfnSymFunctionTableAccess64
(),
// __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
WindowsDbgHelp
::
pfnSymGetModuleBase64
(),
// __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
NULL
);
// __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
if
(
!
result
)
{
break
;
}
}
if
(
count
>
StackPrintLimit
)
{
st
->
print_cr
(
"...<more frames>..."
);
}
st
->
cr
();
return
true
;
}
#endif // AMD64
ExtendedPC
os
::
fetch_frame_from_context
(
void
*
ucVoid
,
intptr_t
**
ret_sp
,
intptr_t
**
ret_fp
)
{
...
...
@@ -401,6 +490,9 @@ frame os::current_frame() {
StubRoutines
::
x86
::
get_previous_fp_entry
());
if
(
func
==
NULL
)
return
frame
();
intptr_t
*
fp
=
(
*
func
)();
if
(
fp
==
NULL
)
{
return
frame
();
}
#else
intptr_t
*
fp
=
_get_previous_fp
();
#endif // AMD64
...
...
src/os_cpu/windows_x86/vm/os_windows_x86.hpp
浏览文件 @
c4ea8057
...
...
@@ -62,4 +62,10 @@
static
bool
register_code_area
(
char
*
low
,
char
*
high
);
#ifdef AMD64
#define PLATFORM_PRINT_NATIVE_STACK 1
static
bool
platform_print_native_stack
(
outputStream
*
st
,
void
*
context
,
char
*
buf
,
int
buf_size
);
#endif
#endif // OS_CPU_WINDOWS_X86_VM_OS_WINDOWS_X86_HPP
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
c4ea8057
...
...
@@ -888,6 +888,7 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count,
int
runtime_visible_type_annotations_length
=
0
;
u1
*
runtime_invisible_type_annotations
=
NULL
;
int
runtime_invisible_type_annotations_length
=
0
;
bool
runtime_invisible_type_annotations_exists
=
false
;
while
(
attributes_count
--
)
{
cfs
->
guarantee_more
(
6
,
CHECK
);
// attribute_name_index, attribute_length
u2
attribute_name_index
=
cfs
->
get_u2_fast
();
...
...
@@ -946,15 +947,27 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count,
assert
(
runtime_invisible_annotations
!=
NULL
,
"null invisible annotations"
);
cfs
->
skip_u1
(
runtime_invisible_annotations_length
,
CHECK
);
}
else
if
(
attribute_name
==
vmSymbols
::
tag_runtime_visible_type_annotations
())
{
if
(
runtime_visible_type_annotations
!=
NULL
)
{
classfile_parse_error
(
"Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s"
,
CHECK
);
}
runtime_visible_type_annotations_length
=
attribute_length
;
runtime_visible_type_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_visible_type_annotations
!=
NULL
,
"null visible type annotations"
);
cfs
->
skip_u1
(
runtime_visible_type_annotations_length
,
CHECK
);
}
else
if
(
PreserveAllAnnotations
&&
attribute_name
==
vmSymbols
::
tag_runtime_invisible_type_annotations
())
{
}
else
if
(
attribute_name
==
vmSymbols
::
tag_runtime_invisible_type_annotations
())
{
if
(
runtime_invisible_type_annotations_exists
)
{
classfile_parse_error
(
"Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s"
,
CHECK
);
}
else
{
runtime_invisible_type_annotations_exists
=
true
;
}
if
(
PreserveAllAnnotations
)
{
runtime_invisible_type_annotations_length
=
attribute_length
;
runtime_invisible_type_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_invisible_type_annotations
!=
NULL
,
"null invisible type annotations"
);
cfs
->
skip_u1
(
runtime_invisible_type_annotations_length
,
CHECK
);
}
cfs
->
skip_u1
(
attribute_length
,
CHECK
);
}
else
{
cfs
->
skip_u1
(
attribute_length
,
CHECK
);
// Skip unknown attributes
}
...
...
@@ -2066,6 +2079,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
int
runtime_visible_type_annotations_length
=
0
;
u1
*
runtime_invisible_type_annotations
=
NULL
;
int
runtime_invisible_type_annotations_length
=
0
;
bool
runtime_invisible_type_annotations_exists
=
false
;
u1
*
annotation_default
=
NULL
;
int
annotation_default_length
=
0
;
...
...
@@ -2322,16 +2336,30 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
assert
(
annotation_default
!=
NULL
,
"null annotation default"
);
cfs
->
skip_u1
(
annotation_default_length
,
CHECK_
(
nullHandle
));
}
else
if
(
method_attribute_name
==
vmSymbols
::
tag_runtime_visible_type_annotations
())
{
if
(
runtime_visible_type_annotations
!=
NULL
)
{
classfile_parse_error
(
"Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s"
,
CHECK_
(
nullHandle
));
}
runtime_visible_type_annotations_length
=
method_attribute_length
;
runtime_visible_type_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_visible_type_annotations
!=
NULL
,
"null visible type annotations"
);
// No need for the VM to parse Type annotations
cfs
->
skip_u1
(
runtime_visible_type_annotations_length
,
CHECK_
(
nullHandle
));
}
else
if
(
PreserveAllAnnotations
&&
method_attribute_name
==
vmSymbols
::
tag_runtime_invisible_type_annotations
())
{
}
else
if
(
method_attribute_name
==
vmSymbols
::
tag_runtime_invisible_type_annotations
())
{
if
(
runtime_invisible_type_annotations_exists
)
{
classfile_parse_error
(
"Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s"
,
CHECK_
(
nullHandle
));
}
else
{
runtime_invisible_type_annotations_exists
=
true
;
}
if
(
PreserveAllAnnotations
)
{
runtime_invisible_type_annotations_length
=
method_attribute_length
;
runtime_invisible_type_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_invisible_type_annotations
!=
NULL
,
"null invisible type annotations"
);
cfs
->
skip_u1
(
runtime_invisible_type_annotations_length
,
CHECK_
(
nullHandle
));
}
cfs
->
skip_u1
(
method_attribute_length
,
CHECK_
(
nullHandle
));
}
else
{
// Skip unknown attributes
cfs
->
skip_u1
(
method_attribute_length
,
CHECK_
(
nullHandle
));
...
...
@@ -2824,6 +2852,7 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio
int
runtime_visible_type_annotations_length
=
0
;
u1
*
runtime_invisible_type_annotations
=
NULL
;
int
runtime_invisible_type_annotations_length
=
0
;
bool
runtime_invisible_type_annotations_exists
=
false
;
u1
*
inner_classes_attribute_start
=
NULL
;
u4
inner_classes_attribute_length
=
0
;
u2
enclosing_method_class_index
=
0
;
...
...
@@ -2927,16 +2956,28 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio
parsed_bootstrap_methods_attribute
=
true
;
parse_classfile_bootstrap_methods_attribute
(
attribute_length
,
CHECK
);
}
else
if
(
tag
==
vmSymbols
::
tag_runtime_visible_type_annotations
())
{
if
(
runtime_visible_type_annotations
!=
NULL
)
{
classfile_parse_error
(
"Multiple RuntimeVisibleTypeAnnotations attributes in class file %s"
,
CHECK
);
}
runtime_visible_type_annotations_length
=
attribute_length
;
runtime_visible_type_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_visible_type_annotations
!=
NULL
,
"null visible type annotations"
);
// No need for the VM to parse Type annotations
cfs
->
skip_u1
(
runtime_visible_type_annotations_length
,
CHECK
);
}
else
if
(
PreserveAllAnnotations
&&
tag
==
vmSymbols
::
tag_runtime_invisible_type_annotations
())
{
}
else
if
(
tag
==
vmSymbols
::
tag_runtime_invisible_type_annotations
())
{
if
(
runtime_invisible_type_annotations_exists
)
{
classfile_parse_error
(
"Multiple RuntimeInvisibleTypeAnnotations attributes in class file %s"
,
CHECK
);
}
else
{
runtime_invisible_type_annotations_exists
=
true
;
}
if
(
PreserveAllAnnotations
)
{
runtime_invisible_type_annotations_length
=
attribute_length
;
runtime_invisible_type_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_invisible_type_annotations
!=
NULL
,
"null invisible type annotations"
);
cfs
->
skip_u1
(
runtime_invisible_type_annotations_length
,
CHECK
);
}
cfs
->
skip_u1
(
attribute_length
,
CHECK
);
}
else
{
// Unknown attribute
cfs
->
skip_u1
(
attribute_length
,
CHECK
);
...
...
src/share/vm/classfile/defaultMethods.cpp
浏览文件 @
c4ea8057
...
...
@@ -450,6 +450,10 @@ class MethodFamily : public ResourceObj {
streamIndentor
si
(
str
,
indent
*
2
);
str
->
indent
().
print
(
"Selected method: "
);
print_method
(
str
,
_selected_target
);
Klass
*
method_holder
=
_selected_target
->
method_holder
();
if
(
!
method_holder
->
is_interface
())
{
tty
->
print
(
" : in superclass"
);
}
str
->
print_cr
(
""
);
}
...
...
@@ -1141,12 +1145,15 @@ static void create_overpasses(
#endif // ndef PRODUCT
if
(
method
->
has_target
())
{
Method
*
selected
=
method
->
get_selected_target
();
if
(
selected
->
method_holder
()
->
is_interface
())
{
max_stack
=
assemble_redirect
(
&
bpool
,
&
buffer
,
slot
->
signature
(),
selected
,
CHECK
);
}
}
else
if
(
method
->
throws_exception
())
{
max_stack
=
assemble_abstract_method_error
(
&
bpool
,
&
buffer
,
method
->
get_exception_message
(),
CHECK
);
}
if
(
max_stack
!=
0
)
{
AccessFlags
flags
=
accessFlags_from
(
JVM_ACC_PUBLIC
|
JVM_ACC_SYNTHETIC
|
JVM_ACC_BRIDGE
);
Method
*
m
=
new_method
(
&
bpool
,
&
buffer
,
slot
->
name
(),
slot
->
signature
(),
...
...
@@ -1157,6 +1164,7 @@ static void create_overpasses(
}
}
}
}
#ifndef PRODUCT
if
(
TraceDefaultMethods
)
{
...
...
src/share/vm/prims/jni.cpp
浏览文件 @
c4ea8057
...
...
@@ -5037,6 +5037,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#endif
#include "utilities/quickSort.hpp"
#include "utilities/ostream.hpp"
#if INCLUDE_VM_STRUCTS
#include "runtime/vmStructs.hpp"
#endif
...
...
@@ -5060,6 +5061,7 @@ void execute_internal_vm_tests() {
run_unit_test
(
CollectedHeap
::
test_is_in
());
run_unit_test
(
QuickSort
::
test_quick_sort
());
run_unit_test
(
AltHashing
::
test_alt_hash
());
run_unit_test
(
test_loggc_filename
());
#if INCLUDE_VM_STRUCTS
run_unit_test
(
VMStructs
::
test
());
#endif
...
...
src/share/vm/prims/jvmtiRedefineClasses.cpp
浏览文件 @
c4ea8057
...
...
@@ -1072,8 +1072,17 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
}
res
=
merge_cp_and_rewrite
(
the_class
,
scratch_class
,
THREAD
);
if
(
res
!=
JVMTI_ERROR_NONE
)
{
return
res
;
if
(
HAS_PENDING_EXCEPTION
)
{
Symbol
*
ex_name
=
PENDING_EXCEPTION
->
klass
()
->
name
();
// RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
RC_TRACE_WITH_THREAD
(
0x00000002
,
THREAD
,
(
"merge_cp_and_rewrite exception: '%s'"
,
ex_name
->
as_C_string
()));
CLEAR_PENDING_EXCEPTION
;
if
(
ex_name
==
vmSymbols
::
java_lang_OutOfMemoryError
())
{
return
JVMTI_ERROR_OUT_OF_MEMORY
;
}
else
{
return
JVMTI_ERROR_INTERNAL
;
}
}
if
(
VerifyMergedCPBytecodes
)
{
...
...
@@ -1105,6 +1114,9 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
}
if
(
HAS_PENDING_EXCEPTION
)
{
Symbol
*
ex_name
=
PENDING_EXCEPTION
->
klass
()
->
name
();
// RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
RC_TRACE_WITH_THREAD
(
0x00000002
,
THREAD
,
(
"Rewriter::rewrite or link_methods exception: '%s'"
,
ex_name
->
as_C_string
()));
CLEAR_PENDING_EXCEPTION
;
if
(
ex_name
==
vmSymbols
::
java_lang_OutOfMemoryError
())
{
return
JVMTI_ERROR_OUT_OF_MEMORY
;
...
...
@@ -1396,7 +1408,7 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
ConstantPool
*
merge_cp_oop
=
ConstantPool
::
allocate
(
loader_data
,
merge_cp_length
,
THREAD
);
CHECK_
(
JVMTI_ERROR_OUT_OF_MEMORY
)
);
MergeCPCleaner
cp_cleaner
(
loader_data
,
merge_cp_oop
);
HandleMark
hm
(
THREAD
);
// make sure handles are cleared before
...
...
@@ -1472,7 +1484,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
// Replace the new constant pool with a shrunken copy of the
// merged constant pool
set_new_constant_pool
(
loader_data
,
scratch_class
,
merge_cp
,
merge_cp_length
,
THREAD
);
set_new_constant_pool
(
loader_data
,
scratch_class
,
merge_cp
,
merge_cp_length
,
CHECK_
(
JVMTI_ERROR_OUT_OF_MEMORY
));
// The new constant pool replaces scratch_cp so have cleaner clean it up.
// It can't be cleaned up while there are handles to it.
cp_cleaner
.
add_scratch_cp
(
scratch_cp
());
...
...
@@ -1502,7 +1515,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
// merged constant pool so now the rewritten bytecodes have
// valid references; the previous new constant pool will get
// GCed.
set_new_constant_pool
(
loader_data
,
scratch_class
,
merge_cp
,
merge_cp_length
,
THREAD
);
set_new_constant_pool
(
loader_data
,
scratch_class
,
merge_cp
,
merge_cp_length
,
CHECK_
(
JVMTI_ERROR_OUT_OF_MEMORY
));
// The new constant pool replaces scratch_cp so have cleaner clean it up.
// It can't be cleaned up while there are handles to it.
cp_cleaner
.
add_scratch_cp
(
scratch_cp
());
...
...
@@ -1590,11 +1604,23 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_methods(
for
(
int
i
=
methods
->
length
()
-
1
;
i
>=
0
;
i
--
)
{
methodHandle
method
(
THREAD
,
methods
->
at
(
i
));
methodHandle
new_method
;
rewrite_cp_refs_in_method
(
method
,
&
new_method
,
CHECK_false
);
rewrite_cp_refs_in_method
(
method
,
&
new_method
,
THREAD
);
if
(
!
new_method
.
is_null
())
{
// the method has been replaced so save the new method version
// even in the case of an exception. original method is on the
// deallocation list.
methods
->
at_put
(
i
,
new_method
());
}
if
(
HAS_PENDING_EXCEPTION
)
{
Symbol
*
ex_name
=
PENDING_EXCEPTION
->
klass
()
->
name
();
// RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
RC_TRACE_WITH_THREAD
(
0x00000002
,
THREAD
,
(
"rewrite_cp_refs_in_method exception: '%s'"
,
ex_name
->
as_C_string
()));
// Need to clear pending exception here as the super caller sets
// the JVMTI_ERROR_INTERNAL if the returned value is false.
CLEAR_PENDING_EXCEPTION
;
return
false
;
}
}
return
true
;
...
...
@@ -1674,10 +1700,7 @@ void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method,
Pause_No_Safepoint_Verifier
pnsv
(
&
nsv
);
// ldc is 2 bytes and ldc_w is 3 bytes
m
=
rc
.
insert_space_at
(
bci
,
3
,
inst_buffer
,
THREAD
);
if
(
m
.
is_null
()
||
HAS_PENDING_EXCEPTION
)
{
guarantee
(
false
,
"insert_space_at() failed"
);
}
m
=
rc
.
insert_space_at
(
bci
,
3
,
inst_buffer
,
CHECK
);
}
// return the new method so that the caller can update
...
...
@@ -2487,8 +2510,8 @@ void VM_RedefineClasses::set_new_constant_pool(
// scratch_cp is a merged constant pool and has enough space for a
// worst case merge situation. We want to associate the minimum
// sized constant pool with the klass to save space.
constantPoolHandle
smaller_cp
(
THREAD
,
ConstantPool
::
allocate
(
loader_data
,
scratch_cp_length
,
THREAD
)
);
ConstantPool
*
cp
=
ConstantPool
::
allocate
(
loader_data
,
scratch_cp_length
,
CHECK
);
constantPoolHandle
smaller_cp
(
THREAD
,
cp
);
// preserve version() value in the smaller copy
int
version
=
scratch_cp
->
version
();
...
...
@@ -2500,6 +2523,11 @@ void VM_RedefineClasses::set_new_constant_pool(
smaller_cp
->
set_pool_holder
(
scratch_class
());
scratch_cp
->
copy_cp_to
(
1
,
scratch_cp_length
-
1
,
smaller_cp
,
1
,
THREAD
);
if
(
HAS_PENDING_EXCEPTION
)
{
// Exception is handled in the caller
loader_data
->
add_to_deallocate_list
(
smaller_cp
());
return
;
}
scratch_cp
=
smaller_cp
;
// attach new constant pool to klass
...
...
src/share/vm/runtime/arguments.cpp
浏览文件 @
c4ea8057
...
...
@@ -1839,7 +1839,7 @@ void check_gclog_consistency() {
(
NumberOfGCLogFiles
==
0
)
||
(
GCLogFileSize
==
0
))
{
jio_fprintf
(
defaultStream
::
output_stream
(),
"To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files> -XX:GCLogFileSize=<num_of_size>
\n
"
"To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files> -XX:GCLogFileSize=<num_of_size>
[k|K|m|M|g|G]
\n
"
"where num_of_file > 0 and num_of_size > 0
\n
"
"GC log rotation is turned off
\n
"
);
UseGCLogFileRotation
=
false
;
...
...
@@ -1853,6 +1853,51 @@ void check_gclog_consistency() {
}
}
// This function is called for -Xloggc:<filename>, it can be used
// to check if a given file name(or string) conforms to the following
// specification:
// A valid string only contains "[A-Z][a-z][0-9].-_%[p|t]"
// %p and %t only allowed once. We only limit usage of filename not path
bool
is_filename_valid
(
const
char
*
file_name
)
{
const
char
*
p
=
file_name
;
char
file_sep
=
os
::
file_separator
()[
0
];
const
char
*
cp
;
// skip prefix path
for
(
cp
=
file_name
;
*
cp
!=
'\0'
;
cp
++
)
{
if
(
*
cp
==
'/'
||
*
cp
==
file_sep
)
{
p
=
cp
+
1
;
}
}
int
count_p
=
0
;
int
count_t
=
0
;
while
(
*
p
!=
'\0'
)
{
if
((
*
p
>=
'0'
&&
*
p
<=
'9'
)
||
(
*
p
>=
'A'
&&
*
p
<=
'Z'
)
||
(
*
p
>=
'a'
&&
*
p
<=
'z'
)
||
*
p
==
'-'
||
*
p
==
'_'
||
*
p
==
'.'
)
{
p
++
;
continue
;
}
if
(
*
p
==
'%'
)
{
if
(
*
(
p
+
1
)
==
'p'
)
{
p
+=
2
;
count_p
++
;
continue
;
}
if
(
*
(
p
+
1
)
==
't'
)
{
p
+=
2
;
count_t
++
;
continue
;
}
}
return
false
;
}
return
count_p
<
2
&&
count_t
<
2
;
}
// Check consistency of GC selection
bool
Arguments
::
check_gc_consistency
()
{
check_gclog_consistency
();
...
...
@@ -2806,6 +2851,13 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
// ostream_init_log(), when called will use this filename
// to initialize a fileStream.
_gc_log_filename
=
strdup
(
tail
);
if
(
!
is_filename_valid
(
_gc_log_filename
))
{
jio_fprintf
(
defaultStream
::
output_stream
(),
"Invalid file name for use with -Xloggc: Filename can only contain the "
"characters [A-Z][a-z][0-9]-_.%%[p|t] but it has been %s
\n
"
"Note %%p or %%t can only be used once
\n
"
,
_gc_log_filename
);
return
JNI_EINVAL
;
}
FLAG_SET_CMDLINE
(
bool
,
PrintGC
,
true
);
FLAG_SET_CMDLINE
(
bool
,
PrintGCTimeStamps
,
true
);
...
...
src/share/vm/runtime/frame.cpp
浏览文件 @
c4ea8057
...
...
@@ -652,7 +652,7 @@ void frame::interpreter_frame_print_on(outputStream* st) const {
// Return whether the frame is in the VM or os indicating a Hotspot problem.
// Otherwise, it's likely a bug in the native library that the Java code calls,
// hopefully indicating where to submit bugs.
static
void
print_C_frame
(
outputStream
*
st
,
char
*
buf
,
int
buflen
,
address
pc
)
{
void
frame
::
print_C_frame
(
outputStream
*
st
,
char
*
buf
,
int
buflen
,
address
pc
)
{
// C/C++ frame
bool
in_vm
=
os
::
address_is_in_vm
(
pc
);
st
->
print
(
in_vm
?
"V"
:
"C"
);
...
...
src/share/vm/runtime/frame.hpp
浏览文件 @
c4ea8057
...
...
@@ -406,6 +406,7 @@ class frame VALUE_OBJ_CLASS_SPEC {
void
print_on
(
outputStream
*
st
)
const
;
void
interpreter_frame_print_on
(
outputStream
*
st
)
const
;
void
print_on_error
(
outputStream
*
st
,
char
*
buf
,
int
buflen
,
bool
verbose
=
false
)
const
;
static
void
print_C_frame
(
outputStream
*
st
,
char
*
buf
,
int
buflen
,
address
pc
);
// Add annotated descriptions of memory locations belonging to this frame to values
void
describe
(
FrameValues
&
values
,
int
frame_no
);
...
...
src/share/vm/runtime/os.hpp
浏览文件 @
c4ea8057
...
...
@@ -795,6 +795,14 @@ class os: AllStatic {
#endif
public:
#ifndef PLATFORM_PRINT_NATIVE_STACK
// No platform-specific code for printing the native stack.
static
bool
platform_print_native_stack
(
outputStream
*
st
,
void
*
context
,
char
*
buf
,
int
buf_size
)
{
return
false
;
}
#endif
// debugging support (mostly used by debug.cpp but also fatal error handler)
static
bool
find
(
address
pc
,
outputStream
*
st
=
tty
);
// OS specific function to make sense out of an address
...
...
src/share/vm/runtime/thread.cpp
浏览文件 @
c4ea8057
...
...
@@ -333,6 +333,8 @@ Thread::~Thread() {
// Reclaim the objectmonitors from the omFreeList of the moribund thread.
ObjectSynchronizer
::
omFlush
(
this
)
;
EVENT_THREAD_DESTRUCT
(
this
);
// stack_base can be NULL if the thread is never started or exited before
// record_stack_base_and_size called. Although, we would like to ensure
// that all started threads do call record_stack_base_and_size(), there is
...
...
src/share/vm/services/gcNotifier.cpp
浏览文件 @
c4ea8057
...
...
@@ -209,7 +209,7 @@ void GCNotifier::sendNotificationInternal(TRAPS) {
GCNotificationRequest
*
request
=
getRequest
();
if
(
request
!=
NULL
)
{
NotificationMark
nm
(
request
);
Handle
objGcInfo
=
createGcInfo
(
request
->
gcManager
,
request
->
gcStatInfo
,
THREAD
);
Handle
objGcInfo
=
createGcInfo
(
request
->
gcManager
,
request
->
gcStatInfo
,
CHECK
);
Handle
objName
=
java_lang_String
::
create_from_str
(
request
->
gcManager
->
name
(),
CHECK
);
Handle
objAction
=
java_lang_String
::
create_from_str
(
request
->
gcAction
,
CHECK
);
...
...
src/share/vm/services/memPtr.cpp
浏览文件 @
c4ea8057
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012,
2013,
Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -34,9 +34,9 @@ jint SequenceGenerator::next() {
jint
seq
=
Atomic
::
add
(
1
,
&
_seq_number
);
if
(
seq
<
0
)
{
MemTracker
::
shutdown
(
MemTracker
::
NMT_sequence_overflow
);
}
assert
(
seq
>
0
,
"counter overflow"
);
}
else
{
NOT_PRODUCT
(
_max_seq_number
=
(
seq
>
_max_seq_number
)
?
seq
:
_max_seq_number
;)
}
return
seq
;
}
src/share/vm/trace/traceMacros.hpp
浏览文件 @
c4ea8057
...
...
@@ -26,6 +26,7 @@
#define SHARE_VM_TRACE_TRACE_MACRO_HPP
#define EVENT_THREAD_EXIT(thread)
#define EVENT_THREAD_DESTRUCT(thread)
#define TRACE_INIT_ID(k)
#define TRACE_DATA TraceThreadData
...
...
src/share/vm/utilities/decoder.cpp
浏览文件 @
c4ea8057
...
...
@@ -24,7 +24,6 @@
#include "precompiled.hpp"
#include "prims/jvm.h"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "utilities/decoder.hpp"
#include "utilities/vmError.hpp"
...
...
@@ -80,6 +79,23 @@ AbstractDecoder* Decoder::create_decoder() {
return
decoder
;
}
inline
bool
DecoderLocker
::
is_first_error_thread
()
{
return
(
os
::
current_thread_id
()
==
VMError
::
get_first_error_tid
());
}
DecoderLocker
::
DecoderLocker
()
:
MutexLockerEx
(
DecoderLocker
::
is_first_error_thread
()
?
NULL
:
Decoder
::
shared_decoder_lock
(),
true
)
{
_decoder
=
is_first_error_thread
()
?
Decoder
::
get_error_handler_instance
()
:
Decoder
::
get_shared_instance
();
assert
(
_decoder
!=
NULL
,
"null decoder"
);
}
Mutex
*
Decoder
::
shared_decoder_lock
()
{
assert
(
_shared_decoder_lock
!=
NULL
,
"Just check"
);
return
_shared_decoder_lock
;
}
bool
Decoder
::
decode
(
address
addr
,
char
*
buf
,
int
buflen
,
int
*
offset
,
const
char
*
modulepath
)
{
assert
(
_shared_decoder_lock
!=
NULL
,
"Just check"
);
bool
error_handling_thread
=
os
::
current_thread_id
()
==
VMError
::
first_error_tid
;
...
...
src/share/vm/utilities/decoder.hpp
浏览文件 @
c4ea8057
...
...
@@ -28,6 +28,7 @@
#include "memory/allocation.hpp"
#include "runtime/mutex.hpp"
#include "runtime/mutexLocker.hpp"
class
AbstractDecoder
:
public
CHeapObj
<
mtInternal
>
{
public:
...
...
@@ -124,6 +125,19 @@ private:
protected:
static
Mutex
*
_shared_decoder_lock
;
static
Mutex
*
shared_decoder_lock
();
friend
class
DecoderLocker
;
};
class
DecoderLocker
:
public
MutexLockerEx
{
AbstractDecoder
*
_decoder
;
inline
bool
is_first_error_thread
();
public:
DecoderLocker
();
AbstractDecoder
*
decoder
()
{
return
_decoder
;
}
};
#endif // SHARE_VM_UTILITIES_DECODER_HPP
src/share/vm/utilities/ostream.cpp
浏览文件 @
c4ea8057
...
...
@@ -342,7 +342,7 @@ void stringStream::write(const char* s, size_t len) {
}
char
*
stringStream
::
as_string
()
{
char
*
copy
=
NEW_RESOURCE_ARRAY
(
char
,
buffer_pos
+
1
);
char
*
copy
=
NEW_RESOURCE_ARRAY
(
char
,
buffer_pos
+
1
);
strncpy
(
copy
,
buffer
,
buffer_pos
);
copy
[
buffer_pos
]
=
0
;
// terminating null
return
copy
;
...
...
@@ -355,14 +355,190 @@ outputStream* tty;
outputStream
*
gclog_or_tty
;
extern
Mutex
*
tty_lock
;
#define EXTRACHARLEN 32
#define CURRENTAPPX ".current"
#define FILENAMEBUFLEN 1024
// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS
char
*
get_datetime_string
(
char
*
buf
,
size_t
len
)
{
os
::
local_time_string
(
buf
,
len
);
int
i
=
(
int
)
strlen
(
buf
);
while
(
i
--
>=
0
)
{
if
(
buf
[
i
]
==
' '
)
buf
[
i
]
=
'_'
;
else
if
(
buf
[
i
]
==
':'
)
buf
[
i
]
=
'-'
;
}
return
buf
;
}
static
const
char
*
make_log_name_internal
(
const
char
*
log_name
,
const
char
*
force_directory
,
int
pid
,
const
char
*
tms
)
{
const
char
*
basename
=
log_name
;
char
file_sep
=
os
::
file_separator
()[
0
];
const
char
*
cp
;
char
pid_text
[
32
];
for
(
cp
=
log_name
;
*
cp
!=
'\0'
;
cp
++
)
{
if
(
*
cp
==
'/'
||
*
cp
==
file_sep
)
{
basename
=
cp
+
1
;
}
}
const
char
*
nametail
=
log_name
;
// Compute buffer length
size_t
buffer_length
;
if
(
force_directory
!=
NULL
)
{
buffer_length
=
strlen
(
force_directory
)
+
strlen
(
os
::
file_separator
())
+
strlen
(
basename
)
+
1
;
}
else
{
buffer_length
=
strlen
(
log_name
)
+
1
;
}
// const char* star = strchr(basename, '*');
const
char
*
pts
=
strstr
(
basename
,
"%p"
);
int
pid_pos
=
(
pts
==
NULL
)
?
-
1
:
(
pts
-
nametail
);
if
(
pid_pos
>=
0
)
{
jio_snprintf
(
pid_text
,
sizeof
(
pid_text
),
"pid%u"
,
pid
);
buffer_length
+=
strlen
(
pid_text
);
}
pts
=
strstr
(
basename
,
"%t"
);
int
tms_pos
=
(
pts
==
NULL
)
?
-
1
:
(
pts
-
nametail
);
if
(
tms_pos
>=
0
)
{
buffer_length
+=
strlen
(
tms
);
}
// Create big enough buffer.
char
*
buf
=
NEW_C_HEAP_ARRAY
(
char
,
buffer_length
,
mtInternal
);
strcpy
(
buf
,
""
);
if
(
force_directory
!=
NULL
)
{
strcat
(
buf
,
force_directory
);
strcat
(
buf
,
os
::
file_separator
());
nametail
=
basename
;
// completely skip directory prefix
}
// who is first, %p or %t?
int
first
=
-
1
,
second
=
-
1
;
const
char
*
p1st
=
NULL
;
const
char
*
p2nd
=
NULL
;
if
(
pid_pos
>=
0
&&
tms_pos
>=
0
)
{
// contains both %p and %t
if
(
pid_pos
<
tms_pos
)
{
// case foo%pbar%tmonkey.log
first
=
pid_pos
;
p1st
=
pid_text
;
second
=
tms_pos
;
p2nd
=
tms
;
}
else
{
// case foo%tbar%pmonkey.log
first
=
tms_pos
;
p1st
=
tms
;
second
=
pid_pos
;
p2nd
=
pid_text
;
}
}
else
if
(
pid_pos
>=
0
)
{
// contains %p only
first
=
pid_pos
;
p1st
=
pid_text
;
}
else
if
(
tms_pos
>=
0
)
{
// contains %t only
first
=
tms_pos
;
p1st
=
tms
;
}
int
buf_pos
=
(
int
)
strlen
(
buf
);
const
char
*
tail
=
nametail
;
if
(
first
>=
0
)
{
tail
=
nametail
+
first
+
2
;
strncpy
(
&
buf
[
buf_pos
],
nametail
,
first
);
strcpy
(
&
buf
[
buf_pos
+
first
],
p1st
);
buf_pos
=
(
int
)
strlen
(
buf
);
if
(
second
>=
0
)
{
strncpy
(
&
buf
[
buf_pos
],
tail
,
second
-
first
-
2
);
strcpy
(
&
buf
[
buf_pos
+
second
-
first
-
2
],
p2nd
);
tail
=
nametail
+
second
+
2
;
}
}
strcat
(
buf
,
tail
);
// append rest of name, or all of name
return
buf
;
}
// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name
// in log_name, %p => pipd1234 and
// %t => YYYY-MM-DD_HH-MM-SS
static
const
char
*
make_log_name
(
const
char
*
log_name
,
const
char
*
force_directory
)
{
char
timestr
[
32
];
get_datetime_string
(
timestr
,
sizeof
(
timestr
));
return
make_log_name_internal
(
log_name
,
force_directory
,
os
::
current_process_id
(),
timestr
);
}
#ifndef PRODUCT
void
test_loggc_filename
()
{
int
pid
;
char
tms
[
32
];
char
i_result
[
FILENAMEBUFLEN
];
const
char
*
o_result
;
get_datetime_string
(
tms
,
sizeof
(
tms
));
pid
=
os
::
current_process_id
();
// test.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUFLEN
,
"test.log"
,
tms
);
o_result
=
make_log_name_internal
(
"test.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
test.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// test-%t-%p.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUFLEN
,
"test-%s-pid%u.log"
,
tms
,
pid
);
o_result
=
make_log_name_internal
(
"test-%t-%p.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
test-%%t-%%p.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// test-%t%p.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUFLEN
,
"test-%spid%u.log"
,
tms
,
pid
);
o_result
=
make_log_name_internal
(
"test-%t%p.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
test-%%t%%p.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// %p%t.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUFLEN
,
"pid%u%s.log"
,
pid
,
tms
);
o_result
=
make_log_name_internal
(
"%p%t.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
%%p%%t.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// %p-test.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUFLEN
,
"pid%u-test.log"
,
pid
);
o_result
=
make_log_name_internal
(
"%p-test.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
%%p-test.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// %t.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUFLEN
,
"%s.log"
,
tms
);
o_result
=
make_log_name_internal
(
"%t.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
%%t.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
}
#endif // PRODUCT
fileStream
::
fileStream
(
const
char
*
file_name
)
{
_file
=
fopen
(
file_name
,
"w"
);
if
(
_file
!=
NULL
)
{
_need_close
=
true
;
}
else
{
warning
(
"Cannot open file %s due to %s
\n
"
,
file_name
,
strerror
(
errno
));
_need_close
=
false
;
}
}
fileStream
::
fileStream
(
const
char
*
file_name
,
const
char
*
opentype
)
{
_file
=
fopen
(
file_name
,
opentype
);
if
(
_file
!=
NULL
)
{
_need_close
=
true
;
}
else
{
warning
(
"Cannot open file %s due to %s
\n
"
,
file_name
,
strerror
(
errno
));
_need_close
=
false
;
}
}
void
fileStream
::
write
(
const
char
*
s
,
size_t
len
)
{
...
...
@@ -423,34 +599,51 @@ void fdStream::write(const char* s, size_t len) {
update_position
(
s
,
len
);
}
rotatingFileStream
::~
rotatingFileStream
()
{
// dump vm version, os version, platform info, build id,
// memory usage and command line flags into header
void
gcLogFileStream
::
dump_loggc_header
()
{
if
(
is_open
())
{
print_cr
(
Abstract_VM_Version
::
internal_vm_info_string
());
os
::
print_memory_info
(
this
);
print
(
"CommandLine flags: "
);
CommandLineFlags
::
printSetFlags
(
this
);
}
}
gcLogFileStream
::~
gcLogFileStream
()
{
if
(
_file
!=
NULL
)
{
if
(
_need_close
)
fclose
(
_file
);
_file
=
NULL
;
}
if
(
_file_name
!=
NULL
)
{
FREE_C_HEAP_ARRAY
(
char
,
_file_name
,
mtInternal
);
_file_name
=
NULL
;
}
}
rotatingFileStream
::
rotatin
gFileStream
(
const
char
*
file_name
)
{
gcLogFileStream
::
gcLo
gFileStream
(
const
char
*
file_name
)
{
_cur_file_num
=
0
;
_bytes_written
=
0L
;
_file_name
=
NEW_C_HEAP_ARRAY
(
char
,
strlen
(
file_name
)
+
10
,
mtInternal
);
jio_snprintf
(
_file_name
,
strlen
(
file_name
)
+
10
,
"%s.%d"
,
file_name
,
_cur_file_num
);
_file
=
fopen
(
_file_name
,
"w"
);
_need_close
=
true
;
}
_file_name
=
make_log_name
(
file_name
,
NULL
);
rotatingFileStream
::
rotatingFileStream
(
const
char
*
file_name
,
const
char
*
opentype
)
{
_cur_file_num
=
0
;
_bytes_written
=
0L
;
_file_name
=
NEW_C_HEAP_ARRAY
(
char
,
strlen
(
file_name
)
+
10
,
mtInternal
);
jio_snprintf
(
_file_name
,
strlen
(
file_name
)
+
10
,
"%s.%d"
,
file_name
,
_cur_file_num
);
_file
=
fopen
(
_file_name
,
opentype
);
// gc log file rotation
if
(
UseGCLogFileRotation
&&
NumberOfGCLogFiles
>
1
)
{
char
tempbuf
[
FILENAMEBUFLEN
];
jio_snprintf
(
tempbuf
,
sizeof
(
tempbuf
),
"%s.%d"
CURRENTAPPX
,
_file_name
,
_cur_file_num
);
_file
=
fopen
(
tempbuf
,
"w"
);
}
else
{
_file
=
fopen
(
_file_name
,
"w"
);
}
if
(
_file
!=
NULL
)
{
_need_close
=
true
;
dump_loggc_header
();
}
else
{
warning
(
"Cannot open file %s due to %s
\n
"
,
_file_name
,
strerror
(
errno
));
_need_close
=
false
;
}
}
void
rotatin
gFileStream
::
write
(
const
char
*
s
,
size_t
len
)
{
void
gcLo
gFileStream
::
write
(
const
char
*
s
,
size_t
len
)
{
if
(
_file
!=
NULL
)
{
size_t
count
=
fwrite
(
s
,
1
,
len
,
_file
);
_bytes_written
+=
count
;
...
...
@@ -466,7 +659,12 @@ void rotatingFileStream::write(const char* s, size_t len) {
// write to gc log file at safepoint. If in future, changes made for mutator threads or
// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
// must be synchronized.
void
rotatingFileStream
::
rotate_log
()
{
void
gcLogFileStream
::
rotate_log
()
{
char
time_msg
[
FILENAMEBUFLEN
];
char
time_str
[
EXTRACHARLEN
];
char
current_file_name
[
FILENAMEBUFLEN
];
char
renamed_file_name
[
FILENAMEBUFLEN
];
if
(
_bytes_written
<
(
jlong
)
GCLogFileSize
)
{
return
;
}
...
...
@@ -481,27 +679,89 @@ void rotatingFileStream::rotate_log() {
// rotate in same file
rewind
();
_bytes_written
=
0L
;
jio_snprintf
(
time_msg
,
sizeof
(
time_msg
),
"File %s rotated at %s
\n
"
,
_file_name
,
os
::
local_time_string
((
char
*
)
time_str
,
sizeof
(
time_str
)));
write
(
time_msg
,
strlen
(
time_msg
));
dump_loggc_header
();
return
;
}
// rotate file in names file.0, file.1, file.2, ..., file.<MaxGCLogFileNumbers-1>
// close current file, rotate to next file
#if defined(_WINDOWS)
#ifndef F_OK
#define F_OK 0
#endif
#endif // _WINDOWS
// rotate file in names extended_filename.0, extended_filename.1, ...,
// extended_filename.<NumberOfGCLogFiles - 1>. Current rotation file name will
// have a form of extended_filename.<i>.current where i is the current rotation
// file number. After it reaches max file size, the file will be saved and renamed
// with .current removed from its tail.
size_t
filename_len
=
strlen
(
_file_name
);
if
(
_file
!=
NULL
)
{
_cur_file_num
++
;
if
(
_cur_file_num
>=
NumberOfGCLogFiles
)
_cur_file_num
=
0
;
jio_snprintf
(
_file_name
,
strlen
(
Arguments
::
gc_log_filename
())
+
10
,
"%s.%d"
,
Arguments
::
gc_log_filename
(),
_cur_file_num
);
jio_snprintf
(
renamed_file_name
,
filename_len
+
EXTRACHARLEN
,
"%s.%d"
,
_file_name
,
_cur_file_num
);
jio_snprintf
(
current_file_name
,
filename_len
+
EXTRACHARLEN
,
"%s.%d"
CURRENTAPPX
,
_file_name
,
_cur_file_num
);
jio_snprintf
(
time_msg
,
sizeof
(
time_msg
),
"%s GC log file has reached the"
" maximum size. Saved as %s
\n
"
,
os
::
local_time_string
((
char
*
)
time_str
,
sizeof
(
time_str
)),
renamed_file_name
);
write
(
time_msg
,
strlen
(
time_msg
));
fclose
(
_file
);
_file
=
NULL
;
bool
can_rename
=
true
;
if
(
access
(
current_file_name
,
F_OK
)
!=
0
)
{
// current file does not exist?
warning
(
"No source file exists, cannot rename
\n
"
);
can_rename
=
false
;
}
_file
=
fopen
(
_file_name
,
"w"
);
if
(
can_rename
)
{
if
(
access
(
renamed_file_name
,
F_OK
)
==
0
)
{
if
(
remove
(
renamed_file_name
)
!=
0
)
{
warning
(
"Could not delete existing file %s
\n
"
,
renamed_file_name
);
can_rename
=
false
;
}
}
else
{
// file does not exist, ok to rename
}
}
if
(
can_rename
&&
rename
(
current_file_name
,
renamed_file_name
)
!=
0
)
{
warning
(
"Could not rename %s to %s
\n
"
,
_file_name
,
renamed_file_name
);
}
}
_cur_file_num
++
;
if
(
_cur_file_num
>
NumberOfGCLogFiles
-
1
)
_cur_file_num
=
0
;
jio_snprintf
(
current_file_name
,
filename_len
+
EXTRACHARLEN
,
"%s.%d"
CURRENTAPPX
,
_file_name
,
_cur_file_num
);
_file
=
fopen
(
current_file_name
,
"w"
);
if
(
_file
!=
NULL
)
{
_bytes_written
=
0L
;
_need_close
=
true
;
// reuse current_file_name for time_msg
jio_snprintf
(
current_file_name
,
filename_len
+
EXTRACHARLEN
,
"%s.%d"
,
_file_name
,
_cur_file_num
);
jio_snprintf
(
time_msg
,
sizeof
(
time_msg
),
"%s GC log file created %s
\n
"
,
os
::
local_time_string
((
char
*
)
time_str
,
sizeof
(
time_str
)),
current_file_name
);
write
(
time_msg
,
strlen
(
time_msg
));
dump_loggc_header
();
// remove the existing file
if
(
access
(
current_file_name
,
F_OK
)
==
0
)
{
if
(
remove
(
current_file_name
)
!=
0
)
{
warning
(
"Could not delete existing file %s
\n
"
,
current_file_name
);
}
}
}
else
{
tty
->
print_cr
(
"failed to open rotation log file %s due to %s
\n
"
,
warning
(
"failed to open rotation log file %s due to %s
\n
"
"Turned off GC log file rotation
\n
"
,
_file_name
,
strerror
(
errno
));
_need_close
=
false
;
FLAG_SET_DEFAULT
(
UseGCLogFileRotation
,
false
);
}
}
...
...
@@ -530,66 +790,6 @@ bool defaultStream::has_log_file() {
return
_log_file
!=
NULL
;
}
static
const
char
*
make_log_name
(
const
char
*
log_name
,
const
char
*
force_directory
)
{
const
char
*
basename
=
log_name
;
char
file_sep
=
os
::
file_separator
()[
0
];
const
char
*
cp
;
for
(
cp
=
log_name
;
*
cp
!=
'\0'
;
cp
++
)
{
if
(
*
cp
==
'/'
||
*
cp
==
file_sep
)
{
basename
=
cp
+
1
;
}
}
const
char
*
nametail
=
log_name
;
// Compute buffer length
size_t
buffer_length
;
if
(
force_directory
!=
NULL
)
{
buffer_length
=
strlen
(
force_directory
)
+
strlen
(
os
::
file_separator
())
+
strlen
(
basename
)
+
1
;
}
else
{
buffer_length
=
strlen
(
log_name
)
+
1
;
}
const
char
*
star
=
strchr
(
basename
,
'*'
);
int
star_pos
=
(
star
==
NULL
)
?
-
1
:
(
star
-
nametail
);
int
skip
=
1
;
if
(
star
==
NULL
)
{
// Try %p
star
=
strstr
(
basename
,
"%p"
);
if
(
star
!=
NULL
)
{
skip
=
2
;
}
}
star_pos
=
(
star
==
NULL
)
?
-
1
:
(
star
-
nametail
);
char
pid
[
32
];
if
(
star_pos
>=
0
)
{
jio_snprintf
(
pid
,
sizeof
(
pid
),
"%u"
,
os
::
current_process_id
());
buffer_length
+=
strlen
(
pid
);
}
// Create big enough buffer.
char
*
buf
=
NEW_C_HEAP_ARRAY
(
char
,
buffer_length
,
mtInternal
);
strcpy
(
buf
,
""
);
if
(
force_directory
!=
NULL
)
{
strcat
(
buf
,
force_directory
);
strcat
(
buf
,
os
::
file_separator
());
nametail
=
basename
;
// completely skip directory prefix
}
if
(
star_pos
>=
0
)
{
// convert foo*bar.log or foo%pbar.log to foo123bar.log
int
buf_pos
=
(
int
)
strlen
(
buf
);
strncpy
(
&
buf
[
buf_pos
],
nametail
,
star_pos
);
strcpy
(
&
buf
[
buf_pos
+
star_pos
],
pid
);
nametail
+=
star_pos
+
skip
;
// skip prefix and pid format
}
strcat
(
buf
,
nametail
);
// append rest of name, or all of name
return
buf
;
}
void
defaultStream
::
init_log
()
{
// %%% Need a MutexLocker?
const
char
*
log_name
=
LogFile
!=
NULL
?
LogFile
:
"hotspot.log"
;
...
...
@@ -877,11 +1077,8 @@ void ostream_init_log() {
gclog_or_tty
=
tty
;
// default to tty
if
(
Arguments
::
gc_log_filename
()
!=
NULL
)
{
fileStream
*
gclog
=
UseGCLogFileRotation
?
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
rotatingFileStream
(
Arguments
::
gc_log_filename
())
:
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
fileStream
(
Arguments
::
gc_log_filename
());
fileStream
*
gclog
=
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
gcLogFileStream
(
Arguments
::
gc_log_filename
());
if
(
gclog
->
is_open
())
{
// now we update the time stamp of the GC log to be synced up
// with tty.
...
...
src/share/vm/utilities/ostream.hpp
浏览文件 @
c4ea8057
...
...
@@ -231,20 +231,24 @@ class fdStream : public outputStream {
void
flush
()
{};
};
class
rotatin
gFileStream
:
public
fileStream
{
class
gcLo
gFileStream
:
public
fileStream
{
protected:
char
*
_file_name
;
c
onst
c
har
*
_file_name
;
jlong
_bytes_written
;
uintx
_cur_file_num
;
// current logfile rotation number, from 0 to
MaxGCLogFileNumber
s-1
uintx
_cur_file_num
;
// current logfile rotation number, from 0 to
NumberOfGCLogFile
s-1
public:
rotatingFileStream
(
const
char
*
file_name
);
rotatingFileStream
(
const
char
*
file_name
,
const
char
*
opentype
);
rotatingFileStream
(
FILE
*
file
)
:
fileStream
(
file
)
{}
~
rotatingFileStream
();
gcLogFileStream
(
const
char
*
file_name
);
~
gcLogFileStream
();
virtual
void
write
(
const
char
*
c
,
size_t
len
);
virtual
void
rotate_log
();
void
dump_loggc_header
();
};
#ifndef PRODUCT
// unit test for checking -Xloggc:<filename> parsing result
void
test_loggc_filename
();
#endif
void
ostream_init
();
void
ostream_init_log
();
void
ostream_exit
();
...
...
src/share/vm/utilities/vmError.cpp
浏览文件 @
c4ea8057
...
...
@@ -574,6 +574,10 @@ void VMError::report(outputStream* st) {
STEP
(
120
,
"(printing native stack)"
)
if
(
_verbose
)
{
if
(
os
::
platform_print_native_stack
(
st
,
_context
,
buf
,
sizeof
(
buf
)))
{
// We have printed the native stack in platform-specific code
// Windows/x64 needs special handling.
}
else
{
frame
fr
=
_context
?
os
::
fetch_frame_from_context
(
_context
)
:
os
::
current_frame
();
...
...
@@ -604,6 +608,7 @@ void VMError::report(outputStream* st) {
st
->
cr
();
}
}
}
STEP
(
130
,
"(printing Java stack)"
)
...
...
src/share/vm/utilities/vmError.hpp
浏览文件 @
c4ea8057
...
...
@@ -136,6 +136,10 @@ public:
// check to see if fatal error reporting is in progress
static
bool
fatal_error_in_progress
()
{
return
first_error
!=
NULL
;
}
static
jlong
get_first_error_tid
()
{
return
first_error_tid
;
}
};
#endif // SHARE_VM_UTILITIES_VMERROR_HPP
test/runtime/6878713/Test6878713.sh
已删除
100644 → 0
浏览文件 @
4bbfb70f
#!/bin/sh
#
# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
##
## @test
## @bug 6878713
## @bug 7030610
## @bug 7037122
## @bug 7123945
## @summary Verifier heap corruption, relating to backward jsrs
## @run shell Test6878713.sh
##
## some tests require path to find test source dir
if
[
"
${
TESTSRC
}
"
=
""
]
then
TESTSRC
=
${
PWD
}
echo
"TESTSRC not set. Using "
${
TESTSRC
}
" as default"
fi
echo
"TESTSRC=
${
TESTSRC
}
"
## Adding common setup Variables for running shell tests.
.
${
TESTSRC
}
/../../test_env.sh
TARGET_CLASS
=
OOMCrashClass1960_2
echo
"INFO: extracting the target class."
${
COMPILEJAVA
}${
FS
}
bin
${
FS
}
jar xvf
\
${
TESTSRC
}${
FS
}
testcase.jar
${
TARGET_CLASS
}
.class
# remove any hs_err_pid that might exist here
rm
-f
hs_err_pid
*
.log
echo
"INFO: checking for 32-bit versus 64-bit VM."
${
TESTJAVA
}${
FS
}
bin
${
FS
}
java
${
TESTVMOPTS
}
-version
2>&1
\
|
grep
"64-Bit [^ ][^ ]* VM"
>
/dev/null 2>&1
status
=
"
$?
"
if
[
"
$status
"
=
0
]
;
then
echo
"INFO: testing a 64-bit VM."
is_64_bit
=
true
else
echo
"INFO: testing a 32-bit VM."
fi
if
[
"
$is_64_bit
"
=
true
]
;
then
# limit is 768MB in 8-byte words (1024 * 1024 * 768 / 8) == 100663296
MALLOC_MAX
=
100663296
else
# limit is 768MB in 4-byte words (1024 * 1024 * 768 / 4) == 201326592
MALLOC_MAX
=
201326592
fi
echo
"INFO: MALLOC_MAX=
$MALLOC_MAX
"
echo
"INFO: executing the target class."
# -XX:+PrintCommandLineFlags for debugging purposes
# -XX:+IgnoreUnrecognizedVMOptions so test will run on a VM without
# the new -XX:MallocMaxTestWords option
# -XX:+UnlockDiagnosticVMOptions so we can use -XX:MallocMaxTestWords
# -XX:MallocMaxTestWords limits malloc to $MALLOC_MAX
${
TESTJAVA
}${
FS
}
bin
${
FS
}
java
\
-XX
:+PrintCommandLineFlags
\
-XX
:+IgnoreUnrecognizedVMOptions
\
-XX
:+UnlockDiagnosticVMOptions
\
-XX
:MallocMaxTestWords
=
$MALLOC_MAX
\
${
TESTVMOPTS
}
${
TARGET_CLASS
}
>
test.out 2>&1
echo
"INFO: begin contents of test.out:"
cat
test.out
echo
"INFO: end contents of test.out."
echo
"INFO: checking for memory allocation error message."
# We are looking for this specific memory allocation failure mesg so
# we know we exercised the right allocation path with the test class:
MESG1
=
"Native memory allocation (malloc) failed to allocate 25696531[0-9][0-9] bytes"
grep
"
$MESG1
"
test.out
status
=
"
$?
"
if
[
"
$status
"
=
0
]
;
then
echo
"INFO: found expected memory allocation error message."
else
echo
"INFO: did not find expected memory allocation error message."
# If we didn't find MESG1 above, then there are several scenarios:
# 1) -XX:MallocMaxTestWords is not supported by the current VM and we
# didn't fail TARGET_CLASS's memory allocation attempt; instead
# we failed to find TARGET_CLASS's main() method. The TARGET_CLASS
# is designed to provoke a memory allocation failure during class
# loading; we actually don't care about running the class which is
# why it doesn't have a main() method.
# 2) we failed a memory allocation, but not the one we were looking
# so it might be that TARGET_CLASS no longer tickles the same
# memory allocation code path
# 3) TARGET_CLASS reproduces the failure mode (SIGSEGV) fixed by
# 6878713 because the test is running on a pre-fix VM.
echo
"INFO: checking for no main() method message."
MESG2
=
"Error: Main method not found in class"
grep
"
$MESG2
"
test.out
status
=
"
$?
"
if
[
"
$status
"
=
0
]
;
then
echo
"INFO: found no main() method message."
else
echo
"FAIL: did not find no main() method message."
# status is non-zero for exit below
if
[
-s
hs_err_pid
*
.log
]
;
then
echo
"INFO: begin contents of hs_err_pid file:"
cat
hs_err_pid
*
.log
echo
"INFO: end contents of hs_err_pid file."
fi
fi
fi
if
[
"
$status
"
=
0
]
;
then
echo
"PASS: test found one of the expected messages."
fi
exit
"
$status
"
test/runtime/7020373/Test7020373.sh
已删除
100644 → 0
浏览文件 @
4bbfb70f
#!/bin/sh
##
## @test
## @bug 7020373 7055247 7053586 7185550
## @key cte_test
## @summary JSR rewriting can overflow memory address size variables
## @ignore Ignore it as 7053586 test uses lots of memory. See bug report for detail.
## @run shell Test7020373.sh
##
if
[
"
${
TESTSRC
}
"
=
""
]
then
TESTSRC
=
${
PWD
}
echo
"TESTSRC not set. Using "
${
TESTSRC
}
" as default"
fi
echo
"TESTSRC=
${
TESTSRC
}
"
## Adding common setup Variables for running shell tests.
.
${
TESTSRC
}
/../../test_env.sh
${
COMPILEJAVA
}${
FS
}
bin
${
FS
}
jar xvf
${
TESTSRC
}${
FS
}
testcase.jar
${
TESTJAVA
}${
FS
}
bin
${
FS
}
java
${
TESTVMOPTS
}
OOMCrashClass4000_1
>
test.out 2>&1
cat
test.out
egrep
"SIGSEGV|An unexpected error has been detected"
test.out
if
[
$?
=
0
]
then
echo
"Test Failed"
exit
1
else
egrep
"java.lang.LinkageError|java.lang.NoSuchMethodError|Main method not found in class OOMCrashClass4000_1|insufficient memory"
test.out
if
[
$?
=
0
]
then
echo
"Test Passed"
exit
0
else
echo
"Test Failed"
exit
1
fi
fi
test/runtime/ClassFile/JsrRewriting.java
0 → 100644
浏览文件 @
c4ea8057
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test JsrRewriting
* @summary JSR (jump local subroutine)
* rewriting can overflow memory address size variables
* @bug 7020373
* @bug 7055247
* @bug 7053586
* @bug 7185550
* @bug 7149464
* @key cte_test
* @library /testlibrary
* @run main JsrRewriting
*/
import
com.oracle.java.testlibrary.*
;
import
java.io.File
;
public
class
JsrRewriting
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// ======= Configure the test
String
jarFile
=
System
.
getProperty
(
"test.src"
)
+
File
.
separator
+
"JsrRewritingTestCase.jar"
;
String
className
=
"OOMCrashClass4000_1"
;
// limit is 768MB in native words
int
mallocMaxTestWords
=
(
1024
*
1024
*
768
/
4
);
if
(
Platform
.
is64bit
())
mallocMaxTestWords
=
(
mallocMaxTestWords
/
2
);
// ======= extract the test class
ProcessBuilder
pb
=
new
ProcessBuilder
(
new
String
[]
{
JDKToolFinder
.
getJDKTool
(
"jar"
),
"xvf"
,
jarFile
}
);
OutputAnalyzer
output
=
new
OutputAnalyzer
(
pb
.
start
());
output
.
shouldHaveExitValue
(
0
);
// ======= execute the test
pb
=
ProcessTools
.
createJavaProcessBuilder
(
"-cp"
,
"."
,
"-XX:+UnlockDiagnosticVMOptions"
,
"-XX:MallocMaxTestWords="
+
mallocMaxTestWords
,
className
);
output
=
new
OutputAnalyzer
(
pb
.
start
());
String
[]
expectedMsgs
=
{
"java.lang.LinkageError"
,
"java.lang.NoSuchMethodError"
,
"Main method not found in class "
+
className
,
"insufficient memory"
};
MultipleOrMatch
(
output
,
expectedMsgs
);
}
private
static
void
MultipleOrMatch
(
OutputAnalyzer
analyzer
,
String
[]
whatToMatch
)
{
String
output
=
analyzer
.
getOutput
();
for
(
String
expected
:
whatToMatch
)
if
(
output
.
contains
(
expected
))
return
;
String
err
=
" stdout: ["
+
analyzer
.
getOutput
()
+
"];\n"
+
" exitValue = "
+
analyzer
.
getExitValue
()
+
"\n"
;
System
.
err
.
println
(
err
);
StringBuilder
msg
=
new
StringBuilder
(
"Output did not contain "
+
"any of the following expected messages: \n"
);
for
(
String
expected
:
whatToMatch
)
msg
.
append
(
expected
).
append
(
System
.
lineSeparator
());
throw
new
RuntimeException
(
msg
.
toString
());
}
}
test/runtime/
7020373/testc
ase.jar
→
test/runtime/
ClassFile/JsrRewritingTestC
ase.jar
浏览文件 @
c4ea8057
文件已移动
test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java
0 → 100644
浏览文件 @
c4ea8057
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test OomWhileParsingRepeatedJsr
* @summary Testing class file parser; specifically parsing
* a file with repeated JSR (jump local subroutine)
* bytecode command.
* @bug 6878713
* @bug 7030610
* @bug 7037122
* @bug 7123945
* @bug 8016029
* @library /testlibrary
* @run main OomWhileParsingRepeatedJsr
*/
import
com.oracle.java.testlibrary.*
;
public
class
OomWhileParsingRepeatedJsr
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// ======= Configure the test
String
jarFile
=
System
.
getProperty
(
"test.src"
)
+
"/testcase.jar"
;
String
className
=
"OOMCrashClass1960_2"
;
// limit is 768MB in native words
int
mallocMaxTestWords
=
(
1024
*
1024
*
768
/
4
);
if
(
Platform
.
is64bit
())
mallocMaxTestWords
=
(
mallocMaxTestWords
/
2
);
// ======= extract the test class
ProcessBuilder
pb
=
new
ProcessBuilder
(
new
String
[]
{
JDKToolFinder
.
getJDKTool
(
"jar"
),
"xvf"
,
jarFile
}
);
OutputAnalyzer
output
=
new
OutputAnalyzer
(
pb
.
start
());
output
.
shouldHaveExitValue
(
0
);
// ======= execute the test
pb
=
ProcessTools
.
createJavaProcessBuilder
(
"-cp"
,
"."
,
"-XX:+UnlockDiagnosticVMOptions"
,
"-XX:MallocMaxTestWords="
+
mallocMaxTestWords
,
className
);
output
=
new
OutputAnalyzer
(
pb
.
start
());
output
.
shouldContain
(
"Cannot reserve enough memory"
);
}
}
test/runtime/
6878713
/testcase.jar
→
test/runtime/
ClassFile
/testcase.jar
浏览文件 @
c4ea8057
文件已移动
test/runtime/InitialThreadOverflow/testme.sh
浏览文件 @
c4ea8057
...
...
@@ -43,9 +43,9 @@ then
exit
0
fi
gcc_cmd
=
`
which g
cc
`
if
[
"x
$gcc_cmd
"
=
=
"x"
]
;
then
echo
"WARNING: g
cc
not found. Cannot execute test."
2>&1
gcc_cmd
=
`
which g
++
`
if
[
"x
$gcc_cmd
"
=
"x"
]
;
then
echo
"WARNING: g
++
not found. Cannot execute test."
2>&1
exit
0
;
fi
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录