Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
a4d467b2
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看板
提交
a4d467b2
编写于
1月 27, 2020
作者:
A
andrew
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
45904d90
0dc1d994
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
172 addition
and
342 deletion
+172
-342
.hgtags
.hgtags
+2
-0
agent/src/os/linux/ps_core.c
agent/src/os/linux/ps_core.c
+7
-4
make/aix/makefiles/vm.make
make/aix/makefiles/vm.make
+1
-0
make/bsd/makefiles/vm.make
make/bsd/makefiles/vm.make
+1
-0
make/linux/makefiles/vm.make
make/linux/makefiles/vm.make
+1
-0
make/solaris/makefiles/vm.make
make/solaris/makefiles/vm.make
+1
-0
src/share/vm/adlc/filebuff.cpp
src/share/vm/adlc/filebuff.cpp
+1
-195
src/share/vm/adlc/filebuff.hpp
src/share/vm/adlc/filebuff.hpp
+1
-27
src/share/vm/opto/c2_globals.hpp
src/share/vm/opto/c2_globals.hpp
+0
-3
src/share/vm/opto/memnode.cpp
src/share/vm/opto/memnode.cpp
+2
-1
src/share/vm/runtime/arguments.cpp
src/share/vm/runtime/arguments.cpp
+3
-2
src/share/vm/runtime/vmThread.cpp
src/share/vm/runtime/vmThread.cpp
+1
-0
src/share/vm/services/heapDumper.cpp
src/share/vm/services/heapDumper.cpp
+149
-108
src/share/vm/utilities/vmError.cpp
src/share/vm/utilities/vmError.cpp
+2
-2
未找到文件。
.hgtags
浏览文件 @
a4d467b2
...
@@ -1294,3 +1294,5 @@ ee19c358e3b8deeda2f64d660a0870df7b1abd49 jdk8u242-b03
...
@@ -1294,3 +1294,5 @@ ee19c358e3b8deeda2f64d660a0870df7b1abd49 jdk8u242-b03
8b80409d5840142a27e274d33948f483a6406a50 jdk8u242-b07
8b80409d5840142a27e274d33948f483a6406a50 jdk8u242-b07
7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-b08
7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-b08
7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-ga
7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-ga
8c0733543544bbcd32c4404630d764d280299056 jdk8u252-b00
a67e9c6edcdd73cb860a16990f0905e102c282d7 jdk8u252-b01
agent/src/os/linux/ps_core.c
浏览文件 @
a4d467b2
...
@@ -868,6 +868,9 @@ err:
...
@@ -868,6 +868,9 @@ err:
#define LINK_MAP_LD_OFFSET offsetof(struct link_map, l_ld)
#define LINK_MAP_LD_OFFSET offsetof(struct link_map, l_ld)
#define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next)
#define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next)
#define INVALID_LOAD_ADDRESS -1L
#define ZERO_LOAD_ADDRESS 0x0L
// Calculate the load address of shared library
// Calculate the load address of shared library
// on prelink-enabled environment.
// on prelink-enabled environment.
//
//
...
@@ -884,7 +887,7 @@ static uintptr_t calc_prelinked_load_address(struct ps_prochandle* ph, int lib_f
...
@@ -884,7 +887,7 @@ static uintptr_t calc_prelinked_load_address(struct ps_prochandle* ph, int lib_f
phbuf
=
read_program_header_table
(
lib_fd
,
elf_ehdr
);
phbuf
=
read_program_header_table
(
lib_fd
,
elf_ehdr
);
if
(
phbuf
==
NULL
)
{
if
(
phbuf
==
NULL
)
{
print_debug
(
"can't read program header of shared object
\n
"
);
print_debug
(
"can't read program header of shared object
\n
"
);
return
0L
;
return
INVALID_LOAD_ADDRESS
;
}
}
// Get the address of .dynamic section from shared library.
// Get the address of .dynamic section from shared library.
...
@@ -900,7 +903,7 @@ static uintptr_t calc_prelinked_load_address(struct ps_prochandle* ph, int lib_f
...
@@ -900,7 +903,7 @@ static uintptr_t calc_prelinked_load_address(struct ps_prochandle* ph, int lib_f
if
(
ps_pdread
(
ph
,
(
psaddr_t
)
link_map_addr
+
LINK_MAP_LD_OFFSET
,
if
(
ps_pdread
(
ph
,
(
psaddr_t
)
link_map_addr
+
LINK_MAP_LD_OFFSET
,
&
lib_ld
,
sizeof
(
uintptr_t
))
!=
PS_OK
)
{
&
lib_ld
,
sizeof
(
uintptr_t
))
!=
PS_OK
)
{
print_debug
(
"can't read address of dynamic section in shared object
\n
"
);
print_debug
(
"can't read address of dynamic section in shared object
\n
"
);
return
0L
;
return
INVALID_LOAD_ADDRESS
;
}
}
// Return the load address which is calculated by the address of .dynamic
// Return the load address which is calculated by the address of .dynamic
...
@@ -1011,9 +1014,9 @@ static bool read_shared_lib_info(struct ps_prochandle* ph) {
...
@@ -1011,9 +1014,9 @@ static bool read_shared_lib_info(struct ps_prochandle* ph) {
// continue with other libraries...
// continue with other libraries...
}
else
{
}
else
{
if
(
read_elf_header
(
lib_fd
,
&
elf_ehdr
))
{
if
(
read_elf_header
(
lib_fd
,
&
elf_ehdr
))
{
if
(
lib_base_diff
==
0x0L
)
{
if
(
lib_base_diff
==
ZERO_LOAD_ADDRESS
)
{
lib_base_diff
=
calc_prelinked_load_address
(
ph
,
lib_fd
,
&
elf_ehdr
,
link_map_addr
);
lib_base_diff
=
calc_prelinked_load_address
(
ph
,
lib_fd
,
&
elf_ehdr
,
link_map_addr
);
if
(
lib_base_diff
==
0x0L
)
{
if
(
lib_base_diff
==
INVALID_LOAD_ADDRESS
)
{
close
(
lib_fd
);
close
(
lib_fd
);
return
false
;
return
false
;
}
}
...
...
make/aix/makefiles/vm.make
浏览文件 @
a4d467b2
...
@@ -119,6 +119,7 @@ CFLAGS += $(CFLAGS/NOEX)
...
@@ -119,6 +119,7 @@ CFLAGS += $(CFLAGS/NOEX)
# Extra flags from gnumake's invocation or environment
# Extra flags from gnumake's invocation or environment
CFLAGS
+=
$(EXTRA_CFLAGS)
CFLAGS
+=
$(EXTRA_CFLAGS)
LFLAGS
+=
$(EXTRA_CFLAGS)
$(EXTRA_LDFLAGS)
LFLAGS
+=
$(EXTRA_CFLAGS)
$(EXTRA_LDFLAGS)
ASFLAGS
+=
$(EXTRA_ASFLAGS)
# Don't set excutable bit on stack segment
# Don't set excutable bit on stack segment
# the same could be done by separate execstack command
# the same could be done by separate execstack command
...
...
make/bsd/makefiles/vm.make
浏览文件 @
a4d467b2
...
@@ -121,6 +121,7 @@ CFLAGS += $(CFLAGS/NOEX)
...
@@ -121,6 +121,7 @@ CFLAGS += $(CFLAGS/NOEX)
# Extra flags from gnumake's invocation or environment
# Extra flags from gnumake's invocation or environment
CFLAGS
+=
$(EXTRA_CFLAGS)
CFLAGS
+=
$(EXTRA_CFLAGS)
LFLAGS
+=
$(EXTRA_CFLAGS)
$(EXTRA_LDFLAGS)
LFLAGS
+=
$(EXTRA_CFLAGS)
$(EXTRA_LDFLAGS)
ASFLAGS
+=
$(EXTRA_ASFLAGS)
# Don't set excutable bit on stack segment
# Don't set excutable bit on stack segment
# the same could be done by separate execstack command
# the same could be done by separate execstack command
...
...
make/linux/makefiles/vm.make
浏览文件 @
a4d467b2
...
@@ -124,6 +124,7 @@ CFLAGS += $(CFLAGS/NOEX)
...
@@ -124,6 +124,7 @@ CFLAGS += $(CFLAGS/NOEX)
# Extra flags from gnumake's invocation or environment
# Extra flags from gnumake's invocation or environment
CFLAGS
+=
$(EXTRA_CFLAGS)
CFLAGS
+=
$(EXTRA_CFLAGS)
LFLAGS
+=
$(EXTRA_CFLAGS)
$(EXTRA_LDFLAGS)
LFLAGS
+=
$(EXTRA_CFLAGS)
$(EXTRA_LDFLAGS)
ASFLAGS
+=
$(EXTRA_ASFLAGS)
# Don't set excutable bit on stack segment
# Don't set excutable bit on stack segment
# the same could be done by separate execstack command
# the same could be done by separate execstack command
...
...
make/solaris/makefiles/vm.make
浏览文件 @
a4d467b2
...
@@ -109,6 +109,7 @@ CFLAGS += $(CFLAGS/NOEX)
...
@@ -109,6 +109,7 @@ CFLAGS += $(CFLAGS/NOEX)
# Extra flags from gnumake's invocation or environment
# Extra flags from gnumake's invocation or environment
CFLAGS
+=
$(EXTRA_CFLAGS)
CFLAGS
+=
$(EXTRA_CFLAGS)
ASFLAGS
+=
$(EXTRA_ASFLAGS)
# Math Library (libm.so), do not use -lm.
# Math Library (libm.so), do not use -lm.
# There might be two versions of libm.so on the build system:
# There might be two versions of libm.so on the build system:
...
...
src/share/vm/adlc/filebuff.cpp
浏览文件 @
a4d467b2
/*
/*
* Copyright (c) 1997, 201
0
, 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
...
@@ -89,200 +89,6 @@ char *FileBuff::get_line(void) {
...
@@ -89,200 +89,6 @@ char *FileBuff::get_line(void) {
return
retval
;
return
retval
;
}
}
//------------------------------FileBuffRegion---------------------------------
// Create a new region in a FileBuff.
FileBuffRegion
::
FileBuffRegion
(
FileBuff
*
bufr
,
int
soln
,
int
ln
,
int
off
,
int
len
)
:
_bfr
(
bufr
),
_sol
(
soln
),
_line
(
ln
),
_offset
(
off
),
_length
(
len
)
{
_next
=
NULL
;
// No chained regions
}
//------------------------------~FileBuffRegion--------------------------------
// Delete the entire linked list of buffer regions.
FileBuffRegion
::~
FileBuffRegion
()
{
if
(
_next
)
delete
_next
;
}
//------------------------------copy-------------------------------------------
// Deep copy a FileBuffRegion
FileBuffRegion
*
FileBuffRegion
::
copy
()
{
if
(
!
this
)
return
NULL
;
// The empty buffer region
FileBuffRegion
*
br
=
new
FileBuffRegion
(
_bfr
,
_sol
,
_line
,
_offset
,
_length
);
if
(
_next
)
br
->
_next
=
_next
->
copy
();
return
br
;
}
//------------------------------merge------------------------------------------
// Merge another buffer region into this buffer region. Make overlapping areas
// become a single region. Remove (delete) the input FileBuffRegion.
// Since the buffer regions are sorted by file offset, this is a varient of a
// "sorted-merge" running in linear time.
FileBuffRegion
*
FileBuffRegion
::
merge
(
FileBuffRegion
*
br
)
{
if
(
!
br
)
return
this
;
// Merging nothing
if
(
!
this
)
return
br
;
// Merging into nothing
assert
(
_bfr
==
br
->
_bfr
,
""
);
// Check for pointer-equivalent buffers
if
(
_offset
<
br
->
_offset
)
{
// "this" starts before "br"
if
(
_offset
+
_length
<
br
->
_offset
)
{
// "this" ends before "br"
if
(
_next
)
_next
->
merge
(
br
);
// Merge with remainder of list
else
_next
=
br
;
// No more in this list; just append.
}
else
{
// Regions overlap.
int
l
=
br
->
_offset
+
br
->
_length
-
_offset
;
if
(
l
>
_length
)
_length
=
l
;
// Pick larger region
FileBuffRegion
*
nr
=
br
->
_next
;
// Get rest of region
br
->
_next
=
NULL
;
// Remove indication of rest of region
delete
br
;
// Delete this region (it's been subsumed).
if
(
nr
)
merge
(
nr
);
// Merge with rest of region
}
// End of if regions overlap or not.
}
else
{
// "this" starts after "br"
if
(
br
->
_offset
+
br
->
_length
<
_offset
)
{
// "br" ends before "this"
FileBuffRegion
*
nr
=
new
FileBuffRegion
(
_bfr
,
_sol
,
_line
,
_offset
,
_length
);
nr
->
_next
=
_next
;
// Structure copy "this" guy to "nr"
*
this
=
*
br
;
// Structure copy "br" over "this".
br
->
_next
=
NULL
;
// Remove indication of rest of region
delete
br
;
// Delete this region (it's been copied)
merge
(
nr
);
// Finish merging
}
else
{
// Regions overlap.
int
l
=
_offset
+
_length
-
br
->
_offset
;
if
(
l
>
_length
)
_length
=
l
;
// Pick larger region
_offset
=
br
->
_offset
;
// Start with earlier region
_sol
=
br
->
_sol
;
// Also use earlier line start
_line
=
br
->
_line
;
// Also use earlier line
FileBuffRegion
*
nr
=
br
->
_next
;
// Get rest of region
br
->
_next
=
NULL
;
// Remove indication of rest of region
delete
br
;
// Delete this region (it's been subsumed).
if
(
nr
)
merge
(
nr
);
// Merge with rest of region
}
// End of if regions overlap or not.
}
return
this
;
}
//------------------------------expandtab--------------------------------------
static
int
expandtab
(
ostream
&
os
,
int
off
,
char
c
,
char
fill1
,
char
fill2
)
{
if
(
c
==
'\t'
)
{
// Tab?
do
os
<<
fill1
;
// Expand the tab; Output space
while
(
(
++
off
)
&
7
);
// Expand to tab stop
}
else
{
// Normal character
os
<<
fill2
;
// Display normal character
off
++
;
// Increment "cursor" offset
}
return
off
;
}
//------------------------------printline--------------------------------------
// Print and highlite a region of a line. Return the amount of highliting left
// to do (i.e. highlite length minus length of line).
static
int
printline
(
ostream
&
os
,
const
char
*
fname
,
int
line
,
const
char
*
_sol
,
int
skip
,
int
len
)
{
// Display the entire tab-expanded line
os
<<
fname
<<
":"
<<
line
<<
": "
;
const
char
*
t
=
strchr
(
_sol
,
'\n'
)
+
1
;
// End of line
int
off
=
0
;
// Cursor offset for tab expansion
const
char
*
s
=
_sol
;
// Nice string pointer
while
(
t
-
s
)
{
// Display whole line
char
c
=
*
s
++
;
// Get next character to display
off
=
expandtab
(
os
,
off
,
c
,
' '
,
c
);
}
// Display the tab-expanded skippings before underlining.
os
<<
fname
<<
":"
<<
line
<<
": "
;
off
=
0
;
// Cursor offset for tab expansion
s
=
_sol
;
// Restart string pointer
// Start underlining.
if
(
skip
!=
-
1
)
{
// The no-start-indicating flag
const
char
*
u
=
_sol
+
skip
;
// Amount to skip
while
(
u
-
s
)
// Display skipped part
off
=
expandtab
(
os
,
off
,
*
s
++
,
' '
,
' '
);
os
<<
'^'
;
// Start region
off
++
;
// Moved cursor
len
--
;
// 1 less char to do
if
(
*
s
++
==
'\t'
)
// Starting character is a tab?
off
=
expandtab
(
os
,
off
,
'\t'
,
'-'
,
'^'
);
}
// Long region doesn't end on this line
int
llen
=
(
int
)(
t
-
s
);
// Length of line, minus what's already done
if
(
len
>
llen
)
{
// Doing entire rest of line?
while
(
t
-
s
)
// Display rest of line
off
=
expandtab
(
os
,
off
,
*
s
++
,
'-'
,
'-'
);
os
<<
'\n'
;
// EOL
return
len
-
llen
;
// Return what's not yet done.
}
// Region does end on this line. This code fails subtly if the region ends
// in a tab character.
int
i
;
for
(
i
=
1
;
i
<
len
;
i
++
)
// Underline just what's needed
off
=
expandtab
(
os
,
off
,
*
s
++
,
'-'
,
'-'
);
if
(
i
==
len
)
os
<<
'^'
;
// Mark end of region
os
<<
'\n'
;
// End of marked line
return
0
;
// All done
}
//------------------------------print------------------------------------------
//std::ostream& operator<< ( std::ostream& os, FileBuffRegion &br ) {
ostream
&
operator
<<
(
ostream
&
os
,
FileBuffRegion
&
br
)
{
if
(
&
br
==
NULL
)
return
os
;
// The empty buffer region
FileBuffRegion
*
brp
=
&
br
;
// Pointer to region
while
(
brp
)
{
// While have chained regions
brp
->
print
(
os
);
// Print region
brp
=
brp
->
_next
;
// Chain to next
}
return
os
;
// Return final stream
}
//------------------------------print------------------------------------------
// Print the FileBuffRegion to a stream. FileBuffRegions are printed with the
// filename and line number to the left, and complete text lines to the right.
// Selected portions (portions of a line actually in the FileBuffRegion are
// underlined. Ellipses are used for long multi-line regions.
//void FileBuffRegion::print( std::ostream& os ) {
void
FileBuffRegion
::
print
(
ostream
&
os
)
{
if
(
!
this
)
return
;
// Nothing to print
char
*
s
=
_bfr
->
get_line
();
int
skip
=
(
int
)(
_offset
-
_sol
);
// Amount to skip to start of data
int
len
=
printline
(
os
,
_bfr
->
_fp
->
_name
,
_line
,
s
,
skip
,
_length
);
if
(
!
len
)
return
;
// All done; exit
// Here we require at least 2 lines
int
off1
=
_length
-
len
+
skip
;
// Length of line 1
int
off2
=
off1
+
_sol
;
// Offset to start of line 2
char
*
s2
=
_bfr
->
get_line
();
// Start of line 2
char
*
s3
=
strchr
(
s2
,
'\n'
)
+
1
;
// Start of line 3 (unread)
if
(
len
<=
(
s3
-
s2
)
)
{
// It all fits on the next line
printline
(
os
,
_bfr
->
_fp
->
_name
,
_line
+
1
,
s2
,
-
1
,
len
);
// Print&underline
return
;
}
// Here we require at least 3 lines
int
off3
=
off2
+
(
int
)(
s3
-
s2
);
// Offset to start of line 3
s3
=
_bfr
->
get_line
();
// Start of line 3 (read)
const
char
*
s4
=
strchr
(
s3
,
'\n'
)
+
1
;
// Start of line 4 (unread)
if
(
len
<
(
s4
-
s3
)
)
{
// It all fits on the next 2 lines
s2
=
_bfr
->
get_line
();
len
=
printline
(
os
,
_bfr
->
_fp
->
_name
,
_line
+
1
,
s2
,
-
1
,
len
);
// Line 2
s3
=
_bfr
->
get_line
();
printline
(
os
,
_bfr
->
_fp
->
_name
,
_line
+
2
,
s3
,
-
1
,
len
);
// Line 3
return
;
}
// Here we require at least 4 lines.
// Print only the 1st and last line, with ellipses in middle.
os
<<
"...
\n
"
;
// The ellipses
int
cline
=
_line
+
1
;
// Skipped 2 lines
do
{
// Do until find last line
len
-=
(
int
)(
s3
-
s2
);
// Remove length of line
cline
++
;
// Next line
s2
=
_bfr
->
get_line
();
// Get next line from end of this line
s3
=
strchr
(
s2
,
'\n'
)
+
1
;
// Get end of next line
}
while
(
len
>
(
s3
-
s2
)
);
// Repeat until last line
printline
(
os
,
_bfr
->
_fp
->
_name
,
cline
,
s2
,
-
1
,
len
);
// Print & underline
}
//------------------------------file_error-------------------------------------
//------------------------------file_error-------------------------------------
void
FileBuff
::
file_error
(
int
flag
,
int
linenum
,
const
char
*
fmt
,
...)
void
FileBuff
::
file_error
(
int
flag
,
int
linenum
,
const
char
*
fmt
,
...)
{
{
...
...
src/share/vm/adlc/filebuff.hpp
浏览文件 @
a4d467b2
/*
/*
* Copyright (c) 1997, 201
0
, 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
...
@@ -46,7 +46,6 @@ class ArchDesc;
...
@@ -46,7 +46,6 @@ class ArchDesc;
// This class defines a nicely behaved buffer of text. Entire file of text
// This class defines a nicely behaved buffer of text. Entire file of text
// is read into buffer at creation, with sentinels at start and end.
// is read into buffer at creation, with sentinels at start and end.
class
FileBuff
{
class
FileBuff
{
friend
class
FileBuffRegion
;
private:
private:
long
_bufferSize
;
// Size of text holding buffer.
long
_bufferSize
;
// Size of text holding buffer.
long
_offset
;
// Expected filepointer offset.
long
_offset
;
// Expected filepointer offset.
...
@@ -82,29 +81,4 @@ class FileBuff {
...
@@ -82,29 +81,4 @@ class FileBuff {
// when the pointer is valid (i.e. just obtained from getline()).
// when the pointer is valid (i.e. just obtained from getline()).
long
getoff
(
const
char
*
s
)
{
return
_bufoff
+
(
long
)(
s
-
_buf
);
}
long
getoff
(
const
char
*
s
)
{
return
_bufoff
+
(
long
)(
s
-
_buf
);
}
};
};
//------------------------------FileBuffRegion---------------------------------
// A buffer region is really a region of some file, specified as a linked list
// of offsets and lengths. These regions can be merged; overlapping regions
// will coalesce.
class
FileBuffRegion
{
public:
// Workaround dev-studio friend/private bug
FileBuffRegion
*
_next
;
// Linked list of regions sorted by offset.
private:
FileBuff
*
_bfr
;
// The Buffer of the file
int
_offset
,
_length
;
// The file area
int
_sol
;
// Start of line where the file area starts
int
_line
;
// First line of region
public:
FileBuffRegion
(
FileBuff
*
,
int
sol
,
int
line
,
int
offset
,
int
len
);
~
FileBuffRegion
();
FileBuffRegion
*
copy
();
// Deep copy
FileBuffRegion
*
merge
(
FileBuffRegion
*
);
// Merge 2 regions; delete input
void
print
(
ostream
&
);
friend
ostream
&
operator
<<
(
ostream
&
,
FileBuffRegion
&
);
};
#endif // SHARE_VM_ADLC_FILEBUFF_HPP
#endif // SHARE_VM_ADLC_FILEBUFF_HPP
src/share/vm/opto/c2_globals.hpp
浏览文件 @
a4d467b2
...
@@ -360,9 +360,6 @@
...
@@ -360,9 +360,6 @@
"File to dump ideal graph to. If set overrides the " \
"File to dump ideal graph to. If set overrides the " \
"use of the network") \
"use of the network") \
\
\
product(bool, UseOldInlining, true, \
"Enable the 1.3 inlining strategy") \
\
product(bool, UseBimorphicInlining, true, \
product(bool, UseBimorphicInlining, true, \
"Profiling based inlining for two receivers") \
"Profiling based inlining for two receivers") \
\
\
...
...
src/share/vm/opto/memnode.cpp
浏览文件 @
a4d467b2
...
@@ -2485,7 +2485,8 @@ Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) {
...
@@ -2485,7 +2485,8 @@ Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) {
assert
(
mem
!=
mem
->
in
(
MemNode
::
Memory
),
"dead loop in StoreNode::Ideal"
);
assert
(
mem
!=
mem
->
in
(
MemNode
::
Memory
),
"dead loop in StoreNode::Ideal"
);
assert
(
Opcode
()
==
mem
->
Opcode
()
||
assert
(
Opcode
()
==
mem
->
Opcode
()
||
phase
->
C
->
get_alias_index
(
adr_type
())
==
Compile
::
AliasIdxRaw
,
phase
->
C
->
get_alias_index
(
adr_type
())
==
Compile
::
AliasIdxRaw
||
(
is_mismatched_access
()
||
mem
->
as_Store
()
->
is_mismatched_access
()),
"no mismatched stores, except on raw memory"
);
"no mismatched stores, except on raw memory"
);
if
(
mem
->
outcnt
()
==
1
&&
// check for intervening uses
if
(
mem
->
outcnt
()
==
1
&&
// check for intervening uses
...
...
src/share/vm/runtime/arguments.cpp
浏览文件 @
a4d467b2
...
@@ -302,9 +302,10 @@ static ObsoleteFlag obsolete_jvm_flags[] = {
...
@@ -302,9 +302,10 @@ static ObsoleteFlag obsolete_jvm_flags[] = {
{
"UsePermISM"
,
JDK_Version
::
jdk
(
8
),
JDK_Version
::
jdk
(
9
)
},
{
"UsePermISM"
,
JDK_Version
::
jdk
(
8
),
JDK_Version
::
jdk
(
9
)
},
{
"UseMPSS"
,
JDK_Version
::
jdk
(
8
),
JDK_Version
::
jdk
(
9
)
},
{
"UseMPSS"
,
JDK_Version
::
jdk
(
8
),
JDK_Version
::
jdk
(
9
)
},
{
"UseStringCache"
,
JDK_Version
::
jdk
(
8
),
JDK_Version
::
jdk
(
9
)
},
{
"UseStringCache"
,
JDK_Version
::
jdk
(
8
),
JDK_Version
::
jdk
(
9
)
},
{
"UseOldInlining"
,
JDK_Version
::
jdk
(
9
),
JDK_Version
::
jdk
(
10
)
},
{
"UseOldInlining"
,
JDK_Version
::
jdk
_update
(
8
,
20
),
JDK_Version
::
jdk
(
10
)
},
{
"AutoShutdownNMT"
,
JDK_Version
::
jdk
(
9
),
JDK_Version
::
jdk
(
10
)
},
{
"AutoShutdownNMT"
,
JDK_Version
::
jdk
_update
(
8
,
40
),
JDK_Version
::
jdk
(
10
)
},
{
"CompilationRepeat"
,
JDK_Version
::
jdk
(
8
),
JDK_Version
::
jdk
(
9
)
},
{
"CompilationRepeat"
,
JDK_Version
::
jdk
(
8
),
JDK_Version
::
jdk
(
9
)
},
{
"SegmentedHeapDumpThreshold"
,
JDK_Version
::
jdk_update
(
8
,
252
),
JDK_Version
::
jdk
(
10
)
},
#ifdef PRODUCT
#ifdef PRODUCT
{
"DesiredMethodLimit"
,
{
"DesiredMethodLimit"
,
JDK_Version
::
jdk_update
(
7
,
2
),
JDK_Version
::
jdk
(
8
)
},
JDK_Version
::
jdk_update
(
7
,
2
),
JDK_Version
::
jdk
(
8
)
},
...
...
src/share/vm/runtime/vmThread.cpp
浏览文件 @
a4d467b2
...
@@ -507,6 +507,7 @@ void VMThread::loop() {
...
@@ -507,6 +507,7 @@ void VMThread::loop() {
_cur_vm_operation
=
safepoint_ops
;
_cur_vm_operation
=
safepoint_ops
;
if
(
_cur_vm_operation
!=
NULL
)
{
if
(
_cur_vm_operation
!=
NULL
)
{
do
{
do
{
EventMark
em
(
"Executing coalesced safepoint VM operation: %s"
,
_cur_vm_operation
->
name
());
// evaluate_operation deletes the op object so we have
// evaluate_operation deletes the op object so we have
// to grab the next op now
// to grab the next op now
VM_Operation
*
next
=
_cur_vm_operation
->
next
();
VM_Operation
*
next
=
_cur_vm_operation
->
next
();
...
...
src/share/vm/services/heapDumper.cpp
浏览文件 @
a4d467b2
...
@@ -50,8 +50,7 @@
...
@@ -50,8 +50,7 @@
* src/share/demo/jvmti/hprof/hprof_io.c
* src/share/demo/jvmti/hprof/hprof_io.c
*
*
*
*
* header "JAVA PROFILE 1.0.1" or "JAVA PROFILE 1.0.2"
* header "JAVA PROFILE 1.0.2" (0-terminated)
* (0-terminated)
*
*
* u4 size of identifiers. Identifiers are used to represent
* u4 size of identifiers. Identifiers are used to represent
* UTF8 strings, objects, stack traces, etc. They usually
* UTF8 strings, objects, stack traces, etc. They usually
...
@@ -382,6 +381,8 @@ class DumpWriter : public StackObj {
...
@@ -382,6 +381,8 @@ class DumpWriter : public StackObj {
size_t
_size
;
size_t
_size
;
size_t
_pos
;
size_t
_pos
;
jlong
_dump_start
;
char
*
_error
;
// error message when I/O fails
char
*
_error
;
// error message when I/O fails
void
set_file_descriptor
(
int
fd
)
{
_fd
=
fd
;
}
void
set_file_descriptor
(
int
fd
)
{
_fd
=
fd
;
}
...
@@ -405,6 +406,10 @@ class DumpWriter : public StackObj {
...
@@ -405,6 +406,10 @@ class DumpWriter : public StackObj {
bool
is_open
()
const
{
return
file_descriptor
()
>=
0
;
}
bool
is_open
()
const
{
return
file_descriptor
()
>=
0
;
}
void
flush
();
void
flush
();
jlong
dump_start
()
const
{
return
_dump_start
;
}
void
set_dump_start
(
jlong
pos
);
julong
current_record_length
();
// total number of bytes written to the disk
// total number of bytes written to the disk
julong
bytes_written
()
const
{
return
_bytes_written
;
}
julong
bytes_written
()
const
{
return
_bytes_written
;
}
...
@@ -446,6 +451,7 @@ DumpWriter::DumpWriter(const char* path) {
...
@@ -446,6 +451,7 @@ DumpWriter::DumpWriter(const char* path) {
_pos
=
0
;
_pos
=
0
;
_error
=
NULL
;
_error
=
NULL
;
_bytes_written
=
0L
;
_bytes_written
=
0L
;
_dump_start
=
(
jlong
)
-
1
;
_fd
=
os
::
create_binary_file
(
path
,
false
);
// don't replace existing file
_fd
=
os
::
create_binary_file
(
path
,
false
);
// don't replace existing file
// if the open failed we record the error
// if the open failed we record the error
...
@@ -473,6 +479,22 @@ void DumpWriter::close() {
...
@@ -473,6 +479,22 @@ void DumpWriter::close() {
}
}
}
}
// sets the dump starting position
void
DumpWriter
::
set_dump_start
(
jlong
pos
)
{
_dump_start
=
pos
;
}
julong
DumpWriter
::
current_record_length
()
{
if
(
is_open
())
{
// calculate the size of the dump record
julong
dump_end
=
bytes_written
()
+
bytes_unwritten
();
assert
(
dump_end
==
(
size_t
)
current_offset
(),
"checking"
);
julong
dump_len
=
dump_end
-
dump_start
()
-
4
;
return
dump_len
;
}
return
0
;
}
// write directly to the file
// write directly to the file
void
DumpWriter
::
write_internal
(
void
*
s
,
size_t
len
)
{
void
DumpWriter
::
write_internal
(
void
*
s
,
size_t
len
)
{
if
(
is_open
())
{
if
(
is_open
())
{
...
@@ -641,6 +663,18 @@ class DumperSupport : AllStatic {
...
@@ -641,6 +663,18 @@ class DumperSupport : AllStatic {
static
void
dump_prim_array
(
DumpWriter
*
writer
,
typeArrayOop
array
);
static
void
dump_prim_array
(
DumpWriter
*
writer
,
typeArrayOop
array
);
// create HPROF_FRAME record for the given method and bci
// create HPROF_FRAME record for the given method and bci
static
void
dump_stack_frame
(
DumpWriter
*
writer
,
int
frame_serial_num
,
int
class_serial_num
,
Method
*
m
,
int
bci
);
static
void
dump_stack_frame
(
DumpWriter
*
writer
,
int
frame_serial_num
,
int
class_serial_num
,
Method
*
m
,
int
bci
);
// check if we need to truncate an array
static
int
calculate_array_max_length
(
DumpWriter
*
writer
,
arrayOop
array
,
short
header_size
);
// writes a HPROF_HEAP_DUMP_SEGMENT record
static
void
write_dump_header
(
DumpWriter
*
writer
);
// fixes up the length of the current dump record
static
void
write_current_dump_record_length
(
DumpWriter
*
writer
);
// fixes up the current dump record and writes HPROF_HEAP_DUMP_END record
static
void
end_of_dump
(
DumpWriter
*
writer
);
};
};
// write a header of the given type
// write a header of the given type
...
@@ -1047,50 +1081,103 @@ void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, Klass* k) {
...
@@ -1047,50 +1081,103 @@ void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, Klass* k) {
}
}
}
}
// Hprof uses an u4 as record length field,
// which means we need to truncate arrays that are too long.
int
DumperSupport
::
calculate_array_max_length
(
DumpWriter
*
writer
,
arrayOop
array
,
short
header_size
)
{
BasicType
type
=
ArrayKlass
::
cast
(
array
->
klass
())
->
element_type
();
assert
(
type
>=
T_BOOLEAN
&&
type
<=
T_OBJECT
,
"invalid array element type"
);
int
length
=
array
->
length
();
int
type_size
;
if
(
type
==
T_OBJECT
)
{
type_size
=
sizeof
(
address
);
}
else
{
type_size
=
type2aelembytes
(
type
);
}
size_t
length_in_bytes
=
(
size_t
)
length
*
type_size
;
// Create a new record if the current record is non-empty and the array can't fit.
julong
current_record_length
=
writer
->
current_record_length
();
if
(
current_record_length
>
0
&&
(
current_record_length
+
header_size
+
length_in_bytes
)
>
max_juint
)
{
write_current_dump_record_length
(
writer
);
write_dump_header
(
writer
);
// We now have an empty record.
current_record_length
=
0
;
}
// Calculate max bytes we can use.
uint
max_bytes
=
max_juint
-
(
header_size
+
current_record_length
);
// Array too long for the record?
// Calculate max length and return it.
if
(
length_in_bytes
>
max_bytes
)
{
length
=
max_bytes
/
type_size
;
length_in_bytes
=
(
size_t
)
length
*
type_size
;
warning
(
"cannot dump array of type %s[] with length %d; truncating to length %d"
,
type2name_tab
[
type
],
array
->
length
(),
length
);
}
return
length
;
}
// creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
// creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
void
DumperSupport
::
dump_object_array
(
DumpWriter
*
writer
,
objArrayOop
array
)
{
void
DumperSupport
::
dump_object_array
(
DumpWriter
*
writer
,
objArrayOop
array
)
{
// sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID) + sizeof(classID)
short
header_size
=
1
+
2
*
4
+
2
*
sizeof
(
address
);
int
length
=
calculate_array_max_length
(
writer
,
array
,
header_size
);
writer
->
write_u1
(
HPROF_GC_OBJ_ARRAY_DUMP
);
writer
->
write_u1
(
HPROF_GC_OBJ_ARRAY_DUMP
);
writer
->
write_objectID
(
array
);
writer
->
write_objectID
(
array
);
writer
->
write_u4
(
STACK_TRACE_ID
);
writer
->
write_u4
(
STACK_TRACE_ID
);
writer
->
write_u4
((
u4
)
array
->
length
());
writer
->
write_u4
(
length
);
// array class ID
// array class ID
writer
->
write_classID
(
array
->
klass
());
writer
->
write_classID
(
array
->
klass
());
// [id]* elements
// [id]* elements
for
(
int
index
=
0
;
index
<
array
->
length
()
;
index
++
)
{
for
(
int
index
=
0
;
index
<
length
;
index
++
)
{
oop
o
=
array
->
obj_at
(
index
);
oop
o
=
array
->
obj_at
(
index
);
writer
->
write_objectID
(
o
);
writer
->
write_objectID
(
o
);
}
}
}
}
#define WRITE_ARRAY(Array, Type, Size) \
#define WRITE_ARRAY(Array, Type, Size, Length) \
for (int i=0; i<Array->length(); i++) { writer->write_##Size((Size)array->Type##_at(i)); }
for (int i = 0; i < Length; i++) { writer->write_##Size((Size)array->Type##_at(i)); }
// creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
// creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
void
DumperSupport
::
dump_prim_array
(
DumpWriter
*
writer
,
typeArrayOop
array
)
{
void
DumperSupport
::
dump_prim_array
(
DumpWriter
*
writer
,
typeArrayOop
array
)
{
BasicType
type
=
TypeArrayKlass
::
cast
(
array
->
klass
())
->
element_type
();
BasicType
type
=
TypeArrayKlass
::
cast
(
array
->
klass
())
->
element_type
();
// 2 * sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID)
short
header_size
=
2
*
1
+
2
*
4
+
sizeof
(
address
);
int
length
=
calculate_array_max_length
(
writer
,
array
,
header_size
);
int
type_size
=
type2aelembytes
(
type
);
u4
length_in_bytes
=
(
u4
)
length
*
type_size
;
writer
->
write_u1
(
HPROF_GC_PRIM_ARRAY_DUMP
);
writer
->
write_u1
(
HPROF_GC_PRIM_ARRAY_DUMP
);
writer
->
write_objectID
(
array
);
writer
->
write_objectID
(
array
);
writer
->
write_u4
(
STACK_TRACE_ID
);
writer
->
write_u4
(
STACK_TRACE_ID
);
writer
->
write_u4
(
(
u4
)
array
->
length
()
);
writer
->
write_u4
(
length
);
writer
->
write_u1
(
type2tag
(
type
));
writer
->
write_u1
(
type2tag
(
type
));
// nothing to copy
// nothing to copy
if
(
array
->
length
()
==
0
)
{
if
(
length
==
0
)
{
return
;
return
;
}
}
// If the byte ordering is big endian then we can copy most types directly
// If the byte ordering is big endian then we can copy most types directly
u4
length_in_bytes
=
(
u4
)
array
->
length
()
*
type2aelembytes
(
type
);
switch
(
type
)
{
switch
(
type
)
{
case
T_INT
:
{
case
T_INT
:
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
WRITE_ARRAY
(
array
,
int
,
u4
);
WRITE_ARRAY
(
array
,
int
,
u4
,
length
);
}
else
{
}
else
{
writer
->
write_raw
((
void
*
)(
array
->
int_at_addr
(
0
)),
length_in_bytes
);
writer
->
write_raw
((
void
*
)(
array
->
int_at_addr
(
0
)),
length_in_bytes
);
}
}
...
@@ -1102,7 +1189,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
...
@@ -1102,7 +1189,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
}
}
case
T_CHAR
:
{
case
T_CHAR
:
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
WRITE_ARRAY
(
array
,
char
,
u2
);
WRITE_ARRAY
(
array
,
char
,
u2
,
length
);
}
else
{
}
else
{
writer
->
write_raw
((
void
*
)(
array
->
char_at_addr
(
0
)),
length_in_bytes
);
writer
->
write_raw
((
void
*
)(
array
->
char_at_addr
(
0
)),
length_in_bytes
);
}
}
...
@@ -1110,7 +1197,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
...
@@ -1110,7 +1197,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
}
}
case
T_SHORT
:
{
case
T_SHORT
:
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
WRITE_ARRAY
(
array
,
short
,
u2
);
WRITE_ARRAY
(
array
,
short
,
u2
,
length
);
}
else
{
}
else
{
writer
->
write_raw
((
void
*
)(
array
->
short_at_addr
(
0
)),
length_in_bytes
);
writer
->
write_raw
((
void
*
)(
array
->
short_at_addr
(
0
)),
length_in_bytes
);
}
}
...
@@ -1118,7 +1205,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
...
@@ -1118,7 +1205,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
}
}
case
T_BOOLEAN
:
{
case
T_BOOLEAN
:
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
WRITE_ARRAY
(
array
,
bool
,
u1
);
WRITE_ARRAY
(
array
,
bool
,
u1
,
length
);
}
else
{
}
else
{
writer
->
write_raw
((
void
*
)(
array
->
bool_at_addr
(
0
)),
length_in_bytes
);
writer
->
write_raw
((
void
*
)(
array
->
bool_at_addr
(
0
)),
length_in_bytes
);
}
}
...
@@ -1126,7 +1213,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
...
@@ -1126,7 +1213,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
}
}
case
T_LONG
:
{
case
T_LONG
:
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
if
(
Bytes
::
is_Java_byte_ordering_different
())
{
WRITE_ARRAY
(
array
,
long
,
u8
);
WRITE_ARRAY
(
array
,
long
,
u8
,
length
);
}
else
{
}
else
{
writer
->
write_raw
((
void
*
)(
array
->
long_at_addr
(
0
)),
length_in_bytes
);
writer
->
write_raw
((
void
*
)(
array
->
long_at_addr
(
0
)),
length_in_bytes
);
}
}
...
@@ -1138,14 +1225,14 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
...
@@ -1138,14 +1225,14 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
// use IEEE 754.
// use IEEE 754.
case
T_FLOAT
:
{
case
T_FLOAT
:
{
for
(
int
i
=
0
;
i
<
array
->
length
()
;
i
++
)
{
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
dump_float
(
writer
,
array
->
float_at
(
i
)
);
dump_float
(
writer
,
array
->
float_at
(
i
)
);
}
}
break
;
break
;
}
}
case
T_DOUBLE
:
{
case
T_DOUBLE
:
{
for
(
int
i
=
0
;
i
<
array
->
length
()
;
i
++
)
{
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
dump_double
(
writer
,
array
->
double_at
(
i
)
);
dump_double
(
writer
,
array
->
double_at
(
i
)
);
}
}
break
;
break
;
}
}
...
@@ -1362,8 +1449,6 @@ class VM_HeapDumper : public VM_GC_Operation {
...
@@ -1362,8 +1449,6 @@ class VM_HeapDumper : public VM_GC_Operation {
JavaThread
*
_oome_thread
;
JavaThread
*
_oome_thread
;
Method
*
_oome_constructor
;
Method
*
_oome_constructor
;
bool
_gc_before_heap_dump
;
bool
_gc_before_heap_dump
;
bool
_is_segmented_dump
;
jlong
_dump_start
;
GrowableArray
<
Klass
*>*
_klass_map
;
GrowableArray
<
Klass
*>*
_klass_map
;
ThreadStackTrace
**
_stack_traces
;
ThreadStackTrace
**
_stack_traces
;
int
_num_threads
;
int
_num_threads
;
...
@@ -1382,11 +1467,6 @@ class VM_HeapDumper : public VM_GC_Operation {
...
@@ -1382,11 +1467,6 @@ class VM_HeapDumper : public VM_GC_Operation {
void
clear_global_dumper
()
{
_global_dumper
=
NULL
;
}
void
clear_global_dumper
()
{
_global_dumper
=
NULL
;
}
void
clear_global_writer
()
{
_global_writer
=
NULL
;
}
void
clear_global_writer
()
{
_global_writer
=
NULL
;
}
bool
is_segmented_dump
()
const
{
return
_is_segmented_dump
;
}
void
set_segmented_dump
()
{
_is_segmented_dump
=
true
;
}
jlong
dump_start
()
const
{
return
_dump_start
;
}
void
set_dump_start
(
jlong
pos
);
bool
skip_operation
()
const
;
bool
skip_operation
()
const
;
// writes a HPROF_LOAD_CLASS record
// writes a HPROF_LOAD_CLASS record
...
@@ -1411,16 +1491,6 @@ class VM_HeapDumper : public VM_GC_Operation {
...
@@ -1411,16 +1491,6 @@ class VM_HeapDumper : public VM_GC_Operation {
// HPROF_TRACE and HPROF_FRAME records
// HPROF_TRACE and HPROF_FRAME records
void
dump_stack_traces
();
void
dump_stack_traces
();
// writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
void
write_dump_header
();
// fixes up the length of the current dump record
void
write_current_dump_record_length
();
// fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
// record in the case of a segmented heap dump)
void
end_of_dump
();
public:
public:
VM_HeapDumper
(
DumpWriter
*
writer
,
bool
gc_before_heap_dump
,
bool
oome
)
:
VM_HeapDumper
(
DumpWriter
*
writer
,
bool
gc_before_heap_dump
,
bool
oome
)
:
VM_GC_Operation
(
0
/* total collections, dummy, ignored */
,
VM_GC_Operation
(
0
/* total collections, dummy, ignored */
,
...
@@ -1429,8 +1499,6 @@ class VM_HeapDumper : public VM_GC_Operation {
...
@@ -1429,8 +1499,6 @@ class VM_HeapDumper : public VM_GC_Operation {
gc_before_heap_dump
)
{
gc_before_heap_dump
)
{
_local_writer
=
writer
;
_local_writer
=
writer
;
_gc_before_heap_dump
=
gc_before_heap_dump
;
_gc_before_heap_dump
=
gc_before_heap_dump
;
_is_segmented_dump
=
false
;
_dump_start
=
(
jlong
)
-
1
;
_klass_map
=
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
GrowableArray
<
Klass
*>
(
INITIAL_CLASS_COUNT
,
true
);
_klass_map
=
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
GrowableArray
<
Klass
*>
(
INITIAL_CLASS_COUNT
,
true
);
_stack_traces
=
NULL
;
_stack_traces
=
NULL
;
_num_threads
=
0
;
_num_threads
=
0
;
...
@@ -1470,35 +1538,23 @@ bool VM_HeapDumper::skip_operation() const {
...
@@ -1470,35 +1538,23 @@ bool VM_HeapDumper::skip_operation() const {
return
false
;
return
false
;
}
}
// sets the dump starting position
// writes a HPROF_HEAP_DUMP_SEGMENT record
void
VM_HeapDumper
::
set_dump_start
(
jlong
pos
)
{
void
DumperSupport
::
write_dump_header
(
DumpWriter
*
writer
)
{
_dump_start
=
pos
;
if
(
writer
->
is_open
())
{
}
writer
->
write_u1
(
HPROF_HEAP_DUMP_SEGMENT
);
writer
->
write_u4
(
0
);
// current ticks
// writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
void
VM_HeapDumper
::
write_dump_header
()
{
if
(
writer
()
->
is_open
())
{
if
(
is_segmented_dump
())
{
writer
()
->
write_u1
(
HPROF_HEAP_DUMP_SEGMENT
);
}
else
{
writer
()
->
write_u1
(
HPROF_HEAP_DUMP
);
}
writer
()
->
write_u4
(
0
);
// current ticks
// record the starting position for the dump (its length will be fixed up later)
// record the starting position for the dump (its length will be fixed up later)
set_dump_start
(
writer
()
->
current_offset
());
writer
->
set_dump_start
(
writer
->
current_offset
());
writer
()
->
write_u4
(
0
);
writer
->
write_u4
(
0
);
}
}
}
}
// fixes up the length of the current dump record
// fixes up the length of the current dump record
void
VM_HeapDumper
::
write_current_dump_record_length
()
{
void
DumperSupport
::
write_current_dump_record_length
(
DumpWriter
*
writer
)
{
if
(
writer
()
->
is_open
())
{
if
(
writer
->
is_open
())
{
assert
(
dump_start
()
>=
0
,
"no dump start recorded"
);
julong
dump_end
=
writer
->
bytes_written
()
+
writer
->
bytes_unwritten
();
julong
dump_len
=
writer
->
current_record_length
();
// calculate the size of the dump record
julong
dump_end
=
writer
()
->
current_offset
();
julong
dump_len
=
(
dump_end
-
dump_start
()
-
4
);
// record length must fit in a u4
// record length must fit in a u4
if
(
dump_len
>
max_juint
)
{
if
(
dump_len
>
max_juint
)
{
...
@@ -1506,17 +1562,18 @@ void VM_HeapDumper::write_current_dump_record_length() {
...
@@ -1506,17 +1562,18 @@ void VM_HeapDumper::write_current_dump_record_length() {
}
}
// seek to the dump start and fix-up the length
// seek to the dump start and fix-up the length
writer
()
->
seek_to_offset
(
dump_start
());
assert
(
writer
->
dump_start
()
>=
0
,
"no dump start recorded"
);
writer
()
->
write_u4
((
u4
)
dump_len
);
writer
->
seek_to_offset
(
writer
->
dump_start
());
writer
->
write_u4
((
u4
)
dump_len
);
// adjust the total size written to keep the bytes written correct.
// adjust the total size written to keep the bytes written correct.
writer
()
->
adjust_bytes_written
(
-
((
jlong
)
sizeof
(
u4
)));
writer
->
adjust_bytes_written
(
-
((
jlong
)
sizeof
(
u4
)));
// seek to dump end so we can continue
// seek to dump end so we can continue
writer
()
->
seek_to_offset
(
dump_end
);
writer
->
seek_to_offset
(
dump_end
);
// no current dump record
// no current dump record
set_dump_start
((
jlong
)
-
1
);
writer
->
set_dump_start
((
jlong
)
-
1
);
}
}
}
}
...
@@ -1524,33 +1581,23 @@ void VM_HeapDumper::write_current_dump_record_length() {
...
@@ -1524,33 +1581,23 @@ void VM_HeapDumper::write_current_dump_record_length() {
// new segment.
// new segment.
void
VM_HeapDumper
::
check_segment_length
()
{
void
VM_HeapDumper
::
check_segment_length
()
{
if
(
writer
()
->
is_open
())
{
if
(
writer
()
->
is_open
())
{
if
(
is_segmented_dump
())
{
julong
dump_len
=
writer
()
->
current_record_length
();
// don't use current_offset that would be too expensive on a per record basis
julong
dump_end
=
writer
()
->
bytes_written
()
+
writer
()
->
bytes_unwritten
();
if
(
dump_len
>
2UL
*
G
)
{
assert
(
dump_end
==
(
julong
)
writer
()
->
current_offset
(),
"checking"
);
DumperSupport
::
write_current_dump_record_length
(
writer
());
julong
dump_len
=
(
dump_end
-
dump_start
()
-
4
);
DumperSupport
::
write_dump_header
(
writer
());
assert
(
dump_len
<=
max_juint
,
"bad dump length"
);
if
(
dump_len
>
HeapDumpSegmentSize
)
{
write_current_dump_record_length
();
write_dump_header
();
}
}
}
}
}
}
}
// fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
// fixes up the current dump record and writes HPROF_HEAP_DUMP_END record
// record in the case of a segmented heap dump)
void
DumperSupport
::
end_of_dump
(
DumpWriter
*
writer
)
{
void
VM_HeapDumper
::
end_of_dump
()
{
if
(
writer
->
is_open
())
{
if
(
writer
()
->
is_open
())
{
write_current_dump_record_length
(
writer
);
write_current_dump_record_length
();
// for segmented dump we write the end record
writer
->
write_u1
(
HPROF_HEAP_DUMP_END
);
if
(
is_segmented_dump
())
{
writer
->
write_u4
(
0
);
writer
()
->
write_u1
(
HPROF_HEAP_DUMP_END
);
writer
->
write_u4
(
0
);
writer
()
->
write_u4
(
0
);
writer
()
->
write_u4
(
0
);
}
}
}
}
}
...
@@ -1716,16 +1763,17 @@ void VM_HeapDumper::do_threads() {
...
@@ -1716,16 +1763,17 @@ void VM_HeapDumper::do_threads() {
// [HPROF_LOAD_CLASS]*
// [HPROF_LOAD_CLASS]*
// [[HPROF_FRAME]*|HPROF_TRACE]*
// [[HPROF_FRAME]*|HPROF_TRACE]*
// [HPROF_GC_CLASS_DUMP]*
// [HPROF_GC_CLASS_DUMP]*
// HPROF_HEAP_DUMP
// [HPROF_HEAP_DUMP_SEGMENT]*
// HPROF_HEAP_DUMP_END
//
//
// The HPROF_TRACE records represent the stack traces where the heap dump
// The HPROF_TRACE records represent the stack traces where the heap dump
// is generated and a "dummy trace" record which does not include
// is generated and a "dummy trace" record which does not include
// any frames. The dummy trace record is used to be referenced as the
// any frames. The dummy trace record is used to be referenced as the
// unknown object alloc site.
// unknown object alloc site.
//
//
//
The HPROF_HEAP_DUMP record has a length following by sub-records. To allow
//
Each HPROF_HEAP_DUMP_SEGMENT record has a length followed by sub-records.
//
the heap dump be generated in a single pass we remember the position of
//
To allow the heap dump be generated in a single pass we remember the position
// the dump length and fix it up after all sub-records have been written.
//
of
the dump length and fix it up after all sub-records have been written.
// To generate the sub-records we iterate over the heap, writing
// To generate the sub-records we iterate over the heap, writing
// HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP
// HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP
// records as we go. Once that is done we write records for some of the GC
// records as we go. Once that is done we write records for some of the GC
...
@@ -1752,15 +1800,9 @@ void VM_HeapDumper::doit() {
...
@@ -1752,15 +1800,9 @@ void VM_HeapDumper::doit() {
set_global_dumper
();
set_global_dumper
();
set_global_writer
();
set_global_writer
();
// Write the file header -
use 1.0.2 for large heaps, otherwise 1.0.1
// Write the file header -
we always use 1.0.2
size_t
used
=
ch
->
used
();
size_t
used
=
ch
->
used
();
const
char
*
header
;
const
char
*
header
=
"JAVA PROFILE 1.0.2"
;
if
(
used
>
(
size_t
)
SegmentedHeapDumpThreshold
)
{
set_segmented_dump
();
header
=
"JAVA PROFILE 1.0.2"
;
}
else
{
header
=
"JAVA PROFILE 1.0.1"
;
}
// header is few bytes long - no chance to overflow int
// header is few bytes long - no chance to overflow int
writer
()
->
write_raw
((
void
*
)
header
,
(
int
)
strlen
(
header
));
writer
()
->
write_raw
((
void
*
)
header
,
(
int
)
strlen
(
header
));
...
@@ -1780,8 +1822,8 @@ void VM_HeapDumper::doit() {
...
@@ -1780,8 +1822,8 @@ void VM_HeapDumper::doit() {
// this must be called after _klass_map is built when iterating the classes above.
// this must be called after _klass_map is built when iterating the classes above.
dump_stack_traces
();
dump_stack_traces
();
// write HPROF_HEAP_DUMP
or HPROF_HEAP_DUMP
_SEGMENT
// write HPROF_HEAP_DUMP_SEGMENT
write_dump_header
(
);
DumperSupport
::
write_dump_header
(
writer
()
);
// Writes HPROF_GC_CLASS_DUMP records
// Writes HPROF_GC_CLASS_DUMP records
ClassLoaderDataGraph
::
classes_do
(
&
do_class_dump
);
ClassLoaderDataGraph
::
classes_do
(
&
do_class_dump
);
...
@@ -1789,9 +1831,9 @@ void VM_HeapDumper::doit() {
...
@@ -1789,9 +1831,9 @@ void VM_HeapDumper::doit() {
check_segment_length
();
check_segment_length
();
// writes HPROF_GC_INSTANCE_DUMP records.
// writes HPROF_GC_INSTANCE_DUMP records.
// After each sub-record is written check_segment_length will be invoked
. When
// After each sub-record is written check_segment_length will be invoked
//
generated a segmented heap dump this allows us to check if the current
//
to check if the current segment exceeds a threshold. If so, a new
// segment
exceeds a threshold and if so, then a new segment
is started.
// segment is started.
// The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
// The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
// of the heap dump.
// of the heap dump.
HeapObjectDumper
obj_dumper
(
this
,
writer
());
HeapObjectDumper
obj_dumper
(
this
,
writer
());
...
@@ -1817,9 +1859,8 @@ void VM_HeapDumper::doit() {
...
@@ -1817,9 +1859,8 @@ void VM_HeapDumper::doit() {
StickyClassDumper
class_dumper
(
writer
());
StickyClassDumper
class_dumper
(
writer
());
SystemDictionary
::
always_strong_classes_do
(
&
class_dumper
);
SystemDictionary
::
always_strong_classes_do
(
&
class_dumper
);
// fixes up the length of the dump record. In the case of a segmented
// fixes up the length of the dump record and writes the HPROF_HEAP_DUMP_END record.
// heap then the HPROF_HEAP_DUMP_END record is also written.
DumperSupport
::
end_of_dump
(
writer
());
end_of_dump
();
// Now we clear the global variables, so that a future dumper might run.
// Now we clear the global variables, so that a future dumper might run.
clear_global_dumper
();
clear_global_dumper
();
...
...
src/share/vm/utilities/vmError.cpp
浏览文件 @
a4d467b2
...
@@ -1060,7 +1060,7 @@ void VMError::report_and_die() {
...
@@ -1060,7 +1060,7 @@ void VMError::report_and_die() {
out
.
print_raw
(
cmd
);
out
.
print_raw
(
cmd
);
out
.
print_raw_cr
(
"
\"
..."
);
out
.
print_raw_cr
(
"
\"
..."
);
if
(
os
::
fork_and_exec
(
cmd
,
true
)
<
0
)
{
if
(
os
::
fork_and_exec
(
cmd
)
<
0
)
{
out
.
print_cr
(
"os::fork_and_exec failed: %s (%d)"
,
strerror
(
errno
),
errno
);
out
.
print_cr
(
"os::fork_and_exec failed: %s (%d)"
,
strerror
(
errno
),
errno
);
}
}
}
}
...
@@ -1147,7 +1147,7 @@ void VM_ReportJavaOutOfMemory::doit() {
...
@@ -1147,7 +1147,7 @@ void VM_ReportJavaOutOfMemory::doit() {
#endif
#endif
tty
->
print_cr
(
"
\"
%s
\"
..."
,
cmd
);
tty
->
print_cr
(
"
\"
%s
\"
..."
,
cmd
);
if
(
os
::
fork_and_exec
(
cmd
)
<
0
)
{
if
(
os
::
fork_and_exec
(
cmd
,
true
)
<
0
)
{
tty
->
print_cr
(
"os::fork_and_exec failed: %s (%d)"
,
strerror
(
errno
),
errno
);
tty
->
print_cr
(
"os::fork_and_exec failed: %s (%d)"
,
strerror
(
errno
),
errno
);
}
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录