Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
9cd6f543
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看板
提交
9cd6f543
编写于
4月 16, 2013
作者:
I
iignatyev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8011971: WB API doesn't accept j.l.reflect.Constructor
Reviewed-by: kvn, vlivanov
上级
6ea208d0
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
534 addition
and
174 deletion
+534
-174
src/share/vm/prims/whitebox.cpp
src/share/vm/prims/whitebox.cpp
+12
-12
test/compiler/whitebox/ClearMethodStateTest.java
test/compiler/whitebox/ClearMethodStateTest.java
+36
-17
test/compiler/whitebox/CompilerWhiteBoxTest.java
test/compiler/whitebox/CompilerWhiteBoxTest.java
+228
-34
test/compiler/whitebox/DeoptimizeAllTest.java
test/compiler/whitebox/DeoptimizeAllTest.java
+19
-5
test/compiler/whitebox/DeoptimizeMethodTest.java
test/compiler/whitebox/DeoptimizeMethodTest.java
+20
-6
test/compiler/whitebox/EnqueueMethodForCompilationTest.java
test/compiler/whitebox/EnqueueMethodForCompilationTest.java
+38
-26
test/compiler/whitebox/IsMethodCompilableTest.java
test/compiler/whitebox/IsMethodCompilableTest.java
+46
-27
test/compiler/whitebox/MakeMethodNotCompilableTest.java
test/compiler/whitebox/MakeMethodNotCompilableTest.java
+69
-12
test/compiler/whitebox/SetDontInlineMethodTest.java
test/compiler/whitebox/SetDontInlineMethodTest.java
+25
-11
test/compiler/whitebox/SetForceInlineMethodTest.java
test/compiler/whitebox/SetForceInlineMethodTest.java
+25
-11
test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
+16
-13
未找到文件。
src/share/vm/prims/whitebox.cpp
浏览文件 @
9cd6f543
...
...
@@ -237,10 +237,10 @@ WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject meth
WB_END
WB_ENTRY
(
void
,
WB_MakeMethodNotCompilable
(
JNIEnv
*
env
,
jobject
o
,
jobject
method
))
WB_ENTRY
(
void
,
WB_MakeMethodNotCompilable
(
JNIEnv
*
env
,
jobject
o
,
jobject
method
,
jint
comp_level
))
jmethodID
jmid
=
reflected_method_to_jmid
(
thread
,
env
,
method
);
methodHandle
mh
(
THREAD
,
Method
::
checked_resolve_jmethod_id
(
jmid
));
mh
->
set_not_compilable
();
mh
->
set_not_compilable
(
comp_level
,
true
/* report */
,
"WhiteBox"
);
WB_END
WB_ENTRY
(
jboolean
,
WB_TestSetDontInlineMethod
(
JNIEnv
*
env
,
jobject
o
,
jobject
method
,
jboolean
value
))
...
...
@@ -398,28 +398,28 @@ static JNINativeMethod methods[] = {
{
CC
"NMTWaitForDataMerge"
,
CC
"()Z"
,
(
void
*
)
&
WB_NMTWaitForDataMerge
},
#endif // INCLUDE_NMT
{
CC
"deoptimizeAll"
,
CC
"()V"
,
(
void
*
)
&
WB_DeoptimizeAll
},
{
CC
"deoptimizeMethod"
,
CC
"(Ljava/lang/reflect/
Method
;)I"
,
{
CC
"deoptimizeMethod"
,
CC
"(Ljava/lang/reflect/
Executable
;)I"
,
(
void
*
)
&
WB_DeoptimizeMethod
},
{
CC
"isMethodCompiled"
,
CC
"(Ljava/lang/reflect/
Method
;)Z"
,
{
CC
"isMethodCompiled"
,
CC
"(Ljava/lang/reflect/
Executable
;)Z"
,
(
void
*
)
&
WB_IsMethodCompiled
},
{
CC
"isMethodCompilable"
,
CC
"(Ljava/lang/reflect/
Method
;I)Z"
,
{
CC
"isMethodCompilable"
,
CC
"(Ljava/lang/reflect/
Executable
;I)Z"
,
(
void
*
)
&
WB_IsMethodCompilable
},
{
CC
"isMethodQueuedForCompilation"
,
CC
"(Ljava/lang/reflect/
Method;)Z"
,
(
void
*
)
&
WB_IsMethodQueuedForCompilation
},
CC
"(Ljava/lang/reflect/
Executable;)Z"
,
(
void
*
)
&
WB_IsMethodQueuedForCompilation
},
{
CC
"makeMethodNotCompilable"
,
CC
"(Ljava/lang/reflect/
Method;)V"
,
(
void
*
)
&
WB_MakeMethodNotCompilable
},
CC
"(Ljava/lang/reflect/
Executable;I)V"
,
(
void
*
)
&
WB_MakeMethodNotCompilable
},
{
CC
"testSetDontInlineMethod"
,
CC
"(Ljava/lang/reflect/
Method;Z)Z"
,
(
void
*
)
&
WB_TestSetDontInlineMethod
},
CC
"(Ljava/lang/reflect/
Executable;Z)Z"
,
(
void
*
)
&
WB_TestSetDontInlineMethod
},
{
CC
"getMethodCompilationLevel"
,
CC
"(Ljava/lang/reflect/
Method;)I"
,
(
void
*
)
&
WB_GetMethodCompilationLevel
},
CC
"(Ljava/lang/reflect/
Executable;)I"
,
(
void
*
)
&
WB_GetMethodCompilationLevel
},
{
CC
"getCompileQueuesSize"
,
CC
"()I"
,
(
void
*
)
&
WB_GetCompileQueuesSize
},
{
CC
"testSetForceInlineMethod"
,
CC
"(Ljava/lang/reflect/
Method;Z)Z"
,
(
void
*
)
&
WB_TestSetForceInlineMethod
},
CC
"(Ljava/lang/reflect/
Executable;Z)Z"
,
(
void
*
)
&
WB_TestSetForceInlineMethod
},
{
CC
"enqueueMethodForCompilation"
,
CC
"(Ljava/lang/reflect/
Method;I)Z"
,
(
void
*
)
&
WB_EnqueueMethodForCompilation
},
CC
"(Ljava/lang/reflect/
Executable;I)Z"
,
(
void
*
)
&
WB_EnqueueMethodForCompilation
},
{
CC
"clearMethodState"
,
CC
"(Ljava/lang/reflect/
Method;)V"
,
(
void
*
)
&
WB_ClearMethodState
},
CC
"(Ljava/lang/reflect/
Executable;)V"
,
(
void
*
)
&
WB_ClearMethodState
},
{
CC
"isInStringTable"
,
CC
"(Ljava/lang/String;)Z"
,
(
void
*
)
&
WB_IsInStringTable
},
{
CC
"fullGC"
,
CC
"()V"
,
(
void
*
)
&
WB_FullGC
},
};
...
...
test/compiler/whitebox/ClearMethodStateTest.java
浏览文件 @
9cd6f543
...
...
@@ -27,42 +27,61 @@
* @build ClearMethodStateTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ClearMethodStateTest
* @summary testing of WB::clearMethodState()
* @author igor.ignatyev@oracle.com
*/
public
class
ClearMethodStateTest
extends
CompilerWhiteBoxTest
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// to prevent inlining #method into #compile() and #test()
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
true
);
new
ClearMethodStateTest
().
runTest
();
for
(
TestCase
test
:
TestCase
.
values
())
{
new
ClearMethodStateTest
(
test
).
runTest
(
);
}
}
public
ClearMethodStateTest
(
TestCase
testCase
)
{
super
(
testCase
);
// to prevent inlining of #method
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
true
);
}
/**
* Tests {@code WB::clearMethodState()} by calling it before/after
* compilation. For non-tiered, checks that counters will be rested after
* clearing of method state.
*
* @throws Exception if one of the checks fails.
*/
@Override
protected
void
test
()
throws
Exception
{
checkNotCompiled
(
METHOD
);
checkNotCompiled
();
compile
();
checkCompiled
(
METHOD
);
WHITE_BOX
.
clearMethodState
(
METHOD
);
WHITE_BOX
.
deoptimizeMethod
(
METHOD
);
checkNotCompiled
(
METHOD
);
WHITE_BOX
.
clearMethodState
(
method
);
checkCompiled
();
WHITE_BOX
.
clearMethodState
(
method
);
WHITE_BOX
.
deoptimizeMethod
(
method
);
checkNotCompiled
();
if
(!
TIERED_COMPILATION
)
{
WHITE_BOX
.
clearMethodState
(
METHOD
);
WHITE_BOX
.
clearMethodState
(
method
);
compile
(
COMPILE_THRESHOLD
);
checkCompiled
(
METHOD
);
checkCompiled
();
WHITE_BOX
.
deoptimizeMethod
(
METHOD
);
checkNotCompiled
(
METHOD
);
WHITE_BOX
.
clearMethodState
(
METHOD
);
WHITE_BOX
.
deoptimizeMethod
(
method
);
checkNotCompiled
();
WHITE_BOX
.
clearMethodState
(
method
);
// invoke method one less time than needed to compile
if
(
COMPILE_THRESHOLD
>
1
)
{
compile
(
COMPILE_THRESHOLD
-
1
);
checkNotCompiled
(
METHOD
);
checkNotCompiled
();
}
else
{
System
.
err
.
println
(
"Warning: 'CompileThreshold' <= 1"
);
System
.
err
.
println
(
"Warning: 'CompileThreshold' <= 1"
);
}
method
(
);
checkCompiled
(
METHOD
);
compile
(
1
);
checkCompiled
();
}
else
{
System
.
err
.
println
(
"Warning: part of test is not applicable in Tiered"
);
...
...
test/compiler/whitebox/CompilerWhiteBoxTest.java
浏览文件 @
9cd6f543
...
...
@@ -21,68 +21,132 @@
* questions.
*/
import
com.sun.management.HotSpotDiagnosticMXBean
;
import
com.sun.management.VMOption
;
import
sun.hotspot.WhiteBox
;
import
sun.management.ManagementFactoryHelper
;
import
com.sun.management.HotSpotDiagnosticMXBean
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Executable
;
import
java.lang.reflect.Method
;
import
java.util.Objects
;
import
java.util.concurrent.Callable
;
/*
/**
* Abstract class for WhiteBox testing of JIT.
*
* @author igor.ignatyev@oracle.com
*/
public
abstract
class
CompilerWhiteBoxTest
{
/** {@code CompLevel::CompLevel_none} -- Interpreter */
protected
static
int
COMP_LEVEL_NONE
=
0
;
/** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */
protected
static
int
COMP_LEVEL_ANY
=
-
1
;
/** Instance of WhiteBox */
protected
static
final
WhiteBox
WHITE_BOX
=
WhiteBox
.
getWhiteBox
();
protected
static
final
Method
METHOD
=
getMethod
(
"method"
);
/** Value of {@code -XX:CompileThreshold} */
protected
static
final
int
COMPILE_THRESHOLD
=
Integer
.
parseInt
(
getVMOption
(
"CompileThreshold"
,
"10000"
));
/** Value of {@code -XX:BackgroundCompilation} */
protected
static
final
boolean
BACKGROUND_COMPILATION
=
Boolean
.
valueOf
(
getVMOption
(
"BackgroundCompilation"
,
"true"
));
/** Value of {@code -XX:TieredCompilation} */
protected
static
final
boolean
TIERED_COMPILATION
=
Boolean
.
valueOf
(
getVMOption
(
"TieredCompilation"
,
"false"
));
/** Value of {@code -XX:TieredStopAtLevel} */
protected
static
final
int
TIERED_STOP_AT_LEVEL
=
Integer
.
parseInt
(
getVMOption
(
"TieredStopAtLevel"
,
"0"
));
protected
static
Method
getMethod
(
String
name
)
{
try
{
return
CompilerWhiteBoxTest
.
class
.
getDeclaredMethod
(
name
);
}
catch
(
NoSuchMethodException
|
SecurityException
e
)
{
throw
new
RuntimeException
(
"exception on getting method "
+
name
,
e
);
}
}
/**
* Returns value of VM option.
*
* @param name option's name
* @return value of option or {@code null}, if option doesn't exist
* @throws NullPointerException if name is null
*/
protected
static
String
getVMOption
(
String
name
)
{
String
result
;
Objects
.
requireNonNull
(
name
)
;
HotSpotDiagnosticMXBean
diagnostic
=
ManagementFactoryHelper
.
getDiagnosticMXBean
();
result
=
diagnostic
.
getVMOption
(
name
).
getValue
();
return
result
;
VMOption
tmp
;
try
{
tmp
=
diagnostic
.
getVMOption
(
name
);
}
catch
(
IllegalArgumentException
e
)
{
tmp
=
null
;
}
return
(
tmp
==
null
?
null
:
tmp
.
getValue
());
}
/**
* Returns value of VM option or default value.
*
* @param name option's name
* @param defaultValue default value
* @return value of option or {@code defaultValue}, if option doesn't exist
* @throws NullPointerException if name is null
* @see #getVMOption(String)
*/
protected
static
String
getVMOption
(
String
name
,
String
defaultValue
)
{
String
result
=
getVMOption
(
name
);
return
result
==
null
?
defaultValue
:
result
;
}
protected
final
void
runTest
()
throws
RuntimeException
{
/** tested method */
protected
final
Executable
method
;
private
final
Callable
<
Integer
>
callable
;
/**
* Constructor.
*
* @param testCase object, that contains tested method and way to invoke it.
*/
protected
CompilerWhiteBoxTest
(
TestCase
testCase
)
{
Objects
.
requireNonNull
(
testCase
);
System
.
out
.
println
(
"TEST CASE:"
+
testCase
.
name
());
method
=
testCase
.
executable
;
callable
=
testCase
.
callable
;
}
/**
* Template method for testing. Prints tested method's info before
* {@linkplain #test()} and after {@linkplain #test()} or on thrown
* exception.
*
* @throws RuntimeException if method {@linkplain #test()} throws any
* exception
* @see #test()
*/
protected
final
void
runTest
()
{
if
(
ManagementFactoryHelper
.
getCompilationMXBean
()
==
null
)
{
System
.
err
.
println
(
"Warning: test is not applicable in interpreted mode"
);
return
;
}
System
.
out
.
println
(
"at test's start:"
);
printInfo
(
METHOD
);
printInfo
();
try
{
test
();
}
catch
(
Exception
e
)
{
System
.
out
.
printf
(
"on exception '%s':"
,
e
.
getMessage
());
printInfo
(
METHOD
);
printInfo
();
e
.
printStackTrace
();
if
(
e
instanceof
RuntimeException
)
{
throw
(
RuntimeException
)
e
;
}
throw
new
RuntimeException
(
e
);
}
System
.
out
.
println
(
"at test's end:"
);
printInfo
(
METHOD
);
printInfo
();
}
protected
static
void
checkNotCompiled
(
Method
method
)
{
/**
* Checks, that {@linkplain #method} is not compiled.
*
* @throws RuntimeException if {@linkplain #method} is in compiler queue or
* is compiled, or if {@linkplain #method} has zero
* compilation level.
*/
protected
final
void
checkNotCompiled
()
{
if
(
WHITE_BOX
.
isMethodQueuedForCompilation
(
method
))
{
throw
new
RuntimeException
(
method
+
" must not be in queue"
);
}
...
...
@@ -94,10 +158,16 @@ public abstract class CompilerWhiteBoxTest {
}
}
protected
static
void
checkCompiled
(
Method
method
)
throws
InterruptedException
{
/**
* Checks, that {@linkplain #method} is compiled.
*
* @throws RuntimeException if {@linkplain #method} isn't in compiler queue
* and isn't compiled, or if {@linkplain #method}
* has nonzero compilation level
*/
protected
final
void
checkCompiled
()
{
final
long
start
=
System
.
currentTimeMillis
();
waitBackgroundCompilation
(
method
);
waitBackgroundCompilation
();
if
(
WHITE_BOX
.
isMethodQueuedForCompilation
(
method
))
{
System
.
err
.
printf
(
"Warning: %s is still in queue after %dms%n"
,
method
,
System
.
currentTimeMillis
()
-
start
);
...
...
@@ -111,23 +181,30 @@ public abstract class CompilerWhiteBoxTest {
}
}
protected
static
void
waitBackgroundCompilation
(
Method
method
)
throws
InterruptedException
{
/**
* Waits for completion of background compilation of {@linkplain #method}.
*/
protected
final
void
waitBackgroundCompilation
()
{
if
(!
BACKGROUND_COMPILATION
)
{
return
;
}
final
Object
obj
=
new
Object
();
synchronized
(
obj
)
{
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
if
(!
WHITE_BOX
.
isMethodQueuedForCompilation
(
method
))
{
break
;
for
(
int
i
=
0
;
i
<
10
&&
WHITE_BOX
.
isMethodQueuedForCompilation
(
method
);
++
i
)
{
synchronized
(
obj
)
{
try
{
obj
.
wait
(
1000
);
}
catch
(
InterruptedException
e
)
{
Thread
.
currentThread
().
interrupt
();
}
obj
.
wait
(
1000
);
}
}
}
protected
static
void
printInfo
(
Method
method
)
{
/**
* Prints information about {@linkplain #method}.
*/
protected
final
void
printInfo
()
{
System
.
out
.
printf
(
"%n%s:%n"
,
method
);
System
.
out
.
printf
(
"\tcompilable:\t%b%n"
,
WHITE_BOX
.
isMethodCompilable
(
method
));
...
...
@@ -141,22 +218,139 @@ public abstract class CompilerWhiteBoxTest {
WHITE_BOX
.
getCompileQueuesSize
());
}
/**
* Executes testing.
*/
protected
abstract
void
test
()
throws
Exception
;
/**
* Tries to trigger compilation of {@linkplain #method} by call
* {@linkplain #callable} enough times.
*
* @return accumulated result
* @see #compile(int)
*/
protected
final
int
compile
()
{
return
compile
(
Math
.
max
(
COMPILE_THRESHOLD
,
150000
));
}
/**
* Tries to trigger compilation of {@linkplain #method} by call
* {@linkplain #callable} specified times.
*
* @param count invocation count
* @return accumulated result
*/
protected
final
int
compile
(
int
count
)
{
int
result
=
0
;
Integer
tmp
;
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
result
+=
method
();
try
{
tmp
=
callable
.
call
();
}
catch
(
Exception
e
)
{
tmp
=
null
;
}
result
+=
tmp
==
null
?
0
:
tmp
;
}
System
.
out
.
println
(
"method was invoked "
+
count
+
" times"
);
return
result
;
}
}
protected
int
method
()
{
return
42
;
/**
* Utility structure containing tested method and object to invoke it.
*/
enum
TestCase
{
/** constructor test case */
CONSTRUCTOR_TEST
(
Helper
.
CONSTRUCTOR
,
Helper
.
CONSTRUCTOR_CALLABLE
),
/** method test case */
METOD_TEST
(
Helper
.
METHOD
,
Helper
.
METHOD_CALLABLE
),
/** static method test case */
STATIC_TEST
(
Helper
.
STATIC
,
Helper
.
STATIC_CALLABLE
);
/** tested method */
final
Executable
executable
;
/** object to invoke {@linkplain #executable} */
final
Callable
<
Integer
>
callable
;
private
TestCase
(
Executable
executable
,
Callable
<
Integer
>
callable
)
{
this
.
executable
=
executable
;
this
.
callable
=
callable
;
}
private
static
class
Helper
{
private
static
final
Callable
<
Integer
>
CONSTRUCTOR_CALLABLE
=
new
Callable
<
Integer
>()
{
@Override
public
Integer
call
()
throws
Exception
{
return
new
Helper
(
1337
).
hashCode
();
}
};
private
static
final
Callable
<
Integer
>
METHOD_CALLABLE
=
new
Callable
<
Integer
>()
{
private
final
Helper
helper
=
new
Helper
();
@Override
public
Integer
call
()
throws
Exception
{
return
helper
.
method
();
}
};
private
static
final
Callable
<
Integer
>
STATIC_CALLABLE
=
new
Callable
<
Integer
>()
{
@Override
public
Integer
call
()
throws
Exception
{
return
staticMethod
();
}
};
private
static
final
Constructor
CONSTRUCTOR
;
private
static
final
Method
METHOD
;
private
static
final
Method
STATIC
;
static
{
try
{
CONSTRUCTOR
=
Helper
.
class
.
getDeclaredConstructor
(
int
.
class
);
}
catch
(
NoSuchMethodException
|
SecurityException
e
)
{
throw
new
RuntimeException
(
"exception on getting method Helper.<init>(int)"
,
e
);
}
try
{
METHOD
=
Helper
.
class
.
getDeclaredMethod
(
"method"
);
}
catch
(
NoSuchMethodException
|
SecurityException
e
)
{
throw
new
RuntimeException
(
"exception on getting method Helper.method()"
,
e
);
}
try
{
STATIC
=
Helper
.
class
.
getDeclaredMethod
(
"staticMethod"
);
}
catch
(
NoSuchMethodException
|
SecurityException
e
)
{
throw
new
RuntimeException
(
"exception on getting method Helper.staticMethod()"
,
e
);
}
}
private
static
int
staticMethod
()
{
return
1138
;
}
private
int
method
()
{
return
42
;
}
private
final
int
x
;
public
Helper
()
{
x
=
0
;
}
private
Helper
(
int
x
)
{
this
.
x
=
x
;
}
@Override
public
int
hashCode
()
{
return
x
;
}
}
}
test/compiler/whitebox/DeoptimizeAllTest.java
浏览文件 @
9cd6f543
...
...
@@ -27,20 +27,34 @@
* @build DeoptimizeAllTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest
* @summary testing of WB::deoptimizeAll()
* @author igor.ignatyev@oracle.com
*/
public
class
DeoptimizeAllTest
extends
CompilerWhiteBoxTest
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// to prevent inlining #method into #compile()
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
true
);
new
DeoptimizeAllTest
().
runTest
();
for
(
TestCase
test
:
TestCase
.
values
())
{
new
DeoptimizeAllTest
(
test
).
runTest
(
);
}
}
public
DeoptimizeAllTest
(
TestCase
testCase
)
{
super
(
testCase
);
// to prevent inlining of #method
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
true
);
}
/**
* Tests {@code WB::deoptimizeAll()} by calling it after
* compilation and checking that method isn't compiled.
*
* @throws Exception if one of the checks fails.
*/
@Override
protected
void
test
()
throws
Exception
{
compile
();
checkCompiled
(
METHOD
);
checkCompiled
();
WHITE_BOX
.
deoptimizeAll
();
checkNotCompiled
(
METHOD
);
checkNotCompiled
();
}
}
test/compiler/whitebox/DeoptimizeMethodTest.java
浏览文件 @
9cd6f543
...
...
@@ -27,20 +27,34 @@
* @build DeoptimizeMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest
* @summary testing of WB::deoptimizeMethod()
* @author igor.ignatyev@oracle.com
*/
public
class
DeoptimizeMethodTest
extends
CompilerWhiteBoxTest
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// to prevent inlining #method into #compile()
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
true
);
new
DeoptimizeMethodTest
().
runTest
();
for
(
TestCase
test
:
TestCase
.
values
())
{
new
DeoptimizeMethodTest
(
test
).
runTest
(
);
}
}
public
DeoptimizeMethodTest
(
TestCase
testCase
)
{
super
(
testCase
);
// to prevent inlining of #method
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
true
);
}
/**
* Tests {@code WB::deoptimizeMethod()} by calling it after
* compilation and checking that method isn't compiled.
*
* @throws Exception if one of the checks fails.
*/
@Override
protected
void
test
()
throws
Exception
{
compile
();
checkCompiled
(
METHOD
);
WHITE_BOX
.
deoptimizeMethod
(
METHOD
);
checkNotCompiled
(
METHOD
);
checkCompiled
();
WHITE_BOX
.
deoptimizeMethod
(
method
);
checkNotCompiled
();
}
}
test/compiler/whitebox/EnqueueMethodForCompilationTest.java
浏览文件 @
9cd6f543
...
...
@@ -27,48 +27,60 @@
* @build EnqueueMethodForCompilationTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI EnqueueMethodForCompilationTest
* @summary testing of WB::enqueueMethodForCompilation()
* @author igor.ignatyev@oracle.com
*/
public
class
EnqueueMethodForCompilationTest
extends
CompilerWhiteBoxTest
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// to prevent inlining #method into #compile()
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
true
);
new
EnqueueMethodForCompilationTest
().
runTest
();
for
(
TestCase
test
:
TestCase
.
values
())
{
new
EnqueueMethodForCompilationTest
(
test
).
runTest
();
}
}
public
EnqueueMethodForCompilationTest
(
TestCase
testCase
)
{
super
(
testCase
);
// to prevent inlining of #method
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
true
);
}
@Override
protected
void
test
()
throws
Exception
{
checkNotCompiled
(
METHOD
);
checkNotCompiled
();
WHITE_BOX
.
enqueueMethodForCompilation
(
METHOD
,
0
);
if
(
WHITE_BOX
.
isMethodCompilable
(
METHOD
,
0
))
{
throw
new
RuntimeException
(
METHOD
+
" is compilable at level 0"
);
// method can not be compiled on level 'none'
WHITE_BOX
.
enqueueMethodForCompilation
(
method
,
COMP_LEVEL_NONE
);
if
(
WHITE_BOX
.
isMethodCompilable
(
method
,
COMP_LEVEL_NONE
))
{
throw
new
RuntimeException
(
method
+
" is compilable at level COMP_LEVEL_NONE"
);
}
checkNotCompiled
(
METHOD
);
checkNotCompiled
();
WHITE_BOX
.
enqueueMethodForCompilation
(
METHOD
,
-
1
);
checkNotCompiled
(
METHOD
);
// COMP_LEVEL_ANY is inapplicable as level for compilation
WHITE_BOX
.
enqueueMethodForCompilation
(
method
,
COMP_LEVEL_ANY
);
checkNotCompiled
();
WHITE_BOX
.
enqueueMethodForCompilation
(
METHOD
,
5
);
if
(!
WHITE_BOX
.
isMethodCompilable
(
METHOD
,
5
))
{
checkNotCompiled
(
METHOD
);
compile
();
checkCompiled
(
METHOD
);
WHITE_BOX
.
enqueueMethodForCompilation
(
method
,
5
);
if
(!
WHITE_BOX
.
isMethodCompilable
(
method
,
5
))
{
checkNotCompiled
(
);
compile
();
checkCompiled
(
);
}
else
{
checkCompiled
(
METHOD
);
checkCompiled
(
);
}
int
compLevel
=
WHITE_BOX
.
getMethodCompilationLevel
(
METHOD
);
WHITE_BOX
.
deoptimizeMethod
(
METHOD
);
checkNotCompiled
(
METHOD
);
int
compLevel
=
WHITE_BOX
.
getMethodCompilationLevel
(
method
);
WHITE_BOX
.
deoptimizeMethod
(
method
);
checkNotCompiled
();
WHITE_BOX
.
enqueueMethodForCompilation
(
METHOD
,
compLevel
);
checkCompiled
(
METHOD
);
WHITE_BOX
.
deoptimizeMethod
(
METHOD
);
checkNotCompiled
(
METHOD
);
WHITE_BOX
.
enqueueMethodForCompilation
(
method
,
compLevel
);
checkCompiled
();
WHITE_BOX
.
deoptimizeMethod
(
method
);
checkNotCompiled
();
compile
();
checkCompiled
(
METHOD
);
WHITE_BOX
.
deoptimizeMethod
(
METHOD
);
checkNotCompiled
(
METHOD
);
checkCompiled
();
WHITE_BOX
.
deoptimizeMethod
(
method
);
checkNotCompiled
();
}
}
test/compiler/whitebox/IsMethodCompilableTest.java
浏览文件 @
9cd6f543
...
...
@@ -28,9 +28,13 @@
* @build IsMethodCompilableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest
* @summary testing of WB::isMethodCompilable()
* @author igor.ignatyev@oracle.com
*/
public
class
IsMethodCompilableTest
extends
CompilerWhiteBoxTest
{
/**
* Value of {@code -XX:PerMethodRecompilationCutoff}
*/
protected
static
final
long
PER_METHOD_RECOMPILATION_CUTOFF
;
static
{
...
...
@@ -44,14 +48,28 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// to prevent inlining #method into #compile()
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
true
);
new
IsMethodCompilableTest
().
runTest
();
for
(
TestCase
test
:
TestCase
.
values
())
{
new
IsMethodCompilableTest
(
test
).
runTest
();
}
}
public
IsMethodCompilableTest
(
TestCase
testCase
)
{
super
(
testCase
);
// to prevent inlining of #method
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
true
);
}
/**
* Tests {@code WB::isMethodCompilable()} by recompilation of tested method
* 'PerMethodRecompilationCutoff' times and checks compilation status. Also
* checks that WB::clearMethodState() clears no-compilable flags.
*
* @throws Exception if one of the checks fails.
*/
@Override
protected
void
test
()
throws
Exception
{
if
(!
WHITE_BOX
.
isMethodCompilable
(
METHOD
))
{
throw
new
RuntimeException
(
METHOD
+
" must be compilable"
);
if
(!
WHITE_BOX
.
isMethodCompilable
(
method
))
{
throw
new
RuntimeException
(
method
+
" must be compilable"
);
}
System
.
out
.
println
(
"PerMethodRecompilationCutoff = "
+
PER_METHOD_RECOMPILATION_CUTOFF
);
...
...
@@ -61,46 +79,47 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
return
;
}
// deoptimze 'PerMethodRecompilationCutoff' times and clear state
// deoptim
i
ze 'PerMethodRecompilationCutoff' times and clear state
for
(
long
i
=
0L
,
n
=
PER_METHOD_RECOMPILATION_CUTOFF
-
1
;
i
<
n
;
++
i
)
{
compileAndDeoptim
a
ze
();
compileAndDeoptim
i
ze
();
}
if
(!
WHITE_BOX
.
isMethodCompilable
(
METHOD
))
{
throw
new
RuntimeException
(
METHOD
+
" is not compilable after "
if
(!
WHITE_BOX
.
isMethodCompilable
(
method
))
{
throw
new
RuntimeException
(
method
+
" is not compilable after "
+
(
PER_METHOD_RECOMPILATION_CUTOFF
-
1
)
+
" iterations"
);
}
WHITE_BOX
.
clearMethodState
(
METHOD
);
WHITE_BOX
.
clearMethodState
(
method
);
// deoptimze 'PerMethodRecompilationCutoff' + 1 times
// deoptim
i
ze 'PerMethodRecompilationCutoff' + 1 times
long
i
;
for
(
i
=
0L
;
i
<
PER_METHOD_RECOMPILATION_CUTOFF
&&
WHITE_BOX
.
isMethodCompilable
(
METHOD
);
++
i
)
{
compileAndDeoptim
a
ze
();
&&
WHITE_BOX
.
isMethodCompilable
(
method
);
++
i
)
{
compileAndDeoptim
i
ze
();
}
if
(
i
!=
PER_METHOD_RECOMPILATION_CUTOFF
)
{
throw
new
RuntimeException
(
METHOD
+
" is not compilable after "
+
i
+
" iterations, but must only after "
+
PER_METHOD_RECOMPILATION_CUTOFF
);
throw
new
RuntimeException
(
method
+
" is not compilable after "
+
i
+
" iterations, but must only after "
+
PER_METHOD_RECOMPILATION_CUTOFF
);
}
if
(
WHITE_BOX
.
isMethodCompilable
(
METHOD
))
{
throw
new
RuntimeException
(
METHOD
+
" is still compilable after "
if
(
WHITE_BOX
.
isMethodCompilable
(
method
))
{
throw
new
RuntimeException
(
method
+
" is still compilable after "
+
PER_METHOD_RECOMPILATION_CUTOFF
+
" iterations"
);
}
compile
();
checkNotCompiled
(
METHOD
);
checkNotCompiled
();
WHITE_BOX
.
clearMethodState
(
METHOD
);
if
(!
WHITE_BOX
.
isMethodCompilable
(
METHOD
))
{
throw
new
RuntimeException
(
METHOD
+
" is compilable after clearMethodState()"
);
// WB.clearMethodState() must reset no-compilable flags
WHITE_BOX
.
clearMethodState
(
method
);
if
(!
WHITE_BOX
.
isMethodCompilable
(
method
))
{
throw
new
RuntimeException
(
method
+
" is not compilable after clearMethodState()"
);
}
compile
();
checkCompiled
(
METHOD
);
checkCompiled
();
}
private
void
compileAndDeoptim
a
ze
()
throws
Exception
{
private
void
compileAndDeoptim
i
ze
()
throws
Exception
{
compile
();
waitBackgroundCompilation
(
METHOD
);
WHITE_BOX
.
deoptimizeMethod
(
METHOD
);
waitBackgroundCompilation
();
WHITE_BOX
.
deoptimizeMethod
(
method
);
}
}
test/compiler/whitebox/MakeMethodNotCompilableTest.java
浏览文件 @
9cd6f543
...
...
@@ -27,28 +27,85 @@
* @build MakeMethodNotCompilableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest
* @summary testing of WB::makeMethodNotCompilable()
* @author igor.ignatyev@oracle.com
*/
public
class
MakeMethodNotCompilableTest
extends
CompilerWhiteBoxTest
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// to prevent inlining #method into #compile()
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
true
);
new
MakeMethodNotCompilableTest
().
runTest
();
if
(
args
.
length
==
0
)
{
for
(
TestCase
test
:
TestCase
.
values
())
{
new
MakeMethodNotCompilableTest
(
test
).
runTest
();
}
}
else
{
for
(
String
name
:
args
)
{
new
MakeMethodNotCompilableTest
(
TestCase
.
valueOf
(
name
)).
runTest
();
}
}
}
public
MakeMethodNotCompilableTest
(
TestCase
testCase
)
{
super
(
testCase
);
// to prevent inlining of #method
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
true
);
}
protected
void
test
()
throws
Exception
{
if
(!
WHITE_BOX
.
isMethodCompilable
(
METHOD
))
{
throw
new
RuntimeException
(
METHOD
+
" must be compilable"
);
/**
* Tests {@code WB::makeMethodNotCompilable()} by calling it before
* compilation and checking that method isn't compiled. Also
* checks that WB::clearMethodState() clears no-compilable flags. For
* tiered, additional checks for all available levels are conducted.
*
* @throws Exception if one of the checks fails.
*/
@Override
protected
void
test
()
throws
Exception
{
checkNotCompiled
();
if
(!
WHITE_BOX
.
isMethodCompilable
(
method
))
{
throw
new
RuntimeException
(
method
+
" must be compilable"
);
}
if
(
TIERED_COMPILATION
)
{
for
(
int
i
=
1
,
n
=
TIERED_STOP_AT_LEVEL
+
1
;
i
<
n
;
++
i
)
{
WHITE_BOX
.
makeMethodNotCompilable
(
method
,
i
);
if
(
WHITE_BOX
.
isMethodCompilable
(
method
,
i
))
{
throw
new
RuntimeException
(
method
+
" must be not compilable at level"
+
i
);
}
WHITE_BOX
.
enqueueMethodForCompilation
(
method
,
i
);
checkNotCompiled
();
if
(!
WHITE_BOX
.
isMethodCompilable
(
method
))
{
System
.
out
.
println
(
method
+
" is not compilable after level "
+
i
);
}
}
// WB.clearMethodState() must reset no-compilable flags
WHITE_BOX
.
clearMethodState
(
method
);
if
(!
WHITE_BOX
.
isMethodCompilable
(
method
))
{
throw
new
RuntimeException
(
method
+
" is not compilable after clearMethodState()"
);
}
}
WHITE_BOX
.
makeMethodNotCompilable
(
METHOD
);
if
(
WHITE_BOX
.
isMethodCompilable
(
METHOD
))
{
throw
new
RuntimeException
(
METHOD
+
" must be not compilable"
);
WHITE_BOX
.
makeMethodNotCompilable
(
method
);
if
(
WHITE_BOX
.
isMethodCompilable
(
method
))
{
throw
new
RuntimeException
(
method
+
" must be not compilable"
);
}
compile
();
checkNotCompiled
(
METHOD
);
if
(
WHITE_BOX
.
isMethodCompilable
(
METHOD
))
{
throw
new
RuntimeException
(
METHOD
+
" must be not compilable"
);
checkNotCompiled
();
if
(
WHITE_BOX
.
isMethodCompilable
(
method
))
{
throw
new
RuntimeException
(
method
+
" must be not compilable"
);
}
// WB.clearMethodState() must reset no-compilable flags
WHITE_BOX
.
clearMethodState
(
method
);
if
(!
WHITE_BOX
.
isMethodCompilable
(
method
))
{
throw
new
RuntimeException
(
method
+
" is not compilable after clearMethodState()"
);
}
compile
();
checkCompiled
();
}
}
test/compiler/whitebox/SetDontInlineMethodTest.java
浏览文件 @
9cd6f543
...
...
@@ -27,33 +27,47 @@
* @build SetDontInlineMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest
* @summary testing of WB::testSetDontInlineMethod()
* @author igor.ignatyev@oracle.com
*/
public
class
SetDontInlineMethodTest
extends
CompilerWhiteBoxTest
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
new
SetDontInlineMethodTest
().
runTest
();
for
(
TestCase
test
:
TestCase
.
values
())
{
new
SetDontInlineMethodTest
(
test
).
runTest
();
}
}
public
SetDontInlineMethodTest
(
TestCase
testCase
)
{
super
(
testCase
);
}
/**
* Tests {@code WB::testSetDontInlineMethod()} by sequential calling it and
* checking of return value.
*
* @throws Exception if one of the checks fails.
*/
@Override
protected
void
test
()
throws
Exception
{
if
(
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
true
))
{
throw
new
RuntimeException
(
"on start "
+
METHOD
if
(
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
true
))
{
throw
new
RuntimeException
(
"on start "
+
method
+
" must be inlineable"
);
}
if
(!
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
true
))
{
throw
new
RuntimeException
(
"after first change to true "
+
METHOD
if
(!
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
true
))
{
throw
new
RuntimeException
(
"after first change to true "
+
method
+
" must be not inlineable"
);
}
if
(!
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
false
))
{
throw
new
RuntimeException
(
"after second change to true "
+
METHOD
if
(!
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
false
))
{
throw
new
RuntimeException
(
"after second change to true "
+
method
+
" must be still not inlineable"
);
}
if
(
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
false
))
{
throw
new
RuntimeException
(
"after first change to false"
+
METHOD
if
(
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
false
))
{
throw
new
RuntimeException
(
"after first change to false"
+
method
+
" must be inlineable"
);
}
if
(
WHITE_BOX
.
testSetDontInlineMethod
(
METHOD
,
false
))
{
throw
new
RuntimeException
(
"after second change to false "
+
METHOD
if
(
WHITE_BOX
.
testSetDontInlineMethod
(
method
,
false
))
{
throw
new
RuntimeException
(
"after second change to false "
+
method
+
" must be inlineable"
);
}
}
...
...
test/compiler/whitebox/SetForceInlineMethodTest.java
浏览文件 @
9cd6f543
...
...
@@ -27,33 +27,47 @@
* @build SetForceInlineMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetForceInlineMethodTest
* @summary testing of WB::testSetForceInlineMethod()
* @author igor.ignatyev@oracle.com
*/
public
class
SetForceInlineMethodTest
extends
CompilerWhiteBoxTest
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
new
SetForceInlineMethodTest
().
runTest
();
for
(
TestCase
test
:
TestCase
.
values
())
{
new
SetForceInlineMethodTest
(
test
).
runTest
();
}
}
public
SetForceInlineMethodTest
(
TestCase
testCase
)
{
super
(
testCase
);
}
/**
* Tests {@code WB::testSetForceInlineMethod()} by sequential calling it and
* checking of return value.
*
* @throws Exception if one of the checks fails.
*/
@Override
protected
void
test
()
throws
Exception
{
if
(
WHITE_BOX
.
testSetForceInlineMethod
(
METHOD
,
true
))
{
throw
new
RuntimeException
(
"on start "
+
METHOD
if
(
WHITE_BOX
.
testSetForceInlineMethod
(
method
,
true
))
{
throw
new
RuntimeException
(
"on start "
+
method
+
" must be not force inlineable"
);
}
if
(!
WHITE_BOX
.
testSetForceInlineMethod
(
METHOD
,
true
))
{
throw
new
RuntimeException
(
"after first change to true "
+
METHOD
if
(!
WHITE_BOX
.
testSetForceInlineMethod
(
method
,
true
))
{
throw
new
RuntimeException
(
"after first change to true "
+
method
+
" must be force inlineable"
);
}
if
(!
WHITE_BOX
.
testSetForceInlineMethod
(
METHOD
,
false
))
{
throw
new
RuntimeException
(
"after second change to true "
+
METHOD
if
(!
WHITE_BOX
.
testSetForceInlineMethod
(
method
,
false
))
{
throw
new
RuntimeException
(
"after second change to true "
+
method
+
" must be still force inlineable"
);
}
if
(
WHITE_BOX
.
testSetForceInlineMethod
(
METHOD
,
false
))
{
throw
new
RuntimeException
(
"after first change to false"
+
METHOD
if
(
WHITE_BOX
.
testSetForceInlineMethod
(
method
,
false
))
{
throw
new
RuntimeException
(
"after first change to false"
+
method
+
" must be not force inlineable"
);
}
if
(
WHITE_BOX
.
testSetForceInlineMethod
(
METHOD
,
false
))
{
throw
new
RuntimeException
(
"after second change to false "
+
METHOD
if
(
WHITE_BOX
.
testSetForceInlineMethod
(
method
,
false
))
{
throw
new
RuntimeException
(
"after second change to false "
+
method
+
" must be not force inlineable"
);
}
}
...
...
test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
浏览文件 @
9cd6f543
...
...
@@ -24,7 +24,7 @@
package
sun.hotspot
;
import
java.lang.reflect.
Method
;
import
java.lang.reflect.
Executable
;
import
java.security.BasicPermission
;
import
sun.hotspot.parser.DiagnosticCommand
;
...
...
@@ -90,22 +90,25 @@ public class WhiteBox {
// Compiler
public
native
void
deoptimizeAll
();
public
native
boolean
isMethodCompiled
(
Method
method
);
public
boolean
isMethodCompilable
(
Method
method
)
{
public
native
boolean
isMethodCompiled
(
Executable
method
);
public
boolean
isMethodCompilable
(
Executable
method
)
{
return
isMethodCompilable
(
method
,
-
1
/*any*/
);
}
public
native
boolean
isMethodCompilable
(
Method
method
,
int
compLevel
);
public
native
boolean
isMethodQueuedForCompilation
(
Method
method
);
public
native
int
deoptimizeMethod
(
Method
method
);
public
native
void
makeMethodNotCompilable
(
Method
method
);
public
native
int
getMethodCompilationLevel
(
Method
method
);
public
native
boolean
testSetDontInlineMethod
(
Method
method
,
boolean
value
);
public
native
boolean
isMethodCompilable
(
Executable
method
,
int
compLevel
);
public
native
boolean
isMethodQueuedForCompilation
(
Executable
method
);
public
native
int
deoptimizeMethod
(
Executable
method
);
public
void
makeMethodNotCompilable
(
Executable
method
)
{
makeMethodNotCompilable
(
method
,
-
1
/*any*/
);
}
public
native
void
makeMethodNotCompilable
(
Executable
method
,
int
compLevel
);
public
native
int
getMethodCompilationLevel
(
Executable
method
);
public
native
boolean
testSetDontInlineMethod
(
Executable
method
,
boolean
value
);
public
native
int
getCompileQueuesSize
();
public
native
boolean
testSetForceInlineMethod
(
Method
method
,
boolean
value
);
public
native
boolean
enqueueMethodForCompilation
(
Method
method
,
int
compLevel
);
public
native
void
clearMethodState
(
Method
method
);
public
native
boolean
testSetForceInlineMethod
(
Executable
method
,
boolean
value
);
public
native
boolean
enqueueMethodForCompilation
(
Executable
method
,
int
compLevel
);
public
native
void
clearMethodState
(
Executable
method
);
//Intered strings
//
Intered strings
public
native
boolean
isInStringTable
(
String
str
);
// force Full GC
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录