Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
03940e3f
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看板
提交
03940e3f
编写于
6月 29, 2013
作者:
D
dcubed
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
01e9c00e
10c84a28
变更
29
隐藏空白更改
内联
并排
Showing
29 changed file
with
393 addition
and
110 deletion
+393
-110
agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java
agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java
+20
-6
agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
...t/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
+6
-3
agent/src/share/classes/sun/jvm/hotspot/HSDB.java
agent/src/share/classes/sun/jvm/hotspot/HSDB.java
+37
-11
agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
+79
-23
agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java
.../classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java
+2
-2
agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java
...lasses/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java
+2
-2
agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
+6
-5
agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java
...share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java
+8
-0
agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java
...rc/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java
+10
-0
agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java
...t/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java
+9
-0
agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java
...t/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java
+6
-0
agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java
.../src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java
+9
-0
agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java
agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java
+9
-0
agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java
agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java
+5
-0
agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java
agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java
+10
-0
agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java
agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java
+6
-0
agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java
.../share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java
+8
-0
agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java
agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java
+9
-0
agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java
agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java
+4
-0
agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java
...t/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java
+10
-0
agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java
...c/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java
+9
-0
agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java
agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java
+28
-3
agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java
.../share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java
+30
-18
agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java
agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java
+10
-0
agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java
agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java
+8
-0
src/share/vm/memory/filemap.cpp
src/share/vm/memory/filemap.cpp
+10
-0
src/share/vm/memory/filemap.hpp
src/share/vm/memory/filemap.hpp
+1
-0
src/share/vm/memory/metaspaceShared.cpp
src/share/vm/memory/metaspaceShared.cpp
+9
-24
src/share/vm/services/memReporter.cpp
src/share/vm/services/memReporter.cpp
+33
-13
未找到文件。
agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java
浏览文件 @
03940e3f
...
...
@@ -31,13 +31,19 @@ import java.io.*;
import
java.util.*
;
public
class
CLHSDB
{
public
CLHSDB
(
JVMDebugger
d
)
{
jvmDebugger
=
d
;
}
public
static
void
main
(
String
[]
args
)
{
new
CLHSDB
(
args
).
run
();
}
private
void
run
()
{
// At this point, if pidText != null we are supposed to attach to it.
// Else, if execPath != null, it is the path of a jdk/bin/java
public
void
run
()
{
// If jvmDebugger is already set, we have been given a JVMDebugger.
// Otherwise, if pidText != null we are supposed to attach to it.
// Finally, if execPath != null, it is the path of a jdk/bin/java
// and coreFilename is the pathname of a core file we are
// supposed to attach to.
...
...
@@ -49,7 +55,9 @@ public class CLHSDB {
}
});
if
(
pidText
!=
null
)
{
if
(
jvmDebugger
!=
null
)
{
attachDebugger
(
jvmDebugger
);
}
else
if
(
pidText
!=
null
)
{
attachDebugger
(
pidText
);
}
else
if
(
execPath
!=
null
)
{
attachDebugger
(
execPath
,
coreFilename
);
...
...
@@ -96,6 +104,7 @@ public class CLHSDB {
// Internals only below this point
//
private
HotSpotAgent
agent
;
private
JVMDebugger
jvmDebugger
;
private
boolean
attached
;
// These had to be made data members because they are referenced in inner classes.
private
String
pidText
;
...
...
@@ -120,7 +129,7 @@ public class CLHSDB {
case
(
1
):
if
(
args
[
0
].
equals
(
"help"
)
||
args
[
0
].
equals
(
"-help"
))
{
doUsage
();
System
.
exit
(
0
)
;
return
;
}
// If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file.
...
...
@@ -142,10 +151,15 @@ public class CLHSDB {
default
:
System
.
out
.
println
(
"HSDB Error: Too many options specified"
);
doUsage
();
System
.
exit
(
1
)
;
return
;
}
}
private
void
attachDebugger
(
JVMDebugger
d
)
{
agent
.
attach
(
d
);
attached
=
true
;
}
/** NOTE we are in a different thread here than either the main
thread or the Swing/AWT event handler thread, so we must be very
careful when creating or removing widgets */
...
...
agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
浏览文件 @
03940e3f
...
...
@@ -101,6 +101,9 @@ import sun.jvm.hotspot.utilities.soql.JSJavaFactoryImpl;
import
sun.jvm.hotspot.utilities.soql.JSJavaScriptEngine
;
public
class
CommandProcessor
{
volatile
boolean
quit
;
public
abstract
static
class
DebuggerInterface
{
public
abstract
HotSpotAgent
getAgent
();
public
abstract
boolean
isAttached
();
...
...
@@ -1135,7 +1138,7 @@ public class CommandProcessor {
usage
();
}
else
{
debugger
.
detach
();
System
.
exit
(
0
)
;
quit
=
true
;
}
}
},
...
...
@@ -1714,7 +1717,7 @@ public class CommandProcessor {
}
protected
void
quit
()
{
debugger
.
detach
();
System
.
exit
(
0
)
;
quit
=
true
;
}
protected
BufferedReader
getInputReader
()
{
return
in
;
...
...
@@ -1781,7 +1784,7 @@ public class CommandProcessor {
public
void
run
(
boolean
prompt
)
{
// Process interactive commands.
while
(
true
)
{
while
(
!
quit
)
{
if
(
prompt
)
printPrompt
();
String
ln
=
null
;
try
{
...
...
agent/src/share/classes/sun/jvm/hotspot/HSDB.java
浏览文件 @
03940e3f
...
...
@@ -59,8 +59,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
// Internals only below this point
//
private
HotSpotAgent
agent
;
private
JVMDebugger
jvmDebugger
;
private
JDesktopPane
desktop
;
private
boolean
attached
;
private
boolean
argError
;
private
JFrame
frame
;
/** List <JMenuItem> */
private
java
.
util
.
List
attachMenuItems
;
/** List <JMenuItem> */
...
...
@@ -85,6 +88,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
System
.
out
.
println
(
" path-to-corefile: Debug this corefile. The default is 'core'"
);
System
.
out
.
println
(
" If no arguments are specified, you can select what to do from the GUI.\n"
);
HotSpotAgent
.
showUsage
();
argError
=
true
;
}
public
HSDB
(
JVMDebugger
d
)
{
jvmDebugger
=
d
;
}
private
HSDB
(
String
[]
args
)
{
...
...
@@ -95,7 +103,6 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
case
(
1
):
if
(
args
[
0
].
equals
(
"help"
)
||
args
[
0
].
equals
(
"-help"
))
{
doUsage
();
System
.
exit
(
0
);
}
// If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file.
...
...
@@ -117,24 +124,29 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
default
:
System
.
out
.
println
(
"HSDB Error: Too many options specified"
);
doUsage
();
System
.
exit
(
1
);
}
}
private
void
run
()
{
// At this point, if pidText != null we are supposed to attach to it.
// Else, if execPath != null, it is the path of a jdk/bin/java
// and coreFilename is the pathname of a core file we are
// supposed to attach to.
// close this tool without calling System.exit
protected
void
closeUI
()
{
workerThread
.
shutdown
();
frame
.
dispose
();
}
public
void
run
()
{
// Don't start the UI if there were bad arguments.
if
(
argError
)
{
return
;
}
agent
=
new
HotSpotAgent
();
workerThread
=
new
WorkerThread
();
attachMenuItems
=
new
java
.
util
.
ArrayList
();
detachMenuItems
=
new
java
.
util
.
ArrayList
();
JFrame
frame
=
new
JFrame
(
"HSDB - HotSpot Debugger"
);
frame
=
new
JFrame
(
"HSDB - HotSpot Debugger"
);
frame
.
setSize
(
800
,
600
);
frame
.
setDefaultCloseOperation
(
WindowConstants
.
EXIT
_ON_CLOSE
);
frame
.
setDefaultCloseOperation
(
WindowConstants
.
DISPOSE
_ON_CLOSE
);
JMenuBar
menuBar
=
new
JMenuBar
();
...
...
@@ -197,7 +209,7 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
item
=
createMenuItem
(
"Exit"
,
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
e
)
{
System
.
exit
(
0
);
closeUI
(
);
}
});
item
.
setAccelerator
(
KeyStroke
.
getKeyStroke
(
KeyEvent
.
VK_X
,
ActionEvent
.
ALT_MASK
));
...
...
@@ -406,7 +418,15 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
}
});
if
(
pidText
!=
null
)
{
// If jvmDebugger is already set, we have been given a JVMDebugger.
// Otherwise, if pidText != null we are supposed to attach to it.
// Finally, if execPath != null, it is the path of a jdk/bin/java
// and coreFilename is the pathname of a core file we are
// supposed to attach to.
if
(
jvmDebugger
!=
null
)
{
attach
(
jvmDebugger
);
}
else
if
(
pidText
!=
null
)
{
attach
(
pidText
);
}
else
if
(
execPath
!=
null
)
{
attach
(
execPath
,
coreFilename
);
...
...
@@ -1113,6 +1133,12 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
});
}
// Attach to existing JVMDebugger, which should be already attached to a core/process.
private
void
attach
(
JVMDebugger
d
)
{
attached
=
true
;
showThreadsDialog
();
}
/** NOTE we are in a different thread here than either the main
thread or the Swing/AWT event handler thread, so we must be very
careful when creating or removing widgets */
...
...
agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
浏览文件 @
03940e3f
...
...
@@ -25,6 +25,8 @@
package
sun.jvm.hotspot
;
import
java.rmi.RemoteException
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.InvocationTargetException
;
import
sun.jvm.hotspot.debugger.Debugger
;
import
sun.jvm.hotspot.debugger.DebuggerException
;
...
...
@@ -63,7 +65,6 @@ public class HotSpotAgent {
private
String
os
;
private
String
cpu
;
private
String
fileSep
;
// The system can work in several ways:
// - Attaching to local process
...
...
@@ -155,6 +156,14 @@ public class HotSpotAgent {
go
();
}
/** This uses a JVMDebugger that is already attached to the core or process */
public
synchronized
void
attach
(
JVMDebugger
d
)
throws
DebuggerException
{
debugger
=
d
;
isServer
=
false
;
go
();
}
/** This attaches to a "debug server" on a remote machine; this
remote server has already attached to a process or opened a
core file and is waiting for RMI calls on the Debugger object to
...
...
@@ -303,28 +312,37 @@ public class HotSpotAgent {
// server, but not client attaching to server)
//
try
{
os
=
PlatformInfo
.
getOS
();
cpu
=
PlatformInfo
.
getCPU
(
);
}
catch
(
UnsupportedPlatformException
e
)
{
throw
new
DebuggerException
(
e
);
}
fileSep
=
System
.
getProperty
(
"file.separator"
);
// Handle existing or alternate JVMDebugger:
// these will set os, cpu independently of our PlatformInfo implementation.
String
alternateDebugger
=
System
.
getProperty
(
"sa.altDebugger"
);
if
(
debugger
!=
null
)
{
setupDebuggerExisting
();
}
else
if
(
alternateDebugger
!=
null
)
{
setupDebuggerAlternate
(
alternateDebugger
);
if
(
os
.
equals
(
"solaris"
))
{
setupDebuggerSolaris
();
}
else
if
(
os
.
equals
(
"win32"
))
{
setupDebuggerWin32
();
}
else
if
(
os
.
equals
(
"linux"
))
{
setupDebuggerLinux
();
}
else
if
(
os
.
equals
(
"bsd"
))
{
setupDebuggerBsd
();
}
else
if
(
os
.
equals
(
"darwin"
))
{
setupDebuggerDarwin
();
}
else
{
// Add support for more operating systems here
throw
new
DebuggerException
(
"Operating system "
+
os
+
" not yet supported"
);
// Otherwise, os, cpu are those of our current platform:
try
{
os
=
PlatformInfo
.
getOS
();
cpu
=
PlatformInfo
.
getCPU
();
}
catch
(
UnsupportedPlatformException
e
)
{
throw
new
DebuggerException
(
e
);
}
if
(
os
.
equals
(
"solaris"
))
{
setupDebuggerSolaris
();
}
else
if
(
os
.
equals
(
"win32"
))
{
setupDebuggerWin32
();
}
else
if
(
os
.
equals
(
"linux"
))
{
setupDebuggerLinux
();
}
else
if
(
os
.
equals
(
"bsd"
))
{
setupDebuggerBsd
();
}
else
if
(
os
.
equals
(
"darwin"
))
{
setupDebuggerDarwin
();
}
else
{
// Add support for more operating systems here
throw
new
DebuggerException
(
"Operating system "
+
os
+
" not yet supported"
);
}
}
if
(
isServer
)
{
...
...
@@ -423,6 +441,41 @@ public class HotSpotAgent {
// OS-specific debugger setup/connect routines
//
// Use the existing JVMDebugger, as passed to our constructor.
// Retrieve os and cpu from that debugger, not the current platform.
private
void
setupDebuggerExisting
()
{
os
=
debugger
.
getOS
();
cpu
=
debugger
.
getCPU
();
setupJVMLibNames
(
os
);
machDesc
=
debugger
.
getMachineDescription
();
}
// Given a classname, load an alternate implementation of JVMDebugger.
private
void
setupDebuggerAlternate
(
String
alternateName
)
{
try
{
Class
c
=
Class
.
forName
(
alternateName
);
Constructor
cons
=
c
.
getConstructor
();
debugger
=
(
JVMDebugger
)
cons
.
newInstance
();
attachDebugger
();
setupDebuggerExisting
();
}
catch
(
ClassNotFoundException
cnfe
)
{
throw
new
DebuggerException
(
"Cannot find alternate SA Debugger: '"
+
alternateName
+
"'"
);
}
catch
(
NoSuchMethodException
nsme
)
{
throw
new
DebuggerException
(
"Alternate SA Debugger: '"
+
alternateName
+
"' has missing constructor."
);
}
catch
(
InstantiationException
ie
)
{
throw
new
DebuggerException
(
"Alternate SA Debugger: '"
+
alternateName
+
"' fails to initialise: "
,
ie
);
}
catch
(
IllegalAccessException
iae
)
{
throw
new
DebuggerException
(
"Alternate SA Debugger: '"
+
alternateName
+
"' fails to initialise: "
,
iae
);
}
catch
(
InvocationTargetException
iae
)
{
throw
new
DebuggerException
(
"Alternate SA Debugger: '"
+
alternateName
+
"' fails to initialise: "
,
iae
);
}
System
.
err
.
println
(
"Loaded alternate HotSpot SA Debugger: "
+
alternateName
);
}
//
// Solaris
//
...
...
@@ -466,6 +519,11 @@ public class HotSpotAgent {
debugger
=
new
RemoteDebuggerClient
(
remote
);
machDesc
=
((
RemoteDebuggerClient
)
debugger
).
getMachineDescription
();
os
=
debugger
.
getOS
();
setupJVMLibNames
(
os
);
cpu
=
debugger
.
getCPU
();
}
private
void
setupJVMLibNames
(
String
os
)
{
if
(
os
.
equals
(
"solaris"
))
{
setupJVMLibNamesSolaris
();
}
else
if
(
os
.
equals
(
"win32"
))
{
...
...
@@ -479,8 +537,6 @@ public class HotSpotAgent {
}
else
{
throw
new
RuntimeException
(
"Unknown OS type"
);
}
cpu
=
debugger
.
getCPU
();
}
private
void
setupJVMLibNamesSolaris
()
{
...
...
agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java
浏览文件 @
03940e3f
...
...
@@ -26,11 +26,11 @@ package sun.jvm.hotspot.debugger.linux;
import
sun.jvm.hotspot.debugger.*
;
class
LinuxAddress
implements
Address
{
public
class
LinuxAddress
implements
Address
{
protected
LinuxDebugger
debugger
;
protected
long
addr
;
LinuxAddress
(
LinuxDebugger
debugger
,
long
addr
)
{
public
LinuxAddress
(
LinuxDebugger
debugger
,
long
addr
)
{
this
.
debugger
=
debugger
;
this
.
addr
=
addr
;
}
...
...
agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java
浏览文件 @
03940e3f
...
...
@@ -26,8 +26,8 @@ package sun.jvm.hotspot.debugger.linux;
import
sun.jvm.hotspot.debugger.*
;
class
LinuxOopHandle
extends
LinuxAddress
implements
OopHandle
{
LinuxOopHandle
(
LinuxDebugger
debugger
,
long
addr
)
{
public
class
LinuxOopHandle
extends
LinuxAddress
implements
OopHandle
{
public
LinuxOopHandle
(
LinuxDebugger
debugger
,
long
addr
)
{
super
(
debugger
,
addr
);
}
...
...
agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
浏览文件 @
03940e3f
...
...
@@ -246,7 +246,7 @@ public class VM {
}
}
private
static
final
boolean
disableDerivedP
r
interTableCheck
;
private
static
final
boolean
disableDerivedP
o
interTableCheck
;
private
static
final
Properties
saProps
;
static
{
...
...
@@ -256,12 +256,12 @@ public class VM {
url
=
VM
.
class
.
getClassLoader
().
getResource
(
"sa.properties"
);
saProps
.
load
(
new
BufferedInputStream
(
url
.
openStream
()));
}
catch
(
Exception
e
)
{
throw
new
RuntimeExceptio
n
(
"Unable to load properties "
+
System
.
err
.
printl
n
(
"Unable to load properties "
+
(
url
==
null
?
"null"
:
url
.
toString
())
+
": "
+
e
.
getMessage
());
}
disableDerivedP
r
interTableCheck
=
System
.
getProperty
(
"sun.jvm.hotspot.runtime.VM.disableDerivedPointerTableCheck"
)
!=
null
;
disableDerivedP
o
interTableCheck
=
System
.
getProperty
(
"sun.jvm.hotspot.runtime.VM.disableDerivedPointerTableCheck"
)
!=
null
;
}
private
VM
(
TypeDataBase
db
,
JVMDebugger
debugger
,
boolean
isBigEndian
)
{
...
...
@@ -371,7 +371,8 @@ public class VM {
/** This is used by the debugging system */
public
static
void
initialize
(
TypeDataBase
db
,
JVMDebugger
debugger
)
{
if
(
soleInstance
!=
null
)
{
throw
new
RuntimeException
(
"Attempt to initialize VM twice"
);
// Using multiple SA Tool classes in the same process creates a call here.
return
;
}
soleInstance
=
new
VM
(
db
,
debugger
,
debugger
.
getMachineDescription
().
isBigEndian
());
...
...
@@ -683,7 +684,7 @@ public class VM {
/** Returns true if C2 derived pointer table should be used, false otherwise */
public
boolean
useDerivedPointerTable
()
{
return
!
disableDerivedP
r
interTableCheck
;
return
!
disableDerivedP
o
interTableCheck
;
}
/** Returns the code cache; should not be used if is core build */
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java
浏览文件 @
03940e3f
...
...
@@ -41,6 +41,14 @@ import sun.jvm.hotspot.utilities.*;
public
class
ClassLoaderStats
extends
Tool
{
boolean
verbose
=
true
;
public
ClassLoaderStats
()
{
super
();
}
public
ClassLoaderStats
(
JVMDebugger
d
)
{
super
(
d
);
}
public
static
void
main
(
String
[]
args
)
{
ClassLoaderStats
cls
=
new
ClassLoaderStats
();
cls
.
start
(
args
);
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java
浏览文件 @
03940e3f
...
...
@@ -24,6 +24,7 @@
package
sun.jvm.hotspot.tools
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
import
sun.jvm.hotspot.tools.*
;
import
sun.jvm.hotspot.oops.*
;
...
...
@@ -42,6 +43,15 @@ import java.util.Comparator;
* summary of these objects in the form of a histogram.
*/
public
class
FinalizerInfo
extends
Tool
{
public
FinalizerInfo
()
{
super
();
}
public
FinalizerInfo
(
JVMDebugger
d
)
{
super
(
d
);
}
public
static
void
main
(
String
[]
args
)
{
FinalizerInfo
finfo
=
new
FinalizerInfo
();
finfo
.
start
(
args
);
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java
浏览文件 @
03940e3f
...
...
@@ -25,10 +25,19 @@
package
sun.jvm.hotspot.tools
;
import
java.io.PrintStream
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
import
sun.jvm.hotspot.runtime.*
;
public
class
FlagDumper
extends
Tool
{
public
FlagDumper
()
{
super
();
}
public
FlagDumper
(
JVMDebugger
d
)
{
super
(
d
);
}
public
void
run
()
{
VM
.
Flag
[]
flags
=
VM
.
getVM
().
getCommandLineFlags
();
PrintStream
out
=
System
.
out
;
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java
浏览文件 @
03940e3f
...
...
@@ -25,6 +25,7 @@
package
sun.jvm.hotspot.tools
;
import
sun.jvm.hotspot.utilities.HeapHprofBinWriter
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
import
java.io.IOException
;
/*
...
...
@@ -42,6 +43,11 @@ public class HeapDumper extends Tool {
this
.
dumpFile
=
dumpFile
;
}
public
HeapDumper
(
String
dumpFile
,
JVMDebugger
d
)
{
super
(
d
);
this
.
dumpFile
=
dumpFile
;
}
protected
void
printFlagsUsage
()
{
System
.
out
.
println
(
" <no option>\tto dump heap to "
+
DEFAULT_DUMP_FILE
);
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java
浏览文件 @
03940e3f
...
...
@@ -29,12 +29,21 @@ import sun.jvm.hotspot.gc_interface.*;
import
sun.jvm.hotspot.gc_implementation.g1.*
;
import
sun.jvm.hotspot.gc_implementation.parallelScavenge.*
;
import
sun.jvm.hotspot.gc_implementation.shared.*
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
import
sun.jvm.hotspot.memory.*
;
import
sun.jvm.hotspot.oops.*
;
import
sun.jvm.hotspot.runtime.*
;
public
class
HeapSummary
extends
Tool
{
public
HeapSummary
()
{
super
();
}
public
HeapSummary
(
JVMDebugger
d
)
{
super
(
d
);
}
public
static
void
main
(
String
[]
args
)
{
HeapSummary
hs
=
new
HeapSummary
();
hs
.
start
(
args
);
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java
浏览文件 @
03940e3f
...
...
@@ -25,12 +25,21 @@
package
sun.jvm.hotspot.tools
;
import
sun.jvm.hotspot.runtime.*
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
public
class
JInfo
extends
Tool
{
public
JInfo
()
{
super
();
}
public
JInfo
(
int
m
)
{
mode
=
m
;
}
public
JInfo
(
JVMDebugger
d
)
{
super
(
d
);
}
protected
boolean
needsJavaPrefix
()
{
return
false
;
}
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java
浏览文件 @
03940e3f
...
...
@@ -25,6 +25,7 @@
package
sun.jvm.hotspot.tools
;
import
java.io.*
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
import
sun.jvm.hotspot.utilities.*
;
public
class
JMap
extends
Tool
{
...
...
@@ -36,6 +37,10 @@ public class JMap extends Tool {
this
(
MODE_PMAP
);
}
public
JMap
(
JVMDebugger
d
)
{
super
(
d
);
}
protected
boolean
needsJavaPrefix
()
{
return
false
;
}
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java
浏览文件 @
03940e3f
...
...
@@ -25,9 +25,19 @@
package
sun.jvm.hotspot.tools
;
import
java.io.*
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
import
sun.jvm.hotspot.runtime.*
;
public
class
JSnap
extends
Tool
{
public
JSnap
()
{
super
();
}
public
JSnap
(
JVMDebugger
d
)
{
super
(
d
);
}
public
void
run
()
{
final
PrintStream
out
=
System
.
out
;
if
(
PerfMemory
.
initialized
())
{
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java
浏览文件 @
03940e3f
...
...
@@ -24,6 +24,8 @@
package
sun.jvm.hotspot.tools
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
public
class
JStack
extends
Tool
{
public
JStack
(
boolean
mixedMode
,
boolean
concurrentLocks
)
{
this
.
mixedMode
=
mixedMode
;
...
...
@@ -34,6 +36,10 @@ public class JStack extends Tool {
this
(
true
,
true
);
}
public
JStack
(
JVMDebugger
d
)
{
super
(
d
);
}
protected
boolean
needsJavaPrefix
()
{
return
false
;
}
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java
浏览文件 @
03940e3f
...
...
@@ -33,6 +33,14 @@ import java.io.PrintStream;
an object histogram from a remote or crashed VM. */
public
class
ObjectHistogram
extends
Tool
{
public
ObjectHistogram
()
{
super
();
}
public
ObjectHistogram
(
JVMDebugger
d
)
{
super
(
d
);
}
public
void
run
()
{
run
(
System
.
out
,
System
.
err
);
}
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java
浏览文件 @
03940e3f
...
...
@@ -31,6 +31,15 @@ import sun.jvm.hotspot.debugger.cdbg.*;
import
sun.jvm.hotspot.runtime.*
;
public
class
PMap
extends
Tool
{
public
PMap
()
{
super
();
}
public
PMap
(
JVMDebugger
d
)
{
super
(
d
);
}
public
void
run
()
{
run
(
System
.
out
);
}
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java
浏览文件 @
03940e3f
...
...
@@ -45,6 +45,10 @@ public class PStack extends Tool {
this
(
true
,
true
);
}
public
PStack
(
JVMDebugger
d
)
{
super
(
d
);
}
public
void
run
()
{
run
(
System
.
out
);
}
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java
浏览文件 @
03940e3f
...
...
@@ -45,6 +45,16 @@ public class StackTrace extends Tool {
run
(
System
.
out
);
}
public
StackTrace
(
JVMDebugger
d
)
{
super
(
d
);
}
public
StackTrace
(
JVMDebugger
d
,
boolean
v
,
boolean
concurrentLocks
)
{
super
(
d
);
this
.
verbose
=
v
;
this
.
concurrentLocks
=
concurrentLocks
;
}
public
void
run
(
java
.
io
.
PrintStream
tty
)
{
// Ready to go with the database...
try
{
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java
浏览文件 @
03940e3f
...
...
@@ -27,10 +27,19 @@ package sun.jvm.hotspot.tools;
import
java.io.PrintStream
;
import
java.util.*
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
import
sun.jvm.hotspot.runtime.*
;
public
class
SysPropsDumper
extends
Tool
{
public
SysPropsDumper
()
{
super
();
}
public
SysPropsDumper
(
JVMDebugger
d
)
{
super
(
d
);
}
public
void
run
()
{
Properties
sysProps
=
VM
.
getVM
().
getSystemProperties
();
PrintStream
out
=
System
.
out
;
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java
浏览文件 @
03940e3f
...
...
@@ -35,6 +35,7 @@ import sun.jvm.hotspot.debugger.*;
public
abstract
class
Tool
implements
Runnable
{
private
HotSpotAgent
agent
;
private
JVMDebugger
jvmDebugger
;
private
int
debugeeType
;
// debugeeType is one of constants below
...
...
@@ -42,6 +43,13 @@ public abstract class Tool implements Runnable {
protected
static
final
int
DEBUGEE_CORE
=
1
;
protected
static
final
int
DEBUGEE_REMOTE
=
2
;
public
Tool
()
{
}
public
Tool
(
JVMDebugger
d
)
{
jvmDebugger
=
d
;
}
public
String
getName
()
{
return
getClass
().
getName
();
}
...
...
@@ -90,7 +98,6 @@ public abstract class Tool implements Runnable {
protected
void
usage
()
{
printUsage
();
System
.
exit
(
1
);
}
/*
...
...
@@ -106,13 +113,13 @@ public abstract class Tool implements Runnable {
protected
void
stop
()
{
if
(
agent
!=
null
)
{
agent
.
detach
();
System
.
exit
(
0
);
}
}
protected
void
start
(
String
[]
args
)
{
if
((
args
.
length
<
1
)
||
(
args
.
length
>
2
))
{
usage
();
return
;
}
// Attempt to handle -h or -help or some invalid flag
...
...
@@ -185,13 +192,31 @@ public abstract class Tool implements Runnable {
}
if
(
e
.
getMessage
()
!=
null
)
{
err
.
print
(
e
.
getMessage
());
e
.
printStackTrace
();
}
err
.
println
();
System
.
exit
(
1
)
;
return
;
}
err
.
println
(
"Debugger attached successfully."
);
startInternal
();
}
// When using an existing JVMDebugger.
public
void
start
()
{
if
(
jvmDebugger
==
null
)
{
throw
new
RuntimeException
(
"Tool.start() called with no JVMDebugger set."
);
}
agent
=
new
HotSpotAgent
();
agent
.
attach
(
jvmDebugger
);
startInternal
();
}
// Remains of the start mechanism, common to both start methods.
private
void
startInternal
()
{
PrintStream
err
=
System
.
err
;
VM
vm
=
VM
.
getVM
();
if
(
vm
.
isCore
())
{
err
.
println
(
"Core build detected."
);
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java
浏览文件 @
03940e3f
...
...
@@ -25,6 +25,7 @@
package
sun.jvm.hotspot.tools.jcore
;
import
java.io.*
;
import
java.lang.reflect.Constructor
;
import
java.util.jar.JarOutputStream
;
import
java.util.jar.JarEntry
;
import
java.util.jar.Manifest
;
...
...
@@ -38,6 +39,16 @@ public class ClassDump extends Tool {
private
ClassFilter
classFilter
;
private
String
outputDirectory
;
private
JarOutputStream
jarStream
;
private
String
pkgList
;
public
ClassDump
()
{
super
();
}
public
ClassDump
(
JVMDebugger
d
,
String
pkgList
)
{
super
(
d
);
this
.
pkgList
=
pkgList
;
}
public
void
setClassFilter
(
ClassFilter
cf
)
{
classFilter
=
cf
;
...
...
@@ -63,6 +74,25 @@ public class ClassDump extends Tool {
public
void
run
()
{
// Ready to go with the database...
try
{
// The name of the filter always comes from a System property.
// If we have a pkgList, pass it, otherwise let the filter read
// its own System property for the list of classes.
String
filterClassName
=
System
.
getProperty
(
"sun.jvm.hotspot.tools.jcore.filter"
,
"sun.jvm.hotspot.tools.jcore.PackageNameFilter"
);
try
{
Class
filterClass
=
Class
.
forName
(
filterClassName
);
if
(
pkgList
==
null
)
{
classFilter
=
(
ClassFilter
)
filterClass
.
newInstance
();
}
else
{
Constructor
con
=
filterClass
.
getConstructor
(
String
.
class
);
classFilter
=
(
ClassFilter
)
con
.
newInstance
(
pkgList
);
}
}
catch
(
Exception
exp
)
{
System
.
err
.
println
(
"Warning: Can not create class filter!"
);
}
String
outputDirectory
=
System
.
getProperty
(
"sun.jvm.hotspot.tools.jcore.outputDir"
,
"."
);
setOutputDirectory
(
outputDirectory
);
// walk through the system dictionary
SystemDictionary
dict
=
VM
.
getVM
().
getSystemDictionary
();
...
...
@@ -139,26 +169,8 @@ public class ClassDump extends Tool {
}
public
static
void
main
(
String
[]
args
)
{
// load class filters
ClassFilter
classFilter
=
null
;
String
filterClassName
=
System
.
getProperty
(
"sun.jvm.hotspot.tools.jcore.filter"
);
if
(
filterClassName
!=
null
)
{
try
{
Class
filterClass
=
Class
.
forName
(
filterClassName
);
classFilter
=
(
ClassFilter
)
filterClass
.
newInstance
();
}
catch
(
Exception
exp
)
{
System
.
err
.
println
(
"Warning: Can not create class filter!"
);
}
}
String
outputDirectory
=
System
.
getProperty
(
"sun.jvm.hotspot.tools.jcore.outputDir"
);
if
(
outputDirectory
==
null
)
outputDirectory
=
"."
;
ClassDump
cd
=
new
ClassDump
();
cd
.
setClassFilter
(
classFilter
);
cd
.
setOutputDirectory
(
outputDirectory
);
cd
.
start
(
args
);
cd
.
stop
();
}
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java
浏览文件 @
03940e3f
...
...
@@ -24,12 +24,22 @@
package
sun.jvm.hotspot.tools.soql
;
import
sun.jvm.hotspot.debugger.JVMDebugger
;
import
sun.jvm.hotspot.tools.*
;
import
sun.jvm.hotspot.utilities.*
;
import
sun.jvm.hotspot.utilities.soql.*
;
/** This is command line JavaScript debugger console */
public
class
JSDB
extends
Tool
{
public
JSDB
()
{
super
();
}
public
JSDB
(
JVMDebugger
d
)
{
super
(
d
);
}
public
static
void
main
(
String
[]
args
)
{
JSDB
jsdb
=
new
JSDB
();
jsdb
.
start
(
args
);
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java
浏览文件 @
03940e3f
...
...
@@ -44,6 +44,14 @@ public class SOQL extends Tool {
soql
.
stop
();
}
public
SOQL
()
{
super
();
}
public
SOQL
(
JVMDebugger
d
)
{
super
(
d
);
}
protected
SOQLEngine
soqlEngine
;
protected
BufferedReader
in
=
new
BufferedReader
(
new
InputStreamReader
(
System
.
in
));
protected
PrintStream
out
=
System
.
out
;
...
...
src/share/vm/memory/filemap.cpp
浏览文件 @
03940e3f
...
...
@@ -549,3 +549,13 @@ bool FileMapInfo::is_in_shared_space(const void* p) {
return
false
;
}
void
FileMapInfo
::
print_shared_spaces
()
{
gclog_or_tty
->
print_cr
(
"Shared Spaces:"
);
for
(
int
i
=
0
;
i
<
MetaspaceShared
::
n_regions
;
i
++
)
{
struct
FileMapInfo
::
FileMapHeader
::
space_info
*
si
=
&
_header
.
_space
[
i
];
gclog_or_tty
->
print
(
" %s "
INTPTR_FORMAT
"-"
INTPTR_FORMAT
,
shared_region_name
[
i
],
si
->
_base
,
si
->
_base
+
si
->
_used
);
}
}
src/share/vm/memory/filemap.hpp
浏览文件 @
03940e3f
...
...
@@ -149,6 +149,7 @@ public:
// Return true if given address is in the mapped shared space.
bool
is_in_shared_space
(
const
void
*
p
)
NOT_CDS_RETURN_
(
false
);
void
print_shared_spaces
()
NOT_CDS_RETURN
;
};
#endif // SHARE_VM_MEMORY_FILEMAP_HPP
src/share/vm/memory/metaspaceShared.cpp
浏览文件 @
03940e3f
...
...
@@ -826,35 +826,15 @@ public:
bool
reading
()
const
{
return
true
;
}
};
// Save bounds of shared spaces mapped in.
static
char
*
_ro_base
=
NULL
;
static
char
*
_rw_base
=
NULL
;
static
char
*
_md_base
=
NULL
;
static
char
*
_mc_base
=
NULL
;
// Return true if given address is in the mapped shared space.
bool
MetaspaceShared
::
is_in_shared_space
(
const
void
*
p
)
{
if
(
_ro_base
==
NULL
||
_rw_base
==
NULL
)
{
return
false
;
}
else
{
return
((
p
>=
_ro_base
&&
p
<
(
_ro_base
+
SharedReadOnlySize
))
||
(
p
>=
_rw_base
&&
p
<
(
_rw_base
+
SharedReadWriteSize
)));
}
return
UseSharedSpaces
&&
FileMapInfo
::
current_info
()
->
is_in_shared_space
(
p
);
}
void
MetaspaceShared
::
print_shared_spaces
()
{
gclog_or_tty
->
print_cr
(
"Shared Spaces:"
);
gclog_or_tty
->
print
(
" read-only "
INTPTR_FORMAT
"-"
INTPTR_FORMAT
,
_ro_base
,
_ro_base
+
SharedReadOnlySize
);
gclog_or_tty
->
print
(
" read-write "
INTPTR_FORMAT
"-"
INTPTR_FORMAT
,
_rw_base
,
_rw_base
+
SharedReadWriteSize
);
gclog_or_tty
->
cr
();
gclog_or_tty
->
print
(
" misc-data "
INTPTR_FORMAT
"-"
INTPTR_FORMAT
,
_md_base
,
_md_base
+
SharedMiscDataSize
);
gclog_or_tty
->
print
(
" misc-code "
INTPTR_FORMAT
"-"
INTPTR_FORMAT
,
_mc_base
,
_mc_base
+
SharedMiscCodeSize
);
gclog_or_tty
->
cr
();
if
(
UseSharedSpaces
)
{
FileMapInfo
::
current_info
()
->
print_shared_spaces
();
}
}
...
...
@@ -874,6 +854,11 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
assert
(
!
DumpSharedSpaces
,
"Should not be called with DumpSharedSpaces"
);
char
*
_ro_base
=
NULL
;
char
*
_rw_base
=
NULL
;
char
*
_md_base
=
NULL
;
char
*
_mc_base
=
NULL
;
// Map each shared region
if
((
_ro_base
=
mapinfo
->
map_region
(
ro
))
!=
NULL
&&
(
_rw_base
=
mapinfo
->
map_region
(
rw
))
!=
NULL
&&
...
...
src/share/vm/services/memReporter.cpp
浏览文件 @
03940e3f
...
...
@@ -188,8 +188,8 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline&
(
MallocCallsitePointer
*
)
prev_malloc_itr
.
current
();
while
(
cur_malloc_callsite
!=
NULL
||
prev_malloc_callsite
!=
NULL
)
{
if
(
prev_malloc_callsite
==
NULL
||
cur_malloc_callsite
->
addr
()
<
prev_malloc_callsite
->
addr
())
{
if
(
prev_malloc_callsite
==
NULL
)
{
assert
(
cur_malloc_callsite
!=
NULL
,
"sanity check"
);
// this is a new callsite
_outputer
.
diff_malloc_callsite
(
cur_malloc_callsite
->
addr
(),
amount_in_current_scale
(
cur_malloc_callsite
->
amount
()),
...
...
@@ -197,22 +197,42 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline&
diff_in_current_scale
(
cur_malloc_callsite
->
amount
(),
0
),
diff
(
cur_malloc_callsite
->
count
(),
0
));
cur_malloc_callsite
=
(
MallocCallsitePointer
*
)
cur_malloc_itr
.
next
();
}
else
if
(
cur_malloc_callsite
==
NULL
||
cur_malloc_callsite
->
addr
()
>
prev_malloc_callsite
->
addr
())
{
}
else
if
(
cur_malloc_callsite
==
NULL
)
{
assert
(
prev_malloc_callsite
!=
NULL
,
"Sanity check"
);
// this callsite is already gone
_outputer
.
diff_malloc_callsite
(
prev_malloc_callsite
->
addr
(),
amount_in_current_scale
(
0
)
,
0
,
0
,
0
,
diff_in_current_scale
(
0
,
prev_malloc_callsite
->
amount
()),
diff
(
0
,
prev_malloc_callsite
->
count
()));
prev_malloc_callsite
=
(
MallocCallsitePointer
*
)
prev_malloc_itr
.
next
();
}
else
{
// the same callsite
_outputer
.
diff_malloc_callsite
(
cur_malloc_callsite
->
addr
(),
amount_in_current_scale
(
cur_malloc_callsite
->
amount
()),
cur_malloc_callsite
->
count
(),
diff_in_current_scale
(
cur_malloc_callsite
->
amount
(),
prev_malloc_callsite
->
amount
()),
diff
(
cur_malloc_callsite
->
count
(),
prev_malloc_callsite
->
count
()));
cur_malloc_callsite
=
(
MallocCallsitePointer
*
)
cur_malloc_itr
.
next
();
prev_malloc_callsite
=
(
MallocCallsitePointer
*
)
prev_malloc_itr
.
next
();
}
else
{
assert
(
cur_malloc_callsite
!=
NULL
,
"Sanity check"
);
assert
(
prev_malloc_callsite
!=
NULL
,
"Sanity check"
);
if
(
cur_malloc_callsite
->
addr
()
<
prev_malloc_callsite
->
addr
())
{
// this is a new callsite
_outputer
.
diff_malloc_callsite
(
cur_malloc_callsite
->
addr
(),
amount_in_current_scale
(
cur_malloc_callsite
->
amount
()),
cur_malloc_callsite
->
count
(),
diff_in_current_scale
(
cur_malloc_callsite
->
amount
(),
0
),
diff
(
cur_malloc_callsite
->
count
(),
0
));
cur_malloc_callsite
=
(
MallocCallsitePointer
*
)
cur_malloc_itr
.
next
();
}
else
if
(
cur_malloc_callsite
->
addr
()
>
prev_malloc_callsite
->
addr
())
{
// this callsite is already gone
_outputer
.
diff_malloc_callsite
(
prev_malloc_callsite
->
addr
(),
0
,
0
,
diff_in_current_scale
(
0
,
prev_malloc_callsite
->
amount
()),
diff
(
0
,
prev_malloc_callsite
->
count
()));
prev_malloc_callsite
=
(
MallocCallsitePointer
*
)
prev_malloc_itr
.
next
();
}
else
{
// the same callsite
_outputer
.
diff_malloc_callsite
(
cur_malloc_callsite
->
addr
(),
amount_in_current_scale
(
cur_malloc_callsite
->
amount
()),
cur_malloc_callsite
->
count
(),
diff_in_current_scale
(
cur_malloc_callsite
->
amount
(),
prev_malloc_callsite
->
amount
()),
diff
(
cur_malloc_callsite
->
count
(),
prev_malloc_callsite
->
count
()));
cur_malloc_callsite
=
(
MallocCallsitePointer
*
)
cur_malloc_itr
.
next
();
prev_malloc_callsite
=
(
MallocCallsitePointer
*
)
prev_malloc_itr
.
next
();
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录