Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
9d513174
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看板
提交
9d513174
编写于
7月 15, 2010
作者:
N
never
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
4a141040
f4f1f417
变更
34
隐藏空白更改
内联
并排
Showing
34 changed file
with
378 addition
and
857 deletion
+378
-857
agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java
agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java
+0
-2
src/cpu/x86/vm/vm_version_x86.hpp
src/cpu/x86/vm/vm_version_x86.hpp
+9
-2
src/os/linux/vm/vtune_linux.cpp
src/os/linux/vm/vtune_linux.cpp
+0
-45
src/os/solaris/vm/vtune_solaris.cpp
src/os/solaris/vm/vtune_solaris.cpp
+0
-40
src/os/windows/vm/vtune_windows.cpp
src/os/windows/vm/vtune_windows.cpp
+0
-290
src/share/vm/ci/bcEscapeAnalyzer.cpp
src/share/vm/ci/bcEscapeAnalyzer.cpp
+34
-31
src/share/vm/ci/bcEscapeAnalyzer.hpp
src/share/vm/ci/bcEscapeAnalyzer.hpp
+12
-26
src/share/vm/ci/ciInstanceKlass.cpp
src/share/vm/ci/ciInstanceKlass.cpp
+5
-19
src/share/vm/ci/ciInstanceKlass.hpp
src/share/vm/ci/ciInstanceKlass.hpp
+19
-13
src/share/vm/ci/ciMethod.cpp
src/share/vm/ci/ciMethod.cpp
+7
-2
src/share/vm/ci/ciMethod.hpp
src/share/vm/ci/ciMethod.hpp
+2
-2
src/share/vm/classfile/classLoader.cpp
src/share/vm/classfile/classLoader.cpp
+1
-2
src/share/vm/code/codeBlob.cpp
src/share/vm/code/codeBlob.cpp
+1
-5
src/share/vm/code/codeCache.cpp
src/share/vm/code/codeCache.cpp
+19
-4
src/share/vm/code/codeCache.hpp
src/share/vm/code/codeCache.hpp
+5
-1
src/share/vm/code/nmethod.cpp
src/share/vm/code/nmethod.cpp
+69
-126
src/share/vm/code/nmethod.hpp
src/share/vm/code/nmethod.hpp
+47
-61
src/share/vm/code/vtableStubs.cpp
src/share/vm/code/vtableStubs.cpp
+1
-2
src/share/vm/includeDB_compiler2
src/share/vm/includeDB_compiler2
+16
-0
src/share/vm/includeDB_core
src/share/vm/includeDB_core
+0
-29
src/share/vm/interpreter/interpreter.cpp
src/share/vm/interpreter/interpreter.cpp
+0
-5
src/share/vm/opto/doCall.cpp
src/share/vm/opto/doCall.cpp
+2
-1
src/share/vm/opto/parse.hpp
src/share/vm/opto/parse.hpp
+1
-0
src/share/vm/opto/parseHelper.cpp
src/share/vm/opto/parseHelper.cpp
+42
-2
src/share/vm/prims/jvmtiCodeBlobEvents.cpp
src/share/vm/prims/jvmtiCodeBlobEvents.cpp
+3
-4
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals.hpp
+0
-3
src/share/vm/runtime/init.cpp
src/share/vm/runtime/init.cpp
+0
-2
src/share/vm/runtime/java.cpp
src/share/vm/runtime/java.cpp
+1
-3
src/share/vm/runtime/sharedRuntime.cpp
src/share/vm/runtime/sharedRuntime.cpp
+0
-1
src/share/vm/runtime/stubCodeGenerator.cpp
src/share/vm/runtime/stubCodeGenerator.cpp
+1
-2
src/share/vm/runtime/sweeper.cpp
src/share/vm/runtime/sweeper.cpp
+74
-73
src/share/vm/runtime/sweeper.hpp
src/share/vm/runtime/sweeper.hpp
+7
-3
src/share/vm/runtime/vmStructs.cpp
src/share/vm/runtime/vmStructs.cpp
+0
-1
src/share/vm/runtime/vtune.hpp
src/share/vm/runtime/vtune.hpp
+0
-55
未找到文件。
agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java
浏览文件 @
9d513174
...
...
@@ -35,7 +35,6 @@ import sun.jvm.hotspot.utilities.*;
public
class
NMethod
extends
CodeBlob
{
private
static
long
pcDescSize
;
private
static
CIntegerField
zombieInstructionSizeField
;
private
static
sun
.
jvm
.
hotspot
.
types
.
OopField
methodField
;
/** != InvocationEntryBci if this nmethod is an on-stack replacement method */
private
static
CIntegerField
entryBCIField
;
...
...
@@ -88,7 +87,6 @@ public class NMethod extends CodeBlob {
private
static
void
initialize
(
TypeDataBase
db
)
{
Type
type
=
db
.
lookupType
(
"nmethod"
);
zombieInstructionSizeField
=
type
.
getCIntegerField
(
"_zombie_instruction_size"
);
methodField
=
type
.
getOopField
(
"_method"
);
entryBCIField
=
type
.
getCIntegerField
(
"_entry_bci"
);
osrLinkField
=
type
.
getAddressField
(
"_osr_link"
);
...
...
src/cpu/x86/vm/vm_version_x86.hpp
浏览文件 @
9d513174
...
...
@@ -376,10 +376,17 @@ public:
static
bool
is_amd
()
{
assert_is_initialized
();
return
_cpuid_info
.
std_vendor_name_0
==
0x68747541
;
}
// 'htuA'
static
bool
is_intel
()
{
assert_is_initialized
();
return
_cpuid_info
.
std_vendor_name_0
==
0x756e6547
;
}
// 'uneG'
static
bool
supports_processor_topology
()
{
return
(
_cpuid_info
.
std_max_function
>=
0xB
)
&&
// eax[4:0] | ebx[0:15] == 0 indicates invalid topology level.
// Some cpus have max cpuid >= 0xB but do not support processor topology.
((
_cpuid_info
.
tpl_cpuidB0_eax
&
0x1f
|
_cpuid_info
.
tpl_cpuidB0_ebx
.
bits
.
logical_cpus
)
!=
0
);
}
static
uint
cores_per_cpu
()
{
uint
result
=
1
;
if
(
is_intel
())
{
if
(
_cpuid_info
.
std_max_function
>=
0xB
)
{
if
(
supports_processor_topology
()
)
{
result
=
_cpuid_info
.
tpl_cpuidB1_ebx
.
bits
.
logical_cpus
/
_cpuid_info
.
tpl_cpuidB0_ebx
.
bits
.
logical_cpus
;
}
else
{
...
...
@@ -393,7 +400,7 @@ public:
static
uint
threads_per_core
()
{
uint
result
=
1
;
if
(
is_intel
()
&&
_cpuid_info
.
std_max_function
>=
0xB
)
{
if
(
is_intel
()
&&
supports_processor_topology
()
)
{
result
=
_cpuid_info
.
tpl_cpuidB0_ebx
.
bits
.
logical_cpus
;
}
else
if
(
_cpuid_info
.
std_cpuid1_edx
.
bits
.
ht
!=
0
)
{
result
=
_cpuid_info
.
std_cpuid1_ebx
.
bits
.
threads_per_cpu
/
...
...
src/os/linux/vm/vtune_linux.cpp
已删除
100644 → 0
浏览文件 @
4a141040
/*
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "incls/_precompiled.incl"
#include "incls/_vtune_linux.cpp.incl"
// empty implementation
void
VTune
::
start_GC
()
{}
void
VTune
::
end_GC
()
{}
void
VTune
::
start_class_load
()
{}
void
VTune
::
end_class_load
()
{}
void
VTune
::
exit
()
{}
void
VTune
::
register_stub
(
const
char
*
name
,
address
start
,
address
end
)
{}
void
VTune
::
create_nmethod
(
nmethod
*
nm
)
{}
void
VTune
::
delete_nmethod
(
nmethod
*
nm
)
{}
void
vtune_init
()
{}
// Reconciliation History
// vtune_solaris.cpp 1.8 99/07/12 23:54:21
// End
src/os/solaris/vm/vtune_solaris.cpp
已删除
100644 → 0
浏览文件 @
4a141040
/*
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "incls/_precompiled.incl"
#include "incls/_vtune_solaris.cpp.incl"
// empty implementation
void
VTune
::
start_GC
()
{}
void
VTune
::
end_GC
()
{}
void
VTune
::
start_class_load
()
{}
void
VTune
::
end_class_load
()
{}
void
VTune
::
exit
()
{}
void
VTune
::
register_stub
(
const
char
*
name
,
address
start
,
address
end
)
{}
void
VTune
::
create_nmethod
(
nmethod
*
nm
)
{}
void
VTune
::
delete_nmethod
(
nmethod
*
nm
)
{}
void
vtune_init
()
{}
src/os/windows/vm/vtune_windows.cpp
已删除
100644 → 0
浏览文件 @
4a141040
/*
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "incls/_precompiled.incl"
#include "incls/_vtune_windows.cpp.incl"
static
int
current_method_ID
=
0
;
// ------------- iJITProf.h -------------------
// defined by Intel -- do not change
#include "windows.h"
extern
"C"
{
enum
iJITP_Event
{
ExceptionOccurred_S
,
// Java exception
ExceptionOccurred_IDS
,
Shutdown
,
// VM exit
ThreadCreate
,
// threads
ThreadDestroy
,
ThreadSwitch
,
ClassLoadStart
,
// class loading
ClassLoadEnd
,
GCStart
,
// GC
GCEnd
,
NMethodCreate
=
13
,
// nmethod creation
NMethodDelete
// rest of event types omitted (call profiling not supported yet)
};
// version number -- 0 if VTune not installed
int
WINAPI
iJitP_VersionNumber
();
enum
iJITP_ModeFlags
{
NoNotification
=
0x0
,
// don't call vtune
NotifyNMethodCreate
=
0x1
,
// notify NMethod_Create
NotifyNMethodDelete
=
0x2
,
// notify NMethod_Create
NotifyMethodEnter
=
0x4
,
// method entry
NotifyMethodExit
=
0x8
,
// method exit
NotifyShutdown
=
0x10
,
// VM exit
NotifyGC
=
0x20
,
// GC
};
// call back function type
typedef
void
(
WINAPI
*
ModeChangedFn
)(
iJITP_ModeFlags
flags
);
// ------------- VTune method interfaces ----------------------
typedef
void
(
WINAPI
*
RegisterCallbackFn
)(
ModeChangedFn
fn
);
// register callback
typedef
int
(
WINAPI
*
NotifyEventFn
)(
iJITP_Event
,
void
*
event_data
);
// specific event data structures
// data for NMethodCreate
struct
VTuneObj
{
// base class for allocation
// (can't use CHeapObj -- has vtable ptr)
void
*
operator
new
(
size_t
size
)
{
return
os
::
malloc
(
size
);
}
void
operator
delete
(
void
*
p
)
{
fatal
(
"never delete VTune data"
);
}
};
struct
LineNumberInfo
:
VTuneObj
{
// PC-to-line number mapping
unsigned
long
offset
;
// byte offset from start of method
unsigned
long
line_num
;
// corresponding line number
};
struct
MethodLoadInfo
:
VTuneObj
{
unsigned
long
methodID
;
// unique method ID
const
char
*
name
;
// method name
unsigned
long
instr_start
;
// start address
unsigned
long
instr_size
;
// length in bytes
unsigned
long
line_number_size
;
// size of line number table
LineNumberInfo
*
line_number_table
;
// line number mapping
unsigned
long
classID
;
// unique class ID
char
*
class_file_name
;
// fully qualified class file name
char
*
source_file_name
;
// fully qualified source file name
MethodLoadInfo
(
nmethod
*
nm
);
// for real nmethods
MethodLoadInfo
(
const
char
*
vm_name
,
address
start
,
address
end
);
// for "nmethods" like stubs, interpreter, etc
};
// data for NMethodDelete
struct
MethodInfo
:
VTuneObj
{
unsigned
long
methodID
;
// unique method ID
unsigned
long
classID
;
// (added for convenience -- not part of Intel interface)
MethodInfo
(
methodOop
m
);
};
};
MethodInfo
::
MethodInfo
(
methodOop
m
)
{
// just give it a new ID -- we're not compiling methods twice (usually)
// (and even if we did, one might want to see the two versions separately)
methodID
=
++
current_method_ID
;
}
MethodLoadInfo
::
MethodLoadInfo
(
const
char
*
vm_name
,
address
start
,
address
end
)
{
classID
=
0
;
methodID
=
++
current_method_ID
;
name
=
vm_name
;
instr_start
=
(
unsigned
long
)
start
;
instr_size
=
end
-
start
;
line_number_size
=
0
;
line_number_table
=
NULL
;
class_file_name
=
source_file_name
=
"HotSpot JVM"
;
}
MethodLoadInfo
::
MethodLoadInfo
(
nmethod
*
nm
)
{
methodOop
m
=
nm
->
method
();
MethodInfo
info
(
m
);
classID
=
info
.
classID
;
methodID
=
info
.
methodID
;
name
=
strdup
(
m
->
name
()
->
as_C_string
());
instr_start
=
(
unsigned
long
)
nm
->
instructions_begin
();
instr_size
=
nm
->
code_size
();
line_number_size
=
0
;
line_number_table
=
NULL
;
klassOop
kl
=
m
->
method_holder
();
char
*
class_name
=
Klass
::
cast
(
kl
)
->
name
()
->
as_C_string
();
char
*
file_name
=
NEW_C_HEAP_ARRAY
(
char
,
strlen
(
class_name
)
+
1
);
strcpy
(
file_name
,
class_name
);
class_file_name
=
file_name
;
char
*
src_name
=
NEW_C_HEAP_ARRAY
(
char
,
strlen
(
class_name
)
+
strlen
(
".java"
)
+
1
);
strcpy
(
src_name
,
class_name
);
strcat
(
src_name
,
".java"
);
source_file_name
=
src_name
;
}
// --------------------- DLL loading functions ------------------------
#define DLLNAME "iJitProf.dll"
static
HINSTANCE
load_lib
(
char
*
name
)
{
HINSTANCE
lib
=
NULL
;
HKEY
hk
;
// try to get VTune directory from the registry
if
(
RegOpenKey
(
HKEY_CURRENT_USER
,
"Software
\\
VB and VBA Program Settings
\\
VTune
\\
StartUp"
,
&
hk
)
==
ERROR_SUCCESS
)
{
for
(
int
i
=
0
;
true
;
i
++
)
{
char
szName
[
MAX_PATH
+
1
];
char
szVal
[
MAX_PATH
+
1
];
DWORD
cbName
,
cbVal
;
cbName
=
cbVal
=
MAX_PATH
+
1
;
if
(
RegEnumValue
(
hk
,
i
,
szName
,
&
cbName
,
NULL
,
NULL
,
(
LPBYTE
)
szVal
,
&
cbVal
)
==
ERROR_SUCCESS
)
{
// get VTune directory
if
(
!
strcmp
(
szName
,
name
))
{
char
*
p
=
szVal
;
while
(
*
p
==
' '
)
p
++
;
// trim
char
*
q
=
p
+
strlen
(
p
)
-
1
;
while
(
*
q
==
' '
)
*
(
q
--
)
=
'\0'
;
// chdir to the VTune dir
GetCurrentDirectory
(
MAX_PATH
+
1
,
szName
);
SetCurrentDirectory
(
p
);
// load lib
lib
=
LoadLibrary
(
strcat
(
strcat
(
p
,
"
\\
"
),
DLLNAME
));
if
(
lib
!=
NULL
&&
WizardMode
)
tty
->
print_cr
(
"*loaded VTune DLL %s"
,
p
);
// restore current dir
SetCurrentDirectory
(
szName
);
break
;
}
}
else
{
break
;
}
}
}
return
lib
;
}
static
RegisterCallbackFn
iJIT_RegisterCallback
=
NULL
;
static
NotifyEventFn
iJIT_NotifyEvent
=
NULL
;
static
bool
load_iJIT_funcs
()
{
// first try to load from PATH
HINSTANCE
lib
=
LoadLibrary
(
DLLNAME
);
if
(
lib
!=
NULL
&&
WizardMode
)
tty
->
print_cr
(
"*loaded VTune DLL %s via PATH"
,
DLLNAME
);
// if not successful, try to look in the VTUNE directory
if
(
lib
==
NULL
)
lib
=
load_lib
(
"VTUNEDIR30"
);
if
(
lib
==
NULL
)
lib
=
load_lib
(
"VTUNEDIR25"
);
if
(
lib
==
NULL
)
lib
=
load_lib
(
"VTUNEDIR"
);
if
(
lib
==
NULL
)
return
false
;
// unsuccessful
// try to load the functions
iJIT_RegisterCallback
=
(
RegisterCallbackFn
)
GetProcAddress
(
lib
,
"iJIT_RegisterCallback"
);
iJIT_NotifyEvent
=
(
NotifyEventFn
)
GetProcAddress
(
lib
,
"iJIT_NotifyEvent"
);
if
(
!
iJIT_RegisterCallback
)
tty
->
print_cr
(
"*couldn't find VTune entry point iJIT_RegisterCallback"
);
if
(
!
iJIT_NotifyEvent
)
tty
->
print_cr
(
"*couldn't find VTune entry point iJIT_NotifyEvent"
);
return
iJIT_RegisterCallback
!=
NULL
&&
iJIT_NotifyEvent
!=
NULL
;
}
// --------------------- VTune class ------------------------
static
bool
active
=
false
;
static
int
flags
=
0
;
void
VTune
::
start_GC
()
{
if
(
active
&&
(
flags
&
NotifyGC
))
iJIT_NotifyEvent
(
GCStart
,
NULL
);
}
void
VTune
::
end_GC
()
{
if
(
active
&&
(
flags
&
NotifyGC
))
iJIT_NotifyEvent
(
GCEnd
,
NULL
);
}
void
VTune
::
start_class_load
()
{
// not yet implemented in VTune
}
void
VTune
::
end_class_load
()
{
// not yet implemented in VTune
}
void
VTune
::
exit
()
{
if
(
active
&&
(
flags
&
NotifyShutdown
))
iJIT_NotifyEvent
(
Shutdown
,
NULL
);
}
void
VTune
::
register_stub
(
const
char
*
name
,
address
start
,
address
end
)
{
if
(
flags
&
NotifyNMethodCreate
)
{
MethodLoadInfo
*
info
=
new
MethodLoadInfo
(
name
,
start
,
end
);
if
(
PrintMiscellaneous
&&
WizardMode
&&
Verbose
)
{
tty
->
print_cr
(
"NMethodCreate %s (%d): %#x..%#x"
,
info
->
name
,
info
->
methodID
,
info
->
instr_start
,
info
->
instr_start
+
info
->
instr_size
);
}
iJIT_NotifyEvent
(
NMethodCreate
,
info
);
}
}
void
VTune
::
create_nmethod
(
nmethod
*
nm
)
{
if
(
flags
&
NotifyNMethodCreate
)
{
MethodLoadInfo
*
info
=
new
MethodLoadInfo
(
nm
);
if
(
PrintMiscellaneous
&&
WizardMode
&&
Verbose
)
{
tty
->
print_cr
(
"NMethodCreate %s (%d): %#x..%#x"
,
info
->
name
,
info
->
methodID
,
info
->
instr_start
,
info
->
instr_start
+
info
->
instr_size
);
}
iJIT_NotifyEvent
(
NMethodCreate
,
info
);
}
}
void
VTune
::
delete_nmethod
(
nmethod
*
nm
)
{
if
(
flags
&
NotifyNMethodDelete
)
{
MethodInfo
*
info
=
new
MethodInfo
(
nm
->
method
());
iJIT_NotifyEvent
(
NMethodDelete
,
info
);
}
}
static
void
set_flags
(
int
new_flags
)
{
flags
=
new_flags
;
// if (WizardMode) tty->print_cr("*new VTune flags: %#x", flags);
}
void
vtune_init
()
{
if
(
!
UseVTune
)
return
;
active
=
load_iJIT_funcs
();
if
(
active
)
{
iJIT_RegisterCallback
((
ModeChangedFn
)
set_flags
);
}
else
{
assert
(
flags
==
0
,
"flags shouldn't be set"
);
}
}
src/share/vm/ci/bcEscapeAnalyzer.cpp
浏览文件 @
9d513174
...
...
@@ -106,7 +106,7 @@ public:
void
BCEscapeAnalyzer
::
set_returned
(
ArgumentMap
vars
)
{
for
(
int
i
=
0
;
i
<
_arg_size
;
i
++
)
{
if
(
vars
.
contains
(
i
))
_arg_returned
.
set
_bit
(
i
);
_arg_returned
.
set
(
i
);
}
_return_local
=
_return_local
&&
!
(
vars
.
contains_unknown
()
||
vars
.
contains_allocated
());
_return_allocated
=
_return_allocated
&&
vars
.
contains_allocated
()
&&
!
(
vars
.
contains_unknown
()
||
vars
.
contains_vars
());
...
...
@@ -126,16 +126,16 @@ bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){
if
(
_conservative
)
return
true
;
for
(
int
i
=
0
;
i
<
_arg_size
;
i
++
)
{
if
(
vars
.
contains
(
i
)
&&
_arg_stack
.
a
t
(
i
))
if
(
vars
.
contains
(
i
)
&&
_arg_stack
.
tes
t
(
i
))
return
true
;
}
return
false
;
}
void
BCEscapeAnalyzer
::
clear_bits
(
ArgumentMap
vars
,
BitMap
&
bm
)
{
void
BCEscapeAnalyzer
::
clear_bits
(
ArgumentMap
vars
,
VectorSet
&
bm
)
{
for
(
int
i
=
0
;
i
<
_arg_size
;
i
++
)
{
if
(
vars
.
contains
(
i
))
{
bm
.
clear_bit
(
i
)
;
bm
>>=
i
;
}
}
}
...
...
@@ -1157,15 +1157,15 @@ void BCEscapeAnalyzer::initialize() {
ciSignature
*
sig
=
method
()
->
signature
();
int
j
=
0
;
if
(
!
method
()
->
is_static
())
{
_arg_local
.
set
_bit
(
0
);
_arg_stack
.
set
_bit
(
0
);
_arg_local
.
set
(
0
);
_arg_stack
.
set
(
0
);
j
++
;
}
for
(
i
=
0
;
i
<
sig
->
count
();
i
++
)
{
ciType
*
t
=
sig
->
type_at
(
i
);
if
(
!
t
->
is_primitive_type
())
{
_arg_local
.
set
_bit
(
j
);
_arg_stack
.
set
_bit
(
j
);
_arg_local
.
set
(
j
);
_arg_stack
.
set
(
j
);
}
j
+=
t
->
size
();
}
...
...
@@ -1198,9 +1198,9 @@ void BCEscapeAnalyzer::clear_escape_info() {
set_modified
(
var
,
OFFSET_ANY
,
4
);
set_global_escape
(
var
);
}
_arg_local
.
c
lear
();
_arg_stack
.
c
lear
();
_arg_returned
.
c
lear
();
_arg_local
.
C
lear
();
_arg_stack
.
C
lear
();
_arg_returned
.
C
lear
();
_return_local
=
false
;
_return_allocated
=
false
;
_allocated_escapes
=
true
;
...
...
@@ -1254,7 +1254,7 @@ void BCEscapeAnalyzer::compute_escape_info() {
// Do not scan method if it has no object parameters and
// does not returns an object (_return_allocated is set in initialize()).
if
(
_arg_local
.
is_empty
()
&&
!
_return_allocated
)
{
if
(
_arg_local
.
Size
()
==
0
&&
!
_return_allocated
)
{
// Clear all info since method's bytecode was not analysed and
// set pessimistic escape information.
clear_escape_info
();
...
...
@@ -1275,14 +1275,14 @@ void BCEscapeAnalyzer::compute_escape_info() {
//
if
(
!
has_dependencies
()
&&
!
methodData
()
->
is_empty
())
{
for
(
i
=
0
;
i
<
_arg_size
;
i
++
)
{
if
(
_arg_local
.
a
t
(
i
))
{
assert
(
_arg_stack
.
a
t
(
i
),
"inconsistent escape info"
);
if
(
_arg_local
.
tes
t
(
i
))
{
assert
(
_arg_stack
.
tes
t
(
i
),
"inconsistent escape info"
);
methodData
()
->
set_arg_local
(
i
);
methodData
()
->
set_arg_stack
(
i
);
}
else
if
(
_arg_stack
.
a
t
(
i
))
{
}
else
if
(
_arg_stack
.
tes
t
(
i
))
{
methodData
()
->
set_arg_stack
(
i
);
}
if
(
_arg_returned
.
a
t
(
i
))
{
if
(
_arg_returned
.
tes
t
(
i
))
{
methodData
()
->
set_arg_returned
(
i
);
}
methodData
()
->
set_arg_modified
(
i
,
_arg_modified
[
i
]);
...
...
@@ -1308,9 +1308,12 @@ void BCEscapeAnalyzer::read_escape_info() {
// read escape information from method descriptor
for
(
int
i
=
0
;
i
<
_arg_size
;
i
++
)
{
_arg_local
.
at_put
(
i
,
methodData
()
->
is_arg_local
(
i
));
_arg_stack
.
at_put
(
i
,
methodData
()
->
is_arg_stack
(
i
));
_arg_returned
.
at_put
(
i
,
methodData
()
->
is_arg_returned
(
i
));
if
(
methodData
()
->
is_arg_local
(
i
))
_arg_local
.
set
(
i
);
if
(
methodData
()
->
is_arg_stack
(
i
))
_arg_stack
.
set
(
i
);
if
(
methodData
()
->
is_arg_returned
(
i
))
_arg_returned
.
set
(
i
);
_arg_modified
[
i
]
=
methodData
()
->
arg_modified
(
i
);
}
_return_local
=
methodData
()
->
eflag_set
(
methodDataOopDesc
::
return_local
);
...
...
@@ -1358,26 +1361,26 @@ void BCEscapeAnalyzer::dump() {
BCEscapeAnalyzer
::
BCEscapeAnalyzer
(
ciMethod
*
method
,
BCEscapeAnalyzer
*
parent
)
:
_conservative
(
method
==
NULL
||
!
EstimateArgEscape
)
,
_arena
(
CURRENT_ENV
->
arena
())
,
_method
(
method
)
,
_methodData
(
method
?
method
->
method_data
()
:
NULL
)
,
_arg_size
(
method
?
method
->
arg_size
()
:
0
)
,
_stack
()
,
_arg_local
(
_arg_size
)
,
_arg_stack
(
_arg_size
)
,
_arg_returned
(
_arg_size
)
,
_dirty
(
_arg_size
)
,
_arg_local
(
_arena
)
,
_arg_stack
(
_arena
)
,
_arg_returned
(
_arena
)
,
_dirty
(
_arena
)
,
_return_local
(
false
)
,
_return_allocated
(
false
)
,
_allocated_escapes
(
false
)
,
_unknown_modified
(
false
)
,
_dependencies
()
,
_dependencies
(
_arena
,
4
,
0
,
NULL
)
,
_parent
(
parent
)
,
_level
(
parent
==
NULL
?
0
:
parent
->
level
()
+
1
)
{
if
(
!
_conservative
)
{
_arg_local
.
c
lear
();
_arg_stack
.
c
lear
();
_arg_returned
.
c
lear
();
_dirty
.
c
lear
();
_arg_local
.
C
lear
();
_arg_stack
.
C
lear
();
_arg_returned
.
C
lear
();
_dirty
.
C
lear
();
Arena
*
arena
=
CURRENT_ENV
->
arena
();
_arg_modified
=
(
uint
*
)
arena
->
Amalloc
(
_arg_size
*
sizeof
(
uint
));
Copy
::
zero_to_bytes
(
_arg_modified
,
_arg_size
*
sizeof
(
uint
));
...
...
@@ -1414,8 +1417,8 @@ void BCEscapeAnalyzer::copy_dependencies(Dependencies *deps) {
deps
->
assert_evol_method
(
method
());
}
for
(
int
i
=
0
;
i
<
_dependencies
.
length
();
i
+=
2
)
{
ciKlass
*
k
=
_dependencies
[
i
]
->
as_klass
();
ciMethod
*
m
=
_dependencies
[
i
+
1
]
->
as_method
();
ciKlass
*
k
=
_dependencies
.
at
(
i
)
->
as_klass
();
ciMethod
*
m
=
_dependencies
.
at
(
i
+
1
)
->
as_method
();
deps
->
assert_unique_concrete_method
(
k
,
m
);
}
}
src/share/vm/ci/bcEscapeAnalyzer.hpp
浏览文件 @
9d513174
...
...
@@ -22,9 +22,6 @@
*
*/
define_array
(
ciObjectArray
,
ciObject
*
);
define_stack
(
ciObjectList
,
ciObjectArray
);
// This class implements a fast, conservative analysis of effect of methods
// on the escape state of their arguments. The analysis is at the bytecode
// level.
...
...
@@ -34,18 +31,17 @@ class ciBlock;
class
BCEscapeAnalyzer
:
public
ResourceObj
{
private:
Arena
*
_arena
;
// ciEnv arena
bool
_conservative
;
// If true, return maximally
// conservative results.
ciMethod
*
_method
;
ciMethodData
*
_methodData
;
int
_arg_size
;
intStack
_stack
;
BitMap
_arg_local
;
BitMap
_arg_stack
;
BitMap
_arg_returned
;
BitMap
_dirty
;
VectorSet
_arg_local
;
VectorSet
_arg_stack
;
VectorSet
_arg_returned
;
VectorSet
_dirty
;
enum
{
ARG_OFFSET_MAX
=
31
};
uint
*
_arg_modified
;
...
...
@@ -54,7 +50,7 @@ class BCEscapeAnalyzer : public ResourceObj {
bool
_allocated_escapes
;
bool
_unknown_modified
;
ciObjectList
_dependencies
;
GrowableArray
<
ciObject
*>
_dependencies
;
ciMethodBlocks
*
_methodBlocks
;
...
...
@@ -68,20 +64,10 @@ class BCEscapeAnalyzer : public ResourceObj {
private:
// helper functions
bool
is_argument
(
int
i
)
{
return
i
>=
0
&&
i
<
_arg_size
;
}
void
raw_push
(
int
i
)
{
_stack
.
push
(
i
);
}
int
raw_pop
()
{
return
_stack
.
is_empty
()
?
-
1
:
_stack
.
pop
();
}
void
apush
(
int
i
)
{
raw_push
(
i
);
}
void
spush
()
{
raw_push
(
-
1
);
}
void
lpush
()
{
spush
();
spush
();
}
int
apop
()
{
return
raw_pop
();
}
void
spop
()
{
assert
(
_stack
.
is_empty
()
||
_stack
.
top
()
==
-
1
,
""
);
raw_pop
();
}
void
lpop
()
{
spop
();
spop
();
}
void
set_returned
(
ArgumentMap
vars
);
bool
is_argument
(
ArgumentMap
vars
);
bool
is_arg_stack
(
ArgumentMap
vars
);
void
clear_bits
(
ArgumentMap
vars
,
BitMap
&
bs
);
void
clear_bits
(
ArgumentMap
vars
,
VectorSet
&
bs
);
void
set_method_escape
(
ArgumentMap
vars
);
void
set_global_escape
(
ArgumentMap
vars
);
void
set_dirty
(
ArgumentMap
vars
);
...
...
@@ -116,25 +102,25 @@ class BCEscapeAnalyzer : public ResourceObj {
ciMethodData
*
methodData
()
const
{
return
_methodData
;
}
BCEscapeAnalyzer
*
parent
()
const
{
return
_parent
;
}
int
level
()
const
{
return
_level
;
}
ciObjectList
*
dependencies
()
{
return
&
_dependencies
;
}
GrowableArray
<
ciObject
*>*
dependencies
()
{
return
&
_dependencies
;
}
bool
has_dependencies
()
const
{
return
!
_dependencies
.
is_empty
();
}
// retrieval of interprocedural escape information
// The given argument does not escape the callee.
bool
is_arg_local
(
int
i
)
const
{
return
!
_conservative
&&
_arg_local
.
a
t
(
i
);
return
!
_conservative
&&
_arg_local
.
tes
t
(
i
);
}
// The given argument escapes the callee, but does not become globally
// reachable.
bool
is_arg_stack
(
int
i
)
const
{
return
!
_conservative
&&
_arg_stack
.
a
t
(
i
);
return
!
_conservative
&&
_arg_stack
.
tes
t
(
i
);
}
// The given argument does not escape globally, and may be returned.
bool
is_arg_returned
(
int
i
)
const
{
return
!
_conservative
&&
_arg_returned
.
a
t
(
i
);
}
return
!
_conservative
&&
_arg_returned
.
tes
t
(
i
);
}
// True iff only input arguments are returned.
bool
is_return_local
()
const
{
...
...
src/share/vm/ci/ciInstanceKlass.cpp
浏览文件 @
9d513174
/*
* Copyright (c) 1999, 20
08
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -44,9 +44,7 @@ ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
_flags
=
ciFlags
(
access_flags
);
_has_finalizer
=
access_flags
.
has_finalizer
();
_has_subklass
=
ik
->
subklass
()
!=
NULL
;
_is_initialized
=
ik
->
is_initialized
();
// Next line must follow and use the result of the previous line:
_is_linked
=
_is_initialized
||
ik
->
is_linked
();
_init_state
=
(
instanceKlass
::
ClassState
)
ik
->
get_init_state
();
_nonstatic_field_size
=
ik
->
nonstatic_field_size
();
_has_nonstatic_fields
=
ik
->
has_nonstatic_fields
();
_nonstatic_fields
=
NULL
;
// initialized lazily by compute_nonstatic_fields:
...
...
@@ -91,8 +89,7 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
:
ciKlass
(
name
,
ciInstanceKlassKlass
::
make
())
{
assert
(
name
->
byte_at
(
0
)
!=
'['
,
"not an instance klass"
);
_is_initialized
=
false
;
_is_linked
=
false
;
_init_state
=
(
instanceKlass
::
ClassState
)
0
;
_nonstatic_field_size
=
-
1
;
_has_nonstatic_fields
=
false
;
_nonstatic_fields
=
NULL
;
...
...
@@ -109,21 +106,10 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
// ------------------------------------------------------------------
// ciInstanceKlass::compute_shared_is_initialized
bool
ciInstanceKlass
::
compute_shared_is_initialized
()
{
void
ciInstanceKlass
::
compute_shared_init_state
()
{
GUARDED_VM_ENTRY
(
instanceKlass
*
ik
=
get_instanceKlass
();
_is_initialized
=
ik
->
is_initialized
();
return
_is_initialized
;
)
}
// ------------------------------------------------------------------
// ciInstanceKlass::compute_shared_is_linked
bool
ciInstanceKlass
::
compute_shared_is_linked
()
{
GUARDED_VM_ENTRY
(
instanceKlass
*
ik
=
get_instanceKlass
();
_is_linked
=
ik
->
is_linked
();
return
_is_linked
;
_init_state
=
(
instanceKlass
::
ClassState
)
ik
->
get_init_state
();
)
}
...
...
src/share/vm/ci/ciInstanceKlass.hpp
浏览文件 @
9d513174
/*
* Copyright (c) 1999, 20
08
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -39,9 +39,8 @@ private:
jobject
_loader
;
jobject
_protection_domain
;
instanceKlass
::
ClassState
_init_state
;
// state of class
bool
_is_shared
;
bool
_is_initialized
;
bool
_is_linked
;
bool
_has_finalizer
;
bool
_has_subklass
;
bool
_has_nonstatic_fields
;
...
...
@@ -87,27 +86,34 @@ protected:
bool
is_shared
()
{
return
_is_shared
;
}
bool
compute_shared_is_initialized
();
bool
compute_shared_is_linked
();
void
compute_shared_init_state
();
bool
compute_shared_has_subklass
();
int
compute_shared_nof_implementors
();
int
compute_nonstatic_fields
();
GrowableArray
<
ciField
*>*
compute_nonstatic_fields_impl
(
GrowableArray
<
ciField
*>*
super_fields
);
// Update the init_state for shared klasses
void
update_if_shared
(
instanceKlass
::
ClassState
expected
)
{
if
(
_is_shared
&&
_init_state
!=
expected
)
{
if
(
is_loaded
())
compute_shared_init_state
();
}
}
public:
// Has this klass been initialized?
bool
is_initialized
()
{
if
(
_is_shared
&&
!
_is_initialized
)
{
return
is_loaded
()
&&
compute_shared_is_initialized
();
}
return
_is_initialized
;
update_if_shared
(
instanceKlass
::
fully_initialized
);
return
_init_state
==
instanceKlass
::
fully_initialized
;
}
// Is this klass being initialized?
bool
is_being_initialized
()
{
update_if_shared
(
instanceKlass
::
being_initialized
);
return
_init_state
==
instanceKlass
::
being_initialized
;
}
// Has this klass been linked?
bool
is_linked
()
{
if
(
_is_shared
&&
!
_is_linked
)
{
return
is_loaded
()
&&
compute_shared_is_linked
();
}
return
_is_linked
;
update_if_shared
(
instanceKlass
::
linked
);
return
_init_state
>=
instanceKlass
::
linked
;
}
// General klass information.
...
...
src/share/vm/ci/ciMethod.cpp
浏览文件 @
9d513174
...
...
@@ -54,10 +54,10 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
_code
=
NULL
;
_exception_handlers
=
NULL
;
_liveness
=
NULL
;
_bcea
=
NULL
;
_method_blocks
=
NULL
;
#ifdef COMPILER2
_flow
=
NULL
;
_bcea
=
NULL
;
#endif // COMPILER2
ciEnv
*
env
=
CURRENT_ENV
;
...
...
@@ -121,11 +121,11 @@ ciMethod::ciMethod(ciInstanceKlass* holder,
_intrinsic_id
=
vmIntrinsics
::
_none
;
_liveness
=
NULL
;
_can_be_statically_bound
=
false
;
_bcea
=
NULL
;
_method_blocks
=
NULL
;
_method_data
=
NULL
;
#ifdef COMPILER2
_flow
=
NULL
;
_bcea
=
NULL
;
#endif // COMPILER2
}
...
...
@@ -1033,10 +1033,15 @@ bool ciMethod::is_accessor () const { FETCH_FLAG_FROM_VM(is_accessor)
bool
ciMethod
::
is_initializer
()
const
{
FETCH_FLAG_FROM_VM
(
is_initializer
);
}
BCEscapeAnalyzer
*
ciMethod
::
get_bcea
()
{
#ifdef COMPILER2
if
(
_bcea
==
NULL
)
{
_bcea
=
new
(
CURRENT_ENV
->
arena
())
BCEscapeAnalyzer
(
this
,
NULL
);
}
return
_bcea
;
#else // COMPILER2
ShouldNotReachHere
();
return
NULL
;
#endif // COMPILER2
}
ciMethodBlocks
*
ciMethod
::
get_method_blocks
()
{
...
...
src/share/vm/ci/ciMethod.hpp
浏览文件 @
9d513174
...
...
@@ -48,7 +48,6 @@ class ciMethod : public ciObject {
ciInstanceKlass
*
_holder
;
ciSignature
*
_signature
;
ciMethodData
*
_method_data
;
BCEscapeAnalyzer
*
_bcea
;
ciMethodBlocks
*
_method_blocks
;
// Code attributes.
...
...
@@ -72,7 +71,8 @@ class ciMethod : public ciObject {
// Optional liveness analyzer.
MethodLiveness
*
_liveness
;
#ifdef COMPILER2
ciTypeFlow
*
_flow
;
ciTypeFlow
*
_flow
;
BCEscapeAnalyzer
*
_bcea
;
#endif
ciMethod
(
methodHandle
h_m
);
...
...
src/share/vm/classfile/classLoader.cpp
浏览文件 @
9d513174
/*
* Copyright (c) 1997, 20
09
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -832,7 +832,6 @@ objArrayOop ClassLoader::get_system_packages(TRAPS) {
instanceKlassHandle
ClassLoader
::
load_classfile
(
symbolHandle
h_name
,
TRAPS
)
{
VTuneClassLoadMarker
clm
;
ResourceMark
rm
(
THREAD
);
EventMark
m
(
"loading class "
INTPTR_FORMAT
,
(
address
)
h_name
());
ThreadProfilerMark
tpm
(
ThreadProfilerMark
::
classLoaderRegion
);
...
...
src/share/vm/code/codeBlob.cpp
浏览文件 @
9d513174
...
...
@@ -210,6 +210,7 @@ AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {
{
MutexLockerEx
mu
(
CodeCache_lock
,
Mutex
::
_no_safepoint_check_flag
);
blob
=
new
(
size
)
AdapterBlob
(
size
,
cb
);
CodeCache
::
commit
(
blob
);
}
// Track memory usage statistic after releasing CodeCache_lock
MemoryService
::
track_code_cache_memory_usage
();
...
...
@@ -281,7 +282,6 @@ RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name,
tty
->
print_cr
(
"Decoding %s "
INTPTR_FORMAT
,
stub_id
,
stub
);
Disassembler
::
decode
(
stub
->
instructions_begin
(),
stub
->
instructions_end
());
}
VTune
::
register_stub
(
stub_id
,
stub
->
instructions_begin
(),
stub
->
instructions_end
());
Forte
::
register_stub
(
stub_id
,
stub
->
instructions_begin
(),
stub
->
instructions_end
());
if
(
JvmtiExport
::
should_post_dynamic_code_generated
())
{
...
...
@@ -356,7 +356,6 @@ DeoptimizationBlob* DeoptimizationBlob::create(
tty
->
print_cr
(
"Decoding %s "
INTPTR_FORMAT
,
blob_id
,
blob
);
Disassembler
::
decode
(
blob
->
instructions_begin
(),
blob
->
instructions_end
());
}
VTune
::
register_stub
(
blob_id
,
blob
->
instructions_begin
(),
blob
->
instructions_end
());
Forte
::
register_stub
(
blob_id
,
blob
->
instructions_begin
(),
blob
->
instructions_end
());
if
(
JvmtiExport
::
should_post_dynamic_code_generated
())
{
...
...
@@ -414,7 +413,6 @@ UncommonTrapBlob* UncommonTrapBlob::create(
tty
->
print_cr
(
"Decoding %s "
INTPTR_FORMAT
,
blob_id
,
blob
);
Disassembler
::
decode
(
blob
->
instructions_begin
(),
blob
->
instructions_end
());
}
VTune
::
register_stub
(
blob_id
,
blob
->
instructions_begin
(),
blob
->
instructions_end
());
Forte
::
register_stub
(
blob_id
,
blob
->
instructions_begin
(),
blob
->
instructions_end
());
if
(
JvmtiExport
::
should_post_dynamic_code_generated
())
{
...
...
@@ -474,7 +472,6 @@ ExceptionBlob* ExceptionBlob::create(
tty
->
print_cr
(
"Decoding %s "
INTPTR_FORMAT
,
blob_id
,
blob
);
Disassembler
::
decode
(
blob
->
instructions_begin
(),
blob
->
instructions_end
());
}
VTune
::
register_stub
(
blob_id
,
blob
->
instructions_begin
(),
blob
->
instructions_end
());
Forte
::
register_stub
(
blob_id
,
blob
->
instructions_begin
(),
blob
->
instructions_end
());
if
(
JvmtiExport
::
should_post_dynamic_code_generated
())
{
...
...
@@ -533,7 +530,6 @@ SafepointBlob* SafepointBlob::create(
tty
->
print_cr
(
"Decoding %s "
INTPTR_FORMAT
,
blob_id
,
blob
);
Disassembler
::
decode
(
blob
->
instructions_begin
(),
blob
->
instructions_end
());
}
VTune
::
register_stub
(
blob_id
,
blob
->
instructions_begin
(),
blob
->
instructions_end
());
Forte
::
register_stub
(
blob_id
,
blob
->
instructions_begin
(),
blob
->
instructions_end
());
if
(
JvmtiExport
::
should_post_dynamic_code_generated
())
{
...
...
src/share/vm/code/codeCache.cpp
浏览文件 @
9d513174
...
...
@@ -93,6 +93,8 @@ class CodeBlob_sizes {
CodeHeap
*
CodeCache
::
_heap
=
new
CodeHeap
();
int
CodeCache
::
_number_of_blobs
=
0
;
int
CodeCache
::
_number_of_adapters
=
0
;
int
CodeCache
::
_number_of_nmethods
=
0
;
int
CodeCache
::
_number_of_nmethods_with_dependencies
=
0
;
bool
CodeCache
::
_needs_cache_clean
=
false
;
nmethod
*
CodeCache
::
_scavenge_root_nmethods
=
NULL
;
...
...
@@ -176,8 +178,14 @@ void CodeCache::free(CodeBlob* cb) {
verify_if_often
();
print_trace
(
"free"
,
cb
);
if
(
cb
->
is_nmethod
()
&&
((
nmethod
*
)
cb
)
->
has_dependencies
())
{
_number_of_nmethods_with_dependencies
--
;
if
(
cb
->
is_nmethod
())
{
_number_of_nmethods
--
;
if
(((
nmethod
*
)
cb
)
->
has_dependencies
())
{
_number_of_nmethods_with_dependencies
--
;
}
}
if
(
cb
->
is_adapter_blob
())
{
_number_of_adapters
--
;
}
_number_of_blobs
--
;
...
...
@@ -191,9 +199,16 @@ void CodeCache::free(CodeBlob* cb) {
void
CodeCache
::
commit
(
CodeBlob
*
cb
)
{
// this is called by nmethod::nmethod, which must already own CodeCache_lock
assert_locked_or_safepoint
(
CodeCache_lock
);
if
(
cb
->
is_nmethod
()
&&
((
nmethod
*
)
cb
)
->
has_dependencies
())
{
_number_of_nmethods_with_dependencies
++
;
if
(
cb
->
is_nmethod
())
{
_number_of_nmethods
++
;
if
(((
nmethod
*
)
cb
)
->
has_dependencies
())
{
_number_of_nmethods_with_dependencies
++
;
}
}
if
(
cb
->
is_adapter_blob
())
{
_number_of_adapters
++
;
}
// flush the hardware I-cache
ICache
::
invalidate_range
(
cb
->
instructions_begin
(),
cb
->
instructions_size
());
}
...
...
src/share/vm/code/codeCache.hpp
浏览文件 @
9d513174
/*
* Copyright (c) 1997, 20
08
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -43,6 +43,8 @@ class CodeCache : AllStatic {
// 4422213 or 4436291 for details.
static
CodeHeap
*
_heap
;
static
int
_number_of_blobs
;
static
int
_number_of_adapters
;
static
int
_number_of_nmethods
;
static
int
_number_of_nmethods_with_dependencies
;
static
bool
_needs_cache_clean
;
static
nmethod
*
_scavenge_root_nmethods
;
// linked via nm->scavenge_root_link()
...
...
@@ -105,6 +107,8 @@ class CodeCache : AllStatic {
static
nmethod
*
first_nmethod
();
static
nmethod
*
next_nmethod
(
CodeBlob
*
cb
);
static
int
nof_blobs
()
{
return
_number_of_blobs
;
}
static
int
nof_adapters
()
{
return
_number_of_adapters
;
}
static
int
nof_nmethods
()
{
return
_number_of_nmethods
;
}
// GC support
static
void
gc_epilogue
();
...
...
src/share/vm/code/nmethod.cpp
浏览文件 @
9d513174
...
...
@@ -397,11 +397,6 @@ void nmethod::add_handler_for_exception_and_pc(Handle exception, address pc, add
//-------------end of code for ExceptionCache--------------
void
nmFlags
::
clear
()
{
assert
(
sizeof
(
nmFlags
)
==
sizeof
(
int
),
"using more than one word for nmFlags"
);
*
(
jint
*
)
this
=
0
;
}
int
nmethod
::
total_size
()
const
{
return
code_size
()
+
...
...
@@ -419,8 +414,32 @@ const char* nmethod::compile_kind() const {
return
NULL
;
}
// %%% This variable is no longer used?
int
nmethod
::
_zombie_instruction_size
=
NativeJump
::
instruction_size
;
// Fill in default values for various flag fields
void
nmethod
::
init_defaults
()
{
_state
=
alive
;
_marked_for_reclamation
=
0
;
_has_flushed_dependencies
=
0
;
_speculatively_disconnected
=
0
;
_has_unsafe_access
=
0
;
_has_method_handle_invokes
=
0
;
_marked_for_deoptimization
=
0
;
_lock_count
=
0
;
_stack_traversal_mark
=
0
;
_unload_reported
=
false
;
// jvmti state
NOT_PRODUCT
(
_has_debug_info
=
false
);
_oops_do_mark_link
=
NULL
;
_jmethod_id
=
NULL
;
_osr_link
=
NULL
;
_scavenge_root_link
=
NULL
;
_scavenge_root_state
=
0
;
_saved_nmethod_link
=
NULL
;
_compiler
=
NULL
;
#ifdef HAVE_DTRACE_H
_trap_offset
=
0
;
#endif // def HAVE_DTRACE_H
}
nmethod
*
nmethod
::
new_native_nmethod
(
methodHandle
method
,
...
...
@@ -580,25 +599,16 @@ nmethod::nmethod(
debug_only
(
No_Safepoint_Verifier
nsv
;)
assert_locked_or_safepoint
(
CodeCache_lock
);
NOT_PRODUCT
(
_has_debug_info
=
false
);
_oops_do_mark_link
=
NULL
;
init_defaults
();
_method
=
method
;
_entry_bci
=
InvocationEntryBci
;
_jmethod_id
=
NULL
;
_osr_link
=
NULL
;
_scavenge_root_link
=
NULL
;
_scavenge_root_state
=
0
;
_saved_nmethod_link
=
NULL
;
_compiler
=
NULL
;
// We have no exception handler or deopt handler make the
// values something that will never match a pc like the nmethod vtable entry
_exception_offset
=
0
;
_deoptimize_offset
=
0
;
_deoptimize_mh_offset
=
0
;
_orig_pc_offset
=
0
;
#ifdef HAVE_DTRACE_H
_trap_offset
=
0
;
#endif // def HAVE_DTRACE_H
_stub_offset
=
data_offset
();
_consts_offset
=
data_offset
();
_oops_offset
=
data_offset
();
...
...
@@ -616,17 +626,9 @@ nmethod::nmethod(
_exception_cache
=
NULL
;
_pc_desc_cache
.
reset_to
(
NULL
);
flags
.
clear
();
flags
.
state
=
alive
;
_markedForDeoptimization
=
0
;
_lock_count
=
0
;
_stack_traversal_mark
=
0
;
code_buffer
->
copy_oops_to
(
this
);
debug_only
(
verify_scavenge_root_oops
());
CodeCache
::
commit
(
this
);
VTune
::
create_nmethod
(
this
);
}
if
(
PrintNativeNMethods
||
PrintDebugInfo
||
PrintRelocations
||
PrintDependencies
)
{
...
...
@@ -674,15 +676,9 @@ nmethod::nmethod(
debug_only
(
No_Safepoint_Verifier
nsv
;)
assert_locked_or_safepoint
(
CodeCache_lock
);
NOT_PRODUCT
(
_has_debug_info
=
false
);
_oops_do_mark_link
=
NULL
;
init_defaults
();
_method
=
method
;
_entry_bci
=
InvocationEntryBci
;
_jmethod_id
=
NULL
;
_osr_link
=
NULL
;
_scavenge_root_link
=
NULL
;
_scavenge_root_state
=
0
;
_compiler
=
NULL
;
// We have no exception handler or deopt handler make the
// values something that will never match a pc like the nmethod vtable entry
_exception_offset
=
0
;
...
...
@@ -708,17 +704,9 @@ nmethod::nmethod(
_exception_cache
=
NULL
;
_pc_desc_cache
.
reset_to
(
NULL
);
flags
.
clear
();
flags
.
state
=
alive
;
_markedForDeoptimization
=
0
;
_lock_count
=
0
;
_stack_traversal_mark
=
0
;
code_buffer
->
copy_oops_to
(
this
);
debug_only
(
verify_scavenge_root_oops
());
CodeCache
::
commit
(
this
);
VTune
::
create_nmethod
(
this
);
}
if
(
PrintNMethods
||
PrintDebugInfo
||
PrintRelocations
||
PrintDependencies
)
{
...
...
@@ -783,21 +771,13 @@ nmethod::nmethod(
debug_only
(
No_Safepoint_Verifier
nsv
;)
assert_locked_or_safepoint
(
CodeCache_lock
);
NOT_PRODUCT
(
_has_debug_info
=
false
);
_oops_do_mark_link
=
NULL
;
init_defaults
();
_method
=
method
;
_
jmethod_id
=
NULL
;
_
entry_bci
=
entry_bci
;
_compile_id
=
compile_id
;
_comp_level
=
comp_level
;
_entry_bci
=
entry_bci
;
_osr_link
=
NULL
;
_scavenge_root_link
=
NULL
;
_scavenge_root_state
=
0
;
_compiler
=
compiler
;
_orig_pc_offset
=
orig_pc_offset
;
#ifdef HAVE_DTRACE_H
_trap_offset
=
0
;
#endif // def HAVE_DTRACE_H
_stub_offset
=
instructions_offset
()
+
code_buffer
->
total_offset_of
(
code_buffer
->
stubs
()
->
start
());
// Exception handler and deopt handler are in the stub section
...
...
@@ -824,15 +804,6 @@ nmethod::nmethod(
_exception_cache
=
NULL
;
_pc_desc_cache
.
reset_to
(
scopes_pcs_begin
());
flags
.
clear
();
flags
.
state
=
alive
;
_markedForDeoptimization
=
0
;
_unload_reported
=
false
;
// jvmti state
_lock_count
=
0
;
_stack_traversal_mark
=
0
;
// Copy contents of ScopeDescRecorder to nmethod
code_buffer
->
copy_oops_to
(
this
);
debug_info
->
copy_to
(
this
);
...
...
@@ -844,8 +815,6 @@ nmethod::nmethod(
CodeCache
::
commit
(
this
);
VTune
::
create_nmethod
(
this
);
// Copy contents of ExceptionHandlerTable to nmethod
handler_table
->
copy_to
(
this
);
nul_chk_table
->
copy_to
(
this
);
...
...
@@ -991,11 +960,6 @@ void nmethod::print_nmethod(bool printmethod) {
}
void
nmethod
::
set_version
(
int
v
)
{
flags
.
version
=
v
;
}
// Promote one word from an assembly-time handle to a live embedded oop.
inline
void
nmethod
::
initialize_immediate_oop
(
oop
*
dest
,
jobject
handle
)
{
if
(
handle
==
NULL
||
...
...
@@ -1142,6 +1106,8 @@ void nmethod::cleanup_inline_caches() {
// This is a private interface with the sweeper.
void
nmethod
::
mark_as_seen_on_stack
()
{
assert
(
is_not_entrant
(),
"must be a non-entrant method"
);
// Set the traversal mark to ensure that the sweeper does 2
// cleaning passes before moving to zombie.
set_stack_traversal_mark
(
NMethodSweeper
::
traversal_count
());
}
...
...
@@ -1210,7 +1176,7 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
// for later on.
CodeCache
::
set_needs_cache_clean
(
true
);
}
flags
.
state
=
unloaded
;
_
state
=
unloaded
;
// Log the unloading.
log_state_change
();
...
...
@@ -1236,21 +1202,21 @@ void nmethod::log_state_change() const {
if
(
LogCompilation
)
{
if
(
xtty
!=
NULL
)
{
ttyLocker
ttyl
;
// keep the following output all in one block
if
(
flags
.
state
==
unloaded
)
{
if
(
_
state
==
unloaded
)
{
xtty
->
begin_elem
(
"make_unloaded thread='"
UINTX_FORMAT
"'"
,
os
::
current_thread_id
());
}
else
{
xtty
->
begin_elem
(
"make_not_entrant thread='"
UINTX_FORMAT
"'%s"
,
os
::
current_thread_id
(),
(
flags
.
state
==
zombie
?
" zombie='1'"
:
""
));
(
_
state
==
zombie
?
" zombie='1'"
:
""
));
}
log_identity
(
xtty
);
xtty
->
stamp
();
xtty
->
end_elem
();
}
}
if
(
PrintCompilation
&&
flags
.
state
!=
unloaded
)
{
print_on
(
tty
,
flags
.
state
==
zombie
?
"made zombie "
:
"made not entrant "
);
if
(
PrintCompilation
&&
_
state
!=
unloaded
)
{
print_on
(
tty
,
_
state
==
zombie
?
"made zombie "
:
"made not entrant "
);
tty
->
cr
();
}
}
...
...
@@ -1261,8 +1227,9 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
bool
was_alive
=
false
;
// Make sure
the nmethod is not
flushed in case of a safepoint in code below.
// Make sure
neither the nmethod nor the method is
flushed in case of a safepoint in code below.
nmethodLocker
nml
(
this
);
methodHandle
the_method
(
method
());
{
// If the method is already zombie there is nothing to do
...
...
@@ -1282,7 +1249,7 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
// Enter critical section. Does not block for safepoint.
MutexLockerEx
pl
(
Patching_lock
,
Mutex
::
_no_safepoint_check_flag
);
if
(
flags
.
state
==
state
)
{
if
(
_
state
==
state
)
{
// another thread already performed this transition so nothing
// to do, but return false to indicate this.
return
false
;
...
...
@@ -1293,17 +1260,37 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
if
(
!
is_osr_method
()
&&
!
is_not_entrant
())
{
NativeJump
::
patch_verified_entry
(
entry_point
(),
verified_entry_point
(),
SharedRuntime
::
get_handle_wrong_method_stub
());
assert
(
NativeJump
::
instruction_size
==
nmethod
::
_zombie_instruction_size
,
""
);
}
was_alive
=
is_in_use
();
// Read state under lock
if
(
is_in_use
())
{
// It's a true state change, so mark the method as decompiled.
// Do it only for transition from alive.
inc_decompile_count
();
}
// Change state
flags
.
state
=
state
;
_
state
=
state
;
// Log the transition once
log_state_change
();
// Remove nmethod from method.
// We need to check if both the _code and _from_compiled_code_entry_point
// refer to this nmethod because there is a race in setting these two fields
// in methodOop as seen in bugid 4947125.
// If the vep() points to the zombie nmethod, the memory for the nmethod
// could be flushed and the compiler and vtable stubs could still call
// through it.
if
(
method
()
!=
NULL
&&
(
method
()
->
code
()
==
this
||
method
()
->
from_compiled_entry
()
==
verified_entry_point
()))
{
HandleMark
hm
;
method
()
->
clear_code
();
}
if
(
state
==
not_entrant
)
{
mark_as_seen_on_stack
();
}
}
// leave critical region under Patching_lock
// When the nmethod becomes zombie it is no longer alive so the
...
...
@@ -1311,18 +1298,17 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
// state will be flushed later when the transition to zombie
// happens or they get unloaded.
if
(
state
==
zombie
)
{
// zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
// and it hasn't already been reported for this nmethod then report it now.
// (the event may have been reported earilier if the GC marked it for unloading).
post_compiled_method_unload
();
MutexLockerEx
mu
(
CodeCache_lock
,
Mutex
::
_no_safepoint_check_flag
);
flush_dependencies
(
NULL
);
}
else
{
assert
(
state
==
not_entrant
,
"other cases may need to be handled differently"
);
}
if
(
state
==
not_entrant
)
{
Events
::
log
(
"Make nmethod not entrant "
INTPTR_FORMAT
,
this
);
}
else
{
Events
::
log
(
"Make nmethod zombie "
INTPTR_FORMAT
,
this
);
}
if
(
TraceCreateZombies
)
{
tty
->
print_cr
(
"nmethod <"
INTPTR_FORMAT
"> code made %s"
,
this
,
(
state
==
not_entrant
)
?
"not entrant"
:
"zombie"
);
}
...
...
@@ -1330,47 +1316,6 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
// Make sweeper aware that there is a zombie method that needs to be removed
NMethodSweeper
::
notify
(
this
);
// not_entrant only stuff
if
(
state
==
not_entrant
)
{
mark_as_seen_on_stack
();
}
if
(
was_alive
)
{
// It's a true state change, so mark the method as decompiled.
// Do it only for transition from alive.
inc_decompile_count
();
}
// zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
// and it hasn't already been reported for this nmethod then report it now.
// (the event may have been reported earilier if the GC marked it for unloading).
if
(
state
==
zombie
)
{
post_compiled_method_unload
();
}
// Zombie only stuff
if
(
state
==
zombie
)
{
VTune
::
delete_nmethod
(
this
);
}
// Check whether method got unloaded at a safepoint before this,
// if so we can skip the flushing steps below
if
(
method
()
==
NULL
)
return
true
;
// Remove nmethod from method.
// We need to check if both the _code and _from_compiled_code_entry_point
// refer to this nmethod because there is a race in setting these two fields
// in methodOop as seen in bugid 4947125.
// If the vep() points to the zombie nmethod, the memory for the nmethod
// could be flushed and the compiler and vtable stubs could still call
// through it.
if
(
method
()
->
code
()
==
this
||
method
()
->
from_compiled_entry
()
==
verified_entry_point
())
{
HandleMark
hm
;
method
()
->
clear_code
();
}
return
true
;
}
...
...
@@ -2109,7 +2054,6 @@ address nmethod::continuation_for_implicit_exception(address pc) {
void
nmethod_init
()
{
// make sure you didn't forget to adjust the filler fields
assert
(
sizeof
(
nmFlags
)
<=
4
,
"nmFlags occupies more than a word"
);
assert
(
sizeof
(
nmethod
)
%
oopSize
==
0
,
"nmethod size must be multiple of a word"
);
}
...
...
@@ -2345,7 +2289,6 @@ void nmethod::print() const {
tty
->
print
(
"((nmethod*) "
INTPTR_FORMAT
") "
,
this
);
tty
->
print
(
" for method "
INTPTR_FORMAT
,
(
address
)
method
());
tty
->
print
(
" { "
);
if
(
version
())
tty
->
print
(
"v%d "
,
version
());
if
(
is_in_use
())
tty
->
print
(
"in_use "
);
if
(
is_not_entrant
())
tty
->
print
(
"not_entrant "
);
if
(
is_zombie
())
tty
->
print
(
"zombie "
);
...
...
src/share/vm/code/nmethod.hpp
浏览文件 @
9d513174
...
...
@@ -78,29 +78,8 @@ class PcDescCache VALUE_OBJ_CLASS_SPEC {
// nmethods (native methods) are the compiled code versions of Java methods.
struct
nmFlags
{
friend
class
VMStructs
;
unsigned
int
version
:
8
;
// version number (0 = first version)
unsigned
int
age
:
4
;
// age (in # of sweep steps)
unsigned
int
state
:
2
;
// {alive, zombie, unloaded)
unsigned
int
isUncommonRecompiled
:
1
;
// recompiled because of uncommon trap?
unsigned
int
isToBeRecompiled
:
1
;
// to be recompiled as soon as it matures
unsigned
int
hasFlushedDependencies
:
1
;
// Used for maintenance of dependencies
unsigned
int
markedForReclamation
:
1
;
// Used by NMethodSweeper
unsigned
int
has_unsafe_access
:
1
;
// May fault due to unsafe access.
unsigned
int
has_method_handle_invokes
:
1
;
// Has this method MethodHandle invokes?
unsigned
int
speculatively_disconnected
:
1
;
// Marked for potential unload
void
clear
();
};
// A nmethod contains:
//
// An nmethod contains:
// - header (the nmethod structure)
// [Relocation]
// - relocation information
...
...
@@ -131,8 +110,6 @@ class nmethod : public CodeBlob {
friend
class
CodeCache
;
// non-perm oops
private:
// Shared fields for all nmethod's
static
int
_zombie_instruction_size
;
methodOop
_method
;
int
_entry_bci
;
// != InvocationEntryBci if this nmethod is an on-stack replacement method
jmethodID
_jmethod_id
;
// Cache of method()->jmethod_id()
...
...
@@ -147,6 +124,11 @@ class nmethod : public CodeBlob {
AbstractCompiler
*
_compiler
;
// The compiler which compiled this nmethod
// offsets for entry points
address
_entry_point
;
// entry point with class check
address
_verified_entry_point
;
// entry point without class check
address
_osr_entry_point
;
// entry point for on stack replacement
// Offsets for different nmethod parts
int
_exception_offset
;
// All deoptee's will resume execution at this location described by
...
...
@@ -175,23 +157,31 @@ class nmethod : public CodeBlob {
// pc during a deopt.
int
_orig_pc_offset
;
int
_compile_id
;
// which compilation made this nmethod
int
_comp_level
;
// compilation level
int
_compile_id
;
// which compilation made this nmethod
int
_comp_level
;
// compilation level
// offsets for entry points
address
_entry_point
;
// entry point with class check
address
_verified_entry_point
;
// entry point without class check
address
_osr_entry_point
;
// entry point for on stack replacement
// protected by CodeCache_lock
bool
_has_flushed_dependencies
;
// Used for maintenance of dependencies (CodeCache_lock)
bool
_speculatively_disconnected
;
// Marked for potential unload
bool
_marked_for_reclamation
;
// Used by NMethodSweeper (set only by sweeper)
bool
_marked_for_deoptimization
;
// Used for stack deoptimization
// used by jvmti to track if an unload event has been posted for this nmethod.
bool
_unload_reported
;
// set during construction
unsigned
int
_has_unsafe_access
:
1
;
// May fault due to unsafe access.
unsigned
int
_has_method_handle_invokes
:
1
;
// Has this method MethodHandle invokes?
// Protected by Patching_lock
unsigned
char
_state
;
// {alive, not_entrant, zombie, unloaded)
nmFlags
flags
;
// various flags to keep track of nmethod state
bool
_markedForDeoptimization
;
// Used for stack deoptimization
enum
{
alive
=
0
,
not_entrant
=
1
,
// uncommon trap has happened but activations may still exist
zombie
=
2
,
unloaded
=
3
};
// used by jvmti to track if an unload event has been posted for this nmethod.
bool
_unload_reported
;
jbyte
_scavenge_root_state
;
...
...
@@ -270,15 +260,15 @@ class nmethod : public CodeBlob {
bool
make_not_entrant_or_zombie
(
unsigned
int
state
);
void
inc_decompile_count
();
// used to check that writes to nmFlags are done consistently.
static
void
check_safepoint
()
PRODUCT_RETURN
;
// Used to manipulate the exception cache
void
add_exception_cache_entry
(
ExceptionCache
*
new_entry
);
ExceptionCache
*
exception_cache_entry_for_exception
(
Handle
exception
);
// Inform external interfaces that a compiled method has been unloaded
inline
void
post_compiled_method_unload
();
void
post_compiled_method_unload
();
// Initailize fields to their default values
void
init_defaults
();
public:
// create nmethod with entry_bci
...
...
@@ -393,11 +383,11 @@ class nmethod : public CodeBlob {
address
verified_entry_point
()
const
{
return
_verified_entry_point
;
}
// if klass is correct
// flag accessing and manipulation
bool
is_in_use
()
const
{
return
flags
.
state
==
alive
;
}
bool
is_alive
()
const
{
return
flags
.
state
==
alive
||
flags
.
state
==
not_entrant
;
}
bool
is_not_entrant
()
const
{
return
flags
.
state
==
not_entrant
;
}
bool
is_zombie
()
const
{
return
flags
.
state
==
zombie
;
}
bool
is_unloaded
()
const
{
return
flags
.
state
==
unloaded
;
}
bool
is_in_use
()
const
{
return
_
state
==
alive
;
}
bool
is_alive
()
const
{
return
_state
==
alive
||
_
state
==
not_entrant
;
}
bool
is_not_entrant
()
const
{
return
_
state
==
not_entrant
;
}
bool
is_zombie
()
const
{
return
_
state
==
zombie
;
}
bool
is_unloaded
()
const
{
return
_
state
==
unloaded
;
}
// Make the nmethod non entrant. The nmethod will continue to be
// alive. It is used when an uncommon trap happens. Returns true
...
...
@@ -410,37 +400,33 @@ class nmethod : public CodeBlob {
bool
unload_reported
()
{
return
_unload_reported
;
}
void
set_unload_reported
()
{
_unload_reported
=
true
;
}
bool
is_marked_for_deoptimization
()
const
{
return
_marked
ForD
eoptimization
;
}
void
mark_for_deoptimization
()
{
_marked
ForD
eoptimization
=
true
;
}
bool
is_marked_for_deoptimization
()
const
{
return
_marked
_for_d
eoptimization
;
}
void
mark_for_deoptimization
()
{
_marked
_for_d
eoptimization
=
true
;
}
void
make_unloaded
(
BoolObjectClosure
*
is_alive
,
oop
cause
);
bool
has_dependencies
()
{
return
dependencies_size
()
!=
0
;
}
void
flush_dependencies
(
BoolObjectClosure
*
is_alive
);
bool
has_flushed_dependencies
()
{
return
flags
.
hasFlushedD
ependencies
;
}
void
set_has_flushed_dependencies
()
{
bool
has_flushed_dependencies
()
{
return
_has_flushed_d
ependencies
;
}
void
set_has_flushed_dependencies
()
{
assert
(
!
has_flushed_dependencies
(),
"should only happen once"
);
flags
.
hasFlushedD
ependencies
=
1
;
_has_flushed_d
ependencies
=
1
;
}
bool
is_marked_for_reclamation
()
const
{
return
flags
.
markedForReclamation
;
}
void
mark_for_reclamation
()
{
flags
.
markedForReclamation
=
1
;
}
void
unmark_for_reclamation
()
{
flags
.
markedForReclamation
=
0
;
}
bool
is_marked_for_reclamation
()
const
{
return
_marked_for_reclamation
;
}
void
mark_for_reclamation
()
{
_marked_for_reclamation
=
1
;
}
bool
has_unsafe_access
()
const
{
return
flags
.
has_unsafe_access
;
}
void
set_has_unsafe_access
(
bool
z
)
{
flags
.
has_unsafe_access
=
z
;
}
bool
has_unsafe_access
()
const
{
return
_
has_unsafe_access
;
}
void
set_has_unsafe_access
(
bool
z
)
{
_
has_unsafe_access
=
z
;
}
bool
has_method_handle_invokes
()
const
{
return
flags
.
has_method_handle_invokes
;
}
void
set_has_method_handle_invokes
(
bool
z
)
{
flags
.
has_method_handle_invokes
=
z
;
}
bool
has_method_handle_invokes
()
const
{
return
_
has_method_handle_invokes
;
}
void
set_has_method_handle_invokes
(
bool
z
)
{
_
has_method_handle_invokes
=
z
;
}
bool
is_speculatively_disconnected
()
const
{
return
flags
.
speculatively_disconnected
;
}
void
set_speculatively_disconnected
(
bool
z
)
{
flags
.
speculatively_disconnected
=
z
;
}
bool
is_speculatively_disconnected
()
const
{
return
_
speculatively_disconnected
;
}
void
set_speculatively_disconnected
(
bool
z
)
{
_
speculatively_disconnected
=
z
;
}
int
comp_level
()
const
{
return
_comp_level
;
}
int
version
()
const
{
return
flags
.
version
;
}
void
set_version
(
int
v
);
// Support for oops in scopes and relocs:
// Note: index 0 is reserved for null.
oop
oop_at
(
int
index
)
const
{
return
index
==
0
?
(
oop
)
NULL
:
*
oop_addr_at
(
index
);
}
...
...
src/share/vm/code/vtableStubs.cpp
浏览文件 @
9d513174
/*
* Copyright (c) 1997, 20
09
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -50,7 +50,6 @@ void* VtableStub::operator new(size_t size, int code_size) {
}
_chunk
=
blob
->
instructions_begin
();
_chunk_end
=
_chunk
+
bytes
;
VTune
::
register_stub
(
"vtable stub"
,
_chunk
,
_chunk_end
);
Forte
::
register_stub
(
"vtable stub"
,
_chunk
,
_chunk_end
);
// Notify JVMTI about this stub. The event will be recorded by the enclosing
// JvmtiDynamicCodeEventCollector and posted when this thread has released
...
...
src/share/vm/includeDB_compiler2
浏览文件 @
9d513174
...
...
@@ -89,6 +89,21 @@ adlcVMDeps.hpp allocation.hpp
allocation.hpp c2_globals.hpp
bcEscapeAnalyzer.cpp bcEscapeAnalyzer.hpp
bcEscapeAnalyzer.cpp bitMap.inline.hpp
bcEscapeAnalyzer.cpp bytecode.hpp
bcEscapeAnalyzer.cpp ciConstant.hpp
bcEscapeAnalyzer.cpp ciField.hpp
bcEscapeAnalyzer.cpp ciMethodBlocks.hpp
bcEscapeAnalyzer.cpp ciStreams.hpp
bcEscapeAnalyzer.hpp allocation.hpp
bcEscapeAnalyzer.hpp ciMethod.hpp
bcEscapeAnalyzer.hpp ciMethodData.hpp
bcEscapeAnalyzer.hpp dependencies.hpp
bcEscapeAnalyzer.hpp growableArray.hpp
bcEscapeAnalyzer.hpp vectset.hpp
block.cpp allocation.inline.hpp
block.cpp block.hpp
block.cpp cfgnode.hpp
...
...
@@ -239,6 +254,7 @@ chaitin_<os_family>.cpp machnode.hpp
ciEnv.cpp compileLog.hpp
ciEnv.cpp runtime.hpp
ciMethod.cpp bcEscapeAnalyzer.hpp
ciMethod.cpp ciTypeFlow.hpp
ciMethod.cpp methodOop.hpp
...
...
src/share/vm/includeDB_core
浏览文件 @
9d513174
...
...
@@ -301,20 +301,6 @@ barrierSet.hpp oopsHierarchy.hpp
barrierSet.inline.hpp barrierSet.hpp
barrierSet.inline.hpp cardTableModRefBS.hpp
bcEscapeAnalyzer.cpp bcEscapeAnalyzer.hpp
bcEscapeAnalyzer.cpp bitMap.inline.hpp
bcEscapeAnalyzer.cpp bytecode.hpp
bcEscapeAnalyzer.cpp ciConstant.hpp
bcEscapeAnalyzer.cpp ciField.hpp
bcEscapeAnalyzer.cpp ciMethodBlocks.hpp
bcEscapeAnalyzer.cpp ciStreams.hpp
bcEscapeAnalyzer.hpp allocation.hpp
bcEscapeAnalyzer.hpp ciMethod.hpp
bcEscapeAnalyzer.hpp ciMethodData.hpp
bcEscapeAnalyzer.hpp dependencies.hpp
bcEscapeAnalyzer.hpp growableArray.hpp
biasedLocking.cpp biasedLocking.hpp
biasedLocking.cpp klass.inline.hpp
biasedLocking.cpp markOop.hpp
...
...
@@ -665,7 +651,6 @@ ciKlassKlass.hpp ciSymbol.hpp
ciMethod.cpp abstractCompiler.hpp
ciMethod.cpp allocation.inline.hpp
ciMethod.cpp bcEscapeAnalyzer.hpp
ciMethod.cpp bitMap.inline.hpp
ciMethod.cpp ciCallProfile.hpp
ciMethod.cpp ciExceptionHandler.hpp
...
...
@@ -964,7 +949,6 @@ classLoader.cpp threadService.hpp
classLoader.cpp timer.hpp
classLoader.cpp universe.inline.hpp
classLoader.cpp vmSymbols.hpp
classLoader.cpp vtune.hpp
classLoader.hpp classFileParser.hpp
classLoader.hpp perfData.hpp
...
...
@@ -1004,7 +988,6 @@ codeBlob.cpp relocInfo.hpp
codeBlob.cpp safepoint.hpp
codeBlob.cpp sharedRuntime.hpp
codeBlob.cpp vframe.hpp
codeBlob.cpp vtune.hpp
codeBlob.hpp codeBuffer.hpp
codeBlob.hpp frame.hpp
...
...
@@ -2167,7 +2150,6 @@ interpreter.cpp sharedRuntime.hpp
interpreter.cpp stubRoutines.hpp
interpreter.cpp templateTable.hpp
interpreter.cpp timer.hpp
interpreter.cpp vtune.hpp
interpreter.hpp cppInterpreter.hpp
interpreter.hpp stubs.hpp
...
...
@@ -2323,7 +2305,6 @@ java.cpp universe.hpp
java.cpp vmError.hpp
java.cpp vm_operations.hpp
java.cpp vm_version_<arch>.hpp
java.cpp vtune.hpp
java.hpp os.hpp
...
...
@@ -3050,7 +3031,6 @@ nmethod.cpp nmethod.hpp
nmethod.cpp scopeDesc.hpp
nmethod.cpp sharedRuntime.hpp
nmethod.cpp sweeper.hpp
nmethod.cpp vtune.hpp
nmethod.cpp xmlstream.hpp
nmethod.hpp codeBlob.hpp
...
...
@@ -3773,7 +3753,6 @@ sharedRuntime.cpp vframeArray.hpp
sharedRuntime.cpp vmSymbols.hpp
sharedRuntime.cpp vmreg_<arch>.inline.hpp
sharedRuntime.cpp vtableStubs.hpp
sharedRuntime.cpp vtune.hpp
sharedRuntime.cpp xmlstream.hpp
sharedRuntime.hpp allocation.hpp
...
...
@@ -3937,7 +3916,6 @@ stubCodeGenerator.cpp disassembler.hpp
stubCodeGenerator.cpp forte.hpp
stubCodeGenerator.cpp oop.inline.hpp
stubCodeGenerator.cpp stubCodeGenerator.hpp
stubCodeGenerator.cpp vtune.hpp
stubCodeGenerator.hpp allocation.hpp
stubCodeGenerator.hpp assembler.hpp
...
...
@@ -4458,7 +4436,6 @@ universe.cpp universe.hpp
universe.cpp universe.inline.hpp
universe.cpp vmSymbols.hpp
universe.cpp vm_operations.hpp
universe.cpp vtune.hpp
universe.hpp growableArray.hpp
universe.hpp handles.hpp
...
...
@@ -4721,7 +4698,6 @@ vtableStubs.cpp mutexLocker.hpp
vtableStubs.cpp resourceArea.hpp
vtableStubs.cpp sharedRuntime.hpp
vtableStubs.cpp vtableStubs.hpp
vtableStubs.cpp vtune.hpp
vtableStubs.hpp allocation.hpp
...
...
@@ -4735,11 +4711,6 @@ vtableStubs_<arch_model>.cpp sharedRuntime.hpp
vtableStubs_<arch_model>.cpp vmreg_<arch>.inline.hpp
vtableStubs_<arch_model>.cpp vtableStubs.hpp
vtune.hpp allocation.hpp
vtune_<os_family>.cpp interpreter.hpp
vtune_<os_family>.cpp vtune.hpp
watermark.hpp allocation.hpp
watermark.hpp globalDefinitions.hpp
...
...
src/share/vm/interpreter/interpreter.cpp
浏览文件 @
9d513174
...
...
@@ -99,11 +99,6 @@ void interpreter_init() {
#endif // PRODUCT
// need to hit every safepoint in order to call zapping routine
// register the interpreter
VTune
::
register_stub
(
"Interpreter"
,
AbstractInterpreter
::
code
()
->
code_start
(),
AbstractInterpreter
::
code
()
->
code_end
()
);
Forte
::
register_stub
(
"Interpreter"
,
AbstractInterpreter
::
code
()
->
code_start
(),
...
...
src/share/vm/opto/doCall.cpp
浏览文件 @
9d513174
...
...
@@ -343,7 +343,8 @@ bool Parse::can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass* kl
// being initialized. Uncommon-trap for not-initialized static or
// v-calls. Let interface calls happen.
ciInstanceKlass
*
holder_klass
=
dest_method
->
holder
();
if
(
!
holder_klass
->
is_initialized
()
&&
if
(
!
holder_klass
->
is_being_initialized
()
&&
!
holder_klass
->
is_initialized
()
&&
!
holder_klass
->
is_interface
())
{
uncommon_trap
(
Deoptimization
::
Reason_uninitialized
,
Deoptimization
::
Action_reinterpret
,
...
...
src/share/vm/opto/parse.hpp
浏览文件 @
9d513174
...
...
@@ -480,6 +480,7 @@ class Parse : public GraphKit {
bool
push_constant
(
ciConstant
con
,
bool
require_constant
=
false
);
// implementation of object creation bytecodes
void
emit_guard_for_new
(
ciInstanceKlass
*
klass
);
void
do_new
();
void
do_newarray
(
BasicType
elemtype
);
void
do_anewarray
();
...
...
src/share/vm/opto/parseHelper.cpp
浏览文件 @
9d513174
/*
* Copyright (c) 1998, 20
09
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -197,6 +197,43 @@ void Parse::array_store_check() {
}
void
Parse
::
emit_guard_for_new
(
ciInstanceKlass
*
klass
)
{
// Emit guarded new
// if (klass->_init_thread != current_thread ||
// klass->_init_state != being_initialized)
// uncommon_trap
Node
*
cur_thread
=
_gvn
.
transform
(
new
(
C
,
1
)
ThreadLocalNode
()
);
Node
*
merge
=
new
(
C
,
3
)
RegionNode
(
3
);
_gvn
.
set_type
(
merge
,
Type
::
CONTROL
);
Node
*
kls
=
makecon
(
TypeKlassPtr
::
make
(
klass
));
Node
*
init_thread_offset
=
_gvn
.
MakeConX
(
instanceKlass
::
init_thread_offset_in_bytes
()
+
klassOopDesc
::
klass_part_offset_in_bytes
());
Node
*
adr_node
=
basic_plus_adr
(
kls
,
kls
,
init_thread_offset
);
Node
*
init_thread
=
make_load
(
NULL
,
adr_node
,
TypeRawPtr
::
BOTTOM
,
T_ADDRESS
);
Node
*
tst
=
Bool
(
CmpP
(
init_thread
,
cur_thread
),
BoolTest
::
eq
);
IfNode
*
iff
=
create_and_map_if
(
control
(),
tst
,
PROB_ALWAYS
,
COUNT_UNKNOWN
);
set_control
(
IfTrue
(
iff
));
merge
->
set_req
(
1
,
IfFalse
(
iff
));
Node
*
init_state_offset
=
_gvn
.
MakeConX
(
instanceKlass
::
init_state_offset_in_bytes
()
+
klassOopDesc
::
klass_part_offset_in_bytes
());
adr_node
=
basic_plus_adr
(
kls
,
kls
,
init_state_offset
);
Node
*
init_state
=
make_load
(
NULL
,
adr_node
,
TypeInt
::
INT
,
T_INT
);
Node
*
being_init
=
_gvn
.
intcon
(
instanceKlass
::
being_initialized
);
tst
=
Bool
(
CmpI
(
init_state
,
being_init
),
BoolTest
::
eq
);
iff
=
create_and_map_if
(
control
(),
tst
,
PROB_ALWAYS
,
COUNT_UNKNOWN
);
set_control
(
IfTrue
(
iff
));
merge
->
set_req
(
2
,
IfFalse
(
iff
));
PreserveJVMState
pjvms
(
this
);
record_for_igvn
(
merge
);
set_control
(
merge
);
uncommon_trap
(
Deoptimization
::
Reason_uninitialized
,
Deoptimization
::
Action_reinterpret
,
klass
);
}
//------------------------------do_new-----------------------------------------
void
Parse
::
do_new
()
{
kill_dead_locals
();
...
...
@@ -206,7 +243,7 @@ void Parse::do_new() {
assert
(
will_link
,
"_new: typeflow responsibility"
);
// Should initialize, or throw an InstantiationError?
if
(
!
klass
->
is_initialized
()
||
if
(
!
klass
->
is_initialized
()
&&
!
klass
->
is_being_initialized
()
||
klass
->
is_abstract
()
||
klass
->
is_interface
()
||
klass
->
name
()
==
ciSymbol
::
java_lang_Class
()
||
iter
().
is_unresolved_klass
())
{
...
...
@@ -215,6 +252,9 @@ void Parse::do_new() {
klass
);
return
;
}
if
(
klass
->
is_being_initialized
())
{
emit_guard_for_new
(
klass
);
}
Node
*
kls
=
makecon
(
TypeKlassPtr
::
make
(
klass
));
Node
*
obj
=
new_instance
(
kls
);
...
...
src/share/vm/prims/jvmtiCodeBlobEvents.cpp
浏览文件 @
9d513174
...
...
@@ -118,7 +118,6 @@ void CodeBlobCollector::do_blob(CodeBlob* cb) {
for
(
int
i
=
0
;
i
<
_global_code_blobs
->
length
();
i
++
)
{
JvmtiCodeBlobDesc
*
scb
=
_global_code_blobs
->
at
(
i
);
if
(
addr
==
scb
->
code_begin
())
{
ShouldNotReachHere
();
return
;
}
}
...
...
@@ -206,11 +205,11 @@ jvmtiError JvmtiCodeBlobEvents::generate_compiled_method_load_events(JvmtiEnv* e
MutexLockerEx
mu
(
CodeCache_lock
,
Mutex
::
_no_safepoint_check_flag
);
nmethod
*
current
=
CodeCache
::
first_nmethod
();
while
(
current
!=
NULL
)
{
// Lock the nmethod so it can't be freed
nmethodLocker
nml
(
current
);
// Only notify for live nmethods
if
(
current
->
is_alive
())
{
// Lock the nmethod so it can't be freed
nmethodLocker
nml
(
current
);
// Don't hold the lock over the notify or jmethodID creation
MutexUnlockerEx
mu
(
CodeCache_lock
,
Mutex
::
_no_safepoint_check_flag
);
current
->
get_and_cache_jmethod_id
();
...
...
src/share/vm/runtime/globals.hpp
浏览文件 @
9d513174
...
...
@@ -2541,9 +2541,6 @@ class CommandLineFlags {
"Enable String cache capabilities on String.java") \
\
/* statistics */
\
develop(bool, UseVTune, false, \
"enable support for Intel's VTune profiler") \
\
develop(bool, CountCompiledCalls, false, \
"counts method invocations") \
\
...
...
src/share/vm/runtime/init.cpp
浏览文件 @
9d513174
...
...
@@ -34,7 +34,6 @@ void perfMemory_init();
// Initialization done by Java thread in init_globals()
void
management_init
();
void
vtune_init
();
void
bytecodes_init
();
void
classLoader_init
();
void
codeCache_init
();
...
...
@@ -82,7 +81,6 @@ void vm_init_globals() {
jint
init_globals
()
{
HandleMark
hm
;
management_init
();
vtune_init
();
bytecodes_init
();
classLoader_init
();
codeCache_init
();
...
...
src/share/vm/runtime/java.cpp
浏览文件 @
9d513174
/*
* Copyright (c) 1997, 20
08
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -432,8 +432,6 @@ void before_exit(JavaThread * thread) {
print_statistics
();
Universe
::
heap
()
->
print_tracing_info
();
VTune
::
exit
();
{
MutexLocker
ml
(
BeforeExit_lock
);
_before_exit_status
=
BEFORE_EXIT_DONE
;
BeforeExit_lock
->
notify_all
();
...
...
src/share/vm/runtime/sharedRuntime.cpp
浏览文件 @
9d513174
...
...
@@ -2251,7 +2251,6 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
B
->
name
(),
fingerprint
->
as_string
(),
B
->
instructions_begin
());
VTune
::
register_stub
(
blob_id
,
B
->
instructions_begin
(),
B
->
instructions_end
());
Forte
::
register_stub
(
blob_id
,
B
->
instructions_begin
(),
B
->
instructions_end
());
if
(
JvmtiExport
::
should_post_dynamic_code_generated
())
{
...
...
src/share/vm/runtime/stubCodeGenerator.cpp
浏览文件 @
9d513174
/*
* Copyright (c) 1997, 20
08
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -132,7 +132,6 @@ StubCodeMark::~StubCodeMark() {
_cdesc
->
set_end
(
_cgen
->
assembler
()
->
pc
());
assert
(
StubCodeDesc
::
_list
==
_cdesc
,
"expected order on list"
);
_cgen
->
stub_epilog
(
_cdesc
);
VTune
::
register_stub
(
_cdesc
->
name
(),
_cdesc
->
begin
(),
_cdesc
->
end
());
Forte
::
register_stub
(
_cdesc
->
name
(),
_cdesc
->
begin
(),
_cdesc
->
end
());
if
(
JvmtiExport
::
should_post_dynamic_code_generated
())
{
...
...
src/share/vm/runtime/sweeper.cpp
浏览文件 @
9d513174
/*
* Copyright (c) 1997, 20
09
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -27,14 +27,15 @@
long
NMethodSweeper
::
_traversals
=
0
;
// No. of stack traversals performed
nmethod
*
NMethodSweeper
::
_current
=
NULL
;
// Current nmethod
int
NMethodSweeper
::
_seen
=
0
;
// No. of blobs we have currently processed in current pass of CodeCache
int
NMethodSweeper
::
_invocations
=
0
;
// No. of invocations left until we are completed with this pass
int
NMethodSweeper
::
_seen
=
0
;
// No. of nmethods we have currently processed in current pass of CodeCache
volatile
int
NMethodSweeper
::
_invocations
=
0
;
// No. of invocations left until we are completed with this pass
volatile
int
NMethodSweeper
::
_sweep_started
=
0
;
// Whether a sweep is in progress.
jint
NMethodSweeper
::
_locked_seen
=
0
;
jint
NMethodSweeper
::
_not_entrant_seen_on_stack
=
0
;
bool
NMethodSweeper
::
_rescan
=
false
;
bool
NMethodSweeper
::
_do_sweep
=
false
;
jint
NMethodSweeper
::
_sweep_started
=
0
;
bool
NMethodSweeper
::
_was_full
=
false
;
jint
NMethodSweeper
::
_advise_to_sweep
=
0
;
jlong
NMethodSweeper
::
_last_was_full
=
0
;
...
...
@@ -108,23 +109,14 @@ void NMethodSweeper::scan_stacks() {
// code cache is filling up
_last_was_full
=
os
::
javaTimeMillis
();
if
(
PrintMethodFlushing
)
{
tty
->
print_cr
(
"### sweeper: Live blobs:"
UINT32_FORMAT
"/Free code cache:"
SIZE_FORMAT
" bytes, restarting compiler"
,
CodeCache
::
nof_blobs
(),
CodeCache
::
unallocated_capacity
());
}
if
(
LogCompilation
&&
(
xtty
!=
NULL
))
{
ttyLocker
ttyl
;
xtty
->
begin_elem
(
"restart_compiler live_blobs='"
UINT32_FORMAT
"' free_code_cache='"
SIZE_FORMAT
"'"
,
CodeCache
::
nof_blobs
(),
CodeCache
::
unallocated_capacity
());
xtty
->
stamp
();
xtty
->
end_elem
();
}
log_sweep
(
"restart_compiler"
);
}
}
}
}
void
NMethodSweeper
::
possibly_sweep
()
{
assert
(
JavaThread
::
current
()
->
thread_state
()
==
_thread_in_vm
,
"must run in vm mode"
);
if
((
!
MethodFlushing
)
||
(
!
_do_sweep
))
return
;
if
(
_invocations
>
0
)
{
...
...
@@ -133,32 +125,31 @@ void NMethodSweeper::possibly_sweep() {
if
(
old
!=
0
)
{
return
;
}
sweep_code_cache
();
if
(
_invocations
>
0
)
{
sweep_code_cache
();
_invocations
--
;
}
_sweep_started
=
0
;
}
_sweep_started
=
0
;
}
void
NMethodSweeper
::
sweep_code_cache
()
{
#ifdef ASSERT
jlong
sweep_start
;
if
(
PrintMethodFlushing
)
{
if
(
PrintMethodFlushing
)
{
sweep_start
=
os
::
javaTimeMillis
();
}
#endif
if
(
PrintMethodFlushing
&&
Verbose
)
{
tty
->
print_cr
(
"### Sweep at %d out of %d. Invocations left: %d"
,
_seen
,
CodeCache
::
nof_blobs
(),
_invocations
);
}
// We want to visit all nmethods after NmethodSweepFraction invocations.
// If invocation is 1 we do the rest
int
todo
=
CodeCache
::
nof_blobs
();
if
(
_invocations
>
1
)
{
todo
=
(
CodeCache
::
nof_blobs
()
-
_seen
)
/
_invocations
;
tty
->
print_cr
(
"### Sweep at %d out of %d. Invocations left: %d"
,
_seen
,
CodeCache
::
nof_nmethods
(),
_invocations
);
}
// Compilers may check to sweep more often than stack scans happen,
// don't keep trying once it is all scanned
_invocations
--
;
// We want to visit all nmethods after NmethodSweepFraction
// invocations so divide the remaining number of nmethods by the
// remaining number of invocations. This is only an estimate since
// the number of nmethods changes during the sweep so the final
// stage must iterate until it there are no more nmethods.
int
todo
=
(
CodeCache
::
nof_nmethods
()
-
_seen
)
/
_invocations
;
assert
(
!
SafepointSynchronize
::
is_at_safepoint
(),
"should not be in safepoint when we get here"
);
assert
(
!
CodeCache_lock
->
owned_by_self
(),
"just checking"
);
...
...
@@ -166,11 +157,12 @@ void NMethodSweeper::sweep_code_cache() {
{
MutexLockerEx
mu
(
CodeCache_lock
,
Mutex
::
_no_safepoint_check_flag
);
for
(
int
i
=
0
;
i
<
todo
&&
_current
!=
NULL
;
i
++
)
{
// The last invocation iterates until there are no more nmethods
for
(
int
i
=
0
;
(
i
<
todo
||
_invocations
==
1
)
&&
_current
!=
NULL
;
i
++
)
{
// Since we will give up the CodeCache_lock, always skip ahead
to an nmethod.
//
Other blobs can be deleted by other threads
//
Read next before we potentially delete current
// Since we will give up the CodeCache_lock, always skip ahead
//
to the next nmethod. Other blobs can be deleted by other
//
threads but nmethods are only reclaimed by the sweeper.
nmethod
*
next
=
CodeCache
::
next_nmethod
(
_current
);
// Now ready to process nmethod and give up CodeCache_lock
...
...
@@ -183,6 +175,8 @@ void NMethodSweeper::sweep_code_cache() {
}
}
assert
(
_invocations
>
1
||
_current
==
NULL
,
"must have scanned the whole cache"
);
if
(
_current
==
NULL
&&
!
_rescan
&&
(
_locked_seen
||
_not_entrant_seen_on_stack
))
{
// we've completed a scan without making progress but there were
// nmethods we were unable to process either because they were
...
...
@@ -201,6 +195,10 @@ void NMethodSweeper::sweep_code_cache() {
tty
->
print_cr
(
"### sweeper: sweep time(%d): "
INT64_FORMAT
,
_invocations
,
sweep_end
-
sweep_start
);
}
#endif
if
(
_invocations
==
1
)
{
log_sweep
(
"finished"
);
}
}
...
...
@@ -223,7 +221,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
if
(
nm
->
is_zombie
())
{
// If it is first time, we see nmethod then we mark it. Otherwise,
// we reclame it. When we have seen a zombie method twice, we know that
// there are no inline caches that refer
es
to it.
// there are no inline caches that refer to it.
if
(
nm
->
is_marked_for_reclamation
())
{
assert
(
!
nm
->
is_locked_by_vm
(),
"must not flush locked nmethods"
);
if
(
PrintMethodFlushing
&&
Verbose
)
{
...
...
@@ -320,16 +318,8 @@ void NMethodSweeper::handle_full_code_cache(bool is_full) {
jlong
curr_interval
=
now
-
_last_was_full
;
if
(
curr_interval
<
max_interval
)
{
_rescan
=
true
;
if
(
PrintMethodFlushing
)
{
tty
->
print_cr
(
"### handle full too often, turning off compiler"
);
}
if
(
LogCompilation
&&
(
xtty
!=
NULL
))
{
ttyLocker
ttyl
;
xtty
->
begin_elem
(
"disable_compiler flushing_interval='"
UINT64_FORMAT
"' live_blobs='"
UINT32_FORMAT
"' free_code_cache='"
SIZE_FORMAT
"'"
,
curr_interval
/
1000
,
CodeCache
::
nof_blobs
(),
CodeCache
::
unallocated_capacity
());
xtty
->
stamp
();
xtty
->
end_elem
();
}
log_sweep
(
"disable_compiler"
,
"flushing_interval='"
UINT64_FORMAT
"'"
,
curr_interval
/
1000
);
return
;
}
}
...
...
@@ -349,17 +339,7 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
if
((
!
was_full
())
&&
(
is_full
))
{
if
(
!
CodeCache
::
needs_flushing
())
{
if
(
PrintMethodFlushing
)
{
tty
->
print_cr
(
"### sweeper: Live blobs:"
UINT32_FORMAT
"/Free code cache:"
SIZE_FORMAT
" bytes, restarting compiler"
,
CodeCache
::
nof_blobs
(),
CodeCache
::
unallocated_capacity
());
}
if
(
LogCompilation
&&
(
xtty
!=
NULL
))
{
ttyLocker
ttyl
;
xtty
->
begin_elem
(
"restart_compiler live_blobs='"
UINT32_FORMAT
"' free_code_cache='"
SIZE_FORMAT
"'"
,
CodeCache
::
nof_blobs
(),
CodeCache
::
unallocated_capacity
());
xtty
->
stamp
();
xtty
->
end_elem
();
}
log_sweep
(
"restart_compiler"
);
CompileBroker
::
set_should_compile_new_jobs
(
CompileBroker
::
run_compilation
);
return
;
}
...
...
@@ -368,17 +348,7 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
// Traverse the code cache trying to dump the oldest nmethods
uint
curr_max_comp_id
=
CompileBroker
::
get_compilation_id
();
uint
flush_target
=
((
curr_max_comp_id
-
_highest_marked
)
>>
1
)
+
_highest_marked
;
if
(
PrintMethodFlushing
&&
Verbose
)
{
tty
->
print_cr
(
"### Cleaning code cache: Live blobs:"
UINT32_FORMAT
"/Free code cache:"
SIZE_FORMAT
" bytes"
,
CodeCache
::
nof_blobs
(),
CodeCache
::
unallocated_capacity
());
}
if
(
LogCompilation
&&
(
xtty
!=
NULL
))
{
ttyLocker
ttyl
;
xtty
->
begin_elem
(
"start_cleaning_code_cache live_blobs='"
UINT32_FORMAT
"' free_code_cache='"
SIZE_FORMAT
"'"
,
CodeCache
::
nof_blobs
(),
CodeCache
::
unallocated_capacity
());
xtty
->
stamp
();
xtty
->
end_elem
();
}
log_sweep
(
"start_cleaning"
);
nmethod
*
nm
=
CodeCache
::
alive_nmethod
(
CodeCache
::
first
());
jint
disconnected
=
0
;
...
...
@@ -411,13 +381,9 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
nm
=
CodeCache
::
alive_nmethod
(
CodeCache
::
next
(
nm
));
}
if
(
LogCompilation
&&
(
xtty
!=
NULL
))
{
ttyLocker
ttyl
;
xtty
->
begin_elem
(
"stop_cleaning_code_cache disconnected='"
UINT32_FORMAT
"' made_not_entrant='"
UINT32_FORMAT
"' live_blobs='"
UINT32_FORMAT
"' free_code_cache='"
SIZE_FORMAT
"'"
,
disconnected
,
made_not_entrant
,
CodeCache
::
nof_blobs
(),
CodeCache
::
unallocated_capacity
());
xtty
->
stamp
();
xtty
->
end_elem
();
}
log_sweep
(
"stop_cleaning"
,
"disconnected='"
UINT32_FORMAT
"' made_not_entrant='"
UINT32_FORMAT
"'"
,
disconnected
,
made_not_entrant
);
// Shut off compiler. Sweeper will start over with a new stack scan and
// traversal cycle and turn it back on if it clears enough space.
...
...
@@ -435,3 +401,38 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
}
#endif
}
// Print out some state information about the current sweep and the
// state of the code cache if it's requested.
void
NMethodSweeper
::
log_sweep
(
const
char
*
msg
,
const
char
*
format
,
...)
{
if
(
PrintMethodFlushing
)
{
ttyLocker
ttyl
;
tty
->
print
(
"### sweeper: %s "
,
msg
);
if
(
format
!=
NULL
)
{
va_list
ap
;
va_start
(
ap
,
format
);
tty
->
vprint
(
format
,
ap
);
va_end
(
ap
);
}
tty
->
print_cr
(
" total_blobs='"
UINT32_FORMAT
"' nmethods='"
UINT32_FORMAT
"'"
" adapters='"
UINT32_FORMAT
"' free_code_cache='"
SIZE_FORMAT
"'"
,
CodeCache
::
nof_blobs
(),
CodeCache
::
nof_nmethods
(),
CodeCache
::
nof_adapters
(),
CodeCache
::
unallocated_capacity
());
}
if
(
LogCompilation
&&
(
xtty
!=
NULL
))
{
ttyLocker
ttyl
;
xtty
->
begin_elem
(
"sweeper state='%s' traversals='"
INTX_FORMAT
"' "
,
msg
,
(
intx
)
traversal_count
());
if
(
format
!=
NULL
)
{
va_list
ap
;
va_start
(
ap
,
format
);
xtty
->
vprint
(
format
,
ap
);
va_end
(
ap
);
}
xtty
->
print
(
" total_blobs='"
UINT32_FORMAT
"' nmethods='"
UINT32_FORMAT
"'"
" adapters='"
UINT32_FORMAT
"' free_code_cache='"
SIZE_FORMAT
"'"
,
CodeCache
::
nof_blobs
(),
CodeCache
::
nof_nmethods
(),
CodeCache
::
nof_adapters
(),
CodeCache
::
unallocated_capacity
());
xtty
->
stamp
();
xtty
->
end_elem
();
}
}
src/share/vm/runtime/sweeper.hpp
浏览文件 @
9d513174
/*
* Copyright (c) 1997, 20
05
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 20
10
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -31,12 +31,13 @@ class NMethodSweeper : public AllStatic {
static
long
_traversals
;
// Stack traversal count
static
nmethod
*
_current
;
// Current nmethod
static
int
_seen
;
// Nof. nmethod we have currently processed in current pass of CodeCache
static
int
_invocations
;
// No. of invocations left until we are completed with this pass
static
volatile
int
_invocations
;
// No. of invocations left until we are completed with this pass
static
volatile
int
_sweep_started
;
// Flag to control conc sweeper
static
bool
_rescan
;
// Indicates that we should do a full rescan of the
// of the code cache looking for work to do.
static
bool
_do_sweep
;
// Flag to skip the conc sweep if no stack scan happened
static
jint
_sweep_started
;
// Flag to control conc sweeper
static
int
_locked_seen
;
// Number of locked nmethods encountered during the scan
static
int
_not_entrant_seen_on_stack
;
// Number of not entrant nmethod were are still on stack
...
...
@@ -47,6 +48,9 @@ class NMethodSweeper : public AllStatic {
static
long
_was_full_traversal
;
// trav number at last emergency unloading
static
void
process_nmethod
(
nmethod
*
nm
);
static
void
log_sweep
(
const
char
*
msg
,
const
char
*
format
=
NULL
,
...);
public:
static
long
traversal_count
()
{
return
_traversals
;
}
...
...
src/share/vm/runtime/vmStructs.cpp
浏览文件 @
9d513174
...
...
@@ -614,7 +614,6 @@ static inline uint64_t cast_uint64_t(size_t x)
/* NMethods (NOTE: incomplete, but only a little) */
\
/**************************************************/
\
\
static_field(nmethod, _zombie_instruction_size, int) \
nonstatic_field(nmethod, _method, methodOop) \
nonstatic_field(nmethod, _entry_bci, int) \
nonstatic_field(nmethod, _osr_link, nmethod*) \
...
...
src/share/vm/runtime/vtune.hpp
已删除
100644 → 0
浏览文件 @
4a141040
/*
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
// Interface to Intel's VTune profiler.
class
VTune
:
AllStatic
{
public:
static
void
create_nmethod
(
nmethod
*
nm
);
// register newly created nmethod
static
void
delete_nmethod
(
nmethod
*
nm
);
// unregister nmethod before discarding it
static
void
register_stub
(
const
char
*
name
,
address
start
,
address
end
);
// register internal VM stub
static
void
start_GC
();
// start/end of GC or scavenge
static
void
end_GC
();
static
void
start_class_load
();
// start/end of class loading
static
void
end_class_load
();
static
void
exit
();
// VM exit
};
// helper objects
class
VTuneGCMarker
:
StackObj
{
public:
VTuneGCMarker
()
{
VTune
::
start_GC
();
}
~
VTuneGCMarker
()
{
VTune
::
end_GC
();
}
};
class
VTuneClassLoadMarker
:
StackObj
{
public:
VTuneClassLoadMarker
()
{
VTune
::
start_class_load
();
}
~
VTuneClassLoadMarker
()
{
VTune
::
end_class_load
();
}
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录