Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
0bb1ab9e
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看板
提交
0bb1ab9e
编写于
7月 22, 2020
作者:
D
Denghui Dong
提交者:
D-D-H
7月 23, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Revert "Revert "[JFR] add support for opto object allocations sampling""
This reverts commit
6585eb9c
.
上级
7796cbc3
变更
34
显示空白变更内容
内联
并排
Showing
34 changed file
with
806 addition
and
36 deletion
+806
-36
make/windows/makefiles/vm.make
make/windows/makefiles/vm.make
+3
-0
src/share/vm/gc_interface/allocTracer.hpp
src/share/vm/gc_interface/allocTracer.hpp
+10
-1
src/share/vm/gc_interface/allocTracer.inline.hpp
src/share/vm/gc_interface/allocTracer.inline.hpp
+128
-0
src/share/vm/gc_interface/collectedHeap.hpp
src/share/vm/gc_interface/collectedHeap.hpp
+10
-0
src/share/vm/gc_interface/collectedHeap.inline.hpp
src/share/vm/gc_interface/collectedHeap.inline.hpp
+7
-5
src/share/vm/jfr/dcmd/jfrDcmds.cpp
src/share/vm/jfr/dcmd/jfrDcmds.cpp
+23
-3
src/share/vm/jfr/dcmd/jfrDcmds.hpp
src/share/vm/jfr/dcmd/jfrDcmds.hpp
+10
-0
src/share/vm/jfr/jni/jfrJniMethod.cpp
src/share/vm/jfr/jni/jfrJniMethod.cpp
+19
-1
src/share/vm/jfr/jni/jfrJniMethod.hpp
src/share/vm/jfr/jni/jfrJniMethod.hpp
+4
-0
src/share/vm/jfr/jni/jfrJniMethodRegistration.cpp
src/share/vm/jfr/jni/jfrJniMethodRegistration.cpp
+2
-0
src/share/vm/jfr/leakprofiler/sampling/objectSampler.cpp
src/share/vm/jfr/leakprofiler/sampling/objectSampler.cpp
+1
-1
src/share/vm/jfr/metadata/metadata.xml
src/share/vm/jfr/metadata/metadata.xml
+12
-0
src/share/vm/jfr/objectprofiler/objectProfiler.cpp
src/share/vm/jfr/objectprofiler/objectProfiler.cpp
+90
-0
src/share/vm/jfr/objectprofiler/objectProfiler.hpp
src/share/vm/jfr/objectprofiler/objectProfiler.hpp
+43
-0
src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
+10
-0
src/share/vm/jfr/recorder/jfrEventSetting.cpp
src/share/vm/jfr/recorder/jfrEventSetting.cpp
+9
-0
src/share/vm/jfr/recorder/jfrEventSetting.hpp
src/share/vm/jfr/recorder/jfrEventSetting.hpp
+2
-0
src/share/vm/jfr/recorder/service/jfrEvent.hpp
src/share/vm/jfr/recorder/service/jfrEvent.hpp
+2
-1
src/share/vm/jfr/recorder/service/jfrOptionSet.cpp
src/share/vm/jfr/recorder/service/jfrOptionSet.cpp
+46
-0
src/share/vm/jfr/recorder/service/jfrOptionSet.hpp
src/share/vm/jfr/recorder/service/jfrOptionSet.hpp
+6
-0
src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp
...re/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp
+54
-8
src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp
...re/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp
+15
-4
src/share/vm/jfr/support/jfrFlush.cpp
src/share/vm/jfr/support/jfrFlush.cpp
+2
-2
src/share/vm/jfr/support/jfrFlush.hpp
src/share/vm/jfr/support/jfrFlush.hpp
+4
-2
src/share/vm/jfr/support/jfrStackTraceMark.cpp
src/share/vm/jfr/support/jfrStackTraceMark.cpp
+7
-4
src/share/vm/jfr/support/jfrThreadLocal.cpp
src/share/vm/jfr/support/jfrThreadLocal.cpp
+5
-1
src/share/vm/jfr/support/jfrThreadLocal.hpp
src/share/vm/jfr/support/jfrThreadLocal.hpp
+72
-0
src/share/vm/jfr/support/jfrTraceIdExtension.hpp
src/share/vm/jfr/support/jfrTraceIdExtension.hpp
+20
-0
src/share/vm/opto/macro.cpp
src/share/vm/opto/macro.cpp
+127
-3
src/share/vm/opto/macro.hpp
src/share/vm/opto/macro.hpp
+8
-0
src/share/vm/opto/runtime.cpp
src/share/vm/opto/runtime.cpp
+46
-0
src/share/vm/opto/runtime.hpp
src/share/vm/opto/runtime.hpp
+5
-0
src/share/vm/precompiled/precompiled.hpp
src/share/vm/precompiled/precompiled.hpp
+2
-0
src/share/vm/runtime/vframe.hpp
src/share/vm/runtime/vframe.hpp
+2
-0
未找到文件。
make/windows/makefiles/vm.make
浏览文件 @
0bb1ab9e
...
@@ -468,6 +468,9 @@ arguments.obj: $(WorkSpace)\src\share\vm\runtime\arguments.cpp
...
@@ -468,6 +468,9 @@ arguments.obj: $(WorkSpace)\src\share\vm\runtime\arguments.cpp
{$(COMMONSRC)\share\vm\jfr\writers}.cpp.obj
::
{$(COMMONSRC)\share\vm\jfr\writers}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
{$(COMMONSRC)\share\vm\jfr\objectprofiler}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
default
::
default
::
_build_pch_file.obj
:
_build_pch_file.obj
:
...
...
src/share/vm/gc_interface/allocTracer.hpp
浏览文件 @
0bb1ab9e
...
@@ -25,14 +25,23 @@
...
@@ -25,14 +25,23 @@
#ifndef SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP
#ifndef SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP
#define SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP
#define SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP
#include "
memory/allocation
.hpp"
#include "
gc_implementation/shared/gcId
.hpp"
#include "runtime/handles.hpp"
#include "runtime/handles.hpp"
#include "utilities/globalDefinitions.hpp"
class
AllocTracer
:
AllStatic
{
class
AllocTracer
:
AllStatic
{
private:
static
void
send_opto_array_allocation_event
(
KlassHandle
klass
,
oop
obj
,
size_t
alloc_size
,
Thread
*
thread
);
static
void
send_opto_instance_allocation_event
(
KlassHandle
klass
,
oop
obj
,
Thread
*
thread
);
public:
public:
static
void
send_allocation_outside_tlab_event
(
KlassHandle
klass
,
HeapWord
*
obj
,
size_t
alloc_size
,
Thread
*
thread
);
static
void
send_allocation_outside_tlab_event
(
KlassHandle
klass
,
HeapWord
*
obj
,
size_t
alloc_size
,
Thread
*
thread
);
static
void
send_allocation_in_new_tlab_event
(
KlassHandle
klass
,
HeapWord
*
obj
,
size_t
tlab_size
,
size_t
alloc_size
,
Thread
*
thread
);
static
void
send_allocation_in_new_tlab_event
(
KlassHandle
klass
,
HeapWord
*
obj
,
size_t
tlab_size
,
size_t
alloc_size
,
Thread
*
thread
);
static
void
send_allocation_requiring_gc_event
(
size_t
size
,
const
GCId
&
gcId
);
static
void
send_allocation_requiring_gc_event
(
size_t
size
,
const
GCId
&
gcId
);
static
void
opto_slow_allocation_enter
(
bool
is_array
,
Thread
*
thread
);
static
void
opto_slow_allocation_leave
(
bool
is_array
,
Thread
*
thread
);
static
void
send_slow_allocation_event
(
KlassHandle
klass
,
oop
obj
,
size_t
alloc_size
,
Thread
*
thread
);
static
void
send_opto_fast_allocation_event
(
KlassHandle
klass
,
oop
obj
,
size_t
alloc_size
,
Thread
*
thread
);
};
};
#endif
/* SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP */
#endif
/* SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP */
src/share/vm/gc_interface/allocTracer.inline.hpp
0 → 100644
浏览文件 @
0bb1ab9e
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. 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. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*
*/
#ifndef SHARE_VM_GC_INTERFACE_ALLOCTRACER_INLINE_HPP
#define SHARE_VM_GC_INTERFACE_ALLOCTRACER_INLINE_HPP
#include "gc_implementation/shared/gcId.hpp"
#include "jfr/jfrEvents.hpp"
#include "runtime/handles.hpp"
#include "utilities/globalDefinitions.hpp"
#include "gc_interface/allocTracer.hpp"
#if INCLUDE_JFR
#include "jfr/recorder/service/jfrOptionSet.hpp"
#include "jfr/objectprofiler/objectProfiler.hpp"
#endif // INCLUDE_JFR
inline
void
AllocTracer
::
opto_slow_allocation_enter
(
bool
is_array
,
Thread
*
thread
)
{
#if INCLUDE_JFR
if
(
JfrOptionSet
::
sample_object_allocations
()
&&
ObjectProfiler
::
enabled
())
{
assert
(
thread
!=
NULL
,
"Invariant"
);
assert
(
thread
->
is_Java_thread
(),
"Invariant"
);
thread
->
jfr_thread_local
()
->
incr_alloc_count
(
1
);
if
(
is_array
)
{
thread
->
jfr_thread_local
()
->
set_cached_event_id
(
JfrOptoArrayObjectAllocationEvent
);
}
else
{
thread
->
jfr_thread_local
()
->
set_cached_event_id
(
JfrOptoInstanceObjectAllocationEvent
);
}
}
#endif // INCLUDE_JFR
}
inline
void
AllocTracer
::
opto_slow_allocation_leave
(
bool
is_array
,
Thread
*
thread
)
{
#if INCLUDE_JFR
#ifndef PRODUCT
if
(
JfrOptionSet
::
sample_object_allocations
())
{
JfrThreadLocal
*
jfr_thread_local
=
thread
->
jfr_thread_local
();
assert
(
!
jfr_thread_local
->
has_cached_event_id
(),
"Invariant"
);
assert
(
jfr_thread_local
->
alloc_count_until_sample
()
>=
jfr_thread_local
->
alloc_count
(),
"Invariant"
);
}
#endif
#endif // INCLUDE_JFR
}
inline
void
AllocTracer
::
send_opto_array_allocation_event
(
KlassHandle
klass
,
oop
obj
,
size_t
alloc_size
,
Thread
*
thread
)
{
EventOptoArrayObjectAllocation
event
;
if
(
event
.
should_commit
())
{
event
.
set_objectClass
(
klass
());
event
.
set_address
(
cast_from_oop
<
u8
>
(
obj
));
event
.
set_allocationSize
(
alloc_size
);
event
.
commit
();
}
}
inline
void
AllocTracer
::
send_opto_instance_allocation_event
(
KlassHandle
klass
,
oop
obj
,
Thread
*
thread
)
{
EventOptoInstanceObjectAllocation
event
;
if
(
event
.
should_commit
())
{
event
.
set_objectClass
(
klass
());
event
.
set_address
(
cast_from_oop
<
u8
>
(
obj
));
event
.
commit
();
}
}
inline
void
AllocTracer
::
send_slow_allocation_event
(
KlassHandle
klass
,
oop
obj
,
size_t
alloc_size
,
Thread
*
thread
)
{
#if INCLUDE_JFR
if
(
JfrOptionSet
::
sample_object_allocations
())
{
assert
(
thread
!=
NULL
,
"Illegal parameter: thread is NULL"
);
assert
(
thread
==
Thread
::
current
(),
"Invariant"
);
if
(
thread
->
jfr_thread_local
()
->
has_cached_event_id
())
{
assert
(
thread
->
is_Java_thread
(),
"Only allow to be called from java thread"
);
jlong
alloc_count
=
thread
->
jfr_thread_local
()
->
alloc_count
();
jlong
alloc_count_until_sample
=
thread
->
jfr_thread_local
()
->
alloc_count_until_sample
();
assert
(
alloc_count
>
0
||
alloc_count
<=
alloc_count_until_sample
,
"Invariant"
);
if
(
alloc_count
==
alloc_count_until_sample
)
{
JfrEventId
event_id
=
thread
->
jfr_thread_local
()
->
cached_event_id
();
if
(
event_id
==
JfrOptoArrayObjectAllocationEvent
)
{
send_opto_array_allocation_event
(
klass
,
obj
,
alloc_size
,
thread
);
}
else
if
(
event_id
==
JfrOptoInstanceObjectAllocationEvent
)
{
send_opto_instance_allocation_event
(
klass
,
obj
,
thread
);
}
else
{
ShouldNotReachHere
();
}
jlong
interval
=
JfrOptionSet
::
object_allocations_sampling_interval
();
thread
->
jfr_thread_local
()
->
incr_alloc_count_until_sample
(
interval
);
}
thread
->
jfr_thread_local
()
->
clear_cached_event_id
();
}
}
#endif // INCLUDE_JFR
}
inline
void
AllocTracer
::
send_opto_fast_allocation_event
(
KlassHandle
klass
,
oop
obj
,
size_t
alloc_size
,
Thread
*
thread
)
{
#if INCLUDE_JFR
assert
(
JfrOptionSet
::
sample_object_allocations
(),
"Invariant"
);
assert
(
thread
!=
NULL
,
"Invariant"
);
assert
(
thread
->
is_Java_thread
(),
"Invariant"
);
assert
(
!
thread
->
jfr_thread_local
()
->
has_cached_event_id
(),
"Invariant"
);
Klass
*
k
=
klass
();
if
(
k
->
oop_is_array
())
{
send_opto_array_allocation_event
(
klass
,
obj
,
alloc_size
,
thread
);
}
else
{
send_opto_instance_allocation_event
(
klass
,
obj
,
thread
);
}
jlong
interval
=
JfrOptionSet
::
object_allocations_sampling_interval
();
thread
->
jfr_thread_local
()
->
incr_alloc_count_until_sample
(
interval
);
#endif // INCLUDE_JFR
}
#endif
/* SHARE_VM_GC_INTERFACE_ALLOCTRACER_INLINE_HPP */
src/share/vm/gc_interface/collectedHeap.hpp
浏览文件 @
0bb1ab9e
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_HPP
#define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_HPP
#include "gc_interface/gcCause.hpp"
#include "gc_interface/gcCause.hpp"
#include "gc_interface/allocTracer.hpp"
#include "gc_implementation/shared/gcWhen.hpp"
#include "gc_implementation/shared/gcWhen.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.hpp"
#include "memory/barrierSet.hpp"
#include "memory/barrierSet.hpp"
...
@@ -323,6 +324,15 @@ class CollectedHeap : public CHeapObj<mtInternal> {
...
@@ -323,6 +324,15 @@ class CollectedHeap : public CHeapObj<mtInternal> {
inline
static
void
check_array_size
(
int
size
,
int
length
,
TRAPS
);
inline
static
void
check_array_size
(
int
size
,
int
length
,
TRAPS
);
public:
public:
// Implicit Jfr inline methods.
static
void
trace_slow_allocation
(
KlassHandle
klass
,
oop
obj
,
size_t
alloc_size
,
Thread
*
thread
)
{
AllocTracer
::
send_slow_allocation_event
(
klass
,
obj
,
alloc_size
,
thread
);
}
static
void
trace_allocation_outside_tlab
(
KlassHandle
klass
,
HeapWord
*
obj
,
size_t
alloc_size
,
Thread
*
thread
)
{
AllocTracer
::
send_allocation_outside_tlab_event
(
klass
,
obj
,
alloc_size
,
thread
);
}
inline
static
void
post_allocation_install_obj_klass
(
KlassHandle
klass
,
inline
static
void
post_allocation_install_obj_klass
(
KlassHandle
klass
,
oop
obj
);
oop
obj
);
...
...
src/share/vm/gc_interface/collectedHeap.inline.hpp
浏览文件 @
0bb1ab9e
...
@@ -25,7 +25,6 @@
...
@@ -25,7 +25,6 @@
#ifndef SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
#ifndef SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
#define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
#define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
#include "gc_interface/allocTracer.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "memory/threadLocalAllocBuffer.inline.hpp"
#include "memory/threadLocalAllocBuffer.inline.hpp"
#include "memory/universe.hpp"
#include "memory/universe.hpp"
...
@@ -69,7 +68,7 @@ void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
...
@@ -69,7 +68,7 @@ void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
"missing klass"
);
"missing klass"
);
}
}
// Support for jvmti and dtrace
// Support for jvmti
, jfr
and dtrace
inline
void
post_allocation_notify
(
KlassHandle
klass
,
oop
obj
,
int
size
)
{
inline
void
post_allocation_notify
(
KlassHandle
klass
,
oop
obj
,
int
size
)
{
// support low memory notifications (no-op if not enabled)
// support low memory notifications (no-op if not enabled)
LowMemoryDetector
::
detect_low_memory_for_collected_pools
();
LowMemoryDetector
::
detect_low_memory_for_collected_pools
();
...
@@ -83,6 +82,9 @@ inline void post_allocation_notify(KlassHandle klass, oop obj, int size) {
...
@@ -83,6 +82,9 @@ inline void post_allocation_notify(KlassHandle klass, oop obj, int size) {
SharedRuntime
::
dtrace_object_alloc
(
obj
,
size
);
SharedRuntime
::
dtrace_object_alloc
(
obj
,
size
);
}
}
}
}
// support for jfr
CollectedHeap
::
trace_slow_allocation
(
klass
,
obj
,
size
*
HeapWordSize
,
Thread
::
current
());
}
}
void
CollectedHeap
::
post_allocation_setup_obj
(
KlassHandle
klass
,
void
CollectedHeap
::
post_allocation_setup_obj
(
KlassHandle
klass
,
...
@@ -91,7 +93,7 @@ void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
...
@@ -91,7 +93,7 @@ void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
post_allocation_setup_common
(
klass
,
obj
);
post_allocation_setup_common
(
klass
,
obj
);
assert
(
Universe
::
is_bootstrapping
()
||
assert
(
Universe
::
is_bootstrapping
()
||
!
((
oop
)
obj
)
->
is_array
(),
"must not be an array"
);
!
((
oop
)
obj
)
->
is_array
(),
"must not be an array"
);
// notify jvmti and dtrace
// notify jvmti
, jfr
and dtrace
post_allocation_notify
(
klass
,
(
oop
)
obj
,
size
);
post_allocation_notify
(
klass
,
(
oop
)
obj
,
size
);
}
}
...
@@ -106,7 +108,7 @@ void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
...
@@ -106,7 +108,7 @@ void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
post_allocation_setup_common
(
klass
,
obj
);
post_allocation_setup_common
(
klass
,
obj
);
oop
new_obj
=
(
oop
)
obj
;
oop
new_obj
=
(
oop
)
obj
;
assert
(
new_obj
->
is_array
(),
"must be an array"
);
assert
(
new_obj
->
is_array
(),
"must be an array"
);
// notify jvmti and dtrace (must be after length is set for dtrace)
// notify jvmti
, jfr
and dtrace (must be after length is set for dtrace)
post_allocation_notify
(
klass
,
new_obj
,
new_obj
->
size
());
post_allocation_notify
(
klass
,
new_obj
,
new_obj
->
size
());
}
}
...
@@ -140,7 +142,7 @@ HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t si
...
@@ -140,7 +142,7 @@ HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t si
"Unexpected exception, will result in uninitialized storage"
);
"Unexpected exception, will result in uninitialized storage"
);
THREAD
->
incr_allocated_bytes
(
size
*
HeapWordSize
);
THREAD
->
incr_allocated_bytes
(
size
*
HeapWordSize
);
AllocTracer
::
send_allocation_outside_tlab_event
(
klass
,
result
,
size
*
HeapWordSize
,
Thread
::
current
()
);
CollectedHeap
::
trace_allocation_outside_tlab
(
klass
,
result
,
size
*
HeapWordSize
,
THREAD
);
return
result
;
return
result
;
}
}
...
...
src/share/vm/jfr/dcmd/jfrDcmds.cpp
浏览文件 @
0bb1ab9e
...
@@ -544,6 +544,7 @@ void JfrStopFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
...
@@ -544,6 +544,7 @@ void JfrStopFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
JfrConfigureFlightRecorderDCmd
::
JfrConfigureFlightRecorderDCmd
(
outputStream
*
output
,
JfrConfigureFlightRecorderDCmd
::
JfrConfigureFlightRecorderDCmd
(
outputStream
*
output
,
bool
heap
)
:
DCmdWithParser
(
output
,
heap
),
bool
heap
)
:
DCmdWithParser
(
output
,
heap
),
_on_vm_start
(
false
),
_repository_path
(
"repositorypath"
,
"Path to repository,.e.g
\\\"
My Repository
\\\"
"
,
"STRING"
,
false
,
NULL
),
_repository_path
(
"repositorypath"
,
"Path to repository,.e.g
\\\"
My Repository
\\\"
"
,
"STRING"
,
false
,
NULL
),
_dump_path
(
"dumppath"
,
"Path to dump,.e.g
\\\"
My Dump path
\\\"
"
,
"STRING"
,
false
,
NULL
),
_dump_path
(
"dumppath"
,
"Path to dump,.e.g
\\\"
My Dump path
\\\"
"
,
"STRING"
,
false
,
NULL
),
_stack_depth
(
"stackdepth"
,
"Stack Depth"
,
"JULONG"
,
false
,
"64"
),
_stack_depth
(
"stackdepth"
,
"Stack Depth"
,
"JULONG"
,
false
,
"64"
),
...
@@ -552,7 +553,9 @@ JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* out
...
@@ -552,7 +553,9 @@ JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* out
_thread_buffer_size
(
"thread_buffer_size"
,
"Size of a thread buffer"
,
"MEMORY SIZE"
,
false
,
"8k"
),
_thread_buffer_size
(
"thread_buffer_size"
,
"Size of a thread buffer"
,
"MEMORY SIZE"
,
false
,
"8k"
),
_memory_size
(
"memorysize"
,
"Overall memory size, "
,
"MEMORY SIZE"
,
false
,
"10m"
),
_memory_size
(
"memorysize"
,
"Overall memory size, "
,
"MEMORY SIZE"
,
false
,
"10m"
),
_max_chunk_size
(
"maxchunksize"
,
"Size of an individual disk chunk"
,
"MEMORY SIZE"
,
false
,
"12m"
),
_max_chunk_size
(
"maxchunksize"
,
"Size of an individual disk chunk"
,
"MEMORY SIZE"
,
false
,
"12m"
),
_sample_threads
(
"samplethreads"
,
"Activate Thread sampling"
,
"BOOLEAN"
,
false
,
"true"
)
{
_sample_threads
(
"samplethreads"
,
"Activate Thread sampling"
,
"BOOLEAN"
,
false
,
"true"
),
_sample_object_allocations
(
"sampleobjectallocations"
,
"object allocations sampling enable / disable"
,
"BOOLEAN"
,
false
,
"false"
),
_object_allocations_sampling_interval
(
"objectallocationssamplinginterval"
,
"object allocations sampling interval"
,
"JLONG"
,
false
,
"1024"
)
{
_dcmdparser
.
add_dcmd_option
(
&
_repository_path
);
_dcmdparser
.
add_dcmd_option
(
&
_repository_path
);
_dcmdparser
.
add_dcmd_option
(
&
_dump_path
);
_dcmdparser
.
add_dcmd_option
(
&
_dump_path
);
_dcmdparser
.
add_dcmd_option
(
&
_stack_depth
);
_dcmdparser
.
add_dcmd_option
(
&
_stack_depth
);
...
@@ -562,6 +565,8 @@ JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* out
...
@@ -562,6 +565,8 @@ JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* out
_dcmdparser
.
add_dcmd_option
(
&
_memory_size
);
_dcmdparser
.
add_dcmd_option
(
&
_memory_size
);
_dcmdparser
.
add_dcmd_option
(
&
_max_chunk_size
);
_dcmdparser
.
add_dcmd_option
(
&
_max_chunk_size
);
_dcmdparser
.
add_dcmd_option
(
&
_sample_threads
);
_dcmdparser
.
add_dcmd_option
(
&
_sample_threads
);
_dcmdparser
.
add_dcmd_option
(
&
_sample_object_allocations
);
_dcmdparser
.
add_dcmd_option
(
&
_object_allocations_sampling_interval
);
};
};
int
JfrConfigureFlightRecorderDCmd
::
num_arguments
()
{
int
JfrConfigureFlightRecorderDCmd
::
num_arguments
()
{
...
@@ -592,6 +597,8 @@ void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
...
@@ -592,6 +597,8 @@ void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
Handle
h_dcmd_instance
(
THREAD
,
dcmd
);
Handle
h_dcmd_instance
(
THREAD
,
dcmd
);
assert
(
h_dcmd_instance
.
not_null
(),
"invariant"
);
assert
(
h_dcmd_instance
.
not_null
(),
"invariant"
);
jobject
on_vm_start
=
JfrJavaSupport
::
new_java_lang_Boolean
(
_on_vm_start
,
CHECK
);
jstring
repository_path
=
NULL
;
jstring
repository_path
=
NULL
;
if
(
_repository_path
.
is_set
()
&&
_repository_path
.
value
()
!=
NULL
)
{
if
(
_repository_path
.
is_set
()
&&
_repository_path
.
value
()
!=
NULL
)
{
repository_path
=
JfrJavaSupport
::
new_string
(
_repository_path
.
value
(),
CHECK
);
repository_path
=
JfrJavaSupport
::
new_string
(
_repository_path
.
value
(),
CHECK
);
...
@@ -637,16 +644,27 @@ void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
...
@@ -637,16 +644,27 @@ void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
sample_threads
=
JfrJavaSupport
::
new_java_lang_Boolean
(
_sample_threads
.
value
(),
CHECK
);
sample_threads
=
JfrJavaSupport
::
new_java_lang_Boolean
(
_sample_threads
.
value
(),
CHECK
);
}
}
jobject
sample_object_allocations
=
NULL
;
if
(
_sample_object_allocations
.
is_set
())
{
sample_object_allocations
=
JfrJavaSupport
::
new_java_lang_Boolean
(
_sample_object_allocations
.
value
(),
CHECK
);
}
jobject
object_allocations_sampling_interval
=
NULL
;
if
(
_object_allocations_sampling_interval
.
is_set
())
{
object_allocations_sampling_interval
=
JfrJavaSupport
::
new_java_lang_Long
(
_object_allocations_sampling_interval
.
value
(),
CHECK
);
}
static
const
char
klass
[]
=
"jdk/jfr/internal/dcmd/DCmdConfigure"
;
static
const
char
klass
[]
=
"jdk/jfr/internal/dcmd/DCmdConfigure"
;
static
const
char
method
[]
=
"execute"
;
static
const
char
method
[]
=
"execute"
;
static
const
char
signature
[]
=
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;"
static
const
char
signature
[]
=
"(Ljava/lang/
Boolean;Ljava/lang/
String;Ljava/lang/String;Ljava/lang/Integer;"
"Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;"
"Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;"
"Ljava/lang/Long;Ljava/lang/Boolean;)Ljava/lang/String;"
;
"Ljava/lang/Long;Ljava/lang/Boolean;
Ljava/lang/Boolean;Ljava/lang/Long;
)Ljava/lang/String;"
;
JfrJavaArguments
execute_args
(
&
result
,
klass
,
method
,
signature
,
CHECK
);
JfrJavaArguments
execute_args
(
&
result
,
klass
,
method
,
signature
,
CHECK
);
execute_args
.
set_receiver
(
h_dcmd_instance
);
execute_args
.
set_receiver
(
h_dcmd_instance
);
// params
// params
execute_args
.
push_jobject
(
on_vm_start
);
execute_args
.
push_jobject
(
repository_path
);
execute_args
.
push_jobject
(
repository_path
);
execute_args
.
push_jobject
(
dump_path
);
execute_args
.
push_jobject
(
dump_path
);
execute_args
.
push_jobject
(
stack_depth
);
execute_args
.
push_jobject
(
stack_depth
);
...
@@ -656,6 +674,8 @@ void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
...
@@ -656,6 +674,8 @@ void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
execute_args
.
push_jobject
(
memory_size
);
execute_args
.
push_jobject
(
memory_size
);
execute_args
.
push_jobject
(
max_chunk_size
);
execute_args
.
push_jobject
(
max_chunk_size
);
execute_args
.
push_jobject
(
sample_threads
);
execute_args
.
push_jobject
(
sample_threads
);
execute_args
.
push_jobject
(
sample_object_allocations
);
execute_args
.
push_jobject
(
object_allocations_sampling_interval
);
JfrJavaSupport
::
call_virtual
(
&
execute_args
,
THREAD
);
JfrJavaSupport
::
call_virtual
(
&
execute_args
,
THREAD
);
handle_dcmd_result
(
output
(),
(
oop
)
result
.
get_jobject
(),
source
,
THREAD
);
handle_dcmd_result
(
output
(),
(
oop
)
result
.
get_jobject
(),
source
,
THREAD
);
...
...
src/share/vm/jfr/dcmd/jfrDcmds.hpp
浏览文件 @
0bb1ab9e
...
@@ -140,6 +140,11 @@ class JfrRuntimeOptions;
...
@@ -140,6 +140,11 @@ class JfrRuntimeOptions;
class
JfrConfigureFlightRecorderDCmd
:
public
DCmdWithParser
{
class
JfrConfigureFlightRecorderDCmd
:
public
DCmdWithParser
{
friend
class
JfrOptionSet
;
friend
class
JfrOptionSet
;
private:
bool
_on_vm_start
;
void
set_on_vm_start
(
bool
on_vm_start
)
{
_on_vm_start
=
on_vm_start
;
}
protected:
protected:
DCmdArgument
<
char
*>
_repository_path
;
DCmdArgument
<
char
*>
_repository_path
;
DCmdArgument
<
char
*>
_dump_path
;
DCmdArgument
<
char
*>
_dump_path
;
...
@@ -150,6 +155,8 @@ class JfrConfigureFlightRecorderDCmd : public DCmdWithParser {
...
@@ -150,6 +155,8 @@ class JfrConfigureFlightRecorderDCmd : public DCmdWithParser {
DCmdArgument
<
MemorySizeArgument
>
_memory_size
;
DCmdArgument
<
MemorySizeArgument
>
_memory_size
;
DCmdArgument
<
MemorySizeArgument
>
_max_chunk_size
;
DCmdArgument
<
MemorySizeArgument
>
_max_chunk_size
;
DCmdArgument
<
bool
>
_sample_threads
;
DCmdArgument
<
bool
>
_sample_threads
;
DCmdArgument
<
bool
>
_sample_object_allocations
;
DCmdArgument
<
jlong
>
_object_allocations_sampling_interval
;
public:
public:
JfrConfigureFlightRecorderDCmd
(
outputStream
*
output
,
bool
heap
);
JfrConfigureFlightRecorderDCmd
(
outputStream
*
output
,
bool
heap
);
...
@@ -168,6 +175,9 @@ class JfrConfigureFlightRecorderDCmd : public DCmdWithParser {
...
@@ -168,6 +175,9 @@ class JfrConfigureFlightRecorderDCmd : public DCmdWithParser {
}
}
static
int
num_arguments
();
static
int
num_arguments
();
virtual
void
execute
(
DCmdSource
source
,
TRAPS
);
virtual
void
execute
(
DCmdSource
source
,
TRAPS
);
bool
on_vm_start
()
const
{
return
_on_vm_start
;
}
};
};
class
JfrUnlockCommercialFeaturesDCmd
:
public
DCmd
{
class
JfrUnlockCommercialFeaturesDCmd
:
public
DCmd
{
...
...
src/share/vm/jfr/jni/jfrJniMethod.cpp
浏览文件 @
0bb1ab9e
...
@@ -44,6 +44,7 @@
...
@@ -44,6 +44,7 @@
#include "jfr/instrumentation/jfrEventClassTransformer.hpp"
#include "jfr/instrumentation/jfrEventClassTransformer.hpp"
#include "jfr/instrumentation/jfrJvmtiAgent.hpp"
#include "jfr/instrumentation/jfrJvmtiAgent.hpp"
#include "jfr/leakprofiler/leakProfiler.hpp"
#include "jfr/leakprofiler/leakProfiler.hpp"
#include "jfr/objectprofiler/objectProfiler.hpp"
#include "jfr/utilities/jfrJavaLog.hpp"
#include "jfr/utilities/jfrJavaLog.hpp"
#include "jfr/utilities/jfrTimeConverter.hpp"
#include "jfr/utilities/jfrTimeConverter.hpp"
#include "jfr/utilities/jfrTime.hpp"
#include "jfr/utilities/jfrTime.hpp"
...
@@ -110,6 +111,15 @@ NO_TRANSITION(void, jfr_set_enabled(JNIEnv* env, jobject jvm, jlong event_type_i
...
@@ -110,6 +111,15 @@ NO_TRANSITION(void, jfr_set_enabled(JNIEnv* env, jobject jvm, jlong event_type_i
LeakProfiler
::
stop
();
LeakProfiler
::
stop
();
}
}
}
}
if
(
EventOptoInstanceObjectAllocation
::
eventId
==
event_type_id
||
EventOptoArrayObjectAllocation
::
eventId
==
event_type_id
)
{
ThreadInVMfromNative
transition
(
JavaThread
::
thread_from_jni_environment
(
env
));
if
(
JNI_TRUE
==
enabled
)
{
ObjectProfiler
::
start
(
event_type_id
);
}
else
{
ObjectProfiler
::
stop
(
event_type_id
);
}
}
NO_TRANSITION_END
NO_TRANSITION_END
NO_TRANSITION
(
void
,
jfr_set_file_notification
(
JNIEnv
*
env
,
jobject
jvm
,
jlong
threshold
))
NO_TRANSITION
(
void
,
jfr_set_file_notification
(
JNIEnv
*
env
,
jobject
jvm
,
jlong
threshold
))
...
@@ -144,6 +154,14 @@ NO_TRANSITION(void, jfr_set_memory_size(JNIEnv* env, jobject jvm, jlong size))
...
@@ -144,6 +154,14 @@ NO_TRANSITION(void, jfr_set_memory_size(JNIEnv* env, jobject jvm, jlong size))
JfrOptionSet
::
set_memory_size
(
size
);
JfrOptionSet
::
set_memory_size
(
size
);
NO_TRANSITION_END
NO_TRANSITION_END
NO_TRANSITION
(
void
,
jfr_set_sample_object_allocations
(
JNIEnv
*
env
,
jobject
jvm
,
jboolean
sampleAllocations
))
JfrOptionSet
::
set_sample_object_allocations
(
sampleAllocations
);
NO_TRANSITION_END
NO_TRANSITION
(
void
,
jfr_set_object_allocations_sampling_interval
(
JNIEnv
*
env
,
jobject
jvm
,
jlong
interval
))
JfrOptionSet
::
set_object_allocations_sampling_interval
(
interval
);
NO_TRANSITION_END
NO_TRANSITION
(
jboolean
,
jfr_set_threshold
(
JNIEnv
*
env
,
jobject
jvm
,
jlong
event_type_id
,
jlong
thresholdTicks
))
NO_TRANSITION
(
jboolean
,
jfr_set_threshold
(
JNIEnv
*
env
,
jobject
jvm
,
jlong
event_type_id
,
jlong
thresholdTicks
))
return
JfrEventSetting
::
set_threshold
(
event_type_id
,
thresholdTicks
)
?
JNI_TRUE
:
JNI_FALSE
;
return
JfrEventSetting
::
set_threshold
(
event_type_id
,
thresholdTicks
)
?
JNI_TRUE
:
JNI_FALSE
;
NO_TRANSITION_END
NO_TRANSITION_END
...
@@ -233,7 +251,7 @@ JVM_ENTRY_NO_ENV(jlong, jfr_class_id(JNIEnv* env, jclass jvm, jclass jc))
...
@@ -233,7 +251,7 @@ JVM_ENTRY_NO_ENV(jlong, jfr_class_id(JNIEnv* env, jclass jvm, jclass jc))
JVM_END
JVM_END
JVM_ENTRY_NO_ENV
(
jlong
,
jfr_stacktrace_id
(
JNIEnv
*
env
,
jobject
jvm
,
jint
skip
))
JVM_ENTRY_NO_ENV
(
jlong
,
jfr_stacktrace_id
(
JNIEnv
*
env
,
jobject
jvm
,
jint
skip
))
return
JfrStackTraceRepository
::
record
(
thread
,
skip
);
return
JfrStackTraceRepository
::
record
(
thread
,
skip
,
WALK_BY_DEFAULT
);
JVM_END
JVM_END
JVM_ENTRY_NO_ENV
(
void
,
jfr_log
(
JNIEnv
*
env
,
jobject
jvm
,
jint
tag_set
,
jint
level
,
jstring
message
))
JVM_ENTRY_NO_ENV
(
void
,
jfr_log
(
JNIEnv
*
env
,
jobject
jvm
,
jint
tag_set
,
jint
level
,
jstring
message
))
...
...
src/share/vm/jfr/jni/jfrJniMethod.hpp
浏览文件 @
0bb1ab9e
...
@@ -93,6 +93,10 @@ void JNICALL jfr_set_memory_size(JNIEnv* env, jobject jvm, jlong size);
...
@@ -93,6 +93,10 @@ void JNICALL jfr_set_memory_size(JNIEnv* env, jobject jvm, jlong size);
jboolean
JNICALL
jfr_set_threshold
(
JNIEnv
*
env
,
jobject
jvm
,
jlong
event_type_id
,
jlong
thresholdTicks
);
jboolean
JNICALL
jfr_set_threshold
(
JNIEnv
*
env
,
jobject
jvm
,
jlong
event_type_id
,
jlong
thresholdTicks
);
void
JNICALL
jfr_set_sample_object_allocations
(
JNIEnv
*
env
,
jobject
jvm
,
jboolean
sampleAllocations
);
void
JNICALL
jfr_set_object_allocations_sampling_interval
(
JNIEnv
*
env
,
jobject
jvm
,
jlong
interval
);
void
JNICALL
jfr_store_metadata_descriptor
(
JNIEnv
*
env
,
jobject
jvm
,
jbyteArray
descriptor
);
void
JNICALL
jfr_store_metadata_descriptor
(
JNIEnv
*
env
,
jobject
jvm
,
jbyteArray
descriptor
);
jlong
JNICALL
jfr_id_for_thread
(
JNIEnv
*
env
,
jobject
jvm
,
jobject
t
);
jlong
JNICALL
jfr_id_for_thread
(
JNIEnv
*
env
,
jobject
jvm
,
jobject
t
);
...
...
src/share/vm/jfr/jni/jfrJniMethodRegistration.cpp
浏览文件 @
0bb1ab9e
...
@@ -62,6 +62,8 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) {
...
@@ -62,6 +62,8 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) {
(
char
*
)
"setThreadBufferSize"
,
(
char
*
)
"(J)V"
,
(
void
*
)
jfr_set_thread_buffer_size
,
(
char
*
)
"setThreadBufferSize"
,
(
char
*
)
"(J)V"
,
(
void
*
)
jfr_set_thread_buffer_size
,
(
char
*
)
"setMemorySize"
,
(
char
*
)
"(J)V"
,
(
void
*
)
jfr_set_memory_size
,
(
char
*
)
"setMemorySize"
,
(
char
*
)
"(J)V"
,
(
void
*
)
jfr_set_memory_size
,
(
char
*
)
"setThreshold"
,
(
char
*
)
"(JJ)Z"
,
(
void
*
)
jfr_set_threshold
,
(
char
*
)
"setThreshold"
,
(
char
*
)
"(JJ)Z"
,
(
void
*
)
jfr_set_threshold
,
(
char
*
)
"setSampleObjectAllocations"
,
(
char
*
)
"(Z)V"
,(
void
*
)
jfr_set_sample_object_allocations
,
(
char
*
)
"setObjectAllocationsSamplingInterval"
,
(
char
*
)
"(J)V"
,(
void
*
)
jfr_set_object_allocations_sampling_interval
,
(
char
*
)
"storeMetadataDescriptor"
,
(
char
*
)
"([B)V"
,
(
void
*
)
jfr_store_metadata_descriptor
,
(
char
*
)
"storeMetadataDescriptor"
,
(
char
*
)
"([B)V"
,
(
void
*
)
jfr_store_metadata_descriptor
,
(
char
*
)
"getAllowedToDoEventRetransforms"
,
(
char
*
)
"()Z"
,
(
void
*
)
jfr_allow_event_retransforms
,
(
char
*
)
"getAllowedToDoEventRetransforms"
,
(
char
*
)
"()Z"
,
(
void
*
)
jfr_allow_event_retransforms
,
(
char
*
)
"isAvailable"
,
(
char
*
)
"()Z"
,
(
void
*
)
jfr_is_available
,
(
char
*
)
"isAvailable"
,
(
char
*
)
"()Z"
,
(
void
*
)
jfr_is_available
,
...
...
src/share/vm/jfr/leakprofiler/sampling/objectSampler.cpp
浏览文件 @
0bb1ab9e
...
@@ -122,7 +122,7 @@ void ObjectSampler::fill_stacktrace(JfrStackTrace* stacktrace, JavaThread* threa
...
@@ -122,7 +122,7 @@ void ObjectSampler::fill_stacktrace(JfrStackTrace* stacktrace, JavaThread* threa
assert
(
stacktrace
!=
NULL
,
"invariant"
);
assert
(
stacktrace
!=
NULL
,
"invariant"
);
assert
(
thread
!=
NULL
,
"invariant"
);
assert
(
thread
!=
NULL
,
"invariant"
);
if
(
JfrEventSetting
::
has_stacktrace
(
EventOldObjectSample
::
eventId
))
{
if
(
JfrEventSetting
::
has_stacktrace
(
EventOldObjectSample
::
eventId
))
{
JfrStackTraceRepository
::
fill_stacktrace_for
(
thread
,
stacktrace
,
0
);
JfrStackTraceRepository
::
fill_stacktrace_for
(
thread
,
stacktrace
,
0
,
WALK_BY_DEFAULT
);
}
}
}
}
...
...
src/share/vm/jfr/metadata/metadata.xml
浏览文件 @
0bb1ab9e
...
@@ -575,6 +575,17 @@
...
@@ -575,6 +575,17 @@
<Field
type=
"ulong"
contentType=
"bytes"
name=
"allocationSize"
label=
"Allocation Size"
/>
<Field
type=
"ulong"
contentType=
"bytes"
name=
"allocationSize"
label=
"Allocation Size"
/>
</Event>
</Event>
<Event
name=
"OptoInstanceObjectAllocation"
category=
"Java Application"
label=
"Opto instance object allocation"
description=
"Allocation by Opto jitted method"
thread=
"true"
stackTrace=
"true"
startTime=
"false"
>
<Field
type=
"Class"
name=
"objectClass"
label=
"Object Class"
description=
"Class of allocated instance object"
/>
<Field
type=
"ulong"
contentType=
"address"
name=
"address"
label=
"Opto Instance Object Allocation Address"
description=
"Address of allocated instance object"
/>
</Event>
<Event
name=
"OptoArrayObjectAllocation"
category=
"Java Application"
label=
"Opto array object allocation"
description=
"Array Allocation by Opto jitted method"
thread=
"true"
stackTrace=
"true"
startTime=
"false"
>
<Field
type=
"Class"
name=
"objectClass"
label=
"Object Class"
description=
"Class of allocated array object"
/>
<Field
type=
"ulong"
contentType=
"address"
name=
"address"
label=
"Opto Array Object Allocation Address"
description=
"Address of allocated instance object"
/>
<Field
type=
"ulong"
contentType=
"bytes"
name=
"allocationSize"
label=
"Object Size"
description=
"The Array Object Size"
/>
</Event>
<Event
name=
"OldObjectSample"
category=
"Java Virtual Machine, Profiling"
label=
"Old Object Sample"
description=
"A potential memory leak"
stackTrace=
"true"
thread=
"true"
<Event
name=
"OldObjectSample"
category=
"Java Virtual Machine, Profiling"
label=
"Old Object Sample"
description=
"A potential memory leak"
stackTrace=
"true"
thread=
"true"
startTime=
"false"
cutoff=
"true"
>
startTime=
"false"
cutoff=
"true"
>
<Field
type=
"Ticks"
name=
"allocationTime"
label=
"Allocation Time"
/>
<Field
type=
"Ticks"
name=
"allocationTime"
label=
"Allocation Time"
/>
...
@@ -949,6 +960,7 @@
...
@@ -949,6 +960,7 @@
<Field
type=
"Symbol"
name=
"name"
label=
"Name"
/>
<Field
type=
"Symbol"
name=
"name"
label=
"Name"
/>
<Field
type=
"Package"
name=
"package"
label=
"Package"
/>
<Field
type=
"Package"
name=
"package"
label=
"Package"
/>
<Field
type=
"int"
name=
"modifiers"
label=
"Access Modifiers"
/>
<Field
type=
"int"
name=
"modifiers"
label=
"Access Modifiers"
/>
<Field
type=
"int"
name=
"objectSize"
label=
"Object Size"
/>
</Type>
</Type>
<Type
name=
"ClassLoader"
label=
"Java Class Loader"
>
<Type
name=
"ClassLoader"
label=
"Java Class Loader"
>
...
...
src/share/vm/jfr/objectprofiler/objectProfiler.cpp
0 → 100644
浏览文件 @
0bb1ab9e
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. 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. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*
*/
#include "precompiled.hpp"
#include "runtime/vmThread.hpp"
#include "jfr/objectprofiler/objectProfiler.hpp"
#include "jfr/utilities/jfrTryLock.hpp"
#include "jfrfiles/jfrEventClasses.hpp"
volatile
jint
ObjectProfiler
::
_enabled
=
JNI_FALSE
;
bool
ObjectProfiler
::
_sample_instance_obj_alloc
=
false
;
bool
ObjectProfiler
::
_sample_array_obj_alloc
=
false
;
#ifndef PRODUCT
volatile
int
ObjectProfiler
::
_try_lock
=
0
;
#endif
void
ObjectProfiler
::
start
(
jlong
event_id
)
{
#ifndef PRODUCT
JfrTryLock
try_lock
(
&
_try_lock
);
assert
(
try_lock
.
has_lock
(),
"Not allow contention"
);
#endif
if
(
EventOptoInstanceObjectAllocation
::
eventId
==
event_id
)
{
if
(
!
_sample_instance_obj_alloc
)
{
_sample_instance_obj_alloc
=
true
;
}
}
else
if
(
EventOptoArrayObjectAllocation
::
eventId
==
event_id
)
{
if
(
!
_sample_array_obj_alloc
)
{
_sample_array_obj_alloc
=
true
;
}
}
else
{
ShouldNotReachHere
();
}
if
(
enabled
()
==
JNI_TRUE
)
{
return
;
}
OrderAccess
::
release_store
((
volatile
jint
*
)
&
_enabled
,
JNI_TRUE
);
}
void
ObjectProfiler
::
stop
(
jlong
event_id
)
{
#ifndef PRODUCT
JfrTryLock
try_lock
(
&
_try_lock
);
assert
(
try_lock
.
has_lock
(),
"Not allow contention"
);
#endif
if
(
enabled
()
==
JNI_FALSE
)
{
assert
(
!
_sample_array_obj_alloc
&&
!
_sample_instance_obj_alloc
,
"Invariant"
);
return
;
}
if
(
EventOptoInstanceObjectAllocation
::
eventId
==
event_id
)
{
if
(
_sample_instance_obj_alloc
)
{
_sample_instance_obj_alloc
=
false
;
}
}
else
if
(
EventOptoArrayObjectAllocation
::
eventId
==
event_id
)
{
if
(
_sample_array_obj_alloc
)
{
_sample_array_obj_alloc
=
false
;
}
}
else
{
ShouldNotReachHere
();
}
bool
should_enable
=
_sample_array_obj_alloc
||
_sample_instance_obj_alloc
;
if
(
should_enable
)
{
return
;
}
OrderAccess
::
release_store
(
&
_enabled
,
JNI_FALSE
);
}
jint
ObjectProfiler
::
enabled
()
{
return
OrderAccess
::
load_acquire
((
volatile
jint
*
)
&
_enabled
);
}
void
*
ObjectProfiler
::
enabled_flag_address
()
{
return
(
void
*
)
&
_enabled
;
}
src/share/vm/jfr/objectprofiler/objectProfiler.hpp
0 → 100644
浏览文件 @
0bb1ab9e
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. 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. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*
*/
#ifndef SHARE_VM_JFR_OBJECTROFILER_OBJECTPROFILER_HPP
#define SHARE_VM_JFR_OBJECTROFILER_OBJECTPROFILER_HPP
#include "prims/jni.h"
class
ObjectProfiler
:
public
AllStatic
{
private:
static
volatile
jint
_enabled
;
static
bool
_sample_instance_obj_alloc
;
static
bool
_sample_array_obj_alloc
;
#ifndef PRODUCT
static
volatile
int
_try_lock
;
#endif
public:
static
void
start
(
jlong
event_id
);
static
void
stop
(
jlong
event_id
);
static
jint
enabled
();
static
void
*
enabled_flag_address
();
};
#endif // SHARE_VM_JFR_OBJECTROFILER_OBJECTPROFILER_HPP
src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
浏览文件 @
0bb1ab9e
...
@@ -148,6 +148,16 @@ int write__artifact__klass(JfrCheckpointWriter* writer, JfrArtifactSet* artifact
...
@@ -148,6 +148,16 @@ int write__artifact__klass(JfrCheckpointWriter* writer, JfrArtifactSet* artifact
writer
->
write
((
traceid
)
CREATE_SYMBOL_ID
(
symbol_id
));
writer
->
write
((
traceid
)
CREATE_SYMBOL_ID
(
symbol_id
));
writer
->
write
(
pkg_id
);
writer
->
write
(
pkg_id
);
writer
->
write
((
s4
)
klass
->
access_flags
().
get_flags
());
writer
->
write
((
s4
)
klass
->
access_flags
().
get_flags
());
if
(
klass
->
oop_is_array
())
{
// The object array size can not be determined statically from klass.
// It is determined by the elements length in object layout.
// So we put a place holder here to make the event parser ignore it.
writer
->
write
((
s4
)
ARRAY_OBJECT_SIZE_PLACE_HOLDER
);
}
else
{
assert
(
klass
->
oop_is_instance
(),
"invariant"
);
jint
instanceSize
=
((
InstanceKlass
*
)
klass
)
->
size_helper
()
*
HeapWordSize
;
writer
->
write
((
s4
)
instanceSize
);
}
return
1
;
return
1
;
}
}
...
...
src/share/vm/jfr/recorder/jfrEventSetting.cpp
浏览文件 @
0bb1ab9e
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "precompiled.hpp"
#include "jfr/recorder/jfrEventSetting.inline.hpp"
#include "jfr/recorder/jfrEventSetting.inline.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
JfrNativeSettings
JfrEventSetting
::
_jvm_event_settings
;
JfrNativeSettings
JfrEventSetting
::
_jvm_event_settings
;
...
@@ -53,6 +54,14 @@ void JfrEventSetting::set_enabled(jlong id, bool enabled) {
...
@@ -53,6 +54,14 @@ void JfrEventSetting::set_enabled(jlong id, bool enabled) {
setting
(
event_id
).
enabled
=
enabled
;
setting
(
event_id
).
enabled
=
enabled
;
}
}
StackWalkMode
JfrEventSetting
::
stack_walk_mode
(
JfrEventId
event_id
)
{
if
(
event_id
==
JfrOptoArrayObjectAllocationEvent
||
event_id
==
JfrOptoInstanceObjectAllocationEvent
)
{
return
WALK_BY_CURRENT_FRAME
;
}
return
WALK_BY_DEFAULT
;
}
#ifdef ASSERT
#ifdef ASSERT
bool
JfrEventSetting
::
bounds_check_event
(
jlong
id
)
{
bool
JfrEventSetting
::
bounds_check_event
(
jlong
id
)
{
if
((
unsigned
)
id
<
NUM_RESERVED_EVENTS
||
(
unsigned
)
id
>=
MaxJfrEventId
)
{
if
((
unsigned
)
id
<
NUM_RESERVED_EVENTS
||
(
unsigned
)
id
>=
MaxJfrEventId
)
{
...
...
src/share/vm/jfr/recorder/jfrEventSetting.hpp
浏览文件 @
0bb1ab9e
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#include "jni.h"
#include "jni.h"
#include "jfr/utilities/jfrAllocation.hpp"
#include "jfr/utilities/jfrAllocation.hpp"
#include "jfrfiles/jfrEventControl.hpp"
#include "jfrfiles/jfrEventControl.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
//
//
// Native event settings as an associative array using the event id as key.
// Native event settings as an associative array using the event id as key.
...
@@ -46,6 +47,7 @@ class JfrEventSetting : AllStatic {
...
@@ -46,6 +47,7 @@ class JfrEventSetting : AllStatic {
static
jlong
threshold
(
JfrEventId
event_id
);
static
jlong
threshold
(
JfrEventId
event_id
);
static
bool
set_cutoff
(
jlong
event_id
,
jlong
cutoff_ticks
);
static
bool
set_cutoff
(
jlong
event_id
,
jlong
cutoff_ticks
);
static
jlong
cutoff
(
JfrEventId
event_id
);
static
jlong
cutoff
(
JfrEventId
event_id
);
static
StackWalkMode
stack_walk_mode
(
JfrEventId
event_id
);
DEBUG_ONLY
(
static
bool
bounds_check_event
(
jlong
id
);)
DEBUG_ONLY
(
static
bool
bounds_check_event
(
jlong
id
);)
};
};
...
...
src/share/vm/jfr/recorder/service/jfrEvent.hpp
浏览文件 @
0bb1ab9e
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#define SHARE_VM_JFR_RECORDER_SERVICE_JFREVENT_HPP
#define SHARE_VM_JFR_RECORDER_SERVICE_JFREVENT_HPP
#include "jfr/recorder/jfrEventSetting.inline.hpp"
#include "jfr/recorder/jfrEventSetting.inline.hpp"
#include "jfr/recorder/jfrEventSetting.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
#include "jfr/utilities/jfrTime.hpp"
#include "jfr/utilities/jfrTime.hpp"
#include "jfr/utilities/jfrTypes.hpp"
#include "jfr/utilities/jfrTypes.hpp"
...
@@ -176,7 +177,7 @@ class JfrEvent {
...
@@ -176,7 +177,7 @@ class JfrEvent {
if
(
tl
->
has_cached_stack_trace
())
{
if
(
tl
->
has_cached_stack_trace
())
{
writer
.
write
(
tl
->
cached_stack_trace_id
());
writer
.
write
(
tl
->
cached_stack_trace_id
());
}
else
{
}
else
{
writer
.
write
(
JfrStackTraceRepository
::
record
(
event_thread
));
writer
.
write
(
JfrStackTraceRepository
::
record
(
event_thread
,
0
,
JfrEventSetting
::
stack_walk_mode
(
T
::
eventId
)
));
}
}
}
else
{
}
else
{
writer
.
write
<
traceid
>
(
0
);
writer
.
write
<
traceid
>
(
0
);
...
...
src/share/vm/jfr/recorder/service/jfrOptionSet.cpp
浏览文件 @
0bb1ab9e
...
@@ -35,6 +35,7 @@
...
@@ -35,6 +35,7 @@
#include "services/diagnosticFramework.hpp"
#include "services/diagnosticFramework.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/ostream.hpp"
#include "utilities/ostream.hpp"
#include "utilities/debug.hpp"
struct
ObsoleteOption
{
struct
ObsoleteOption
{
const
char
*
name
;
const
char
*
name
;
...
@@ -162,6 +163,22 @@ bool JfrOptionSet::allow_event_retransforms() {
...
@@ -162,6 +163,22 @@ bool JfrOptionSet::allow_event_retransforms() {
return
allow_retransforms
()
&&
(
DumpSharedSpaces
||
can_retransform
());
return
allow_retransforms
()
&&
(
DumpSharedSpaces
||
can_retransform
());
}
}
bool
JfrOptionSet
::
sample_object_allocations
()
{
return
_sample_object_allocations
==
JNI_TRUE
;
}
void
JfrOptionSet
::
set_sample_object_allocations
(
jboolean
value
)
{
_sample_object_allocations
=
value
;
}
jlong
JfrOptionSet
::
object_allocations_sampling_interval
()
{
return
_object_allocations_sampling_interval
;
}
void
JfrOptionSet
::
set_object_allocations_sampling_interval
(
jlong
value
)
{
_object_allocations_sampling_interval
=
value
;
}
// default options for the dcmd parser
// default options for the dcmd parser
const
char
*
const
default_repository
=
NULL
;
const
char
*
const
default_repository
=
NULL
;
const
char
*
const
default_global_buffer_size
=
"512k"
;
const
char
*
const
default_global_buffer_size
=
"512k"
;
...
@@ -174,6 +191,9 @@ const char* const default_stack_depth = "64";
...
@@ -174,6 +191,9 @@ const char* const default_stack_depth = "64";
const
char
*
const
default_retransform
=
"true"
;
const
char
*
const
default_retransform
=
"true"
;
const
char
*
const
default_old_object_queue_size
=
"256"
;
const
char
*
const
default_old_object_queue_size
=
"256"
;
DEBUG_ONLY
(
const
char
*
const
default_sample_protection
=
"false"
;)
DEBUG_ONLY
(
const
char
*
const
default_sample_protection
=
"false"
;)
const
char
*
const
default_sample_object_allocations
=
"false"
;
// the unit of this value is not time but quantity
const
char
*
const
default_object_allocations_sampling_interval
=
"1024"
;
// statics
// statics
static
DCmdArgument
<
char
*>
_dcmd_repository
(
static
DCmdArgument
<
char
*>
_dcmd_repository
(
...
@@ -255,6 +275,20 @@ static DCmdArgument<bool> _dcmd_retransform(
...
@@ -255,6 +275,20 @@ static DCmdArgument<bool> _dcmd_retransform(
true
,
true
,
default_retransform
);
default_retransform
);
static
DCmdArgument
<
bool
>
_dcmd_sampleobjectallocations
(
"sampleobjectallocations"
,
"If object allocations should be sampled (by default false)"
,
"BOOLEAN"
,
false
,
default_sample_object_allocations
);
static
DCmdArgument
<
jlong
>
_dcmd_objectallocationssamplinginterval
(
"objectallocationssamplinginterval"
,
"object allocations sampling interval (by default 1024)"
,
"JLONG"
,
false
,
default_object_allocations_sampling_interval
);
static
DCmdParser
_parser
;
static
DCmdParser
_parser
;
static
void
register_parser_options
()
{
static
void
register_parser_options
()
{
...
@@ -269,6 +303,8 @@ static void register_parser_options() {
...
@@ -269,6 +303,8 @@ static void register_parser_options() {
_parser
.
add_dcmd_option
(
&
_dcmd_retransform
);
_parser
.
add_dcmd_option
(
&
_dcmd_retransform
);
_parser
.
add_dcmd_option
(
&
_dcmd_old_object_queue_size
);
_parser
.
add_dcmd_option
(
&
_dcmd_old_object_queue_size
);
DEBUG_ONLY
(
_parser
.
add_dcmd_option
(
&
_dcmd_sample_protection
);)
DEBUG_ONLY
(
_parser
.
add_dcmd_option
(
&
_dcmd_sample_protection
);)
_parser
.
add_dcmd_option
(
&
_dcmd_sampleobjectallocations
);
_parser
.
add_dcmd_option
(
&
_dcmd_objectallocationssamplinginterval
);
}
}
static
bool
parse_flight_recorder_options_internal
(
TRAPS
)
{
static
bool
parse_flight_recorder_options_internal
(
TRAPS
)
{
...
@@ -314,6 +350,9 @@ jboolean JfrOptionSet::_sample_protection = JNI_FALSE;
...
@@ -314,6 +350,9 @@ jboolean JfrOptionSet::_sample_protection = JNI_FALSE;
#else
#else
jboolean
JfrOptionSet
::
_sample_protection
=
JNI_TRUE
;
jboolean
JfrOptionSet
::
_sample_protection
=
JNI_TRUE
;
#endif
#endif
volatile
jboolean
JfrOptionSet
::
_sample_object_allocations
=
JNI_FALSE
;
// the unit of this value is not time but quantity
volatile
jlong
JfrOptionSet
::
_object_allocations_sampling_interval
=
1024
;
bool
JfrOptionSet
::
initialize
(
Thread
*
thread
)
{
bool
JfrOptionSet
::
initialize
(
Thread
*
thread
)
{
register_parser_options
();
register_parser_options
();
...
@@ -335,6 +374,7 @@ bool JfrOptionSet::configure(TRAPS) {
...
@@ -335,6 +374,7 @@ bool JfrOptionSet::configure(TRAPS) {
bufferedStream
st
;
bufferedStream
st
;
// delegate to DCmd execution
// delegate to DCmd execution
JfrConfigureFlightRecorderDCmd
configure
(
&
st
,
false
);
JfrConfigureFlightRecorderDCmd
configure
(
&
st
,
false
);
configure
.
set_on_vm_start
(
true
);
configure
.
_repository_path
.
set_is_set
(
_dcmd_repository
.
is_set
());
configure
.
_repository_path
.
set_is_set
(
_dcmd_repository
.
is_set
());
char
*
repo
=
_dcmd_repository
.
value
();
char
*
repo
=
_dcmd_repository
.
value
();
if
(
repo
!=
NULL
)
{
if
(
repo
!=
NULL
)
{
...
@@ -368,6 +408,12 @@ bool JfrOptionSet::configure(TRAPS) {
...
@@ -368,6 +408,12 @@ bool JfrOptionSet::configure(TRAPS) {
configure
.
_sample_threads
.
set_is_set
(
_dcmd_sample_threads
.
is_set
());
configure
.
_sample_threads
.
set_is_set
(
_dcmd_sample_threads
.
is_set
());
configure
.
_sample_threads
.
set_value
(
_dcmd_sample_threads
.
value
());
configure
.
_sample_threads
.
set_value
(
_dcmd_sample_threads
.
value
());
configure
.
_sample_object_allocations
.
set_is_set
(
_dcmd_sampleobjectallocations
.
is_set
());
configure
.
_sample_object_allocations
.
set_value
(
_dcmd_sampleobjectallocations
.
value
());
configure
.
_object_allocations_sampling_interval
.
set_is_set
(
_dcmd_objectallocationssamplinginterval
.
is_set
());
configure
.
_object_allocations_sampling_interval
.
set_value
(
_dcmd_objectallocationssamplinginterval
.
value
());
configure
.
execute
(
DCmd_Source_Internal
,
THREAD
);
configure
.
execute
(
DCmd_Source_Internal
,
THREAD
);
if
(
HAS_PENDING_EXCEPTION
)
{
if
(
HAS_PENDING_EXCEPTION
)
{
...
...
src/share/vm/jfr/recorder/service/jfrOptionSet.hpp
浏览文件 @
0bb1ab9e
...
@@ -48,6 +48,8 @@ class JfrOptionSet : public AllStatic {
...
@@ -48,6 +48,8 @@ class JfrOptionSet : public AllStatic {
static
jboolean
_sample_threads
;
static
jboolean
_sample_threads
;
static
jboolean
_retransform
;
static
jboolean
_retransform
;
static
jboolean
_sample_protection
;
static
jboolean
_sample_protection
;
static
volatile
jboolean
_sample_object_allocations
;
static
volatile
jlong
_object_allocations_sampling_interval
;
static
bool
initialize
(
Thread
*
thread
);
static
bool
initialize
(
Thread
*
thread
);
static
bool
configure
(
TRAPS
);
static
bool
configure
(
TRAPS
);
...
@@ -77,6 +79,10 @@ class JfrOptionSet : public AllStatic {
...
@@ -77,6 +79,10 @@ class JfrOptionSet : public AllStatic {
static
bool
allow_event_retransforms
();
static
bool
allow_event_retransforms
();
static
bool
sample_protection
();
static
bool
sample_protection
();
DEBUG_ONLY
(
static
void
set_sample_protection
(
jboolean
protection
);)
DEBUG_ONLY
(
static
void
set_sample_protection
(
jboolean
protection
);)
static
bool
sample_object_allocations
();
static
void
set_sample_object_allocations
(
jboolean
value
);
static
jlong
object_allocations_sampling_interval
();
static
void
set_object_allocations_sampling_interval
(
jlong
value
);
static
bool
parse_flight_recorder_option
(
const
JavaVMOption
**
option
,
char
*
delimiter
);
static
bool
parse_flight_recorder_option
(
const
JavaVMOption
**
option
,
char
*
delimiter
);
static
bool
parse_start_flight_recording_option
(
const
JavaVMOption
**
option
,
char
*
delimiter
);
static
bool
parse_start_flight_recording_option
(
const
JavaVMOption
**
option
,
char
*
delimiter
);
...
...
src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp
浏览文件 @
0bb1ab9e
...
@@ -173,7 +173,7 @@ traceid JfrStackTraceRepository::add(const JfrStackTrace& stacktrace) {
...
@@ -173,7 +173,7 @@ traceid JfrStackTraceRepository::add(const JfrStackTrace& stacktrace) {
return
tid
;
return
tid
;
}
}
traceid
JfrStackTraceRepository
::
record
(
Thread
*
thread
,
int
skip
/* 0 */
)
{
traceid
JfrStackTraceRepository
::
record
(
Thread
*
thread
,
int
skip
,
StackWalkMode
mode
)
{
assert
(
thread
==
Thread
::
current
(),
"invariant"
);
assert
(
thread
==
Thread
::
current
(),
"invariant"
);
JfrThreadLocal
*
const
tl
=
thread
->
jfr_thread_local
();
JfrThreadLocal
*
const
tl
=
thread
->
jfr_thread_local
();
assert
(
tl
!=
NULL
,
"invariant"
);
assert
(
tl
!=
NULL
,
"invariant"
);
...
@@ -190,12 +190,12 @@ traceid JfrStackTraceRepository::record(Thread* thread, int skip /* 0 */) {
...
@@ -190,12 +190,12 @@ traceid JfrStackTraceRepository::record(Thread* thread, int skip /* 0 */) {
}
}
assert
(
frames
!=
NULL
,
"invariant"
);
assert
(
frames
!=
NULL
,
"invariant"
);
assert
(
tl
->
stackframes
()
==
frames
,
"invariant"
);
assert
(
tl
->
stackframes
()
==
frames
,
"invariant"
);
return
instance
().
record_for
((
JavaThread
*
)
thread
,
skip
,
frames
,
tl
->
stackdepth
());
return
instance
().
record_for
((
JavaThread
*
)
thread
,
skip
,
mode
,
frames
,
tl
->
stackdepth
());
}
}
traceid
JfrStackTraceRepository
::
record_for
(
JavaThread
*
thread
,
int
skip
,
JfrStackFrame
*
frames
,
u4
max_frames
)
{
traceid
JfrStackTraceRepository
::
record_for
(
JavaThread
*
thread
,
int
skip
,
StackWalkMode
mode
,
JfrStackFrame
*
frames
,
u4
max_frames
)
{
JfrStackTrace
stacktrace
(
frames
,
max_frames
);
JfrStackTrace
stacktrace
(
frames
,
max_frames
);
return
stacktrace
.
record_safe
(
thread
,
skip
)
?
add
(
stacktrace
)
:
0
;
return
stacktrace
.
record_safe
(
thread
,
skip
,
false
,
mode
)
?
add
(
stacktrace
)
:
0
;
}
}
traceid
JfrStackTraceRepository
::
add
(
const
JfrStackTrace
*
stacktrace
,
JavaThread
*
thread
)
{
traceid
JfrStackTraceRepository
::
add
(
const
JfrStackTrace
*
stacktrace
,
JavaThread
*
thread
)
{
...
@@ -205,7 +205,7 @@ traceid JfrStackTraceRepository::add(const JfrStackTrace* stacktrace, JavaThread
...
@@ -205,7 +205,7 @@ traceid JfrStackTraceRepository::add(const JfrStackTrace* stacktrace, JavaThread
return
add
(
*
stacktrace
);
return
add
(
*
stacktrace
);
}
}
bool
JfrStackTraceRepository
::
fill_stacktrace_for
(
JavaThread
*
thread
,
JfrStackTrace
*
stacktrace
,
int
skip
)
{
bool
JfrStackTraceRepository
::
fill_stacktrace_for
(
JavaThread
*
thread
,
JfrStackTrace
*
stacktrace
,
int
skip
,
StackWalkMode
mode
)
{
assert
(
thread
==
Thread
::
current
(),
"invariant"
);
assert
(
thread
==
Thread
::
current
(),
"invariant"
);
assert
(
stacktrace
!=
NULL
,
"invariant"
);
assert
(
stacktrace
!=
NULL
,
"invariant"
);
JfrThreadLocal
*
const
tl
=
thread
->
jfr_thread_local
();
JfrThreadLocal
*
const
tl
=
thread
->
jfr_thread_local
();
...
@@ -215,7 +215,7 @@ bool JfrStackTraceRepository::fill_stacktrace_for(JavaThread* thread, JfrStackTr
...
@@ -215,7 +215,7 @@ bool JfrStackTraceRepository::fill_stacktrace_for(JavaThread* thread, JfrStackTr
stacktrace
->
set_hash
(
cached_stacktrace_hash
);
stacktrace
->
set_hash
(
cached_stacktrace_hash
);
return
true
;
return
true
;
}
}
return
stacktrace
->
record_safe
(
thread
,
skip
,
true
);
return
stacktrace
->
record_safe
(
thread
,
skip
,
true
,
mode
);
}
}
size_t
JfrStackTraceRepository
::
write_impl
(
JfrChunkWriter
&
sw
,
bool
clear
)
{
size_t
JfrStackTraceRepository
::
write_impl
(
JfrChunkWriter
&
sw
,
bool
clear
)
{
...
@@ -363,16 +363,45 @@ void JfrStackTrace::resolve_linenos() const {
...
@@ -363,16 +363,45 @@ void JfrStackTrace::resolve_linenos() const {
_lineno
=
true
;
_lineno
=
true
;
}
}
bool
JfrStackTrace
::
record_safe
(
JavaThread
*
thread
,
int
skip
,
bool
leakp
/* false */
)
{
bool
JfrStackTrace
::
record_safe
(
JavaThread
*
thread
,
int
skip
,
bool
leakp
,
StackWalkMode
mode
)
{
assert
(
SafepointSynchronize
::
safepoint_safe
(
thread
,
thread
->
thread_state
())
assert
(
SafepointSynchronize
::
safepoint_safe
(
thread
,
thread
->
thread_state
())
||
thread
==
Thread
::
current
(),
"Thread stack needs to be walkable"
);
||
thread
==
Thread
::
current
(),
"Thread stack needs to be walkable"
);
bool
success
=
false
;
switch
(
mode
)
{
case
WALK_BY_DEFAULT
:
{
vframeStream
vfs
(
thread
);
vframeStream
vfs
(
thread
);
success
=
fill_in
(
vfs
,
skip
,
leakp
,
mode
);
break
;
}
case
WALK_BY_CURRENT_FRAME
:
{
vframeStream
vfs
(
thread
,
os
::
current_frame
());
success
=
fill_in
(
vfs
,
skip
,
leakp
,
mode
);
break
;
}
default:
ShouldNotReachHere
();
}
return
success
;
}
bool
JfrStackTrace
::
fill_in
(
vframeStream
&
vfs
,
int
skip
,
bool
leakp
,
StackWalkMode
mode
)
{
u4
count
=
0
;
u4
count
=
0
;
_reached_root
=
true
;
_reached_root
=
true
;
// Indicates whether the top frame is visited in this frames iteration.
// Top frame bci may be invalid and fill_in() will fix the top frame bci in a conservative way.
bool
top_frame_visited
=
false
;
for
(
int
i
=
0
;
i
<
skip
;
i
++
)
{
for
(
int
i
=
0
;
i
<
skip
;
i
++
)
{
if
(
vfs
.
at_end
())
{
if
(
vfs
.
at_end
())
{
break
;
break
;
}
}
// The top frame is in skip list.
// Mark top_frame_visited to avoid unnecessary top frame bci fixing.
if
(
!
top_frame_visited
)
{
top_frame_visited
=
true
;
}
vfs
.
next
();
vfs
.
next
();
}
}
...
@@ -387,8 +416,25 @@ bool JfrStackTrace::record_safe(JavaThread* thread, int skip, bool leakp /* fals
...
@@ -387,8 +416,25 @@ bool JfrStackTrace::record_safe(JavaThread* thread, int skip, bool leakp /* fals
int
bci
=
0
;
int
bci
=
0
;
if
(
method
->
is_native
())
{
if
(
method
->
is_native
())
{
type
=
JfrStackFrame
::
FRAME_NATIVE
;
type
=
JfrStackFrame
::
FRAME_NATIVE
;
// The top frame is in native.
// Mark top_frame_visited to avoid unnecessary top frame bci fixing.
if
(
!
top_frame_visited
)
{
top_frame_visited
=
true
;
}
}
else
{
}
else
{
bci
=
vfs
.
bci
();
bci
=
vfs
.
bci
();
// Hit the top frame and fix bci here.
if
(
!
top_frame_visited
)
{
if
(
mode
==
WALK_BY_CURRENT_FRAME
)
{
// Only fix opto fast path allocation.
// All fast path allocations do not have cached event id.
if
(
!
vfs
.
thread_ref
()
->
jfr_thread_local
()
->
has_cached_event_id
())
{
assert
(
vfs
.
thread_ref
()
->
jfr_thread_local
()
->
has_cached_top_frame_bci
(),
"Invariant"
);
bci
=
vfs
.
thread_ref
()
->
jfr_thread_local
()
->
cached_top_frame_bci
();
}
}
top_frame_visited
=
true
;
}
}
}
// Can we determine if it's inlined?
// Can we determine if it's inlined?
_hash
=
(
_hash
<<
2
)
+
(
unsigned
int
)(((
size_t
)
mid
>>
2
)
+
(
bci
<<
4
)
+
type
);
_hash
=
(
_hash
<<
2
)
+
(
unsigned
int
)(((
size_t
)
mid
>>
2
)
+
(
bci
<<
4
)
+
type
);
...
...
src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp
浏览文件 @
0bb1ab9e
...
@@ -33,6 +33,7 @@ class JavaThread;
...
@@ -33,6 +33,7 @@ class JavaThread;
class
JfrCheckpointWriter
;
class
JfrCheckpointWriter
;
class
JfrChunkWriter
;
class
JfrChunkWriter
;
class
Method
;
class
Method
;
class
vframeStream
;
class
JfrStackFrame
{
class
JfrStackFrame
{
private:
private:
...
@@ -61,6 +62,15 @@ class JfrStackFrame {
...
@@ -61,6 +62,15 @@ class JfrStackFrame {
void
resolve_lineno
()
const
;
void
resolve_lineno
()
const
;
};
};
enum
StackWalkMode
{
// walk stack by vframeStream vfs(thread).
WALK_BY_DEFAULT
=
0
,
// walk stack by vframeStream vfs(thread, os::current_frame()).
// It is only used in JIT runtime leaf call. In JIT runtime leaf call,
// last_java_sp is not maintained and WALK_BY_DEFAULT can not walk stack.
WALK_BY_CURRENT_FRAME
};
class
JfrStackTrace
:
public
StackObj
{
class
JfrStackTrace
:
public
StackObj
{
friend
class
JfrStackTraceRepository
;
friend
class
JfrStackTraceRepository
;
private:
private:
...
@@ -72,6 +82,7 @@ class JfrStackTrace : public StackObj {
...
@@ -72,6 +82,7 @@ class JfrStackTrace : public StackObj {
bool
_reached_root
;
bool
_reached_root
;
mutable
bool
_lineno
;
mutable
bool
_lineno
;
bool
fill_in
(
vframeStream
&
vfs
,
int
skip
,
bool
leakp
,
StackWalkMode
mode
);
public:
public:
JfrStackTrace
(
JfrStackFrame
*
frames
,
u4
max_frames
)
:
_frames
(
frames
),
JfrStackTrace
(
JfrStackFrame
*
frames
,
u4
max_frames
)
:
_frames
(
frames
),
_id
(
0
),
_id
(
0
),
...
@@ -81,7 +92,7 @@ class JfrStackTrace : public StackObj {
...
@@ -81,7 +92,7 @@ class JfrStackTrace : public StackObj {
_max_frames
(
max_frames
),
_max_frames
(
max_frames
),
_lineno
(
false
)
{}
_lineno
(
false
)
{}
bool
record_thread
(
JavaThread
&
thread
,
frame
&
frame
);
bool
record_thread
(
JavaThread
&
thread
,
frame
&
frame
);
bool
record_safe
(
JavaThread
*
thread
,
int
skip
,
bool
leakp
=
fals
e
);
bool
record_safe
(
JavaThread
*
thread
,
int
skip
,
bool
leakp
,
StackWalkMode
stack_walk_mod
e
);
void
resolve_linenos
()
const
;
void
resolve_linenos
()
const
;
void
set_nr_of_frames
(
u4
nr_of_frames
)
{
_nr_of_frames
=
nr_of_frames
;
}
void
set_nr_of_frames
(
u4
nr_of_frames
)
{
_nr_of_frames
=
nr_of_frames
;
}
void
set_hash
(
unsigned
int
hash
)
{
_hash
=
hash
;
}
void
set_hash
(
unsigned
int
hash
)
{
_hash
=
hash
;
}
...
@@ -131,13 +142,13 @@ class JfrStackTraceRepository : public JfrCHeapObj {
...
@@ -131,13 +142,13 @@ class JfrStackTraceRepository : public JfrCHeapObj {
traceid
add_trace
(
const
JfrStackTrace
&
stacktrace
);
traceid
add_trace
(
const
JfrStackTrace
&
stacktrace
);
static
traceid
add
(
const
JfrStackTrace
*
stacktrace
,
JavaThread
*
thread
);
static
traceid
add
(
const
JfrStackTrace
*
stacktrace
,
JavaThread
*
thread
);
traceid
record_for
(
JavaThread
*
thread
,
int
skip
,
JfrStackFrame
*
frames
,
u4
max_frames
);
traceid
record_for
(
JavaThread
*
thread
,
int
skip
,
StackWalkMode
mode
,
JfrStackFrame
*
frames
,
u4
max_frames
);
size_t
write_impl
(
JfrChunkWriter
&
cw
,
bool
clear
);
size_t
write_impl
(
JfrChunkWriter
&
cw
,
bool
clear
);
const
StackTrace
*
resolve_entry
(
unsigned
int
hash
,
traceid
id
)
const
;
const
StackTrace
*
resolve_entry
(
unsigned
int
hash
,
traceid
id
)
const
;
static
void
write_metadata
(
JfrCheckpointWriter
&
cpw
);
static
void
write_metadata
(
JfrCheckpointWriter
&
cpw
);
static
bool
fill_stacktrace_for
(
JavaThread
*
thread
,
JfrStackTrace
*
stacktrace
,
int
skip
);
static
bool
fill_stacktrace_for
(
JavaThread
*
thread
,
JfrStackTrace
*
stacktrace
,
int
skip
,
StackWalkMode
mode
);
JfrStackTraceRepository
();
JfrStackTraceRepository
();
static
JfrStackTraceRepository
*
create
();
static
JfrStackTraceRepository
*
create
();
...
@@ -148,7 +159,7 @@ class JfrStackTraceRepository : public JfrCHeapObj {
...
@@ -148,7 +159,7 @@ class JfrStackTraceRepository : public JfrCHeapObj {
public:
public:
static
traceid
add
(
const
JfrStackTrace
&
stacktrace
);
static
traceid
add
(
const
JfrStackTrace
&
stacktrace
);
static
traceid
record
(
Thread
*
thread
,
int
skip
=
0
);
static
traceid
record
(
Thread
*
thread
,
int
skip
,
StackWalkMode
mode
);
traceid
write
(
JfrCheckpointWriter
&
cpw
,
traceid
id
,
unsigned
int
hash
);
traceid
write
(
JfrCheckpointWriter
&
cpw
,
traceid
id
,
unsigned
int
hash
);
size_t
write
(
JfrChunkWriter
&
cw
,
bool
clear
);
size_t
write
(
JfrChunkWriter
&
cw
,
bool
clear
);
size_t
clear
();
size_t
clear
();
...
...
src/share/vm/jfr/support/jfrFlush.cpp
浏览文件 @
0bb1ab9e
...
@@ -70,12 +70,12 @@ void jfr_conditional_flush(JfrEventId id, size_t size, Thread* t) {
...
@@ -70,12 +70,12 @@ void jfr_conditional_flush(JfrEventId id, size_t size, Thread* t) {
}
}
}
}
bool
jfr_save_stacktrace
(
Thread
*
t
)
{
bool
jfr_save_stacktrace
(
Thread
*
t
,
StackWalkMode
mode
)
{
JfrThreadLocal
*
const
tl
=
t
->
jfr_thread_local
();
JfrThreadLocal
*
const
tl
=
t
->
jfr_thread_local
();
if
(
tl
->
has_cached_stack_trace
())
{
if
(
tl
->
has_cached_stack_trace
())
{
return
false
;
// no ownership
return
false
;
// no ownership
}
}
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
t
));
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
t
,
0
,
mode
));
return
true
;
return
true
;
}
}
...
...
src/share/vm/jfr/support/jfrFlush.hpp
浏览文件 @
0bb1ab9e
...
@@ -27,6 +27,8 @@
...
@@ -27,6 +27,8 @@
#include "jfr/recorder/storage/jfrBuffer.hpp"
#include "jfr/recorder/storage/jfrBuffer.hpp"
#include "jfr/utilities/jfrTypes.hpp"
#include "jfr/utilities/jfrTypes.hpp"
#include "jfr/recorder/jfrEventSetting.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.hpp"
class
Thread
;
class
Thread
;
...
@@ -43,7 +45,7 @@ class JfrFlush : public StackObj {
...
@@ -43,7 +45,7 @@ class JfrFlush : public StackObj {
void
jfr_conditional_flush
(
JfrEventId
id
,
size_t
size
,
Thread
*
t
);
void
jfr_conditional_flush
(
JfrEventId
id
,
size_t
size
,
Thread
*
t
);
bool
jfr_is_event_enabled
(
JfrEventId
id
);
bool
jfr_is_event_enabled
(
JfrEventId
id
);
bool
jfr_has_stacktrace_enabled
(
JfrEventId
id
);
bool
jfr_has_stacktrace_enabled
(
JfrEventId
id
);
bool
jfr_save_stacktrace
(
Thread
*
t
);
bool
jfr_save_stacktrace
(
Thread
*
t
,
StackWalkMode
mode
);
void
jfr_clear_stacktrace
(
Thread
*
t
);
void
jfr_clear_stacktrace
(
Thread
*
t
);
template
<
typename
Event
>
template
<
typename
Event
>
...
@@ -66,7 +68,7 @@ class JfrConditionalFlushWithStacktrace : public JfrConditionalFlush<Event> {
...
@@ -66,7 +68,7 @@ class JfrConditionalFlushWithStacktrace : public JfrConditionalFlush<Event> {
public:
public:
JfrConditionalFlushWithStacktrace
(
Thread
*
t
)
:
JfrConditionalFlush
<
Event
>
(
t
),
_t
(
t
),
_owner
(
false
)
{
JfrConditionalFlushWithStacktrace
(
Thread
*
t
)
:
JfrConditionalFlush
<
Event
>
(
t
),
_t
(
t
),
_owner
(
false
)
{
if
(
this
->
_enabled
&&
Event
::
has_stacktrace
()
&&
jfr_has_stacktrace_enabled
(
Event
::
eventId
))
{
if
(
this
->
_enabled
&&
Event
::
has_stacktrace
()
&&
jfr_has_stacktrace_enabled
(
Event
::
eventId
))
{
_owner
=
jfr_save_stacktrace
(
t
);
_owner
=
jfr_save_stacktrace
(
t
,
JfrEventSetting
::
stack_walk_mode
(
Event
::
eventId
)
);
}
}
}
}
~
JfrConditionalFlushWithStacktrace
()
{
~
JfrConditionalFlushWithStacktrace
()
{
...
...
src/share/vm/jfr/support/jfrStackTraceMark.cpp
浏览文件 @
0bb1ab9e
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "precompiled.hpp"
#include "jfr/recorder/jfrEventSetting.inline.hpp"
#include "jfr/recorder/jfrEventSetting.inline.hpp"
#include "jfr/recorder/jfrEventSetting.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
#include "jfr/support/jfrStackTraceMark.hpp"
#include "jfr/support/jfrStackTraceMark.hpp"
#include "jfr/support/jfrThreadLocal.hpp"
#include "jfr/support/jfrThreadLocal.hpp"
...
@@ -35,7 +36,7 @@ JfrStackTraceMark::JfrStackTraceMark() : _t(Thread::current()), _previous_id(0),
...
@@ -35,7 +36,7 @@ JfrStackTraceMark::JfrStackTraceMark() : _t(Thread::current()), _previous_id(0),
_previous_id
=
tl
->
cached_stack_trace_id
();
_previous_id
=
tl
->
cached_stack_trace_id
();
_previous_hash
=
tl
->
cached_stack_trace_hash
();
_previous_hash
=
tl
->
cached_stack_trace_hash
();
}
}
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
Thread
::
current
()));
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
Thread
::
current
()
,
0
,
WALK_BY_DEFAULT
));
}
}
JfrStackTraceMark
::
JfrStackTraceMark
(
Thread
*
t
)
:
_t
(
t
),
_previous_id
(
0
),
_previous_hash
(
0
)
{
JfrStackTraceMark
::
JfrStackTraceMark
(
Thread
*
t
)
:
_t
(
t
),
_previous_id
(
0
),
_previous_hash
(
0
)
{
...
@@ -44,7 +45,7 @@ JfrStackTraceMark::JfrStackTraceMark(Thread* t) : _t(t), _previous_id(0), _previ
...
@@ -44,7 +45,7 @@ JfrStackTraceMark::JfrStackTraceMark(Thread* t) : _t(t), _previous_id(0), _previ
_previous_id
=
tl
->
cached_stack_trace_id
();
_previous_id
=
tl
->
cached_stack_trace_id
();
_previous_hash
=
tl
->
cached_stack_trace_hash
();
_previous_hash
=
tl
->
cached_stack_trace_hash
();
}
}
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
t
));
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
t
,
0
,
WALK_BY_DEFAULT
));
}
}
JfrStackTraceMark
::
JfrStackTraceMark
(
JfrEventId
eventId
)
:
_t
(
NULL
),
_previous_id
(
0
),
_previous_hash
(
0
)
{
JfrStackTraceMark
::
JfrStackTraceMark
(
JfrEventId
eventId
)
:
_t
(
NULL
),
_previous_id
(
0
),
_previous_hash
(
0
)
{
...
@@ -55,7 +56,8 @@ JfrStackTraceMark::JfrStackTraceMark(JfrEventId eventId) : _t(NULL), _previous_i
...
@@ -55,7 +56,8 @@ JfrStackTraceMark::JfrStackTraceMark(JfrEventId eventId) : _t(NULL), _previous_i
_previous_id
=
tl
->
cached_stack_trace_id
();
_previous_id
=
tl
->
cached_stack_trace_id
();
_previous_hash
=
tl
->
cached_stack_trace_hash
();
_previous_hash
=
tl
->
cached_stack_trace_hash
();
}
}
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
_t
));
StackWalkMode
mode
=
JfrEventSetting
::
stack_walk_mode
(
eventId
);
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
_t
,
0
,
mode
));
}
}
}
}
...
@@ -67,7 +69,8 @@ JfrStackTraceMark::JfrStackTraceMark(JfrEventId eventId, Thread* t) : _t(NULL),
...
@@ -67,7 +69,8 @@ JfrStackTraceMark::JfrStackTraceMark(JfrEventId eventId, Thread* t) : _t(NULL),
_previous_id
=
tl
->
cached_stack_trace_id
();
_previous_id
=
tl
->
cached_stack_trace_id
();
_previous_hash
=
tl
->
cached_stack_trace_hash
();
_previous_hash
=
tl
->
cached_stack_trace_hash
();
}
}
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
_t
));
StackWalkMode
mode
=
JfrEventSetting
::
stack_walk_mode
(
eventId
);
tl
->
set_cached_stack_trace_id
(
JfrStackTraceRepository
::
record
(
_t
,
0
,
mode
));
}
}
}
}
...
...
src/share/vm/jfr/support/jfrThreadLocal.cpp
浏览文件 @
0bb1ab9e
...
@@ -55,7 +55,11 @@ JfrThreadLocal::JfrThreadLocal() :
...
@@ -55,7 +55,11 @@ JfrThreadLocal::JfrThreadLocal() :
_stack_trace_hash
(
0
),
_stack_trace_hash
(
0
),
_stackdepth
(
0
),
_stackdepth
(
0
),
_entering_suspend_flag
(
0
),
_entering_suspend_flag
(
0
),
_dead
(
false
)
{}
_dead
(
false
),
_cached_top_frame_bci
(
max_jint
),
_alloc_count
(
0
),
_alloc_count_until_sample
(
1
),
_cached_event_id
(
MaxJfrEventId
)
{}
u8
JfrThreadLocal
::
add_data_lost
(
u8
value
)
{
u8
JfrThreadLocal
::
add_data_lost
(
u8
value
)
{
_data_lost
+=
value
;
_data_lost
+=
value
;
...
...
src/share/vm/jfr/support/jfrThreadLocal.hpp
浏览文件 @
0bb1ab9e
...
@@ -51,6 +51,27 @@ class JfrThreadLocal {
...
@@ -51,6 +51,27 @@ class JfrThreadLocal {
mutable
u4
_stackdepth
;
mutable
u4
_stackdepth
;
volatile
jint
_entering_suspend_flag
;
volatile
jint
_entering_suspend_flag
;
bool
_dead
;
bool
_dead
;
// Jfr callstack collection relies on vframeStream.
// But the bci of top frame can not be determined by vframeStream in some scenarios.
// For example, in the opto CallLeafNode runtime call of
// OptoRuntime::jfr_fast_object_alloc_C, the top frame bci
// returned by vframeStream is always invalid. This is largely due to the oopmap that
// is not correctly granted ( refer to PhaseMacroExpand::expand_allocate_common to get more details ).
// The opto fast path object allocation tracing occurs in the opto CallLeafNode,
// which has been broken by invalid top frame bci.
// To fix this, we get the top frame bci in opto compilation phase
// and pass it as parameter to runtime call. Our implementation will replace the invalid top
// frame bci with cached_top_frame_bci.
jint
_cached_top_frame_bci
;
jlong
_alloc_count
;
jlong
_alloc_count_until_sample
;
// This field is used to help to distinguish the object allocation request source.
// For example, for object allocation slow path, we trace it in CollectedHeap::obj_allocate.
// But in CollectedHeap::obj_allocate, it is impossible to determine where the allocation request
// is from, which could be from c1, opto, or even interpreter.
// We save this infomation in _event_id, which later can be retrieved in
// CollecetedHeap::obj_allocate to identify the real allocation request source.
JfrEventId
_cached_event_id
;
JfrBuffer
*
install_native_buffer
()
const
;
JfrBuffer
*
install_native_buffer
()
const
;
JfrBuffer
*
install_java_buffer
()
const
;
JfrBuffer
*
install_java_buffer
()
const
;
...
@@ -207,6 +228,54 @@ class JfrThreadLocal {
...
@@ -207,6 +228,54 @@ class JfrThreadLocal {
return
_dead
;
return
_dead
;
}
}
void
set_cached_top_frame_bci
(
jint
bci
)
{
_cached_top_frame_bci
=
bci
;
}
bool
has_cached_top_frame_bci
()
const
{
return
_cached_top_frame_bci
!=
max_jint
;
}
jint
cached_top_frame_bci
()
const
{
return
_cached_top_frame_bci
;
}
void
clear_cached_top_frame_bci
()
{
_cached_top_frame_bci
=
max_jint
;
}
jlong
alloc_count
()
const
{
return
_alloc_count
;
}
void
incr_alloc_count
(
jlong
delta
)
{
_alloc_count
+=
delta
;
}
jlong
alloc_count_until_sample
()
const
{
return
_alloc_count_until_sample
;
}
void
incr_alloc_count_until_sample
(
jlong
delta
)
{
_alloc_count_until_sample
+=
delta
;
}
void
set_cached_event_id
(
JfrEventId
event_id
)
{
_cached_event_id
=
event_id
;
}
JfrEventId
cached_event_id
()
const
{
return
_cached_event_id
;
}
bool
has_cached_event_id
()
const
{
return
_cached_event_id
!=
MaxJfrEventId
;
}
void
clear_cached_event_id
()
{
_cached_event_id
=
MaxJfrEventId
;
}
bool
has_thread_checkpoint
()
const
;
bool
has_thread_checkpoint
()
const
;
void
set_thread_checkpoint
(
const
JfrCheckpointBlobHandle
&
handle
);
void
set_thread_checkpoint
(
const
JfrCheckpointBlobHandle
&
handle
);
const
JfrCheckpointBlobHandle
&
thread_checkpoint
()
const
;
const
JfrCheckpointBlobHandle
&
thread_checkpoint
()
const
;
...
@@ -217,6 +286,9 @@ class JfrThreadLocal {
...
@@ -217,6 +286,9 @@ class JfrThreadLocal {
// Code generation
// Code generation
static
ByteSize
trace_id_offset
();
static
ByteSize
trace_id_offset
();
static
ByteSize
java_event_writer_offset
();
static
ByteSize
java_event_writer_offset
();
TRACE_DEFINE_THREAD_ALLOC_COUNT_UNTIL_SAMPLE_OFFSET
;
TRACE_DEFINE_THREAD_ALLOC_COUNT_OFFSET
;
};
};
#endif // SHARE_VM_JFR_SUPPORT_JFRTHREADLOCAL_HPP
#endif // SHARE_VM_JFR_SUPPORT_JFRTHREADLOCAL_HPP
src/share/vm/jfr/support/jfrTraceIdExtension.hpp
浏览文件 @
0bb1ab9e
...
@@ -78,4 +78,24 @@ class JfrTraceFlag {
...
@@ -78,4 +78,24 @@ class JfrTraceFlag {
return _trace_flags.flags_addr(); \
return _trace_flags.flags_addr(); \
}
}
#define ARRAY_OBJECT_SIZE_PLACE_HOLDER 0x1111baba
#define TRACE_OPTO_SLOW_ALLOCATION_ENTER(is_array, thread) \
AllocTracer::opto_slow_allocation_enter(is_array, thread)
#define TRACE_OPTO_SLOW_ALLOCATION_LEAVE(is_array, thread) \
AllocTracer::opto_slow_allocation_leave(is_array, thread)
#define TRACE_SLOW_ALLOCATION(klass, obj, alloc_size, thread) \
AllocTracer::send_slow_allocation_event(klass, obj, alloc_size, thread)
#define TRACE_DEFINE_THREAD_ALLOC_COUNT_OFFSET \
static ByteSize alloc_count_offset() { return in_ByteSize(offset_of(JfrThreadLocal, _alloc_count)); }
#define TRACE_THREAD_ALLOC_COUNT_OFFSET \
(JfrThreadLocal::alloc_count_offset() + Thread::jfr_thread_local_offset())
#define TRACE_DEFINE_THREAD_ALLOC_COUNT_UNTIL_SAMPLE_OFFSET \
static ByteSize alloc_count_until_sample_offset() { return in_ByteSize(offset_of(JfrThreadLocal, _alloc_count_until_sample)); }
#define TRACE_THREAD_ALLOC_COUNT_UNTIL_SAMPLE_OFFSET \
(JfrThreadLocal::alloc_count_until_sample_offset() + Thread::jfr_thread_local_offset())
#endif // SHARE_VM_JFR_SUPPORT_JFRTRACEIDEXTENSION_HPP
#endif // SHARE_VM_JFR_SUPPORT_JFRTRACEIDEXTENSION_HPP
src/share/vm/opto/macro.cpp
浏览文件 @
0bb1ab9e
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "libadt/vectset.hpp"
#include "libadt/vectset.hpp"
#include "opto/addnode.hpp"
#include "opto/addnode.hpp"
#include "opto/callnode.hpp"
#include "opto/callnode.hpp"
#include "opto/divnode.hpp"
#include "opto/cfgnode.hpp"
#include "opto/cfgnode.hpp"
#include "opto/compile.hpp"
#include "opto/compile.hpp"
#include "opto/connode.hpp"
#include "opto/connode.hpp"
...
@@ -41,6 +42,7 @@
...
@@ -41,6 +42,7 @@
#include "opto/subnode.hpp"
#include "opto/subnode.hpp"
#include "opto/type.hpp"
#include "opto/type.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/sharedRuntime.hpp"
#include "jfr/objectprofiler/objectProfiler.hpp"
//
//
...
@@ -1087,15 +1089,21 @@ void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_ad
...
@@ -1087,15 +1089,21 @@ void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_ad
}
}
}
}
Node
*
PhaseMacroExpand
::
load
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
const
Type
*
value_type
,
BasicType
bt
,
MemNode
::
MemOrd
mo
)
{
Node
*
PhaseMacroExpand
::
make_load
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
const
Type
*
value_type
,
BasicType
bt
)
{
Node
*
adr
=
basic_plus_adr
(
base
,
offset
);
Node
*
adr
=
basic_plus_adr
(
base
,
offset
);
const
TypePtr
*
adr_type
=
adr
->
bottom_type
()
->
is_ptr
();
const
TypePtr
*
adr_type
=
adr
->
bottom_type
()
->
is_ptr
();
Node
*
value
=
LoadNode
::
make
(
_igvn
,
ctl
,
mem
,
adr
,
adr_type
,
value_type
,
bt
,
MemNode
::
unordered
);
Node
*
value
=
LoadNode
::
make
(
_igvn
,
ctl
,
mem
,
adr
,
adr_type
,
value_type
,
bt
,
mo
);
transform_later
(
value
);
transform_later
(
value
);
return
value
;
return
value
;
}
}
Node
*
PhaseMacroExpand
::
make_load
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
const
Type
*
value_type
,
BasicType
bt
)
{
return
load
(
ctl
,
mem
,
base
,
offset
,
value_type
,
bt
,
MemNode
::
unordered
);
}
Node
*
PhaseMacroExpand
::
make_load_acquire
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
const
Type
*
value_type
,
BasicType
bt
)
{
return
load
(
ctl
,
mem
,
base
,
offset
,
value_type
,
bt
,
MemNode
::
acquire
);
}
Node
*
PhaseMacroExpand
::
make_store
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
Node
*
value
,
BasicType
bt
)
{
Node
*
PhaseMacroExpand
::
make_store
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
Node
*
value
,
BasicType
bt
)
{
Node
*
adr
=
basic_plus_adr
(
base
,
offset
);
Node
*
adr
=
basic_plus_adr
(
base
,
offset
);
...
@@ -1434,6 +1442,12 @@ void PhaseMacroExpand::expand_allocate_common(
...
@@ -1434,6 +1442,12 @@ void PhaseMacroExpand::expand_allocate_common(
}
}
}
}
#if INCLUDE_JFR
if
(
JfrOptionSet
::
sample_object_allocations
())
{
jfr_sample_fast_object_allocation
(
alloc
,
fast_oop
,
fast_oop_ctrl
,
fast_oop_rawmem
);
}
#endif // INCLUDE_JFR
if
(
C
->
env
()
->
dtrace_extended_probes
())
{
if
(
C
->
env
()
->
dtrace_extended_probes
())
{
// Slow-path call
// Slow-path call
int
size
=
TypeFunc
::
Parms
+
2
;
int
size
=
TypeFunc
::
Parms
+
2
;
...
@@ -1619,6 +1633,116 @@ void PhaseMacroExpand::expand_allocate_common(
...
@@ -1619,6 +1633,116 @@ void PhaseMacroExpand::expand_allocate_common(
// This completes all paths into the result merge point
// This completes all paths into the result merge point
}
}
#if INCLUDE_JFR
static
jint
bottom_java_frame_bci
(
JVMState
*
state
)
{
assert
(
state
!=
NULL
,
"Invariant"
);
JVMState
*
last
=
NULL
;
JVMState
*
current
=
state
;
while
(
current
!=
NULL
)
{
last
=
current
;
current
=
current
->
caller
();
}
return
last
->
bci
();
}
//
// Pseudo code:
//
// int alloc_sample_enabled = *(int *)ObjectProfiler::enabled_flag_address();
// if (alloc_sample_enabled) {
// long alloc_count = thread->jfr_thread_local()->alloc_count();
// long alloc_count_new = alloc_count + 1;
// thread->jfr_thread_local()->set_alloc_count(alloc_count_new);
// long alloc_count_until_sample = thread->jfr_thread_local()->alloc_count_until_sample();
// if (alloc_count_until_sample == alloc_count_new) {
// jfr_fast_object_alloc_C(obj, thread);
// }
// }
void
PhaseMacroExpand
::
jfr_sample_fast_object_allocation
(
AllocateNode
*
alloc
,
Node
*
fast_oop
,
Node
*&
fast_oop_ctrl
,
Node
*&
fast_oop_rawmem
)
{
Node
*
tls
=
transform_later
(
new
(
C
)
ThreadLocalNode
());
Node
*
alloc_sample_enabled_addr
=
transform_later
(
ConPNode
::
make
(
C
,
(
address
)
ObjectProfiler
::
enabled_flag_address
()));
Node
*
alloc_sample_enabled
=
make_load_acquire
(
fast_oop_ctrl
,
fast_oop_rawmem
,
alloc_sample_enabled_addr
,
0
,
TypeInt
::
INT
,
T_INT
);
Node
*
alloc_sample_enabled_cmp
=
transform_later
(
new
(
C
)
CmpINode
(
alloc_sample_enabled
,
intcon
(
1
)));
Node
*
alloc_sample_enabled_bool
=
transform_later
(
new
(
C
)
BoolNode
(
alloc_sample_enabled_cmp
,
BoolTest
::
eq
));
IfNode
*
alloc_sample_enabled_if
=
(
IfNode
*
)
transform_later
(
new
(
C
)
IfNode
(
fast_oop_ctrl
,
alloc_sample_enabled_bool
,
PROB_MIN
,
COUNT_UNKNOWN
));
Node
*
alloc_sample_enabled_ctrl
=
transform_later
(
new
(
C
)
IfTrueNode
(
alloc_sample_enabled_if
));
Node
*
alloc_sample_enabled_mem
=
fast_oop_rawmem
;
Node
*
alloc_sample_disabled_ctrl
=
transform_later
(
new
(
C
)
IfFalseNode
(
alloc_sample_enabled_if
));
Node
*
alloc_sample_disabled_mem
=
fast_oop_rawmem
;
Node
*
alloc_sample_enabled_region
=
transform_later
(
new
(
C
)
RegionNode
(
3
));
Node
*
alloc_sample_enabled_region_phi_mem
=
transform_later
(
new
(
C
)
PhiNode
(
alloc_sample_enabled_region
,
Type
::
MEMORY
,
TypeRawPtr
::
BOTTOM
));
enum
{
enabled_idx
=
1
,
disabled_idx
=
2
};
// if _enabled then
{
const
int
alloc_count_offset
=
in_bytes
(
TRACE_THREAD_ALLOC_COUNT_OFFSET
);
Node
*
alloc_count
=
make_load
(
alloc_sample_enabled_ctrl
,
alloc_sample_enabled_mem
,
tls
,
alloc_count_offset
,
TypeLong
::
LONG
,
T_LONG
);
Node
*
alloc_count_new
=
transform_later
(
new
(
C
)
AddLNode
(
alloc_count
,
longcon
(
1
)));
alloc_sample_enabled_mem
=
make_store
(
alloc_sample_enabled_ctrl
,
alloc_sample_enabled_mem
,
tls
,
alloc_count_offset
,
alloc_count_new
,
T_LONG
);
const
int
alloc_count_until_sample_offset
=
in_bytes
(
TRACE_THREAD_ALLOC_COUNT_UNTIL_SAMPLE_OFFSET
);
Node
*
alloc_count_until_sample
=
make_load
(
alloc_sample_enabled_ctrl
,
alloc_sample_enabled_mem
,
tls
,
alloc_count_until_sample_offset
,
TypeLong
::
LONG
,
T_LONG
);
Node
*
alloc_count_until_sample_cmp
=
transform_later
(
new
(
C
)
CmpLNode
(
alloc_count_until_sample
,
alloc_count_new
));
Node
*
alloc_sample_hit_bool
=
transform_later
(
new
(
C
)
BoolNode
(
alloc_count_until_sample_cmp
,
BoolTest
::
eq
));
IfNode
*
alloc_sample_hit_if
=
(
IfNode
*
)
transform_later
(
new
(
C
)
IfNode
(
alloc_sample_enabled_ctrl
,
alloc_sample_hit_bool
,
PROB_MIN
,
COUNT_UNKNOWN
));
Node
*
alloc_sample_hit_ctrl
=
transform_later
(
new
(
C
)
IfTrueNode
(
alloc_sample_hit_if
));
Node
*
alloc_sample_hit_mem
=
alloc_sample_enabled_mem
;
Node
*
alloc_sample_miss_ctrl
=
transform_later
(
new
(
C
)
IfFalseNode
(
alloc_sample_hit_if
));
Node
*
alloc_sample_miss_mem
=
alloc_sample_enabled_mem
;
Node
*
alloc_sample_hit_region
=
transform_later
(
new
(
C
)
RegionNode
(
3
));
Node
*
alloc_sample_hit_region_phi_mem
=
transform_later
(
new
(
C
)
PhiNode
(
alloc_sample_hit_region
,
Type
::
MEMORY
,
TypeRawPtr
::
BOTTOM
));
// if sample_hit then
{
CallLeafNode
*
call
=
new
(
C
)
CallLeafNode
(
OptoRuntime
::
jfr_fast_object_alloc_Type
(),
CAST_FROM_FN_PTR
(
address
,
OptoRuntime
::
jfr_fast_object_alloc_C
),
"jfr_fast_object_alloc_C"
,
TypeRawPtr
::
BOTTOM
);
call
->
init_req
(
TypeFunc
::
Parms
+
0
,
fast_oop
);
call
->
init_req
(
TypeFunc
::
Parms
+
1
,
intcon
(
bottom_java_frame_bci
(
alloc
->
jvms
())));
call
->
init_req
(
TypeFunc
::
Parms
+
2
,
tls
);
call
->
init_req
(
TypeFunc
::
Control
,
alloc_sample_hit_ctrl
);
call
->
init_req
(
TypeFunc
::
I_O
,
top
());
call
->
init_req
(
TypeFunc
::
Memory
,
alloc_sample_hit_mem
);
call
->
init_req
(
TypeFunc
::
ReturnAdr
,
alloc
->
in
(
TypeFunc
::
ReturnAdr
));
call
->
init_req
(
TypeFunc
::
FramePtr
,
alloc
->
in
(
TypeFunc
::
FramePtr
));
transform_later
(
call
);
alloc_sample_hit_ctrl
=
new
(
C
)
ProjNode
(
call
,
TypeFunc
::
Control
);
transform_later
(
alloc_sample_hit_ctrl
);
alloc_sample_hit_mem
=
new
(
C
)
ProjNode
(
call
,
TypeFunc
::
Memory
);
transform_later
(
alloc_sample_hit_mem
);
alloc_sample_hit_region
->
init_req
(
enabled_idx
,
alloc_sample_hit_ctrl
);
alloc_sample_hit_region_phi_mem
->
init_req
(
enabled_idx
,
alloc_sample_hit_mem
);
}
{
alloc_sample_hit_region
->
init_req
(
disabled_idx
,
alloc_sample_miss_ctrl
);
alloc_sample_hit_region_phi_mem
->
init_req
(
disabled_idx
,
alloc_sample_miss_mem
);
}
{
alloc_sample_enabled_ctrl
=
alloc_sample_hit_region
;
alloc_sample_enabled_mem
=
alloc_sample_hit_region_phi_mem
;
}
alloc_sample_enabled_region
->
init_req
(
enabled_idx
,
alloc_sample_enabled_ctrl
);
alloc_sample_enabled_region_phi_mem
->
init_req
(
enabled_idx
,
alloc_sample_enabled_mem
);
}
{
alloc_sample_enabled_region
->
init_req
(
disabled_idx
,
alloc_sample_disabled_ctrl
);
alloc_sample_enabled_region_phi_mem
->
init_req
(
disabled_idx
,
alloc_sample_disabled_mem
);
}
{
fast_oop_ctrl
=
alloc_sample_enabled_region
;
fast_oop_rawmem
=
alloc_sample_enabled_region_phi_mem
;
}
}
#endif // INCLUDE_JFR
// Helper for PhaseMacroExpand::expand_allocate_common.
// Helper for PhaseMacroExpand::expand_allocate_common.
// Initializes the newly-allocated storage.
// Initializes the newly-allocated storage.
...
...
src/share/vm/opto/macro.hpp
浏览文件 @
0bb1ab9e
...
@@ -61,8 +61,12 @@ private:
...
@@ -61,8 +61,12 @@ private:
return
n
;
return
n
;
}
}
void
set_eden_pointers
(
Node
*
&
eden_top_adr
,
Node
*
&
eden_end_adr
);
void
set_eden_pointers
(
Node
*
&
eden_top_adr
,
Node
*
&
eden_end_adr
);
Node
*
load
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
const
Type
*
value_type
,
BasicType
bt
,
MemNode
::
MemOrd
mo
);
Node
*
make_load
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
Node
*
make_load
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
const
Type
*
value_type
,
BasicType
bt
);
const
Type
*
value_type
,
BasicType
bt
);
Node
*
make_load_acquire
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
const
Type
*
value_type
,
BasicType
bt
);
Node
*
make_store
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
Node
*
make_store
(
Node
*
ctl
,
Node
*
mem
,
Node
*
base
,
int
offset
,
Node
*
value
,
BasicType
bt
);
Node
*
value
,
BasicType
bt
);
...
@@ -119,6 +123,10 @@ private:
...
@@ -119,6 +123,10 @@ private:
Node
*
old_eden_top
,
Node
*
new_eden_top
,
Node
*
old_eden_top
,
Node
*
new_eden_top
,
Node
*
length
);
Node
*
length
);
//JFR tracing
void
jfr_sample_fast_object_allocation
(
AllocateNode
*
alloc
,
Node
*
fast_oop
,
Node
*&
fast_oop_ctrl
,
Node
*&
fast_oop_rawmem
);
public:
public:
PhaseMacroExpand
(
PhaseIterGVN
&
igvn
)
:
Phase
(
Macro_Expand
),
_igvn
(
igvn
),
_has_locks
(
false
)
{
PhaseMacroExpand
(
PhaseIterGVN
&
igvn
)
:
Phase
(
Macro_Expand
),
_igvn
(
igvn
),
_has_locks
(
false
)
{
_igvn
.
set_delay_transform
(
true
);
_igvn
.
set_delay_transform
(
true
);
...
...
src/share/vm/opto/runtime.cpp
浏览文件 @
0bb1ab9e
...
@@ -68,6 +68,7 @@
...
@@ -68,6 +68,7 @@
#include "runtime/vframe_hp.hpp"
#include "runtime/vframe_hp.hpp"
#include "utilities/copy.hpp"
#include "utilities/copy.hpp"
#include "utilities/preserveException.hpp"
#include "utilities/preserveException.hpp"
#include "gc_interface/allocTracer.inline.hpp"
#if defined AD_MD_HPP
#if defined AD_MD_HPP
# include AD_MD_HPP
# include AD_MD_HPP
#elif defined TARGET_ARCH_MODEL_x86_32
#elif defined TARGET_ARCH_MODEL_x86_32
...
@@ -260,8 +261,10 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* thre
...
@@ -260,8 +261,10 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* thre
if
(
!
HAS_PENDING_EXCEPTION
)
{
if
(
!
HAS_PENDING_EXCEPTION
)
{
// Scavenge and allocate an instance.
// Scavenge and allocate an instance.
Handle
holder
(
THREAD
,
klass
->
klass_holder
());
// keep the klass alive
Handle
holder
(
THREAD
,
klass
->
klass_holder
());
// keep the klass alive
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_ENTER
(
false
,
THREAD
);)
oop
result
=
InstanceKlass
::
cast
(
klass
)
->
allocate_instance
(
THREAD
);
oop
result
=
InstanceKlass
::
cast
(
klass
)
->
allocate_instance
(
THREAD
);
thread
->
set_vm_result
(
result
);
thread
->
set_vm_result
(
result
);
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_LEAVE
(
false
,
THREAD
);)
// Pass oops back through thread local storage. Our apparent type to Java
// Pass oops back through thread local storage. Our apparent type to Java
// is that we return an oop, but we can block on exit from this routine and
// is that we return an oop, but we can block on exit from this routine and
...
@@ -290,6 +293,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaT
...
@@ -290,6 +293,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaT
// Scavenge and allocate an instance.
// Scavenge and allocate an instance.
oop
result
;
oop
result
;
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_ENTER
(
true
,
THREAD
);)
if
(
array_type
->
oop_is_typeArray
())
{
if
(
array_type
->
oop_is_typeArray
())
{
// The oopFactory likes to work with the element type.
// The oopFactory likes to work with the element type.
// (We could bypass the oopFactory, since it doesn't add much value.)
// (We could bypass the oopFactory, since it doesn't add much value.)
...
@@ -303,6 +307,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaT
...
@@ -303,6 +307,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaT
Klass
*
elem_type
=
ObjArrayKlass
::
cast
(
array_type
)
->
element_klass
();
Klass
*
elem_type
=
ObjArrayKlass
::
cast
(
array_type
)
->
element_klass
();
result
=
oopFactory
::
new_objArray
(
elem_type
,
len
,
THREAD
);
result
=
oopFactory
::
new_objArray
(
elem_type
,
len
,
THREAD
);
}
}
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_LEAVE
(
true
,
THREAD
);)
// Pass oops back through thread local storage. Our apparent type to Java
// Pass oops back through thread local storage. Our apparent type to Java
// is that we return an oop, but we can block on exit from this routine and
// is that we return an oop, but we can block on exit from this routine and
...
@@ -329,10 +334,12 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len
...
@@ -329,10 +334,12 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len
// Scavenge and allocate an instance.
// Scavenge and allocate an instance.
oop
result
;
oop
result
;
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_ENTER
(
true
,
THREAD
);)
assert
(
array_type
->
oop_is_typeArray
(),
"should be called only for type array"
);
assert
(
array_type
->
oop_is_typeArray
(),
"should be called only for type array"
);
// The oopFactory likes to work with the element type.
// The oopFactory likes to work with the element type.
BasicType
elem_type
=
TypeArrayKlass
::
cast
(
array_type
)
->
element_type
();
BasicType
elem_type
=
TypeArrayKlass
::
cast
(
array_type
)
->
element_type
();
result
=
oopFactory
::
new_typeArray_nozero
(
elem_type
,
len
,
THREAD
);
result
=
oopFactory
::
new_typeArray_nozero
(
elem_type
,
len
,
THREAD
);
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_LEAVE
(
true
,
THREAD
);)
// Pass oops back through thread local storage. Our apparent type to Java
// Pass oops back through thread local storage. Our apparent type to Java
// is that we return an oop, but we can block on exit from this routine and
// is that we return an oop, but we can block on exit from this routine and
...
@@ -379,7 +386,9 @@ JRT_ENTRY(void, OptoRuntime::multianewarray2_C(Klass* elem_type, int len1, int l
...
@@ -379,7 +386,9 @@ JRT_ENTRY(void, OptoRuntime::multianewarray2_C(Klass* elem_type, int len1, int l
dims
[
0
]
=
len1
;
dims
[
0
]
=
len1
;
dims
[
1
]
=
len2
;
dims
[
1
]
=
len2
;
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_ENTER
(
true
,
THREAD
);)
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
2
,
dims
,
THREAD
);
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
2
,
dims
,
THREAD
);
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_LEAVE
(
true
,
THREAD
);)
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
thread
->
set_vm_result
(
obj
);
thread
->
set_vm_result
(
obj
);
JRT_END
JRT_END
...
@@ -396,7 +405,9 @@ JRT_ENTRY(void, OptoRuntime::multianewarray3_C(Klass* elem_type, int len1, int l
...
@@ -396,7 +405,9 @@ JRT_ENTRY(void, OptoRuntime::multianewarray3_C(Klass* elem_type, int len1, int l
dims
[
1
]
=
len2
;
dims
[
1
]
=
len2
;
dims
[
2
]
=
len3
;
dims
[
2
]
=
len3
;
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_ENTER
(
true
,
THREAD
);)
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
3
,
dims
,
THREAD
);
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
3
,
dims
,
THREAD
);
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_LEAVE
(
true
,
THREAD
);)
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
thread
->
set_vm_result
(
obj
);
thread
->
set_vm_result
(
obj
);
JRT_END
JRT_END
...
@@ -414,7 +425,9 @@ JRT_ENTRY(void, OptoRuntime::multianewarray4_C(Klass* elem_type, int len1, int l
...
@@ -414,7 +425,9 @@ JRT_ENTRY(void, OptoRuntime::multianewarray4_C(Klass* elem_type, int len1, int l
dims
[
2
]
=
len3
;
dims
[
2
]
=
len3
;
dims
[
3
]
=
len4
;
dims
[
3
]
=
len4
;
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_ENTER
(
true
,
THREAD
);)
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
4
,
dims
,
THREAD
);
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
4
,
dims
,
THREAD
);
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_LEAVE
(
true
,
THREAD
);)
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
thread
->
set_vm_result
(
obj
);
thread
->
set_vm_result
(
obj
);
JRT_END
JRT_END
...
@@ -451,7 +464,9 @@ JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* d
...
@@ -451,7 +464,9 @@ JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* d
Copy
::
conjoint_jints_atomic
(
j_dims
,
c_dims
,
len
);
Copy
::
conjoint_jints_atomic
(
j_dims
,
c_dims
,
len
);
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_ENTER
(
true
,
THREAD
);)
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
len
,
c_dims
,
THREAD
);
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
len
,
c_dims
,
THREAD
);
JFR_ONLY
(
TRACE_OPTO_SLOW_ALLOCATION_LEAVE
(
true
,
THREAD
);)
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
thread
->
set_vm_result
(
obj
);
thread
->
set_vm_result
(
obj
);
JRT_END
JRT_END
...
@@ -1677,3 +1692,34 @@ JRT_LEAF(void, OptoRuntime::zap_dead_native_locals_C(JavaThread* thread))
...
@@ -1677,3 +1692,34 @@ JRT_LEAF(void, OptoRuntime::zap_dead_native_locals_C(JavaThread* thread))
JRT_END
JRT_END
# endif
# endif
#if INCLUDE_JFR
//-----------------------------------------------------------------------------
// JFR support.
const
TypeFunc
*
OptoRuntime
::
jfr_fast_object_alloc_Type
()
{
const
Type
**
fields
=
TypeTuple
::
fields
(
3
);
fields
[
TypeFunc
::
Parms
+
0
]
=
TypeRawPtr
::
BOTTOM
;
// newly allocated object
fields
[
TypeFunc
::
Parms
+
1
]
=
TypeInt
::
INT
;
// bci
fields
[
TypeFunc
::
Parms
+
2
]
=
TypeRawPtr
::
BOTTOM
;
// tls
const
TypeTuple
*
domain
=
TypeTuple
::
make
(
TypeFunc
::
Parms
+
3
,
fields
);
// create result type (range)
fields
=
TypeTuple
::
fields
(
1
);
fields
[
TypeFunc
::
Parms
+
0
]
=
TypeRawPtr
::
BOTTOM
;
// returned oop
const
TypeTuple
*
range
=
TypeTuple
::
make
(
TypeFunc
::
Parms
+
1
,
fields
);
return
TypeFunc
::
make
(
domain
,
range
);
}
void
OptoRuntime
::
jfr_fast_object_alloc_C
(
oopDesc
*
obj
,
jint
top_frame_bci
,
JavaThread
*
thread
)
{
KlassHandle
kh
(
thread
,
obj
->
klass
());
assert
(
obj
!=
NULL
,
"invariant"
);
assert
(
obj
->
klass
()
!=
NULL
,
"invariant"
);
thread
->
jfr_thread_local
()
->
set_cached_top_frame_bci
(
top_frame_bci
);
AllocTracer
::
send_opto_fast_allocation_event
(
kh
,
obj
,
obj
->
size
()
*
HeapWordSize
,
thread
);
thread
->
jfr_thread_local
()
->
clear_cached_top_frame_bci
();
thread
->
set_vm_result
(
obj
);
}
#endif // INCLUDE_JFR
src/share/vm/opto/runtime.hpp
浏览文件 @
0bb1ab9e
...
@@ -179,6 +179,8 @@ public:
...
@@ -179,6 +179,8 @@ public:
static
void
complete_monitor_locking_C
(
oopDesc
*
obj
,
BasicLock
*
lock
,
JavaThread
*
thread
);
static
void
complete_monitor_locking_C
(
oopDesc
*
obj
,
BasicLock
*
lock
,
JavaThread
*
thread
);
static
void
complete_monitor_unlocking_C
(
oopDesc
*
obj
,
BasicLock
*
lock
);
static
void
complete_monitor_unlocking_C
(
oopDesc
*
obj
,
BasicLock
*
lock
);
// JFR support
static
void
jfr_fast_object_alloc_C
(
oopDesc
*
obj
,
jint
bci
,
JavaThread
*
thread
);
private:
private:
// Implicit exception support
// Implicit exception support
...
@@ -339,6 +341,9 @@ private:
...
@@ -339,6 +341,9 @@ private:
static
const
TypeFunc
*
zap_dead_locals_Type
();
static
const
TypeFunc
*
zap_dead_locals_Type
();
# endif
# endif
// JFR support
static
const
TypeFunc
*
jfr_fast_object_alloc_Type
();
private:
private:
static
NamedCounter
*
volatile
_named_counters
;
static
NamedCounter
*
volatile
_named_counters
;
...
...
src/share/vm/precompiled/precompiled.hpp
浏览文件 @
0bb1ab9e
...
@@ -97,6 +97,8 @@
...
@@ -97,6 +97,8 @@
# include "gc_interface/collectedHeap.hpp"
# include "gc_interface/collectedHeap.hpp"
# include "gc_interface/collectedHeap.inline.hpp"
# include "gc_interface/collectedHeap.inline.hpp"
# include "gc_interface/gcCause.hpp"
# include "gc_interface/gcCause.hpp"
# include "gc_interface/allocTracer.hpp"
# include "gc_interface/allocTracer.inline.hpp"
# include "interpreter/abstractInterpreter.hpp"
# include "interpreter/abstractInterpreter.hpp"
# include "interpreter/bytecode.hpp"
# include "interpreter/bytecode.hpp"
# include "interpreter/bytecodeHistogram.hpp"
# include "interpreter/bytecodeHistogram.hpp"
...
...
src/share/vm/runtime/vframe.hpp
浏览文件 @
0bb1ab9e
...
@@ -367,6 +367,8 @@ class vframeStream : public vframeStreamCommon {
...
@@ -367,6 +367,8 @@ class vframeStream : public vframeStreamCommon {
}
}
}
}
Thread
*&
thread_ref
()
{
return
(
Thread
*&
)
_thread
;
}
// top_frame may not be at safepoint, start with sender
// top_frame may not be at safepoint, start with sender
vframeStream
(
JavaThread
*
thread
,
frame
top_frame
,
bool
stop_at_java_call_stub
=
false
);
vframeStream
(
JavaThread
*
thread
,
frame
top_frame
,
bool
stop_at_java_call_stub
=
false
);
};
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录