Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
4f1e9592
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看板
提交
4f1e9592
编写于
8月 29, 2013
作者:
D
dsamersoff
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
d5103fad
8c157aef
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
256 addition
and
89 deletion
+256
-89
src/os/linux/vm/os_linux.cpp
src/os/linux/vm/os_linux.cpp
+72
-47
src/share/vm/runtime/os.cpp
src/share/vm/runtime/os.cpp
+0
-38
src/share/vm/runtime/os.hpp
src/share/vm/runtime/os.hpp
+0
-4
test/runtime/InitialThreadOverflow/DoOverflow.java
test/runtime/InitialThreadOverflow/DoOverflow.java
+41
-0
test/runtime/InitialThreadOverflow/invoke.cxx
test/runtime/InitialThreadOverflow/invoke.cxx
+70
-0
test/runtime/InitialThreadOverflow/testme.sh
test/runtime/InitialThreadOverflow/testme.sh
+73
-0
未找到文件。
src/os/linux/vm/os_linux.cpp
浏览文件 @
4f1e9592
...
...
@@ -2943,6 +2943,53 @@ bool os::pd_uncommit_memory(char* addr, size_t size) {
return
res
!=
(
uintptr_t
)
MAP_FAILED
;
}
static
address
get_stack_commited_bottom
(
address
bottom
,
size_t
size
)
{
address
nbot
=
bottom
;
address
ntop
=
bottom
+
size
;
size_t
page_sz
=
os
::
vm_page_size
();
unsigned
pages
=
size
/
page_sz
;
unsigned
char
vec
[
1
];
unsigned
imin
=
1
,
imax
=
pages
+
1
,
imid
;
int
mincore_return_value
;
while
(
imin
<
imax
)
{
imid
=
(
imax
+
imin
)
/
2
;
nbot
=
ntop
-
(
imid
*
page_sz
);
// Use a trick with mincore to check whether the page is mapped or not.
// mincore sets vec to 1 if page resides in memory and to 0 if page
// is swapped output but if page we are asking for is unmapped
// it returns -1,ENOMEM
mincore_return_value
=
mincore
(
nbot
,
page_sz
,
vec
);
if
(
mincore_return_value
==
-
1
)
{
// Page is not mapped go up
// to find first mapped page
if
(
errno
!=
EAGAIN
)
{
assert
(
errno
==
ENOMEM
,
"Unexpected mincore errno"
);
imax
=
imid
;
}
}
else
{
// Page is mapped go down
// to find first not mapped page
imin
=
imid
+
1
;
}
}
nbot
=
nbot
+
page_sz
;
// Adjust stack bottom one page up if last checked page is not mapped
if
(
mincore_return_value
==
-
1
)
{
nbot
=
nbot
+
page_sz
;
}
return
nbot
;
}
// Linux uses a growable mapping for the stack, and if the mapping for
// the stack guard pages is not removed when we detach a thread the
// stack cannot grow beyond the pages where the stack guard was
...
...
@@ -2957,59 +3004,37 @@ bool os::pd_uncommit_memory(char* addr, size_t size) {
// So, we need to know the extent of the stack mapping when
// create_stack_guard_pages() is called.
// Find the bounds of the stack mapping. Return true for success.
//
// We only need this for stacks that are growable: at the time of
// writing thread stacks don't use growable mappings (i.e. those
// creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
// only applies to the main thread.
static
bool
get_stack_bounds
(
uintptr_t
*
bottom
,
uintptr_t
*
top
)
{
char
buf
[
128
];
int
fd
,
sz
;
if
((
fd
=
::
open
(
"/proc/self/maps"
,
O_RDONLY
))
<
0
)
{
return
false
;
}
const
char
kw
[]
=
"[stack]"
;
const
int
kwlen
=
sizeof
(
kw
)
-
1
;
// Address part of /proc/self/maps couldn't be more than 128 bytes
while
((
sz
=
os
::
get_line_chars
(
fd
,
buf
,
sizeof
(
buf
)))
>
0
)
{
if
(
sz
>
kwlen
&&
::
memcmp
(
buf
+
sz
-
kwlen
,
kw
,
kwlen
)
==
0
)
{
// Extract addresses
if
(
sscanf
(
buf
,
"%"
SCNxPTR
"-%"
SCNxPTR
,
bottom
,
top
)
==
2
)
{
uintptr_t
sp
=
(
uintptr_t
)
__builtin_frame_address
(
0
);
if
(
sp
>=
*
bottom
&&
sp
<=
*
top
)
{
::
close
(
fd
);
return
true
;
}
}
}
}
::
close
(
fd
);
return
false
;
}
// If the (growable) stack mapping already extends beyond the point
// where we're going to put our guard pages, truncate the mapping at
// that point by munmap()ping it. This ensures that when we later
// munmap() the guard pages we don't leave a hole in the stack
// mapping. This only affects the main/initial thread
, but guard
// against future OS changes
// mapping. This only affects the main/initial thread
bool
os
::
pd_create_stack_guard_pages
(
char
*
addr
,
size_t
size
)
{
uintptr_t
stack_extent
,
stack_base
;
bool
chk_bounds
=
NOT_DEBUG
(
os
::
Linux
::
is_initial_thread
())
DEBUG_ONLY
(
true
);
if
(
chk_bounds
&&
get_stack_bounds
(
&
stack_extent
,
&
stack_base
))
{
assert
(
os
::
Linux
::
is_initial_thread
(),
"growable stack in non-initial thread"
);
if
(
stack_extent
<
(
uintptr_t
)
addr
)
::
munmap
((
void
*
)
stack_extent
,
(
uintptr_t
)
addr
-
stack_extent
);
if
(
os
::
Linux
::
is_initial_thread
())
{
// As we manually grow stack up to bottom inside create_attached_thread(),
// it's likely that os::Linux::initial_thread_stack_bottom is mapped and
// we don't need to do anything special.
// Check it first, before calling heavy function.
uintptr_t
stack_extent
=
(
uintptr_t
)
os
::
Linux
::
initial_thread_stack_bottom
();
unsigned
char
vec
[
1
];
if
(
mincore
((
address
)
stack_extent
,
os
::
vm_page_size
(),
vec
)
==
-
1
)
{
// Fallback to slow path on all errors, including EAGAIN
stack_extent
=
(
uintptr_t
)
get_stack_commited_bottom
(
os
::
Linux
::
initial_thread_stack_bottom
(),
(
size_t
)
addr
-
stack_extent
);
}
if
(
stack_extent
<
(
uintptr_t
)
addr
)
{
::
munmap
((
void
*
)
stack_extent
,
(
uintptr_t
)(
addr
-
stack_extent
));
}
}
return
os
::
commit_memory
(
addr
,
size
,
!
ExecMem
);
...
...
@@ -3018,13 +3043,13 @@ bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
// If this is a growable mapping, remove the guard pages entirely by
// munmap()ping them. If not, just call uncommit_memory(). This only
// affects the main/initial thread, but guard against future OS changes
// It's safe to always unmap guard pages for initial thread because we
// always place it right after end of the mapped region
bool
os
::
remove_stack_guard_pages
(
char
*
addr
,
size_t
size
)
{
uintptr_t
stack_extent
,
stack_base
;
bool
chk_bounds
=
NOT_DEBUG
(
os
::
Linux
::
is_initial_thread
())
DEBUG_ONLY
(
true
);
if
(
chk_bounds
&&
get_stack_bounds
(
&
stack_extent
,
&
stack_base
))
{
assert
(
os
::
Linux
::
is_initial_thread
(),
"growable stack in non-initial thread"
);
if
(
os
::
Linux
::
is_initial_thread
())
{
return
::
munmap
(
addr
,
size
)
==
0
;
}
...
...
src/share/vm/runtime/os.cpp
浏览文件 @
4f1e9592
...
...
@@ -1424,44 +1424,6 @@ bool os::is_server_class_machine() {
return
result
;
}
// Read file line by line, if line is longer than bsize,
// skip rest of line.
int
os
::
get_line_chars
(
int
fd
,
char
*
buf
,
const
size_t
bsize
){
size_t
sz
,
i
=
0
;
// read until EOF, EOL or buf is full
while
((
sz
=
(
int
)
read
(
fd
,
&
buf
[
i
],
1
))
==
1
&&
i
<
(
bsize
-
2
)
&&
buf
[
i
]
!=
'\n'
)
{
++
i
;
}
if
(
buf
[
i
]
==
'\n'
)
{
// EOL reached so ignore EOL character and return
buf
[
i
]
=
0
;
return
(
int
)
i
;
}
buf
[
i
+
1
]
=
0
;
if
(
sz
!=
1
)
{
// EOF reached. if we read chars before EOF return them and
// return EOF on next call otherwise return EOF
return
(
i
==
0
)
?
-
1
:
(
int
)
i
;
}
// line is longer than size of buf, skip to EOL
char
ch
;
while
(
read
(
fd
,
&
ch
,
1
)
==
1
&&
ch
!=
'\n'
)
{
// Do nothing
}
// return initial part of line that fits in buf.
// If we reached EOF, it will be returned on next call.
return
(
int
)
i
;
}
void
os
::
SuspendedThreadTask
::
run
()
{
assert
(
Threads_lock
->
owned_by_self
()
||
(
_thread
==
VMThread
::
vm_thread
()),
"must have threads lock to call this"
);
internal_do_task
();
...
...
src/share/vm/runtime/os.hpp
浏览文件 @
4f1e9592
...
...
@@ -725,10 +725,6 @@ class os: AllStatic {
// Hook for os specific jvm options that we don't want to abort on seeing
static
bool
obsolete_option
(
const
JavaVMOption
*
option
);
// Read file line by line. If line is longer than bsize,
// rest of line is skipped. Returns number of bytes read or -1 on EOF
static
int
get_line_chars
(
int
fd
,
char
*
buf
,
const
size_t
bsize
);
// Extensions
#include "runtime/os_ext.hpp"
...
...
test/runtime/InitialThreadOverflow/DoOverflow.java
0 → 100644
浏览文件 @
4f1e9592
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public
class
DoOverflow
{
static
int
count
;
public
void
overflow
()
{
count
+=
1
;
overflow
();
}
public
static
void
printIt
()
{
System
.
out
.
println
(
"Going to overflow stack"
);
try
{
new
DoOverflow
().
overflow
();
}
catch
(
java
.
lang
.
StackOverflowError
e
)
{
System
.
out
.
println
(
"Overflow OK "
+
count
);
}
}
}
test/runtime/InitialThreadOverflow/invoke.cxx
0 → 100644
浏览文件 @
4f1e9592
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <assert.h>
#include <jni.h>
#include <pthread.h>
JavaVM
*
jvm
;
void
*
floobydust
(
void
*
p
)
{
JNIEnv
*
env
;
jvm
->
AttachCurrentThread
((
void
**
)
&
env
,
NULL
);
jclass
class_id
=
env
->
FindClass
(
"DoOverflow"
);
assert
(
class_id
);
jmethodID
method_id
=
env
->
GetStaticMethodID
(
class_id
,
"printIt"
,
"()V"
);
assert
(
method_id
);
env
->
CallStaticVoidMethod
(
class_id
,
method_id
,
NULL
);
jvm
->
DetachCurrentThread
();
}
int
main
(
int
argc
,
const
char
**
argv
)
{
JavaVMOption
options
[
1
];
options
[
0
].
optionString
=
(
char
*
)
"-Xss320k"
;
JavaVMInitArgs
vm_args
;
vm_args
.
version
=
JNI_VERSION_1_2
;
vm_args
.
ignoreUnrecognized
=
JNI_TRUE
;
vm_args
.
options
=
options
;
vm_args
.
nOptions
=
1
;
JNIEnv
*
env
;
jint
result
=
JNI_CreateJavaVM
(
&
jvm
,
(
void
**
)
&
env
,
&
vm_args
);
assert
(
result
>=
0
);
pthread_t
thr
;
pthread_create
(
&
thr
,
NULL
,
floobydust
,
NULL
);
pthread_join
(
thr
,
NULL
);
floobydust
(
NULL
);
return
0
;
}
test/runtime/InitialThreadOverflow/testme.sh
0 → 100644
浏览文件 @
4f1e9592
#!/bin/sh
# Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
# @test testme.sh
# @bug 8009062
# @summary Poor performance of JNI AttachCurrentThread after fix for 7017193
# @compile DoOverflow.java
# @run shell testme.sh
set
-x
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
if
[
"
${
VM_OS
}
"
!=
"linux"
]
then
echo
"Test only valid for Linux"
exit
0
fi
gcc_cmd
=
`
which gcc
`
if
[
"x
$gcc_cmd
"
==
"x"
]
;
then
echo
"WARNING: gcc not found. Cannot execute test."
2>&1
exit
0
;
fi
CFLAGS
=
"-m
${
VM_BITS
}
"
LD_LIBRARY_PATH
=
.:
${
COMPILEJAVA
}
/jre/lib/
${
VM_CPU
}
/
${
VM_TYPE
}
:/usr/lib:
$LD_LIBRARY_PATH
export
LD_LIBRARY_PATH
cp
${
TESTSRC
}${
FS
}
invoke.cxx
.
# Copy the result of our @compile action:
cp
${
TESTCLASSES
}${
FS
}
DoOverflow.class
.
echo
"Compilation flag:
${
COMP_FLAG
}
"
# Note pthread may not be found thus invoke creation will fail to be created.
# Check to ensure you have a /usr/lib/libpthread.so if you don't please look
# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation.
$gcc_cmd
-DLINUX
${
CFLAGS
}
-o
invoke
\
-I
${
COMPILEJAVA
}
/include
-I
${
COMPILEJAVA
}
/include/linux
\
-L
${
COMPILEJAVA
}
/jre/lib/
${
VM_CPU
}
/
${
VM_TYPE
}
\
-ljvm
-lpthread
invoke.cxx
./invoke
exit
$?
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录